From 579f129e45071261819a54ffe772d2c463eeb656 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E4=BA=88=E9=A1=BA?= <ys_37677@126.com>
Date: Fri, 18 May 2018 16:29:10 +0800
Subject: [PATCH 01/12] Reformat

---
 src/CMakeLists.txt                |  124 +-
 src/autocomplete.cc               |  318 +-
 src/autocomplete.h                |   99 +-
 src/buildsystem/buildsystem.h     |   20 +
 src/buildsystem/cmake.cc          |  386 ++
 src/buildsystem/cmake.h           |   41 +
 src/buildsystem/meson.cc          |  123 +
 src/buildsystem/meson.h           |   18 +
 src/cmake.cc                      |  378 --
 src/cmake.h                       |   30 -
 src/compile_commands.cc           |  290 +-
 src/compile_commands.h            |   31 +-
 src/config.cc                     |  347 +-
 src/config.h                      |  219 +-
 src/ctags.cc                      |  350 +-
 src/ctags.h                       |   39 +-
 src/debug_lldb.cc                 |  862 ++---
 src/debug_lldb.h                  |  171 +-
 src/dialogs.cc                    |  131 +-
 src/dialogs.h                     |   38 +-
 src/dialogs_unix.cc               |   30 +-
 src/dialogs_win.cc                |  252 +-
 src/directories.cc                | 1323 +++----
 src/directories.h                 |  159 +-
 src/dispatcher.cc                 |   40 +-
 src/dispatcher.h                  |   34 +-
 src/documentation_cppreference.cc |   72 +-
 src/documentation_cppreference.h  |    9 +-
 src/entrybox.cc                   |  161 +-
 src/entrybox.h                    |   94 +-
 src/files.h                       |   59 +-
 src/filesystem.cc                 |  365 +-
 src/filesystem.h                  |   79 +-
 src/git.cc                        |  479 +--
 src/git.h                         |  202 +-
 src/info.cc                       |   58 +-
 src/info.h                        |   22 +-
 src/juci.cc                       |  212 +-
 src/juci.h                        |   18 +-
 src/menu.cc                       |   56 +-
 src/menu.h                        |   40 +-
 src/meson.cc                      |  117 -
 src/meson.h                       |   15 -
 src/notebook.cc                   | 1139 +++---
 src/notebook.h                    |  175 +-
 src/project.cc                    |  968 +++---
 src/project.h                     |  350 +-
 src/project_build.cc              |  190 +-
 src/project_build.h               |  130 +-
 src/selection_dialog.cc           |  800 ++---
 src/selection_dialog.h            |  189 +-
 src/source.cc                     | 5408 +++++++++++++++--------------
 src/source.h                      |  369 +-
 src/source_base.cc                |  606 ++--
 src/source_base.h                 |  190 +-
 src/source_clang.cc               | 3395 +++++++++---------
 src/source_clang.h                |  225 +-
 src/source_diff.cc                |  634 ++--
 src/source_diff.h                 |  116 +-
 src/source_language_protocol.cc   | 2728 ++++++++-------
 src/source_language_protocol.h    |  250 +-
 src/source_spellcheck.cc          |  891 ++---
 src/source_spellcheck.h           |   87 +-
 src/terminal.cc                   |  721 ++--
 src/terminal.h                    |   85 +-
 src/tooltips.cc                   |  429 +--
 src/tooltips.h                    |   92 +-
 src/usages_clang.cc               | 1266 +++----
 src/usages_clang.h                |  254 +-
 src/window.cc                     | 3294 +++++++++---------
 src/window.h                      |   71 +-
 71 files changed, 16954 insertions(+), 16009 deletions(-)
 create mode 100644 src/buildsystem/buildsystem.h
 create mode 100644 src/buildsystem/cmake.cc
 create mode 100644 src/buildsystem/cmake.h
 create mode 100644 src/buildsystem/meson.cc
 create mode 100644 src/buildsystem/meson.h
 delete mode 100644 src/cmake.cc
 delete mode 100644 src/cmake.h
 delete mode 100644 src/meson.cc
 delete mode 100644 src/meson.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9c32003c..b988f114 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,75 +1,77 @@
 # Files used both in ../src and ../tests
+
+file(GLOB JUCI_SRC_BUILDSYSTEMS buildsystem/*.*)
+
 set(JUCI_SHARED_FILES
-  autocomplete.cc
-  cmake.cc
-  compile_commands.cc
-  ctags.cc
-  dispatcher.cc
-  documentation_cppreference.cc
-  filesystem.cc
-  git.cc
-  menu.cc
-  meson.cc
-  project_build.cc
-  source.cc
-  source_base.cc
-  source_clang.cc
-  source_diff.cc
-  source_language_protocol.cc
-  source_spellcheck.cc
-  terminal.cc
-  usages_clang.cc
-)
-if(LIBLLDB_FOUND)
-  list(APPEND JUCI_SHARED_FILES debug_lldb.cc)
-endif()
+        ${JUCI_SRC_BUILDSYSTEMS}
+        autocomplete.cc
+        compile_commands.cc
+        ctags.cc
+        dispatcher.cc
+        documentation_cppreference.cc
+        filesystem.cc
+        git.cc
+        menu.cc
+        project_build.cc
+        source.cc
+        source_base.cc
+        source_clang.cc
+        source_diff.cc
+        source_language_protocol.cc
+        source_spellcheck.cc
+        terminal.cc
+        usages_clang.cc
+        )
+if (LIBLLDB_FOUND)
+    list(APPEND JUCI_SHARED_FILES debug_lldb.cc)
+endif ()
 add_library(juci_shared STATIC ${JUCI_SHARED_FILES})
 target_link_libraries(juci_shared
-  ${GTKMM_LIBRARIES}
-  ${GTKSVMM_LIBRARIES}
-  ${Boost_LIBRARIES}
-  ${LIBLLDB_LIBRARIES}
-  ${ASPELL_LIBRARIES}
-  ${LIBGIT2_LIBRARIES}
-  clangmm
-  tiny-process-library
-)
+        ${GTKMM_LIBRARIES}
+        ${GTKSVMM_LIBRARIES}
+        ${Boost_LIBRARIES}
+        ${LIBLLDB_LIBRARIES}
+        ${ASPELL_LIBRARIES}
+        ${LIBGIT2_LIBRARIES}
+        clangmm
+        tiny-process-library
+        )
 
 add_executable(juci
-  config.cc
-  dialogs.cc
-  dialogs_unix.cc
-  directories.cc
-  entrybox.cc
-  info.cc
-  juci.cc
-  notebook.cc
-  project.cc
-  selection_dialog.cc
-  tooltips.cc
-  window.cc
-)
+        config.cc
+        dialogs.cc
+        dialogs_unix.cc
+        directories.cc
+        entrybox.cc
+        info.cc
+        juci.cc
+        notebook.cc
+        project.cc
+        selection_dialog.cc
+        tooltips.cc
+        window.cc
+        )
 target_link_libraries(juci juci_shared)
 
 install(TARGETS juci RUNTIME DESTINATION bin)
-if(${CMAKE_SYSTEM_NAME} MATCHES Linux|.*BSD|DragonFly)
-  install(FILES "${CMAKE_SOURCE_DIR}/share/juci.desktop"
-          DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
-  install(FILES "${CMAKE_SOURCE_DIR}/share/juci.svg"
-          DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps")
-elseif(APPLE)
-  install(CODE "execute_process(COMMAND /usr/bin/python ${CMAKE_SOURCE_DIR}/share/set_icon_macos.py ${CMAKE_SOURCE_DIR}/share/juci.png ${CMAKE_INSTALL_PREFIX}/bin/juci)")
-endif()
+if (${CMAKE_SYSTEM_NAME} MATCHES Linux|.*BSD|DragonFly)
+    install(FILES "${CMAKE_SOURCE_DIR}/share/juci.desktop"
+            DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
+    install(FILES "${CMAKE_SOURCE_DIR}/share/juci.svg"
+            DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps")
+elseif (APPLE)
+    install(CODE "execute_process(COMMAND /usr/bin/python ${CMAKE_SOURCE_DIR}/share/set_icon_macos.py ${CMAKE_SOURCE_DIR}/share/juci.png ${CMAKE_INSTALL_PREFIX}/bin/juci)")
+endif ()
 
 # add a target to generate API documentation with Doxygen
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules/")
 find_package(Plantuml)
 find_package(Doxygen)
-if(DOXYGEN_FOUND)
-  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
-  add_custom_target(doc
-    ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-    COMMENT "Generating API documentation with Doxygen to ${CMAKE_CURRENT_BINARY_DIR}" VERBATIM
-  )
-endif(DOXYGEN_FOUND)
+if (DOXYGEN_FOUND)
+    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
+    add_custom_target(doc
+            ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
+            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+            COMMENT "Generating API documentation with Doxygen to ${CMAKE_CURRENT_BINARY_DIR}" VERBATIM
+            )
+endif (DOXYGEN_FOUND)
diff --git a/src/autocomplete.cc b/src/autocomplete.cc
index 8d5b6848..374e25c7 100644
--- a/src/autocomplete.cc
+++ b/src/autocomplete.cc
@@ -2,178 +2,178 @@
 #include "selection_dialog.h"
 
 Autocomplete::Autocomplete(Gtk::TextView *view, bool &interactive_completion, guint &last_keyval, bool strip_word)
-    : view(view), interactive_completion(interactive_completion), strip_word(strip_word), state(State::IDLE) {
-  view->get_buffer()->signal_changed().connect([this, &last_keyval] {
-    if(CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
-      cancel_reparse();
-      return;
-    }
-    if(!this->view->has_focus())
-      return;
-    if(is_continue_key(last_keyval) && (this->interactive_completion || state != State::IDLE))
-      run();
-    else {
-      stop();
-
-      if(is_restart_key(last_keyval) && this->interactive_completion)
-        run();
-    }
-  });
-
-  view->get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-    if(mark->get_name() == "insert")
-      stop();
-  });
+        : view(view), interactive_completion(interactive_completion), strip_word(strip_word), state(State::IDLE) {
+    view->get_buffer()->signal_changed().connect([this, &last_keyval] {
+        if (CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
+            cancel_reparse();
+            return;
+        }
+        if (!this->view->has_focus())
+            return;
+        if (is_continue_key(last_keyval) && (this->interactive_completion || state != State::IDLE))
+            run();
+        else {
+            stop();
 
-  view->signal_key_release_event().connect([](GdkEventKey *key) {
-    if(CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
-      if(CompletionDialog::get()->on_key_release(key))
-        return true;
-    }
-    return false;
-  }, false);
+            if (is_restart_key(last_keyval) && this->interactive_completion)
+                run();
+        }
+    });
 
-  view->signal_focus_out_event().connect([this](GdkEventFocus *event) {
-    stop();
-    return false;
-  });
+    view->get_buffer()->signal_mark_set().connect(
+            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+                if (mark->get_name() == "insert")
+                    stop();
+            });
+
+    view->signal_key_release_event().connect([](GdkEventKey *key) {
+        if (CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
+            if (CompletionDialog::get()->on_key_release(key))
+                return true;
+        }
+        return false;
+    }, false);
+
+    view->signal_focus_out_event().connect([this](GdkEventFocus *event) {
+        stop();
+        return false;
+    });
 }
 
 void Autocomplete::run() {
-  if(run_check()) {
-    if(!is_processing())
-      return;
-
-    if(state == State::CANCELED)
-      state = State::RESTARTING;
-
-    if(state != State::IDLE)
-      return;
-
-    state = State::STARTING;
-
-    before_add_rows();
-
-    if(thread.joinable())
-      thread.join();
-    auto buffer = view->get_buffer()->get_text();
-    auto iter = view->get_buffer()->get_insert()->get_iter();
-    auto line_nr = iter.get_line() + 1;
-    auto column_nr = iter.get_line_index() + 1;
-    if(strip_word) {
-      auto pos = iter.get_offset() - 1;
-      while(pos >= 0 && ((buffer[pos] >= 'a' && buffer[pos] <= 'z') || (buffer[pos] >= 'A' && buffer[pos] <= 'Z') ||
-                         (buffer[pos] >= '0' && buffer[pos] <= '9') || buffer[pos] == '_')) {
-        buffer.replace(pos, 1, " ");
-        column_nr--;
-        pos--;
-      }
-    }
-    thread = std::thread([this, line_nr, column_nr, buffer = std::move(buffer)] {
-      auto lock = get_parse_lock();
-      if(!is_processing())
-        return;
-      stop_parse();
-
-      auto &buffer_raw = const_cast<std::string &>(buffer.raw());
-      rows.clear();
-      add_rows(buffer_raw, line_nr, column_nr);
-
-      if(is_processing()) {
-        dispatcher.post([this]() {
-          after_add_rows();
-          if(state == State::RESTARTING) {
-            state = State::IDLE;
-            reparse();
-            run();
-          }
-          else if(state == State::CANCELED || rows.empty()) {
-            state = State::IDLE;
-            reparse();
-          }
-          else {
-            auto start_iter = view->get_buffer()->get_insert()->get_iter();
-            if(prefix.size() > 0 && !start_iter.backward_chars(prefix.size())) {
-              state = State::IDLE;
-              reparse();
-              return;
+    if (run_check()) {
+        if (!is_processing())
+            return;
+
+        if (state == State::CANCELED)
+            state = State::RESTARTING;
+
+        if (state != State::IDLE)
+            return;
+
+        state = State::STARTING;
+
+        before_add_rows();
+
+        if (thread.joinable())
+            thread.join();
+        auto buffer = view->get_buffer()->get_text();
+        auto iter = view->get_buffer()->get_insert()->get_iter();
+        auto line_nr = iter.get_line() + 1;
+        auto column_nr = iter.get_line_index() + 1;
+        if (strip_word) {
+            auto pos = iter.get_offset() - 1;
+            while (pos >= 0 &&
+                   ((buffer[pos] >= 'a' && buffer[pos] <= 'z') || (buffer[pos] >= 'A' && buffer[pos] <= 'Z') ||
+                    (buffer[pos] >= '0' && buffer[pos] <= '9') || buffer[pos] == '_')) {
+                buffer.replace(pos, 1, " ");
+                column_nr--;
+                pos--;
             }
-            CompletionDialog::create(view, view->get_buffer()->create_mark(start_iter));
-            setup_dialog();
-            for(auto &row : rows) {
-              CompletionDialog::get()->add_row(row);
-              row.clear();
+        }
+        thread = std::thread([this, line_nr, column_nr, buffer = std::move(buffer)] {
+            auto lock = get_parse_lock();
+            if (!is_processing())
+                return;
+            stop_parse();
+
+            auto &buffer_raw = const_cast<std::string &>(buffer.raw());
+            rows.clear();
+            add_rows(buffer_raw, line_nr, column_nr);
+
+            if (is_processing()) {
+                dispatcher.post([this]() {
+                    after_add_rows();
+                    if (state == State::RESTARTING) {
+                        state = State::IDLE;
+                        reparse();
+                        run();
+                    } else if (state == State::CANCELED || rows.empty()) {
+                        state = State::IDLE;
+                        reparse();
+                    } else {
+                        auto start_iter = view->get_buffer()->get_insert()->get_iter();
+                        if (prefix.size() > 0 && !start_iter.backward_chars(prefix.size())) {
+                            state = State::IDLE;
+                            reparse();
+                            return;
+                        }
+                        CompletionDialog::create(view, view->get_buffer()->create_mark(start_iter));
+                        setup_dialog();
+                        for (auto &row : rows) {
+                            CompletionDialog::get()->add_row(row);
+                            row.clear();
+                        }
+                        state = State::IDLE;
+
+                        view->get_buffer()->begin_user_action();
+                        CompletionDialog::get()->show();
+                    }
+                });
+            } else {
+                dispatcher.post([this] {
+                    state = State::CANCELED;
+                    on_add_rows_error();
+                });
             }
-            state = State::IDLE;
-
-            view->get_buffer()->begin_user_action();
-            CompletionDialog::get()->show();
-          }
         });
-      }
-      else {
-        dispatcher.post([this] {
-          state = State::CANCELED;
-          on_add_rows_error();
-        });
-      }
-    });
-  }
+    }
 
-  if(state != State::IDLE)
-    cancel_reparse();
+    if (state != State::IDLE)
+        cancel_reparse();
 }
 
 void Autocomplete::stop() {
-  if(state == State::STARTING || state == State::RESTARTING)
-    state = State::CANCELED;
+    if (state == State::STARTING || state == State::RESTARTING)
+        state = State::CANCELED;
 }
 
 void Autocomplete::setup_dialog() {
-  CompletionDialog::get()->on_show=[this] {
-    on_show();
-  };
-  
-  CompletionDialog::get()->on_hide = [this]() {
-    view->get_buffer()->end_user_action();
-    tooltips.hide();
-    tooltips.clear();
-    on_hide();
-    reparse();
-  };
-  
-  CompletionDialog::get()->on_changed = [this](unsigned int index, const std::string &text) {
-    if(index >= rows.size()) {
-      tooltips.hide();
-      return;
-    }
-    
-    on_changed(index, text);
-    
-    auto tooltip = get_tooltip(index);
-    if(tooltip.empty())
-      tooltips.hide();
-    else {
-      tooltips.clear();
-      auto create_tooltip_buffer = [ this, tooltip = std::move(tooltip) ]() {
-        auto tooltip_buffer = Gtk::TextBuffer::create(view->get_buffer()->get_tag_table());
-  
-        tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), tooltip);
-  
-        return tooltip_buffer;
-      };
-  
-      auto iter = CompletionDialog::get()->start_mark->get_iter();
-      tooltips.emplace_back(create_tooltip_buffer, view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter));
-  
-      tooltips.show(true);
-    }
-  };
-  
-  CompletionDialog::get()->on_select=[this](unsigned int index, const std::string &text, bool hide_window) {
-    if(index>=rows.size())
-      return;
-    
-    on_select(index, text, hide_window);
-  };
+    CompletionDialog::get()->on_show = [this] {
+        on_show();
+    };
+
+    CompletionDialog::get()->on_hide = [this]() {
+        view->get_buffer()->end_user_action();
+        tooltips.hide();
+        tooltips.clear();
+        on_hide();
+        reparse();
+    };
+
+    CompletionDialog::get()->on_changed = [this](unsigned int index, const std::string &text) {
+        if (index >= rows.size()) {
+            tooltips.hide();
+            return;
+        }
+
+        on_changed(index, text);
+
+        auto tooltip = get_tooltip(index);
+        if (tooltip.empty())
+            tooltips.hide();
+        else {
+            tooltips.clear();
+            auto create_tooltip_buffer = [this, tooltip = std::move(tooltip)]() {
+                auto tooltip_buffer = Gtk::TextBuffer::create(view->get_buffer()->get_tag_table());
+
+                tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), tooltip);
+
+                return tooltip_buffer;
+            };
+
+            auto iter = CompletionDialog::get()->start_mark->get_iter();
+            tooltips.emplace_back(create_tooltip_buffer, view, view->get_buffer()->create_mark(iter),
+                                  view->get_buffer()->create_mark(iter));
+
+            tooltips.show(true);
+        }
+    };
+
+    CompletionDialog::get()->on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
+        if (index >= rows.size())
+            return;
+
+        on_select(index, text, hide_window);
+    };
 }
diff --git a/src/autocomplete.h b/src/autocomplete.h
index 1d5939bc..b808ca04 100644
--- a/src/autocomplete.h
+++ b/src/autocomplete.h
@@ -1,58 +1,65 @@
 #pragma once
+
 #include "dispatcher.h"
 #include "tooltips.h"
 #include <atomic>
 #include <thread>
 
 class Autocomplete {
-  Gtk::TextView *view;
-  bool &interactive_completion;
-  /// Some libraries/utilities, like libclang, require that autocomplete is started at the beginning of a word
-  bool strip_word;
+    Gtk::TextView *view;
+    bool &interactive_completion;
+    /// Some libraries/utilities, like libclang, require that autocomplete is started at the beginning of a word
+    bool strip_word;
 
-  Dispatcher dispatcher;
+    Dispatcher dispatcher;
 
 public:
-  enum class State { IDLE, STARTING, RESTARTING, CANCELED };
-
-  std::string prefix;
-  std::mutex prefix_mutex;
-  std::vector<std::string> rows;
-  Tooltips tooltips;
-
-  std::atomic<State> state;
-
-  std::thread thread;
-
-  std::function<bool()> is_processing = [] { return true; };
-  std::function<void()> reparse = [] {};
-  std::function<void()> cancel_reparse = [] {};
-  std::function<std::unique_ptr<std::lock_guard<std::mutex>>()> get_parse_lock = [] { return nullptr; };
-  std::function<void()> stop_parse = [] {};
-
-  std::function<bool(guint last_keyval)> is_continue_key = [](guint) { return false; };
-  std::function<bool(guint last_keyval)> is_restart_key = [](guint) { return false; };
-  std::function<bool()> run_check = [] { return false; };
-
-  std::function<void()> before_add_rows = [] {};
-  std::function<void()> after_add_rows = [] {};
-  std::function<void()> on_add_rows_error = [] {};
-
-  /// The handler is not run in the main loop.
-  std::function<void(std::string &buffer, int line_number, int column)> add_rows = [](std::string &, int, int) {};
-  
-  std::function<void()> on_show = [] {};
-  std::function<void()> on_hide = [] {};
-  std::function<void(unsigned int, const std::string &)> on_changed = [](unsigned int index, const std::string &text) {};
-  std::function<void(unsigned int, const std::string &, bool)> on_select = [](unsigned int index, const std::string &text, bool hide_window) {};
-  
-  std::function<std::string(unsigned int)> get_tooltip = [](unsigned int index) {return std::string();};
-
-  Autocomplete(Gtk::TextView *view, bool &interactive_completion, guint &last_keyval, bool strip_word);
-
-  void run();
-  void stop();
-  
+    enum class State {
+        IDLE, STARTING, RESTARTING, CANCELED
+    };
+
+    std::string prefix;
+    std::mutex prefix_mutex;
+    std::vector<std::string> rows;
+    Tooltips tooltips;
+
+    std::atomic<State> state;
+
+    std::thread thread;
+
+    std::function<bool()> is_processing = [] { return true; };
+    std::function<void()> reparse = [] {};
+    std::function<void()> cancel_reparse = [] {};
+    std::function<std::unique_ptr<std::lock_guard<std::mutex>>()> get_parse_lock = [] { return nullptr; };
+    std::function<void()> stop_parse = [] {};
+
+    std::function<bool(guint last_keyval)> is_continue_key = [](guint) { return false; };
+    std::function<bool(guint last_keyval)> is_restart_key = [](guint) { return false; };
+    std::function<bool()> run_check = [] { return false; };
+
+    std::function<void()> before_add_rows = [] {};
+    std::function<void()> after_add_rows = [] {};
+    std::function<void()> on_add_rows_error = [] {};
+
+    /// The handler is not run in the main loop.
+    std::function<void(std::string &buffer, int line_number, int column)> add_rows = [](std::string &, int, int) {};
+
+    std::function<void()> on_show = [] {};
+    std::function<void()> on_hide = [] {};
+    std::function<void(unsigned int, const std::string &)> on_changed = [](unsigned int index,
+                                                                           const std::string &text) {};
+    std::function<void(unsigned int, const std::string &, bool)> on_select = [](unsigned int index,
+                                                                                const std::string &text,
+                                                                                bool hide_window) {};
+
+    std::function<std::string(unsigned int)> get_tooltip = [](unsigned int index) { return std::string(); };
+
+    Autocomplete(Gtk::TextView *view, bool &interactive_completion, guint &last_keyval, bool strip_word);
+
+    void run();
+
+    void stop();
+
 private:
-  void setup_dialog();
+    void setup_dialog();
 };
diff --git a/src/buildsystem/buildsystem.h b/src/buildsystem/buildsystem.h
new file mode 100644
index 00000000..d384bec2
--- /dev/null
+++ b/src/buildsystem/buildsystem.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <boost/filesystem.hpp>
+#include <vector>
+
+class BuildSystemBase {
+public:
+    auto get_project_path() const { return project_path; }
+    void set_project_path(const boost::filesystem::path& rhs) { project_path = rhs; }
+
+    virtual bool update_default_build(const boost::filesystem::path &default_build_path, bool force = false);
+
+    virtual bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force = false);
+
+    virtual boost::filesystem::path
+    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
+
+private:
+    boost::filesystem::path project_path;
+};
diff --git a/src/buildsystem/cmake.cc b/src/buildsystem/cmake.cc
new file mode 100644
index 00000000..c656c536
--- /dev/null
+++ b/src/buildsystem/cmake.cc
@@ -0,0 +1,386 @@
+#include "cmake.h"
+#include "../filesystem.h"
+#include "../dialogs.h"
+#include "../config.h"
+#include "../terminal.h"
+#include <regex>
+#include "../compile_commands.h"
+
+CMake::CMake(const boost::filesystem::path &path) {
+    const auto find_cmake_project = [](const boost::filesystem::path &cmake_path) {
+        for (auto &line: filesystem::read_lines(cmake_path)) {
+            const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
+            std::smatch sm;
+            if (std::regex_match(line, sm, project_regex))
+                return true;
+        }
+        return false;
+    };
+
+    auto search_path = boost::filesystem::is_directory(path) ? path : path.parent_path();
+    while (true) {
+        auto search_cmake_path = search_path / "CMakeLists.txt";
+        if (boost::filesystem::exists(search_cmake_path)) {
+            paths.emplace(paths.begin(), search_cmake_path);
+            if (find_cmake_project(search_cmake_path)) {
+                set_project_path(search_path);
+                break;
+            }
+        }
+        if (search_path == search_path.root_directory())
+            break;
+        search_path = search_path.parent_path();
+    }
+}
+
+bool CMake::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
+    if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "CMakeLists.txt") ||
+        default_build_path.empty())
+        return false;
+
+    if (!boost::filesystem::exists(default_build_path)) {
+        boost::system::error_code ec;
+        boost::filesystem::create_directories(default_build_path, ec);
+        if (ec) {
+            Terminal::get().print("Error: could not create " + default_build_path.string() + ": " + ec.message() + "\n",
+                                  true);
+            return false;
+        }
+    }
+
+    if (!force && boost::filesystem::exists(default_build_path / "compile_commands.json"))
+        return true;
+
+    auto compile_commands_path = default_build_path / "compile_commands.json";
+    Dialog::Message message("Creating/updating default build");
+    auto exit_status = Terminal::get().process(Config::get().project.cmake.command + ' ' +
+                                               filesystem::escape_argument(get_project_path().string()) +
+                                               " -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path);
+    message.hide();
+    if (exit_status == EXIT_SUCCESS) {
+#ifdef _WIN32 //Temporary fix to MSYS2's libclang
+        auto compile_commands_file = filesystem::read(compile_commands_path);
+        auto replace_drive = [&compile_commands_file](const std::string &param) {
+            size_t pos = 0;
+            auto param_size = param.length();
+            while ((pos = compile_commands_file.find(param + "/", pos)) != std::string::npos) {
+                if (pos + param_size + 1 < compile_commands_file.size())
+                    compile_commands_file.replace(pos, param_size + 2,
+                                                  param + compile_commands_file[pos + param_size + 1] + ":");
+                else
+                    break;
+            }
+        };
+        replace_drive("-I");
+        replace_drive("-isystem ");
+        filesystem::write(compile_commands_path, compile_commands_file);
+#endif
+        return true;
+    }
+    return false;
+}
+
+bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
+    if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "CMakeLists.txt") || debug_build_path.empty())
+        return false;
+
+    if (!boost::filesystem::exists(debug_build_path)) {
+        boost::system::error_code ec;
+        boost::filesystem::create_directories(debug_build_path, ec);
+        if (ec) {
+            Terminal::get().print("Error: could not create " + debug_build_path.string() + ": " + ec.message() + "\n",
+                                  true);
+            return false;
+        }
+    }
+
+    if (!force && boost::filesystem::exists(debug_build_path / "CMakeCache.txt"))
+        return true;
+
+    Dialog::Message message("Creating/updating debug build");
+    auto exit_status = Terminal::get().process(Config::get().project.cmake.command + ' ' +
+                                               filesystem::escape_argument(get_project_path().string()) +
+                                               " -DCMAKE_BUILD_TYPE=Debug", debug_build_path);
+    message.hide();
+    if (exit_status == EXIT_SUCCESS)
+        return true;
+    return false;
+}
+
+boost::filesystem::path
+CMake::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
+    // CMake does not store in compile_commands.json if an object is part of an executable or not.
+    // Therefore, executables are first attempted found in the cmake files. These executables
+    // are then used to identify if a file in compile_commands.json is part of an executable or not
+
+    auto parameters = get_functions_parameters("add_executable");
+
+    std::vector<boost::filesystem::path> cmake_executables;
+    for (auto &parameter: parameters) {
+        if (parameter.second.size() > 1 && parameter.second[0].size() > 0 &&
+            parameter.second[0].compare(0, 2, "${") != 0) {
+            auto executable = (parameter.first.parent_path() / parameter.second[0]).string();
+            auto project_path_str = get_project_path().string();
+            size_t pos = executable.find(project_path_str);
+            if (pos != std::string::npos)
+                executable.replace(pos, project_path_str.size(), build_path.string());
+            cmake_executables.emplace_back(executable);
+        }
+    }
+
+
+    CompileCommands compile_commands(build_path);
+    std::vector<std::pair<boost::filesystem::path, boost::filesystem::path>> command_files_and_maybe_executables;
+    for (auto &command: compile_commands.commands) {
+        auto command_file = filesystem::get_normal_path(command.file);
+        auto values = command.parameter_values("-o");
+        if (!values.empty()) {
+            size_t pos;
+            values[0].erase(0, 11);
+            if ((pos = values[0].find(".dir")) != std::string::npos) {
+                auto executable = command.directory / values[0].substr(0, pos);
+                command_files_and_maybe_executables.emplace_back(command_file, executable);
+            }
+        }
+    }
+
+    size_t best_match_size = -1;
+    boost::filesystem::path best_match_executable;
+
+    for (auto &cmake_executable: cmake_executables) {
+        for (auto &command_file_and_maybe_executable: command_files_and_maybe_executables) {
+            auto &command_file = command_file_and_maybe_executable.first;
+            auto &maybe_executable = command_file_and_maybe_executable.second;
+            if (cmake_executable == maybe_executable) {
+                if (command_file == file_path)
+                    return maybe_executable;
+                auto command_file_directory = command_file.parent_path();
+                if (filesystem::file_in_path(file_path, command_file_directory)) {
+                    auto size = static_cast<size_t>(std::distance(command_file_directory.begin(),
+                                                                  command_file_directory.end()));
+                    if (best_match_size == static_cast<size_t>(-1) || best_match_size < size) {
+                        best_match_size = size;
+                        best_match_executable = maybe_executable;
+                    }
+                }
+            }
+        }
+    }
+    if (!best_match_executable.empty())
+        return best_match_executable;
+
+    for (auto &command_file_and_maybe_executable: command_files_and_maybe_executables) {
+        auto &command_file = command_file_and_maybe_executable.first;
+        auto &maybe_executable = command_file_and_maybe_executable.second;
+        if (command_file == file_path)
+            return maybe_executable;
+        auto command_file_directory = command_file.parent_path();
+        if (filesystem::file_in_path(file_path, command_file_directory)) {
+            auto size = static_cast<size_t>(std::distance(command_file_directory.begin(),
+                                                          command_file_directory.end()));
+            if (best_match_size == static_cast<size_t>(-1) || best_match_size < size) {
+                best_match_size = size;
+                best_match_executable = maybe_executable;
+            }
+        }
+    }
+    return best_match_executable;
+}
+
+void CMake::read_files() {
+    for (auto &path: paths)
+        files.emplace_back(filesystem::read(path));
+}
+
+void CMake::remove_tabs() {
+    for (auto &file: files) {
+        for (auto &chr: file) {
+            if (chr == '\t')
+                chr = ' ';
+        }
+    }
+}
+
+void CMake::remove_comments() {
+    for (auto &file: files) {
+        size_t pos = 0;
+        size_t comment_start;
+        bool inside_comment = false;
+        while (pos < file.size()) {
+            if (!inside_comment && file[pos] == '#') {
+                comment_start = pos;
+                inside_comment = true;
+            }
+            if (inside_comment && file[pos] == '\n') {
+                file.erase(comment_start, pos - comment_start);
+                pos -= pos - comment_start;
+                inside_comment = false;
+            }
+            pos++;
+        }
+        if (inside_comment)
+            file.erase(comment_start);
+    }
+}
+
+void CMake::remove_newlines_inside_parentheses() {
+    for (auto &file: files) {
+        size_t pos = 0;
+        bool inside_para = false;
+        bool inside_quote = false;
+        char last_char = 0;
+        while (pos < file.size()) {
+            if (!inside_quote && file[pos] == '"' && last_char != '\\')
+                inside_quote = true;
+            else if (inside_quote && file[pos] == '"' && last_char != '\\')
+                inside_quote = false;
+
+            else if (!inside_quote && file[pos] == '(')
+                inside_para = true;
+            else if (!inside_quote && file[pos] == ')')
+                inside_para = false;
+
+            else if (inside_para && file[pos] == '\n')
+                file.replace(pos, 1, 1, ' ');
+            last_char = file[pos];
+            pos++;
+        }
+    }
+}
+
+void CMake::parse_variable_parameters(std::string &data) {
+    size_t pos = 0;
+    bool inside_quote = false;
+    char last_char = 0;
+    while (pos < data.size()) {
+        if (!inside_quote && data[pos] == '"' && last_char != '\\') {
+            inside_quote = true;
+            data.erase(pos,
+                       1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
+            pos--;
+        } else if (inside_quote && data[pos] == '"' && last_char != '\\') {
+            inside_quote = false;
+            data.erase(pos,
+                       1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
+            pos--;
+        } else if (!inside_quote && data[pos] == ' ' && pos + 1 < data.size() && data[pos + 1] == ' ') {
+            data.erase(pos, 1);
+            pos--;
+        }
+
+        if (pos != static_cast<size_t>(-1))
+            last_char = data[pos];
+        pos++;
+    }
+    for (auto &var: variables) {
+        auto pos = data.find("${" + var.first + '}');
+        while (pos != std::string::npos) {
+            data.replace(pos, var.first.size() + 3, var.second);
+            pos = data.find("${" + var.first + '}');
+        }
+    }
+
+    //Remove variables we do not know:
+    pos = data.find("${");
+    auto pos_end = data.find("}", pos + 2);
+    while (pos != std::string::npos && pos_end != std::string::npos) {
+        data.erase(pos, pos_end - pos + 1);
+        pos = data.find("${");
+        pos_end = data.find("}", pos + 2);
+    }
+}
+
+void CMake::parse() {
+    read_files();
+    remove_tabs();
+    remove_comments();
+    remove_newlines_inside_parentheses();
+    parsed = true;
+}
+
+std::vector<std::string> CMake::get_function_parameters(std::string &data) {
+    std::vector<std::string> parameters;
+    size_t pos = 0;
+    size_t parameter_pos = 0;
+    bool inside_quote = false;
+    char last_char = 0;
+    while (pos < data.size()) {
+        if (!inside_quote && data[pos] == '"' && last_char != '\\') {
+            inside_quote = true;
+            data.erase(pos, 1);
+            pos--;
+        } else if (inside_quote && data[pos] == '"' && last_char != '\\') {
+            inside_quote = false;
+            data.erase(pos, 1);
+            pos--;
+        } else if (!inside_quote && pos + 1 < data.size() && data[pos] == ' ' && data[pos + 1] == ' ') {
+            data.erase(pos, 1);
+            pos--;
+        } else if (!inside_quote && data[pos] == ' ') {
+            parameters.emplace_back(data.substr(parameter_pos, pos - parameter_pos));
+            if (pos + 1 < data.size())
+                parameter_pos = pos + 1;
+        }
+
+        if (pos != static_cast<size_t>(-1))
+            last_char = data[pos];
+        pos++;
+    }
+    parameters.emplace_back(data.substr(parameter_pos));
+    for (auto &var: variables) {
+        for (auto &parameter: parameters) {
+            auto pos = parameter.find("${" + var.first + '}');
+            while (pos != std::string::npos) {
+                parameter.replace(pos, var.first.size() + 3, var.second);
+                pos = parameter.find("${" + var.first + '}');
+            }
+        }
+    }
+    return parameters;
+}
+
+std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > >
+CMake::get_functions_parameters(const std::string &name) {
+    const std::regex function_regex("^ *" + name + " *\\( *(.*)\\) *\\r?$", std::regex::icase);
+    variables.clear();
+    if (!parsed)
+        parse();
+    std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > > functions;
+    for (size_t c = 0; c < files.size(); ++c) {
+        size_t pos = 0;
+        while (pos < files[c].size()) {
+            auto start_line = pos;
+            auto end_line = files[c].find('\n', start_line);
+            if (end_line == std::string::npos)
+                end_line = files[c].size();
+            if (end_line > start_line) {
+                auto line = files[c].substr(start_line, end_line - start_line);
+                std::smatch sm;
+                const static std::regex set_regex("^ *set *\\( *([A-Za-z_][A-Za-z_0-9]*) +(.*)\\) *\\r?$",
+                                                  std::regex::icase);
+                const static std::regex project_regex("^ *project *\\( *([^ ]+).*\\) *\\r?$", std::regex::icase);
+                if (std::regex_match(line, sm, set_regex)) {
+                    auto data = sm[2].str();
+                    while (data.size() > 0 && data.back() == ' ')
+                        data.pop_back();
+                    parse_variable_parameters(data);
+                    variables[sm[1].str()] = data;
+                } else if (std::regex_match(line, sm, project_regex)) {
+                    auto data = sm[1].str();
+                    parse_variable_parameters(data);
+                    variables["CMAKE_PROJECT_NAME"] = data; //TODO: is this variable deprecated/non-standard?
+                    variables["PROJECT_NAME"] = data;
+                }
+                if (std::regex_match(line, sm, function_regex)) {
+                    auto data = sm[1].str();
+                    while (data.size() > 0 && data.back() == ' ')
+                        data.pop_back();
+                    auto parameters = get_function_parameters(data);
+                    functions.emplace_back(paths[c], parameters);
+                }
+            }
+            pos = end_line + 1;
+        }
+    }
+    return functions;
+}
diff --git a/src/buildsystem/cmake.h b/src/buildsystem/cmake.h
new file mode 100644
index 00000000..9ea4c41b
--- /dev/null
+++ b/src/buildsystem/cmake.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "buildsystem.h"
+#include <unordered_map>
+#include <unordered_set>
+
+class CMake : public BuildSystemBase {
+public:
+    CMake(const boost::filesystem::path &path);
+
+    bool update_default_build(const boost::filesystem::path &default_build_path, bool force = false) override;
+
+    bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force = false) override;
+
+    boost::filesystem::path
+    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
+
+private:
+    std::vector<boost::filesystem::path> paths;
+    std::vector<std::string> files;
+    std::unordered_map<std::string, std::string> variables;
+
+    void read_files();
+
+    void remove_tabs();
+
+    void remove_comments();
+
+    void remove_newlines_inside_parentheses();
+
+    void parse_variable_parameters(std::string &data);
+
+    void parse();
+
+    std::vector<std::string> get_function_parameters(std::string &data);
+
+    std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > >
+    get_functions_parameters(const std::string &name);
+
+    bool parsed = false;
+};
diff --git a/src/buildsystem/meson.cc b/src/buildsystem/meson.cc
new file mode 100644
index 00000000..9b2b994c
--- /dev/null
+++ b/src/buildsystem/meson.cc
@@ -0,0 +1,123 @@
+#include "meson.h"
+#include "../filesystem.h"
+#include "../compile_commands.h"
+#include <regex>
+#include "../terminal.h"
+#include "../dialogs.h"
+#include "../config.h"
+
+Meson::Meson(const boost::filesystem::path &path) {
+    const auto find_project = [](const boost::filesystem::path &file_path) {
+        for (auto &line: filesystem::read_lines(file_path)) {
+            const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
+            std::smatch sm;
+            if (std::regex_match(line, sm, project_regex))
+                return true;
+        }
+        return false;
+    };
+
+    auto search_path = boost::filesystem::is_directory(path) ? path : path.parent_path();
+    while (true) {
+        auto search_file = search_path / "meson.build";
+        if (boost::filesystem::exists(search_file)) {
+            if (find_project(search_file)) {
+                project_path = search_path;
+                break;
+            }
+        }
+        if (search_path == search_path.root_directory())
+            break;
+        search_path = search_path.parent_path();
+    }
+}
+
+bool Meson::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
+    if (project_path.empty() || !boost::filesystem::exists(project_path / "meson.build") || default_build_path.empty())
+        return false;
+
+    if (!boost::filesystem::exists(default_build_path)) {
+        boost::system::error_code ec;
+        boost::filesystem::create_directories(default_build_path, ec);
+        if (ec) {
+            Terminal::get().print("Error: could not create " + default_build_path.string() + ": " + ec.message() + "\n",
+                                  true);
+            return false;
+        }
+    }
+
+    auto compile_commands_path = default_build_path / "compile_commands.json";
+    bool compile_commands_exists = boost::filesystem::exists(compile_commands_path);
+    if (!force && compile_commands_exists)
+        return true;
+
+    Dialog::Message message("Creating/updating default build");
+    auto exit_status = Terminal::get().process(
+            Config::get().project.meson.command + ' ' + (compile_commands_exists ? "--internal regenerate " : "") +
+            filesystem::escape_argument(project_path.string()), default_build_path);
+    message.hide();
+    if (exit_status == EXIT_SUCCESS)
+        return true;
+    return false;
+}
+
+bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
+    if (project_path.empty() || !boost::filesystem::exists(project_path / "meson.build") || debug_build_path.empty())
+        return false;
+
+    if (!boost::filesystem::exists(debug_build_path)) {
+        boost::system::error_code ec;
+        boost::filesystem::create_directories(debug_build_path, ec);
+        if (ec) {
+            Terminal::get().print("Error: could not create " + debug_build_path.string() + ": " + ec.message() + "\n",
+                                  true);
+            return false;
+        }
+    }
+
+    bool compile_commands_exists = boost::filesystem::exists(debug_build_path / "compile_commands.json");
+    if (!force && compile_commands_exists)
+        return true;
+
+    Dialog::Message message("Creating/updating debug build");
+    auto exit_status = Terminal::get().process(
+            Config::get().project.meson.command + ' ' + (compile_commands_exists ? "--internal regenerate " : "") +
+            "--buildtype debug " + filesystem::escape_argument(project_path.string()), debug_build_path);
+    message.hide();
+    if (exit_status == EXIT_SUCCESS)
+        return true;
+    return false;
+}
+
+boost::filesystem::path
+Meson::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
+    CompileCommands compile_commands(build_path);
+
+    size_t best_match_size = -1;
+    boost::filesystem::path best_match_executable;
+    for (auto &command: compile_commands.commands) {
+        auto command_file = filesystem::get_normal_path(command.file);
+        auto values = command.parameter_values("-o");
+        if (!values.empty()) {
+            size_t pos;
+            if ((pos = values[0].find("@")) != std::string::npos) {
+                if (pos + 1 < values[0].size() && values[0].compare(pos + 1, 3, "exe") == 0) {
+                    auto executable = build_path / values[0].substr(0, pos);
+                    if (command_file == file_path)
+                        return executable;
+                    auto command_file_directory = command_file.parent_path();
+                    if (filesystem::file_in_path(file_path, command_file_directory)) {
+                        auto size = static_cast<size_t>(std::distance(command_file_directory.begin(),
+                                                                      command_file_directory.end()));
+                        if (best_match_size == static_cast<size_t>(-1) || best_match_size < size) {
+                            best_match_size = size;
+                            best_match_executable = executable;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return best_match_executable;
+}
diff --git a/src/buildsystem/meson.h b/src/buildsystem/meson.h
new file mode 100644
index 00000000..17b9a540
--- /dev/null
+++ b/src/buildsystem/meson.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <boost/filesystem.hpp>
+#include <vector>
+
+class Meson {
+public:
+    Meson(const boost::filesystem::path &path);
+
+    boost::filesystem::path project_path;
+
+    bool update_default_build(const boost::filesystem::path &default_build_path, bool force = false);
+
+    bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force = false);
+
+    boost::filesystem::path
+    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
+};
diff --git a/src/cmake.cc b/src/cmake.cc
deleted file mode 100644
index f3945acb..00000000
--- a/src/cmake.cc
+++ /dev/null
@@ -1,378 +0,0 @@
-#include "cmake.h"
-#include "filesystem.h"
-#include "dialogs.h"
-#include "config.h"
-#include "terminal.h"
-#include <regex>
-#include "compile_commands.h"
-
-CMake::CMake(const boost::filesystem::path &path) {
-  const auto find_cmake_project=[](const boost::filesystem::path &cmake_path) {
-    for(auto &line: filesystem::read_lines(cmake_path)) {
-      const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
-      std::smatch sm;
-      if(std::regex_match(line, sm, project_regex))
-        return true;
-    }
-    return false;
-  };
-  
-  auto search_path=boost::filesystem::is_directory(path)?path:path.parent_path();
-  while(true) {
-    auto search_cmake_path=search_path/"CMakeLists.txt";
-    if(boost::filesystem::exists(search_cmake_path)) {
-      paths.emplace(paths.begin(), search_cmake_path);
-      if(find_cmake_project(search_cmake_path)) {
-        project_path=search_path;
-        break;
-      }
-    }
-    if(search_path==search_path.root_directory())
-      break;
-    search_path=search_path.parent_path();
-  }
-}
-
-bool CMake::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
-  if(project_path.empty() || !boost::filesystem::exists(project_path/"CMakeLists.txt") || default_build_path.empty())
-    return false;
-  
-  if(!boost::filesystem::exists(default_build_path)) {
-    boost::system::error_code ec;
-    boost::filesystem::create_directories(default_build_path, ec);
-    if(ec) {
-      Terminal::get().print("Error: could not create "+default_build_path.string()+": "+ec.message()+"\n", true);
-      return false;
-    }
-  }
-  
-  if(!force && boost::filesystem::exists(default_build_path/"compile_commands.json"))
-    return true;
-  
-  auto compile_commands_path=default_build_path/"compile_commands.json";
-  Dialog::Message message("Creating/updating default build");
-  auto exit_status=Terminal::get().process(Config::get().project.cmake.command+' '+
-                                           filesystem::escape_argument(project_path.string())+" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path);
-  message.hide();
-  if(exit_status==EXIT_SUCCESS) {
-#ifdef _WIN32 //Temporary fix to MSYS2's libclang
-    auto compile_commands_file=filesystem::read(compile_commands_path);
-    auto replace_drive = [&compile_commands_file](const std::string& param) {
-      size_t pos=0;
-      auto param_size = param.length();
-      while((pos=compile_commands_file.find(param+"/", pos))!=std::string::npos) {
-        if(pos+param_size+1<compile_commands_file.size())
-          compile_commands_file.replace(pos, param_size+2, param+compile_commands_file[pos+param_size+1]+":");
-        else
-          break;
-      }
-    };
-    replace_drive("-I");
-    replace_drive("-isystem ");
-    filesystem::write(compile_commands_path, compile_commands_file);
-#endif
-    return true;
-  }
-  return false;
-}
-
-bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-  if(project_path.empty() || !boost::filesystem::exists(project_path/"CMakeLists.txt") || debug_build_path.empty())
-    return false;
-  
-  if(!boost::filesystem::exists(debug_build_path)) {
-    boost::system::error_code ec;
-    boost::filesystem::create_directories(debug_build_path, ec);
-    if(ec) {
-      Terminal::get().print("Error: could not create "+debug_build_path.string()+": "+ec.message()+"\n", true);
-      return false;
-    }
-  }
-  
-  if(!force && boost::filesystem::exists(debug_build_path/"CMakeCache.txt"))
-    return true;
-  
-  Dialog::Message message("Creating/updating debug build");
-  auto exit_status=Terminal::get().process(Config::get().project.cmake.command+' '+
-                                           filesystem::escape_argument(project_path.string())+" -DCMAKE_BUILD_TYPE=Debug", debug_build_path);
-  message.hide();
-  if(exit_status==EXIT_SUCCESS)
-    return true;
-  return false;
-}
-
-boost::filesystem::path CMake::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
-  // CMake does not store in compile_commands.json if an object is part of an executable or not.
-  // Therefore, executables are first attempted found in the cmake files. These executables
-  // are then used to identify if a file in compile_commands.json is part of an executable or not
-  
-  auto parameters = get_functions_parameters("add_executable");
-  
-  std::vector<boost::filesystem::path> cmake_executables;
-  for(auto &parameter: parameters) {
-    if(parameter.second.size()>1 && parameter.second[0].size()>0 && parameter.second[0].compare(0, 2, "${")!=0) {
-      auto executable=(parameter.first.parent_path()/parameter.second[0]).string();
-      auto project_path_str=project_path.string();
-      size_t pos=executable.find(project_path_str);
-      if(pos!=std::string::npos)
-        executable.replace(pos, project_path_str.size(), build_path.string());
-      cmake_executables.emplace_back(executable);
-    }
-  }
-  
-  
-  CompileCommands compile_commands(build_path);
-  std::vector<std::pair<boost::filesystem::path, boost::filesystem::path>> command_files_and_maybe_executables;
-  for(auto &command: compile_commands.commands) {
-    auto command_file=filesystem::get_normal_path(command.file);
-    auto values=command.parameter_values("-o");
-    if(!values.empty()) {
-      size_t pos;
-      values[0].erase(0, 11);
-      if((pos=values[0].find(".dir"))!=std::string::npos) {
-        auto executable=command.directory/values[0].substr(0, pos);
-        command_files_and_maybe_executables.emplace_back(command_file, executable);
-      }
-    }
-  }
-  
-  size_t best_match_size=-1;
-  boost::filesystem::path best_match_executable;
-  
-  for(auto &cmake_executable: cmake_executables) {
-    for(auto &command_file_and_maybe_executable: command_files_and_maybe_executables) {
-      auto &command_file=command_file_and_maybe_executable.first;
-      auto &maybe_executable=command_file_and_maybe_executable.second;
-      if(cmake_executable==maybe_executable) {
-        if(command_file==file_path)
-          return maybe_executable;
-        auto command_file_directory=command_file.parent_path();
-        if(filesystem::file_in_path(file_path, command_file_directory)) {
-          auto size=static_cast<size_t>(std::distance(command_file_directory.begin(), command_file_directory.end()));
-          if(best_match_size==static_cast<size_t>(-1) || best_match_size<size) {
-            best_match_size=size;
-            best_match_executable=maybe_executable;
-          }
-        }
-      }
-    }
-  }
-  if(!best_match_executable.empty())
-    return best_match_executable;
-  
-  for(auto &command_file_and_maybe_executable: command_files_and_maybe_executables) {
-    auto &command_file=command_file_and_maybe_executable.first;
-    auto &maybe_executable=command_file_and_maybe_executable.second;
-    if(command_file==file_path)
-      return maybe_executable;
-    auto command_file_directory=command_file.parent_path();
-    if(filesystem::file_in_path(file_path, command_file_directory)) {
-      auto size=static_cast<size_t>(std::distance(command_file_directory.begin(), command_file_directory.end()));
-      if(best_match_size==static_cast<size_t>(-1) || best_match_size<size) {
-        best_match_size=size;
-        best_match_executable=maybe_executable;
-      }
-    }
-  }
-  return best_match_executable;
-}
-
-void CMake::read_files() {
-  for(auto &path: paths)
-    files.emplace_back(filesystem::read(path));
-}
-
-void CMake::remove_tabs() {
-  for(auto &file: files) {
-    for(auto &chr: file) {
-      if(chr=='\t')
-        chr=' ';
-    }
-  }
-}
-
-void CMake::remove_comments() {
-  for(auto &file: files) {
-    size_t pos=0;
-    size_t comment_start;
-    bool inside_comment=false;
-    while(pos<file.size()) {
-      if(!inside_comment && file[pos]=='#') {
-        comment_start=pos;
-        inside_comment=true;
-      }
-      if(inside_comment && file[pos]=='\n') {
-        file.erase(comment_start, pos-comment_start);
-        pos-=pos-comment_start;
-        inside_comment=false;
-      }
-      pos++;
-    }
-    if(inside_comment)
-      file.erase(comment_start);
-  }
-}
-
-void CMake::remove_newlines_inside_parentheses() {
-  for(auto &file: files) {
-    size_t pos=0;
-    bool inside_para=false;
-    bool inside_quote=false;
-    char last_char=0;
-    while(pos<file.size()) {
-      if(!inside_quote && file[pos]=='"' && last_char!='\\')
-        inside_quote=true;
-      else if(inside_quote && file[pos]=='"' && last_char!='\\')
-        inside_quote=false;
-
-      else if(!inside_quote && file[pos]=='(')
-        inside_para=true;
-      else if(!inside_quote && file[pos]==')')
-        inside_para=false;
-
-      else if(inside_para && file[pos]=='\n')
-        file.replace(pos, 1, 1, ' ');
-      last_char=file[pos];
-      pos++;
-    }
-  }
-}
-
-void CMake::parse_variable_parameters(std::string &data) {
-  size_t pos=0;
-  bool inside_quote=false;
-  char last_char=0;
-  while(pos<data.size()) {
-    if(!inside_quote && data[pos]=='"' && last_char!='\\') {
-      inside_quote=true;
-      data.erase(pos, 1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
-      pos--;
-    }
-    else if(inside_quote && data[pos]=='"' && last_char!='\\') {
-      inside_quote=false;
-      data.erase(pos, 1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
-      pos--;
-    }
-    else if(!inside_quote && data[pos]==' ' && pos+1<data.size() && data[pos+1]==' ') {
-      data.erase(pos, 1);
-      pos--;
-    }
-    
-    if(pos!=static_cast<size_t>(-1))
-      last_char=data[pos];
-    pos++;
-  }
-  for(auto &var: variables) {
-    auto pos=data.find("${"+var.first+'}');
-    while(pos!=std::string::npos) {
-      data.replace(pos, var.first.size()+3, var.second);
-      pos=data.find("${"+var.first+'}');
-    }
-  }
-  
-  //Remove variables we do not know:
-  pos=data.find("${");
-  auto pos_end=data.find("}", pos+2);
-  while(pos!=std::string::npos && pos_end!=std::string::npos) {
-    data.erase(pos, pos_end-pos+1);
-    pos=data.find("${");
-    pos_end=data.find("}", pos+2);
-  }
-}
-
-void CMake::parse() {
-  read_files();
-  remove_tabs();
-  remove_comments();
-  remove_newlines_inside_parentheses();
-  parsed=true;
-}
-
-std::vector<std::string> CMake::get_function_parameters(std::string &data) {
-  std::vector<std::string> parameters;
-  size_t pos=0;
-  size_t parameter_pos=0;
-  bool inside_quote=false;
-  char last_char=0;
-  while(pos<data.size()) {
-    if(!inside_quote && data[pos]=='"' && last_char!='\\') {
-      inside_quote=true;
-      data.erase(pos, 1);
-      pos--;
-    }
-    else if(inside_quote && data[pos]=='"' && last_char!='\\') {
-      inside_quote=false;
-      data.erase(pos, 1);
-      pos--;
-    }
-    else if(!inside_quote && pos+1<data.size() && data[pos]==' ' && data[pos+1]==' ') {
-      data.erase(pos, 1);
-      pos--;
-    }
-    else if(!inside_quote && data[pos]==' ') {
-      parameters.emplace_back(data.substr(parameter_pos, pos-parameter_pos));
-      if(pos+1<data.size())
-        parameter_pos=pos+1;
-    }
-    
-    if(pos!=static_cast<size_t>(-1))
-      last_char=data[pos];
-    pos++;
-  }
-  parameters.emplace_back(data.substr(parameter_pos));
-  for(auto &var: variables) {
-    for(auto &parameter: parameters) {
-      auto pos=parameter.find("${"+var.first+'}');
-      while(pos!=std::string::npos) {
-        parameter.replace(pos, var.first.size()+3, var.second);
-        pos=parameter.find("${"+var.first+'}');
-      }
-    }
-  }
-  return parameters;
-}
-
-std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > > CMake::get_functions_parameters(const std::string &name) {
-  const std::regex function_regex("^ *"+name+" *\\( *(.*)\\) *\\r?$", std::regex::icase);
-  variables.clear();
-  if(!parsed)
-    parse();
-  std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > > functions;
-  for(size_t c=0;c<files.size();++c) {
-    size_t pos=0;
-    while(pos<files[c].size()) {
-      auto start_line=pos;
-      auto end_line=files[c].find('\n', start_line);
-      if(end_line==std::string::npos)
-        end_line=files[c].size();
-      if(end_line>start_line) {
-        auto line=files[c].substr(start_line, end_line-start_line);
-        std::smatch sm;
-        const static std::regex set_regex("^ *set *\\( *([A-Za-z_][A-Za-z_0-9]*) +(.*)\\) *\\r?$", std::regex::icase);
-        const static std::regex project_regex("^ *project *\\( *([^ ]+).*\\) *\\r?$", std::regex::icase);
-        if(std::regex_match(line, sm, set_regex)) {
-          auto data=sm[2].str();
-          while(data.size()>0 && data.back()==' ')
-            data.pop_back();
-          parse_variable_parameters(data);
-          variables[sm[1].str()]=data;
-        }
-        else if(std::regex_match(line, sm, project_regex)) {
-          auto data=sm[1].str();
-          parse_variable_parameters(data);
-          variables["CMAKE_PROJECT_NAME"]=data; //TODO: is this variable deprecated/non-standard?
-          variables["PROJECT_NAME"]=data;
-        }
-        if(std::regex_match(line, sm, function_regex)) {
-          auto data=sm[1].str();
-          while(data.size()>0 && data.back()==' ')
-            data.pop_back();
-          auto parameters=get_function_parameters(data);
-          functions.emplace_back(paths[c], parameters);
-        }
-      }
-      pos=end_line+1;
-    }
-  }
-  return functions;
-}
diff --git a/src/cmake.h b/src/cmake.h
deleted file mode 100644
index f87010a3..00000000
--- a/src/cmake.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-#include <boost/filesystem.hpp>
-#include <vector>
-#include <unordered_map>
-#include <unordered_set>
-
-class CMake {
-public:
-  CMake(const boost::filesystem::path &path);
-  boost::filesystem::path project_path;
-  
-  bool update_default_build(const boost::filesystem::path &default_build_path, bool force=false);
-  bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force=false);
-  
-  boost::filesystem::path get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
-  
-private:
-  std::vector<boost::filesystem::path> paths;
-  std::vector<std::string> files;
-  std::unordered_map<std::string, std::string> variables;
-  void read_files();
-  void remove_tabs();
-  void remove_comments();
-  void remove_newlines_inside_parentheses();
-  void parse_variable_parameters(std::string &data);
-  void parse();
-  std::vector<std::string> get_function_parameters(std::string &data);
-  std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > > get_functions_parameters(const std::string &name);
-  bool parsed=false;
-};
diff --git a/src/compile_commands.cc b/src/compile_commands.cc
index 5f11afe8..7f283d8d 100644
--- a/src/compile_commands.cc
+++ b/src/compile_commands.cc
@@ -4,161 +4,159 @@
 #include <regex>
 
 std::vector<std::string> CompileCommands::Command::parameter_values(const std::string &parameter_name) const {
-  std::vector<std::string> parameter_values;
-  
-  bool found_argument=false;
-  for(auto &parameter: parameters) {
-    if(found_argument) {
-      parameter_values.emplace_back(parameter);
-      found_argument=false;
+    std::vector<std::string> parameter_values;
+
+    bool found_argument = false;
+    for (auto &parameter: parameters) {
+        if (found_argument) {
+            parameter_values.emplace_back(parameter);
+            found_argument = false;
+        } else if (parameter == parameter_name)
+            found_argument = true;
     }
-    else if(parameter==parameter_name)
-      found_argument=true;
-  }
-  
-  return parameter_values;
+
+    return parameter_values;
 }
 
 CompileCommands::CompileCommands(const boost::filesystem::path &build_path) {
-  try {
-    boost::property_tree::ptree root_pt;
-    boost::property_tree::json_parser::read_json((build_path/"compile_commands.json").string(), root_pt);
-    
-    auto commands_pt=root_pt.get_child("");
-    for(auto &command: commands_pt) {
-      boost::filesystem::path directory=command.second.get<std::string>("directory");
-      auto parameters_str=command.second.get<std::string>("command");
-      boost::filesystem::path file=command.second.get<std::string>("file");
-      
-      std::vector<std::string> parameters;
-      bool backslash=false;
-      bool single_quote=false;
-      bool double_quote=false;
-      size_t parameter_start_pos=std::string::npos;
-      size_t parameter_size=0;
-      auto add_parameter=[&parameters, &parameters_str, &parameter_start_pos, &parameter_size] {
-        auto parameter=parameters_str.substr(parameter_start_pos, parameter_size);
-        // Remove escaping
-        for(size_t c=0;c<parameter.size()-1;++c) {
-          if(parameter[c]=='\\')
-            parameter.replace(c, 2, std::string()+parameter[c+1]);
-        }
-        parameters.emplace_back(parameter);
-      };
-      for(size_t c=0;c<parameters_str.size();++c) {
-        if(backslash)
-          backslash=false;
-        else if(parameters_str[c]=='\\')
-          backslash=true;
-        else if((parameters_str[c]==' ' || parameters_str[c]=='\t') && !backslash && !single_quote && !double_quote) {
-          if(parameter_start_pos!=std::string::npos) {
-            add_parameter();
-            parameter_start_pos=std::string::npos;
-            parameter_size=0;
-          }
-          continue;
-        }
-        else if(parameters_str[c]=='\'' && !backslash && !double_quote) {
-          single_quote=!single_quote;
-          continue;
-        }
-        else if(parameters_str[c]=='\"' && !backslash && !single_quote) {
-          double_quote=!double_quote;
-          continue;
+    try {
+        boost::property_tree::ptree root_pt;
+        boost::property_tree::json_parser::read_json((build_path / "compile_commands.json").string(), root_pt);
+
+        auto commands_pt = root_pt.get_child("");
+        for (auto &command: commands_pt) {
+            boost::filesystem::path directory = command.second.get<std::string>("directory");
+            auto parameters_str = command.second.get<std::string>("command");
+            boost::filesystem::path file = command.second.get<std::string>("file");
+
+            std::vector<std::string> parameters;
+            bool backslash = false;
+            bool single_quote = false;
+            bool double_quote = false;
+            size_t parameter_start_pos = std::string::npos;
+            size_t parameter_size = 0;
+            auto add_parameter = [&parameters, &parameters_str, &parameter_start_pos, &parameter_size] {
+                auto parameter = parameters_str.substr(parameter_start_pos, parameter_size);
+                // Remove escaping
+                for (size_t c = 0; c < parameter.size() - 1; ++c) {
+                    if (parameter[c] == '\\')
+                        parameter.replace(c, 2, std::string() + parameter[c + 1]);
+                }
+                parameters.emplace_back(parameter);
+            };
+            for (size_t c = 0; c < parameters_str.size(); ++c) {
+                if (backslash)
+                    backslash = false;
+                else if (parameters_str[c] == '\\')
+                    backslash = true;
+                else if ((parameters_str[c] == ' ' || parameters_str[c] == '\t') && !backslash && !single_quote &&
+                         !double_quote) {
+                    if (parameter_start_pos != std::string::npos) {
+                        add_parameter();
+                        parameter_start_pos = std::string::npos;
+                        parameter_size = 0;
+                    }
+                    continue;
+                } else if (parameters_str[c] == '\'' && !backslash && !double_quote) {
+                    single_quote = !single_quote;
+                    continue;
+                } else if (parameters_str[c] == '\"' && !backslash && !single_quote) {
+                    double_quote = !double_quote;
+                    continue;
+                }
+
+                if (parameter_start_pos == std::string::npos)
+                    parameter_start_pos = c;
+                ++parameter_size;
+            }
+            if (parameter_start_pos != std::string::npos)
+                add_parameter();
+
+            commands.emplace_back(Command{directory, parameters, boost::filesystem::absolute(file, build_path)});
         }
-        
-        if(parameter_start_pos==std::string::npos)
-          parameter_start_pos=c;
-        ++parameter_size;
-      }
-      if(parameter_start_pos!=std::string::npos)
-        add_parameter();
-      
-      commands.emplace_back(Command{directory, parameters, boost::filesystem::absolute(file, build_path)});
     }
-  }
-  catch(...) {}
+    catch (...) {}
 }
 
-std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
-  std::string default_std_argument="-std=c++1y";
-  
-  std::vector<std::string> arguments;
-  if(!build_path.empty()) {
-    clangmm::CompilationDatabase db(build_path.string());
-    if(db) {
-      clangmm::CompileCommands commands(file_path.string(), db);
-      auto cmds = commands.get_commands();
-      for (auto &cmd : cmds) {
-        auto cmd_arguments = cmd.get_arguments();
-        bool ignore_next=false;
-        for (size_t c = 1; c < cmd_arguments.size(); c++) {
-          if(ignore_next) {
-            ignore_next=false;
-            continue;
-          }
-          else if(cmd_arguments[c]=="-o" || cmd_arguments[c]=="-c") {
-            ignore_next=true;
-            continue;
-          }
-          arguments.emplace_back(cmd_arguments[c]);
-        }
-      }
-    }
-    else
-      arguments.emplace_back(default_std_argument);
-  }
-  else
-    arguments.emplace_back(default_std_argument);
-  
-  auto clang_version_string=clangmm::to_string(clang_getClangVersion());
-  const static std::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$");
-  std::smatch sm;
-  if(std::regex_match(clang_version_string, sm, clang_version_regex)) {
-    auto clang_version=sm[1].str();
-    arguments.emplace_back("-I/usr/lib/clang/"+clang_version+"/include");
-    arguments.emplace_back("-I/usr/lib64/clang/"+clang_version+"/include"); // For Fedora
-#if defined(__APPLE__) && CINDEX_VERSION_MAJOR==0 && CINDEX_VERSION_MINOR<32 // TODO: remove during 2018 if llvm3.7 is no longer in homebrew (CINDEX_VERSION_MINOR=32 equals clang-3.8 I think)
-    arguments.emplace_back("-I/usr/local/Cellar/llvm/"+clang_version+"/lib/clang/"+clang_version+"/include");
-    arguments.emplace_back("-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1");
-    arguments.emplace_back("-I/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1"); //Added for OS X 10.11
+std::vector<std::string>
+CompileCommands::get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
+    std::string default_std_argument = "-std=c++1y";
+
+    std::vector<std::string> arguments;
+    if (!build_path.empty()) {
+        clangmm::CompilationDatabase db(build_path.string());
+        if (db) {
+            clangmm::CompileCommands commands(file_path.string(), db);
+            auto cmds = commands.get_commands();
+            for (auto &cmd : cmds) {
+                auto cmd_arguments = cmd.get_arguments();
+                bool ignore_next = false;
+                for (size_t c = 1; c < cmd_arguments.size(); c++) {
+                    if (ignore_next) {
+                        ignore_next = false;
+                        continue;
+                    } else if (cmd_arguments[c] == "-o" || cmd_arguments[c] == "-c") {
+                        ignore_next = true;
+                        continue;
+                    }
+                    arguments.emplace_back(cmd_arguments[c]);
+                }
+            }
+        } else
+            arguments.emplace_back(default_std_argument);
+    } else
+        arguments.emplace_back(default_std_argument);
+
+    auto clang_version_string = clangmm::to_string(clang_getClangVersion());
+    const static std::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$");
+    std::smatch sm;
+    if (std::regex_match(clang_version_string, sm, clang_version_regex)) {
+        auto clang_version = sm[1].str();
+        arguments.emplace_back("-I/usr/lib/clang/" + clang_version + "/include");
+        arguments.emplace_back("-I/usr/lib64/clang/" + clang_version + "/include"); // For Fedora
+#if defined(__APPLE__) && CINDEX_VERSION_MAJOR == 0 && CINDEX_VERSION_MINOR < 32 // TODO: remove during 2018 if llvm3.7 is no longer in homebrew (CINDEX_VERSION_MINOR=32 equals clang-3.8 I think)
+        arguments.emplace_back("-I/usr/local/Cellar/llvm/"+clang_version+"/lib/clang/"+clang_version+"/include");
+        arguments.emplace_back("-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1");
+        arguments.emplace_back("-I/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1"); //Added for OS X 10.11
 #endif
 #ifdef _WIN32
-    auto env_msystem_prefix=std::getenv("MSYSTEM_PREFIX");
-    if(env_msystem_prefix!=nullptr)
-      arguments.emplace_back("-I"+(boost::filesystem::path(env_msystem_prefix)/"lib/clang"/clang_version/"include").string());
+        auto env_msystem_prefix = std::getenv("MSYSTEM_PREFIX");
+        if (env_msystem_prefix != nullptr)
+            arguments.emplace_back("-I" + (boost::filesystem::path(env_msystem_prefix) / "lib/clang" / clang_version /
+                                           "include").string());
 #endif
-  }
-  arguments.emplace_back("-fretain-comments-from-system-headers");
-  
-  auto extension=file_path.extension().string();
-  if(extension==".h" ||  //TODO: temporary fix for .h-files (parse as c++)
-     extension!=".c")
-    arguments.emplace_back("-xc++");
-  
-  if(extension.empty() || (1<extension.size() && extension[1]=='h') || extension==".tcc" || extension==".cuh") {
-    arguments.emplace_back("-Wno-pragma-once-outside-header");
-    arguments.emplace_back("-Wno-pragma-system-header-outside-header");
-    arguments.emplace_back("-Wno-include-next-outside-header");
-  }
-  
-  if(extension==".cu" || extension==".cuh") {
-    arguments.emplace_back("-include");
-    arguments.emplace_back("cuda_runtime.h");
-  }
-  
-  if(extension==".cl") {
-    arguments.emplace_back("-xcl");
-    arguments.emplace_back("-cl-std=CL2.0");
-    arguments.emplace_back("-Xclang");
-    arguments.emplace_back("-finclude-default-header");
-    arguments.emplace_back("-Wno-gcc-compat");
-  }
-  
-  if(!build_path.empty()) {
-    arguments.emplace_back("-working-directory");
-    arguments.emplace_back(build_path.string());
-  }
-
-  return arguments;
+    }
+    arguments.emplace_back("-fretain-comments-from-system-headers");
+
+    auto extension = file_path.extension().string();
+    if (extension == ".h" ||  //TODO: temporary fix for .h-files (parse as c++)
+        extension != ".c")
+        arguments.emplace_back("-xc++");
+
+    if (extension.empty() || (1 < extension.size() && extension[1] == 'h') || extension == ".tcc" ||
+        extension == ".cuh") {
+        arguments.emplace_back("-Wno-pragma-once-outside-header");
+        arguments.emplace_back("-Wno-pragma-system-header-outside-header");
+        arguments.emplace_back("-Wno-include-next-outside-header");
+    }
+
+    if (extension == ".cu" || extension == ".cuh") {
+        arguments.emplace_back("-include");
+        arguments.emplace_back("cuda_runtime.h");
+    }
+
+    if (extension == ".cl") {
+        arguments.emplace_back("-xcl");
+        arguments.emplace_back("-cl-std=CL2.0");
+        arguments.emplace_back("-Xclang");
+        arguments.emplace_back("-finclude-default-header");
+        arguments.emplace_back("-Wno-gcc-compat");
+    }
+
+    if (!build_path.empty()) {
+        arguments.emplace_back("-working-directory");
+        arguments.emplace_back(build_path.string());
+    }
+
+    return arguments;
 }
diff --git a/src/compile_commands.h b/src/compile_commands.h
index 642cd33f..83c3d6dd 100644
--- a/src/compile_commands.h
+++ b/src/compile_commands.h
@@ -1,22 +1,25 @@
 #pragma once
+
 #include <boost/filesystem.hpp>
 #include <vector>
 #include <string>
 
 class CompileCommands {
 public:
-  class Command {
-  public:
-    boost::filesystem::path directory;
-    std::vector<std::string> parameters;
-    boost::filesystem::path file;
-    
-    std::vector<std::string> parameter_values(const std::string &parameter_name) const;
-  };
-  
-  CompileCommands(const boost::filesystem::path &build_path);
-  std::vector<Command> commands;
-  
-  /// Return arguments for the given file using libclangmm
-  static std::vector<std::string> get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
+    class Command {
+    public:
+        boost::filesystem::path directory;
+        std::vector<std::string> parameters;
+        boost::filesystem::path file;
+
+        std::vector<std::string> parameter_values(const std::string &parameter_name) const;
+    };
+
+    CompileCommands(const boost::filesystem::path &build_path);
+
+    std::vector<Command> commands;
+
+    /// Return arguments for the given file using libclangmm
+    static std::vector<std::string>
+    get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
 };
diff --git a/src/config.cc b/src/config.cc
index 934b4388..625da547 100644
--- a/src/config.cc
+++ b/src/config.cc
@@ -7,198 +7,203 @@
 #include <algorithm>
 
 Config::Config() {
-  home_path=filesystem::get_home_path();
-  if(home_path.empty())
-    throw std::runtime_error("Could not find home path");
-  home_juci_path=home_path/".juci";
+    home_path = filesystem::get_home_path();
+    if (home_path.empty())
+        throw std::runtime_error("Could not find home path");
+    home_juci_path = home_path / ".juci";
 }
 
 void Config::load() {
-  auto config_json = (home_juci_path/"config"/"config.json").string(); // This causes some redundant copies, but assures windows support
-  boost::property_tree::ptree cfg;
-  try {
-    find_or_create_config_files();
-    boost::property_tree::json_parser::read_json(config_json, cfg);
-    update(cfg);
-    read(cfg);
-  }
-  catch(const std::exception &e) {
-    dispatcher.post([config_json, e_what=std::string(e.what())] {
-      ::Terminal::get().print("Error: could not parse "+config_json+": "+e_what+"\n", true);
-    });
-    std::stringstream ss;
-    ss << default_config_file;
-    boost::property_tree::read_json(ss, cfg);
-    read(cfg);
-  }
+    auto config_json = (home_juci_path / "config" /
+                        "config.json").string(); // This causes some redundant copies, but assures windows support
+    boost::property_tree::ptree cfg;
+    try {
+        find_or_create_config_files();
+        boost::property_tree::json_parser::read_json(config_json, cfg);
+        update(cfg);
+        read(cfg);
+    }
+    catch (const std::exception &e) {
+        dispatcher.post([config_json, e_what = std::string(e.what())] {
+            ::Terminal::get().print("Error: could not parse " + config_json + ": " + e_what + "\n", true);
+        });
+        std::stringstream ss;
+        ss << default_config_file;
+        boost::property_tree::read_json(ss, cfg);
+        read(cfg);
+    }
 }
 
 void Config::find_or_create_config_files() {
-  auto config_dir = home_juci_path/"config";
-  auto config_json = config_dir/"config.json";
-
-  boost::filesystem::create_directories(config_dir); // io exp captured by calling method
-
-  if (!boost::filesystem::exists(config_json))
-    filesystem::write(config_json, default_config_file);
-
-  auto juci_style_path = home_juci_path/"styles";
-  boost::filesystem::create_directories(juci_style_path); // io exp captured by calling method
-
-  juci_style_path/="juci-light.xml";
-  if(!boost::filesystem::exists(juci_style_path))
-    filesystem::write(juci_style_path, juci_light_style);
-  juci_style_path=juci_style_path.parent_path();
-  juci_style_path/="juci-dark.xml";
-  if(!boost::filesystem::exists(juci_style_path))
-    filesystem::write(juci_style_path, juci_dark_style);
-  juci_style_path=juci_style_path.parent_path();
-  juci_style_path/="juci-dark-blue.xml";
-  if(!boost::filesystem::exists(juci_style_path))
-    filesystem::write(juci_style_path, juci_dark_blue_style);
+    auto config_dir = home_juci_path / "config";
+    auto config_json = config_dir / "config.json";
+
+    boost::filesystem::create_directories(config_dir); // io exp captured by calling method
+
+    if (!boost::filesystem::exists(config_json))
+        filesystem::write(config_json, default_config_file);
+
+    auto juci_style_path = home_juci_path / "styles";
+    boost::filesystem::create_directories(juci_style_path); // io exp captured by calling method
+
+    juci_style_path /= "juci-light.xml";
+    if (!boost::filesystem::exists(juci_style_path))
+        filesystem::write(juci_style_path, juci_light_style);
+    juci_style_path = juci_style_path.parent_path();
+    juci_style_path /= "juci-dark.xml";
+    if (!boost::filesystem::exists(juci_style_path))
+        filesystem::write(juci_style_path, juci_dark_style);
+    juci_style_path = juci_style_path.parent_path();
+    juci_style_path /= "juci-dark-blue.xml";
+    if (!boost::filesystem::exists(juci_style_path))
+        filesystem::write(juci_style_path, juci_dark_blue_style);
 }
 
 void Config::update(boost::property_tree::ptree &cfg) {
-  boost::property_tree::ptree default_cfg;
-  bool cfg_ok=true;
-  if(cfg.get<std::string>("version")!=JUCI_VERSION) {
-    std::stringstream ss;
-    ss << default_config_file;
-    boost::property_tree::read_json(ss, default_cfg);
-    cfg_ok=false;
-    auto it_version=cfg.find("version");
-    if(it_version!=cfg.not_found()) {
-      make_version_dependent_corrections(cfg, default_cfg, it_version->second.data());
-      it_version->second.data()=JUCI_VERSION;
-    }
-    
-    auto style_path=home_juci_path/"styles";
-    filesystem::write(style_path/"juci-light.xml", juci_light_style);
-    filesystem::write(style_path/"juci-dark.xml", juci_dark_style);
-    filesystem::write(style_path/"juci-dark-blue.xml", juci_dark_blue_style);
-  }
-  else
-    return;
-  cfg_ok&=add_missing_nodes(cfg, default_cfg);
-  cfg_ok&=remove_deprecated_nodes(cfg, default_cfg);
-  if(!cfg_ok)
-    boost::property_tree::write_json((home_juci_path/"config"/"config.json").string(), cfg);
-}
+    boost::property_tree::ptree default_cfg;
+    bool cfg_ok = true;
+    if (cfg.get<std::string>("version") != JUCI_VERSION) {
+        std::stringstream ss;
+        ss << default_config_file;
+        boost::property_tree::read_json(ss, default_cfg);
+        cfg_ok = false;
+        auto it_version = cfg.find("version");
+        if (it_version != cfg.not_found()) {
+            make_version_dependent_corrections(cfg, default_cfg, it_version->second.data());
+            it_version->second.data() = JUCI_VERSION;
+        }
 
-void Config::make_version_dependent_corrections(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg, const std::string &version) {
-  auto &keybindings_cfg=cfg.get_child("keybindings");
-  try {
-    if(version<="1.2.4") {
-      auto it_file_print=keybindings_cfg.find("print");
-      if(it_file_print!=keybindings_cfg.not_found() && it_file_print->second.data()=="<primary>p") {
-        dispatcher.post([] {
-          ::Terminal::get().print("Preference change: keybindings.print set to \"\"\n");
-        });
-        it_file_print->second.data()="";
-      }
-    }
-  }
-  catch(const std::exception &e) {
-    std::cerr << "Error correcting preferences: " << e.what() << std::endl;
-  }
+        auto style_path = home_juci_path / "styles";
+        filesystem::write(style_path / "juci-light.xml", juci_light_style);
+        filesystem::write(style_path / "juci-dark.xml", juci_dark_style);
+        filesystem::write(style_path / "juci-dark-blue.xml", juci_dark_blue_style);
+    } else
+        return;
+    cfg_ok &= add_missing_nodes(cfg, default_cfg);
+    cfg_ok &= remove_deprecated_nodes(cfg, default_cfg);
+    if (!cfg_ok)
+        boost::property_tree::write_json((home_juci_path / "config" / "config.json").string(), cfg);
 }
 
-bool Config::add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg, std::string parent_path) {
-  if(parent_path.size()>0)
-    parent_path+=".";
-  bool unchanged=true;
-  for(auto &node: default_cfg) {
-    auto path=parent_path+node.first;
+void Config::make_version_dependent_corrections(boost::property_tree::ptree &cfg,
+                                                const boost::property_tree::ptree &default_cfg,
+                                                const std::string &version) {
+    auto &keybindings_cfg = cfg.get_child("keybindings");
     try {
-      cfg.get<std::string>(path);
+        if (version <= "1.2.4") {
+            auto it_file_print = keybindings_cfg.find("print");
+            if (it_file_print != keybindings_cfg.not_found() && it_file_print->second.data() == "<primary>p") {
+                dispatcher.post([] {
+                    ::Terminal::get().print("Preference change: keybindings.print set to \"\"\n");
+                });
+                it_file_print->second.data() = "";
+            }
+        }
     }
-    catch(const std::exception &e) {
-      cfg.add(path, node.second.data());
-      unchanged=false;
+    catch (const std::exception &e) {
+        std::cerr << "Error correcting preferences: " << e.what() << std::endl;
     }
-    unchanged&=add_missing_nodes(cfg, node.second, path);
-  }
-  return unchanged;
 }
 
-bool Config::remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg, std::string parent_path) {
-  if(parent_path.size()>0)
-    parent_path+=".";
-  bool unchanged=true;
-  for(auto it=cfg.begin();it!=cfg.end();) {
-    auto path=parent_path+it->first;
-    try {
-      default_cfg.get<std::string>(path);
-      unchanged&=remove_deprecated_nodes(it->second, default_cfg, path);
-      ++it;
+bool Config::add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                               std::string parent_path) {
+    if (parent_path.size() > 0)
+        parent_path += ".";
+    bool unchanged = true;
+    for (auto &node: default_cfg) {
+        auto path = parent_path + node.first;
+        try {
+            cfg.get<std::string>(path);
+        }
+        catch (const std::exception &e) {
+            cfg.add(path, node.second.data());
+            unchanged = false;
+        }
+        unchanged &= add_missing_nodes(cfg, node.second, path);
     }
-    catch(const std::exception &e) {
-      it=cfg.erase(it);
-      unchanged=false;
+    return unchanged;
+}
+
+bool Config::remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                                     std::string parent_path) {
+    if (parent_path.size() > 0)
+        parent_path += ".";
+    bool unchanged = true;
+    for (auto it = cfg.begin(); it != cfg.end();) {
+        auto path = parent_path + it->first;
+        try {
+            default_cfg.get<std::string>(path);
+            unchanged &= remove_deprecated_nodes(it->second, default_cfg, path);
+            ++it;
+        }
+        catch (const std::exception &e) {
+            it = cfg.erase(it);
+            unchanged = false;
+        }
     }
-  }
-  return unchanged;
+    return unchanged;
 }
 
 void Config::read(const boost::property_tree::ptree &cfg) {
-  auto keybindings_pt = cfg.get_child("keybindings");
-  for (auto &i : keybindings_pt) {
-    menu.keys[i.first] = i.second.get_value<std::string>();
-  }
-  
-  auto source_json = cfg.get_child("source");
-  source.style=source_json.get<std::string>("style");
-  source.font=source_json.get<std::string>("font");
-  source.cleanup_whitespace_characters=source_json.get<bool>("cleanup_whitespace_characters");
-  source.show_whitespace_characters=source_json.get<std::string>("show_whitespace_characters");
-  source.format_style_on_save=source_json.get<bool>("format_style_on_save");
-  source.format_style_on_save_if_style_file_found=source_json.get<bool>("format_style_on_save_if_style_file_found");
-  source.smart_brackets=source_json.get<bool>("smart_brackets");
-  source.smart_inserts=source_json.get<bool>("smart_inserts");
-  if(source.smart_inserts)
-    source.smart_brackets=true;
-  source.show_map = source_json.get<bool>("show_map");
-  source.map_font_size = source_json.get<std::string>("map_font_size");
-  source.show_git_diff = source_json.get<bool>("show_git_diff");
-  source.show_background_pattern = source_json.get<bool>("show_background_pattern");
-  source.show_right_margin = source_json.get<bool>("show_right_margin");
-  source.right_margin_position = source_json.get<unsigned>("right_margin_position");
-  source.spellcheck_language = source_json.get<std::string>("spellcheck_language");
-  source.default_tab_char = source_json.get<char>("default_tab_char");
-  source.default_tab_size = source_json.get<unsigned>("default_tab_size");
-  source.auto_tab_char_and_size = source_json.get<bool>("auto_tab_char_and_size");
-  source.tab_indents_line = source_json.get<bool>("tab_indents_line");
-  source.wrap_lines = source_json.get<bool>("wrap_lines");
-  source.highlight_current_line = source_json.get<bool>("highlight_current_line");
-  source.show_line_numbers = source_json.get<bool>("show_line_numbers");
-  source.enable_multiple_cursors = source_json.get<bool>("enable_multiple_cursors");
-  source.auto_reload_changed_files = source_json.get<bool>("auto_reload_changed_files");
-  source.clang_format_style = source_json.get<std::string>("clang_format_style");
-  source.clang_usages_threads = static_cast<unsigned>(source_json.get<int>("clang_usages_threads"));
-  auto pt_doc_search=cfg.get_child("documentation_searches");
-  for(auto &pt_doc_search_lang: pt_doc_search) {
-    source.documentation_searches[pt_doc_search_lang.first].separator=pt_doc_search_lang.second.get<std::string>("separator");
-    auto &queries=source.documentation_searches.find(pt_doc_search_lang.first)->second.queries;
-    for(auto &i: pt_doc_search_lang.second.get_child("queries")) {
-      queries[i.first]=i.second.get_value<std::string>();
+    auto keybindings_pt = cfg.get_child("keybindings");
+    for (auto &i : keybindings_pt) {
+        menu.keys[i.first] = i.second.get_value<std::string>();
     }
-  }
-
-  window.theme_name=cfg.get<std::string>("gtk_theme.name");
-  window.theme_variant=cfg.get<std::string>("gtk_theme.variant");
-  window.version = cfg.get<std::string>("version");
-  
-  project.default_build_path=cfg.get<std::string>("project.default_build_path");
-  project.debug_build_path=cfg.get<std::string>("project.debug_build_path");
-  project.cmake.command=cfg.get<std::string>("project.cmake.command");
-  project.cmake.compile_command=cfg.get<std::string>("project.cmake.compile_command");
-  project.meson.command=cfg.get<std::string>("project.meson.command");
-  project.meson.compile_command=cfg.get<std::string>("project.meson.compile_command");
-  project.save_on_compile_or_run=cfg.get<bool>("project.save_on_compile_or_run");
-  project.clear_terminal_on_compile=cfg.get<bool>("project.clear_terminal_on_compile");
-  project.ctags_command=cfg.get<std::string>("project.ctags_command");
-  project.python_command=cfg.get<std::string>("project.python_command");
-  
-  terminal.history_size=cfg.get<int>("terminal.history_size");
-  terminal.font=cfg.get<std::string>("terminal.font");
+
+    auto source_json = cfg.get_child("source");
+    source.style = source_json.get<std::string>("style");
+    source.font = source_json.get<std::string>("font");
+    source.cleanup_whitespace_characters = source_json.get<bool>("cleanup_whitespace_characters");
+    source.show_whitespace_characters = source_json.get<std::string>("show_whitespace_characters");
+    source.format_style_on_save = source_json.get<bool>("format_style_on_save");
+    source.format_style_on_save_if_style_file_found = source_json.get<bool>("format_style_on_save_if_style_file_found");
+    source.smart_brackets = source_json.get<bool>("smart_brackets");
+    source.smart_inserts = source_json.get<bool>("smart_inserts");
+    if (source.smart_inserts)
+        source.smart_brackets = true;
+    source.show_map = source_json.get<bool>("show_map");
+    source.map_font_size = source_json.get<std::string>("map_font_size");
+    source.show_git_diff = source_json.get<bool>("show_git_diff");
+    source.show_background_pattern = source_json.get<bool>("show_background_pattern");
+    source.show_right_margin = source_json.get<bool>("show_right_margin");
+    source.right_margin_position = source_json.get<unsigned>("right_margin_position");
+    source.spellcheck_language = source_json.get<std::string>("spellcheck_language");
+    source.default_tab_char = source_json.get<char>("default_tab_char");
+    source.default_tab_size = source_json.get<unsigned>("default_tab_size");
+    source.auto_tab_char_and_size = source_json.get<bool>("auto_tab_char_and_size");
+    source.tab_indents_line = source_json.get<bool>("tab_indents_line");
+    source.wrap_lines = source_json.get<bool>("wrap_lines");
+    source.highlight_current_line = source_json.get<bool>("highlight_current_line");
+    source.show_line_numbers = source_json.get<bool>("show_line_numbers");
+    source.enable_multiple_cursors = source_json.get<bool>("enable_multiple_cursors");
+    source.auto_reload_changed_files = source_json.get<bool>("auto_reload_changed_files");
+    source.clang_format_style = source_json.get<std::string>("clang_format_style");
+    source.clang_usages_threads = static_cast<unsigned>(source_json.get<int>("clang_usages_threads"));
+    auto pt_doc_search = cfg.get_child("documentation_searches");
+    for (auto &pt_doc_search_lang: pt_doc_search) {
+        source.documentation_searches[pt_doc_search_lang.first].separator = pt_doc_search_lang.second.get<std::string>(
+                "separator");
+        auto &queries = source.documentation_searches.find(pt_doc_search_lang.first)->second.queries;
+        for (auto &i: pt_doc_search_lang.second.get_child("queries")) {
+            queries[i.first] = i.second.get_value<std::string>();
+        }
+    }
+
+    window.theme_name = cfg.get<std::string>("gtk_theme.name");
+    window.theme_variant = cfg.get<std::string>("gtk_theme.variant");
+    window.version = cfg.get<std::string>("version");
+
+    project.default_build_path = cfg.get<std::string>("project.default_build_path");
+    project.debug_build_path = cfg.get<std::string>("project.debug_build_path");
+    project.cmake.command = cfg.get<std::string>("project.cmake.command");
+    project.cmake.compile_command = cfg.get<std::string>("project.cmake.compile_command");
+    project.meson.command = cfg.get<std::string>("project.meson.command");
+    project.meson.compile_command = cfg.get<std::string>("project.meson.compile_command");
+    project.save_on_compile_or_run = cfg.get<bool>("project.save_on_compile_or_run");
+    project.clear_terminal_on_compile = cfg.get<bool>("project.clear_terminal_on_compile");
+    project.ctags_command = cfg.get<std::string>("project.ctags_command");
+    project.python_command = cfg.get<std::string>("project.python_command");
+
+    terminal.history_size = cfg.get<int>("terminal.history_size");
+    terminal.font = cfg.get<std::string>("terminal.font");
 }
diff --git a/src/config.h b/src/config.h
index 1c1000be..5ec14d86 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <boost/property_tree/json_parser.hpp>
 #include <boost/filesystem.hpp>
 #include <unordered_map>
@@ -9,117 +10,129 @@
 
 class Config {
 public:
-  class Menu {
-  public:
-    std::unordered_map<std::string, std::string> keys;
-  };
-  
-  class Window {
-  public:
-    std::string theme_name;
-    std::string theme_variant;
-    std::string version;
-  };
-  
-  class Terminal {
-  public:
-    int history_size;
-    std::string font;
-  };
-  
-  class Project {
-  public:
-    class CMake {
+    class Menu {
+    public:
+        std::unordered_map<std::string, std::string> keys;
+    };
+
+    class Window {
     public:
-      std::string command;
-      std::string compile_command;
+        std::string theme_name;
+        std::string theme_variant;
+        std::string version;
     };
-    class Meson {
+
+    class Terminal {
     public:
-      std::string command;
-      std::string compile_command;
+        int history_size;
+        std::string font;
     };
-    
-    std::string default_build_path;
-    std::string debug_build_path;
-    CMake cmake;
-    Meson meson;
-    bool save_on_compile_or_run;
-    bool clear_terminal_on_compile;
-    std::string ctags_command;
-    std::string python_command;
-  };
-  
-  class Source {
-  public:
-    class DocumentationSearch {
+
+    class Project {
     public:
-      std::string separator;
-      std::unordered_map<std::string, std::string> queries;
+        class CMake {
+        public:
+            std::string command;
+            std::string compile_command;
+        };
+
+        class Meson {
+        public:
+            std::string command;
+            std::string compile_command;
+        };
+
+        std::string default_build_path;
+        std::string debug_build_path;
+        CMake cmake;
+        Meson meson;
+        bool save_on_compile_or_run;
+        bool clear_terminal_on_compile;
+        std::string ctags_command;
+        std::string python_command;
+    };
+
+    class Source {
+    public:
+        class DocumentationSearch {
+        public:
+            std::string separator;
+            std::unordered_map<std::string, std::string> queries;
+        };
+
+        std::string style;
+        std::string font;
+        std::string spellcheck_language;
+
+        bool cleanup_whitespace_characters;
+        std::string show_whitespace_characters;
+
+        bool format_style_on_save;
+        bool format_style_on_save_if_style_file_found;
+
+        bool smart_brackets;
+        bool smart_inserts;
+
+        bool show_map;
+        std::string map_font_size;
+        bool show_git_diff;
+        bool show_background_pattern;
+        bool show_right_margin;
+        unsigned right_margin_position;
+
+        bool auto_tab_char_and_size;
+        char default_tab_char;
+        unsigned default_tab_size;
+        bool tab_indents_line;
+        bool wrap_lines;
+        bool highlight_current_line;
+        bool show_line_numbers;
+        bool enable_multiple_cursors;
+        bool auto_reload_changed_files;
+
+        std::string clang_format_style;
+        unsigned clang_usages_threads;
+
+        std::unordered_map<std::string, DocumentationSearch> documentation_searches;
     };
-    
-    std::string style;
-    std::string font;
-    std::string spellcheck_language;
-    
-    bool cleanup_whitespace_characters;
-    std::string show_whitespace_characters;
-    
-    bool format_style_on_save;
-    bool format_style_on_save_if_style_file_found;
-    
-    bool smart_brackets;
-    bool smart_inserts;
-    
-    bool show_map;
-    std::string map_font_size;
-    bool show_git_diff;
-    bool show_background_pattern;
-    bool show_right_margin;
-    unsigned right_margin_position;
-    
-    bool auto_tab_char_and_size;
-    char default_tab_char;
-    unsigned default_tab_size;
-    bool tab_indents_line;
-    bool wrap_lines;
-    bool highlight_current_line;
-    bool show_line_numbers;
-    bool enable_multiple_cursors;
-    bool auto_reload_changed_files;
-    
-    std::string clang_format_style;
-    unsigned clang_usages_threads;
-    
-    std::unordered_map<std::string, DocumentationSearch> documentation_searches;
-  };
+
 private:
-  Config();
+    Config();
+
 public:
-  static Config &get() {
-    static Config singleton;
-    return singleton;
-  }
-  
-  void load();
-  
-  Menu menu;
-  Window window;
-  Terminal terminal;
-  Project project;
-  Source source;
-  
-  boost::filesystem::path home_path;
-  boost::filesystem::path home_juci_path;
+    static Config &get() {
+        static Config singleton;
+        return singleton;
+    }
+
+    void load();
+
+    Menu menu;
+    Window window;
+    Terminal terminal;
+    Project project;
+    Source source;
+
+    boost::filesystem::path home_path;
+    boost::filesystem::path home_juci_path;
 
 private:
-  /// Used to dispatch Terminal outputs after juCi++ GUI setup and configuration
-  Dispatcher dispatcher;
-  
-  void find_or_create_config_files();
-  void update(boost::property_tree::ptree &cfg);
-  void make_version_dependent_corrections(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg, const std::string &version);
-  bool add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg, std::string parent_path="");
-  bool remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg, std::string parent_path="");
-  void read(const boost::property_tree::ptree &cfg);
+    /// Used to dispatch Terminal outputs after juCi++ GUI setup and configuration
+    Dispatcher dispatcher;
+
+    void find_or_create_config_files();
+
+    void update(boost::property_tree::ptree &cfg);
+
+    void
+    make_version_dependent_corrections(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                                       const std::string &version);
+
+    bool add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                           std::string parent_path = "");
+
+    bool remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                                 std::string parent_path = "");
+
+    void read(const boost::property_tree::ptree &cfg);
 };
diff --git a/src/ctags.cc b/src/ctags.cc
index 31a0845f..e51213c1 100644
--- a/src/ctags.cc
+++ b/src/ctags.cc
@@ -8,199 +8,199 @@
 #include <regex>
 #include <climits>
 
-std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> > Ctags::get_result(const boost::filesystem::path &path) {
-  auto build=Project::Build::create(path);
-  auto run_path=build->project_path;
-  std::string exclude;
-  if(!run_path.empty()) {
-    auto relative_default_path=filesystem::get_relative_path(build->get_default_path(), run_path);
-    if(!relative_default_path.empty())
-      exclude+=" --exclude="+relative_default_path.string();
-    
-    auto relative_debug_path=filesystem::get_relative_path(build->get_debug_path(), run_path);
-    if(!relative_debug_path.empty())
-      exclude+=" --exclude="+relative_debug_path.string();
-  }
-  else {
-    boost::system::error_code ec;
-    if(boost::filesystem::is_directory(path, ec) || ec)
-      run_path=path;
-    else
-      run_path=path.parent_path();
-  }
-  
-  std::stringstream stdin_stream;
-  //TODO: when debian stable gets newer g++ version that supports move on streams, remove unique_ptr below
-  auto stdout_stream=std::make_unique<std::stringstream>();
-  auto command=Config::get().project.ctags_command+exclude+" --fields=ns --sort=foldcase -I \"override noexcept\" -f - -R *";
-  Terminal::get().process(stdin_stream, *stdout_stream, command, run_path);
-  return {run_path, std::move(stdout_stream)};
+std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> >
+Ctags::get_result(const boost::filesystem::path &path) {
+    auto build = Project::Build::create(path);
+    auto run_path = build->project_path;
+    std::string exclude;
+    if (!run_path.empty()) {
+        auto relative_default_path = filesystem::get_relative_path(build->get_default_path(), run_path);
+        if (!relative_default_path.empty())
+            exclude += " --exclude=" + relative_default_path.string();
+
+        auto relative_debug_path = filesystem::get_relative_path(build->get_debug_path(), run_path);
+        if (!relative_debug_path.empty())
+            exclude += " --exclude=" + relative_debug_path.string();
+    } else {
+        boost::system::error_code ec;
+        if (boost::filesystem::is_directory(path, ec) || ec)
+            run_path = path;
+        else
+            run_path = path.parent_path();
+    }
+
+    std::stringstream stdin_stream;
+    //TODO: when debian stable gets newer g++ version that supports move on streams, remove unique_ptr below
+    auto stdout_stream = std::make_unique<std::stringstream>();
+    auto command = Config::get().project.ctags_command + exclude +
+                   " --fields=ns --sort=foldcase -I \"override noexcept\" -f - -R *";
+    Terminal::get().process(stdin_stream, *stdout_stream, command, run_path);
+    return {run_path, std::move(stdout_stream)};
 }
 
 Ctags::Location Ctags::get_location(const std::string &line, bool markup) {
-  Location location;
+    Location location;
 
 #ifdef _WIN32
-  auto line_fixed=line;
-  if(!line_fixed.empty() && line_fixed.back()=='\r')
-    line_fixed.pop_back();
+    auto line_fixed = line;
+    if (!line_fixed.empty() && line_fixed.back() == '\r')
+        line_fixed.pop_back();
 #else
-  auto &line_fixed=line;
+    auto &line_fixed=line;
 #endif
 
-  const static std::regex regex("^([^\t]+)\t([^\t]+)\t(?:/\\^)?([ \t]*)(.+?)(\\$/)?;\"\tline:([0-9]+)\t?[a-zA-Z]*:?(.*)$");
-  std::smatch sm;
-  if(std::regex_match(line_fixed, sm, regex)) {
-    location.symbol=sm[1].str();
-    //fix location.symbol for operators
-    if(9<location.symbol.size() && location.symbol[8]==' ' && location.symbol.compare(0, 8, "operator")==0) {
-      auto &chr=location.symbol[9];
-      if(!((chr>='a' && chr<='z') || (chr>='A' && chr<='Z') || (chr>='0' && chr<='9') || chr=='_'))
-        location.symbol.erase(8, 1);
-    }
-    
-    location.file_path=sm[2].str();
-    location.source=sm[4].str();
-    try {
-      location.line=std::stoul(sm[6])-1;
-    }
-    catch(const std::exception&) {
-      location.line=0;
-    }
-    location.scope=sm[7].str();
-    if(!sm[5].str().empty()) {
-      location.index=sm[3].str().size();
-      
-      size_t pos=location.source.find(location.symbol);
-      if(pos!=std::string::npos)
-        location.index+=pos;
-      
-      if(markup) {
-        location.source=Glib::Markup::escape_text(location.source);
-        auto symbol=Glib::Markup::escape_text(location.symbol);
-        pos=-1;
-        while((pos=location.source.find(symbol, pos+1))!=std::string::npos) {
-          location.source.insert(pos+symbol.size(), "</b>");
-          location.source.insert(pos, "<b>");
-          pos+=7+symbol.size();
+    const static std::regex regex(
+            "^([^\t]+)\t([^\t]+)\t(?:/\\^)?([ \t]*)(.+?)(\\$/)?;\"\tline:([0-9]+)\t?[a-zA-Z]*:?(.*)$");
+    std::smatch sm;
+    if (std::regex_match(line_fixed, sm, regex)) {
+        location.symbol = sm[1].str();
+        //fix location.symbol for operators
+        if (9 < location.symbol.size() && location.symbol[8] == ' ' && location.symbol.compare(0, 8, "operator") == 0) {
+            auto &chr = location.symbol[9];
+            if (!((chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr == '_'))
+                location.symbol.erase(8, 1);
         }
-      }
-    }
-    else {
-      location.index=0;
-      location.source=location.symbol;
-      if(markup)
-        location.source="<b>"+Glib::Markup::escape_text(location.source)+"</b>";
-    }
-  }
-  else
-    std::cerr << "Warning (ctags): please report to the juCi++ project that the following line was not parsed:\n" << line << std::endl;
-  
-  return location;
+
+        location.file_path = sm[2].str();
+        location.source = sm[4].str();
+        try {
+            location.line = std::stoul(sm[6]) - 1;
+        }
+        catch (const std::exception &) {
+            location.line = 0;
+        }
+        location.scope = sm[7].str();
+        if (!sm[5].str().empty()) {
+            location.index = sm[3].str().size();
+
+            size_t pos = location.source.find(location.symbol);
+            if (pos != std::string::npos)
+                location.index += pos;
+
+            if (markup) {
+                location.source = Glib::Markup::escape_text(location.source);
+                auto symbol = Glib::Markup::escape_text(location.symbol);
+                pos = -1;
+                while ((pos = location.source.find(symbol, pos + 1)) != std::string::npos) {
+                    location.source.insert(pos + symbol.size(), "</b>");
+                    location.source.insert(pos, "<b>");
+                    pos += 7 + symbol.size();
+                }
+            }
+        } else {
+            location.index = 0;
+            location.source = location.symbol;
+            if (markup)
+                location.source = "<b>" + Glib::Markup::escape_text(location.source) + "</b>";
+        }
+    } else
+        std::cerr << "Warning (ctags): please report to the juCi++ project that the following line was not parsed:\n"
+                  << line << std::endl;
+
+    return location;
 }
 
 ///Split up a type into its various significant parts
 std::vector<std::string> Ctags::get_type_parts(const std::string type) {
-  std::vector<std::string> parts;
-  size_t text_start=-1;
-  for(size_t c=0;c<type.size();++c) {
-    auto &chr=type[c];
-    if((chr>='0' && chr<='9') || (chr>='a' && chr<='z') || (chr>='A' && chr<='Z') || chr=='_' || chr=='~') {
-      if(text_start==static_cast<size_t>(-1))
-        text_start=c;
-    }
-    else {
-      if(text_start!=static_cast<size_t>(-1)) {
-        parts.emplace_back(type.substr(text_start, c-text_start));
-        text_start=-1;
-      }
-      if(chr=='*' || chr=='&')
-        parts.emplace_back(std::string()+chr);
+    std::vector<std::string> parts;
+    size_t text_start = -1;
+    for (size_t c = 0; c < type.size(); ++c) {
+        auto &chr = type[c];
+        if ((chr >= '0' && chr <= '9') || (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || chr == '_' ||
+            chr == '~') {
+            if (text_start == static_cast<size_t>(-1))
+                text_start = c;
+        } else {
+            if (text_start != static_cast<size_t>(-1)) {
+                parts.emplace_back(type.substr(text_start, c - text_start));
+                text_start = -1;
+            }
+            if (chr == '*' || chr == '&')
+                parts.emplace_back(std::string() + chr);
+        }
     }
-  }
-  return parts;
+    return parts;
 }
 
-std::vector<Ctags::Location> Ctags::get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type) {
-  auto result=get_result(path);
-  result.second->seekg(0, std::ios::end);
-  if(result.second->tellg()==0)
-    return std::vector<Location>();
-  result.second->seekg(0, std::ios::beg);
-  
-  //insert name into type
-  size_t c=0;
-  size_t bracket_count=0;
-  for(;c<type.size();++c) {
-    if(type[c]=='<')
-      ++bracket_count;
-    else if(type[c]=='>')
-      --bracket_count;
-    else if(bracket_count==0 && type[c]=='(')
-      break;
-  }
-  auto full_type=type;
-  full_type.insert(c, name);
-  
-  auto parts=get_type_parts(full_type);
-  
-  std::string line;
-  long best_score=LONG_MIN;
-  std::vector<Location> best_locations;
-  while(std::getline(*result.second, line)) {
-    if(line.size()>2048)
-      continue;
-    auto location=Ctags::get_location(line, false);
-    if(!location.scope.empty()) {
-      if(location.scope+"::"+location.symbol!=name)
-        continue;
+std::vector<Ctags::Location>
+Ctags::get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type) {
+    auto result = get_result(path);
+    result.second->seekg(0, std::ios::end);
+    if (result.second->tellg() == 0)
+        return std::vector<Location>();
+    result.second->seekg(0, std::ios::beg);
+
+    //insert name into type
+    size_t c = 0;
+    size_t bracket_count = 0;
+    for (; c < type.size(); ++c) {
+        if (type[c] == '<')
+            ++bracket_count;
+        else if (type[c] == '>')
+            --bracket_count;
+        else if (bracket_count == 0 && type[c] == '(')
+            break;
     }
-    else if(location.symbol!=name)
-      continue;
-    
-    location.file_path=result.first/location.file_path;
-    
-    auto source_parts=get_type_parts(location.source);
-    
-    //Find match score
-    long score=0;
-    size_t source_index=0;
-    for(auto &part: parts) {
-      bool found=false;
-      for(auto c=source_index;c<source_parts.size();++c) {
-        if(part==source_parts[c]) {
-          source_index=c+1;
-          ++score;
-          found=true;
-          break;
+    auto full_type = type;
+    full_type.insert(c, name);
+
+    auto parts = get_type_parts(full_type);
+
+    std::string line;
+    long best_score = LONG_MIN;
+    std::vector<Location> best_locations;
+    while (std::getline(*result.second, line)) {
+        if (line.size() > 2048)
+            continue;
+        auto location = Ctags::get_location(line, false);
+        if (!location.scope.empty()) {
+            if (location.scope + "::" + location.symbol != name)
+                continue;
+        } else if (location.symbol != name)
+            continue;
+
+        location.file_path = result.first / location.file_path;
+
+        auto source_parts = get_type_parts(location.source);
+
+        //Find match score
+        long score = 0;
+        size_t source_index = 0;
+        for (auto &part: parts) {
+            bool found = false;
+            for (auto c = source_index; c < source_parts.size(); ++c) {
+                if (part == source_parts[c]) {
+                    source_index = c + 1;
+                    ++score;
+                    found = true;
+                    break;
+                }
+            }
+            if (!found)
+                --score;
         }
-      }
-      if(!found)
-        --score;
-    }
-    size_t index=0;
-    for(auto &source_part: source_parts) {
-      bool found=false;
-      for(auto c=index;c<parts.size();++c) {
-        if(source_part==parts[c]) {
-          index=c+1;
-          ++score;
-          found=true;
-          break;
+        size_t index = 0;
+        for (auto &source_part: source_parts) {
+            bool found = false;
+            for (auto c = index; c < parts.size(); ++c) {
+                if (source_part == parts[c]) {
+                    index = c + 1;
+                    ++score;
+                    found = true;
+                    break;
+                }
+            }
+            if (!found)
+                --score;
         }
-      }
-      if(!found)
-        --score;
-    }
-    
-    if(score>best_score) {
-      best_score=score;
-      best_locations.clear();
-      best_locations.emplace_back(location);
+
+        if (score > best_score) {
+            best_score = score;
+            best_locations.clear();
+            best_locations.emplace_back(location);
+        } else if (score == best_score)
+            best_locations.emplace_back(location);
     }
-    else if(score==best_score)
-      best_locations.emplace_back(location);
-  }
-  
-  return best_locations;
+
+    return best_locations;
 }
diff --git a/src/ctags.h b/src/ctags.h
index f39ddfb2..0d0aefad 100644
--- a/src/ctags.h
+++ b/src/ctags.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <string>
 #include <boost/filesystem.hpp>
 #include <sstream>
@@ -6,22 +7,26 @@
 
 class Ctags {
 public:
-  class Location {
-  public:
-    boost::filesystem::path file_path;
-    unsigned long line;
-    unsigned long index;
-    std::string symbol;
-    std::string scope;
-    std::string source;
-    operator bool() const { return !file_path.empty(); }
-  };
-  
-  static std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> > get_result(const boost::filesystem::path &path);
-  
-  static Location get_location(const std::string &line, bool markup);
-  
-  static std::vector<Location> get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type);
+    class Location {
+    public:
+        boost::filesystem::path file_path;
+        unsigned long line;
+        unsigned long index;
+        std::string symbol;
+        std::string scope;
+        std::string source;
+
+        operator bool() const { return !file_path.empty(); }
+    };
+
+    static std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> >
+    get_result(const boost::filesystem::path &path);
+
+    static Location get_location(const std::string &line, bool markup);
+
+    static std::vector<Location>
+    get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type);
+
 private:
-  static std::vector<std::string> get_type_parts(const std::string type);
+    static std::vector<std::string> get_type_parts(const std::string type);
 };
diff --git a/src/debug_lldb.cc b/src/debug_lldb.cc
index f70b3aaa..7bfa7172 100644
--- a/src/debug_lldb.cc
+++ b/src/debug_lldb.cc
@@ -1,8 +1,10 @@
 #include "debug_lldb.h"
 #include <stdio.h>
+
 #ifdef __APPLE__
 #include <stdlib.h>
 #endif
+
 #include <boost/filesystem.hpp>
 #include <iostream>
 #include "terminal.h"
@@ -13,519 +15,529 @@
 extern char **environ;
 
 void log(const char *msg, void *) {
-  std::cout << "debugger log: " << msg << std::endl;
+    std::cout << "debugger log: " << msg << std::endl;
 }
 
-Debug::LLDB::LLDB(): state(lldb::StateType::eStateInvalid), buffer_size(131072) {
-  if(!getenv("LLDB_DEBUGSERVER_PATH")) {
+Debug::LLDB::LLDB() : state(lldb::StateType::eStateInvalid), buffer_size(131072) {
+    if (!getenv("LLDB_DEBUGSERVER_PATH")) {
 #ifdef __APPLE__
-    std::string debug_server_path("/usr/local/opt/llvm/bin/debugserver");
-    if(boost::filesystem::exists(debug_server_path))
-      setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
+        std::string debug_server_path("/usr/local/opt/llvm/bin/debugserver");
+        if(boost::filesystem::exists(debug_server_path))
+          setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
 #else
-    auto debug_server_path = filesystem::get_executable("lldb-server").string();
-    if(debug_server_path != "lldb-server")
-      setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
+        auto debug_server_path = filesystem::get_executable("lldb-server").string();
+        if (debug_server_path != "lldb-server")
+            setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
 #endif
-  }
+    }
 }
 
-std::tuple<std::vector<std::string>, std::string, std::vector<std::string> > Debug::LLDB::parse_run_arguments(const std::string &command) {
-  std::vector<std::string> environment;
-  std::string executable;
-  std::vector<std::string> arguments;
-  
-  size_t start_pos=std::string::npos;
-  bool quote=false;
-  bool double_quote=false;
-  size_t backslash_count=0;
-  for(size_t c=0;c<=command.size();c++) { 
-    if(c==command.size() || (!quote && !double_quote && backslash_count%2==0 && command[c]==' ')) {
-      if(c>0 && start_pos!=std::string::npos) {
-        auto argument=command.substr(start_pos, c-start_pos);
-        if(executable.empty()) {
-          //Check for environment variable
-          bool env_arg=false;
-          for(size_t c=0;c<argument.size();++c) {
-            if((argument[c]>='a' && argument[c]<='z') || (argument[c]>='A' && argument[c]<='Z') ||
-               (argument[c]>='0' && argument[c]<='9') || argument[c]=='_')
-              continue;
-            else if(argument[c]=='=' && c+1<argument.size()) {
-              environment.emplace_back(argument.substr(0, c+1)+filesystem::unescape_argument(argument.substr(c+1)));
-              env_arg=true;
-              break;
-            }
-            else
-              break;
-          }
-          
-          if(!env_arg) {
-            executable=filesystem::unescape_argument(argument);
+std::tuple<std::vector<std::string>, std::string, std::vector<std::string> >
+Debug::LLDB::parse_run_arguments(const std::string &command) {
+    std::vector<std::string> environment;
+    std::string executable;
+    std::vector<std::string> arguments;
+
+    size_t start_pos = std::string::npos;
+    bool quote = false;
+    bool double_quote = false;
+    size_t backslash_count = 0;
+    for (size_t c = 0; c <= command.size(); c++) {
+        if (c == command.size() || (!quote && !double_quote && backslash_count % 2 == 0 && command[c] == ' ')) {
+            if (c > 0 && start_pos != std::string::npos) {
+                auto argument = command.substr(start_pos, c - start_pos);
+                if (executable.empty()) {
+                    //Check for environment variable
+                    bool env_arg = false;
+                    for (size_t c = 0; c < argument.size(); ++c) {
+                        if ((argument[c] >= 'a' && argument[c] <= 'z') || (argument[c] >= 'A' && argument[c] <= 'Z') ||
+                            (argument[c] >= '0' && argument[c] <= '9') || argument[c] == '_')
+                            continue;
+                        else if (argument[c] == '=' && c + 1 < argument.size()) {
+                            environment.emplace_back(
+                                    argument.substr(0, c + 1) + filesystem::unescape_argument(argument.substr(c + 1)));
+                            env_arg = true;
+                            break;
+                        } else
+                            break;
+                    }
+
+                    if (!env_arg) {
+                        executable = filesystem::unescape_argument(argument);
 #ifdef _WIN32
-            if(remote_host.empty())
-              executable+=".exe";
+                        if (remote_host.empty())
+                            executable += ".exe";
 #endif
-          }
-        }
+                    }
+                } else
+                    arguments.emplace_back(filesystem::unescape_argument(argument));
+                start_pos = std::string::npos;
+            }
+        } else if (command[c] == '\'' && backslash_count % 2 == 0 && !double_quote)
+            quote = !quote;
+        else if (command[c] == '"' && backslash_count % 2 == 0 && !quote)
+            double_quote = !double_quote;
+        else if (command[c] == '\\' && !quote && !double_quote)
+            ++backslash_count;
         else
-          arguments.emplace_back(filesystem::unescape_argument(argument));
-        start_pos=std::string::npos;
-      }
+            backslash_count = 0;
+        if (c < command.size() && start_pos == std::string::npos && command[c] != ' ')
+            start_pos = c;
     }
-    else if(command[c]=='\'' && backslash_count%2==0 && !double_quote)
-      quote=!quote;
-    else if(command[c]=='"' && backslash_count%2==0 && !quote)
-      double_quote=!double_quote;
-    else if(command[c]=='\\' && !quote && !double_quote)
-      ++backslash_count;
-    else
-      backslash_count=0;
-    if(c<command.size() && start_pos==std::string::npos && command[c]!=' ')
-      start_pos=c;
-  }
-  
-  return std::make_tuple(environment, executable, arguments);
+
+    return std::make_tuple(environment, executable, arguments);
 }
 
 void Debug::LLDB::start(const std::string &command, const boost::filesystem::path &path,
-                  const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints,
-                  const std::vector<std::string> &startup_commands, const std::string &remote_host) {
-  if(!debugger) {
-    lldb::SBDebugger::Initialize();
-    debugger=std::make_unique<lldb::SBDebugger>(lldb::SBDebugger::Create(true, log, nullptr));
-    listener=std::make_unique<lldb::SBListener>("juCi++ lldb listener");
-  }
-  
-  //Create executable string and argument array
-  auto parsed_run_arguments=parse_run_arguments(command);
-  auto &environment_from_arguments=std::get<0>(parsed_run_arguments);
-  auto &executable=std::get<1>(parsed_run_arguments);
-  auto &arguments=std::get<2>(parsed_run_arguments);
-  
-  std::vector<const char*> argv;
-  for(size_t c=0;c<arguments.size();c++)
-    argv.emplace_back(arguments[c].c_str());
-  argv.emplace_back(nullptr);
-  
-  auto target=debugger->CreateTarget(executable.c_str());
-  if(!target.IsValid()) {
-    Terminal::get().async_print("Error (debug): Could not create debug target to: "+executable+'\n', true);
-    for(auto &handler: on_exit)
-      handler(-1);
-    return;
-  }
-  
-  //Set breakpoints
-  for(auto &breakpoint: breakpoints) {
-    if(!(target.BreakpointCreateByLocation(breakpoint.first.string().c_str(), breakpoint.second)).IsValid()) {
-      Terminal::get().async_print("Error (debug): Could not create breakpoint at: "+breakpoint.first.string()+":"+std::to_string(breakpoint.second)+'\n', true);
-      for(auto &handler: on_exit)
-        handler(-1);
-      return;
+                        const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints,
+                        const std::vector<std::string> &startup_commands, const std::string &remote_host) {
+    if (!debugger) {
+        lldb::SBDebugger::Initialize();
+        debugger = std::make_unique<lldb::SBDebugger>(lldb::SBDebugger::Create(true, log, nullptr));
+        listener = std::make_unique<lldb::SBListener>("juCi++ lldb listener");
     }
-  }
-  
-  lldb::SBError error;
-  if(!remote_host.empty()) {
-    auto connect_string="connect://"+remote_host;
-    process = std::make_unique<lldb::SBProcess>(target.ConnectRemote(*listener, connect_string.c_str(), "gdb-remote", error));
-    if(error.Fail()) {
-      Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true);
-      for(auto &handler: on_exit)
-        handler(-1);
-      return;
+
+    //Create executable string and argument array
+    auto parsed_run_arguments = parse_run_arguments(command);
+    auto &environment_from_arguments = std::get<0>(parsed_run_arguments);
+    auto &executable = std::get<1>(parsed_run_arguments);
+    auto &arguments = std::get<2>(parsed_run_arguments);
+
+    std::vector<const char *> argv;
+    for (size_t c = 0; c < arguments.size(); c++)
+        argv.emplace_back(arguments[c].c_str());
+    argv.emplace_back(nullptr);
+
+    auto target = debugger->CreateTarget(executable.c_str());
+    if (!target.IsValid()) {
+        Terminal::get().async_print("Error (debug): Could not create debug target to: " + executable + '\n', true);
+        for (auto &handler: on_exit)
+            handler(-1);
+        return;
     }
-    lldb::SBEvent event;
-    while(true) {
-      if(listener->GetNextEvent(event)) {
-        if((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged)>0) {
-          auto state=process->GetStateFromEvent(event);
-          this->state=state;
-          if(state==lldb::StateType::eStateConnected)
-            break;
+
+    //Set breakpoints
+    for (auto &breakpoint: breakpoints) {
+        if (!(target.BreakpointCreateByLocation(breakpoint.first.string().c_str(), breakpoint.second)).IsValid()) {
+            Terminal::get().async_print(
+                    "Error (debug): Could not create breakpoint at: " + breakpoint.first.string() + ":" +
+                    std::to_string(breakpoint.second) + '\n', true);
+            for (auto &handler: on_exit)
+                handler(-1);
+            return;
         }
-      }
     }
-    
-    // Create environment array
-    std::vector<const char*> environment;
-    for(auto &e: environment_from_arguments)
-      environment.emplace_back(e.c_str());
-    environment.emplace_back(nullptr);
-    
-    process->RemoteLaunch(argv.data(), environment.data(), nullptr, nullptr, nullptr, nullptr, lldb::eLaunchFlagNone, false, error);
-    if(!error.Fail())
-      process->Continue();
-  }
-  else {
-    // Create environment array
-    std::vector<const char*> environment;
-    for(auto &e: environment_from_arguments)
-      environment.emplace_back(e.c_str());
-    size_t environ_size=0;
-    while(environ[environ_size]!=nullptr)
-      ++environ_size;
-    for(size_t c=0;c<environ_size;++c)
-      environment.emplace_back(environ[c]);
-    environment.emplace_back(nullptr);
-    
-    process = std::make_unique<lldb::SBProcess>(target.Launch(*listener, argv.data(), environment.data(), nullptr, nullptr, nullptr, path.string().c_str(), lldb::eLaunchFlagNone, false, error));
-  }
-  if(error.Fail()) {
-    Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true);
-    for(auto &handler: on_exit)
-      handler(-1);
-    return;
-  }
-  if(debug_thread.joinable())
-    debug_thread.join();
-  for(auto &handler: on_start)
-    handler(*process);
-  
-  for(auto &command: startup_commands) {
-    lldb::SBCommandReturnObject command_return_object;
-    debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, false);
-  }
-  
-  debug_thread=std::thread([this]() {
-    lldb::SBEvent event;
-    while(true) {
-      std::unique_lock<std::mutex> lock(mutex);
-      if(listener->GetNextEvent(event)) {
-        if((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged)>0) {
-          auto state=process->GetStateFromEvent(event);
-          this->state=state;
-          
-          if(state==lldb::StateType::eStateStopped) {
-            for(uint32_t c=0;c<process->GetNumThreads();c++) {
-              auto thread=process->GetThreadAtIndex(c);
-              if(thread.GetStopReason()>=2) {
-                process->SetSelectedThreadByIndexID(thread.GetIndexID());
-                break;
-              }
-            }
-          }
-          
-          lock.unlock();
-          for(auto &handler: on_event)
-            handler(event);
-          lock.lock();
-          
-          if(state==lldb::StateType::eStateExited || state==lldb::StateType::eStateCrashed) {
-            auto exit_status=state==lldb::StateType::eStateCrashed?-1:process->GetExitStatus();
-            lock.unlock();
-            for(auto &handler: on_exit)
-              handler(exit_status);
-            lock.lock();
-            process.reset();
-            this->state=lldb::StateType::eStateInvalid;
+
+    lldb::SBError error;
+    if (!remote_host.empty()) {
+        auto connect_string = "connect://" + remote_host;
+        process = std::make_unique<lldb::SBProcess>(
+                target.ConnectRemote(*listener, connect_string.c_str(), "gdb-remote", error));
+        if (error.Fail()) {
+            Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
+            for (auto &handler: on_exit)
+                handler(-1);
             return;
-          }
         }
-        if((event.GetType() & lldb::SBProcess::eBroadcastBitSTDOUT)>0) {
-          char buffer[buffer_size];
-          size_t n;
-          while((n=process->GetSTDOUT(buffer, buffer_size))!=0)
-            Terminal::get().async_print(std::string(buffer, n));
-        }
-        //TODO: for some reason stderr is redirected to stdout
-        if((event.GetType() & lldb::SBProcess::eBroadcastBitSTDERR)>0) {
-          char buffer[buffer_size];
-          size_t n;
-          while((n=process->GetSTDERR(buffer, buffer_size))!=0)
-            Terminal::get().async_print(std::string(buffer, n), true);
+        lldb::SBEvent event;
+        while (true) {
+            if (listener->GetNextEvent(event)) {
+                if ((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged) > 0) {
+                    auto state = process->GetStateFromEvent(event);
+                    this->state = state;
+                    if (state == lldb::StateType::eStateConnected)
+                        break;
+                }
+            }
         }
-      }
-      lock.unlock();
-      std::this_thread::sleep_for(std::chrono::milliseconds(200));
+
+        // Create environment array
+        std::vector<const char *> environment;
+        for (auto &e: environment_from_arguments)
+            environment.emplace_back(e.c_str());
+        environment.emplace_back(nullptr);
+
+        process->RemoteLaunch(argv.data(), environment.data(), nullptr, nullptr, nullptr, nullptr,
+                              lldb::eLaunchFlagNone, false, error);
+        if (!error.Fail())
+            process->Continue();
+    } else {
+        // Create environment array
+        std::vector<const char *> environment;
+        for (auto &e: environment_from_arguments)
+            environment.emplace_back(e.c_str());
+        size_t environ_size = 0;
+        while (environ[environ_size] != nullptr)
+            ++environ_size;
+        for (size_t c = 0; c < environ_size; ++c)
+            environment.emplace_back(environ[c]);
+        environment.emplace_back(nullptr);
+
+        process = std::make_unique<lldb::SBProcess>(
+                target.Launch(*listener, argv.data(), environment.data(), nullptr, nullptr, nullptr,
+                              path.string().c_str(), lldb::eLaunchFlagNone, false, error));
     }
-  });
+    if (error.Fail()) {
+        Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
+        for (auto &handler: on_exit)
+            handler(-1);
+        return;
+    }
+    if (debug_thread.joinable())
+        debug_thread.join();
+    for (auto &handler: on_start)
+        handler(*process);
+
+    for (auto &command: startup_commands) {
+        lldb::SBCommandReturnObject command_return_object;
+        debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, false);
+    }
+
+    debug_thread = std::thread([this]() {
+        lldb::SBEvent event;
+        while (true) {
+            std::unique_lock<std::mutex> lock(mutex);
+            if (listener->GetNextEvent(event)) {
+                if ((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged) > 0) {
+                    auto state = process->GetStateFromEvent(event);
+                    this->state = state;
+
+                    if (state == lldb::StateType::eStateStopped) {
+                        for (uint32_t c = 0; c < process->GetNumThreads(); c++) {
+                            auto thread = process->GetThreadAtIndex(c);
+                            if (thread.GetStopReason() >= 2) {
+                                process->SetSelectedThreadByIndexID(thread.GetIndexID());
+                                break;
+                            }
+                        }
+                    }
+
+                    lock.unlock();
+                    for (auto &handler: on_event)
+                        handler(event);
+                    lock.lock();
+
+                    if (state == lldb::StateType::eStateExited || state == lldb::StateType::eStateCrashed) {
+                        auto exit_status = state == lldb::StateType::eStateCrashed ? -1 : process->GetExitStatus();
+                        lock.unlock();
+                        for (auto &handler: on_exit)
+                            handler(exit_status);
+                        lock.lock();
+                        process.reset();
+                        this->state = lldb::StateType::eStateInvalid;
+                        return;
+                    }
+                }
+                if ((event.GetType() & lldb::SBProcess::eBroadcastBitSTDOUT) > 0) {
+                    char buffer[buffer_size];
+                    size_t n;
+                    while ((n = process->GetSTDOUT(buffer, buffer_size)) != 0)
+                        Terminal::get().async_print(std::string(buffer, n));
+                }
+                //TODO: for some reason stderr is redirected to stdout
+                if ((event.GetType() & lldb::SBProcess::eBroadcastBitSTDERR) > 0) {
+                    char buffer[buffer_size];
+                    size_t n;
+                    while ((n = process->GetSTDERR(buffer, buffer_size)) != 0)
+                        Terminal::get().async_print(std::string(buffer, n), true);
+                }
+            }
+            lock.unlock();
+            std::this_thread::sleep_for(std::chrono::milliseconds(200));
+        }
+    });
 }
 
 void Debug::LLDB::continue_debug() {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped)
-    process->Continue();
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped)
+        process->Continue();
 }
 
 void Debug::LLDB::stop() {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateRunning) {
-    auto error=process->Stop();
-    if(error.Fail())
-      Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true);
-  }
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateRunning) {
+        auto error = process->Stop();
+        if (error.Fail())
+            Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
+    }
 }
 
 void Debug::LLDB::kill() {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(process) {
-    auto error=process->Kill();
-    if(error.Fail())
-      Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true);
-  }
+    std::unique_lock<std::mutex> lock(mutex);
+    if (process) {
+        auto error = process->Kill();
+        if (error.Fail())
+            Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
+    }
 }
 
 void Debug::LLDB::step_over() {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped) {
-    process->GetSelectedThread().StepOver();
-  }
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped) {
+        process->GetSelectedThread().StepOver();
+    }
 }
 
 void Debug::LLDB::step_into() {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped) {
-    process->GetSelectedThread().StepInto();
-  }
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped) {
+        process->GetSelectedThread().StepInto();
+    }
 }
 
 void Debug::LLDB::step_out() {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped) {
-    process->GetSelectedThread().StepOut();
-  }
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped) {
+        process->GetSelectedThread().StepOut();
+    }
 }
 
 std::pair<std::string, std::string> Debug::LLDB::run_command(const std::string &command) {
-  std::pair<std::string, std::string> command_return;
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped || state==lldb::StateType::eStateRunning) {
-    lldb::SBCommandReturnObject command_return_object;
-    debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, true);
-    auto output=command_return_object.GetOutput();
-    if(output)
-      command_return.first=output;
-    auto error=command_return_object.GetError();
-    if(error)
-      command_return.second=error;
-  }
-  return command_return;
+    std::pair<std::string, std::string> command_return;
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped || state == lldb::StateType::eStateRunning) {
+        lldb::SBCommandReturnObject command_return_object;
+        debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, true);
+        auto output = command_return_object.GetOutput();
+        if (output)
+            command_return.first = output;
+        auto error = command_return_object.GetError();
+        if (error)
+            command_return.second = error;
+    }
+    return command_return;
 }
 
 std::vector<Debug::LLDB::Frame> Debug::LLDB::get_backtrace() {
-  std::vector<Frame> backtrace;
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped) {
-    auto thread=process->GetSelectedThread();
-    for(uint32_t c_f=0;c_f<thread.GetNumFrames();c_f++) {
-      Frame backtrace_frame;
-      auto frame=thread.GetFrameAtIndex(c_f);
-      
-      backtrace_frame.index=c_f;
-      
-      if(frame.GetFunctionName()!=nullptr)
-        backtrace_frame.function_name=frame.GetFunctionName();
-      
-      auto module_filename=frame.GetModule().GetFileSpec().GetFilename();
-      if(module_filename!=nullptr) {
-        backtrace_frame.module_filename=module_filename;
-      }
-      
-      auto line_entry=frame.GetLineEntry();
-      if(line_entry.IsValid()) {
-        lldb::SBStream stream;
-        line_entry.GetFileSpec().GetDescription(stream);
-        auto column=line_entry.GetColumn();
-        if(column==0)
-          column=1;
-        backtrace_frame.file_path=filesystem::get_normal_path(stream.GetData());
-        backtrace_frame.line_nr=line_entry.GetLine();
-        backtrace_frame.line_index=column;
-      }
-      backtrace.emplace_back(backtrace_frame);
+    std::vector<Frame> backtrace;
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped) {
+        auto thread = process->GetSelectedThread();
+        for (uint32_t c_f = 0; c_f < thread.GetNumFrames(); c_f++) {
+            Frame backtrace_frame;
+            auto frame = thread.GetFrameAtIndex(c_f);
+
+            backtrace_frame.index = c_f;
+
+            if (frame.GetFunctionName() != nullptr)
+                backtrace_frame.function_name = frame.GetFunctionName();
+
+            auto module_filename = frame.GetModule().GetFileSpec().GetFilename();
+            if (module_filename != nullptr) {
+                backtrace_frame.module_filename = module_filename;
+            }
+
+            auto line_entry = frame.GetLineEntry();
+            if (line_entry.IsValid()) {
+                lldb::SBStream stream;
+                line_entry.GetFileSpec().GetDescription(stream);
+                auto column = line_entry.GetColumn();
+                if (column == 0)
+                    column = 1;
+                backtrace_frame.file_path = filesystem::get_normal_path(stream.GetData());
+                backtrace_frame.line_nr = line_entry.GetLine();
+                backtrace_frame.line_index = column;
+            }
+            backtrace.emplace_back(backtrace_frame);
+        }
     }
-  }
-  return backtrace;
+    return backtrace;
 }
 
 std::vector<Debug::LLDB::Variable> Debug::LLDB::get_variables() {
-  std::vector<Debug::LLDB::Variable> variables;
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped) {
-    for(uint32_t c_t=0;c_t<process->GetNumThreads();c_t++) {
-      auto thread=process->GetThreadAtIndex(c_t);
-      for(uint32_t c_f=0;c_f<thread.GetNumFrames();c_f++) {
-        auto frame=thread.GetFrameAtIndex(c_f);
-        auto values=frame.GetVariables(true, true, true, false);
-        for(uint32_t value_index=0;value_index<values.GetSize();value_index++) {
-          lldb::SBStream stream;
-          auto value=values.GetValueAtIndex(value_index);
-        
-          Debug::LLDB::Variable variable;
-          variable.thread_index_id=thread.GetIndexID();
-          variable.frame_index=c_f;
-          if(value.GetName()!=nullptr)
-            variable.name=value.GetName();
-          value.GetDescription(stream);
-          variable.value=stream.GetData();
-          
-          auto declaration=value.GetDeclaration();
-          if(declaration.IsValid()) {
-            variable.declaration_found=true;
-            variable.line_nr=declaration.GetLine();
-            variable.line_index=declaration.GetColumn();
-            if(variable.line_index==0)
-              variable.line_index=1;
-            
-            auto file_spec=declaration.GetFileSpec();
-            variable.file_path=filesystem::get_normal_path(file_spec.GetDirectory());
-            variable.file_path/=file_spec.GetFilename();
-          }
-          else {
-            variable.declaration_found=false;
-            auto line_entry=frame.GetLineEntry();
-            if(line_entry.IsValid()) {
-              variable.line_nr=line_entry.GetLine();
-              variable.line_index=line_entry.GetColumn();
-              if(variable.line_index==0)
-                variable.line_index=1;
-              
-              auto file_spec=line_entry.GetFileSpec();
-              variable.file_path=filesystem::get_normal_path(file_spec.GetDirectory());
-              variable.file_path/=file_spec.GetFilename();
+    std::vector<Debug::LLDB::Variable> variables;
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped) {
+        for (uint32_t c_t = 0; c_t < process->GetNumThreads(); c_t++) {
+            auto thread = process->GetThreadAtIndex(c_t);
+            for (uint32_t c_f = 0; c_f < thread.GetNumFrames(); c_f++) {
+                auto frame = thread.GetFrameAtIndex(c_f);
+                auto values = frame.GetVariables(true, true, true, false);
+                for (uint32_t value_index = 0; value_index < values.GetSize(); value_index++) {
+                    lldb::SBStream stream;
+                    auto value = values.GetValueAtIndex(value_index);
+
+                    Debug::LLDB::Variable variable;
+                    variable.thread_index_id = thread.GetIndexID();
+                    variable.frame_index = c_f;
+                    if (value.GetName() != nullptr)
+                        variable.name = value.GetName();
+                    value.GetDescription(stream);
+                    variable.value = stream.GetData();
+
+                    auto declaration = value.GetDeclaration();
+                    if (declaration.IsValid()) {
+                        variable.declaration_found = true;
+                        variable.line_nr = declaration.GetLine();
+                        variable.line_index = declaration.GetColumn();
+                        if (variable.line_index == 0)
+                            variable.line_index = 1;
+
+                        auto file_spec = declaration.GetFileSpec();
+                        variable.file_path = filesystem::get_normal_path(file_spec.GetDirectory());
+                        variable.file_path /= file_spec.GetFilename();
+                    } else {
+                        variable.declaration_found = false;
+                        auto line_entry = frame.GetLineEntry();
+                        if (line_entry.IsValid()) {
+                            variable.line_nr = line_entry.GetLine();
+                            variable.line_index = line_entry.GetColumn();
+                            if (variable.line_index == 0)
+                                variable.line_index = 1;
+
+                            auto file_spec = line_entry.GetFileSpec();
+                            variable.file_path = filesystem::get_normal_path(file_spec.GetDirectory());
+                            variable.file_path /= file_spec.GetFilename();
+                        }
+                    }
+                    variables.emplace_back(variable);
+                }
             }
-          }
-          variables.emplace_back(variable);
         }
-      }
     }
-  }
-  return variables;
+    return variables;
 }
 
 void Debug::LLDB::select_frame(uint32_t frame_index, uint32_t thread_index_id) {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped) {
-    if(thread_index_id!=0)
-      process->SetSelectedThreadByIndexID(thread_index_id);
-    process->GetSelectedThread().SetSelectedFrame(frame_index);;
-  }
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped) {
+        if (thread_index_id != 0)
+            process->SetSelectedThreadByIndexID(thread_index_id);
+        process->GetSelectedThread().SetSelectedFrame(frame_index);;
+    }
 }
 
 void Debug::LLDB::cancel() {
-  kill();
-  if(debug_thread.joinable())
-    debug_thread.join();
+    kill();
+    if (debug_thread.joinable())
+        debug_thread.join();
 }
 
-std::string Debug::LLDB::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) {
-  std::string variable_value;
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped) {
-    auto frame=process->GetSelectedThread().GetSelectedFrame();
-    
-    auto values=frame.GetVariables(true, true, true, false);
-    //First try to find variable based on name, file and line number
-    if(!file_path.empty()) {
-      for(uint32_t value_index=0;value_index<values.GetSize();value_index++) {
-        lldb::SBStream stream;
-        auto value=values.GetValueAtIndex(value_index);
-  
-        if(value.GetName()!=nullptr && value.GetName()==variable) {
-          auto declaration=value.GetDeclaration();
-          if(declaration.IsValid()) {
-            if(declaration.GetLine()==line_nr && (declaration.GetColumn()==0 || declaration.GetColumn()==line_index)) {
-              auto file_spec=declaration.GetFileSpec();
-              auto value_decl_path=filesystem::get_normal_path(file_spec.GetDirectory());
-              value_decl_path/=file_spec.GetFilename();
-              if(value_decl_path==file_path) {
+std::string
+Debug::LLDB::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr,
+                       unsigned int line_index) {
+    std::string variable_value;
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped) {
+        auto frame = process->GetSelectedThread().GetSelectedFrame();
+
+        auto values = frame.GetVariables(true, true, true, false);
+        //First try to find variable based on name, file and line number
+        if (!file_path.empty()) {
+            for (uint32_t value_index = 0; value_index < values.GetSize(); value_index++) {
+                lldb::SBStream stream;
+                auto value = values.GetValueAtIndex(value_index);
+
+                if (value.GetName() != nullptr && value.GetName() == variable) {
+                    auto declaration = value.GetDeclaration();
+                    if (declaration.IsValid()) {
+                        if (declaration.GetLine() == line_nr &&
+                            (declaration.GetColumn() == 0 || declaration.GetColumn() == line_index)) {
+                            auto file_spec = declaration.GetFileSpec();
+                            auto value_decl_path = filesystem::get_normal_path(file_spec.GetDirectory());
+                            value_decl_path /= file_spec.GetFilename();
+                            if (value_decl_path == file_path) {
+                                value.GetDescription(stream);
+                                variable_value = stream.GetData();
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (variable_value.empty()) {
+            //In case a variable is missing file and line number, only do check on name
+            auto value = frame.GetValueForVariablePath(variable.c_str());
+            if (value.IsValid()) {
+                lldb::SBStream stream;
                 value.GetDescription(stream);
-                variable_value=stream.GetData();
-                break;
-              }
+                variable_value = stream.GetData();
             }
-          }
         }
-      }
-    }
-    if(variable_value.empty()) {
-      //In case a variable is missing file and line number, only do check on name
-      auto value=frame.GetValueForVariablePath(variable.c_str());
-      if(value.IsValid()) {
-        lldb::SBStream stream;
-        value.GetDescription(stream);
-        variable_value=stream.GetData();
-      }
     }
-  }
-  return variable_value;
+    return variable_value;
 }
 
-std::string Debug::LLDB::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) {
-  std::string return_value;
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateStopped) {
-    auto thread=process->GetSelectedThread();
-    auto thread_return_value=thread.GetStopReturnValue();
-    if(thread_return_value.IsValid()) {
-      auto line_entry=thread.GetSelectedFrame().GetLineEntry();
-      if(line_entry.IsValid()) {
-        lldb::SBStream stream;
-        line_entry.GetFileSpec().GetDescription(stream);
-        if(filesystem::get_normal_path(stream.GetData())==file_path && line_entry.GetLine()==line_nr &&
-           (line_entry.GetColumn()==0 || line_entry.GetColumn()==line_index)) {
-          lldb::SBStream stream;
-          thread_return_value.GetDescription(stream);
-          return_value=stream.GetData();
+std::string
+Debug::LLDB::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) {
+    std::string return_value;
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateStopped) {
+        auto thread = process->GetSelectedThread();
+        auto thread_return_value = thread.GetStopReturnValue();
+        if (thread_return_value.IsValid()) {
+            auto line_entry = thread.GetSelectedFrame().GetLineEntry();
+            if (line_entry.IsValid()) {
+                lldb::SBStream stream;
+                line_entry.GetFileSpec().GetDescription(stream);
+                if (filesystem::get_normal_path(stream.GetData()) == file_path && line_entry.GetLine() == line_nr &&
+                    (line_entry.GetColumn() == 0 || line_entry.GetColumn() == line_index)) {
+                    lldb::SBStream stream;
+                    thread_return_value.GetDescription(stream);
+                    return_value = stream.GetData();
+                }
+            }
         }
-      }
     }
-  }
-  return return_value;
+    return return_value;
 }
 
 bool Debug::LLDB::is_invalid() {
-  std::unique_lock<std::mutex> lock(mutex);
-  return state==lldb::StateType::eStateInvalid;
+    std::unique_lock<std::mutex> lock(mutex);
+    return state == lldb::StateType::eStateInvalid;
 }
 
 bool Debug::LLDB::is_stopped() {
-  std::unique_lock<std::mutex> lock(mutex);
-  return state==lldb::StateType::eStateStopped;
+    std::unique_lock<std::mutex> lock(mutex);
+    return state == lldb::StateType::eStateStopped;
 }
 
 bool Debug::LLDB::is_running() {
-  std::unique_lock<std::mutex> lock(mutex);
-  return state==lldb::StateType::eStateRunning;
+    std::unique_lock<std::mutex> lock(mutex);
+    return state == lldb::StateType::eStateRunning;
 }
 
 void Debug::LLDB::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::eStateStopped || state==lldb::eStateRunning) {
-    if(!(process->GetTarget().BreakpointCreateByLocation(file_path.string().c_str(), line_nr)).IsValid())
-      Terminal::get().async_print("Error (debug): Could not create breakpoint at: "+file_path.string()+":"+std::to_string(line_nr)+'\n', true);
-  }
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::eStateStopped || state == lldb::eStateRunning) {
+        if (!(process->GetTarget().BreakpointCreateByLocation(file_path.string().c_str(), line_nr)).IsValid())
+            Terminal::get().async_print("Error (debug): Could not create breakpoint at: " + file_path.string() + ":" +
+                                        std::to_string(line_nr) + '\n', true);
+    }
 }
 
 void Debug::LLDB::remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::eStateStopped || state==lldb::eStateRunning) {
-    auto target=process->GetTarget();
-    for(int line_nr_try=line_nr;line_nr_try<line_count;line_nr_try++) {
-      for(uint32_t b_index=0;b_index<target.GetNumBreakpoints();b_index++) {
-        auto breakpoint=target.GetBreakpointAtIndex(b_index);
-        for(uint32_t l_index=0;l_index<breakpoint.GetNumLocations();l_index++) {
-          auto line_entry=breakpoint.GetLocationAtIndex(l_index).GetAddress().GetLineEntry();
-          if(line_entry.GetLine()==static_cast<uint32_t>(line_nr_try)) {
-            auto file_spec=line_entry.GetFileSpec();
-            auto breakpoint_path=filesystem::get_normal_path(file_spec.GetDirectory());
-            breakpoint_path/=file_spec.GetFilename();
-            if(breakpoint_path==file_path) {
-              if(!target.BreakpointDelete(breakpoint.GetID()))
-                Terminal::get().async_print("Error (debug): Could not delete breakpoint at: "+file_path.string()+":"+std::to_string(line_nr)+'\n', true);
-              return;
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::eStateStopped || state == lldb::eStateRunning) {
+        auto target = process->GetTarget();
+        for (int line_nr_try = line_nr; line_nr_try < line_count; line_nr_try++) {
+            for (uint32_t b_index = 0; b_index < target.GetNumBreakpoints(); b_index++) {
+                auto breakpoint = target.GetBreakpointAtIndex(b_index);
+                for (uint32_t l_index = 0; l_index < breakpoint.GetNumLocations(); l_index++) {
+                    auto line_entry = breakpoint.GetLocationAtIndex(l_index).GetAddress().GetLineEntry();
+                    if (line_entry.GetLine() == static_cast<uint32_t>(line_nr_try)) {
+                        auto file_spec = line_entry.GetFileSpec();
+                        auto breakpoint_path = filesystem::get_normal_path(file_spec.GetDirectory());
+                        breakpoint_path /= file_spec.GetFilename();
+                        if (breakpoint_path == file_path) {
+                            if (!target.BreakpointDelete(breakpoint.GetID()))
+                                Terminal::get().async_print(
+                                        "Error (debug): Could not delete breakpoint at: " + file_path.string() + ":" +
+                                        std::to_string(line_nr) + '\n', true);
+                            return;
+                        }
+                    }
+                }
             }
-          }
         }
-      }
     }
-  }
 }
 
 void Debug::LLDB::write(const std::string &buffer) {
-  std::unique_lock<std::mutex> lock(mutex);
-  if(state==lldb::StateType::eStateRunning) {
-    process->PutSTDIN(buffer.c_str(), buffer.size());
-  }
+    std::unique_lock<std::mutex> lock(mutex);
+    if (state == lldb::StateType::eStateRunning) {
+        process->PutSTDIN(buffer.c_str(), buffer.size());
+    }
 }
diff --git a/src/debug_lldb.h b/src/debug_lldb.h
index 42560c3f..1b948a7b 100644
--- a/src/debug_lldb.h
+++ b/src/debug_lldb.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <boost/filesystem.hpp>
 #include <list>
 #include <lldb/API/LLDB.h>
@@ -7,82 +8,102 @@
 #include <tuple>
 
 namespace Debug {
-  class LLDB {
-  public:
-    class Frame {
+    class LLDB {
     public:
-      uint32_t index;
-      std::string module_filename;
-      boost::filesystem::path file_path;
-      std::string function_name;
-      int line_nr;
-      int line_index;
-    };
-    class Variable {
+        class Frame {
+        public:
+            uint32_t index;
+            std::string module_filename;
+            boost::filesystem::path file_path;
+            std::string function_name;
+            int line_nr;
+            int line_index;
+        };
+
+        class Variable {
+        public:
+            uint32_t thread_index_id;
+            uint32_t frame_index;
+            std::string name;
+            std::string value;
+            bool declaration_found;
+            boost::filesystem::path file_path;
+            int line_nr;
+            int line_index;
+        };
+
+    private:
+        LLDB();
+
     public:
-      uint32_t thread_index_id;
-      uint32_t frame_index;
-      std::string name;
-      std::string value;
-      bool declaration_found;
-      boost::filesystem::path file_path;
-      int line_nr;
-      int line_index;
+        static LLDB &get() {
+            static LLDB singleton;
+            return singleton;
+        }
+
+        std::list<std::function<void(const lldb::SBProcess &)>> on_start;
+        /// The handlers are not run in the main loop.
+        std::list<std::function<void(int exit_status)>> on_exit;
+        /// The handlers are not run in the main loop.
+        std::list<std::function<void(const lldb::SBEvent &)>> on_event;
+
+        std::mutex mutex;
+
+        void start(const std::string &command, const boost::filesystem::path &path = "",
+                   const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints = {},
+                   const std::vector<std::string> &startup_commands = {}, const std::string &remote_host = "");
+
+        void continue_debug(); //can't use continue as function name
+        void stop();
+
+        void kill();
+
+        void step_over();
+
+        void step_into();
+
+        void step_out();
+
+        std::pair<std::string, std::string> run_command(const std::string &command);
+
+        std::vector<Frame> get_backtrace();
+
+        std::vector<Variable> get_variables();
+
+        void select_frame(uint32_t frame_index, uint32_t thread_index_id = 0);
+
+        void cancel();
+
+        std::string
+        get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr,
+                  unsigned int line_index);
+
+        std::string
+        get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index);
+
+        bool is_invalid();
+
+        bool is_stopped();
+
+        bool is_running();
+
+        void add_breakpoint(const boost::filesystem::path &file_path, int line_nr);
+
+        void remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count);
+
+        void write(const std::string &buffer);
+
+    private:
+        std::tuple<std::vector<std::string>, std::string, std::vector<std::string>>
+        parse_run_arguments(const std::string &command);
+
+        std::unique_ptr<lldb::SBDebugger> debugger;
+        std::unique_ptr<lldb::SBListener> listener;
+        std::unique_ptr<lldb::SBProcess> process;
+        std::thread debug_thread;
+
+        lldb::StateType state;
+
+        size_t buffer_size;
     };
-  private:
-    LLDB();
-  public:
-    static LLDB &get() {
-      static LLDB singleton;
-      return singleton;
-    }
-    
-    std::list<std::function<void(const lldb::SBProcess &)>> on_start;
-    /// The handlers are not run in the main loop.
-    std::list<std::function<void(int exit_status)>> on_exit;
-    /// The handlers are not run in the main loop.
-    std::list<std::function<void(const lldb::SBEvent &)>> on_event;
-    
-    std::mutex mutex;
-
-    void start(const std::string &command, const boost::filesystem::path &path="",
-               const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints={},
-               const std::vector<std::string> &startup_commands={}, const std::string &remote_host="");
-    void continue_debug(); //can't use continue as function name
-    void stop();
-    void kill();
-    void step_over();
-    void step_into();
-    void step_out();
-    std::pair<std::string, std::string> run_command(const std::string &command);
-    std::vector<Frame> get_backtrace();
-    std::vector<Variable> get_variables();
-    void select_frame(uint32_t frame_index, uint32_t thread_index_id=0);
-    
-    void cancel();
-    
-    std::string get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index);
-    std::string get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index);
-    
-    bool is_invalid();
-    bool is_stopped();
-    bool is_running();
-    
-    void add_breakpoint(const boost::filesystem::path &file_path, int line_nr);
-    void remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count);
-    
-    void write(const std::string &buffer);
-    
-  private:
-    std::tuple<std::vector<std::string>, std::string, std::vector<std::string>> parse_run_arguments(const std::string &command);
-    
-    std::unique_ptr<lldb::SBDebugger> debugger;
-    std::unique_ptr<lldb::SBListener> listener;
-    std::unique_ptr<lldb::SBProcess> process;
-    std::thread debug_thread;
-    
-    lldb::StateType state;
-    
-    size_t buffer_size;
-  };
 }
diff --git a/src/dialogs.cc b/src/dialogs.cc
index ab5bc550..f4194848 100644
--- a/src/dialogs.cc
+++ b/src/dialogs.cc
@@ -1,79 +1,80 @@
 #include "dialogs.h"
 #include <cmath>
 
-Dialog::Message::Message(const std::string &text): Gtk::Window(Gtk::WindowType::WINDOW_POPUP) {
-  auto g_application=g_application_get_default();
-  auto gio_application=Glib::wrap(g_application, true);
-  auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-  set_transient_for(*application->get_active_window());
-  
-  set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);
-  set_modal(true);
-  set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_NOTIFICATION);
-  property_decorated()=false;
-  set_skip_taskbar_hint(true);
-  
-  auto box=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-  auto label=Gtk::manage(new Gtk::Label(text));
-  label->set_padding(10, 10);
-  box->pack_start(*label);
-  add(*box);
-  
-  show_all_children();
-  show_now();
-  
-  while(Gtk::Main::events_pending())
-    Gtk::Main::iteration(false);
+Dialog::Message::Message(const std::string &text) : Gtk::Window(Gtk::WindowType::WINDOW_POPUP) {
+    auto g_application = g_application_get_default();
+    auto gio_application = Glib::wrap(g_application, true);
+    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+    set_transient_for(*application->get_active_window());
+
+    set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);
+    set_modal(true);
+    set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_NOTIFICATION);
+    property_decorated() = false;
+    set_skip_taskbar_hint(true);
+
+    auto box = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+    auto label = Gtk::manage(new Gtk::Label(text));
+    label->set_padding(10, 10);
+    box->pack_start(*label);
+    add(*box);
+
+    show_all_children();
+    show_now();
+
+    while (Gtk::Main::events_pending())
+        Gtk::Main::iteration(false);
 }
 
 bool Dialog::Message::on_delete_event(GdkEventAny *event) {
-  return true;
+    return true;
 }
 
 std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::string &title,
-                        const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
-                        Gtk::FileChooserAction action) {
-  // Workaround for crash on MacOS when filtering files in file/folder dialogs.
-  // See also https://github.com/cppit/jucipp/issues/259.
-  // TODO 2018: check if this bug has been fixed
+                               const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
+                               Gtk::FileChooserAction action) {
+    // Workaround for crash on MacOS when filtering files in file/folder dialogs.
+    // See also https://github.com/cppit/jucipp/issues/259.
+    // TODO 2018: check if this bug has been fixed
 #ifdef __APPLE__
-  class FileChooserDialog : public Gtk::FileChooserDialog {
-    Gtk::FileChooserAction action;
-  public:
-    FileChooserDialog(const Glib::ustring& title, Gtk::FileChooserAction action) : Gtk::FileChooserDialog(title, action), action(action) {}
-  protected:
-    bool on_key_press_event(GdkEventKey *key_event) override {
-      if(action==Gtk::FileChooserAction::FILE_CHOOSER_ACTION_OPEN || action==Gtk::FileChooserAction::FILE_CHOOSER_ACTION_SELECT_FOLDER) {
-        auto unicode=gdk_keyval_to_unicode(key_event->keyval);
-        if(unicode>31 && unicode!=127)
-          return true;
+    class FileChooserDialog : public Gtk::FileChooserDialog {
+      Gtk::FileChooserAction action;
+    public:
+      FileChooserDialog(const Glib::ustring& title, Gtk::FileChooserAction action) : Gtk::FileChooserDialog(title, action), action(action) {}
+    protected:
+      bool on_key_press_event(GdkEventKey *key_event) override {
+        if(action==Gtk::FileChooserAction::FILE_CHOOSER_ACTION_OPEN || action==Gtk::FileChooserAction::FILE_CHOOSER_ACTION_SELECT_FOLDER) {
+          auto unicode=gdk_keyval_to_unicode(key_event->keyval);
+          if(unicode>31 && unicode!=127)
+            return true;
+        }
+        return Gtk::FileChooserDialog::on_key_press_event(key_event);
       }
-      return Gtk::FileChooserDialog::on_key_press_event(key_event);
-    }
-  };
-  FileChooserDialog dialog(title, action);
+    };
+    FileChooserDialog dialog(title, action);
 #else
-  Gtk::FileChooserDialog dialog(title, action);
+    Gtk::FileChooserDialog dialog(title, action);
 #endif
-  
-  auto g_application=g_application_get_default();
-  auto gio_application=Glib::wrap(g_application, true);
-  auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-  dialog.set_transient_for(*application->get_active_window());
-  dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);
-  
-  if(title=="Save File As")
-    gtk_file_chooser_set_filename(reinterpret_cast<GtkFileChooser*>(dialog.gobj()), path.string().c_str());
-  else if(!path.empty())
-    gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser*>(dialog.gobj()), path.string().c_str());
-  else {
-    boost::system::error_code ec;
-    auto current_path=boost::filesystem::current_path(ec);
-    if(!ec)
-      gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser*>(dialog.gobj()), current_path.string().c_str());
-  }
-  
-  for (auto &button : buttons) 
-    dialog.add_button(button.first, button.second);
-  return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : "";
+
+    auto g_application = g_application_get_default();
+    auto gio_application = Glib::wrap(g_application, true);
+    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+    dialog.set_transient_for(*application->get_active_window());
+    dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);
+
+    if (title == "Save File As")
+        gtk_file_chooser_set_filename(reinterpret_cast<GtkFileChooser *>(dialog.gobj()), path.string().c_str());
+    else if (!path.empty())
+        gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser *>(dialog.gobj()), path.string().c_str());
+    else {
+        boost::system::error_code ec;
+        auto current_path = boost::filesystem::current_path(ec);
+        if (!ec)
+            gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser *>(dialog.gobj()),
+                                                current_path.string().c_str());
+    }
+
+    for (auto &button : buttons)
+        dialog.add_button(button.first, button.second);
+    return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : "";
 }
diff --git a/src/dialogs.h b/src/dialogs.h
index e1deeb53..b3e57730 100644
--- a/src/dialogs.h
+++ b/src/dialogs.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <string>
 #include <boost/filesystem.hpp>
 #include <vector>
@@ -6,21 +7,26 @@
 
 class Dialog {
 public:
-  static std::string open_folder(const boost::filesystem::path &path);
-  static std::string open_file(const boost::filesystem::path &path);
-  static std::string new_file(const boost::filesystem::path &path);
-  static std::string new_folder(const boost::filesystem::path &path);
-  static std::string save_file_as(const boost::filesystem::path &path);
-  
-  class Message : public Gtk::Window {
-  public:
-    Message(const std::string &text);
-  protected:
-    bool on_delete_event(GdkEventAny *event) override;
-  };
-  
+    static std::string open_folder(const boost::filesystem::path &path);
+
+    static std::string open_file(const boost::filesystem::path &path);
+
+    static std::string new_file(const boost::filesystem::path &path);
+
+    static std::string new_folder(const boost::filesystem::path &path);
+
+    static std::string save_file_as(const boost::filesystem::path &path);
+
+    class Message : public Gtk::Window {
+    public:
+        Message(const std::string &text);
+
+    protected:
+        bool on_delete_event(GdkEventAny *event) override;
+    };
+
 private:
-  static std::string gtk_dialog(const boost::filesystem::path &path, const std::string &title,
-                          const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
-                          Gtk::FileChooserAction gtk_options);
+    static std::string gtk_dialog(const boost::filesystem::path &path, const std::string &title,
+                                  const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
+                                  Gtk::FileChooserAction gtk_options);
 };
diff --git a/src/dialogs_unix.cc b/src/dialogs_unix.cc
index 2512ce8a..865bf3d9 100644
--- a/src/dialogs_unix.cc
+++ b/src/dialogs_unix.cc
@@ -1,32 +1,32 @@
 #include "dialogs.h"
 
 std::string Dialog::open_folder(const boost::filesystem::path &path) {
-  return gtk_dialog(path, "Open Folder",
-            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Open", Gtk::RESPONSE_OK)},
-            Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
+    return gtk_dialog(path, "Open Folder",
+                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Open", Gtk::RESPONSE_OK)},
+                      Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
 }
 
 std::string Dialog::new_file(const boost::filesystem::path &path) {
-  return gtk_dialog(path, "New File",
-            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
-            Gtk::FILE_CHOOSER_ACTION_SAVE);
+    return gtk_dialog(path, "New File",
+                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
+                      Gtk::FILE_CHOOSER_ACTION_SAVE);
 }
 
 std::string Dialog::new_folder(const boost::filesystem::path &path) {
-  return gtk_dialog(path, "New Folder",
-            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)},
-            Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
+    return gtk_dialog(path, "New Folder",
+                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Create", Gtk::RESPONSE_OK)},
+                      Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
 }
 
 std::string Dialog::open_file(const boost::filesystem::path &path) {
-  return gtk_dialog(path, "Open File",
-            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)},
-            Gtk::FILE_CHOOSER_ACTION_OPEN);
+    return gtk_dialog(path, "Open File",
+                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Select", Gtk::RESPONSE_OK)},
+                      Gtk::FILE_CHOOSER_ACTION_OPEN);
 }
 
 std::string Dialog::save_file_as(const boost::filesystem::path &path) {
-  return gtk_dialog(path, "Save File As",
-            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)},
-            Gtk::FILE_CHOOSER_ACTION_SAVE);
+    return gtk_dialog(path, "Save File As",
+                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
+                      Gtk::FILE_CHOOSER_ACTION_SAVE);
 }
 
diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc
index 72d18691..6322a9ae 100644
--- a/src/dialogs_win.cc
+++ b/src/dialogs_win.cc
@@ -12,152 +12,154 @@
 #include <vector>
 
 #include <iostream> //TODO: remove
+
 using namespace std; //TODO: remove
 
 class Win32Dialog {
 public:
-  Win32Dialog() {};
-  
-  ~Win32Dialog() {
-    if(dialog!=nullptr)
-      dialog->Release();
-  }
-  
-  /** Returns the selected item's path as a string */
-  std::string open(const std::wstring &title, unsigned option=0) {
-    if(!init(CLSID_FileOpenDialog))
-      return "";
-    
-    if(!set_title(title) || !add_option(option))
-      return "";
-    if(!set_folder())
-      return "";
-    
-    return show();
-  }
-  
-  std::string save(const std::wstring &title, const boost::filesystem::path &file_path="", unsigned option=0) {
-    if(!init(CLSID_FileSaveDialog))
-      return "";
-    
-    if(!set_title(title) || !add_option(option))
-      return "";
-    if(!set_folder())
-      return "";
-    std::vector<COMDLG_FILTERSPEC> extensions;
-    if(!file_path.empty()) {
-      if(file_path.has_extension() && file_path.filename()!=file_path.extension()) {
-        auto extension=(L"*"+file_path.extension().native()).c_str();
-        extensions.emplace_back(COMDLG_FILTERSPEC{extension, extension});
-        if(!set_default_file_extension(extension))
-          return "";
-      }
+    Win32Dialog() {};
+
+    ~Win32Dialog() {
+        if (dialog != nullptr)
+            dialog->Release();
+    }
+
+    /** Returns the selected item's path as a string */
+    std::string open(const std::wstring &title, unsigned option = 0) {
+        if (!init(CLSID_FileOpenDialog))
+            return "";
+
+        if (!set_title(title) || !add_option(option))
+            return "";
+        if (!set_folder())
+            return "";
+
+        return show();
+    }
+
+    std::string save(const std::wstring &title, const boost::filesystem::path &file_path = "", unsigned option = 0) {
+        if (!init(CLSID_FileSaveDialog))
+            return "";
+
+        if (!set_title(title) || !add_option(option))
+            return "";
+        if (!set_folder())
+            return "";
+        std::vector<COMDLG_FILTERSPEC> extensions;
+        if (!file_path.empty()) {
+            if (file_path.has_extension() && file_path.filename() != file_path.extension()) {
+                auto extension = (L"*" + file_path.extension().native()).c_str();
+                extensions.emplace_back(COMDLG_FILTERSPEC{extension, extension});
+                if (!set_default_file_extension(extension))
+                    return "";
+            }
+        }
+        extensions.emplace_back(COMDLG_FILTERSPEC{L"All files", L"*.*"});
+        if (dialog->SetFileTypes(extensions.size(), extensions.data()) != S_OK)
+            return "";
+
+        return show();
     }
-    extensions.emplace_back(COMDLG_FILTERSPEC{L"All files", L"*.*"});
-    if(dialog->SetFileTypes(extensions.size(), extensions.data())!=S_OK)
-      return "";
-    
-    return show();
-  }
 
 private:
-  IFileDialog *dialog=nullptr;
-  DWORD options;
-  
-  bool init(CLSID type) {
-    if(CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog))!=S_OK)
-      return false;
-    if(dialog->GetOptions(&options)!=S_OK)
-      return false;
-    return true;
-  }
-  
-  /** available options are listed at https://msdn.microsoft.com/en-gb/library/windows/desktop/dn457282(v=vs.85).aspx */
-  bool add_option(unsigned option) {
-    if(dialog->SetOptions(options | option)!=S_OK)
-      return false;
-    return true;
-  }
-  
-  bool set_title(const std::wstring &title) {
-    if(dialog->SetTitle(title.c_str())!=S_OK)
-      return false;
-    return true;
-  }
-  
-  /** Sets the extensions the browser can find */
-  bool set_default_file_extension(const std::wstring &file_extension) {
-    if(dialog->SetDefaultExtension(file_extension.c_str())!=S_OK)
-      return false;
-    return true;
-  }
-  
-  /** Sets the directory to start browsing */
-  bool set_folder() {
-    auto g_application=g_application_get_default(); //TODO: Post issue that Gio::Application::get_default should return pointer and not Glib::RefPtr
-    auto gio_application=Glib::wrap(g_application, true);
-    auto application=Glib::RefPtr<Application>::cast_static(gio_application);
-    
-    auto current_path=application->window->notebook.get_current_folder();
-    boost::system::error_code ec;
-    if(current_path.empty())
-      current_path=boost::filesystem::current_path(ec);
-    if(ec)
-      return false;
-    
-    std::wstring path=current_path.native();
-    size_t pos=0;
-    while((pos=path.find(L'/', pos))!=std::wstring::npos) {//TODO: issue bug report on boost::filesystem::path::native on MSYS2
-      path.replace(pos, 1, L"\\");
-      pos++;
+    IFileDialog *dialog = nullptr;
+    DWORD options;
+
+    bool init(CLSID type) {
+        if (CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog)) != S_OK)
+            return false;
+        if (dialog->GetOptions(&options) != S_OK)
+            return false;
+        return true;
+    }
+
+    /** available options are listed at https://msdn.microsoft.com/en-gb/library/windows/desktop/dn457282(v=vs.85).aspx */
+    bool add_option(unsigned option) {
+        if (dialog->SetOptions(options | option) != S_OK)
+            return false;
+        return true;
+    }
+
+    bool set_title(const std::wstring &title) {
+        if (dialog->SetTitle(title.c_str()) != S_OK)
+            return false;
+        return true;
+    }
+
+    /** Sets the extensions the browser can find */
+    bool set_default_file_extension(const std::wstring &file_extension) {
+        if (dialog->SetDefaultExtension(file_extension.c_str()) != S_OK)
+            return false;
+        return true;
+    }
+
+    /** Sets the directory to start browsing */
+    bool set_folder() {
+        auto g_application = g_application_get_default(); //TODO: Post issue that Gio::Application::get_default should return pointer and not Glib::RefPtr
+        auto gio_application = Glib::wrap(g_application, true);
+        auto application = Glib::RefPtr<Application>::cast_static(gio_application);
+
+        auto current_path = application->window->notebook.get_current_folder();
+        boost::system::error_code ec;
+        if (current_path.empty())
+            current_path = boost::filesystem::current_path(ec);
+        if (ec)
+            return false;
+
+        std::wstring path = current_path.native();
+        size_t pos = 0;
+        while ((pos = path.find(L'/', pos)) !=
+               std::wstring::npos) {//TODO: issue bug report on boost::filesystem::path::native on MSYS2
+            path.replace(pos, 1, L"\\");
+            pos++;
+        }
+
+        IShellItem *folder = nullptr;
+        if (SHCreateItemFromParsingName(path.c_str(), nullptr, IID_PPV_ARGS(&folder)) != S_OK)
+            return false;
+        if (dialog->SetFolder(folder) != S_OK)
+            return false;
+        folder->Release();
+        return true;
+    }
+
+    std::string show() {
+        if (dialog->Show(nullptr) != S_OK)
+            return "";
+        IShellItem *result = nullptr;
+        if (dialog->GetResult(&result) != S_OK)
+            return "";
+        LPWSTR file_path = nullptr;
+        auto hresult = result->GetDisplayName(SIGDN_FILESYSPATH, &file_path);
+        result->Release();
+        if (hresult != S_OK)
+            return "";
+        std::wstring file_path_wstring(file_path);
+        std::string file_path_string(file_path_wstring.begin(), file_path_wstring.end());
+        CoTaskMemFree(file_path);
+        return file_path_string;
     }
-    
-    IShellItem *folder = nullptr;
-    if(SHCreateItemFromParsingName(path.c_str(), nullptr, IID_PPV_ARGS(&folder))!=S_OK)
-      return false;
-    if(dialog->SetFolder(folder)!=S_OK)
-      return false;
-    folder->Release();
-    return true;
-  }
-  
-  std::string show() {
-    if(dialog->Show(nullptr)!=S_OK)
-      return "";
-    IShellItem *result = nullptr;
-    if(dialog->GetResult(&result)!=S_OK)
-      return "";
-    LPWSTR file_path = nullptr; 
-    auto hresult=result->GetDisplayName(SIGDN_FILESYSPATH, &file_path);
-    result->Release();
-    if(hresult!=S_OK)
-      return "";
-    std::wstring file_path_wstring(file_path);
-    std::string file_path_string(file_path_wstring.begin(), file_path_wstring.end());
-    CoTaskMemFree(file_path);
-    return file_path_string;
-  }
 };
 
 std::string Dialog::open_folder() {
-  return Win32Dialog().open(L"Open Folder", FOS_PICKFOLDERS);
+    return Win32Dialog().open(L"Open Folder", FOS_PICKFOLDERS);
 }
 
 std::string Dialog::new_file() {
-  return Win32Dialog().save(L"New File");
+    return Win32Dialog().save(L"New File");
 }
 
 std::string Dialog::new_folder() {
-  //Win32 (IFileDialog) does not support create folder...
-  return gtk_dialog("New Folder",
-                     {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)},
-                     Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
+    //Win32 (IFileDialog) does not support create folder...
+    return gtk_dialog("New Folder",
+                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Create", Gtk::RESPONSE_OK)},
+                      Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
 }
 
 std::string Dialog::open_file() {
-  return  Win32Dialog().open(L"Open File");
+    return Win32Dialog().open(L"Open File");
 }
 
 std::string Dialog::save_file_as(const boost::filesystem::path &file_path) {
-  return Win32Dialog().save(L"Save File As", file_path);
+    return Win32Dialog().save(L"Save File As", file_path);
 }
diff --git a/src/directories.cc b/src/directories.cc
index 0ceb032c..299f379c 100644
--- a/src/directories.cc
+++ b/src/directories.cc
@@ -6,717 +6,726 @@
 #include "filesystem.h"
 #include "entrybox.h"
 
-bool Directories::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path &path, const Gtk::SelectionData &selection_data) const {
-  return true;
+bool Directories::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path &path,
+                                                     const Gtk::SelectionData &selection_data) const {
+    return true;
 }
 
-bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) {
-  auto &directories=Directories::get();
-  
-  auto get_target_folder=[this, &directories](const TreeModel::Path &path) {
-    if(path.size()==1)
-      return directories.path;
-    else {
-      auto it=get_iter(path);
-      if(it) {
-        auto prev_path=path;
-        prev_path.up();
-        it=get_iter(prev_path);
-        if(it)
-          return it->get_value(directories.column_record.path);
-      }
-      else {
-        auto prev_path=path;
-        prev_path.up();
-        if(prev_path.size()==1)
-          return directories.path;
+bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &path,
+                                                      const Gtk::SelectionData &selection_data) {
+    auto &directories = Directories::get();
+
+    auto get_target_folder = [this, &directories](const TreeModel::Path &path) {
+        if (path.size() == 1)
+            return directories.path;
         else {
-          prev_path.up();
-          it=get_iter(prev_path);
-          if(it)
-            return it->get_value(directories.column_record.path);
+            auto it = get_iter(path);
+            if (it) {
+                auto prev_path = path;
+                prev_path.up();
+                it = get_iter(prev_path);
+                if (it)
+                    return it->get_value(directories.column_record.path);
+            } else {
+                auto prev_path = path;
+                prev_path.up();
+                if (prev_path.size() == 1)
+                    return directories.path;
+                else {
+                    prev_path.up();
+                    it = get_iter(prev_path);
+                    if (it)
+                        return it->get_value(directories.column_record.path);
+                }
+            }
         }
-      }
-    }
-    return boost::filesystem::path();
-  };
-  
-  auto it=directories.get_selection()->get_selected();
-  if(it) {
-    auto source_path=it->get_value(directories.column_record.path);
-    if(source_path.empty())
-      return false;
-    
-    auto target_path=get_target_folder(path);
-    target_path/=source_path.filename();
-    
-    if(source_path==target_path)
-      return false;
-    
-    if(boost::filesystem::exists(target_path)) {
-      Terminal::get().print("Error: could not move file: "+target_path.string()+" already exists\n", true);
-      return false;
-    }
-    
-    bool is_directory=boost::filesystem::is_directory(source_path);
-    
-    if(is_directory)
-      Directories::get().remove_path(source_path);
-    
-    boost::system::error_code ec;
-    boost::filesystem::rename(source_path, target_path, ec);
-    if(ec) {
-      Terminal::get().print("Error: could not move file: "+ec.message()+'\n', true);
-      return false;
-    }
-    
-    for(size_t c=0;c<Notebook::get().size();c++) {
-      auto view=Notebook::get().get_view(c);
-      if(is_directory) {
-        if(filesystem::file_in_path(view->file_path, source_path)) {
-          auto file_it=view->file_path.begin();
-          for(auto source_it=source_path.begin();source_it!=source_path.end();source_it++)
-            file_it++;
-          auto new_file_path=target_path;
-          for(;file_it!=view->file_path.end();file_it++)
-            new_file_path/=*file_it;
-          view->rename(new_file_path);
+        return boost::filesystem::path();
+    };
+
+    auto it = directories.get_selection()->get_selected();
+    if (it) {
+        auto source_path = it->get_value(directories.column_record.path);
+        if (source_path.empty())
+            return false;
+
+        auto target_path = get_target_folder(path);
+        target_path /= source_path.filename();
+
+        if (source_path == target_path)
+            return false;
+
+        if (boost::filesystem::exists(target_path)) {
+            Terminal::get().print("Error: could not move file: " + target_path.string() + " already exists\n", true);
+            return false;
+        }
+
+        bool is_directory = boost::filesystem::is_directory(source_path);
+
+        if (is_directory)
+            Directories::get().remove_path(source_path);
+
+        boost::system::error_code ec;
+        boost::filesystem::rename(source_path, target_path, ec);
+        if (ec) {
+            Terminal::get().print("Error: could not move file: " + ec.message() + '\n', true);
+            return false;
+        }
+
+        for (size_t c = 0; c < Notebook::get().size(); c++) {
+            auto view = Notebook::get().get_view(c);
+            if (is_directory) {
+                if (filesystem::file_in_path(view->file_path, source_path)) {
+                    auto file_it = view->file_path.begin();
+                    for (auto source_it = source_path.begin(); source_it != source_path.end(); source_it++)
+                        file_it++;
+                    auto new_file_path = target_path;
+                    for (; file_it != view->file_path.end(); file_it++)
+                        new_file_path /= *file_it;
+                    view->rename(new_file_path);
+                }
+            } else if (view->file_path == source_path) {
+                view->rename(target_path);
+                break;
+            }
         }
-      }
-      else if(view->file_path==source_path) {
-        view->rename(target_path);
-        break;
-      }
+
+        Directories::get().update();
+        Directories::get().on_save_file(target_path);
+        directories.select(target_path);
     }
-    
-    Directories::get().update();
-    Directories::get().on_save_file(target_path);
-    directories.select(target_path);
-  }
-  
-  EntryBox::get().hide();
-  return false;
+
+    EntryBox::get().hide();
+    return false;
 }
 
-bool Directories::TreeStore::drag_data_delete_vfunc (const Gtk::TreeModel::Path &path) {
-  return false;
+bool Directories::TreeStore::drag_data_delete_vfunc(const Gtk::TreeModel::Path &path) {
+    return false;
 }
 
 Directories::Directories() : Gtk::ListViewText(1) {
-  set_enable_tree_lines(true);
-  
-  tree_store = TreeStore::create();
-  tree_store->set_column_types(column_record);
-  set_model(tree_store);
-  
-  get_column(0)->set_title("");
-  
-  auto renderer=dynamic_cast<Gtk::CellRendererText*>(get_column(0)->get_first_cell());
-  get_column(0)->set_cell_data_func(*renderer, [this] (Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &iter) {
-    if(auto renderer_text=dynamic_cast<Gtk::CellRendererText*>(renderer))
-      renderer_text->property_markup()=iter->get_value(column_record.markup);
-  });
-  
-  get_style_context()->add_class("juci_directories");
-  
-  tree_store->set_sort_column(column_record.id, Gtk::SortType::SORT_ASCENDING);
-  set_enable_search(true); //TODO: why does this not work in OS X?
-  set_search_column(column_record.name);
-  
-  signal_row_activated().connect([this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column){
-    auto iter = tree_store->get_iter(path);
-    if (iter) {
-      auto filesystem_path=iter->get_value(column_record.path);
-      if(filesystem_path!="") {
-        if (boost::filesystem::is_directory(boost::filesystem::path(filesystem_path)))
-          row_expanded(path) ? collapse_row(path) : expand_row(path, false);
-        else
-          Notebook::get().open(filesystem_path);
-      }
-    }
-  });
-  
-  signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path){
-    if(iter->children().begin()->get_value(column_record.path)=="")
-      add_or_update_path(iter->get_value(column_record.path), *iter, true);
-    return false;
-  });
-  signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path){
-    this->remove_path(iter->get_value(column_record.path));
-  });
-  
-  enable_model_drag_source();
-  enable_model_drag_dest();
-  
-  auto new_file_label = "New File";
-  auto new_file_function = [this] {
-    if(menu_popup_row_path.empty())
-      return;
-    EntryBox::get().clear();
-    EntryBox::get().entries.emplace_back("", [this, source_path=menu_popup_row_path](const std::string &content) {
-      bool is_directory=boost::filesystem::is_directory(source_path);
-      auto target_path = (is_directory ? source_path : source_path.parent_path())/content;
-      if(!boost::filesystem::exists(target_path)) {
-        if(filesystem::write(target_path, "")) {
-          update();
-          Notebook::get().open(target_path);
-          on_save_file(target_path);
-        }
-        else {
-          Terminal::get().print("Error: could not create "+target_path.string()+'\n', true);
-          return;
+    set_enable_tree_lines(true);
+
+    tree_store = TreeStore::create();
+    tree_store->set_column_types(column_record);
+    set_model(tree_store);
+
+    get_column(0)->set_title("");
+
+    auto renderer = dynamic_cast<Gtk::CellRendererText *>(get_column(0)->get_first_cell());
+    get_column(0)->set_cell_data_func(*renderer,
+                                      [this](Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &iter) {
+                                          if (auto renderer_text = dynamic_cast<Gtk::CellRendererText *>(renderer))
+                                              renderer_text->property_markup() = iter->get_value(column_record.markup);
+                                      });
+
+    get_style_context()->add_class("juci_directories");
+
+    tree_store->set_sort_column(column_record.id, Gtk::SortType::SORT_ASCENDING);
+    set_enable_search(true); //TODO: why does this not work in OS X?
+    set_search_column(column_record.name);
+
+    signal_row_activated().connect([this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column) {
+        auto iter = tree_store->get_iter(path);
+        if (iter) {
+            auto filesystem_path = iter->get_value(column_record.path);
+            if (filesystem_path != "") {
+                if (boost::filesystem::is_directory(boost::filesystem::path(filesystem_path)))
+                    row_expanded(path) ? collapse_row(path) : expand_row(path, false);
+                else
+                    Notebook::get().open(filesystem_path);
+            }
         }
-      }
-      else {
-        Terminal::get().print("Error: could not create "+target_path.string()+": already exists\n", true);
-        return;
-      }
-      
-      EntryBox::get().hide();
     });
-    auto entry_it=EntryBox::get().entries.begin();
-    entry_it->set_placeholder_text("Filename");
-    EntryBox::get().buttons.emplace_back("Create New File", [entry_it](){
-      entry_it->activate();
+
+    signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) {
+        if (iter->children().begin()->get_value(column_record.path) == "")
+            add_or_update_path(iter->get_value(column_record.path), *iter, true);
+        return false;
     });
-    EntryBox::get().show();
-  };
-  
-  menu_item_new_file.set_label(new_file_label);
-  menu_item_new_file.signal_activate().connect(new_file_function);
-  menu.append(menu_item_new_file);
-  
-  menu_root_item_new_file.set_label(new_file_label);
-  menu_root_item_new_file.signal_activate().connect(new_file_function);
-  menu_root.append(menu_root_item_new_file);
-  
-  auto new_folder_label = "New Folder";
-  auto new_folder_function = [this] {
-    if(menu_popup_row_path.empty())
-      return;
-    EntryBox::get().clear();
-    EntryBox::get().entries.emplace_back("", [this, source_path=menu_popup_row_path](const std::string &content) {
-      bool is_directory=boost::filesystem::is_directory(source_path);
-      auto target_path = (is_directory ? source_path : source_path.parent_path())/content;
-      if(!boost::filesystem::exists(target_path)) {
-        boost::system::error_code ec;
-        boost::filesystem::create_directory(target_path, ec);
-        if(!ec) {
-          update();
-          select(target_path);
-        }
-        else {
-          Terminal::get().print("Error: could not create "+target_path.string()+": "+ec.message(), true);
-          return;
-        }
-      }
-      else {
-        Terminal::get().print("Error: could not create "+target_path.string()+": already exists\n", true);
-        return;
-      }
-      
-      EntryBox::get().hide();
+    signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) {
+        this->remove_path(iter->get_value(column_record.path));
     });
-    auto entry_it=EntryBox::get().entries.begin();
-    entry_it->set_placeholder_text("Folder name");
-    EntryBox::get().buttons.emplace_back("Create New Folder", [entry_it](){
-      entry_it->activate();
+
+    enable_model_drag_source();
+    enable_model_drag_dest();
+
+    auto new_file_label = "New File";
+    auto new_file_function = [this] {
+        if (menu_popup_row_path.empty())
+            return;
+        EntryBox::get().clear();
+        EntryBox::get().entries.emplace_back("", [this, source_path = menu_popup_row_path](const std::string &content) {
+            bool is_directory = boost::filesystem::is_directory(source_path);
+            auto target_path = (is_directory ? source_path : source_path.parent_path()) / content;
+            if (!boost::filesystem::exists(target_path)) {
+                if (filesystem::write(target_path, "")) {
+                    update();
+                    Notebook::get().open(target_path);
+                    on_save_file(target_path);
+                } else {
+                    Terminal::get().print("Error: could not create " + target_path.string() + '\n', true);
+                    return;
+                }
+            } else {
+                Terminal::get().print("Error: could not create " + target_path.string() + ": already exists\n", true);
+                return;
+            }
+
+            EntryBox::get().hide();
+        });
+        auto entry_it = EntryBox::get().entries.begin();
+        entry_it->set_placeholder_text("Filename");
+        EntryBox::get().buttons.emplace_back("Create New File", [entry_it]() {
+            entry_it->activate();
+        });
+        EntryBox::get().show();
+    };
+
+    menu_item_new_file.set_label(new_file_label);
+    menu_item_new_file.signal_activate().connect(new_file_function);
+    menu.append(menu_item_new_file);
+
+    menu_root_item_new_file.set_label(new_file_label);
+    menu_root_item_new_file.signal_activate().connect(new_file_function);
+    menu_root.append(menu_root_item_new_file);
+
+    auto new_folder_label = "New Folder";
+    auto new_folder_function = [this] {
+        if (menu_popup_row_path.empty())
+            return;
+        EntryBox::get().clear();
+        EntryBox::get().entries.emplace_back("", [this, source_path = menu_popup_row_path](const std::string &content) {
+            bool is_directory = boost::filesystem::is_directory(source_path);
+            auto target_path = (is_directory ? source_path : source_path.parent_path()) / content;
+            if (!boost::filesystem::exists(target_path)) {
+                boost::system::error_code ec;
+                boost::filesystem::create_directory(target_path, ec);
+                if (!ec) {
+                    update();
+                    select(target_path);
+                } else {
+                    Terminal::get().print("Error: could not create " + target_path.string() + ": " + ec.message(),
+                                          true);
+                    return;
+                }
+            } else {
+                Terminal::get().print("Error: could not create " + target_path.string() + ": already exists\n", true);
+                return;
+            }
+
+            EntryBox::get().hide();
+        });
+        auto entry_it = EntryBox::get().entries.begin();
+        entry_it->set_placeholder_text("Folder name");
+        EntryBox::get().buttons.emplace_back("Create New Folder", [entry_it]() {
+            entry_it->activate();
+        });
+        EntryBox::get().show();
+    };
+
+    menu_item_new_folder.set_label(new_folder_label);
+    menu_item_new_folder.signal_activate().connect(new_folder_function);
+    menu.append(menu_item_new_folder);
+
+    menu_root_item_new_folder.set_label(new_folder_label);
+    menu_root_item_new_folder.signal_activate().connect(new_folder_function);
+    menu_root.append(menu_root_item_new_folder);
+
+    menu.append(menu_item_separator);
+
+    menu_item_rename.set_label("Rename");
+    menu_item_rename.signal_activate().connect([this] {
+        if (menu_popup_row_path.empty())
+            return;
+        EntryBox::get().clear();
+        EntryBox::get().entries.emplace_back(menu_popup_row_path.filename().string(),
+                                             [this, source_path = menu_popup_row_path](const std::string &content) {
+                                                 bool is_directory = boost::filesystem::is_directory(source_path);
+
+                                                 auto target_path = source_path.parent_path() / content;
+
+                                                 if (boost::filesystem::exists(target_path)) {
+                                                     Terminal::get().print(
+                                                             "Error: could not rename to " + target_path.string() +
+                                                             ": already exists\n", true);
+                                                     return;
+                                                 }
+
+                                                 if (is_directory)
+                                                     this->remove_path(source_path);
+
+                                                 boost::system::error_code ec;
+                                                 boost::filesystem::rename(source_path, target_path, ec);
+                                                 if (ec) {
+                                                     Terminal::get().print(
+                                                             "Error: could not rename " + source_path.string() + ": " +
+                                                             ec.message() + '\n', true);
+                                                     return;
+                                                 }
+                                                 update();
+                                                 on_save_file(target_path);
+                                                 select(target_path);
+
+                                                 for (size_t c = 0; c < Notebook::get().size(); c++) {
+                                                     auto view = Notebook::get().get_view(c);
+                                                     if (is_directory) {
+                                                         if (filesystem::file_in_path(view->file_path, source_path)) {
+                                                             auto file_it = view->file_path.begin();
+                                                             for (auto source_it = source_path.begin();
+                                                                  source_it != source_path.end(); source_it++)
+                                                                 file_it++;
+                                                             auto new_file_path = target_path;
+                                                             for (; file_it != view->file_path.end(); file_it++)
+                                                                 new_file_path /= *file_it;
+                                                             view->rename(new_file_path);
+                                                         }
+                                                     } else if (view->file_path == source_path) {
+                                                         view->rename(target_path);
+
+                                                         std::string old_language_id;
+                                                         if (view->language)
+                                                             old_language_id = view->language->get_id();
+                                                         view->language = Source::guess_language(target_path);
+                                                         std::string new_language_id;
+                                                         if (view->language)
+                                                             new_language_id = view->language->get_id();
+                                                         if (new_language_id != old_language_id)
+                                                             Terminal::get().print(
+                                                                     "Warning: language for " + target_path.string() +
+                                                                     " has changed. Please reopen the file\n");
+                                                     }
+                                                 }
+
+                                                 EntryBox::get().hide();
+                                             });
+        auto entry_it = EntryBox::get().entries.begin();
+        entry_it->set_placeholder_text("Filename");
+        EntryBox::get().buttons.emplace_back("Rename file", [entry_it]() {
+            entry_it->activate();
+        });
+        EntryBox::get().show();
     });
-    EntryBox::get().show();
-  };
-  
-  menu_item_new_folder.set_label(new_folder_label);
-  menu_item_new_folder.signal_activate().connect(new_folder_function);
-  menu.append(menu_item_new_folder);
-  
-  menu_root_item_new_folder.set_label(new_folder_label);
-  menu_root_item_new_folder.signal_activate().connect(new_folder_function);
-  menu_root.append(menu_root_item_new_folder);
-  
-  menu.append(menu_item_separator);
-  
-  menu_item_rename.set_label("Rename");
-  menu_item_rename.signal_activate().connect([this] {
-    if(menu_popup_row_path.empty())
-      return;
-    EntryBox::get().clear();
-    EntryBox::get().entries.emplace_back(menu_popup_row_path.filename().string(), [this, source_path=menu_popup_row_path](const std::string &content){
-      bool is_directory=boost::filesystem::is_directory(source_path);
-      
-      auto target_path=source_path.parent_path()/content;
-      
-      if(boost::filesystem::exists(target_path)) {
-        Terminal::get().print("Error: could not rename to "+target_path.string()+": already exists\n", true);
-        return;
-      }
-      
-      if(is_directory)
-        this->remove_path(source_path);
-      
-      boost::system::error_code ec;
-      boost::filesystem::rename(source_path, target_path, ec);
-      if(ec) {
-        Terminal::get().print("Error: could not rename "+source_path.string()+": "+ec.message()+'\n', true);
-        return;
-      }
-      update();
-      on_save_file(target_path);
-      select(target_path);
-      
-      for(size_t c=0;c<Notebook::get().size();c++) {
-        auto view=Notebook::get().get_view(c);
-        if(is_directory) {
-          if(filesystem::file_in_path(view->file_path, source_path)) {
-            auto file_it=view->file_path.begin();
-            for(auto source_it=source_path.begin();source_it!=source_path.end();source_it++)
-              file_it++;
-            auto new_file_path=target_path;
-            for(;file_it!=view->file_path.end();file_it++)
-              new_file_path/=*file_it;
-            view->rename(new_file_path);
-          }
-        }
-        else if(view->file_path==source_path) {
-          view->rename(target_path);
-          
-          std::string old_language_id;
-          if(view->language)
-            old_language_id=view->language->get_id();
-          view->language=Source::guess_language(target_path);
-          std::string new_language_id;
-          if(view->language)
-            new_language_id=view->language->get_id();
-          if(new_language_id!=old_language_id)
-            Terminal::get().print("Warning: language for "+target_path.string()+" has changed. Please reopen the file\n");
+    menu.append(menu_item_rename);
+
+    menu_item_delete.set_label("Delete");
+    menu_item_delete.signal_activate().connect([this] {
+        if (menu_popup_row_path.empty())
+            return;
+        Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(get_toplevel()), "Delete!", false, Gtk::MESSAGE_QUESTION,
+                                  Gtk::BUTTONS_YES_NO);
+        dialog.set_default_response(Gtk::RESPONSE_NO);
+        dialog.set_secondary_text("Are you sure you want to delete " + menu_popup_row_path.string() + "?");
+        int result = dialog.run();
+        if (result == Gtk::RESPONSE_YES) {
+            bool is_directory = boost::filesystem::is_directory(menu_popup_row_path);
+
+            boost::system::error_code ec;
+            boost::filesystem::remove_all(menu_popup_row_path, ec);
+            if (ec)
+                Terminal::get().print(
+                        "Error: could not delete " + menu_popup_row_path.string() + ": " + ec.message() + "\n", true);
+            else {
+                update();
+
+                for (size_t c = 0; c < Notebook::get().size(); c++) {
+                    auto view = Notebook::get().get_view(c);
+
+                    if (is_directory) {
+                        if (filesystem::file_in_path(view->file_path, menu_popup_row_path))
+                            view->get_buffer()->set_modified();
+                    } else if (view->file_path == menu_popup_row_path)
+                        view->get_buffer()->set_modified();
+                }
+            }
         }
-      }
-      
-      EntryBox::get().hide();
     });
-    auto entry_it=EntryBox::get().entries.begin();
-    entry_it->set_placeholder_text("Filename");
-    EntryBox::get().buttons.emplace_back("Rename file", [entry_it](){
-      entry_it->activate();
-    });
-    EntryBox::get().show();
-  });
-  menu.append(menu_item_rename);
-  
-  menu_item_delete.set_label("Delete");
-  menu_item_delete.signal_activate().connect([this] {
-    if(menu_popup_row_path.empty())
-      return;
-    Gtk::MessageDialog dialog(*static_cast<Gtk::Window*>(get_toplevel()), "Delete!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
-    dialog.set_default_response(Gtk::RESPONSE_NO);
-    dialog.set_secondary_text("Are you sure you want to delete "+menu_popup_row_path.string()+"?");
-    int result = dialog.run();
-    if(result==Gtk::RESPONSE_YES) {
-      bool is_directory=boost::filesystem::is_directory(menu_popup_row_path);
-      
-      boost::system::error_code ec;
-      boost::filesystem::remove_all(menu_popup_row_path, ec);
-      if(ec)
-        Terminal::get().print("Error: could not delete "+menu_popup_row_path.string()+": "+ec.message()+"\n", true);
-      else {
-        update();
-        
-        for(size_t c=0;c<Notebook::get().size();c++) {
-          auto view=Notebook::get().get_view(c);
-          
-          if(is_directory) {
-            if(filesystem::file_in_path(view->file_path, menu_popup_row_path))
-              view->get_buffer()->set_modified();
-          }
-          else if(view->file_path==menu_popup_row_path)
-            view->get_buffer()->set_modified();
-        }
-      }
-    }
-  });
-  menu.append(menu_item_delete);
-  
-  menu.show_all();
-  menu.accelerate(*this);
-  
-  menu_root.show_all();
-  menu_root.accelerate(*this);
-  
-  set_headers_clickable();
-  forall([this](Gtk::Widget &widget) {
-    if(widget.get_name()=="GtkButton") {
-      widget.signal_button_press_event().connect([this](GdkEventButton *event) {
-        if(event->type==GDK_BUTTON_PRESS && event->button==GDK_BUTTON_SECONDARY && !path.empty()) {
-          menu_popup_row_path=this->path;
-          menu_root.popup(event->button, event->time);
+    menu.append(menu_item_delete);
+
+    menu.show_all();
+    menu.accelerate(*this);
+
+    menu_root.show_all();
+    menu_root.accelerate(*this);
+
+    set_headers_clickable();
+    forall([this](Gtk::Widget &widget) {
+        if (widget.get_name() == "GtkButton") {
+            widget.signal_button_press_event().connect([this](GdkEventButton *event) {
+                if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY && !path.empty()) {
+                    menu_popup_row_path = this->path;
+                    menu_root.popup(event->button, event->time);
+                }
+                return true;
+            });
         }
-        return true;
-      });
-    }
-  });
+    });
 }
 
 Directories::~Directories() {
-  dispatcher.disconnect();
+    dispatcher.disconnect();
 }
 
 void Directories::open(const boost::filesystem::path &dir_path) {
-  boost::system::error_code ec;
-  if(dir_path.empty() || !boost::filesystem::exists(dir_path, ec) || ec)
-    return;
-  
-  tree_store->clear();
-  
-  path=filesystem::get_normal_path(dir_path);
-  
-  //TODO: report that set_title does not handle '_' correctly?
-  auto title=path.filename().string();
-  size_t pos=0;
-  while((pos=title.find('_', pos))!=std::string::npos) {
-    title.replace(pos, 1, "__");
-    pos+=2;
-  }
-  get_column(0)->set_title(title);
-
-  for(auto &directory: directories) {
-    if(directory.second.repository)
-      directory.second.repository->clear_saved_status();
-  }
-  directories.clear();
-  
-  add_or_update_path(path, Gtk::TreeModel::Row(), true);
+    boost::system::error_code ec;
+    if (dir_path.empty() || !boost::filesystem::exists(dir_path, ec) || ec)
+        return;
+
+    tree_store->clear();
+
+    path = filesystem::get_normal_path(dir_path);
+
+    //TODO: report that set_title does not handle '_' correctly?
+    auto title = path.filename().string();
+    size_t pos = 0;
+    while ((pos = title.find('_', pos)) != std::string::npos) {
+        title.replace(pos, 1, "__");
+        pos += 2;
+    }
+    get_column(0)->set_title(title);
+
+    for (auto &directory: directories) {
+        if (directory.second.repository)
+            directory.second.repository->clear_saved_status();
+    }
+    directories.clear();
+
+    add_or_update_path(path, Gtk::TreeModel::Row(), true);
 }
 
 void Directories::update() {
-  std::vector<std::pair<std::string, Gtk::TreeModel::Row> > saved_directories;
-  for(auto &directory: directories)
-    saved_directories.emplace_back(directory.first, directory.second.row);
-  for(auto &directory: saved_directories)
-    add_or_update_path(directory.first, directory.second, false);
+    std::vector<std::pair<std::string, Gtk::TreeModel::Row> > saved_directories;
+    for (auto &directory: directories)
+        saved_directories.emplace_back(directory.first, directory.second.row);
+    for (auto &directory: saved_directories)
+        add_or_update_path(directory.first, directory.second, false);
 }
 
 void Directories::on_save_file(boost::filesystem::path file_path) {
-  auto it=directories.find(file_path.parent_path().string());
-  if(it!=directories.end()) {
-    if(it->second.repository)
-      it->second.repository->clear_saved_status();
-    colorize_path(it->first, true);
-  }
+    auto it = directories.find(file_path.parent_path().string());
+    if (it != directories.end()) {
+        if (it->second.repository)
+            it->second.repository->clear_saved_status();
+        colorize_path(it->first, true);
+    }
 }
 
 void Directories::select(const boost::filesystem::path &select_path) {
-  if(path=="")
-    return;
-  
-  if(!filesystem::file_in_path(select_path, path))
-    return;
-  
-  //return if the select_path is already selected
-  auto iter=get_selection()->get_selected();
-  if(iter) {
-    if(iter->get_value(column_record.path)==select_path)
-      return;
-  }
-  
-  std::list<boost::filesystem::path> paths;
-  boost::filesystem::path parent_path;
-  if(boost::filesystem::is_directory(select_path))
-    parent_path=select_path;
-  else
-    parent_path=select_path.parent_path();
-  
-  //check if select_path is already expanded
-  if(directories.find(parent_path.string())!=directories.end()) {
-    //set cursor at select_path and return
-    tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter){
-      if(iter->get_value(column_record.path)==select_path) {
-        auto tree_path=Gtk::TreePath(iter);
-        expand_to_path(tree_path);
-        set_cursor(tree_path);
-        return true;
-      }
-      return false;
-    });
-    return;
-  }
-  
-  paths.emplace_front(parent_path);
-  while(parent_path!=path) {
-    parent_path=parent_path.parent_path();
+    if (path == "")
+        return;
+
+    if (!filesystem::file_in_path(select_path, path))
+        return;
+
+    //return if the select_path is already selected
+    auto iter = get_selection()->get_selected();
+    if (iter) {
+        if (iter->get_value(column_record.path) == select_path)
+            return;
+    }
+
+    std::list<boost::filesystem::path> paths;
+    boost::filesystem::path parent_path;
+    if (boost::filesystem::is_directory(select_path))
+        parent_path = select_path;
+    else
+        parent_path = select_path.parent_path();
+
+    //check if select_path is already expanded
+    if (directories.find(parent_path.string()) != directories.end()) {
+        //set cursor at select_path and return
+        tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter) {
+            if (iter->get_value(column_record.path) == select_path) {
+                auto tree_path = Gtk::TreePath(iter);
+                expand_to_path(tree_path);
+                set_cursor(tree_path);
+                return true;
+            }
+            return false;
+        });
+        return;
+    }
+
     paths.emplace_front(parent_path);
-  }
-
-  //expand to select_path
-  for(auto &a_path: paths) {
-    tree_store->foreach_iter([this, &a_path](const Gtk::TreeModel::iterator &iter){
-      if(iter->get_value(column_record.path)==a_path) {
-        add_or_update_path(a_path, *iter, true);
-        return true;
-      }
-      return false;
-    });
-  }
-  
-  //set cursor at select_path
-  tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter){
-    if(iter->get_value(column_record.path)==select_path) {
-      auto tree_path=Gtk::TreePath(iter);
-      expand_to_path(tree_path);
-      set_cursor(tree_path);
-      return true;
+    while (parent_path != path) {
+        parent_path = parent_path.parent_path();
+        paths.emplace_front(parent_path);
     }
-    return false;
-  });
+
+    //expand to select_path
+    for (auto &a_path: paths) {
+        tree_store->foreach_iter([this, &a_path](const Gtk::TreeModel::iterator &iter) {
+            if (iter->get_value(column_record.path) == a_path) {
+                add_or_update_path(a_path, *iter, true);
+                return true;
+            }
+            return false;
+        });
+    }
+
+    //set cursor at select_path
+    tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter) {
+        if (iter->get_value(column_record.path) == select_path) {
+            auto tree_path = Gtk::TreePath(iter);
+            expand_to_path(tree_path);
+            set_cursor(tree_path);
+            return true;
+        }
+        return false;
+    });
 }
 
-bool Directories::on_button_press_event(GdkEventButton* event) {
-  if(event->type==GDK_BUTTON_PRESS && event->button==GDK_BUTTON_SECONDARY) {
-    EntryBox::get().hide();
-    Gtk::TreeModel::Path path;
-    if(get_path_at_pos(static_cast<int>(event->x), static_cast<int>(event->y), path)) {
-      menu_popup_row_path=get_model()->get_iter(path)->get_value(column_record.path);
-      if(menu_popup_row_path.empty()) {
-        auto parent=get_model()->get_iter(path)->parent();
-        if(parent)
-          menu_popup_row_path=parent->get_value(column_record.path);
-        else {
-          menu_popup_row_path=this->path;
-          menu_root.popup(event->button, event->time);
-          return true;
+bool Directories::on_button_press_event(GdkEventButton *event) {
+    if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY) {
+        EntryBox::get().hide();
+        Gtk::TreeModel::Path path;
+        if (get_path_at_pos(static_cast<int>(event->x), static_cast<int>(event->y), path)) {
+            menu_popup_row_path = get_model()->get_iter(path)->get_value(column_record.path);
+            if (menu_popup_row_path.empty()) {
+                auto parent = get_model()->get_iter(path)->parent();
+                if (parent)
+                    menu_popup_row_path = parent->get_value(column_record.path);
+                else {
+                    menu_popup_row_path = this->path;
+                    menu_root.popup(event->button, event->time);
+                    return true;
+                }
+            }
+            menu.popup(event->button, event->time);
+            return true;
+        } else if (!this->path.empty()) {
+            menu_popup_row_path = this->path;
+            menu_root.popup(event->button, event->time);
+            return true;
         }
-      }
-      menu.popup(event->button, event->time);
-      return true;
     }
-    else if(!this->path.empty()) {
-      menu_popup_row_path=this->path;
-      menu_root.popup(event->button, event->time);
-      return true;
-    }
-  }
-  
-  return Gtk::TreeView::on_button_press_event(event);
+
+    return Gtk::TreeView::on_button_press_event(event);
 }
 
-void Directories::add_or_update_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row, bool include_parent_paths) {
-  auto path_it=directories.find(dir_path.string());
-  if(!boost::filesystem::exists(dir_path)) {
-    if(path_it!=directories.end())
-      directories.erase(path_it);
-    return;
-  }
-  
-  if(path_it==directories.end()) {
-    auto g_file=Gio::File::create_for_path(dir_path.string());
-    auto monitor=g_file->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
-    auto path_and_row=std::make_shared<std::pair<boost::filesystem::path, Gtk::TreeModel::Row> >(dir_path, row);
-    auto connection=std::make_shared<sigc::connection>();
-    
-    std::shared_ptr<Git::Repository> repository;
-    try {
-      repository=Git::get_repository(dir_path);
+void Directories::add_or_update_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row,
+                                     bool include_parent_paths) {
+    auto path_it = directories.find(dir_path.string());
+    if (!boost::filesystem::exists(dir_path)) {
+        if (path_it != directories.end())
+            directories.erase(path_it);
+        return;
     }
-    catch(const std::exception &) {}
-    
-    monitor->signal_changed().connect([this, connection, path_and_row, repository] (const Glib::RefPtr<Gio::File> &file,
-                                                                        const Glib::RefPtr<Gio::File>&,
-                                                                        Gio::FileMonitorEvent monitor_event) {
-      if(monitor_event!=Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-        if(repository)
-          repository->clear_saved_status();
-        connection->disconnect();
-        *connection=Glib::signal_timeout().connect([path_and_row, this]() {
-          if(directories.find(path_and_row->first.string())!=directories.end())
-            add_or_update_path(path_and_row->first, path_and_row->second, true);
-          return false;
-        }, 500);
-      }
-    });
-    
-    std::shared_ptr<sigc::connection> repository_connection(new sigc::connection(), [](sigc::connection *connection) {
-      connection->disconnect();
-      delete connection;
-    });
-    
-    if(repository) {
-      auto connection=std::make_shared<sigc::connection>();
-      *repository_connection=repository->monitor->signal_changed().connect([this, connection, path_and_row](const Glib::RefPtr<Gio::File> &file,
-                                                                                                            const Glib::RefPtr<Gio::File>&,
-                                                                                                            Gio::FileMonitorEvent monitor_event) {
-        if(monitor_event!=Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-          connection->disconnect();
-          *connection=Glib::signal_timeout().connect([this, path_and_row] {
-            if(directories.find(path_and_row->first.string())!=directories.end())
-              colorize_path(path_and_row->first, false);
-            return false;
-          }, 500);
+
+    if (path_it == directories.end()) {
+        auto g_file = Gio::File::create_for_path(dir_path.string());
+        auto monitor = g_file->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
+        auto path_and_row = std::make_shared<std::pair<boost::filesystem::path, Gtk::TreeModel::Row> >(dir_path, row);
+        auto connection = std::make_shared<sigc::connection>();
+
+        std::shared_ptr<Git::Repository> repository;
+        try {
+            repository = Git::get_repository(dir_path);
         }
-      });
+        catch (const std::exception &) {}
+
+        monitor->signal_changed().connect(
+                [this, connection, path_and_row, repository](const Glib::RefPtr<Gio::File> &file,
+                                                             const Glib::RefPtr<Gio::File> &,
+                                                             Gio::FileMonitorEvent monitor_event) {
+                    if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+                        if (repository)
+                            repository->clear_saved_status();
+                        connection->disconnect();
+                        *connection = Glib::signal_timeout().connect([path_and_row, this]() {
+                            if (directories.find(path_and_row->first.string()) != directories.end())
+                                add_or_update_path(path_and_row->first, path_and_row->second, true);
+                            return false;
+                        }, 500);
+                    }
+                });
+
+        std::shared_ptr<sigc::connection> repository_connection(new sigc::connection(),
+                                                                [](sigc::connection *connection) {
+                                                                    connection->disconnect();
+                                                                    delete connection;
+                                                                });
+
+        if (repository) {
+            auto connection = std::make_shared<sigc::connection>();
+            *repository_connection = repository->monitor->signal_changed().connect(
+                    [this, connection, path_and_row](const Glib::RefPtr<Gio::File> &file,
+                                                     const Glib::RefPtr<Gio::File> &,
+                                                     Gio::FileMonitorEvent monitor_event) {
+                        if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+                            connection->disconnect();
+                            *connection = Glib::signal_timeout().connect([this, path_and_row] {
+                                if (directories.find(path_and_row->first.string()) != directories.end())
+                                    colorize_path(path_and_row->first, false);
+                                return false;
+                            }, 500);
+                        }
+                    });
+        }
+        directories[dir_path.string()] = {row, monitor, repository, repository_connection};
     }
-    directories[dir_path.string()]={row, monitor, repository, repository_connection};
-  }
-  
-  Gtk::TreeNodeChildren children(row?row.children():tree_store->children());
-  if(children) {
-    if(children.begin()->get_value(column_record.path)=="")
-      tree_store->erase(children.begin());
-  }
-  std::unordered_set<std::string> not_deleted;
-  boost::filesystem::directory_iterator end_it;
-  for(boost::filesystem::directory_iterator it(dir_path);it!=end_it;it++) {
-    auto filename=it->path().filename().string();
-    bool already_added=false;
-    if(children) {
-      for(auto &child: children) {
-        if(child->get_value(column_record.name)==filename) {
-          not_deleted.emplace(filename);
-          already_added=true;
-          break;
+
+    Gtk::TreeNodeChildren children(row ? row.children() : tree_store->children());
+    if (children) {
+        if (children.begin()->get_value(column_record.path) == "")
+            tree_store->erase(children.begin());
+    }
+    std::unordered_set<std::string> not_deleted;
+    boost::filesystem::directory_iterator end_it;
+    for (boost::filesystem::directory_iterator it(dir_path); it != end_it; it++) {
+        auto filename = it->path().filename().string();
+        bool already_added = false;
+        if (children) {
+            for (auto &child: children) {
+                if (child->get_value(column_record.name) == filename) {
+                    not_deleted.emplace(filename);
+                    already_added = true;
+                    break;
+                }
+            }
+        }
+        if (!already_added) {
+            auto child = tree_store->append(children);
+            not_deleted.emplace(filename);
+            child->set_value(column_record.name, filename);
+            child->set_value(column_record.markup, Glib::Markup::escape_text(filename));
+            child->set_value(column_record.path, it->path());
+            if (boost::filesystem::is_directory(it->path())) {
+                child->set_value(column_record.id, '1' + filename);
+                auto grandchild = tree_store->append(child->children());
+                grandchild->set_value(column_record.name, std::string("(empty)"));
+                grandchild->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
+                grandchild->set_value(column_record.type, PathType::UNKNOWN);
+            } else {
+                child->set_value(column_record.id, '2' + filename);
+
+                auto language = Source::guess_language(it->path().filename());
+                if (!language)
+                    child->set_value(column_record.type, PathType::UNKNOWN);
+            }
         }
-      }
     }
-    if(!already_added) {
-      auto child = tree_store->append(children);
-      not_deleted.emplace(filename);
-      child->set_value(column_record.name, filename);
-      child->set_value(column_record.markup, Glib::Markup::escape_text(filename));
-      child->set_value(column_record.path, it->path());
-      if (boost::filesystem::is_directory(it->path())) {
-        child->set_value(column_record.id, '1'+filename);
-        auto grandchild=tree_store->append(child->children());
-        grandchild->set_value(column_record.name, std::string("(empty)"));
-        grandchild->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
-        grandchild->set_value(column_record.type, PathType::UNKNOWN);
-      }
-      else {
-        child->set_value(column_record.id, '2'+filename);
-        
-        auto language=Source::guess_language(it->path().filename());
-        if(!language)
-          child->set_value(column_record.type, PathType::UNKNOWN);
-      }
+    if (children) {
+        for (auto it = children.begin(); it != children.end();) {
+            if (not_deleted.count(it->get_value(column_record.name)) == 0) {
+                it = tree_store->erase(it);
+            } else
+                it++;
+        }
     }
-  }
-  if(children) {
-    for(auto it=children.begin();it!=children.end();) {
-      if(not_deleted.count(it->get_value(column_record.name))==0) {
-        it=tree_store->erase(it);
-      }
-      else
-        it++;
+    if (!children) {
+        auto child = tree_store->append(children);
+        child->set_value(column_record.name, std::string("(empty)"));
+        child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
+        child->set_value(column_record.type, PathType::UNKNOWN);
     }
-  }
-  if(!children) {
-    auto child=tree_store->append(children);
-    child->set_value(column_record.name, std::string("(empty)"));
-    child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
-    child->set_value(column_record.type, PathType::UNKNOWN);
-  }
-  
-  colorize_path(dir_path, include_parent_paths);
+
+    colorize_path(dir_path, include_parent_paths);
 }
 
 void Directories::remove_path(const boost::filesystem::path &dir_path) {
-  auto it=directories.find(dir_path.string());
-  if(it==directories.end())
-    return;
-  auto children=it->second.row->children();
-  
-  for(auto it=directories.begin();it!=directories.end();) {
-    if(filesystem::file_in_path(it->first, dir_path))
-      it=directories.erase(it);
-    else
-      it++;
-  }
-  
-  if(children) {
-    while(children) {
-      tree_store->erase(children.begin());
+    auto it = directories.find(dir_path.string());
+    if (it == directories.end())
+        return;
+    auto children = it->second.row->children();
+
+    for (auto it = directories.begin(); it != directories.end();) {
+        if (filesystem::file_in_path(it->first, dir_path))
+            it = directories.erase(it);
+        else
+            it++;
+    }
+
+    if (children) {
+        while (children) {
+            tree_store->erase(children.begin());
+        }
+        auto child = tree_store->append(children);
+        child->set_value(column_record.name, std::string("(empty)"));
+        child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
+        child->set_value(column_record.type, PathType::UNKNOWN);
     }
-    auto child=tree_store->append(children);
-    child->set_value(column_record.name, std::string("(empty)"));
-    child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
-    child->set_value(column_record.type, PathType::UNKNOWN);
-  }
 }
 
 void Directories::colorize_path(const boost::filesystem::path &dir_path, bool include_parent_paths) {
-  auto it=directories.find(dir_path.string());
-  if(it==directories.end())
-    return;
-  
-  if(it!=directories.end() && it->second.repository) {
-    auto repository=it->second.repository;
-    std::thread git_status_thread([this, dir_path, repository, include_parent_paths] {
-      Git::Repository::Status status;
-      try {
-        status=repository->get_status();
-      }
-      catch(const std::exception &e) {
-        Terminal::get().async_print(std::string("Error (git): ")+e.what()+'\n', true);
-      }
-      
-      dispatcher.post([this, dir_path=std::move(dir_path), include_parent_paths, status=std::move(status)] {
-        auto it=directories.find(dir_path.string());
-        if(it==directories.end())
-          return;
-        
-        auto normal_color=get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
-        Gdk::RGBA gray;
-        gray.set_rgba(0.5, 0.5, 0.5);
-        Gdk::RGBA yellow;
-        yellow.set_rgba(1.0, 1.0, 0.2);
-        double factor=0.5;
-        yellow.set_red(normal_color.get_red()+factor*(yellow.get_red()-normal_color.get_red()));
-        yellow.set_green(normal_color.get_green()+factor*(yellow.get_green()-normal_color.get_green()));
-        yellow.set_blue(normal_color.get_blue()+factor*(yellow.get_blue()-normal_color.get_blue()));
-        Gdk::RGBA green;
-        green.set_rgba(0.0, 1.0, 0.0);
-        factor=0.4;
-        green.set_red(normal_color.get_red()+factor*(green.get_red()-normal_color.get_red()));
-        green.set_green(normal_color.get_green()+factor*(green.get_green()-normal_color.get_green()));
-        green.set_blue(normal_color.get_blue()+factor*(green.get_blue()-normal_color.get_blue()));
-        
-        do {
-          Gtk::TreeNodeChildren children(it->second.row?it->second.row.children():tree_store->children());
-          if(!children)
-            return;
-          
-          for(auto &child: children) {
-            auto name=Glib::Markup::escape_text(child.get_value(column_record.name));
-            auto path=child.get_value(column_record.path);
-            Gdk::RGBA *color;
-            if(status.modified.find(path.generic_string())!=status.modified.end())
-              color=&yellow;
-            else if(status.added.find(path.generic_string())!=status.added.end())
-              color=&green;
-            else
-              color=&normal_color;
-            
-            std::stringstream ss;
-            ss << '#' << std::setfill('0') << std::hex;
-            ss << std::setw(2) << std::hex << (color->get_red_u()>>8);
-            ss << std::setw(2) << std::hex << (color->get_green_u()>>8);
-            ss << std::setw(2) << std::hex << (color->get_blue_u()>>8);
-            child.set_value(column_record.markup, "<span foreground=\""+ss.str()+"\">"+name+"</span>");
-            
-            auto type=child.get_value(column_record.type);
-            if(type==PathType::UNKNOWN)
-              child.set_value(column_record.markup, "<i>"+child.get_value(column_record.markup)+"</i>");
-          }
-          
-          if(!include_parent_paths)
-            break;
-          
-          auto path=boost::filesystem::path(it->first);
-          if(boost::filesystem::exists(path/".git"))
-            break;
-          if(path==path.root_directory())
-            break;
-          auto parent_path=boost::filesystem::path(it->first).parent_path();
-          it=directories.find(parent_path.string());
-        } while(it!=directories.end());
-      });
-    });
-    git_status_thread.detach();
-  }
+    auto it = directories.find(dir_path.string());
+    if (it == directories.end())
+        return;
+
+    if (it != directories.end() && it->second.repository) {
+        auto repository = it->second.repository;
+        std::thread git_status_thread([this, dir_path, repository, include_parent_paths] {
+            Git::Repository::Status status;
+            try {
+                status = repository->get_status();
+            }
+            catch (const std::exception &e) {
+                Terminal::get().async_print(std::string("Error (git): ") + e.what() + '\n', true);
+            }
+
+            dispatcher.post([this, dir_path = std::move(dir_path), include_parent_paths, status = std::move(status)] {
+                auto it = directories.find(dir_path.string());
+                if (it == directories.end())
+                    return;
+
+                auto normal_color = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
+                Gdk::RGBA gray;
+                gray.set_rgba(0.5, 0.5, 0.5);
+                Gdk::RGBA yellow;
+                yellow.set_rgba(1.0, 1.0, 0.2);
+                double factor = 0.5;
+                yellow.set_red(normal_color.get_red() + factor * (yellow.get_red() - normal_color.get_red()));
+                yellow.set_green(normal_color.get_green() + factor * (yellow.get_green() - normal_color.get_green()));
+                yellow.set_blue(normal_color.get_blue() + factor * (yellow.get_blue() - normal_color.get_blue()));
+                Gdk::RGBA green;
+                green.set_rgba(0.0, 1.0, 0.0);
+                factor = 0.4;
+                green.set_red(normal_color.get_red() + factor * (green.get_red() - normal_color.get_red()));
+                green.set_green(normal_color.get_green() + factor * (green.get_green() - normal_color.get_green()));
+                green.set_blue(normal_color.get_blue() + factor * (green.get_blue() - normal_color.get_blue()));
+
+                do {
+                    Gtk::TreeNodeChildren children(it->second.row ? it->second.row.children() : tree_store->children());
+                    if (!children)
+                        return;
+
+                    for (auto &child: children) {
+                        auto name = Glib::Markup::escape_text(child.get_value(column_record.name));
+                        auto path = child.get_value(column_record.path);
+                        Gdk::RGBA *color;
+                        if (status.modified.find(path.generic_string()) != status.modified.end())
+                            color = &yellow;
+                        else if (status.added.find(path.generic_string()) != status.added.end())
+                            color = &green;
+                        else
+                            color = &normal_color;
+
+                        std::stringstream ss;
+                        ss << '#' << std::setfill('0') << std::hex;
+                        ss << std::setw(2) << std::hex << (color->get_red_u() >> 8);
+                        ss << std::setw(2) << std::hex << (color->get_green_u() >> 8);
+                        ss << std::setw(2) << std::hex << (color->get_blue_u() >> 8);
+                        child.set_value(column_record.markup,
+                                        "<span foreground=\"" + ss.str() + "\">" + name + "</span>");
+
+                        auto type = child.get_value(column_record.type);
+                        if (type == PathType::UNKNOWN)
+                            child.set_value(column_record.markup,
+                                            "<i>" + child.get_value(column_record.markup) + "</i>");
+                    }
+
+                    if (!include_parent_paths)
+                        break;
+
+                    auto path = boost::filesystem::path(it->first);
+                    if (boost::filesystem::exists(path / ".git"))
+                        break;
+                    if (path == path.root_directory())
+                        break;
+                    auto parent_path = boost::filesystem::path(it->first).parent_path();
+                    it = directories.find(parent_path.string());
+                } while (it != directories.end());
+            });
+        });
+        git_status_thread.detach();
+    }
 }
diff --git a/src/directories.h b/src/directories.h
index da6191fb..6caaea48 100644
--- a/src/directories.h
+++ b/src/directories.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <gtkmm.h>
 #include <vector>
 #include <string>
@@ -12,82 +13,96 @@
 #include "dispatcher.h"
 
 class Directories : public Gtk::ListViewText {
-  class DirectoryData {
-  public:
-    Gtk::TreeModel::Row row;
-    Glib::RefPtr<Gio::FileMonitor> monitor;
-    std::shared_ptr<Git::Repository> repository;
-    std::shared_ptr<sigc::connection> connection;
-  };
-  
-  enum class PathType {KNOWN, UNKNOWN};
-  
-  class TreeStore : public Gtk::TreeStore {
-  protected:
-    TreeStore() {}
-    
-    bool row_drop_possible_vfunc(const Gtk::TreeModel::Path &path, const Gtk::SelectionData &selection_data) const override;
-    bool drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) override;
-    bool drag_data_delete_vfunc (const Gtk::TreeModel::Path &path) override;
-    
-  public:
-    class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
+    class DirectoryData {
+    public:
+        Gtk::TreeModel::Row row;
+        Glib::RefPtr<Gio::FileMonitor> monitor;
+        std::shared_ptr<Git::Repository> repository;
+        std::shared_ptr<sigc::connection> connection;
+    };
+
+    enum class PathType {
+        KNOWN, UNKNOWN
+    };
+
+    class TreeStore : public Gtk::TreeStore {
+    protected:
+        TreeStore() {}
+
+        bool row_drop_possible_vfunc(const Gtk::TreeModel::Path &path,
+                                     const Gtk::SelectionData &selection_data) const override;
+
+        bool drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) override;
+
+        bool drag_data_delete_vfunc(const Gtk::TreeModel::Path &path) override;
+
     public:
-      ColumnRecord() {
-        add(id);
-        add(name);
-        add(markup);
-        add(path);
-        add(type);
-      }
-      Gtk::TreeModelColumn<std::string> id;
-      Gtk::TreeModelColumn<std::string> name;
-      Gtk::TreeModelColumn<Glib::ustring> markup;
-      Gtk::TreeModelColumn<boost::filesystem::path> path;
-      Gtk::TreeModelColumn<PathType> type;
+        class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
+        public:
+            ColumnRecord() {
+                add(id);
+                add(name);
+                add(markup);
+                add(path);
+                add(type);
+            }
+
+            Gtk::TreeModelColumn<std::string> id;
+            Gtk::TreeModelColumn<std::string> name;
+            Gtk::TreeModelColumn<Glib::ustring> markup;
+            Gtk::TreeModelColumn<boost::filesystem::path> path;
+            Gtk::TreeModelColumn<PathType> type;
+        };
+
+        static Glib::RefPtr<TreeStore> create() { return Glib::RefPtr<TreeStore>(new TreeStore()); }
     };
-    
-    static Glib::RefPtr<TreeStore> create() {return Glib::RefPtr<TreeStore>(new TreeStore());}
-  };
 
-  Directories();
+    Directories();
+
 public:
-  static Directories &get() {
-    static Directories singleton;
-    return singleton;
-  }
-  ~Directories();
-  
-  void open(const boost::filesystem::path &dir_path="");
-  void update();
-  void on_save_file(boost::filesystem::path file_path);
-  void select(const boost::filesystem::path &path);
-  
-  boost::filesystem::path path;
-  
+    static Directories &get() {
+        static Directories singleton;
+        return singleton;
+    }
+
+    ~Directories();
+
+    void open(const boost::filesystem::path &dir_path = "");
+
+    void update();
+
+    void on_save_file(boost::filesystem::path file_path);
+
+    void select(const boost::filesystem::path &path);
+
+    boost::filesystem::path path;
+
 protected:
-  bool on_button_press_event(GdkEventButton *event) override;
-  
+    bool on_button_press_event(GdkEventButton *event) override;
+
 private:
-  void add_or_update_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row, bool include_parent_paths);
-  void remove_path(const boost::filesystem::path &dir_path);
-  void colorize_path(const boost::filesystem::path &dir_path, bool include_parent_paths);
-  
-  Glib::RefPtr<Gtk::TreeStore> tree_store;
-  TreeStore::ColumnRecord column_record;
-  
-  std::unordered_map<std::string, DirectoryData> directories;
-  
-  Dispatcher dispatcher;
-  
-  Gtk::Menu menu;
-  Gtk::MenuItem menu_item_new_file;
-  Gtk::MenuItem menu_item_new_folder;
-  Gtk::SeparatorMenuItem menu_item_separator;
-  Gtk::MenuItem menu_item_rename;
-  Gtk::MenuItem menu_item_delete;
-  Gtk::Menu menu_root;
-  Gtk::MenuItem menu_root_item_new_file;
-  Gtk::MenuItem menu_root_item_new_folder;
-  boost::filesystem::path menu_popup_row_path;
+    void add_or_update_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row,
+                            bool include_parent_paths);
+
+    void remove_path(const boost::filesystem::path &dir_path);
+
+    void colorize_path(const boost::filesystem::path &dir_path, bool include_parent_paths);
+
+    Glib::RefPtr<Gtk::TreeStore> tree_store;
+    TreeStore::ColumnRecord column_record;
+
+    std::unordered_map<std::string, DirectoryData> directories;
+
+    Dispatcher dispatcher;
+
+    Gtk::Menu menu;
+    Gtk::MenuItem menu_item_new_file;
+    Gtk::MenuItem menu_item_new_folder;
+    Gtk::SeparatorMenuItem menu_item_separator;
+    Gtk::MenuItem menu_item_rename;
+    Gtk::MenuItem menu_item_delete;
+    Gtk::Menu menu_root;
+    Gtk::MenuItem menu_root_item_new_file;
+    Gtk::MenuItem menu_root_item_new_folder;
+    boost::filesystem::path menu_popup_row_path;
 };
diff --git a/src/dispatcher.cc b/src/dispatcher.cc
index 5ad2d602..1a0651de 100644
--- a/src/dispatcher.cc
+++ b/src/dispatcher.cc
@@ -2,30 +2,30 @@
 #include <vector>
 
 Dispatcher::Dispatcher() {
-  connection=dispatcher.connect([this] {
-    std::vector<std::list<std::function<void()>>::iterator> its;
-    {
-      std::unique_lock<std::mutex> lock(functions_mutex);
-      if(functions.empty())
-        return;
-      its.reserve(functions.size());
-      for(auto it=functions.begin();it!=functions.end();++it)
-        its.emplace_back(it);
-    }
-    for(auto &it: its)
-      (*it)();
-    {
-      std::unique_lock<std::mutex> lock(functions_mutex);
-      for(auto &it: its)
-        functions.erase(it);
-    }
-  });
+    connection = dispatcher.connect([this] {
+        std::vector<std::list<std::function<void()>>::iterator> its;
+        {
+            std::unique_lock<std::mutex> lock(functions_mutex);
+            if (functions.empty())
+                return;
+            its.reserve(functions.size());
+            for (auto it = functions.begin(); it != functions.end(); ++it)
+                its.emplace_back(it);
+        }
+        for (auto &it: its)
+            (*it)();
+        {
+            std::unique_lock<std::mutex> lock(functions_mutex);
+            for (auto &it: its)
+                functions.erase(it);
+        }
+    });
 }
 
 Dispatcher::~Dispatcher() {
-  disconnect();
+    disconnect();
 }
 
 void Dispatcher::disconnect() {
-  connection.disconnect();
+    connection.disconnect();
 }
diff --git a/src/dispatcher.h b/src/dispatcher.h
index 84766285..6fbab177 100644
--- a/src/dispatcher.h
+++ b/src/dispatcher.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <gtkmm.h>
 #include <mutex>
 #include <functional>
@@ -6,22 +7,23 @@
 
 class Dispatcher {
 private:
-  std::list<std::function<void()>> functions;
-  std::mutex functions_mutex;
-  Glib::Dispatcher dispatcher;
-  sigc::connection connection;
+    std::list<std::function<void()>> functions;
+    std::mutex functions_mutex;
+    Glib::Dispatcher dispatcher;
+    sigc::connection connection;
 public:
-  Dispatcher();
-  ~Dispatcher();
-  
-  template<typename T>
-  void post(T &&function) {
-    {
-      std::unique_lock<std::mutex> lock(functions_mutex);
-      functions.emplace_back(std::forward<T>(function));
+    Dispatcher();
+
+    ~Dispatcher();
+
+    template<typename T>
+    void post(T &&function) {
+        {
+            std::unique_lock<std::mutex> lock(functions_mutex);
+            functions.emplace_back(std::forward<T>(function));
+        }
+        dispatcher();
     }
-    dispatcher();
-  }
-  
-  void disconnect();
+
+    void disconnect();
 };
diff --git a/src/documentation_cppreference.cc b/src/documentation_cppreference.cc
index 060e791d..ef7365bd 100644
--- a/src/documentation_cppreference.cc
+++ b/src/documentation_cppreference.cc
@@ -1,10 +1,12 @@
-#include "documentation_cppreference.h"
-#include <unordered_map>
+#include
+"documentation_cppreference.h"
+#include
+<unordered_map>
 
 std::string Documentation::CppReference::get_url(const std::string symbol) noexcept {
-  // Copied from http://upload.cppreference.com/mwiki/images/d/df/html_book_20170409.zip/reference/cppreference-export-ns0,4,8,10.xml
-  // Using raw string instead of map to reduce compile time
-  const static std::string symbol_urls = R"(size_t	c/types/size_t
+// Copied from http://upload.cppreference.com/mwiki/images/d/df/html_book_20170409.zip/reference/cppreference-export-ns0,4,8,10.xml
+// Using raw string instead of map to reduce compile time
+const static std::string symbol_urls = R"(size_t	c/types/size_t
 ptrdiff_t	c/types/ptrdiff_t
 nullptr_t	c/types/nullptr_t
 NULL	c/types/NULL
@@ -12173,34 +12175,34 @@ std::experimental::filesystem::is_socket	cpp/experimental/fs/is_socket
 std::experimental::filesystem::is_symlink	cpp/experimental/fs/is_symlink
 std::experimental::filesystem::status_known	cpp/experimental/fs/status_known"}
 )";
-  
-  class SymbolToUrl {
-  public:
-    SymbolToUrl(const std::string &symbol_urls) {
-      size_t symbol_start=0;
-      size_t symbol_end=std::string::npos;
-      size_t url_start=std::string::npos;
-      for(size_t c=0;c<symbol_urls.size();++c) {
-        auto &chr=symbol_urls[c];
-        if(chr=='\t') {
-          symbol_end=c;
-          url_start=c+1;
-        }
-        else if(chr=='\n') {
-          if(symbol_end!=std::string::npos && url_start!=std::string::npos)
-            map.emplace(symbol_urls.substr(symbol_start, symbol_end-symbol_start), symbol_urls.substr(url_start, c-url_start));
-          symbol_start=c+1;
-          symbol_end=std::string::npos;
-          url_start=std::string::npos;
-        }
-      }
-    }
-    std::unordered_map<std::string, std::string> map;
-  };
-  
-  static SymbolToUrl symbol_to_url(symbol_urls);
-  auto it=symbol_to_url.map.find(symbol);
-  if(it==symbol_to_url.map.end())
-    return std::string();
-  return "http://en.cppreference.com/w/"+it->second;
+
+class SymbolToUrl {
+public:
+SymbolToUrl(const std::string &symbol_urls) {
+size_t symbol_start=0;
+size_t symbol_end=std::string::npos;
+size_t url_start=std::string::npos;
+for (size_t c=0;c<symbol_urls.size();++c) {
+auto &chr=symbol_urls[c];
+if (chr=='\t') {
+symbol_end=c;
+url_start=c+1;
+}
+else if (chr=='\n') {
+if (symbol_end!=std::string::npos && url_start!=std::string::npos)
+map.emplace(symbol_urls.substr(symbol_start, symbol_end-symbol_start), symbol_urls.substr(url_start, c-url_start));
+symbol_start=c+1;
+symbol_end=std::string::npos;
+url_start=std::string::npos;
+}
+}
+}
+std::unordered_map<std::string, std::string> map;
+};
+
+static SymbolToUrl symbol_to_url(symbol_urls);
+auto it=symbol_to_url.map.find(symbol);
+if (it==symbol_to_url.map.end())
+return std::string();
+return "http://en.cppreference.com/w/"+it->second;
 }
diff --git a/src/documentation_cppreference.h b/src/documentation_cppreference.h
index 7a61f837..db9bf26e 100644
--- a/src/documentation_cppreference.h
+++ b/src/documentation_cppreference.h
@@ -1,9 +1,10 @@
 #pragma once
+
 #include <string>
 
 namespace Documentation {
-  class CppReference {
-  public:
-    static std::string get_url(const std::string symbol) noexcept;
-  };
+    class CppReference {
+    public:
+        static std::string get_url(const std::string symbol) noexcept;
+    };
 }
diff --git a/src/entrybox.cc b/src/entrybox.cc
index b5cd6638..5a81ef1e 100644
--- a/src/entrybox.cc
+++ b/src/entrybox.cc
@@ -2,96 +2,101 @@
 
 std::unordered_map<std::string, std::vector<std::string> > EntryBox::entry_histories;
 
-EntryBox::Entry::Entry(const std::string& content, std::function<void(const std::string& content)> on_activate, unsigned width_chars) : Gtk::Entry(), on_activate(on_activate) {
-  set_max_length(0);
-  set_width_chars(width_chars);
-  set_text(content);
-  selected_history=0;
-  signal_activate().connect([this](){
-    if(this->on_activate) {
-      auto &history=EntryBox::entry_histories[get_placeholder_text()];
-      auto text=get_text();
-      if(history.size()==0 || (history.size()>0 && *history.begin()!=text))
-        history.emplace(history.begin(), text);
-      selected_history=0;
-      this->on_activate(text);
-    }
-  });
-  signal_key_press_event().connect([this](GdkEventKey* key){
-    if(key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up) {
-      auto &history=entry_histories[get_placeholder_text()];
-      if(history.size()>0) {
-        selected_history++;
-        if(selected_history>=history.size())
-          selected_history=history.size()-1;
-        set_text(history[selected_history]);
-        set_position(-1);
-      }
-    }
-    if(key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down) {
-      auto &history=entry_histories[get_placeholder_text()];
-      if(history.size()>0) {
-        if(selected_history!=0)
-          selected_history--;
-        set_text(history[selected_history]);
-        set_position(-1);
-      }
-    }
-    return false;
-  });
+EntryBox::Entry::Entry(const std::string &content, std::function<void(const std::string &content)> on_activate,
+                       unsigned width_chars) : Gtk::Entry(), on_activate(on_activate) {
+    set_max_length(0);
+    set_width_chars(width_chars);
+    set_text(content);
+    selected_history = 0;
+    signal_activate().connect([this]() {
+        if (this->on_activate) {
+            auto &history = EntryBox::entry_histories[get_placeholder_text()];
+            auto text = get_text();
+            if (history.size() == 0 || (history.size() > 0 && *history.begin() != text))
+                history.emplace(history.begin(), text);
+            selected_history = 0;
+            this->on_activate(text);
+        }
+    });
+    signal_key_press_event().connect([this](GdkEventKey *key) {
+        if (key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) {
+            auto &history = entry_histories[get_placeholder_text()];
+            if (history.size() > 0) {
+                selected_history++;
+                if (selected_history >= history.size())
+                    selected_history = history.size() - 1;
+                set_text(history[selected_history]);
+                set_position(-1);
+            }
+        }
+        if (key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) {
+            auto &history = entry_histories[get_placeholder_text()];
+            if (history.size() > 0) {
+                if (selected_history != 0)
+                    selected_history--;
+                set_text(history[selected_history]);
+                set_position(-1);
+            }
+        }
+        return false;
+    });
 }
 
-EntryBox::Button::Button(const std::string& label, std::function<void()> on_activate) : Gtk::Button(label), on_activate(on_activate) {
-  set_focus_on_click(false);
-  signal_clicked().connect([this](){
-    if(this->on_activate)
-      this->on_activate();
-  });
+EntryBox::Button::Button(const std::string &label, std::function<void()> on_activate) : Gtk::Button(label),
+                                                                                        on_activate(on_activate) {
+    set_focus_on_click(false);
+    signal_clicked().connect([this]() {
+        if (this->on_activate)
+            this->on_activate();
+    });
 }
 
-EntryBox::ToggleButton::ToggleButton(const std::string& label, std::function<void()> on_activate) : Gtk::ToggleButton(label), on_activate(on_activate) {
-  set_focus_on_click(false);
-  signal_clicked().connect([this](){
-    if(this->on_activate)
-      this->on_activate();
-  });
+EntryBox::ToggleButton::ToggleButton(const std::string &label, std::function<void()> on_activate) : Gtk::ToggleButton(
+        label), on_activate(on_activate) {
+    set_focus_on_click(false);
+    signal_clicked().connect([this]() {
+        if (this->on_activate)
+            this->on_activate();
+    });
 }
 
-EntryBox::Label::Label(std::function<void(int state, const std::string& message)> update) : Gtk::Label(), update(update) {
-    if(this->update)
-      this->update(-1, "");
+EntryBox::Label::Label(std::function<void(int state, const std::string &message)> update)
+        : Gtk::Label(), update(update) {
+    if (this->update)
+        this->update(-1, "");
 }
 
-EntryBox::EntryBox() : Gtk::Box(Gtk::ORIENTATION_VERTICAL), upper_box(Gtk::ORIENTATION_HORIZONTAL), lower_box(Gtk::ORIENTATION_HORIZONTAL) {
-  pack_start(upper_box, Gtk::PACK_SHRINK);
-  pack_start(lower_box, Gtk::PACK_SHRINK);
-  this->set_focus_chain({&lower_box});
+EntryBox::EntryBox() : Gtk::Box(Gtk::ORIENTATION_VERTICAL), upper_box(Gtk::ORIENTATION_HORIZONTAL),
+                       lower_box(Gtk::ORIENTATION_HORIZONTAL) {
+    pack_start(upper_box, Gtk::PACK_SHRINK);
+    pack_start(lower_box, Gtk::PACK_SHRINK);
+    this->set_focus_chain({&lower_box});
 }
 
 void EntryBox::clear() {
-  Gtk::Box::hide();
-  entries.clear();
-  buttons.clear();
-  toggle_buttons.clear();
-  labels.clear();
+    Gtk::Box::hide();
+    entries.clear();
+    buttons.clear();
+    toggle_buttons.clear();
+    labels.clear();
 }
 
 void EntryBox::show() {
-  std::vector<Gtk::Widget*> focus_chain;
-  for(auto& entry: entries) {
-    lower_box.pack_start(entry, Gtk::PACK_SHRINK);
-    focus_chain.emplace_back(&entry);
-  }
-  for(auto& button: buttons)
-    lower_box.pack_start(button, Gtk::PACK_SHRINK);
-  for(auto& toggle_button: toggle_buttons)
-    lower_box.pack_start(toggle_button, Gtk::PACK_SHRINK);
-  for(auto& label: labels)
-    upper_box.pack_start(label, Gtk::PACK_SHRINK);
-  lower_box.set_focus_chain(focus_chain);
-  show_all();
-  if(entries.size()>0) {
-    entries.begin()->grab_focus();
-    entries.begin()->select_region(0, entries.begin()->get_text_length());
-  }
+    std::vector<Gtk::Widget *> focus_chain;
+    for (auto &entry: entries) {
+        lower_box.pack_start(entry, Gtk::PACK_SHRINK);
+        focus_chain.emplace_back(&entry);
+    }
+    for (auto &button: buttons)
+        lower_box.pack_start(button, Gtk::PACK_SHRINK);
+    for (auto &toggle_button: toggle_buttons)
+        lower_box.pack_start(toggle_button, Gtk::PACK_SHRINK);
+    for (auto &label: labels)
+        upper_box.pack_start(label, Gtk::PACK_SHRINK);
+    lower_box.set_focus_chain(focus_chain);
+    show_all();
+    if (entries.size() > 0) {
+        entries.begin()->grab_focus();
+        entries.begin()->select_region(0, entries.begin()->get_text_length());
+    }
 }
diff --git a/src/entrybox.h b/src/entrybox.h
index 3a722be9..107ba085 100644
--- a/src/entrybox.h
+++ b/src/entrybox.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <list>
 #include <functional>
 #include "gtkmm.h"
@@ -8,47 +9,60 @@
 
 class EntryBox : public Gtk::Box {
 public:
-  class Entry : public Gtk::Entry {
-  public:
-    Entry(const std::string& content="", std::function<void(const std::string& content)> on_activate=nullptr, unsigned width_chars=-1);
-    std::function<void(const std::string& content)> on_activate;
-  private:
-    size_t selected_history;
-  };
-  class Button : public Gtk::Button {
-  public:
-    Button(const std::string& label, std::function<void()> on_activate=nullptr);
-    std::function<void()> on_activate;
-  };
-  class ToggleButton : public Gtk::ToggleButton {
-  public:
-    ToggleButton(const std::string& label, std::function<void()> on_activate=nullptr);
-    std::function<void()> on_activate;
-  };
-  class Label : public Gtk::Label {
-  public:
-    Label(std::function<void(int state, const std::string& message)> update=nullptr);
-    std::function<void(int state, const std::string& message)> update;
-  };
-  
+    class Entry : public Gtk::Entry {
+    public:
+        Entry(const std::string &content = "", std::function<void(const std::string &content)> on_activate = nullptr,
+              unsigned width_chars = -1);
+
+        std::function<void(const std::string &content)> on_activate;
+    private:
+        size_t selected_history;
+    };
+
+    class Button : public Gtk::Button {
+    public:
+        Button(const std::string &label, std::function<void()> on_activate = nullptr);
+
+        std::function<void()> on_activate;
+    };
+
+    class ToggleButton : public Gtk::ToggleButton {
+    public:
+        ToggleButton(const std::string &label, std::function<void()> on_activate = nullptr);
+
+        std::function<void()> on_activate;
+    };
+
+    class Label : public Gtk::Label {
+    public:
+        Label(std::function<void(int state, const std::string &message)> update = nullptr);
+
+        std::function<void(int state, const std::string &message)> update;
+    };
+
 private:
-  EntryBox();
+    EntryBox();
+
 public:
-  static EntryBox &get() {
-    static EntryBox singleton;
-    return singleton;
-  }
-  
-  Gtk::Box upper_box;
-  Gtk::Box lower_box;
-  void clear();
-  void hide() {clear();}
-  void show();
-  std::list<Entry> entries;
-  std::list<Button> buttons;
-  std::list<ToggleButton> toggle_buttons;
-  std::list<Label> labels;
-  
+    static EntryBox &get() {
+        static EntryBox singleton;
+        return singleton;
+    }
+
+    Gtk::Box upper_box;
+    Gtk::Box lower_box;
+
+    void clear();
+
+    void hide() { clear(); }
+
+    void show();
+
+    std::list<Entry> entries;
+    std::list<Button> buttons;
+    std::list<ToggleButton> toggle_buttons;
+    std::list<Label> labels;
+
 private:
-  static std::unordered_map<std::string, std::vector<std::string> > entry_histories;
+    static std::unordered_map<std::string, std::vector<std::string> > entry_histories;
 };
diff --git a/src/files.h b/src/files.h
index a98215f6..d72bbcf8 100644
--- a/src/files.h
+++ b/src/files.h
@@ -1,11 +1,12 @@
 #pragma once
+
 #include <string>
 
 /// If you add or remove nodes from the default_config_file, increase the juci
 /// version number (JUCI_VERSION) in ../CMakeLists.txt to automatically apply
 /// the changes to user's ~/.juci/config/config.json files
 const std::string default_config_file = R"RAW({
-    "version": ")RAW"+std::string(JUCI_VERSION)+R"RAW(",
+    "version": ")RAW" + std::string(JUCI_VERSION) + R"RAW(",
     "gtk_theme": {
         "name_comment": "Use \"\" for default theme, At least these two exist on all systems: Adwaita, Raleigh",
         "name": "",
@@ -16,19 +17,19 @@ const std::string default_config_file = R"RAW({
         "style_comment": "Use \"\" for default style, and for instance juci-dark or juci-dark-blue together with dark gtk_theme variant. Styles from normal gtksourceview install: classic, cobalt, kate, oblivion, solarized-dark, solarized-light, tango",
         "style": "juci-light",
         "font_comment": "Use \"\" for default font, and for instance \"Monospace 12\" to also set size",)RAW"
-#ifdef __APPLE__
-R"RAW(
+                                                    #ifdef __APPLE__
+                                                    R"RAW(
         "font": "Menlo",)RAW"
-#else
-#ifdef _WIN32
-R"RAW(
+                                                    #else
+                                                    #ifdef _WIN32
+                                                    R"RAW(
         "font": "Consolas",)RAW"
-#else
-R"RAW(
+                                                    #else
+                                                    R"RAW(
         "font": "Monospace",)RAW"
-#endif
-#endif
-R"RAW(
+                                                    #endif
+                                                    #endif
+                                                    R"RAW(
         "cleanup_whitespace_characters_comment": "Remove trailing whitespace characters on save, and add trailing newline if missing",
         "cleanup_whitespace_characters": false,
         "show_whitespace_characters_comment": "Determines what kind of whitespaces should be drawn. Use comma-separated list of: space, tab, newline, nbsp, leading, text, trailing or all",
@@ -132,26 +133,26 @@ R"RAW(
         "debug_run_command": "<alt><shift>Return",
         "debug_toggle_breakpoint": "<primary>b",
         "debug_goto_stop": "<primary><shift>l",)RAW"
-#ifdef __linux
-R"RAW(
+                                                    #ifdef __linux
+                                                    R"RAW(
         "window_next_tab": "<primary>Tab",
         "window_previous_tab": "<primary><shift>Tab",)RAW"
-#else
-R"RAW(
+                                                    #else
+                                                    R"RAW(
         "window_next_tab": "<primary><alt>Right",
         "window_previous_tab": "<primary><alt>Left",)RAW"
-#endif
-R"RAW(
+                                                    #endif
+                                                    R"RAW(
         "window_close_tab": "<primary>w",
         "window_toggle_split": "",)RAW"
-#ifdef __APPLE__
-R"RAW(
+                                                    #ifdef __APPLE__
+                                                    R"RAW(
         "window_toggle_full_screen": "<primary><control>f",)RAW"
-#else
-R"RAW(
+                                                    #else
+                                                    R"RAW(
         "window_toggle_full_screen": "F11",)RAW"
-#endif
-R"RAW(
+                                                    #endif
+                                                    R"RAW(
         "window_toggle_tabs": "",
         "window_clear_terminal": ""
     },
@@ -161,14 +162,14 @@ R"RAW(
         "debug_build_path_comment": "Use <project_directory_name> to insert the project top level directory name, and <default_build_path> to insert your default_build_path setting.",
         "debug_build_path": "<default_build_path>/debug",
         "cmake": {)RAW"
-#ifdef _WIN32
-R"RAW(
+                                                    #ifdef _WIN32
+                                                    R"RAW(
             "command": "cmake -G\"MSYS Makefiles\"",)RAW"
-#else
-R"RAW(
+                                                    #else
+                                                    R"RAW(
             "command": "cmake",)RAW"
-#endif
-R"RAW(
+                                                    #endif
+                                                    R"RAW(
             "compile_command": "cmake --build ."
         },
         "meson": {
diff --git a/src/filesystem.cc b/src/filesystem.cc
index d8b8505e..a7289137 100644
--- a/src/filesystem.cc
+++ b/src/filesystem.cc
@@ -7,240 +7,243 @@
 
 //Only use on small files
 std::string filesystem::read(const std::string &path) {
-  std::stringstream ss;
-  std::ifstream input(path, std::ofstream::binary);
-  if(input) {
-    ss << input.rdbuf();
-    input.close();
-  }
-  return ss.str();
+    std::stringstream ss;
+    std::ifstream input(path, std::ofstream::binary);
+    if (input) {
+        ss << input.rdbuf();
+        input.close();
+    }
+    return ss.str();
 }
 
 //Only use on small files
 std::vector<std::string> filesystem::read_lines(const std::string &path) {
-  std::vector<std::string> res;
-  std::ifstream input(path, std::ofstream::binary);
-  if (input) {
-    do { res.emplace_back(); } while(getline(input, res.back()));
-  }
-  input.close();
-  return res;
+    std::vector<std::string> res;
+    std::ifstream input(path, std::ofstream::binary);
+    if (input) {
+        do { res.emplace_back(); } while (getline(input, res.back()));
+    }
+    input.close();
+    return res;
 }
 
 //Only use on small files
 bool filesystem::write(const std::string &path, const std::string &new_content) {
-  std::ofstream output(path, std::ofstream::binary);
-  if(output)
-    output << new_content;
-  else
-    return false;
-  output.close();
-  return true;
+    std::ofstream output(path, std::ofstream::binary);
+    if (output)
+        output << new_content;
+    else
+        return false;
+    output.close();
+    return true;
 }
 
 std::string filesystem::escape_argument(const std::string &argument) {
-  auto escaped=argument;
-  for(size_t pos=0;pos<escaped.size();++pos) {
-    if(escaped[pos]==' ' || escaped[pos]=='(' || escaped[pos]==')' || escaped[pos]=='\'' || escaped[pos]=='"') {
-      escaped.insert(pos, "\\");
-      ++pos;
+    auto escaped = argument;
+    for (size_t pos = 0; pos < escaped.size(); ++pos) {
+        if (escaped[pos] == ' ' || escaped[pos] == '(' || escaped[pos] == ')' || escaped[pos] == '\'' ||
+            escaped[pos] == '"') {
+            escaped.insert(pos, "\\");
+            ++pos;
+        }
     }
-  }
-  return escaped;
+    return escaped;
 }
 
 std::string filesystem::unescape_argument(const std::string &argument) {
-  auto unescaped=argument;
-  
-  if(unescaped.size()>=2) {
-    if((unescaped[0]=='\'' && unescaped[unescaped.size()-1]=='\'') ||
-       (unescaped[0]=='"' && unescaped[unescaped.size()-1]=='"')) {
-      char quotation_mark=unescaped[0];
-      unescaped=unescaped.substr(1, unescaped.size()-2);
-      size_t backslash_count=0;
-      for(size_t pos=0;pos<unescaped.size();++pos) {
-        if(backslash_count%2==1 && (unescaped[pos]=='\\' || unescaped[pos]==quotation_mark)) {
-          unescaped.erase(pos-1, 1);
-          --pos;
-          backslash_count=0;
+    auto unescaped = argument;
+
+    if (unescaped.size() >= 2) {
+        if ((unescaped[0] == '\'' && unescaped[unescaped.size() - 1] == '\'') ||
+            (unescaped[0] == '"' && unescaped[unescaped.size() - 1] == '"')) {
+            char quotation_mark = unescaped[0];
+            unescaped = unescaped.substr(1, unescaped.size() - 2);
+            size_t backslash_count = 0;
+            for (size_t pos = 0; pos < unescaped.size(); ++pos) {
+                if (backslash_count % 2 == 1 && (unescaped[pos] == '\\' || unescaped[pos] == quotation_mark)) {
+                    unescaped.erase(pos - 1, 1);
+                    --pos;
+                    backslash_count = 0;
+                } else if (unescaped[pos] == '\\')
+                    ++backslash_count;
+                else
+                    backslash_count = 0;
+            }
+            return unescaped;
         }
-        else if(unescaped[pos]=='\\')
-          ++backslash_count;
-        else
-          backslash_count=0;
-      }
-      return unescaped;
     }
-  }
-  
-  size_t backslash_count=0;
-  for(size_t pos=0;pos<unescaped.size();++pos) {
-    if(backslash_count%2==1 && (unescaped[pos]=='\\' || unescaped[pos]==' ' || unescaped[pos]=='(' || unescaped[pos]==')' || unescaped[pos]=='\'' || unescaped[pos]=='"')) {
-      unescaped.erase(pos-1, 1);
-      --pos;
-      backslash_count=0;
+
+    size_t backslash_count = 0;
+    for (size_t pos = 0; pos < unescaped.size(); ++pos) {
+        if (backslash_count % 2 == 1 &&
+            (unescaped[pos] == '\\' || unescaped[pos] == ' ' || unescaped[pos] == '(' || unescaped[pos] == ')' ||
+             unescaped[pos] == '\'' || unescaped[pos] == '"')) {
+            unescaped.erase(pos - 1, 1);
+            --pos;
+            backslash_count = 0;
+        } else if (unescaped[pos] == '\\')
+            ++backslash_count;
+        else
+            backslash_count = 0;
     }
-    else if(unescaped[pos]=='\\')
-      ++backslash_count;
-    else
-      backslash_count=0;
-  }
-  return unescaped;
+    return unescaped;
 }
 
 boost::filesystem::path filesystem::get_home_path() noexcept {
-  std::vector<std::string> environment_variables = {"HOME", "AppData"};
-  char *ptr = nullptr;
-  for (auto &variable : environment_variables) {
-    ptr=std::getenv(variable.c_str());
-    boost::system::error_code ec;
-    if (ptr!=nullptr && boost::filesystem::exists(ptr, ec))
-      return ptr;
-  }
-  return boost::filesystem::path();
+    std::vector<std::string> environment_variables = {"HOME", "AppData"};
+    char *ptr = nullptr;
+    for (auto &variable : environment_variables) {
+        ptr = std::getenv(variable.c_str());
+        boost::system::error_code ec;
+        if (ptr != nullptr && boost::filesystem::exists(ptr, ec))
+            return ptr;
+    }
+    return boost::filesystem::path();
 }
 
 boost::filesystem::path filesystem::get_short_path(const boost::filesystem::path &path) noexcept {
 #ifdef _WIN32
-  return path;
+    return path;
 #else
-  static auto home_path=get_home_path();
-  if(!home_path.empty()) {
-    auto relative_path=filesystem::get_relative_path(path, home_path);
-    if(!relative_path.empty())
-      return "~"/relative_path;
-  }
-  return path;
+    static auto home_path=get_home_path();
+    if(!home_path.empty()) {
+      auto relative_path=filesystem::get_relative_path(path, home_path);
+      if(!relative_path.empty())
+        return "~"/relative_path;
+    }
+    return path;
 #endif
 }
 
 bool filesystem::file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path) {
-  if(std::distance(file_path.begin(), file_path.end())<std::distance(path.begin(), path.end()))
-    return false;
-  return std::equal(path.begin(), path.end(), file_path.begin());
+    if (std::distance(file_path.begin(), file_path.end()) < std::distance(path.begin(), path.end()))
+        return false;
+    return std::equal(path.begin(), path.end(), file_path.begin());
 }
 
-boost::filesystem::path filesystem::find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path) {
-  auto current_path=path;
-  while(true) {
-    auto test_path=current_path/file_name;
-    if(boost::filesystem::exists(test_path))
-      return test_path;
-    if(current_path==current_path.root_directory())
-      return boost::filesystem::path();
-    current_path=current_path.parent_path();
-  }
+boost::filesystem::path
+filesystem::find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path) {
+    auto current_path = path;
+    while (true) {
+        auto test_path = current_path / file_name;
+        if (boost::filesystem::exists(test_path))
+            return test_path;
+        if (current_path == current_path.root_directory())
+            return boost::filesystem::path();
+        current_path = current_path.parent_path();
+    }
 }
 
 boost::filesystem::path filesystem::get_normal_path(const boost::filesystem::path &path) noexcept {
-  boost::filesystem::path normal_path;
-  
-  for(auto &e: path) {
-    if(e==".")
-      continue;
-    else if(e=="..") {
-      auto parent_path=normal_path.parent_path();
-      if(!parent_path.empty())
-        normal_path=parent_path;
-      else
-        normal_path/=e;
+    boost::filesystem::path normal_path;
+
+    for (auto &e: path) {
+        if (e == ".")
+            continue;
+        else if (e == "..") {
+            auto parent_path = normal_path.parent_path();
+            if (!parent_path.empty())
+                normal_path = parent_path;
+            else
+                normal_path /= e;
+        } else if (e.empty())
+            continue;
+        else
+            normal_path /= e;
     }
-    else if(e.empty())
-      continue;
-    else
-      normal_path/=e;
-  }
-  
-  return normal_path;
+
+    return normal_path;
 }
 
-boost::filesystem::path filesystem::get_relative_path(const boost::filesystem::path &path, const boost::filesystem::path &base) noexcept {
-  boost::filesystem::path relative_path;
+boost::filesystem::path
+filesystem::get_relative_path(const boost::filesystem::path &path, const boost::filesystem::path &base) noexcept {
+    boost::filesystem::path relative_path;
 
-  if(std::distance(path.begin(), path.end())<std::distance(base.begin(), base.end()))
-    return boost::filesystem::path();
-  
-  auto base_it=base.begin();
-  auto path_it=path.begin();
-  while(path_it!=path.end() && base_it!=base.end()) {
-    if(*path_it!=*base_it)
-      return boost::filesystem::path();
-    ++path_it;
-    ++base_it;
-  }
-  for(;path_it!=path.end();++path_it)
-    relative_path/=*path_it;
-
-  return relative_path;
+    if (std::distance(path.begin(), path.end()) < std::distance(base.begin(), base.end()))
+        return boost::filesystem::path();
+
+    auto base_it = base.begin();
+    auto path_it = path.begin();
+    while (path_it != path.end() && base_it != base.end()) {
+        if (*path_it != *base_it)
+            return boost::filesystem::path();
+        ++path_it;
+        ++base_it;
+    }
+    for (; path_it != path.end(); ++path_it)
+        relative_path /= *path_it;
+
+    return relative_path;
 }
 
 boost::filesystem::path filesystem::get_executable(const boost::filesystem::path &executable_name) noexcept {
 #if defined(__APPLE__) || defined(_WIN32)
-  return executable_name;
+    return executable_name;
 #endif
 
-  static std::vector<boost::filesystem::path> bin_paths={"/usr/bin", "/usr/local/bin"};
-  
-  try {
-    for(auto &path: bin_paths) {
-      if(boost::filesystem::exists(path/executable_name))
-        return executable_name;
-    }
-    
-    auto executable_name_str = executable_name.string();
-    for(auto &path: bin_paths) {
-      boost::filesystem::path executable;
-      for(boost::filesystem::directory_iterator it(path), end; it != end; ++it) {
-        auto it_path = it->path();
-        auto it_path_filename_str = it_path.filename().string();
-        if(!it_path_filename_str.empty() && it_path_filename_str.compare(0, executable_name_str.size(), executable_name_str)==0) {
-          if(it_path > executable &&
-             ((it_path_filename_str.size() > executable_name_str.size() &&
-               it_path_filename_str[executable_name_str.size()]>='0' &&
-               it_path_filename_str[executable_name_str.size()]<='9') ||
-              (it_path_filename_str.size() > executable_name_str.size()+1 &&
-               it_path_filename_str[executable_name_str.size()]=='-' &&
-               it_path_filename_str[executable_name_str.size()+1]>='0' &&
-               it_path_filename_str[executable_name_str.size()+1]<='9')) &&
-             !boost::filesystem::is_directory(it_path))
-            executable=it_path;
+    static std::vector<boost::filesystem::path> bin_paths = {"/usr/bin", "/usr/local/bin"};
+
+    try {
+        for (auto &path: bin_paths) {
+            if (boost::filesystem::exists(path / executable_name))
+                return executable_name;
+        }
+
+        auto executable_name_str = executable_name.string();
+        for (auto &path: bin_paths) {
+            boost::filesystem::path executable;
+            for (boost::filesystem::directory_iterator it(path), end; it != end; ++it) {
+                auto it_path = it->path();
+                auto it_path_filename_str = it_path.filename().string();
+                if (!it_path_filename_str.empty() &&
+                    it_path_filename_str.compare(0, executable_name_str.size(), executable_name_str) == 0) {
+                    if (it_path > executable &&
+                        ((it_path_filename_str.size() > executable_name_str.size() &&
+                          it_path_filename_str[executable_name_str.size()] >= '0' &&
+                          it_path_filename_str[executable_name_str.size()] <= '9') ||
+                         (it_path_filename_str.size() > executable_name_str.size() + 1 &&
+                          it_path_filename_str[executable_name_str.size()] == '-' &&
+                          it_path_filename_str[executable_name_str.size() + 1] >= '0' &&
+                          it_path_filename_str[executable_name_str.size() + 1] <= '9')) &&
+                        !boost::filesystem::is_directory(it_path))
+                        executable = it_path;
+                }
+            }
+            if (!executable.empty())
+                return executable;
         }
-      }
-      if(!executable.empty())
-        return executable;
     }
-  }
-  catch(...) {}
-  
-  return executable_name;
+    catch (...) {}
+
+    return executable_name;
 }
 
 // Based on https://stackoverflow.com/a/11295568
 const std::vector<boost::filesystem::path> &filesystem::get_executable_search_paths() {
-  static std::vector<boost::filesystem::path> result;
-  if(!result.empty())
-    return result;
-
-  const std::string env = getenv("PATH");
-  const char delimiter = ':';
-
-  size_t previous = 0;
-  size_t pos;
-  while((pos = env.find(delimiter, previous)) != std::string::npos) {
-    result.emplace_back(env.substr(previous, pos - previous));
-    previous = pos + 1;
-  }
-  result.emplace_back(env.substr(previous));
+    static std::vector<boost::filesystem::path> result;
+    if (!result.empty())
+        return result;
+
+    const std::string env = getenv("PATH");
+    const char delimiter = ':';
+
+    size_t previous = 0;
+    size_t pos;
+    while ((pos = env.find(delimiter, previous)) != std::string::npos) {
+        result.emplace_back(env.substr(previous, pos - previous));
+        previous = pos + 1;
+    }
+    result.emplace_back(env.substr(previous));
 
-  return result;
+    return result;
 }
 
 boost::filesystem::path filesystem::find_executable(const std::string &executable_name) {
-  for(auto &path: get_executable_search_paths()) {
-    boost::system::error_code ec;
-    auto executable_path=path/executable_name;
-    if(boost::filesystem::exists(executable_path, ec))
-      return executable_path;
-  }
-  return boost::filesystem::path();
+    for (auto &path: get_executable_search_paths()) {
+        boost::system::error_code ec;
+        auto executable_path = path / executable_name;
+        if (boost::filesystem::exists(executable_path, ec))
+            return executable_path;
+    }
+    return boost::filesystem::path();
 }
diff --git a/src/filesystem.h b/src/filesystem.h
index 11121283..e32a18a0 100644
--- a/src/filesystem.h
+++ b/src/filesystem.h
@@ -1,40 +1,55 @@
 #pragma once
+
 #include <vector>
 #include <string>
 #include <boost/filesystem.hpp>
 
 class filesystem {
 public:
-  static std::string read(const std::string &path);
-  static std::string read(const boost::filesystem::path &path) { return read(path.string()); }
-
-  static std::vector<std::string> read_lines(const std::string &path);
-  static std::vector<std::string> read_lines(const boost::filesystem::path &path) { return read_lines(path.string()); };
-
-  static bool write(const std::string &path, const std::string &new_content);
-  static bool write(const boost::filesystem::path &path, const std::string &new_content) { return write(path.string(), new_content); }
-  static bool write(const std::string &path) { return write(path, ""); };
-  static bool write(const boost::filesystem::path &path) { return write(path, ""); };
-
-  static std::string escape_argument(const std::string &argument);
-  static std::string unescape_argument(const std::string &argument);
-  
-  static boost::filesystem::path get_home_path() noexcept;
-  static boost::filesystem::path get_short_path(const boost::filesystem::path &path) noexcept;
-  
-  static bool file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path);
-  static boost::filesystem::path find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path);
-  
-  /// Return path with dot, dot-dot and directory separator elements removed
-  static boost::filesystem::path get_normal_path(const boost::filesystem::path &path) noexcept;
-  
-  /// Returns empty path on failure
-  static boost::filesystem::path get_relative_path(const boost::filesystem::path &path, const boost::filesystem::path &base) noexcept;
-  
-  /// Return executable with latest version in filename on systems that is lacking executable_name symbolic link
-  static boost::filesystem::path get_executable(const boost::filesystem::path &executable_name) noexcept;
-
-  static const std::vector<boost::filesystem::path> &get_executable_search_paths();
-  
-  static boost::filesystem::path find_executable(const std::string &executable_name);
+    static std::string read(const std::string &path);
+
+    static std::string read(const boost::filesystem::path &path) { return read(path.string()); }
+
+    static std::vector<std::string> read_lines(const std::string &path);
+
+    static std::vector<std::string> read_lines(const boost::filesystem::path &path) {
+        return read_lines(path.string());
+    };
+
+    static bool write(const std::string &path, const std::string &new_content);
+
+    static bool write(const boost::filesystem::path &path, const std::string &new_content) {
+        return write(path.string(), new_content);
+    }
+
+    static bool write(const std::string &path) { return write(path, ""); };
+
+    static bool write(const boost::filesystem::path &path) { return write(path, ""); };
+
+    static std::string escape_argument(const std::string &argument);
+
+    static std::string unescape_argument(const std::string &argument);
+
+    static boost::filesystem::path get_home_path() noexcept;
+
+    static boost::filesystem::path get_short_path(const boost::filesystem::path &path) noexcept;
+
+    static bool file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path);
+
+    static boost::filesystem::path
+    find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path);
+
+    /// Return path with dot, dot-dot and directory separator elements removed
+    static boost::filesystem::path get_normal_path(const boost::filesystem::path &path) noexcept;
+
+    /// Returns empty path on failure
+    static boost::filesystem::path
+    get_relative_path(const boost::filesystem::path &path, const boost::filesystem::path &base) noexcept;
+
+    /// Return executable with latest version in filename on systems that is lacking executable_name symbolic link
+    static boost::filesystem::path get_executable(const boost::filesystem::path &executable_name) noexcept;
+
+    static const std::vector<boost::filesystem::path> &get_executable_search_paths();
+
+    static boost::filesystem::path find_executable(const std::string &executable_name);
 };
diff --git a/src/git.cc b/src/git.cc
index 0a1d1198..100ad9a1 100644
--- a/src/git.cc
+++ b/src/git.cc
@@ -1,300 +1,317 @@
 #include "git.h"
 #include <cstring>
 
-bool Git::initialized=false;
+bool Git::initialized = false;
 std::mutex Git::mutex;
 
 std::string Git::Error::message() noexcept {
-  const git_error *last_error = giterr_last();
-  if(last_error==nullptr)
-    return std::string();
-  else
-    return last_error->message;
+    const git_error *last_error = giterr_last();
+    if (last_error == nullptr)
+        return std::string();
+    else
+        return last_error->message;
 }
 
 Git::Repository::Diff::Diff(const boost::filesystem::path &path, git_repository *repository) : repository(repository) {
-  blob=std::shared_ptr<git_blob>(nullptr, [](git_blob *blob) {
-    if(blob) git_blob_free(blob);
-  });
-  Error error;
-  std::lock_guard<std::mutex> lock(mutex);
-  auto spec="HEAD:"+path.generic_string();
-  error.code = git_revparse_single(reinterpret_cast<git_object**>(&blob), repository, spec.c_str());
-  if(error)
-    throw std::runtime_error(error.message());
-  
-  git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
-  options.context_lines=0;
+    blob = std::shared_ptr<git_blob>(nullptr, [](git_blob *blob) {
+        if (blob) git_blob_free(blob);
+    });
+    Error error;
+    std::lock_guard<std::mutex> lock(mutex);
+    auto spec = "HEAD:" + path.generic_string();
+    error.code = git_revparse_single(reinterpret_cast<git_object **>(&blob), repository, spec.c_str());
+    if (error)
+        throw std::runtime_error(error.message());
+
+    git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
+    options.context_lines = 0;
 }
 
 //Based on https://github.com/atom/git-diff/blob/master/lib/git-diff-view.coffee
 int Git::Repository::Diff::hunk_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) noexcept {
-  auto lines=static_cast<Lines*>(payload);
-  auto start=hunk->new_start-1;
-  auto end=hunk->new_start+hunk->new_lines-1;
-  if(hunk->old_lines==0 && hunk->new_lines>0)
-    lines->added.emplace_back(start, end);
-  else if(hunk->new_lines==0 && hunk->old_lines>0)
-    lines->removed.emplace_back(start);
-  else
-    lines->modified.emplace_back(start, end);
-    
-  return 0;
+    auto lines = static_cast<Lines *>(payload);
+    auto start = hunk->new_start - 1;
+    auto end = hunk->new_start + hunk->new_lines - 1;
+    if (hunk->old_lines == 0 && hunk->new_lines > 0)
+        lines->added.emplace_back(start, end);
+    else if (hunk->new_lines == 0 && hunk->old_lines > 0)
+        lines->removed.emplace_back(start);
+    else
+        lines->modified.emplace_back(start, end);
+
+    return 0;
 }
 
 Git::Repository::Diff::Lines Git::Repository::Diff::get_lines(const std::string &buffer) {
-  Lines lines;
-  Error error;
-  std::lock_guard<std::mutex> lock(mutex);
-  error.code=git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr, nullptr, hunk_cb, nullptr, &lines);
-  if(error)
-    throw std::runtime_error(error.message());
-  return lines;
+    Lines lines;
+    Error error;
+    std::lock_guard<std::mutex> lock(mutex);
+    error.code = git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr,
+                                         nullptr, hunk_cb, nullptr, &lines);
+    if (error)
+        throw std::runtime_error(error.message());
+    return lines;
 }
 
-std::vector<Git::Repository::Diff::Hunk> Git::Repository::Diff::get_hunks(const std::string &old_buffer, const std::string &new_buffer) {
-  std::vector<Git::Repository::Diff::Hunk> hunks;
-  Error error;
-  git_diff_options options;
-  git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
-  options.context_lines=0;
-  error.code=git_diff_buffers(old_buffer.c_str(), old_buffer.size(), nullptr, new_buffer.c_str(), new_buffer.size(), nullptr, &options, nullptr, nullptr,
-                              [](const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) {
-    auto hunks=static_cast<std::vector<Git::Repository::Diff::Hunk>*>(payload);
-    hunks->emplace_back(hunk->old_start, hunk->old_lines, hunk->new_start, hunk->new_lines);
-    return 0;
-  }, nullptr, &hunks);
-  if(error)
-    throw std::runtime_error(error.message());
-  return hunks;
+std::vector<Git::Repository::Diff::Hunk>
+Git::Repository::Diff::get_hunks(const std::string &old_buffer, const std::string &new_buffer) {
+    std::vector<Git::Repository::Diff::Hunk> hunks;
+    Error error;
+    git_diff_options options;
+    git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
+    options.context_lines = 0;
+    error.code = git_diff_buffers(old_buffer.c_str(), old_buffer.size(), nullptr, new_buffer.c_str(), new_buffer.size(),
+                                  nullptr, &options, nullptr, nullptr,
+                                  [](const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) {
+                                      auto hunks = static_cast<std::vector<Git::Repository::Diff::Hunk> *>(payload);
+                                      hunks->emplace_back(hunk->old_start, hunk->old_lines, hunk->new_start,
+                                                          hunk->new_lines);
+                                      return 0;
+                                  }, nullptr, &hunks);
+    if (error)
+        throw std::runtime_error(error.message());
+    return hunks;
 }
 
-int Git::Repository::Diff::line_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line, void *payload) noexcept {
-  auto details=static_cast<std::pair<std::string, int> *>(payload);
-  auto line_nr=details->second;
-  auto start=hunk->new_start-1;
-  auto end=hunk->new_start+hunk->new_lines-1;
-  if(line_nr==start || (line_nr>=start && line_nr<end)) {
-    if(details->first.empty())
-      details->first+=std::string(hunk->header, hunk->header_len);
-    details->first+=line->origin+std::string(line->content, line->content_len);
-  }
-  return 0;
+int Git::Repository::Diff::line_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line,
+                                   void *payload) noexcept {
+    auto details = static_cast<std::pair<std::string, int> *>(payload);
+    auto line_nr = details->second;
+    auto start = hunk->new_start - 1;
+    auto end = hunk->new_start + hunk->new_lines - 1;
+    if (line_nr == start || (line_nr >= start && line_nr < end)) {
+        if (details->first.empty())
+            details->first += std::string(hunk->header, hunk->header_len);
+        details->first += line->origin + std::string(line->content, line->content_len);
+    }
+    return 0;
 }
 
 std::string Git::Repository::Diff::get_details(const std::string &buffer, int line_nr) {
-  std::pair<std::string, int> details;
-  details.second=line_nr;
-  Error error;
-  std::lock_guard<std::mutex> lock(mutex);
-  error.code=git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr, nullptr, nullptr, line_cb, &details);
-  if(error)
-    throw std::runtime_error(error.message());
-  return details.first;
+    std::pair<std::string, int> details;
+    details.second = line_nr;
+    Error error;
+    std::lock_guard<std::mutex> lock(mutex);
+    error.code = git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr,
+                                         nullptr, nullptr, line_cb, &details);
+    if (error)
+        throw std::runtime_error(error.message());
+    return details.first;
 }
 
 Git::Repository::Repository(const boost::filesystem::path &path) {
-  git_repository *repository_ptr;
-  {
-    Error error;
-    std::lock_guard<std::mutex> lock(mutex);
-    auto path_str=path.generic_string();
-    error.code = git_repository_open_ext(&repository_ptr, path_str.c_str(), 0, nullptr);
-    if(error)
-      throw std::runtime_error(error.message());
-  }
-  repository=std::unique_ptr<git_repository, std::function<void(git_repository *)> >(repository_ptr, [](git_repository *ptr) {
-    git_repository_free(ptr);
-  });
-  
-  work_path=get_work_path();
-  if(work_path.empty())
-    throw std::runtime_error("Could not find work path");
-  
-  auto git_directory=Gio::File::create_for_path(get_path().string());
-  monitor=git_directory->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
-  monitor_changed_connection=monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
-                                                                      const Glib::RefPtr<Gio::File>&,
-                                                                      Gio::FileMonitorEvent monitor_event) {
-    if(monitor_event!=Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-      this->clear_saved_status();
+    git_repository *repository_ptr;
+    {
+        Error error;
+        std::lock_guard<std::mutex> lock(mutex);
+        auto path_str = path.generic_string();
+        error.code = git_repository_open_ext(&repository_ptr, path_str.c_str(), 0, nullptr);
+        if (error)
+            throw std::runtime_error(error.message());
     }
-  }, false);
+    repository = std::unique_ptr<git_repository, std::function<void(git_repository *)> >(repository_ptr,
+                                                                                         [](git_repository *ptr) {
+                                                                                             git_repository_free(ptr);
+                                                                                         });
+
+    work_path = get_work_path();
+    if (work_path.empty())
+        throw std::runtime_error("Could not find work path");
+
+    auto git_directory = Gio::File::create_for_path(get_path().string());
+    monitor = git_directory->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
+    monitor_changed_connection = monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
+                                                                          const Glib::RefPtr<Gio::File> &,
+                                                                          Gio::FileMonitorEvent monitor_event) {
+        if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+            this->clear_saved_status();
+        }
+    }, false);
 }
 
 Git::Repository::~Repository() {
-  monitor_changed_connection.disconnect();
+    monitor_changed_connection.disconnect();
 }
 
 std::string Git::Repository::status_string(STATUS status) noexcept {
-  switch(status) {
-    case STATUS::CURRENT: return "current";
-    case STATUS::NEW: return "new";
-    case STATUS::MODIFIED: return "modified";
-    case STATUS::DELETED: return "deleted";
-    case STATUS::RENAMED: return "renamed";
-    case STATUS::TYPECHANGE: return "typechange";
-    case STATUS::UNREADABLE: return "unreadable";
-    case STATUS::IGNORED: return "ignored";
-    case STATUS::CONFLICTED: return "conflicted";
-    default: return "";
-  }
+    switch (status) {
+        case STATUS::CURRENT:
+            return "current";
+        case STATUS::NEW:
+            return "new";
+        case STATUS::MODIFIED:
+            return "modified";
+        case STATUS::DELETED:
+            return "deleted";
+        case STATUS::RENAMED:
+            return "renamed";
+        case STATUS::TYPECHANGE:
+            return "typechange";
+        case STATUS::UNREADABLE:
+            return "unreadable";
+        case STATUS::IGNORED:
+            return "ignored";
+        case STATUS::CONFLICTED:
+            return "conflicted";
+        default:
+            return "";
+    }
 }
 
 int Git::Repository::status_callback(const char *path, unsigned int status_flags, void *data) noexcept {
-  auto callback=static_cast<std::function<void(const char *path, STATUS status)>*>(data);
-  
-  STATUS status;
-  if((status_flags&(GIT_STATUS_INDEX_NEW|GIT_STATUS_WT_NEW))>0)
-    status=STATUS::NEW;
-  else if((status_flags&(GIT_STATUS_INDEX_MODIFIED|GIT_STATUS_WT_MODIFIED))>0)
-    status=STATUS::MODIFIED;
-  else if((status_flags&(GIT_STATUS_INDEX_DELETED|GIT_STATUS_WT_DELETED))>0)
-    status=STATUS::DELETED;
-  else if((status_flags&(GIT_STATUS_INDEX_RENAMED|GIT_STATUS_WT_RENAMED))>0)
-    status=STATUS::RENAMED;
-  else if((status_flags&(GIT_STATUS_INDEX_TYPECHANGE|GIT_STATUS_WT_TYPECHANGE))>0)
-    status=STATUS::TYPECHANGE;
-  else if((status_flags&(GIT_STATUS_WT_UNREADABLE))>0)
-    status=STATUS::UNREADABLE;
-  else if((status_flags&(GIT_STATUS_IGNORED))>0)
-    status=STATUS::IGNORED;
-  else if((status_flags&(GIT_STATUS_CONFLICTED))>0)
-    status=STATUS::CONFLICTED;
-  else
-    status=STATUS::CURRENT;
-  
-  if(*callback)
-    (*callback)(path, status);
-  
-  return 0;
+    auto callback = static_cast<std::function<void(const char *path, STATUS status)> *>(data);
+
+    STATUS status;
+    if ((status_flags & (GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_NEW)) > 0)
+        status = STATUS::NEW;
+    else if ((status_flags & (GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED)) > 0)
+        status = STATUS::MODIFIED;
+    else if ((status_flags & (GIT_STATUS_INDEX_DELETED | GIT_STATUS_WT_DELETED)) > 0)
+        status = STATUS::DELETED;
+    else if ((status_flags & (GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED)) > 0)
+        status = STATUS::RENAMED;
+    else if ((status_flags & (GIT_STATUS_INDEX_TYPECHANGE | GIT_STATUS_WT_TYPECHANGE)) > 0)
+        status = STATUS::TYPECHANGE;
+    else if ((status_flags & (GIT_STATUS_WT_UNREADABLE)) > 0)
+        status = STATUS::UNREADABLE;
+    else if ((status_flags & (GIT_STATUS_IGNORED)) > 0)
+        status = STATUS::IGNORED;
+    else if ((status_flags & (GIT_STATUS_CONFLICTED)) > 0)
+        status = STATUS::CONFLICTED;
+    else
+        status = STATUS::CURRENT;
+
+    if (*callback)
+        (*callback)(path, status);
+
+    return 0;
 }
 
 Git::Repository::Status Git::Repository::get_status() {
-  {
-    std::unique_lock<std::mutex> lock(saved_status_mutex);
-    if(has_saved_status)
-      return saved_status;
-  }
-  
-  Status status;
-  bool first=true;
-  std::unique_lock<std::mutex> status_saved_lock(saved_status_mutex, std::defer_lock);
-  std::function<void(const char *path, STATUS status)> callback=[this, &status, &first, &status_saved_lock](const char *path_cstr, STATUS status_enum) {
-    if(first) {
-      status_saved_lock.lock();
-      first=false;
+    {
+        std::unique_lock<std::mutex> lock(saved_status_mutex);
+        if (has_saved_status)
+            return saved_status;
     }
-    boost::filesystem::path rel_path(path_cstr);
-    do {
-      if(status_enum==STATUS::MODIFIED)
-        status.modified.emplace((work_path/rel_path).generic_string());
-      if(status_enum==STATUS::NEW)
-        status.added.emplace((work_path/rel_path).generic_string());
-      rel_path=rel_path.parent_path();
-    } while(!rel_path.empty());
-  };
-  Error error;
-  std::lock_guard<std::mutex> lock(mutex);
-  error.code = git_status_foreach(repository.get(), status_callback, &callback);
-  if(error)
-    throw std::runtime_error(error.message());
-  saved_status=status;
-  has_saved_status=true;
-  if(status_saved_lock)
-    status_saved_lock.unlock();
-  return status;
+
+    Status status;
+    bool first = true;
+    std::unique_lock<std::mutex> status_saved_lock(saved_status_mutex, std::defer_lock);
+    std::function<void(const char *path, STATUS status)> callback = [this, &status, &first, &status_saved_lock](
+            const char *path_cstr, STATUS status_enum) {
+        if (first) {
+            status_saved_lock.lock();
+            first = false;
+        }
+        boost::filesystem::path rel_path(path_cstr);
+        do {
+            if (status_enum == STATUS::MODIFIED)
+                status.modified.emplace((work_path / rel_path).generic_string());
+            if (status_enum == STATUS::NEW)
+                status.added.emplace((work_path / rel_path).generic_string());
+            rel_path = rel_path.parent_path();
+        } while (!rel_path.empty());
+    };
+    Error error;
+    std::lock_guard<std::mutex> lock(mutex);
+    error.code = git_status_foreach(repository.get(), status_callback, &callback);
+    if (error)
+        throw std::runtime_error(error.message());
+    saved_status = status;
+    has_saved_status = true;
+    if (status_saved_lock)
+        status_saved_lock.unlock();
+    return status;
 }
 
 void Git::Repository::clear_saved_status() {
-  std::unique_lock<std::mutex> lock(saved_status_mutex);
-  saved_status.added.clear();
-  saved_status.modified.clear();
-  has_saved_status=false;
+    std::unique_lock<std::mutex> lock(saved_status_mutex);
+    saved_status.added.clear();
+    saved_status.modified.clear();
+    has_saved_status = false;
 }
 
 boost::filesystem::path Git::Repository::get_work_path() noexcept {
-  std::lock_guard<std::mutex> lock(mutex);
-  return Git::path(git_repository_workdir(repository.get()));
+    std::lock_guard<std::mutex> lock(mutex);
+    return Git::path(git_repository_workdir(repository.get()));
 }
 
 boost::filesystem::path Git::Repository::get_path() noexcept {
-  std::lock_guard<std::mutex> lock(mutex);
-  return Git::path(git_repository_path(repository.get()));
+    std::lock_guard<std::mutex> lock(mutex);
+    return Git::path(git_repository_path(repository.get()));
 }
 
 boost::filesystem::path Git::Repository::get_root_path(const boost::filesystem::path &path) {
-  initialize();
-  git_buf root = {0, 0, 0};
-  {
-    Error error;
-    std::lock_guard<std::mutex> lock(mutex);
-    auto path_str=path.generic_string();
-    error.code = git_repository_discover(&root, path_str.c_str(), 0, nullptr);
-    if(error)
-      throw std::runtime_error(error.message());
-  }
-  auto root_path=Git::path(root.ptr, root.size);
-  git_buf_free(&root);
-  return root_path;
+    initialize();
+    git_buf root = {0, 0, 0};
+    {
+        Error error;
+        std::lock_guard<std::mutex> lock(mutex);
+        auto path_str = path.generic_string();
+        error.code = git_repository_discover(&root, path_str.c_str(), 0, nullptr);
+        if (error)
+            throw std::runtime_error(error.message());
+    }
+    auto root_path = Git::path(root.ptr, root.size);
+    git_buf_free(&root);
+    return root_path;
 }
 
 Git::Repository::Diff Git::Repository::get_diff(const boost::filesystem::path &path) {
-  return Diff(path, repository.get());
+    return Diff(path, repository.get());
 }
 
 std::string Git::Repository::get_branch() noexcept {
-  std::string branch;
-  git_reference *reference;
-  if(git_repository_head(&reference, repository.get())==0) {
-    if(auto reference_name_cstr=git_reference_name(reference)) {
-      std::string reference_name(reference_name_cstr);
-      size_t pos;
-      if((pos=reference_name.rfind('/'))!=std::string::npos) {
-        if(pos+1<reference_name.size())
-          branch=reference_name.substr(pos+1);
-      }
-      else if((pos=reference_name.rfind('\\'))!=std::string::npos) {
-        if(pos+1<reference_name.size())
-          branch=reference_name.substr(pos+1);
-      }
+    std::string branch;
+    git_reference *reference;
+    if (git_repository_head(&reference, repository.get()) == 0) {
+        if (auto reference_name_cstr = git_reference_name(reference)) {
+            std::string reference_name(reference_name_cstr);
+            size_t pos;
+            if ((pos = reference_name.rfind('/')) != std::string::npos) {
+                if (pos + 1 < reference_name.size())
+                    branch = reference_name.substr(pos + 1);
+            } else if ((pos = reference_name.rfind('\\')) != std::string::npos) {
+                if (pos + 1 < reference_name.size())
+                    branch = reference_name.substr(pos + 1);
+            }
+        }
+        git_reference_free(reference);
     }
-    git_reference_free(reference);
-  }
-  return branch;
+    return branch;
 }
 
 void Git::initialize() noexcept {
-  std::lock_guard<std::mutex> lock(mutex);
-  if(!initialized) {
-    git_libgit2_init();
-    initialized=true;
-  }
+    std::lock_guard<std::mutex> lock(mutex);
+    if (!initialized) {
+        git_libgit2_init();
+        initialized = true;
+    }
 }
 
 std::shared_ptr<Git::Repository> Git::get_repository(const boost::filesystem::path &path) {
-  initialize();
-  static std::unordered_map<std::string, std::weak_ptr<Git::Repository> > cache;
-  static std::mutex mutex;
-  
-  std::lock_guard<std::mutex> lock(mutex);
-  auto root_path=Repository::get_root_path(path).generic_string();
-  auto it=cache.find(root_path);
-  if(it==cache.end())
-    it=cache.emplace(root_path, std::weak_ptr<Git::Repository>()).first;
-  auto instance=it->second.lock();
-  if(!instance)
-    it->second=instance=std::shared_ptr<Repository>(new Repository(root_path));
-  return instance;
+    initialize();
+    static std::unordered_map<std::string, std::weak_ptr<Git::Repository> > cache;
+    static std::mutex mutex;
+
+    std::lock_guard<std::mutex> lock(mutex);
+    auto root_path = Repository::get_root_path(path).generic_string();
+    auto it = cache.find(root_path);
+    if (it == cache.end())
+        it = cache.emplace(root_path, std::weak_ptr<Git::Repository>()).first;
+    auto instance = it->second.lock();
+    if (!instance)
+        it->second = instance = std::shared_ptr<Repository>(new Repository(root_path));
+    return instance;
 }
 
 boost::filesystem::path Git::path(const char *cpath, size_t cpath_length) noexcept {
-  if(cpath==nullptr)
-    return boost::filesystem::path();
-  if(cpath_length==static_cast<size_t>(-1))
-    cpath_length=strlen(cpath);
-  if(cpath_length>0 && (cpath[cpath_length-1]=='/' || cpath[cpath_length-1]=='\\'))
-    return std::string(cpath, cpath_length-1);
-  else
-    return std::string(cpath, cpath_length);
+    if (cpath == nullptr)
+        return boost::filesystem::path();
+    if (cpath_length == static_cast<size_t>(-1))
+        cpath_length = strlen(cpath);
+    if (cpath_length > 0 && (cpath[cpath_length - 1] == '/' || cpath[cpath_length - 1] == '\\'))
+        return std::string(cpath, cpath_length - 1);
+    else
+        return std::string(cpath, cpath_length);
 }
diff --git a/src/git.h b/src/git.h
index eaf9526a..38545c92 100644
--- a/src/git.h
+++ b/src/git.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <git2.h>
 #include <mutex>
 #include <memory>
@@ -10,98 +11,125 @@
 #include <boost/filesystem.hpp>
 
 class Git {
-  friend class Repository;
+    friend class Repository;
+
 public:
-  class Error {
-    friend class Git;
-    std::string message() noexcept;
-  public:
-    int code=0;
-    Error() {}
-    operator bool() noexcept {return code<0;}
-  };
-  
-  class Repository {
-  public:
-    class Diff {
-    public:
-      class Lines {
-      public:
-        std::vector<std::pair<int, int> > added;
-        std::vector<std::pair<int, int> > modified;
-        std::vector<int> removed;
-      };
-      class Hunk {
-      public:
-        Hunk(int old_start, int old_size, int new_start, int new_size): old_lines(old_start, old_size), new_lines(new_start, new_size) {}
-        /// Start and size
-        std::pair<int, int> old_lines;
-        /// Start and size
-        std::pair<int, int> new_lines;
-      };
-    private:
-      friend class Repository;
-      Diff(const boost::filesystem::path &path, git_repository *repository);
-      git_repository *repository;
-      std::shared_ptr<git_blob> blob;
-      git_diff_options options;
-      static int hunk_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) noexcept;
-      static int line_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line, void *payload) noexcept;
+    class Error {
+        friend class Git;
+
+        std::string message() noexcept;
+
     public:
-      Diff() : repository(nullptr), blob(nullptr) {}
-      Lines get_lines(const std::string &buffer);
-      static std::vector<Hunk> get_hunks(const std::string &old_buffer, const std::string &new_buffer);
-      std::string get_details(const std::string &buffer, int line_nr);
+        int code = 0;
+
+        Error() {}
+
+        operator bool() noexcept { return code < 0; }
     };
-    
-    enum class STATUS {CURRENT, NEW, MODIFIED, DELETED, RENAMED, TYPECHANGE, UNREADABLE, IGNORED, CONFLICTED};
-    class Status {
+
+    class Repository {
     public:
-      std::unordered_set<std::string> added;
-      std::unordered_set<std::string> modified;
+        class Diff {
+        public:
+            class Lines {
+            public:
+                std::vector<std::pair<int, int> > added;
+                std::vector<std::pair<int, int> > modified;
+                std::vector<int> removed;
+            };
+
+            class Hunk {
+            public:
+                Hunk(int old_start, int old_size, int new_start, int new_size) : old_lines(old_start, old_size),
+                                                                                 new_lines(new_start, new_size) {}
+
+                /// Start and size
+                std::pair<int, int> old_lines;
+                /// Start and size
+                std::pair<int, int> new_lines;
+            };
+
+        private:
+            friend class Repository;
+
+            Diff(const boost::filesystem::path &path, git_repository *repository);
+
+            git_repository *repository;
+            std::shared_ptr<git_blob> blob;
+            git_diff_options options;
+
+            static int hunk_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) noexcept;
+
+            static int line_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line,
+                               void *payload) noexcept;
+
+        public:
+            Diff() : repository(nullptr), blob(nullptr) {}
+
+            Lines get_lines(const std::string &buffer);
+
+            static std::vector<Hunk> get_hunks(const std::string &old_buffer, const std::string &new_buffer);
+
+            std::string get_details(const std::string &buffer, int line_nr);
+        };
+
+        enum class STATUS {
+            CURRENT, NEW, MODIFIED, DELETED, RENAMED, TYPECHANGE, UNREADABLE, IGNORED, CONFLICTED
+        };
+
+        class Status {
+        public:
+            std::unordered_set<std::string> added;
+            std::unordered_set<std::string> modified;
+        };
+
+    private:
+        friend class Git;
+
+        Repository(const boost::filesystem::path &path);
+
+        static int status_callback(const char *path, unsigned int status_flags, void *data) noexcept;
+
+        std::unique_ptr<git_repository, std::function<void(git_repository *)> > repository;
+
+        boost::filesystem::path work_path;
+        sigc::connection monitor_changed_connection;
+        Status saved_status;
+        bool has_saved_status = false;
+        std::mutex saved_status_mutex;
+    public:
+        ~Repository();
+
+        static std::string status_string(STATUS status) noexcept;
+
+        Status get_status();
+
+        void clear_saved_status();
+
+        boost::filesystem::path get_work_path() noexcept;
+
+        boost::filesystem::path get_path() noexcept;
+
+        static boost::filesystem::path get_root_path(const boost::filesystem::path &path);
+
+        Diff get_diff(const boost::filesystem::path &path);
+
+        std::string get_branch() noexcept;
+
+        Glib::RefPtr<Gio::FileMonitor> monitor;
     };
-  private:
-    friend class Git;
-    Repository(const boost::filesystem::path &path);
-    
-    static int status_callback(const char *path, unsigned int status_flags, void *data) noexcept;
-    
-    std::unique_ptr<git_repository, std::function<void(git_repository *)> > repository;
-    
-    boost::filesystem::path work_path;
-    sigc::connection monitor_changed_connection;
-    Status saved_status;
-    bool has_saved_status=false;
-    std::mutex saved_status_mutex;
-  public:
-    ~Repository();
-    
-    static std::string status_string(STATUS status) noexcept;
-    
-    Status get_status();
-    void clear_saved_status();
-    
-    boost::filesystem::path get_work_path() noexcept;
-    boost::filesystem::path get_path() noexcept;
-    static boost::filesystem::path get_root_path(const boost::filesystem::path &path);
-    
-    Diff get_diff(const boost::filesystem::path &path);
-    
-    std::string get_branch() noexcept;
-    
-    Glib::RefPtr<Gio::FileMonitor> monitor;
-  };
-  
+
 private:
-  static bool initialized;
-  
-  ///Mutex for thread safe operations
-  static std::mutex mutex;
-  
-  ///Call initialize in public static methods
-  static void initialize() noexcept;
-  
-  static boost::filesystem::path path(const char *cpath, size_t cpath_length=static_cast<size_t>(-1)) noexcept;
+    static bool initialized;
+
+    ///Mutex for thread safe operations
+    static std::mutex mutex;
+
+    ///Call initialize in public static methods
+    static void initialize() noexcept;
+
+    static boost::filesystem::path path(const char *cpath, size_t cpath_length = static_cast<size_t>(-1)) noexcept;
+
 public:
-  static std::shared_ptr<Repository> get_repository(const boost::filesystem::path &path);
+    static std::shared_ptr<Repository> get_repository(const boost::filesystem::path &path);
 };
diff --git a/src/info.cc b/src/info.cc
index 22029a75..a4723a4c 100644
--- a/src/info.cc
+++ b/src/info.cc
@@ -1,36 +1,36 @@
 #include "info.h"
 
 Info::Info() {
-  set_hexpand(false);
-  set_halign(Gtk::Align::ALIGN_END);
-  
-  auto content_area=dynamic_cast<Gtk::Container*>(get_content_area());
-  label.set_max_width_chars(40);
-  label.set_line_wrap(true);
-  content_area->add(label);
-  
-  get_style_context()->add_class("juci_info");
-  
-  //Workaround from https://bugzilla.gnome.org/show_bug.cgi?id=710888
-  //Issue described at the same issue report
-  //TODO: remove later
-  auto revealer = gtk_widget_get_template_child (GTK_WIDGET (gobj()), GTK_TYPE_INFO_BAR, "revealer");
-  if (revealer) {
-    gtk_revealer_set_transition_type (GTK_REVEALER (revealer), GTK_REVEALER_TRANSITION_TYPE_NONE);
-    gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), 0);
-  }
+    set_hexpand(false);
+    set_halign(Gtk::Align::ALIGN_END);
+
+    auto content_area = dynamic_cast<Gtk::Container *>(get_content_area());
+    label.set_max_width_chars(40);
+    label.set_line_wrap(true);
+    content_area->add(label);
+
+    get_style_context()->add_class("juci_info");
+
+    //Workaround from https://bugzilla.gnome.org/show_bug.cgi?id=710888
+    //Issue described at the same issue report
+    //TODO: remove later
+    auto revealer = gtk_widget_get_template_child(GTK_WIDGET (gobj()), GTK_TYPE_INFO_BAR, "revealer");
+    if (revealer) {
+        gtk_revealer_set_transition_type(GTK_REVEALER (revealer), GTK_REVEALER_TRANSITION_TYPE_NONE);
+        gtk_revealer_set_transition_duration(GTK_REVEALER (revealer), 0);
+    }
 }
 
 void Info::print(const std::string &text) {
-  timeout_connection.disconnect();
-  //Timeout based on https://en.wikipedia.org/wiki/Words_per_minute
-  //(average_words_per_minute*average_letters_per_word)/60 => (228*4.5)/60 = 17.1
-  double timeout=1000.0*std::max(3.0, 1.0+text.size()/17.1);
-  timeout_connection=Glib::signal_timeout().connect([this]() {
-    hide();
-    return false;
-  }, timeout);
-  
-  label.set_text(text);
-  show();
+    timeout_connection.disconnect();
+    //Timeout based on https://en.wikipedia.org/wiki/Words_per_minute
+    //(average_words_per_minute*average_letters_per_word)/60 => (228*4.5)/60 = 17.1
+    double timeout = 1000.0 * std::max(3.0, 1.0 + text.size() / 17.1);
+    timeout_connection = Glib::signal_timeout().connect([this]() {
+        hide();
+        return false;
+    }, timeout);
+
+    label.set_text(text);
+    show();
 }
diff --git a/src/info.h b/src/info.h
index 38bc841a..d1ad78ab 100644
--- a/src/info.h
+++ b/src/info.h
@@ -1,17 +1,19 @@
 #pragma once
+
 #include <gtkmm.h>
 
 class Info : public Gtk::InfoBar {
-  Info();
+    Info();
+
 public:
-  static Info &get() {
-    static Info instance;
-    return instance;
-  }
-  
-  void print(const std::string &text);
-  
+    static Info &get() {
+        static Info instance;
+        return instance;
+    }
+
+    void print(const std::string &text);
+
 private:
-  Gtk::Label label;
-  sigc::connection timeout_connection;
+    Gtk::Label label;
+    sigc::connection timeout_connection;
 };
diff --git a/src/juci.cc b/src/juci.cc
index a063a1df..29881803 100644
--- a/src/juci.cc
+++ b/src/juci.cc
@@ -5,133 +5,133 @@
 #include "menu.h"
 #include "config.h"
 #include "terminal.h"
+
 #ifndef _WIN32
 #include <signal.h>
 #endif
 
 int Application::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) {
-  Glib::set_prgname("juci");
-  Glib::OptionContext ctx("[PATH ...]");
-  Glib::OptionGroup gtk_group(gtk_get_option_group(true));
-  ctx.add_group(gtk_group);
-  int argc;
-  char **argv = cmd->get_arguments(argc);
-  ctx.parse(argc, argv);
-  if(argc>=2) {
-    boost::system::error_code current_path_ec;
-    auto current_path=boost::filesystem::current_path(current_path_ec);
-    if(current_path_ec)
-      errors.emplace_back("Error: could not find current path\n");
-    for(int c=1;c<argc;c++) {
-      boost::filesystem::path path(argv[c]);
-      if(path.is_relative() && !current_path_ec)
-        path=current_path/path;
-      if(boost::filesystem::exists(path)) {
-        if(boost::filesystem::is_regular_file(path))
-          files.emplace_back(path, 0);
-        else if(boost::filesystem::is_directory(path))
-          directories.emplace_back(path);
-      }
-      //Open new file if parent path exists
-      else {
-        if(path.is_absolute() && boost::filesystem::is_directory(path.parent_path()))
-          files.emplace_back(path, 0);
-        else
-          errors.emplace_back("Error: could not create "+path.string()+".\n");
-      }
+    Glib::set_prgname("juci");
+    Glib::OptionContext ctx("[PATH ...]");
+    Glib::OptionGroup gtk_group(gtk_get_option_group(true));
+    ctx.add_group(gtk_group);
+    int argc;
+    char **argv = cmd->get_arguments(argc);
+    ctx.parse(argc, argv);
+    if (argc >= 2) {
+        boost::system::error_code current_path_ec;
+        auto current_path = boost::filesystem::current_path(current_path_ec);
+        if (current_path_ec)
+            errors.emplace_back("Error: could not find current path\n");
+        for (int c = 1; c < argc; c++) {
+            boost::filesystem::path path(argv[c]);
+            if (path.is_relative() && !current_path_ec)
+                path = current_path / path;
+            if (boost::filesystem::exists(path)) {
+                if (boost::filesystem::is_regular_file(path))
+                    files.emplace_back(path, 0);
+                else if (boost::filesystem::is_directory(path))
+                    directories.emplace_back(path);
+            }
+                //Open new file if parent path exists
+            else {
+                if (path.is_absolute() && boost::filesystem::is_directory(path.parent_path()))
+                    files.emplace_back(path, 0);
+                else
+                    errors.emplace_back("Error: could not create " + path.string() + ".\n");
+            }
+        }
     }
-  }
-  activate();
-  return 0;
+    activate();
+    return 0;
 }
 
 void Application::on_activate() {
-  std::vector<std::pair<int, int>> file_offsets;
-  std::string current_file;
-  Window::get().load_session(directories, files, file_offsets, current_file, directories.empty() && files.empty());
-  
-  Window::get().add_widgets();
-  
-  add_window(Window::get());
-  Window::get().show();
-  
-  bool first_directory=true;
-  for(auto &directory: directories) {
-    if(first_directory) {
-      Directories::get().open(directory);
-      first_directory=false;
-    }
-    else {
-      std::string files_in_directory;
-      for(auto it=files.begin();it!=files.end();) {
-        if(it->first.generic_string().compare(0, directory.generic_string().size()+1, directory.generic_string()+'/')==0) {
-          files_in_directory+=" "+it->first.string();
-          it=files.erase(it);
+    std::vector<std::pair<int, int>> file_offsets;
+    std::string current_file;
+    Window::get().load_session(directories, files, file_offsets, current_file, directories.empty() && files.empty());
+
+    Window::get().add_widgets();
+
+    add_window(Window::get());
+    Window::get().show();
+
+    bool first_directory = true;
+    for (auto &directory: directories) {
+        if (first_directory) {
+            Directories::get().open(directory);
+            first_directory = false;
+        } else {
+            std::string files_in_directory;
+            for (auto it = files.begin(); it != files.end();) {
+                if (it->first.generic_string().compare(0, directory.generic_string().size() + 1,
+                                                       directory.generic_string() + '/') == 0) {
+                    files_in_directory += " " + it->first.string();
+                    it = files.erase(it);
+                } else
+                    it++;
+            }
+            std::thread another_juci_app([directory, files_in_directory]() {
+                Terminal::get().async_print("Executing: juci " + directory.string() + files_in_directory + "\n");
+                Terminal::get().process("juci " + directory.string() + files_in_directory, "", false);
+            });
+            another_juci_app.detach();
         }
-        else
-          it++;
-      }
-      std::thread another_juci_app([directory, files_in_directory](){
-        Terminal::get().async_print("Executing: juci "+directory.string()+files_in_directory+"\n");
-        Terminal::get().process("juci "+directory.string()+files_in_directory, "", false);
-      });
-      another_juci_app.detach();
     }
-  }
-  
-  for(size_t i=0;i<files.size();++i) {
-    Notebook::get().open(files[i].first, files[i].second);
-    if(i<file_offsets.size()) {
-      if(auto view=Notebook::get().get_current_view()) {
-        view->place_cursor_at_line_offset(file_offsets[i].first, file_offsets[i].second);
-        view->hide_tooltips();
-      }
+
+    for (size_t i = 0; i < files.size(); ++i) {
+        Notebook::get().open(files[i].first, files[i].second);
+        if (i < file_offsets.size()) {
+            if (auto view = Notebook::get().get_current_view()) {
+                view->place_cursor_at_line_offset(file_offsets[i].first, file_offsets[i].second);
+                view->hide_tooltips();
+            }
+        }
     }
-  }
-  
-  for(auto &error: errors)
-    Terminal::get().print(error, true);
-  
-  if(!current_file.empty()) {
-    Notebook::get().open(current_file);
-    if(auto view=Notebook::get().get_current_view()) {
-      auto iter=view->get_buffer()->get_insert()->get_iter();
-      // To update cursor history
-      view->place_cursor_at_line_offset(iter.get_line(), iter.get_line_offset());
-      view->hide_tooltips();
+
+    for (auto &error: errors)
+        Terminal::get().print(error, true);
+
+    if (!current_file.empty()) {
+        Notebook::get().open(current_file);
+        if (auto view = Notebook::get().get_current_view()) {
+            auto iter = view->get_buffer()->get_insert()->get_iter();
+            // To update cursor history
+            view->place_cursor_at_line_offset(iter.get_line(), iter.get_line_offset());
+            view->hide_tooltips();
+        }
     }
-  }
-  
-  while(Gtk::Main::events_pending())
-    Gtk::Main::iteration(false);
-  for(auto view: Notebook::get().get_views())
-    view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+
+    while (Gtk::Main::events_pending())
+        Gtk::Main::iteration(false);
+    for (auto view: Notebook::get().get_views())
+        view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
 }
 
 void Application::on_startup() {
-  Gtk::Application::on_startup();
-  
-  Menu::get().build();
-
-  if (!Menu::get().juci_menu || !Menu::get().window_menu) {
-    std::cerr << "Menu not found." << std::endl;
-  }
-  else {
-    set_app_menu(Menu::get().juci_menu);
-    set_menubar(Menu::get().window_menu);
-  }
+    Gtk::Application::on_startup();
+
+    Menu::get().build();
+
+    if (!Menu::get().juci_menu || !Menu::get().window_menu) {
+        std::cerr << "Menu not found." << std::endl;
+    } else {
+        set_app_menu(Menu::get().juci_menu);
+        set_menubar(Menu::get().window_menu);
+    }
 }
 
-Application::Application() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) {
-  Glib::set_application_name("juCi++");
-  
-  //Gtk::MessageDialog without buttons caused text to be selected, this prevents that
-  Gtk::Settings::get_default()->property_gtk_label_select_on_focus()=false;
+Application::Application() : Gtk::Application("no.sout.juci",
+                                              Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) {
+    Glib::set_application_name("juCi++");
+
+    //Gtk::MessageDialog without buttons caused text to be selected, this prevents that
+    Gtk::Settings::get_default()->property_gtk_label_select_on_focus() = false;
 }
 
 int main(int argc, char *argv[]) {
 #ifndef _WIN32
-  signal(SIGPIPE, SIG_IGN); // Do not terminate application when writing to a process fails
+    signal(SIGPIPE, SIG_IGN); // Do not terminate application when writing to a process fails
 #endif
-  return Application().run(argc, argv);
+    return Application().run(argc, argv);
 }
diff --git a/src/juci.h b/src/juci.h
index 5a4a4bb0..0d267496 100644
--- a/src/juci.h
+++ b/src/juci.h
@@ -30,12 +30,16 @@
 
 class Application : public Gtk::Application {
 public:
-  Application();
-  int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) override;
-  void on_activate() override;
-  void on_startup() override;
+    Application();
+
+    int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) override;
+
+    void on_activate() override;
+
+    void on_startup() override;
+
 private:
-  std::vector<boost::filesystem::path> directories;
-  std::vector<std::pair<boost::filesystem::path, size_t>> files;
-  std::vector<std::string> errors;
+    std::vector<boost::filesystem::path> directories;
+    std::vector<std::pair<boost::filesystem::path, size_t>> files;
+    std::vector<std::string> errors;
 };
diff --git a/src/menu.cc b/src/menu.cc
index a79d156c..3a0e16dd 100644
--- a/src/menu.cc
+++ b/src/menu.cc
@@ -3,7 +3,7 @@
 #include <string>
 #include <iostream>
 
-const Glib::ustring menu_xml= R"RAW(<interface>
+const Glib::ustring menu_xml = R"RAW(<interface>
   <menu id='right-click-line-menu'>
     <section>
       <item>
@@ -478,39 +478,39 @@ const Glib::ustring menu_xml= R"RAW(<interface>
 )RAW";
 
 void Menu::add_action(const std::string &name, std::function<void()> action) {
-  auto g_application=g_application_get_default();
-  auto gio_application=Glib::wrap(g_application, true);
-  auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+    auto g_application = g_application_get_default();
+    auto gio_application = Glib::wrap(g_application, true);
+    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
 
-  actions[name]=application->add_action(name, action);
+    actions[name] = application->add_action(name, action);
 }
 
 void Menu::set_keys() {
-  auto g_application=g_application_get_default();
-  auto gio_application=Glib::wrap(g_application, true);
-  auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+    auto g_application = g_application_get_default();
+    auto gio_application = Glib::wrap(g_application, true);
+    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
 
-  for(auto &key: Config::get().menu.keys) {
-    if(key.second.size()>0 && actions.find(key.first)!=actions.end())
-      application->set_accel_for_action("app."+key.first, key.second);
-  }
+    for (auto &key: Config::get().menu.keys) {
+        if (key.second.size() > 0 && actions.find(key.first) != actions.end())
+            application->set_accel_for_action("app." + key.first, key.second);
+    }
 }
 
 void Menu::build() {
-  try {
-    builder = Gtk::Builder::create_from_string(menu_xml);
-    auto object = builder->get_object("juci-menu");
-    juci_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
-    object = builder->get_object("window-menu");
-    window_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
-    object = builder->get_object("right-click-line-menu");
-    auto ptr = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
-    right_click_line_menu = std::make_unique<Gtk::Menu>(ptr);
-    object = builder->get_object("right-click-selected-menu");
-    ptr = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
-    right_click_selected_menu = std::make_unique<Gtk::Menu>(ptr);
-  }
-  catch (const Glib::Error &ex) {
-    std::cerr << "building menu failed: " << ex.what();
-  }
+    try {
+        builder = Gtk::Builder::create_from_string(menu_xml);
+        auto object = builder->get_object("juci-menu");
+        juci_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
+        object = builder->get_object("window-menu");
+        window_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
+        object = builder->get_object("right-click-line-menu");
+        auto ptr = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
+        right_click_line_menu = std::make_unique<Gtk::Menu>(ptr);
+        object = builder->get_object("right-click-selected-menu");
+        ptr = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
+        right_click_selected_menu = std::make_unique<Gtk::Menu>(ptr);
+    }
+    catch (const Glib::Error &ex) {
+        std::cerr << "building menu failed: " << ex.what();
+    }
 }
diff --git a/src/menu.h b/src/menu.h
index 9d56d6ff..9951b373 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -1,28 +1,32 @@
 #pragma once
+
 #include <string>
 #include <unordered_map>
 #include <functional>
 #include <gtkmm.h>
 
 class Menu {
-  Menu() {}
+    Menu() {}
+
 public:
-  static Menu &get() {
-    static Menu singleton;
-    return singleton;
-  }
-  
-  void add_action(const std::string &name, std::function<void()> action);
-  std::unordered_map<std::string, Glib::RefPtr<Gio::SimpleAction> > actions;
-  void set_keys();
-  
-  void build();
-  
-  Glib::RefPtr<Gio::Menu> juci_menu;
-  Glib::RefPtr<Gio::Menu> window_menu;
-  std::unique_ptr<Gtk::Menu> right_click_line_menu;
-  std::unique_ptr<Gtk::Menu> right_click_selected_menu;
-  std::function<void()> toggle_menu_items = []{};
+    static Menu &get() {
+        static Menu singleton;
+        return singleton;
+    }
+
+    void add_action(const std::string &name, std::function<void()> action);
+
+    std::unordered_map<std::string, Glib::RefPtr<Gio::SimpleAction> > actions;
+
+    void set_keys();
+
+    void build();
+
+    Glib::RefPtr<Gio::Menu> juci_menu;
+    Glib::RefPtr<Gio::Menu> window_menu;
+    std::unique_ptr<Gtk::Menu> right_click_line_menu;
+    std::unique_ptr<Gtk::Menu> right_click_selected_menu;
+    std::function<void()> toggle_menu_items = [] {};
 private:
-  Glib::RefPtr<Gtk::Builder> builder;
+    Glib::RefPtr<Gtk::Builder> builder;
 };
diff --git a/src/meson.cc b/src/meson.cc
deleted file mode 100644
index 0960c925..00000000
--- a/src/meson.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-#include "meson.h"
-#include "filesystem.h"
-#include "compile_commands.h"
-#include <regex>
-#include "terminal.h"
-#include "dialogs.h"
-#include "config.h"
-
-Meson::Meson(const boost::filesystem::path &path) {
-  const auto find_project=[](const boost::filesystem::path &file_path) {
-    for(auto &line: filesystem::read_lines(file_path)) {
-      const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
-      std::smatch sm;
-      if(std::regex_match(line, sm, project_regex))
-        return true;
-    }
-    return false;
-  };
-  
-  auto search_path=boost::filesystem::is_directory(path)?path:path.parent_path();
-  while(true) {
-    auto search_file=search_path/"meson.build";
-    if(boost::filesystem::exists(search_file)) {
-      if(find_project(search_file)) {
-        project_path=search_path;
-        break;
-      }
-    }
-    if(search_path==search_path.root_directory())
-      break;
-    search_path=search_path.parent_path();
-  }
-}
-
-bool Meson::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
-  if(project_path.empty() || !boost::filesystem::exists(project_path/"meson.build") || default_build_path.empty())
-      return false;
-  
-  if(!boost::filesystem::exists(default_build_path)) {
-    boost::system::error_code ec;
-    boost::filesystem::create_directories(default_build_path, ec);
-    if(ec) {
-      Terminal::get().print("Error: could not create "+default_build_path.string()+": "+ec.message()+"\n", true);
-      return false;
-    }
-  }
-  
-  auto compile_commands_path=default_build_path/"compile_commands.json";
-  bool compile_commands_exists=boost::filesystem::exists(compile_commands_path);
-  if(!force && compile_commands_exists)
-    return true;
-  
-  Dialog::Message message("Creating/updating default build");
-  auto exit_status=Terminal::get().process(Config::get().project.meson.command+' '+(compile_commands_exists?"--internal regenerate ":"")+
-                                           filesystem::escape_argument(project_path.string()), default_build_path);
-  message.hide();
-  if(exit_status==EXIT_SUCCESS)
-    return true;
-  return false;
-}
-
-bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-  if(project_path.empty() || !boost::filesystem::exists(project_path/"meson.build") || debug_build_path.empty())
-    return false;
-  
-  if(!boost::filesystem::exists(debug_build_path)) {
-    boost::system::error_code ec;
-    boost::filesystem::create_directories(debug_build_path, ec);
-    if(ec) {
-      Terminal::get().print("Error: could not create "+debug_build_path.string()+": "+ec.message()+"\n", true);
-      return false;
-    }
-  }
-  
-  bool compile_commands_exists=boost::filesystem::exists(debug_build_path/"compile_commands.json");
-  if(!force && compile_commands_exists)
-    return true;
-  
-  Dialog::Message message("Creating/updating debug build");
-  auto exit_status=Terminal::get().process(Config::get().project.meson.command+' '+(compile_commands_exists?"--internal regenerate ":"")+
-                                           "--buildtype debug "+filesystem::escape_argument(project_path.string()), debug_build_path);
-  message.hide();
-  if(exit_status==EXIT_SUCCESS)
-    return true;
-  return false;
-}
-
-boost::filesystem::path Meson::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
-  CompileCommands compile_commands(build_path);
-  
-  size_t best_match_size=-1;
-  boost::filesystem::path best_match_executable;
-  for(auto &command: compile_commands.commands) {
-    auto command_file=filesystem::get_normal_path(command.file);
-    auto values=command.parameter_values("-o");
-    if(!values.empty()) {
-      size_t pos;
-      if((pos=values[0].find("@"))!=std::string::npos) {
-        if(pos+1<values[0].size() && values[0].compare(pos+1, 3, "exe")==0) {
-          auto executable=build_path/values[0].substr(0, pos);
-          if(command_file==file_path)
-            return executable;
-          auto command_file_directory=command_file.parent_path();
-          if(filesystem::file_in_path(file_path, command_file_directory)) {
-            auto size=static_cast<size_t>(std::distance(command_file_directory.begin(), command_file_directory.end()));
-            if(best_match_size==static_cast<size_t>(-1) || best_match_size<size) {
-              best_match_size=size;
-              best_match_executable=executable;
-            }
-          }
-        }
-      }
-    }
-  }
-  
-  return best_match_executable;
-}
diff --git a/src/meson.h b/src/meson.h
deleted file mode 100644
index 264afb18..00000000
--- a/src/meson.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-#include <boost/filesystem.hpp>
-#include <vector>
-
-class Meson {
-public:
-  Meson(const boost::filesystem::path &path);
-  
-  boost::filesystem::path project_path;
-  
-  bool update_default_build(const boost::filesystem::path &default_build_path, bool force=false);
-  bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force=false);
-  
-  boost::filesystem::path get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
-};
diff --git a/src/notebook.cc b/src/notebook.cc
index b2327b11..a177968a 100644
--- a/src/notebook.cc
+++ b/src/notebook.cc
@@ -11,664 +11,673 @@
 #include "gtksourceview-3.0/gtksourceview/gtksourcemap.h"
 
 Notebook::TabLabel::TabLabel(std::function<void()> on_close) {
-  set_can_focus(false);
-  
-  auto button=Gtk::manage(new Gtk::Button());
-  auto hbox=Gtk::manage(new Gtk::Box());
-  
-  hbox->set_can_focus(false);
-  label.set_can_focus(false);
-  button->set_image_from_icon_name("window-close-symbolic", Gtk::ICON_SIZE_MENU);
-  button->set_can_focus(false);
-  button->set_relief(Gtk::ReliefStyle::RELIEF_NONE);
-  
-  hbox->pack_start(label, Gtk::PACK_SHRINK);
-  hbox->pack_end(*button, Gtk::PACK_SHRINK);
-  add(*hbox);
-  
-  button->signal_clicked().connect(on_close);
-  signal_button_press_event().connect([on_close](GdkEventButton *event) {
-    if(event->button==GDK_BUTTON_MIDDLE) {
-      on_close();
-      return true;
-    }
-    return false;
-  });
-  
-  show_all();
-}
+    set_can_focus(false);
 
-Notebook::Notebook() : Gtk::Paned(), notebooks(2) {
-  for(auto &notebook: notebooks) {
-    notebook.get_style_context()->add_class("juci_notebook");
-    notebook.set_scrollable();
-    notebook.set_group_name("source_notebooks");
-    notebook.signal_switch_page().connect([this](Gtk::Widget *widget, guint) {
-      auto hbox=dynamic_cast<Gtk::Box*>(widget);
-      for(size_t c=0;c<hboxes.size();++c) {
-        if(hboxes[c].get()==hbox) {
-          focus_view(source_views[c]);
-          set_current_view(source_views[c]);
-          break;
-        }
-      }
-      last_index=-1;
-    });
-    notebook.signal_page_added().connect([this](Gtk::Widget* widget, guint) {
-      auto hbox=dynamic_cast<Gtk::Box*>(widget);
-      for(size_t c=0;c<hboxes.size();++c) {
-        if(hboxes[c].get()==hbox) {
-          focus_view(source_views[c]);
-          set_current_view(source_views[c]);
-          break;
+    auto button = Gtk::manage(new Gtk::Button());
+    auto hbox = Gtk::manage(new Gtk::Box());
+
+    hbox->set_can_focus(false);
+    label.set_can_focus(false);
+    button->set_image_from_icon_name("window-close-symbolic", Gtk::ICON_SIZE_MENU);
+    button->set_can_focus(false);
+    button->set_relief(Gtk::ReliefStyle::RELIEF_NONE);
+
+    hbox->pack_start(label, Gtk::PACK_SHRINK);
+    hbox->pack_end(*button, Gtk::PACK_SHRINK);
+    add(*hbox);
+
+    button->signal_clicked().connect(on_close);
+    signal_button_press_event().connect([on_close](GdkEventButton *event) {
+        if (event->button == GDK_BUTTON_MIDDLE) {
+            on_close();
+            return true;
         }
-      }
+        return false;
     });
-  }
-  pack1(notebooks[0], true, true);
+
+    show_all();
+}
+
+Notebook::Notebook() : Gtk::Paned(), notebooks(2) {
+    for (auto &notebook: notebooks) {
+        notebook.get_style_context()->add_class("juci_notebook");
+        notebook.set_scrollable();
+        notebook.set_group_name("source_notebooks");
+        notebook.signal_switch_page().connect([this](Gtk::Widget *widget, guint) {
+            auto hbox = dynamic_cast<Gtk::Box *>(widget);
+            for (size_t c = 0; c < hboxes.size(); ++c) {
+                if (hboxes[c].get() == hbox) {
+                    focus_view(source_views[c]);
+                    set_current_view(source_views[c]);
+                    break;
+                }
+            }
+            last_index = -1;
+        });
+        notebook.signal_page_added().connect([this](Gtk::Widget *widget, guint) {
+            auto hbox = dynamic_cast<Gtk::Box *>(widget);
+            for (size_t c = 0; c < hboxes.size(); ++c) {
+                if (hboxes[c].get() == hbox) {
+                    focus_view(source_views[c]);
+                    set_current_view(source_views[c]);
+                    break;
+                }
+            }
+        });
+    }
+    pack1(notebooks[0], true, true);
 }
 
 size_t Notebook::size() {
-  return source_views.size();
+    return source_views.size();
 }
 
-Source::View* Notebook::get_view(size_t index) {
-  if(index>=size())
-    return nullptr;
-  return source_views[index];
+Source::View *Notebook::get_view(size_t index) {
+    if (index >= size())
+        return nullptr;
+    return source_views[index];
 }
 
-Source::View* Notebook::get_current_view() {
-  if(intermediate_view) {
-    for(auto view: source_views) {
-      if(view==intermediate_view)
-        return view;
+Source::View *Notebook::get_current_view() {
+    if (intermediate_view) {
+        for (auto view: source_views) {
+            if (view == intermediate_view)
+                return view;
+        }
+    }
+    for (auto view: source_views) {
+        if (view == current_view)
+            return view;
     }
-  }
-  for(auto view: source_views) {
-    if(view==current_view)
-      return view;
-  }
-  //In case there exist a tab that has not yet received focus again in a different notebook
-  for(int notebook_index=0;notebook_index<2;++notebook_index) {
-    auto page=notebooks[notebook_index].get_current_page();
-    if(page>=0)
-      return get_view(notebook_index, page);
-  }
-  return nullptr;
+    //In case there exist a tab that has not yet received focus again in a different notebook
+    for (int notebook_index = 0; notebook_index < 2; ++notebook_index) {
+        auto page = notebooks[notebook_index].get_current_page();
+        if (page >= 0)
+            return get_view(notebook_index, page);
+    }
+    return nullptr;
 }
 
-std::vector<Source::View*> &Notebook::get_views() {
-  return source_views;
+std::vector<Source::View *> &Notebook::get_views() {
+    return source_views;
 }
 
 void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_index) {
-  auto file_path=filesystem::get_normal_path(file_path_);
-  
-  if(notebook_index==1 && !split)
-    toggle_split();
-  
-  // Use canonical path to follow symbolic links
-  boost::system::error_code ec;
-  auto canonical_file_path=boost::filesystem::canonical(file_path, ec);
-  if(ec)
-    canonical_file_path=file_path;
-  for(size_t c=0;c<size();c++) {
-    if(canonical_file_path==source_views[c]->canonical_file_path) {
-      auto notebook_page=get_notebook_page(c);
-      notebooks[notebook_page.first].set_current_page(notebook_page.second);
-      focus_view(source_views[c]);
-      return;
-    }
-  }
-  
-  if(boost::filesystem::exists(file_path)) {
-    std::ifstream can_read(file_path.string());
-    if(!can_read) {
-      Terminal::get().print("Error: could not open "+file_path.string()+"\n", true);
-      return;
-    }
-    can_read.close();
-  }
-  
-  auto last_view=get_current_view();
-  
-  auto language=Source::guess_language(file_path);
-  
-  std::string language_protocol_language_id;
-  if(language) {
-    language_protocol_language_id=language->get_id();
-    if(language_protocol_language_id=="js") {
-      if(file_path.extension()==".ts")
-        language_protocol_language_id="typescript";
-      else
-        language_protocol_language_id="javascript";
-    }
-  }
-  
-  if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc"))
-    source_views.emplace_back(new Source::ClangView(file_path, language));
-  else if(language && !language_protocol_language_id.empty() && !filesystem::find_executable(language_protocol_language_id+"-language-server").empty())
-    source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id));
-  else
-    source_views.emplace_back(new Source::GenericView(file_path, language));
-  
-  auto source_view=source_views.back();
-  
-  source_view->scroll_to_cursor_delayed=[this](Source::BaseView* view, bool center, bool show_tooltips) {
-    while(Gtk::Main::events_pending())
-      Gtk::Main::iteration(false);
-    if(get_current_view()==view) {
-      if(center)
-        view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-      else
-        view->scroll_to(view->get_buffer()->get_insert());
-      if(!show_tooltips)
-        view->hide_tooltips();
+    auto file_path = filesystem::get_normal_path(file_path_);
+
+    if (notebook_index == 1 && !split)
+        toggle_split();
+
+    // Use canonical path to follow symbolic links
+    boost::system::error_code ec;
+    auto canonical_file_path = boost::filesystem::canonical(file_path, ec);
+    if (ec)
+        canonical_file_path = file_path;
+    for (size_t c = 0; c < size(); c++) {
+        if (canonical_file_path == source_views[c]->canonical_file_path) {
+            auto notebook_page = get_notebook_page(c);
+            notebooks[notebook_page.first].set_current_page(notebook_page.second);
+            focus_view(source_views[c]);
+            return;
+        }
     }
-  };
-  source_view->update_status_location=[this](Source::BaseView* view) {
-    if(get_current_view()==view) {
-      auto iter=view->get_buffer()->get_insert()->get_iter();
-      status_location.set_text(" "+std::to_string(iter.get_line()+1)+":"+std::to_string(iter.get_line_offset()+1));
+
+    if (boost::filesystem::exists(file_path)) {
+        std::ifstream can_read(file_path.string());
+        if (!can_read) {
+            Terminal::get().print("Error: could not open " + file_path.string() + "\n", true);
+            return;
+        }
+        can_read.close();
     }
-  };
-  source_view->update_status_file_path=[this](Source::BaseView* view) {
-    if(get_current_view()==view)
-      status_file_path.set_text(' '+filesystem::get_short_path(view->file_path).string());
-  };
-  source_view->update_status_branch=[this](Source::BaseView* view) {
-    if(get_current_view()==view) {
-      if(!view->status_branch.empty())
-        status_branch.set_text(" ("+view->status_branch+")");
-      else
-        status_branch.set_text("");
+
+    auto last_view = get_current_view();
+
+    auto language = Source::guess_language(file_path);
+
+    std::string language_protocol_language_id;
+    if (language) {
+        language_protocol_language_id = language->get_id();
+        if (language_protocol_language_id == "js") {
+            if (file_path.extension() == ".ts")
+                language_protocol_language_id = "typescript";
+            else
+                language_protocol_language_id = "javascript";
+        }
     }
-  };
-  source_view->update_status_diagnostics=[this](Source::BaseView* view) {
-    if(get_current_view()==view) {
-      std::string diagnostic_info;
-      
-      auto num_warnings=std::get<0>(view->status_diagnostics);
-      auto num_errors=std::get<1>(view->status_diagnostics);
-      auto num_fix_its=std::get<2>(view->status_diagnostics);
-      if(num_warnings>0 || num_errors>0 || num_fix_its>0) {
-        auto normal_color=get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
-        Gdk::RGBA yellow;
-        yellow.set_rgba(1.0, 1.0, 0.2);
-        double factor=0.5;
-        yellow.set_red(normal_color.get_red()+factor*(yellow.get_red()-normal_color.get_red()));
-        yellow.set_green(normal_color.get_green()+factor*(yellow.get_green()-normal_color.get_green()));
-        yellow.set_blue(normal_color.get_blue()+factor*(yellow.get_blue()-normal_color.get_blue()));
-        Gdk::RGBA red;
-        red.set_rgba(1.0, 0.0, 0.0);
-        factor=0.5;
-        red.set_red(normal_color.get_red()+factor*(red.get_red()-normal_color.get_red()));
-        red.set_green(normal_color.get_green()+factor*(red.get_green()-normal_color.get_green()));
-        red.set_blue(normal_color.get_blue()+factor*(red.get_blue()-normal_color.get_blue()));
-        Gdk::RGBA green;
-        green.set_rgba(0.0, 1.0, 0.0);
-        factor=0.4;
-        green.set_red(normal_color.get_red()+factor*(green.get_red()-normal_color.get_red()));
-        green.set_green(normal_color.get_green()+factor*(green.get_green()-normal_color.get_green()));
-        green.set_blue(normal_color.get_blue()+factor*(green.get_blue()-normal_color.get_blue()));
-        
-        std::stringstream yellow_ss, red_ss, green_ss;
-        yellow_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(yellow.get_red_u()>>8) << std::setw(2) << (int)(yellow.get_green_u()>>8) << std::setw(2) << (int)(yellow.get_blue_u()>>8);
-        red_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(red.get_red_u()>>8) << std::setw(2) << (int)(red.get_green_u()>>8) << std::setw(2) << (int)(red.get_blue_u()>>8);
-        green_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(green.get_red_u()>>8) << std::setw(2) << (int)(green.get_green_u()>>8) << std::setw(2) << (int)(green.get_blue_u()>>8);
-        if(num_warnings>0) {
-          diagnostic_info+="<span color='#"+yellow_ss.str()+"'>";
-          diagnostic_info+=std::to_string(num_warnings)+" warning";
-          if(num_warnings>1)
-            diagnostic_info+='s';
-          diagnostic_info+="</span>";
+
+    if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr" || language->get_id() == "c" ||
+                     language->get_id() == "cpp" || language->get_id() == "objc"))
+        source_views.emplace_back(new Source::ClangView(file_path, language));
+    else if (language && !language_protocol_language_id.empty() &&
+             !filesystem::find_executable(language_protocol_language_id + "-language-server").empty())
+        source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id));
+    else
+        source_views.emplace_back(new Source::GenericView(file_path, language));
+
+    auto source_view = source_views.back();
+
+    source_view->scroll_to_cursor_delayed = [this](Source::BaseView *view, bool center, bool show_tooltips) {
+        while (Gtk::Main::events_pending())
+            Gtk::Main::iteration(false);
+        if (get_current_view() == view) {
+            if (center)
+                view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+            else
+                view->scroll_to(view->get_buffer()->get_insert());
+            if (!show_tooltips)
+                view->hide_tooltips();
         }
-        if(num_errors>0) {
-          if(num_warnings>0)
-            diagnostic_info+=", ";
-          diagnostic_info+="<span color='#"+red_ss.str()+"'>";
-          diagnostic_info+=std::to_string(num_errors)+" error";
-          if(num_errors>1)
-            diagnostic_info+='s';
-          diagnostic_info+="</span>";
+    };
+    source_view->update_status_location = [this](Source::BaseView *view) {
+        if (get_current_view() == view) {
+            auto iter = view->get_buffer()->get_insert()->get_iter();
+            status_location.set_text(
+                    " " + std::to_string(iter.get_line() + 1) + ":" + std::to_string(iter.get_line_offset() + 1));
         }
-        if(num_fix_its>0) {
-          if(num_warnings>0 || num_errors>0)
-            diagnostic_info+=", ";
-          diagnostic_info+="<span color='#"+green_ss.str()+"'>";
-          diagnostic_info+=std::to_string(num_fix_its)+" fix it";
-          if(num_fix_its>1)
-            diagnostic_info+='s';
-          diagnostic_info+="</span>";
+    };
+    source_view->update_status_file_path = [this](Source::BaseView *view) {
+        if (get_current_view() == view)
+            status_file_path.set_text(' ' + filesystem::get_short_path(view->file_path).string());
+    };
+    source_view->update_status_branch = [this](Source::BaseView *view) {
+        if (get_current_view() == view) {
+            if (!view->status_branch.empty())
+                status_branch.set_text(" (" + view->status_branch + ")");
+            else
+                status_branch.set_text("");
         }
-      }
-      status_diagnostics.set_markup(diagnostic_info);
-    }
-  };
-  source_view->update_status_state=[this](Source::BaseView* view) {
-    if(get_current_view()==view)
-      status_state.set_text(view->status_state+" ");
-  };
-  
-  scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
-  hboxes.emplace_back(new Gtk::Box());
-  scrolled_windows.back()->add(*source_view);
-  hboxes.back()->pack_start(*scrolled_windows.back());
-
-  source_maps.emplace_back(Glib::wrap(gtk_source_map_new()));
-  gtk_source_map_set_view(GTK_SOURCE_MAP(source_maps.back()->gobj()), source_view->gobj());
-
-  configure(source_views.size()-1);
-  
-  //Set up tab label
-  tab_labels.emplace_back(new TabLabel([this, source_view]() {
-    auto index=get_index(source_view);
-    if(index!=static_cast<size_t>(-1))
-      close(index);
-  }));
-  source_view->update_tab_label=[this](Source::BaseView *view) {
-    std::string title=view->file_path.filename().string();
-    if(view->get_buffer()->get_modified())
-      title+='*';
-    else
-      title+=' ';
-    for(size_t c=0;c<size();++c) {
-      if(source_views[c]==view) {
-        auto &tab_label=tab_labels.at(c);
-        tab_label->label.set_text(title);
-        tab_label->set_tooltip_text(filesystem::get_short_path(view->file_path).string());
-        return;
-      }
-    }
-  };
-  source_view->update_tab_label(source_view);
-  
-  //Add star on tab label when the page is not saved:
-  source_view->get_buffer()->signal_modified_changed().connect([source_view]() {
-    if(source_view->update_tab_label)
-      source_view->update_tab_label(source_view);
-  });
-  
-  //Cursor history
-  auto update_cursor_locations=[this, source_view](const Gtk::TextBuffer::iterator &iter) {
-    bool mark_moved=false;
-    if(current_cursor_location!=static_cast<size_t>(-1)) {
-      auto &cursor_location=cursor_locations.at(current_cursor_location);
-      if(cursor_location.view==source_view && abs(cursor_location.mark->get_iter().get_line()-iter.get_line())<=2) {
-        source_view->get_buffer()->move_mark(cursor_location.mark, iter);
-        mark_moved=true;
-      }
-    }
-    if(!mark_moved) {
-      if(current_cursor_location!=static_cast<size_t>(-1)) {
-        for(auto it=cursor_locations.begin()+current_cursor_location+1;it!=cursor_locations.end();) {
-          it->view->get_buffer()->delete_mark(it->mark);
-          it=cursor_locations.erase(it);
+    };
+    source_view->update_status_diagnostics = [this](Source::BaseView *view) {
+        if (get_current_view() == view) {
+            std::string diagnostic_info;
+
+            auto num_warnings = std::get<0>(view->status_diagnostics);
+            auto num_errors = std::get<1>(view->status_diagnostics);
+            auto num_fix_its = std::get<2>(view->status_diagnostics);
+            if (num_warnings > 0 || num_errors > 0 || num_fix_its > 0) {
+                auto normal_color = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
+                Gdk::RGBA yellow;
+                yellow.set_rgba(1.0, 1.0, 0.2);
+                double factor = 0.5;
+                yellow.set_red(normal_color.get_red() + factor * (yellow.get_red() - normal_color.get_red()));
+                yellow.set_green(normal_color.get_green() + factor * (yellow.get_green() - normal_color.get_green()));
+                yellow.set_blue(normal_color.get_blue() + factor * (yellow.get_blue() - normal_color.get_blue()));
+                Gdk::RGBA red;
+                red.set_rgba(1.0, 0.0, 0.0);
+                factor = 0.5;
+                red.set_red(normal_color.get_red() + factor * (red.get_red() - normal_color.get_red()));
+                red.set_green(normal_color.get_green() + factor * (red.get_green() - normal_color.get_green()));
+                red.set_blue(normal_color.get_blue() + factor * (red.get_blue() - normal_color.get_blue()));
+                Gdk::RGBA green;
+                green.set_rgba(0.0, 1.0, 0.0);
+                factor = 0.4;
+                green.set_red(normal_color.get_red() + factor * (green.get_red() - normal_color.get_red()));
+                green.set_green(normal_color.get_green() + factor * (green.get_green() - normal_color.get_green()));
+                green.set_blue(normal_color.get_blue() + factor * (green.get_blue() - normal_color.get_blue()));
+
+                std::stringstream yellow_ss, red_ss, green_ss;
+                yellow_ss << std::hex << std::setfill('0') << std::setw(2) << (int) (yellow.get_red_u() >> 8)
+                          << std::setw(2) << (int) (yellow.get_green_u() >> 8) << std::setw(2)
+                          << (int) (yellow.get_blue_u() >> 8);
+                red_ss << std::hex << std::setfill('0') << std::setw(2) << (int) (red.get_red_u() >> 8) << std::setw(2)
+                       << (int) (red.get_green_u() >> 8) << std::setw(2) << (int) (red.get_blue_u() >> 8);
+                green_ss << std::hex << std::setfill('0') << std::setw(2) << (int) (green.get_red_u() >> 8)
+                         << std::setw(2) << (int) (green.get_green_u() >> 8) << std::setw(2)
+                         << (int) (green.get_blue_u() >> 8);
+                if (num_warnings > 0) {
+                    diagnostic_info += "<span color='#" + yellow_ss.str() + "'>";
+                    diagnostic_info += std::to_string(num_warnings) + " warning";
+                    if (num_warnings > 1)
+                        diagnostic_info += 's';
+                    diagnostic_info += "</span>";
+                }
+                if (num_errors > 0) {
+                    if (num_warnings > 0)
+                        diagnostic_info += ", ";
+                    diagnostic_info += "<span color='#" + red_ss.str() + "'>";
+                    diagnostic_info += std::to_string(num_errors) + " error";
+                    if (num_errors > 1)
+                        diagnostic_info += 's';
+                    diagnostic_info += "</span>";
+                }
+                if (num_fix_its > 0) {
+                    if (num_warnings > 0 || num_errors > 0)
+                        diagnostic_info += ", ";
+                    diagnostic_info += "<span color='#" + green_ss.str() + "'>";
+                    diagnostic_info += std::to_string(num_fix_its) + " fix it";
+                    if (num_fix_its > 1)
+                        diagnostic_info += 's';
+                    diagnostic_info += "</span>";
+                }
+            }
+            status_diagnostics.set_markup(diagnostic_info);
         }
-      }
-      cursor_locations.emplace_back(source_view, source_view->get_buffer()->create_mark(iter));
-      current_cursor_location=cursor_locations.size()-1;
-    }
-    
-    // Combine adjacent cursor histories that are similar
-    if(!cursor_locations.empty()) {
-      size_t cursor_locations_index=1;
-      auto last_it=cursor_locations.begin();
-      for(auto it=cursor_locations.begin()+1;it!=cursor_locations.end();) {
-        if(last_it->view==it->view && abs(last_it->mark->get_iter().get_line()-it->mark->get_iter().get_line())<=2) {
-          last_it->view->get_buffer()->delete_mark(last_it->mark);
-          last_it->mark=it->mark;
-          it=cursor_locations.erase(it);
-          if(current_cursor_location!=static_cast<size_t>(-1) && current_cursor_location>cursor_locations_index)
-            --current_cursor_location;
+    };
+    source_view->update_status_state = [this](Source::BaseView *view) {
+        if (get_current_view() == view)
+            status_state.set_text(view->status_state + " ");
+    };
+
+    scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
+    hboxes.emplace_back(new Gtk::Box());
+    scrolled_windows.back()->add(*source_view);
+    hboxes.back()->pack_start(*scrolled_windows.back());
+
+    source_maps.emplace_back(Glib::wrap(gtk_source_map_new()));
+    gtk_source_map_set_view(GTK_SOURCE_MAP(source_maps.back()->gobj()), source_view->gobj());
+
+    configure(source_views.size() - 1);
+
+    //Set up tab label
+    tab_labels.emplace_back(new TabLabel([this, source_view]() {
+        auto index = get_index(source_view);
+        if (index != static_cast<size_t>(-1))
+            close(index);
+    }));
+    source_view->update_tab_label = [this](Source::BaseView *view) {
+        std::string title = view->file_path.filename().string();
+        if (view->get_buffer()->get_modified())
+            title += '*';
+        else
+            title += ' ';
+        for (size_t c = 0; c < size(); ++c) {
+            if (source_views[c] == view) {
+                auto &tab_label = tab_labels.at(c);
+                tab_label->label.set_text(title);
+                tab_label->set_tooltip_text(filesystem::get_short_path(view->file_path).string());
+                return;
+            }
+        }
+    };
+    source_view->update_tab_label(source_view);
+
+    //Add star on tab label when the page is not saved:
+    source_view->get_buffer()->signal_modified_changed().connect([source_view]() {
+        if (source_view->update_tab_label)
+            source_view->update_tab_label(source_view);
+    });
+
+    //Cursor history
+    auto update_cursor_locations = [this, source_view](const Gtk::TextBuffer::iterator &iter) {
+        bool mark_moved = false;
+        if (current_cursor_location != static_cast<size_t>(-1)) {
+            auto &cursor_location = cursor_locations.at(current_cursor_location);
+            if (cursor_location.view == source_view &&
+                abs(cursor_location.mark->get_iter().get_line() - iter.get_line()) <= 2) {
+                source_view->get_buffer()->move_mark(cursor_location.mark, iter);
+                mark_moved = true;
+            }
+        }
+        if (!mark_moved) {
+            if (current_cursor_location != static_cast<size_t>(-1)) {
+                for (auto it = cursor_locations.begin() + current_cursor_location + 1; it != cursor_locations.end();) {
+                    it->view->get_buffer()->delete_mark(it->mark);
+                    it = cursor_locations.erase(it);
+                }
+            }
+            cursor_locations.emplace_back(source_view, source_view->get_buffer()->create_mark(iter));
+            current_cursor_location = cursor_locations.size() - 1;
+        }
+
+        // Combine adjacent cursor histories that are similar
+        if (!cursor_locations.empty()) {
+            size_t cursor_locations_index = 1;
+            auto last_it = cursor_locations.begin();
+            for (auto it = cursor_locations.begin() + 1; it != cursor_locations.end();) {
+                if (last_it->view == it->view &&
+                    abs(last_it->mark->get_iter().get_line() - it->mark->get_iter().get_line()) <= 2) {
+                    last_it->view->get_buffer()->delete_mark(last_it->mark);
+                    last_it->mark = it->mark;
+                    it = cursor_locations.erase(it);
+                    if (current_cursor_location != static_cast<size_t>(-1) &&
+                        current_cursor_location > cursor_locations_index)
+                        --current_cursor_location;
+                } else {
+                    ++it;
+                    ++last_it;
+                    ++cursor_locations_index;
+                }
+            }
+        }
+
+        // Remove start of cache if cache limit is exceeded
+        while (cursor_locations.size() > 10) {
+            cursor_locations.begin()->view->get_buffer()->delete_mark(cursor_locations.begin()->mark);
+            cursor_locations.erase(cursor_locations.begin());
+            if (current_cursor_location != static_cast<size_t>(-1))
+                --current_cursor_location;
+        }
+
+        if (current_cursor_location >= cursor_locations.size())
+            current_cursor_location = cursor_locations.size() - 1;
+    };
+    source_view->get_buffer()->signal_mark_set().connect(
+            [this, update_cursor_locations](const Gtk::TextBuffer::iterator &iter,
+                                            const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+                if (mark->get_name() == "insert") {
+                    if (disable_next_update_cursor_locations) {
+                        disable_next_update_cursor_locations = false;
+                        return;
+                    }
+                    update_cursor_locations(iter);
+                }
+            });
+    source_view->get_buffer()->signal_changed().connect([source_view, update_cursor_locations] {
+        update_cursor_locations(source_view->get_buffer()->get_insert()->get_iter());
+    });
+
+#ifdef JUCI_ENABLE_DEBUG
+    if(dynamic_cast<Source::ClangView*>(source_view) || (source_view->language && source_view->language->get_id()=="rust")) {
+      source_view->toggle_breakpoint=[source_view](int line_nr) {
+        if(source_view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_breakpoint").size()>0) {
+          auto start_iter=source_view->get_buffer()->get_iter_at_line(line_nr);
+          auto end_iter=source_view->get_iter_at_line_end(line_nr);
+          source_view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint");
+          source_view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint_and_stop");
+          if(Project::current && Project::debugging)
+            Project::current->debug_remove_breakpoint(source_view->file_path, line_nr+1, source_view->get_buffer()->get_line_count()+1);
         }
         else {
-          ++it;
-          ++last_it;
-          ++cursor_locations_index;
+          auto iter=source_view->get_buffer()->get_iter_at_line(line_nr);
+          source_view->get_source_buffer()->create_source_mark("debug_breakpoint", iter);
+          if(source_view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_stop").size()>0)
+            source_view->get_source_buffer()->create_source_mark("debug_breakpoint_and_stop", iter);
+          if(Project::current && Project::debugging)
+            Project::current->debug_add_breakpoint(source_view->file_path, line_nr+1);
         }
-      }
+      };
     }
-    
-    // Remove start of cache if cache limit is exceeded
-    while(cursor_locations.size()>10) {
-      cursor_locations.begin()->view->get_buffer()->delete_mark(cursor_locations.begin()->mark);
-      cursor_locations.erase(cursor_locations.begin());
-      if(current_cursor_location!=static_cast<size_t>(-1))
-        --current_cursor_location;
+#endif
+
+    source_view->signal_focus_in_event().connect([this, source_view](GdkEventFocus *) {
+        set_current_view(source_view);
+        return false;
+    });
+
+    if (notebook_index == static_cast<size_t>(-1)) {
+        if (!split)
+            notebook_index = 0;
+        else if (notebooks[0].get_n_pages() == 0)
+            notebook_index = 0;
+        else if (notebooks[1].get_n_pages() == 0)
+            notebook_index = 1;
+        else if (last_view)
+            notebook_index = get_notebook_page(get_index(last_view)).first;
     }
-    
-    if(current_cursor_location>=cursor_locations.size())
-      current_cursor_location=cursor_locations.size()-1;
-  };
-  source_view->get_buffer()->signal_mark_set().connect([this, update_cursor_locations](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-    if(mark->get_name()=="insert") {
-      if(disable_next_update_cursor_locations) {
-        disable_next_update_cursor_locations=false;
-        return;
-      }
-      update_cursor_locations(iter);
+    auto &notebook = notebooks[notebook_index];
+
+    notebook.append_page(*hboxes.back(), *tab_labels.back());
+
+    notebook.set_tab_reorderable(*hboxes.back(), true);
+    notebook.set_tab_detachable(*hboxes.back(), true);
+    show_all_children();
+
+    notebook.set_current_page(notebook.get_n_pages() - 1);
+    last_index = -1;
+    if (last_view) {
+        auto index = get_index(last_view);
+        auto notebook_page = get_notebook_page(index);
+        if (notebook_page.first == notebook_index)
+            last_index = index;
     }
-  });
-  source_view->get_buffer()->signal_changed().connect([source_view, update_cursor_locations] {
-    update_cursor_locations(source_view->get_buffer()->get_insert()->get_iter());
-  });
-  
-#ifdef JUCI_ENABLE_DEBUG
-  if(dynamic_cast<Source::ClangView*>(source_view) || (source_view->language && source_view->language->get_id()=="rust")) {
-    source_view->toggle_breakpoint=[source_view](int line_nr) {
-      if(source_view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_breakpoint").size()>0) {
-        auto start_iter=source_view->get_buffer()->get_iter_at_line(line_nr);
-        auto end_iter=source_view->get_iter_at_line_end(line_nr);
-        source_view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint");
-        source_view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint_and_stop");
-        if(Project::current && Project::debugging)
-          Project::current->debug_remove_breakpoint(source_view->file_path, line_nr+1, source_view->get_buffer()->get_line_count()+1);
-      }
-      else {
-        auto iter=source_view->get_buffer()->get_iter_at_line(line_nr);
-        source_view->get_source_buffer()->create_source_mark("debug_breakpoint", iter);
-        if(source_view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_stop").size()>0)
-          source_view->get_source_buffer()->create_source_mark("debug_breakpoint_and_stop", iter);
-        if(Project::current && Project::debugging)
-          Project::current->debug_add_breakpoint(source_view->file_path, line_nr+1);
-      }
-    };
-  }
-#endif
-  
-  source_view->signal_focus_in_event().connect([this, source_view](GdkEventFocus *) {
-    set_current_view(source_view);
-    return false;
-  });
-  
-  if(notebook_index==static_cast<size_t>(-1)) {
-    if(!split)
-      notebook_index=0;
-    else if(notebooks[0].get_n_pages()==0)
-      notebook_index=0;
-    else if(notebooks[1].get_n_pages()==0)
-      notebook_index=1;
-    else if(last_view)
-      notebook_index=get_notebook_page(get_index(last_view)).first;
-  }
-  auto &notebook=notebooks[notebook_index];
-  
-  notebook.append_page(*hboxes.back(), *tab_labels.back());
-  
-  notebook.set_tab_reorderable(*hboxes.back(), true);
-  notebook.set_tab_detachable(*hboxes.back(), true);
-  show_all_children();
-  
-  notebook.set_current_page(notebook.get_n_pages()-1);
-  last_index=-1;
-  if(last_view) {
-    auto index=get_index(last_view);
-    auto notebook_page=get_notebook_page(index);
-    if(notebook_page.first==notebook_index)
-      last_index=index;
-  }
-  
-  set_focus_child(*source_views.back());
-  focus_view(source_view);
+
+    set_focus_child(*source_views.back());
+    focus_view(source_view);
 }
 
 void Notebook::configure(size_t index) {
-  auto source_font_description=Pango::FontDescription(Config::get().source.font);
-  auto source_map_font_desc=Pango::FontDescription(static_cast<std::string>(source_font_description.get_family())+" "+Config::get().source.map_font_size); 
-  source_maps.at(index)->override_font(source_map_font_desc);
-  if(Config::get().source.show_map) {
-    if(hboxes.at(index)->get_children().size()==1)
-      hboxes.at(index)->pack_end(*source_maps.at(index), Gtk::PACK_SHRINK);
-  }
-  else if(hboxes.at(index)->get_children().size()==2)
-    hboxes.at(index)->remove(*source_maps.at(index));
+    auto source_font_description = Pango::FontDescription(Config::get().source.font);
+    auto source_map_font_desc = Pango::FontDescription(
+            static_cast<std::string>(source_font_description.get_family()) + " " + Config::get().source.map_font_size);
+    source_maps.at(index)->override_font(source_map_font_desc);
+    if (Config::get().source.show_map) {
+        if (hboxes.at(index)->get_children().size() == 1)
+            hboxes.at(index)->pack_end(*source_maps.at(index), Gtk::PACK_SHRINK);
+    } else if (hboxes.at(index)->get_children().size() == 2)
+        hboxes.at(index)->remove(*source_maps.at(index));
 }
 
 bool Notebook::save(size_t index) {
-  if(!source_views[index]->save())
-    return false;
-  Project::on_save(index);
-  return true;
+    if (!source_views[index]->save())
+        return false;
+    Project::on_save(index);
+    return true;
 }
 
 bool Notebook::save_current() {
-  if(auto view=get_current_view())
-    return save(get_index(view));
-  return false;
+    if (auto view = get_current_view())
+        return save(get_index(view));
+    return false;
 }
 
 bool Notebook::close(size_t index) {
-  if(auto view=get_view(index)) {
-    if(view->get_buffer()->get_modified()){
-      if(!save_modified_dialog(index))
-        return false;
-    }
-    if(view==get_current_view()) {
-      bool focused=false;
-      if(last_index!=static_cast<size_t>(-1)) {
-        auto notebook_page=get_notebook_page(last_index);
-        if(notebook_page.first==get_notebook_page(get_index(view)).first) {
-          focus_view(source_views[last_index]);
-          notebooks[notebook_page.first].set_current_page(notebook_page.second);
-          last_index=-1;
-          focused=true;
-        }
-      }
-      if(!focused) {
-        auto notebook_page=get_notebook_page(get_index(view));
-        if(notebook_page.second>0)
-          focus_view(get_view(notebook_page.first, notebook_page.second-1));
-        else {
-          size_t notebook_index=notebook_page.first==0?1:0;
-          if(notebooks[notebook_index].get_n_pages()>0)
-            focus_view(get_view(notebook_index, notebooks[notebook_index].get_current_page()));
-          else
-            set_current_view(nullptr);
+    if (auto view = get_view(index)) {
+        if (view->get_buffer()->get_modified()) {
+            if (!save_modified_dialog(index))
+                return false;
         }
-      }
+        if (view == get_current_view()) {
+            bool focused = false;
+            if (last_index != static_cast<size_t>(-1)) {
+                auto notebook_page = get_notebook_page(last_index);
+                if (notebook_page.first == get_notebook_page(get_index(view)).first) {
+                    focus_view(source_views[last_index]);
+                    notebooks[notebook_page.first].set_current_page(notebook_page.second);
+                    last_index = -1;
+                    focused = true;
+                }
+            }
+            if (!focused) {
+                auto notebook_page = get_notebook_page(get_index(view));
+                if (notebook_page.second > 0)
+                    focus_view(get_view(notebook_page.first, notebook_page.second - 1));
+                else {
+                    size_t notebook_index = notebook_page.first == 0 ? 1 : 0;
+                    if (notebooks[notebook_index].get_n_pages() > 0)
+                        focus_view(get_view(notebook_index, notebooks[notebook_index].get_current_page()));
+                    else
+                        set_current_view(nullptr);
+                }
+            }
+        } else if (index == last_index)
+            last_index = -1;
+        else if (index < last_index && last_index != static_cast<size_t>(-1))
+            last_index--;
+
+        auto notebook_page = get_notebook_page(index);
+        notebooks[notebook_page.first].remove_page(notebook_page.second);
+        source_maps.erase(source_maps.begin() + index);
+
+        if (on_close_page)
+            on_close_page(view);
+
+        delete_cursor_locations(view);
+
+        SelectionDialog::get() = nullptr;
+        CompletionDialog::get() = nullptr;
+
+        if (auto clang_view = dynamic_cast<Source::ClangView *>(view))
+            clang_view->async_delete();
+        else
+            delete view;
+        source_views.erase(source_views.begin() + index);
+        scrolled_windows.erase(scrolled_windows.begin() + index);
+        hboxes.erase(hboxes.begin() + index);
+        tab_labels.erase(tab_labels.begin() + index);
     }
-    else if(index==last_index)
-      last_index=-1;
-    else if(index<last_index && last_index!=static_cast<size_t>(-1))
-      last_index--;
-    
-    auto notebook_page=get_notebook_page(index);
-    notebooks[notebook_page.first].remove_page(notebook_page.second);
-    source_maps.erase(source_maps.begin()+index);
-
-    if(on_close_page)
-      on_close_page(view);
-    
-    delete_cursor_locations(view);
-    
-    SelectionDialog::get()=nullptr;
-    CompletionDialog::get()=nullptr;
-    
-    if(auto clang_view=dynamic_cast<Source::ClangView*>(view))
-      clang_view->async_delete();
-    else
-      delete view;
-    source_views.erase(source_views.begin()+index);
-    scrolled_windows.erase(scrolled_windows.begin()+index);
-    hboxes.erase(hboxes.begin()+index);
-    tab_labels.erase(tab_labels.begin()+index);
-  }
-  return true;
+    return true;
 }
 
 void Notebook::delete_cursor_locations(Source::View *view) {
-  size_t cursor_locations_index=0;
-  for(auto it=cursor_locations.begin();it!=cursor_locations.end();) {
-    if(it->view==view) {
-      view->get_buffer()->delete_mark(it->mark);
-      it=cursor_locations.erase(it);
-      if(current_cursor_location!=static_cast<size_t>(-1) && current_cursor_location>cursor_locations_index)
-        --current_cursor_location;
-    }
-    else {
-      ++it;
-      ++cursor_locations_index;
+    size_t cursor_locations_index = 0;
+    for (auto it = cursor_locations.begin(); it != cursor_locations.end();) {
+        if (it->view == view) {
+            view->get_buffer()->delete_mark(it->mark);
+            it = cursor_locations.erase(it);
+            if (current_cursor_location != static_cast<size_t>(-1) && current_cursor_location > cursor_locations_index)
+                --current_cursor_location;
+        } else {
+            ++it;
+            ++cursor_locations_index;
+        }
     }
-  }
-  if(current_cursor_location>=cursor_locations.size())
-    current_cursor_location=cursor_locations.size()-1;
+    if (current_cursor_location >= cursor_locations.size())
+        current_cursor_location = cursor_locations.size() - 1;
 }
 
 bool Notebook::close_current() {
-  return close(get_index(get_current_view()));
+    return close(get_index(get_current_view()));
 }
 
 void Notebook::next() {
-  if(auto view=get_current_view()) {
-    auto notebook_page=get_notebook_page(get_index(view));
-    int page=notebook_page.second+1;
-    if(page>=notebooks[notebook_page.first].get_n_pages())
-      notebooks[notebook_page.first].set_current_page(0);
-    else
-      notebooks[notebook_page.first].set_current_page(page);
-  }
+    if (auto view = get_current_view()) {
+        auto notebook_page = get_notebook_page(get_index(view));
+        int page = notebook_page.second + 1;
+        if (page >= notebooks[notebook_page.first].get_n_pages())
+            notebooks[notebook_page.first].set_current_page(0);
+        else
+            notebooks[notebook_page.first].set_current_page(page);
+    }
 }
 
 void Notebook::previous() {
-  if(auto view=get_current_view()) {
-    auto notebook_page=get_notebook_page(get_index(view));
-    int page=notebook_page.second-1;
-    if(page<0)
-      notebooks[notebook_page.first].set_current_page(notebooks[notebook_page.first].get_n_pages()-1);
-    else
-      notebooks[notebook_page.first].set_current_page(page);
-  }
+    if (auto view = get_current_view()) {
+        auto notebook_page = get_notebook_page(get_index(view));
+        int page = notebook_page.second - 1;
+        if (page < 0)
+            notebooks[notebook_page.first].set_current_page(notebooks[notebook_page.first].get_n_pages() - 1);
+        else
+            notebooks[notebook_page.first].set_current_page(page);
+    }
 }
 
 void Notebook::toggle_split() {
-  if(!split) {
-    pack2(notebooks[1], true, true);
-    set_position(get_width()/2);
-    show_all();
-    //Make sure the position is correct
-    //TODO: report bug to gtk if it is not fixed in gtk3.22
-    Glib::signal_timeout().connect([this] {
-      set_position(get_width()/2);
-      return false;
-    }, 200);
-  }
-  else {
-    for(size_t c=size()-1;c!=static_cast<size_t>(-1);--c) {
-      auto notebook_index=get_notebook_page(c).first;
-      if(notebook_index==1 && !close(c))
-        return;
+    if (!split) {
+        pack2(notebooks[1], true, true);
+        set_position(get_width() / 2);
+        show_all();
+        //Make sure the position is correct
+        //TODO: report bug to gtk if it is not fixed in gtk3.22
+        Glib::signal_timeout().connect([this] {
+            set_position(get_width() / 2);
+            return false;
+        }, 200);
+    } else {
+        for (size_t c = size() - 1; c != static_cast<size_t>(-1); --c) {
+            auto notebook_index = get_notebook_page(c).first;
+            if (notebook_index == 1 && !close(c))
+                return;
+        }
+        remove(notebooks[1]);
     }
-    remove(notebooks[1]);
-  }
-  split=!split;
+    split = !split;
 }
+
 void Notebook::toggle_tabs() {
-  //Show / Hide tabs for each notebook.
-  for(auto &notebook : Notebook::notebooks)
-    notebook.set_show_tabs(!notebook.get_show_tabs());
+    //Show / Hide tabs for each notebook.
+    for (auto &notebook : Notebook::notebooks)
+        notebook.set_show_tabs(!notebook.get_show_tabs());
 }
 
 boost::filesystem::path Notebook::get_current_folder() {
-  if(!Directories::get().path.empty())
-    return Directories::get().path;
-  else if(auto view=get_current_view())
-    return view->file_path.parent_path();
-  else
-    return boost::filesystem::path();
+    if (!Directories::get().path.empty())
+        return Directories::get().path;
+    else if (auto view = get_current_view())
+        return view->file_path.parent_path();
+    else
+        return boost::filesystem::path();
 }
 
 std::vector<std::pair<size_t, Source::View *>> Notebook::get_notebook_views() {
-  std::vector<std::pair<size_t, Source::View *>> notebook_views;
-  for(size_t notebook_index=0;notebook_index<notebooks.size();++notebook_index) {
-    for(int page=0;page<notebooks[notebook_index].get_n_pages();++page) {
-      if(auto view=get_view(notebook_index, page))
-        notebook_views.emplace_back(notebook_index, view);
+    std::vector<std::pair<size_t, Source::View *>> notebook_views;
+    for (size_t notebook_index = 0; notebook_index < notebooks.size(); ++notebook_index) {
+        for (int page = 0; page < notebooks[notebook_index].get_n_pages(); ++page) {
+            if (auto view = get_view(notebook_index, page))
+                notebook_views.emplace_back(notebook_index, view);
+        }
     }
-  }
-  return notebook_views;
+    return notebook_views;
 }
 
 void Notebook::update_status(Source::BaseView *view) {
-  if(view->update_status_location)
-    view->update_status_location(view);
-  if(view->update_status_file_path)
-    view->update_status_file_path(view);
-  if(view->update_status_branch)
-    view->update_status_branch(view);
-  if(view->update_status_diagnostics)
-    view->update_status_diagnostics(view);
-  if(view->update_status_state)
-    view->update_status_state(view);
+    if (view->update_status_location)
+        view->update_status_location(view);
+    if (view->update_status_file_path)
+        view->update_status_file_path(view);
+    if (view->update_status_branch)
+        view->update_status_branch(view);
+    if (view->update_status_diagnostics)
+        view->update_status_diagnostics(view);
+    if (view->update_status_state)
+        view->update_status_state(view);
 }
 
 void Notebook::clear_status() {
-  status_location.set_text("");
-  status_file_path.set_text("");
-  status_branch.set_text("");
-  status_diagnostics.set_text("");
-  status_state.set_text("");
+    status_location.set_text("");
+    status_file_path.set_text("");
+    status_branch.set_text("");
+    status_diagnostics.set_text("");
+    status_state.set_text("");
 }
 
 size_t Notebook::get_index(Source::View *view) {
-  for(size_t c=0;c<size();++c) {
-    if(source_views[c]==view)
-      return c;
-  }
-  return -1;
+    for (size_t c = 0; c < size(); ++c) {
+        if (source_views[c] == view)
+            return c;
+    }
+    return -1;
 }
 
 Source::View *Notebook::get_view(size_t notebook_index, int page) {
-  if(notebook_index==static_cast<size_t>(-1) || notebook_index>=notebooks.size() ||
-     page<0 || page>=notebooks[notebook_index].get_n_pages())
-    return nullptr;
-  auto hbox=dynamic_cast<Gtk::Box*>(notebooks[notebook_index].get_nth_page(page));
-  auto scrolled_window=dynamic_cast<Gtk::ScrolledWindow*>(hbox->get_children()[0]);
-  return dynamic_cast<Source::View*>(scrolled_window->get_children()[0]);
+    if (notebook_index == static_cast<size_t>(-1) || notebook_index >= notebooks.size() ||
+        page < 0 || page >= notebooks[notebook_index].get_n_pages())
+        return nullptr;
+    auto hbox = dynamic_cast<Gtk::Box *>(notebooks[notebook_index].get_nth_page(page));
+    auto scrolled_window = dynamic_cast<Gtk::ScrolledWindow *>(hbox->get_children()[0]);
+    return dynamic_cast<Source::View *>(scrolled_window->get_children()[0]);
 }
 
 void Notebook::focus_view(Source::View *view) {
-  intermediate_view=view;
-  view->grab_focus();
+    intermediate_view = view;
+    view->grab_focus();
 }
 
 std::pair<size_t, int> Notebook::get_notebook_page(size_t index) {
-  if(index>=hboxes.size())
+    if (index >= hboxes.size())
+        return {-1, -1};
+    for (size_t c = 0; c < notebooks.size(); ++c) {
+        auto page_num = notebooks[c].page_num(*hboxes[index]);
+        if (page_num >= 0)
+            return {c, page_num};
+    }
     return {-1, -1};
-  for(size_t c=0;c<notebooks.size();++c) {
-    auto page_num=notebooks[c].page_num(*hboxes[index]);
-    if(page_num>=0)
-      return {c, page_num};
-  }
-  return {-1, -1};
 }
 
 void Notebook::set_current_view(Source::View *view) {
-  intermediate_view=nullptr;
-  if(current_view!=view) {
-    if(auto view=get_current_view()) {
-      view->hide_tooltips();
-      view->hide_dialogs();
+    intermediate_view = nullptr;
+    if (current_view != view) {
+        if (auto view = get_current_view()) {
+            view->hide_tooltips();
+            view->hide_dialogs();
+        }
+        current_view = view;
+        if (view && on_change_page)
+            on_change_page(view);
     }
-    current_view=view;
-    if(view && on_change_page)
-      on_change_page(view);
-  }
 }
 
 bool Notebook::save_modified_dialog(size_t index) {
-  Gtk::MessageDialog dialog(*static_cast<Gtk::Window*>(get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
-  dialog.set_default_response(Gtk::RESPONSE_YES);
-  dialog.set_secondary_text("Do you want to save: " + get_view(index)->file_path.string()+" ?");
-  int result = dialog.run();
-  if(result==Gtk::RESPONSE_YES) {
-    return save(index);
-  }
-  else if(result==Gtk::RESPONSE_NO) {
-    return true;
-  }
-  else {
-    return false;
-  }
+    Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION,
+                              Gtk::BUTTONS_YES_NO);
+    dialog.set_default_response(Gtk::RESPONSE_YES);
+    dialog.set_secondary_text("Do you want to save: " + get_view(index)->file_path.string() + " ?");
+    int result = dialog.run();
+    if (result == Gtk::RESPONSE_YES) {
+        return save(index);
+    } else if (result == Gtk::RESPONSE_NO) {
+        return true;
+    } else {
+        return false;
+    }
 }
diff --git a/src/notebook.h b/src/notebook.h
index 1a601f1c..9bf1cdc4 100644
--- a/src/notebook.h
+++ b/src/notebook.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <iostream>
 #include "gtkmm.h"
 #include "source.h"
@@ -7,82 +8,106 @@
 #include <sigc++/sigc++.h>
 
 class Notebook : public Gtk::Paned {
-  class TabLabel : public Gtk::EventBox {
-  public:
-    TabLabel(std::function<void()> on_close);
-    Gtk::Label label;
-  };
-  
-  class CursorLocation {
-  public:
-    CursorLocation(Source::View *view, Glib::RefPtr<Gtk::TextBuffer::Mark> mark) : view(view), mark(mark) {}
-    Source::View *view;
-    Glib::RefPtr<Gtk::TextBuffer::Mark> mark;
-  };
-  
+    class TabLabel : public Gtk::EventBox {
+    public:
+        TabLabel(std::function<void()> on_close);
+
+        Gtk::Label label;
+    };
+
+    class CursorLocation {
+    public:
+        CursorLocation(Source::View *view, Glib::RefPtr<Gtk::TextBuffer::Mark> mark) : view(view), mark(mark) {}
+
+        Source::View *view;
+        Glib::RefPtr<Gtk::TextBuffer::Mark> mark;
+    };
+
 private:
-  Notebook();
+    Notebook();
+
 public:
-  static Notebook &get() {
-    static Notebook singleton;
-    return singleton;
-  }
-  
-  size_t size();
-  Source::View* get_view(size_t index);
-  Source::View* get_current_view();
-  std::vector<Source::View*> &get_views();
-  
-  void open(const boost::filesystem::path &file_path, size_t notebook_index=-1);
-  void configure(size_t index);
-  bool save(size_t index);
-  bool save_current();
-  bool close(size_t index);
-  bool close_current();
-  void next();
-  void previous();
-  void toggle_split();
-  /// Hide/Show tabs.		
-  void toggle_tabs();
-  boost::filesystem::path get_current_folder();
-  std::vector<std::pair<size_t, Source::View*>> get_notebook_views();
-
-  Gtk::Label status_location;
-  Gtk::Label status_file_path;
-  Gtk::Label status_branch;
-  Gtk::Label status_diagnostics;
-  Gtk::Label status_state;
-  void update_status(Source::BaseView *view);
-  void clear_status();
-  
-  std::function<void(Source::View*)> on_change_page;
-  std::function<void(Source::View*)> on_close_page;
-  
-  /// Cursor history
-  std::vector<CursorLocation> cursor_locations;
-  size_t current_cursor_location=-1;
-  bool disable_next_update_cursor_locations=false;
-  void delete_cursor_locations(Source::View *view);
-  
+    static Notebook &get() {
+        static Notebook singleton;
+        return singleton;
+    }
+
+    size_t size();
+
+    Source::View *get_view(size_t index);
+
+    Source::View *get_current_view();
+
+    std::vector<Source::View *> &get_views();
+
+    void open(const boost::filesystem::path &file_path, size_t notebook_index = -1);
+
+    void configure(size_t index);
+
+    bool save(size_t index);
+
+    bool save_current();
+
+    bool close(size_t index);
+
+    bool close_current();
+
+    void next();
+
+    void previous();
+
+    void toggle_split();
+
+    /// Hide/Show tabs.
+    void toggle_tabs();
+
+    boost::filesystem::path get_current_folder();
+
+    std::vector<std::pair<size_t, Source::View *>> get_notebook_views();
+
+    Gtk::Label status_location;
+    Gtk::Label status_file_path;
+    Gtk::Label status_branch;
+    Gtk::Label status_diagnostics;
+    Gtk::Label status_state;
+
+    void update_status(Source::BaseView *view);
+
+    void clear_status();
+
+    std::function<void(Source::View *)> on_change_page;
+    std::function<void(Source::View *)> on_close_page;
+
+    /// Cursor history
+    std::vector<CursorLocation> cursor_locations;
+    size_t current_cursor_location = -1;
+    bool disable_next_update_cursor_locations = false;
+
+    void delete_cursor_locations(Source::View *view);
+
 private:
-  size_t get_index(Source::View *view);
-  Source::View *get_view(size_t notebook_index, int page);
-  void focus_view(Source::View *view);
-  std::pair<size_t, int> get_notebook_page(size_t index);
-  
-  std::vector<Gtk::Notebook> notebooks;
-  std::vector<Source::View*> source_views; //Is NOT freed in destructor, this is intended for quick program exit.
-  std::vector<std::unique_ptr<Gtk::Widget> > source_maps;
-  std::vector<std::unique_ptr<Gtk::ScrolledWindow> > scrolled_windows;
-  std::vector<std::unique_ptr<Gtk::Box> > hboxes;
-  std::vector<std::unique_ptr<TabLabel> > tab_labels;
-  
-  bool split=false;
-  size_t last_index=-1;
-  
-  void set_current_view(Source::View *view);
-  Source::View* current_view=nullptr;
-  Source::View* intermediate_view=nullptr;
-  
-  bool save_modified_dialog(size_t index);
+    size_t get_index(Source::View *view);
+
+    Source::View *get_view(size_t notebook_index, int page);
+
+    void focus_view(Source::View *view);
+
+    std::pair<size_t, int> get_notebook_page(size_t index);
+
+    std::vector<Gtk::Notebook> notebooks;
+    std::vector<Source::View *> source_views; //Is NOT freed in destructor, this is intended for quick program exit.
+    std::vector<std::unique_ptr<Gtk::Widget> > source_maps;
+    std::vector<std::unique_ptr<Gtk::ScrolledWindow> > scrolled_windows;
+    std::vector<std::unique_ptr<Gtk::Box> > hboxes;
+    std::vector<std::unique_ptr<TabLabel> > tab_labels;
+
+    bool split = false;
+    size_t last_index = -1;
+
+    void set_current_view(Source::View *view);
+
+    Source::View *current_view = nullptr;
+    Source::View *intermediate_view = nullptr;
+
+    bool save_modified_dialog(size_t index);
 };
diff --git a/src/project.cc b/src/project.cc
index 508ffcdb..61976041 100644
--- a/src/project.cc
+++ b/src/project.cc
@@ -7,9 +7,11 @@
 #include "menu.h"
 #include "notebook.h"
 #include "selection_dialog.h"
+
 #ifdef JUCI_ENABLE_DEBUG
 #include "debug_lldb.h"
 #endif
+
 #include "info.h"
 #include "source_clang.h"
 #include "source_language_protocol.h"
@@ -28,229 +30,231 @@ std::shared_ptr<Project::Base> Project::current;
 std::unique_ptr<Project::DebugOptions> Project::Base::debug_options;
 
 Gtk::Label &Project::debug_status_label() {
-  static Gtk::Label label;
-  return label;
+    static Gtk::Label label;
+    return label;
 }
 
 void Project::save_files(const boost::filesystem::path &path) {
-  for(size_t c=0;c<Notebook::get().size();c++) {
-    auto view=Notebook::get().get_view(c);
-    if(view->get_buffer()->get_modified()) {
-      if(filesystem::file_in_path(view->file_path, path))
-        Notebook::get().save(c);
+    for (size_t c = 0; c < Notebook::get().size(); c++) {
+        auto view = Notebook::get().get_view(c);
+        if (view->get_buffer()->get_modified()) {
+            if (filesystem::file_in_path(view->file_path, path))
+                Notebook::get().save(c);
+        }
     }
-  }
 }
 
 void Project::on_save(size_t index) {
-  auto view=Notebook::get().get_view(index);
-  if(!view)
-    return;
-  boost::filesystem::path build_path;
-  if(view->language && view->language->get_id()=="cmake") {
-    if(view->file_path.filename()=="CMakeLists.txt")
-      build_path=view->file_path;
-    else
-      build_path=filesystem::find_file_in_path_parents("CMakeLists.txt", view->file_path.parent_path());
-  }
-  else if(view->language && view->language->get_id()=="meson") {
-    if(view->file_path.filename()=="meson.build")
-      build_path=view->file_path;
-    else
-      build_path=filesystem::find_file_in_path_parents("meson.build", view->file_path.parent_path());
-  }
-  
-  if(!build_path.empty()) {
-    auto build=Build::create(build_path);
-    if(dynamic_cast<CMakeBuild*>(build.get()) || dynamic_cast<MesonBuild*>(build.get())) {
-      build->update_default(true);
-      Usages::Clang::erase_all_caches_for_project(build->project_path, build->get_default_path());
-      boost::system::error_code ec;
-      if(boost::filesystem::exists(build->get_debug_path()), ec)
-        build->update_debug(true);
-      
-      for(size_t c=0;c<Notebook::get().size();c++) {
-        auto source_view=Notebook::get().get_view(c);
-        if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
-          if(filesystem::file_in_path(source_clang_view->file_path, build->project_path))
-            source_clang_view->full_reparse_needed=true;
+    auto view = Notebook::get().get_view(index);
+    if (!view)
+        return;
+    boost::filesystem::path build_path;
+    if (view->language && view->language->get_id() == "cmake") {
+        if (view->file_path.filename() == "CMakeLists.txt")
+            build_path = view->file_path;
+        else
+            build_path = filesystem::find_file_in_path_parents("CMakeLists.txt", view->file_path.parent_path());
+    } else if (view->language && view->language->get_id() == "meson") {
+        if (view->file_path.filename() == "meson.build")
+            build_path = view->file_path;
+        else
+            build_path = filesystem::find_file_in_path_parents("meson.build", view->file_path.parent_path());
+    }
+
+    if (!build_path.empty()) {
+        auto build = Build::create(build_path);
+        if (dynamic_cast<CMakeBuild *>(build.get()) || dynamic_cast<MesonBuild *>(build.get())) {
+            build->update_default(true);
+            Usages::Clang::erase_all_caches_for_project(build->project_path, build->get_default_path());
+            boost::system::error_code ec;
+            if (boost::filesystem::exists(build->get_debug_path()), ec)
+                build->update_debug(true);
+
+            for (size_t c = 0; c < Notebook::get().size(); c++) {
+                auto source_view = Notebook::get().get_view(c);
+                if (auto source_clang_view = dynamic_cast<Source::ClangView *>(source_view)) {
+                    if (filesystem::file_in_path(source_clang_view->file_path, build->project_path))
+                        source_clang_view->full_reparse_needed = true;
+                }
+            }
         }
-      }
     }
-  }
 }
 
 void Project::debug_update_status(const std::string &new_debug_status) {
-  debug_status=new_debug_status;
-  if(debug_status.empty())
-    debug_status_label().set_text("");
-  else
-    debug_status_label().set_text(debug_status);
-  debug_activate_menu_items();
+    debug_status = new_debug_status;
+    if (debug_status.empty())
+        debug_status_label().set_text("");
+    else
+        debug_status_label().set_text(debug_status);
+    debug_activate_menu_items();
 }
 
 void Project::debug_activate_menu_items() {
-  auto &menu=Menu::get();
-  auto view=Notebook::get().get_current_view();
-  menu.actions["debug_stop"]->set_enabled(!debug_status.empty());
-  menu.actions["debug_kill"]->set_enabled(!debug_status.empty());
-  menu.actions["debug_step_over"]->set_enabled(!debug_status.empty());
-  menu.actions["debug_step_into"]->set_enabled(!debug_status.empty());
-  menu.actions["debug_step_out"]->set_enabled(!debug_status.empty());
-  menu.actions["debug_backtrace"]->set_enabled(!debug_status.empty());
-  menu.actions["debug_show_variables"]->set_enabled(!debug_status.empty());
-  menu.actions["debug_run_command"]->set_enabled(!debug_status.empty());
-  menu.actions["debug_toggle_breakpoint"]->set_enabled(view && view->toggle_breakpoint);
-  menu.actions["debug_goto_stop"]->set_enabled(!debug_status.empty());
+    auto &menu = Menu::get();
+    auto view = Notebook::get().get_current_view();
+    menu.actions["debug_stop"]->set_enabled(!debug_status.empty());
+    menu.actions["debug_kill"]->set_enabled(!debug_status.empty());
+    menu.actions["debug_step_over"]->set_enabled(!debug_status.empty());
+    menu.actions["debug_step_into"]->set_enabled(!debug_status.empty());
+    menu.actions["debug_step_out"]->set_enabled(!debug_status.empty());
+    menu.actions["debug_backtrace"]->set_enabled(!debug_status.empty());
+    menu.actions["debug_show_variables"]->set_enabled(!debug_status.empty());
+    menu.actions["debug_run_command"]->set_enabled(!debug_status.empty());
+    menu.actions["debug_toggle_breakpoint"]->set_enabled(view && view->toggle_breakpoint);
+    menu.actions["debug_goto_stop"]->set_enabled(!debug_status.empty());
 }
 
 void Project::debug_update_stop() {
-  if(!debug_last_stop_file_path.empty()) {
-    for(size_t c=0;c<Notebook::get().size();c++) {
-      auto view=Notebook::get().get_view(c);
-      if(view->file_path==debug_last_stop_file_path) {
-        view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(), "debug_stop");
-        view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(), "debug_breakpoint_and_stop");
-        break;
-      }
+    if (!debug_last_stop_file_path.empty()) {
+        for (size_t c = 0; c < Notebook::get().size(); c++) {
+            auto view = Notebook::get().get_view(c);
+            if (view->file_path == debug_last_stop_file_path) {
+                view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(),
+                                                               "debug_stop");
+                view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(),
+                                                               "debug_breakpoint_and_stop");
+                break;
+            }
+        }
     }
-  }
-  //Add debug stop source mark
-  debug_last_stop_file_path.clear();
-  for(size_t c=0;c<Notebook::get().size();c++) {
-    auto view=Notebook::get().get_view(c);
-    if(view->file_path==debug_stop.first) {
-      if(debug_stop.second.first<view->get_buffer()->get_line_count()) {
-        auto iter=view->get_buffer()->get_iter_at_line(debug_stop.second.first);
-        view->get_source_buffer()->create_source_mark("debug_stop", iter);
-        if(view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size()>0)
-          view->get_source_buffer()->create_source_mark("debug_breakpoint_and_stop", iter);
-        debug_last_stop_file_path=debug_stop.first;
-      }
-      break;
+    //Add debug stop source mark
+    debug_last_stop_file_path.clear();
+    for (size_t c = 0; c < Notebook::get().size(); c++) {
+        auto view = Notebook::get().get_view(c);
+        if (view->file_path == debug_stop.first) {
+            if (debug_stop.second.first < view->get_buffer()->get_line_count()) {
+                auto iter = view->get_buffer()->get_iter_at_line(debug_stop.second.first);
+                view->get_source_buffer()->create_source_mark("debug_stop", iter);
+                if (view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size() > 0)
+                    view->get_source_buffer()->create_source_mark("debug_breakpoint_and_stop", iter);
+                debug_last_stop_file_path = debug_stop.first;
+            }
+            break;
+        }
     }
-  }
 }
 
 std::shared_ptr<Project::Base> Project::create() {
-  std::unique_ptr<Project::Build> build;
-  
-  if(auto view=Notebook::get().get_current_view()) {
-    build=Build::create(view->file_path);
-    if(view->language) {
-      auto language_id=view->language->get_id();
-      if(language_id=="markdown")
-        return std::shared_ptr<Project::Base>(new Project::Markdown(std::move(build)));
-      if(language_id=="python")
-        return std::shared_ptr<Project::Base>(new Project::Python(std::move(build)));
-      if(language_id=="js")
+    std::unique_ptr<Project::Build> build;
+
+    if (auto view = Notebook::get().get_current_view()) {
+        build = Build::create(view->file_path);
+        if (view->language) {
+            auto language_id = view->language->get_id();
+            if (language_id == "markdown")
+                return std::shared_ptr<Project::Base>(new Project::Markdown(std::move(build)));
+            if (language_id == "python")
+                return std::shared_ptr<Project::Base>(new Project::Python(std::move(build)));
+            if (language_id == "js")
+                return std::shared_ptr<Project::Base>(new Project::JavaScript(std::move(build)));
+            if (language_id == "html")
+                return std::shared_ptr<Project::Base>(new Project::HTML(std::move(build)));
+        }
+    } else
+        build = Build::create(Directories::get().path);
+
+    if (dynamic_cast<CMakeBuild *>(build.get()) || dynamic_cast<MesonBuild *>(build.get()))
+        return std::shared_ptr<Project::Base>(new Project::Clang(std::move(build)));
+    else if (dynamic_cast<CargoBuild *>(build.get()))
+        return std::shared_ptr<Project::Base>(new Project::Rust(std::move(build)));
+    else if (dynamic_cast<NpmBuild *>(build.get()))
         return std::shared_ptr<Project::Base>(new Project::JavaScript(std::move(build)));
-      if(language_id=="html")
-        return std::shared_ptr<Project::Base>(new Project::HTML(std::move(build)));
-    }
-  }
-  else
-    build=Build::create(Directories::get().path);
-  
-  if(dynamic_cast<CMakeBuild*>(build.get()) || dynamic_cast<MesonBuild*>(build.get()))
-    return std::shared_ptr<Project::Base>(new Project::Clang(std::move(build)));
-  else if(dynamic_cast<CargoBuild*>(build.get()))
-    return std::shared_ptr<Project::Base>(new Project::Rust(std::move(build)));
-  else if(dynamic_cast<NpmBuild*>(build.get()))
-    return std::shared_ptr<Project::Base>(new Project::JavaScript(std::move(build)));
-  else
-    return std::shared_ptr<Project::Base>(new Project::Base(std::move(build)));
+    else
+        return std::shared_ptr<Project::Base>(new Project::Base(std::move(build)));
 }
 
 std::pair<std::string, std::string> Project::Base::get_run_arguments() {
-  Info::get().print("Could not find a supported project");
-  return {"", ""};
+    Info::get().print("Could not find a supported project");
+    return {"", ""};
 }
 
 void Project::Base::compile() {
-  Info::get().print("Could not find a supported project");
+    Info::get().print("Could not find a supported project");
 }
 
 void Project::Base::compile_and_run() {
-  Info::get().print("Could not find a supported project");
+    Info::get().print("Could not find a supported project");
 }
 
 void Project::Base::recreate_build() {
-  Info::get().print("Could not find a supported project");
+    Info::get().print("Could not find a supported project");
 }
 
 void Project::Base::show_symbols() {
-  auto view=Notebook::get().get_current_view();
-  
-  boost::filesystem::path search_path;
-  if(view)
-    search_path=view->file_path.parent_path();
-  else if(!Directories::get().path.empty())
-    search_path=Directories::get().path;
-  else {
-    boost::system::error_code ec;
-    search_path=boost::filesystem::current_path(ec);
-    if(ec) {
-      Terminal::get().print("Error: could not find current path\n", true);
-      return;
+    auto view = Notebook::get().get_current_view();
+
+    boost::filesystem::path search_path;
+    if (view)
+        search_path = view->file_path.parent_path();
+    else if (!Directories::get().path.empty())
+        search_path = Directories::get().path;
+    else {
+        boost::system::error_code ec;
+        search_path = boost::filesystem::current_path(ec);
+        if (ec) {
+            Terminal::get().print("Error: could not find current path\n", true);
+            return;
+        }
     }
-  }
-  auto pair=Ctags::get_result(search_path);
-  
-  auto path=std::move(pair.first);
-  auto stream=std::move(pair.second);
-  stream->seekg(0, std::ios::end);
-  if(stream->tellg()==0) {
-    Info::get().print("No symbols found in current project");
-    return;
-  }
-  stream->seekg(0, std::ios::beg);
-  
-  if(view) {
-    auto dialog_iter=view->get_iter_for_dialog();
-    SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-  }
-  else
-    SelectionDialog::create(true, true);
-  
-  std::vector<Source::Offset> rows;
-    
-  std::string line;
-  while(std::getline(*stream, line)) {
-    auto location=Ctags::get_location(line, true);
-    
-    std::string row=location.file_path.string()+":"+std::to_string(location.line+1)+": "+location.source;
-    rows.emplace_back(Source::Offset(location.line, location.index, location.file_path));
-    SelectionDialog::get()->add_row(row);
-  }
-    
-  if(rows.size()==0)
-    return;
-  SelectionDialog::get()->on_select=[rows=std::move(rows), path=std::move(path)](unsigned int index, const std::string &text, bool hide_window) {
-    if(index>=rows.size())
-      return;
-    auto offset=rows[index];
-    auto full_path=path/offset.file_path;
-    if(!boost::filesystem::is_regular_file(full_path))
-      return;
-    Notebook::get().open(full_path);
-    auto view=Notebook::get().get_current_view();
-    view->place_cursor_at_line_index(offset.line, offset.index);
-    view->scroll_to_cursor_delayed(view, true, false);
-    view->hide_tooltips();
-  };
-  if(view)
-    view->hide_tooltips();
-  SelectionDialog::get()->show();
+    auto pair = Ctags::get_result(search_path);
+
+    auto path = std::move(pair.first);
+    auto stream = std::move(pair.second);
+    stream->seekg(0, std::ios::end);
+    if (stream->tellg() == 0) {
+        Info::get().print("No symbols found in current project");
+        return;
+    }
+    stream->seekg(0, std::ios::beg);
+
+    if (view) {
+        auto dialog_iter = view->get_iter_for_dialog();
+        SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+    } else
+        SelectionDialog::create(true, true);
+
+    std::vector<Source::Offset> rows;
+
+    std::string line;
+    while (std::getline(*stream, line)) {
+        auto location = Ctags::get_location(line, true);
+
+        std::string row =
+                location.file_path.string() + ":" + std::to_string(location.line + 1) + ": " + location.source;
+        rows.emplace_back(Source::Offset(location.line, location.index, location.file_path));
+        SelectionDialog::get()->add_row(row);
+    }
+
+    if (rows.size() == 0)
+        return;
+    SelectionDialog::get()->on_select = [rows = std::move(rows), path = std::move(path)](unsigned int index,
+                                                                                         const std::string &text,
+                                                                                         bool hide_window) {
+        if (index >= rows.size())
+            return;
+        auto offset = rows[index];
+        auto full_path = path / offset.file_path;
+        if (!boost::filesystem::is_regular_file(full_path))
+            return;
+        Notebook::get().open(full_path);
+        auto view = Notebook::get().get_current_view();
+        view->place_cursor_at_line_index(offset.line, offset.index);
+        view->scroll_to_cursor_delayed(view, true, false);
+        view->hide_tooltips();
+    };
+    if (view)
+        view->hide_tooltips();
+    SelectionDialog::get()->show();
 }
 
 std::pair<std::string, std::string> Project::Base::debug_get_run_arguments() {
-  Info::get().print("Could not find a supported project");
-  return {"", ""};
+    Info::get().print("Could not find a supported project");
+    return {"", ""};
 }
 
 void Project::Base::debug_start() {
-  Info::get().print("Could not find a supported project");
+    Info::get().print("Could not find a supported project");
 }
 
 #ifdef JUCI_ENABLE_DEBUG
@@ -667,351 +671,371 @@ void Project::LLDB::debug_cancel() {
 #endif
 
 void Project::LanguageProtocol::show_symbols() {
-  if(build->project_path.empty()) {
-    Info::get().print("Could not find project folder");
-    return;
-  }
-  
-  auto language_id=get_language_id();
-  auto executable_name=language_id+"-language-server";
-  if(filesystem::find_executable(executable_name).empty()) {
-    Info::get().print("Executable "+executable_name+" not found");
-    return;
-  }
-  
-  auto project_path=std::make_shared<boost::filesystem::path>(build->project_path);
-  
-  auto client=::LanguageProtocol::Client::get(*project_path, language_id);
-  auto capabilities=client->initialize(nullptr);
-  
-  if(!capabilities.workspace_symbol) {
-    Info::get().print("Language server does not support workspace/symbol");
-    return;
-  }
-  
-  auto view=Notebook::get().get_current_view();
-  if(view) {
-    auto dialog_iter=view->get_iter_for_dialog();
-    SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-  }
-  else
-    SelectionDialog::create(true, true);
-  
-  SelectionDialog::get()->on_hide=[] {
-    SelectionDialog::get()->on_search_entry_changed=nullptr; // To delete client object
-  };
-  
-  auto offsets=std::make_shared<std::vector<Source::Offset>>();
-  SelectionDialog::get()->on_search_entry_changed=[client, project_path, offsets](const std::string &text) {
-    if(text.size()>1)
-      return;
-    else {
-      offsets->clear();
-      SelectionDialog::get()->erase_rows();
-      if(text.empty())
+    if (build->project_path.empty()) {
+        Info::get().print("Could not find project folder");
         return;
     }
-    std::vector<std::string> names;
-    std::promise<void> result_processed;
-    client->write_request(nullptr, "workspace/symbol", "\"query\":\""+text+"\"", [&result_processed, &names, offsets, project_path](const boost::property_tree::ptree &result, bool error) {
-      if(!error) {
-        for(auto it=result.begin();it!=result.end();++it) {
-          auto name=it->second.get<std::string>("name", "");
-          if(!name.empty()) {
-            auto location_it=it->second.find("location");
-            if(location_it!=it->second.not_found()) {
-              auto file=location_it->second.get<std::string>("uri", "");
-              if(file.size()>7) {
-                file.erase(0, 7);
-                auto range_it=location_it->second.find("range");
-                if(range_it!=location_it->second.not_found()) {
-                  auto start_it=range_it->second.find("start");
-                  if(start_it!=range_it->second.not_found()) {
-                    try {
-                      offsets->emplace_back(Source::Offset(start_it->second.get<unsigned>("line"), start_it->second.get<unsigned>("character"), file));
-                      names.emplace_back(name);
-                    }
-                    catch(...) {}
-                  }
-                }
-              }
-            }
-          }
+
+    auto language_id = get_language_id();
+    auto executable_name = language_id + "-language-server";
+    if (filesystem::find_executable(executable_name).empty()) {
+        Info::get().print("Executable " + executable_name + " not found");
+        return;
+    }
+
+    auto project_path = std::make_shared<boost::filesystem::path>(build->project_path);
+
+    auto client = ::LanguageProtocol::Client::get(*project_path, language_id);
+    auto capabilities = client->initialize(nullptr);
+
+    if (!capabilities.workspace_symbol) {
+        Info::get().print("Language server does not support workspace/symbol");
+        return;
+    }
+
+    auto view = Notebook::get().get_current_view();
+    if (view) {
+        auto dialog_iter = view->get_iter_for_dialog();
+        SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+    } else
+        SelectionDialog::create(true, true);
+
+    SelectionDialog::get()->on_hide = [] {
+        SelectionDialog::get()->on_search_entry_changed = nullptr; // To delete client object
+    };
+
+    auto offsets = std::make_shared<std::vector<Source::Offset>>();
+    SelectionDialog::get()->on_search_entry_changed = [client, project_path, offsets](const std::string &text) {
+        if (text.size() > 1)
+            return;
+        else {
+            offsets->clear();
+            SelectionDialog::get()->erase_rows();
+            if (text.empty())
+                return;
         }
-      }
-      result_processed.set_value();
-    });
-    result_processed.get_future().get();
-    for(size_t c=0;c<offsets->size() && c<names.size();++c)
-      SelectionDialog::get()->add_row(filesystem::get_relative_path((*offsets)[c].file_path, *project_path).string()+':'+std::to_string((*offsets)[c].line+1)+':'+std::to_string((*offsets)[c].index+1)+": "+names[c]);
-  };
-  
-  SelectionDialog::get()->on_select=[offsets](unsigned int index, const std::string &text, bool hide_window) {
-    auto &offset=(*offsets)[index];
-    if(!boost::filesystem::is_regular_file(offset.file_path))
-      return;
-    Notebook::get().open(offset.file_path);
-    auto view=Notebook::get().get_current_view();
-    view->place_cursor_at_line_offset(offset.line, offset.index);
-    view->scroll_to_cursor_delayed(view, true, false);
-    view->hide_tooltips();
-  };
-  
-  if(view)
-    view->hide_tooltips();
-  SelectionDialog::get()->show();
+        std::vector<std::string> names;
+        std::promise<void> result_processed;
+        client->write_request(nullptr, "workspace/symbol", "\"query\":\"" + text + "\"",
+                              [&result_processed, &names, offsets, project_path](
+                                      const boost::property_tree::ptree &result, bool error) {
+                                  if (!error) {
+                                      for (auto it = result.begin(); it != result.end(); ++it) {
+                                          auto name = it->second.get<std::string>("name", "");
+                                          if (!name.empty()) {
+                                              auto location_it = it->second.find("location");
+                                              if (location_it != it->second.not_found()) {
+                                                  auto file = location_it->second.get<std::string>("uri", "");
+                                                  if (file.size() > 7) {
+                                                      file.erase(0, 7);
+                                                      auto range_it = location_it->second.find("range");
+                                                      if (range_it != location_it->second.not_found()) {
+                                                          auto start_it = range_it->second.find("start");
+                                                          if (start_it != range_it->second.not_found()) {
+                                                              try {
+                                                                  offsets->emplace_back(Source::Offset(
+                                                                          start_it->second.get<unsigned>("line"),
+                                                                          start_it->second.get<unsigned>("character"),
+                                                                          file));
+                                                                  names.emplace_back(name);
+                                                              }
+                                                              catch (...) {}
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                                  result_processed.set_value();
+                              });
+        result_processed.get_future().get();
+        for (size_t c = 0; c < offsets->size() && c < names.size(); ++c)
+            SelectionDialog::get()->add_row(
+                    filesystem::get_relative_path((*offsets)[c].file_path, *project_path).string() + ':' +
+                    std::to_string((*offsets)[c].line + 1) + ':' + std::to_string((*offsets)[c].index + 1) + ": " +
+                    names[c]);
+    };
+
+    SelectionDialog::get()->on_select = [offsets](unsigned int index, const std::string &text, bool hide_window) {
+        auto &offset = (*offsets)[index];
+        if (!boost::filesystem::is_regular_file(offset.file_path))
+            return;
+        Notebook::get().open(offset.file_path);
+        auto view = Notebook::get().get_current_view();
+        view->place_cursor_at_line_offset(offset.line, offset.index);
+        view->scroll_to_cursor_delayed(view, true, false);
+        view->hide_tooltips();
+    };
+
+    if (view)
+        view->hide_tooltips();
+    SelectionDialog::get()->show();
 }
 
 std::pair<std::string, std::string> Project::Clang::get_run_arguments() {
-  auto build_path=build->get_default_path();
-  if(build_path.empty())
-    return {"", ""};
-  
-  auto project_path=build->project_path.string();
-  auto run_arguments_it=run_arguments.find(project_path);
-  std::string arguments;
-  if(run_arguments_it!=run_arguments.end())
-    arguments=run_arguments_it->second;
-  
-  if(arguments.empty()) {
-    auto view=Notebook::get().get_current_view();
-    auto executable=build->get_executable(view?view->file_path:Directories::get().path);
-    
-    if(!executable.empty())
-      arguments=filesystem::escape_argument(filesystem::get_short_path(executable).string());
-    else
-      arguments=filesystem::escape_argument(filesystem::get_short_path(build->get_default_path()).string());
-  }
-  
-  return {project_path, arguments};
+    auto build_path = build->get_default_path();
+    if (build_path.empty())
+        return {"", ""};
+
+    auto project_path = build->project_path.string();
+    auto run_arguments_it = run_arguments.find(project_path);
+    std::string arguments;
+    if (run_arguments_it != run_arguments.end())
+        arguments = run_arguments_it->second;
+
+    if (arguments.empty()) {
+        auto view = Notebook::get().get_current_view();
+        auto executable = build->get_executable(view ? view->file_path : Directories::get().path);
+
+        if (!executable.empty())
+            arguments = filesystem::escape_argument(filesystem::get_short_path(executable).string());
+        else
+            arguments = filesystem::escape_argument(filesystem::get_short_path(build->get_default_path()).string());
+    }
+
+    return {project_path, arguments};
 }
 
 void Project::Clang::compile() {
-  auto default_build_path=build->get_default_path();
-  if(default_build_path.empty() || !build->update_default())
-    return;
-  
-  compiling=true;
-  
-  if(Config::get().project.clear_terminal_on_compile)
-    Terminal::get().clear();
-  
-  Terminal::get().print("Compiling project "+filesystem::get_short_path(build->project_path).string()+"\n");
-  Terminal::get().async_process(build->get_compile_command(), default_build_path, [](int exit_status) {
-    compiling=false;
-  });
+    auto default_build_path = build->get_default_path();
+    if (default_build_path.empty() || !build->update_default())
+        return;
+
+    compiling = true;
+
+    if (Config::get().project.clear_terminal_on_compile)
+        Terminal::get().clear();
+
+    Terminal::get().print("Compiling project " + filesystem::get_short_path(build->project_path).string() + "\n");
+    Terminal::get().async_process(build->get_compile_command(), default_build_path, [](int exit_status) {
+        compiling = false;
+    });
 }
 
 void Project::Clang::compile_and_run() {
-  auto default_build_path=build->get_default_path();
-  if(default_build_path.empty() || !build->update_default())
-    return;
-  
-  auto project_path=build->project_path;
-  
-  auto run_arguments_it=run_arguments.find(project_path.string());
-  std::string arguments;
-  if(run_arguments_it!=run_arguments.end())
-    arguments=run_arguments_it->second;
-  
-  if(arguments.empty()) {
-    auto view=Notebook::get().get_current_view();
-    auto executable=build->get_executable(view?view->file_path:Directories::get().path);
-    if(executable.empty()) {
-      Terminal::get().print("Warning: could not find executable.\n");
-      Terminal::get().print("Solution: either use Project Set Run Arguments, or open a source file within a directory where an executable is defined.\n", true);
-      return;
-    }
-    arguments=filesystem::escape_argument(filesystem::get_short_path(executable).string());
-  }
-  
-  compiling=true;
-  
-  if(Config::get().project.clear_terminal_on_compile)
-    Terminal::get().clear();
-  
-  Terminal::get().print("Compiling and running "+arguments+"\n");
-  Terminal::get().async_process(build->get_compile_command(), default_build_path, [arguments, project_path](int exit_status){
-    compiling=false;
-    if(exit_status==EXIT_SUCCESS) {
-      Terminal::get().async_process(arguments, project_path, [arguments](int exit_status){
-        Terminal::get().async_print(arguments+" returned: "+std::to_string(exit_status)+'\n');
-      });
+    auto default_build_path = build->get_default_path();
+    if (default_build_path.empty() || !build->update_default())
+        return;
+
+    auto project_path = build->project_path;
+
+    auto run_arguments_it = run_arguments.find(project_path.string());
+    std::string arguments;
+    if (run_arguments_it != run_arguments.end())
+        arguments = run_arguments_it->second;
+
+    if (arguments.empty()) {
+        auto view = Notebook::get().get_current_view();
+        auto executable = build->get_executable(view ? view->file_path : Directories::get().path);
+        if (executable.empty()) {
+            Terminal::get().print("Warning: could not find executable.\n");
+            Terminal::get().print(
+                    "Solution: either use Project Set Run Arguments, or open a source file within a directory where an executable is defined.\n",
+                    true);
+            return;
+        }
+        arguments = filesystem::escape_argument(filesystem::get_short_path(executable).string());
     }
-  });
+
+    compiling = true;
+
+    if (Config::get().project.clear_terminal_on_compile)
+        Terminal::get().clear();
+
+    Terminal::get().print("Compiling and running " + arguments + "\n");
+    Terminal::get().async_process(build->get_compile_command(), default_build_path,
+                                  [arguments, project_path](int exit_status) {
+                                      compiling = false;
+                                      if (exit_status == EXIT_SUCCESS) {
+                                          Terminal::get().async_process(arguments, project_path,
+                                                                        [arguments](int exit_status) {
+                                                                            Terminal::get().async_print(
+                                                                                    arguments + " returned: " +
+                                                                                    std::to_string(exit_status) + '\n');
+                                                                        });
+                                      }
+                                  });
 }
 
 void Project::Clang::recreate_build() {
-  if(build->project_path.empty())
-    return;
-  auto default_build_path=build->get_default_path();
-  if(default_build_path.empty())
-    return;
-  
-  auto debug_build_path=build->get_debug_path();
-  bool has_default_build=boost::filesystem::exists(default_build_path);
-  bool has_debug_build=!debug_build_path.empty() && boost::filesystem::exists(debug_build_path);
-  
-  if(has_default_build || has_debug_build) {
-    Gtk::MessageDialog dialog(*static_cast<Gtk::Window*>(Notebook::get().get_toplevel()), "Recreate Build", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
-    dialog.set_default_response(Gtk::RESPONSE_NO);
-    std::string message="Are you sure you want to recreate ";
-    if(has_default_build)
-      message+=default_build_path.string();
-    if(has_debug_build) {
-      if(has_default_build)
-        message+=" and ";
-      message+=debug_build_path.string();
-    }
-    dialog.set_secondary_text(message+"?");
-    if(dialog.run()!=Gtk::RESPONSE_YES)
-      return;
-    Usages::Clang::erase_all_caches_for_project(build->project_path, default_build_path);
-    try {
-      if(has_default_build)
-        boost::filesystem::remove_all(default_build_path);
-      if(has_debug_build)
-        boost::filesystem::remove_all(debug_build_path);
+    if (build->project_path.empty())
+        return;
+    auto default_build_path = build->get_default_path();
+    if (default_build_path.empty())
+        return;
+
+    auto debug_build_path = build->get_debug_path();
+    bool has_default_build = boost::filesystem::exists(default_build_path);
+    bool has_debug_build = !debug_build_path.empty() && boost::filesystem::exists(debug_build_path);
+
+    if (has_default_build || has_debug_build) {
+        Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(Notebook::get().get_toplevel()), "Recreate Build", false,
+                                  Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
+        dialog.set_default_response(Gtk::RESPONSE_NO);
+        std::string message = "Are you sure you want to recreate ";
+        if (has_default_build)
+            message += default_build_path.string();
+        if (has_debug_build) {
+            if (has_default_build)
+                message += " and ";
+            message += debug_build_path.string();
+        }
+        dialog.set_secondary_text(message + "?");
+        if (dialog.run() != Gtk::RESPONSE_YES)
+            return;
+        Usages::Clang::erase_all_caches_for_project(build->project_path, default_build_path);
+        try {
+            if (has_default_build)
+                boost::filesystem::remove_all(default_build_path);
+            if (has_debug_build)
+                boost::filesystem::remove_all(debug_build_path);
+        }
+        catch (const std::exception &e) {
+            Terminal::get().print(std::string("Error: could not remove build: ") + e.what() + "\n", true);
+            return;
+        }
     }
-    catch(const std::exception &e) {
-      Terminal::get().print(std::string("Error: could not remove build: ")+e.what()+"\n", true);
-      return;
+
+    build->update_default(true);
+    if (has_debug_build)
+        build->update_debug(true);
+
+    for (size_t c = 0; c < Notebook::get().size(); c++) {
+        auto source_view = Notebook::get().get_view(c);
+        if (auto source_clang_view = dynamic_cast<Source::ClangView *>(source_view)) {
+            if (filesystem::file_in_path(source_clang_view->file_path, build->project_path))
+                source_clang_view->full_reparse_needed = true;
+        }
     }
-  }
-  
-  build->update_default(true);
-  if(has_debug_build)
-    build->update_debug(true);
-  
-  for(size_t c=0;c<Notebook::get().size();c++) {
-    auto source_view=Notebook::get().get_view(c);
-    if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
-      if(filesystem::file_in_path(source_clang_view->file_path, build->project_path))
-        source_clang_view->full_reparse_needed=true;
+
+    if (auto view = Notebook::get().get_current_view()) {
+        if (view->full_reparse_needed)
+            view->full_reparse();
     }
-  }
-  
-  if(auto view=Notebook::get().get_current_view()) {
-    if(view->full_reparse_needed)
-      view->full_reparse();
-  }
 }
 
 Project::Markdown::~Markdown() {
-  if(!last_temp_path.empty()) {
-    boost::filesystem::remove(last_temp_path);
-    last_temp_path=boost::filesystem::path();
-  }
+    if (!last_temp_path.empty()) {
+        boost::filesystem::remove(last_temp_path);
+        last_temp_path = boost::filesystem::path();
+    }
 }
 
 void Project::Markdown::compile_and_run() {
-  if(!last_temp_path.empty()) {
-    boost::filesystem::remove(last_temp_path);
-    last_temp_path=boost::filesystem::path();
-  }
-  
-  std::stringstream stdin_stream, stdout_stream;
-  auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, "command -v grip");
-  if(exit_status==0) {
-    auto command="grip -b "+filesystem::escape_argument(filesystem::get_short_path(Notebook::get().get_current_view()->file_path).string());
-    Terminal::get().print("Running: "+command+" in a quiet background process\n");
-    Terminal::get().async_process(command, "", nullptr, true);
-  }
-  else
-    Terminal::get().print("Warning: install grip to preview Markdown files\n");
+    if (!last_temp_path.empty()) {
+        boost::filesystem::remove(last_temp_path);
+        last_temp_path = boost::filesystem::path();
+    }
+
+    std::stringstream stdin_stream, stdout_stream;
+    auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, "command -v grip");
+    if (exit_status == 0) {
+        auto command = "grip -b " + filesystem::escape_argument(
+                filesystem::get_short_path(Notebook::get().get_current_view()->file_path).string());
+        Terminal::get().print("Running: " + command + " in a quiet background process\n");
+        Terminal::get().async_process(command, "", nullptr, true);
+    } else
+        Terminal::get().print("Warning: install grip to preview Markdown files\n");
 }
 
 void Project::Python::compile_and_run() {
-  auto command=Config::get().project.python_command+' '+filesystem::escape_argument(filesystem::get_short_path(Notebook::get().get_current_view()->file_path).string());
-  Terminal::get().print("Running "+command+"\n");
-  Terminal::get().async_process(command, Notebook::get().get_current_view()->file_path.parent_path(), [command](int exit_status) {
-    Terminal::get().async_print(command+" returned: "+std::to_string(exit_status)+'\n');
-  });
+    auto command = Config::get().project.python_command + ' ' + filesystem::escape_argument(
+            filesystem::get_short_path(Notebook::get().get_current_view()->file_path).string());
+    Terminal::get().print("Running " + command + "\n");
+    Terminal::get().async_process(command, Notebook::get().get_current_view()->file_path.parent_path(),
+                                  [command](int exit_status) {
+                                      Terminal::get().async_print(
+                                              command + " returned: " + std::to_string(exit_status) + '\n');
+                                  });
 }
 
 void Project::JavaScript::compile_and_run() {
-  std::string command;
-  boost::filesystem::path path;
-  if(!build->project_path.empty()) {
-    command="npm start";
-    path=build->project_path;
-  }
-  else {
-    auto view=Notebook::get().get_current_view();
-    if(!view) {
-      Info::get().print("No executable found");
-      return;
+    std::string command;
+    boost::filesystem::path path;
+    if (!build->project_path.empty()) {
+        command = "npm start";
+        path = build->project_path;
+    } else {
+        auto view = Notebook::get().get_current_view();
+        if (!view) {
+            Info::get().print("No executable found");
+            return;
+        }
+        command = "node --harmony " + filesystem::escape_argument(filesystem::get_short_path(view->file_path).string());
+        path = view->file_path.parent_path();
     }
-    command="node --harmony "+filesystem::escape_argument(filesystem::get_short_path(view->file_path).string());
-    path=view->file_path.parent_path();
-  }
-  Terminal::get().print("Running "+command+"\n");
-  Terminal::get().async_process(command, path, [command](int exit_status) {
-    Terminal::get().async_print(command+" returned: "+std::to_string(exit_status)+'\n');
-  });
+    Terminal::get().print("Running " + command + "\n");
+    Terminal::get().async_process(command, path, [command](int exit_status) {
+        Terminal::get().async_print(command + " returned: " + std::to_string(exit_status) + '\n');
+    });
 }
 
 void Project::HTML::compile_and_run() {
-  auto uri=Notebook::get().get_current_view()->file_path.string();
+    auto uri = Notebook::get().get_current_view()->file_path.string();
 #ifdef __APPLE__
-  Terminal::get().process("open "+filesystem::escape_argument(uri));
+    Terminal::get().process("open "+filesystem::escape_argument(uri));
 #else
 #ifdef __linux
-  uri="file://"+uri;
+    uri="file://"+uri;
 #endif
-  GError* error=nullptr;
+    GError *error = nullptr;
 #if GTK_VERSION_GE(3, 22)
-  gtk_show_uri_on_window(nullptr, uri.c_str(), GDK_CURRENT_TIME, &error);
+    gtk_show_uri_on_window(nullptr, uri.c_str(), GDK_CURRENT_TIME, &error);
 #else
-  gtk_show_uri(nullptr, uri.c_str(), GDK_CURRENT_TIME, &error);
+    gtk_show_uri(nullptr, uri.c_str(), GDK_CURRENT_TIME, &error);
 #endif
-  g_clear_error(&error);
+    g_clear_error(&error);
 #endif
 }
 
 std::pair<std::string, std::string> Project::Rust::get_run_arguments() {
-  auto project_path=build->project_path.string();
-  auto run_arguments_it=run_arguments.find(project_path);
-  std::string arguments;
-  if(run_arguments_it!=run_arguments.end())
-    arguments=run_arguments_it->second;
-  
-  if(arguments.empty())
-    arguments=filesystem::get_short_path(build->get_executable(project_path)).string();
-  
-  return {project_path, arguments};
+    auto project_path = build->project_path.string();
+    auto run_arguments_it = run_arguments.find(project_path);
+    std::string arguments;
+    if (run_arguments_it != run_arguments.end())
+        arguments = run_arguments_it->second;
+
+    if (arguments.empty())
+        arguments = filesystem::get_short_path(build->get_executable(project_path)).string();
+
+    return {project_path, arguments};
 }
 
 void Project::Rust::compile() {
-  compiling=true;
-  
-  if(Config::get().project.clear_terminal_on_compile)
-    Terminal::get().clear();
-  
-  Terminal::get().print("Compiling project "+filesystem::get_short_path(build->project_path).string()+"\n");
-  
-  auto command=build->get_compile_command();
-  Terminal::get().async_process(command, build->project_path, [](int exit_status) {
-    compiling=false;
-  });
+    compiling = true;
+
+    if (Config::get().project.clear_terminal_on_compile)
+        Terminal::get().clear();
+
+    Terminal::get().print("Compiling project " + filesystem::get_short_path(build->project_path).string() + "\n");
+
+    auto command = build->get_compile_command();
+    Terminal::get().async_process(command, build->project_path, [](int exit_status) {
+        compiling = false;
+    });
 }
 
 void Project::Rust::compile_and_run() {
-  compiling=true;
-  
-  if(Config::get().project.clear_terminal_on_compile)
-    Terminal::get().clear();
-  
-  auto arguments=get_run_arguments().second;
-  Terminal::get().print("Compiling and running "+arguments+"\n");
-  
-  auto self=this->shared_from_this();
-  Terminal::get().async_process(build->get_compile_command(), build->project_path, [self, arguments=std::move(arguments)](int exit_status) {
-    compiling=false;
-    if(exit_status==EXIT_SUCCESS) {
-      Terminal::get().async_process(arguments, self->build->project_path, [arguments](int exit_status) {
-        Terminal::get().async_print(arguments+" returned: "+std::to_string(exit_status)+'\n');
-      });
-    }
-  });
+    compiling = true;
+
+    if (Config::get().project.clear_terminal_on_compile)
+        Terminal::get().clear();
+
+    auto arguments = get_run_arguments().second;
+    Terminal::get().print("Compiling and running " + arguments + "\n");
+
+    auto self = this->shared_from_this();
+    Terminal::get().async_process(build->get_compile_command(), build->project_path,
+                                  [self, arguments = std::move(arguments)](int exit_status) {
+                                      compiling = false;
+                                      if (exit_status == EXIT_SUCCESS) {
+                                          Terminal::get().async_process(arguments, self->build->project_path,
+                                                                        [arguments](int exit_status) {
+                                                                            Terminal::get().async_print(
+                                                                                    arguments + " returned: " +
+                                                                                    std::to_string(exit_status) + '\n');
+                                                                        });
+                                      }
+                                  });
 }
diff --git a/src/project.h b/src/project.h
index d0db2c68..82c100ce 100644
--- a/src/project.h
+++ b/src/project.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <gtkmm.h>
 #include <boost/filesystem.hpp>
 #include <atomic>
@@ -9,161 +10,200 @@
 #include "project_build.h"
 
 namespace Project {
-  class DebugRunArguments {
-  public:
-    std::string arguments;
-    bool remote_enabled;
-    std::string remote_host_port;
-  };
-  
-  class DebugOptions : public Gtk::Popover {
-  public:
-    DebugOptions() : Gtk::Popover(), vbox(Gtk::Orientation::ORIENTATION_VERTICAL) { add(vbox); }
-    Gtk::Box vbox;
-  };
-  
-  Gtk::Label &debug_status_label();
-  void save_files(const boost::filesystem::path &path);
-  void on_save(size_t index);
-  
-  extern boost::filesystem::path debug_last_stop_file_path;
-  extern std::unordered_map<std::string, std::string> run_arguments;
-  extern std::unordered_map<std::string, DebugRunArguments> debug_run_arguments;
-  extern std::atomic<bool> compiling;
-  extern std::atomic<bool> debugging;
-  extern std::pair<boost::filesystem::path, std::pair<int, int> > debug_stop;
-  extern std::string debug_status;
-  void debug_update_status(const std::string &new_debug_status);
-  void debug_activate_menu_items();
-  void debug_update_stop();
-  
-  class Base : public std::enable_shared_from_this<Base> {
-  protected:
-    static std::unique_ptr<DebugOptions> debug_options;
-  public:
-    Base() {}
-    Base(std::unique_ptr<Build> &&build): build(std::move(build)) {}
-    virtual ~Base() {}
-    
-    std::unique_ptr<Build> build;
-    
-    Dispatcher dispatcher;
-    
-    virtual std::pair<std::string, std::string> get_run_arguments();
-    virtual void compile();
-    virtual void compile_and_run();
-    virtual void recreate_build();
-    
-    virtual void show_symbols();
-    
-    virtual std::pair<std::string, std::string> debug_get_run_arguments();
-    virtual Project::DebugOptions *debug_get_options() { return nullptr; }
-    Tooltips debug_variable_tooltips;
-    virtual void debug_start();
-    virtual void debug_continue() {}
-    virtual void debug_stop() {}
-    virtual void debug_kill() {}
-    virtual void debug_step_over() {}
-    virtual void debug_step_into() {}
-    virtual void debug_step_out() {}
-    virtual void debug_backtrace() {}
-    virtual void debug_show_variables() {}
-    virtual void debug_run_command(const std::string &command) {}
-    virtual void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {}
-    virtual void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {}
-    virtual bool debug_is_running() { return false; }
-    virtual void debug_write(const std::string &buffer) {}
-    virtual void debug_cancel() {}
-  };
-  
-  class LLDB : public virtual Base {
-  public:
-    LLDB() {}
-    ~LLDB() { dispatcher.disconnect(); }
-    
+    class DebugRunArguments {
+    public:
+        std::string arguments;
+        bool remote_enabled;
+        std::string remote_host_port;
+    };
+
+    class DebugOptions : public Gtk::Popover {
+    public:
+        DebugOptions() : Gtk::Popover(), vbox(Gtk::Orientation::ORIENTATION_VERTICAL) { add(vbox); }
+
+        Gtk::Box vbox;
+    };
+
+    Gtk::Label &debug_status_label();
+
+    void save_files(const boost::filesystem::path &path);
+
+    void on_save(size_t index);
+
+    extern boost::filesystem::path debug_last_stop_file_path;
+    extern std::unordered_map<std::string, std::string> run_arguments;
+    extern std::unordered_map<std::string, DebugRunArguments> debug_run_arguments;
+    extern std::atomic<bool> compiling;
+    extern std::atomic<bool> debugging;
+    extern std::pair<boost::filesystem::path, std::pair<int, int> > debug_stop;
+    extern std::string debug_status;
+
+    void debug_update_status(const std::string &new_debug_status);
+
+    void debug_activate_menu_items();
+
+    void debug_update_stop();
+
+    class Base : public std::enable_shared_from_this<Base> {
+    protected:
+        static std::unique_ptr<DebugOptions> debug_options;
+    public:
+        Base() {}
+
+        Base(std::unique_ptr<Build> &&build) : build(std::move(build)) {}
+
+        virtual ~Base() {}
+
+        std::unique_ptr<Build> build;
+
+        Dispatcher dispatcher;
+
+        virtual std::pair<std::string, std::string> get_run_arguments();
+
+        virtual void compile();
+
+        virtual void compile_and_run();
+
+        virtual void recreate_build();
+
+        virtual void show_symbols();
+
+        virtual std::pair<std::string, std::string> debug_get_run_arguments();
+
+        virtual Project::DebugOptions *debug_get_options() { return nullptr; }
+
+        Tooltips debug_variable_tooltips;
+
+        virtual void debug_start();
+
+        virtual void debug_continue() {}
+
+        virtual void debug_stop() {}
+
+        virtual void debug_kill() {}
+
+        virtual void debug_step_over() {}
+
+        virtual void debug_step_into() {}
+
+        virtual void debug_step_out() {}
+
+        virtual void debug_backtrace() {}
+
+        virtual void debug_show_variables() {}
+
+        virtual void debug_run_command(const std::string &command) {}
+
+        virtual void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {}
+
+        virtual void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {}
+
+        virtual bool debug_is_running() { return false; }
+
+        virtual void debug_write(const std::string &buffer) {}
+
+        virtual void debug_cancel() {}
+    };
+
+    class LLDB : public virtual Base {
+    public:
+        LLDB() {}
+
+        ~LLDB() { dispatcher.disconnect(); }
+
 #ifdef JUCI_ENABLE_DEBUG
-    std::pair<std::string, std::string> debug_get_run_arguments() override;
-    Project::DebugOptions *debug_get_options() override;
-    void debug_start() override;
-    void debug_continue() override;
-    void debug_stop() override;
-    void debug_kill() override;
-    void debug_step_over() override;
-    void debug_step_into() override;
-    void debug_step_out() override;
-    void debug_backtrace() override;
-    void debug_show_variables() override;
-    void debug_run_command(const std::string &command) override;
-    void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) override;
-    void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) override;
-    bool debug_is_running() override;
-    void debug_write(const std::string &buffer) override;
-    void debug_cancel() override;
+        std::pair<std::string, std::string> debug_get_run_arguments() override;
+        Project::DebugOptions *debug_get_options() override;
+        void debug_start() override;
+        void debug_continue() override;
+        void debug_stop() override;
+        void debug_kill() override;
+        void debug_step_over() override;
+        void debug_step_into() override;
+        void debug_step_out() override;
+        void debug_backtrace() override;
+        void debug_show_variables() override;
+        void debug_run_command(const std::string &command) override;
+        void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) override;
+        void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) override;
+        bool debug_is_running() override;
+        void debug_write(const std::string &buffer) override;
+        void debug_cancel() override;
 #endif
-  };
-  
-  class LanguageProtocol : public virtual Base {
-  public:
-    LanguageProtocol() {}
-    virtual std::string get_language_id()=0;
-    void show_symbols() override;
-  };
-  
-  class Clang : public LLDB {
-  public:
-    Clang(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
-    std::pair<std::string, std::string> get_run_arguments() override;
-    void compile() override;
-    void compile_and_run() override;
-    void recreate_build() override;    
-  };
-  
-  class Markdown : public Base {
-  public:
-    Markdown(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    ~Markdown();
-    
-    boost::filesystem::path last_temp_path;
-    void compile_and_run() override;
-  };
-  
-  class Python : public LanguageProtocol {
-  public:
-    Python(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
-    void compile_and_run() override;
-    
-    std::string get_language_id() override { return "python"; }
-  };
-  
-  class JavaScript : public LanguageProtocol {
-  public:
-    JavaScript(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
-    void compile_and_run() override;
-    
-    std::string get_language_id() override { return "javascript"; }
-  };
-  
-  class HTML : public Base {
-  public:
-    HTML(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
-    void compile_and_run() override;
-  };
-  
-  class Rust : public LLDB, public LanguageProtocol {
-  public:
-    Rust(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
-    std::pair<std::string, std::string> get_run_arguments() override;
-    void compile() override;
-    void compile_and_run() override;
-    
-    std::string get_language_id() override { return "rust"; }
-  };
-  
-  std::shared_ptr<Base> create();
-  extern std::shared_ptr<Base> current;
+    };
+
+    class LanguageProtocol : public virtual Base {
+    public:
+        LanguageProtocol() {}
+
+        virtual std::string get_language_id()=0;
+
+        void show_symbols() override;
+    };
+
+    class Clang : public LLDB {
+    public:
+        Clang(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+
+        std::pair<std::string, std::string> get_run_arguments() override;
+
+        void compile() override;
+
+        void compile_and_run() override;
+
+        void recreate_build() override;
+    };
+
+    class Markdown : public Base {
+    public:
+        Markdown(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+
+        ~Markdown();
+
+        boost::filesystem::path last_temp_path;
+
+        void compile_and_run() override;
+    };
+
+    class Python : public LanguageProtocol {
+    public:
+        Python(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+
+        void compile_and_run() override;
+
+        std::string get_language_id() override { return "python"; }
+    };
+
+    class JavaScript : public LanguageProtocol {
+    public:
+        JavaScript(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+
+        void compile_and_run() override;
+
+        std::string get_language_id() override { return "javascript"; }
+    };
+
+    class HTML : public Base {
+    public:
+        HTML(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+
+        void compile_and_run() override;
+    };
+
+    class Rust : public LLDB, public LanguageProtocol {
+    public:
+        Rust(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+
+        std::pair<std::string, std::string> get_run_arguments() override;
+
+        void compile() override;
+
+        void compile_and_run() override;
+
+        std::string get_language_id() override { return "rust"; }
+    };
+
+    std::shared_ptr<Base> create();
+
+    extern std::shared_ptr<Base> current;
 };
diff --git a/src/project_build.cc b/src/project_build.cc
index 5f313b3f..b756f592 100644
--- a/src/project_build.cc
+++ b/src/project_build.cc
@@ -3,136 +3,136 @@
 #include "filesystem.h"
 
 std::unique_ptr<Project::Build> Project::Build::create(const boost::filesystem::path &path) {
-  auto search_path=boost::filesystem::is_directory(path)?path:path.parent_path();
-  
-  while(true) {
-    if(boost::filesystem::exists(search_path/"CMakeLists.txt")) {
-      std::unique_ptr<Project::Build> build(new CMakeBuild(path));
-      if(!build->project_path.empty())
-        return build;
-      else
-        return std::make_unique<Project::Build>();
-    }
-    
-    if(boost::filesystem::exists(search_path/"meson.build")) {
-      std::unique_ptr<Project::Build> build(new MesonBuild(path));
-      if(!build->project_path.empty())
-        return build;
-    }
-    
-    if(boost::filesystem::exists(search_path/"Cargo.toml")) {
-      std::unique_ptr<Project::Build> build(new CargoBuild());
-      build->project_path=search_path;
-      return build;
-    }
-    
-    if(boost::filesystem::exists(search_path/"package.json")) {
-      std::unique_ptr<Project::Build> build(new NpmBuild());
-      build->project_path=search_path;
-      return build;
+    auto search_path = boost::filesystem::is_directory(path) ? path : path.parent_path();
+
+    while (true) {
+        if (boost::filesystem::exists(search_path / "CMakeLists.txt")) {
+            std::unique_ptr<Project::Build> build(new CMakeBuild(path));
+            if (!build->project_path.empty())
+                return build;
+            else
+                return std::make_unique<Project::Build>();
+        }
+
+        if (boost::filesystem::exists(search_path / "meson.build")) {
+            std::unique_ptr<Project::Build> build(new MesonBuild(path));
+            if (!build->project_path.empty())
+                return build;
+        }
+
+        if (boost::filesystem::exists(search_path / "Cargo.toml")) {
+            std::unique_ptr<Project::Build> build(new CargoBuild());
+            build->project_path = search_path;
+            return build;
+        }
+
+        if (boost::filesystem::exists(search_path / "package.json")) {
+            std::unique_ptr<Project::Build> build(new NpmBuild());
+            build->project_path = search_path;
+            return build;
+        }
+
+        if (search_path == search_path.root_directory())
+            break;
+        search_path = search_path.parent_path();
     }
-    
-    if(search_path==search_path.root_directory())
-      break;
-    search_path=search_path.parent_path();
-  }
-  
-  return std::make_unique<Project::Build>();
+
+    return std::make_unique<Project::Build>();
 }
 
 boost::filesystem::path Project::Build::get_default_path() {
-  if(project_path.empty())
-    return boost::filesystem::path();
-    
-  boost::filesystem::path default_build_path=Config::get().project.default_build_path;
-  
-  const std::string path_variable_project_directory_name="<project_directory_name>";
-  size_t pos=0;
-  auto default_build_path_string=default_build_path.string();
-  auto path_filename_string=project_path.filename().string();
-  while((pos=default_build_path_string.find(path_variable_project_directory_name, pos))!=std::string::npos) {
-    default_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
-    pos+=path_filename_string.size();
-  }
-  if(pos!=0)
-    default_build_path=default_build_path_string;
-  
-  if(default_build_path.is_relative())
-    default_build_path=project_path/default_build_path;
-  
-  return filesystem::get_normal_path(default_build_path);
+    if (project_path.empty())
+        return boost::filesystem::path();
+
+    boost::filesystem::path default_build_path = Config::get().project.default_build_path;
+
+    const std::string path_variable_project_directory_name = "<project_directory_name>";
+    size_t pos = 0;
+    auto default_build_path_string = default_build_path.string();
+    auto path_filename_string = project_path.filename().string();
+    while ((pos = default_build_path_string.find(path_variable_project_directory_name, pos)) != std::string::npos) {
+        default_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
+        pos += path_filename_string.size();
+    }
+    if (pos != 0)
+        default_build_path = default_build_path_string;
+
+    if (default_build_path.is_relative())
+        default_build_path = project_path / default_build_path;
+
+    return filesystem::get_normal_path(default_build_path);
 }
 
 boost::filesystem::path Project::Build::get_debug_path() {
-  if(project_path.empty())
-    return boost::filesystem::path();
-  
-  boost::filesystem::path debug_build_path=Config::get().project.debug_build_path;
-  
-  const std::string path_variable_project_directory_name="<project_directory_name>";
-  size_t pos=0;
-  auto debug_build_path_string=debug_build_path.string();
-  auto path_filename_string=project_path.filename().string();
-  while((pos=debug_build_path_string.find(path_variable_project_directory_name, pos))!=std::string::npos) {
-    debug_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
-    pos+=path_filename_string.size();
-  }
-  if(pos!=0)
-    debug_build_path=debug_build_path_string;
-  
-  const std::string path_variable_default_build_path="<default_build_path>";
-  pos=0;
-  debug_build_path_string=debug_build_path.string();
-  auto default_build_path=Config::get().project.default_build_path;
-  while((pos=debug_build_path_string.find(path_variable_default_build_path, pos))!=std::string::npos) {
-    debug_build_path_string.replace(pos, path_variable_default_build_path.size(), default_build_path);
-    pos+=default_build_path.size();
-  }
-  if(pos!=0)
-    debug_build_path=debug_build_path_string;
-  
-  if(debug_build_path.is_relative())
-    debug_build_path=project_path/debug_build_path;
-  
-  return filesystem::get_normal_path(debug_build_path);
+    if (project_path.empty())
+        return boost::filesystem::path();
+
+    boost::filesystem::path debug_build_path = Config::get().project.debug_build_path;
+
+    const std::string path_variable_project_directory_name = "<project_directory_name>";
+    size_t pos = 0;
+    auto debug_build_path_string = debug_build_path.string();
+    auto path_filename_string = project_path.filename().string();
+    while ((pos = debug_build_path_string.find(path_variable_project_directory_name, pos)) != std::string::npos) {
+        debug_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
+        pos += path_filename_string.size();
+    }
+    if (pos != 0)
+        debug_build_path = debug_build_path_string;
+
+    const std::string path_variable_default_build_path = "<default_build_path>";
+    pos = 0;
+    debug_build_path_string = debug_build_path.string();
+    auto default_build_path = Config::get().project.default_build_path;
+    while ((pos = debug_build_path_string.find(path_variable_default_build_path, pos)) != std::string::npos) {
+        debug_build_path_string.replace(pos, path_variable_default_build_path.size(), default_build_path);
+        pos += default_build_path.size();
+    }
+    if (pos != 0)
+        debug_build_path = debug_build_path_string;
+
+    if (debug_build_path.is_relative())
+        debug_build_path = project_path / debug_build_path;
+
+    return filesystem::get_normal_path(debug_build_path);
 }
 
 Project::CMakeBuild::CMakeBuild(const boost::filesystem::path &path) : Project::Build(), cmake(path) {
-  project_path=cmake.project_path;
+    project_path = cmake.project_path;
 }
 
 bool Project::CMakeBuild::update_default(bool force) {
-  return cmake.update_default_build(get_default_path(), force);
+    return cmake.update_default_build(get_default_path(), force);
 }
 
 bool Project::CMakeBuild::update_debug(bool force) {
-  return cmake.update_debug_build(get_debug_path(), force);
+    return cmake.update_debug_build(get_debug_path(), force);
 }
 
 std::string Project::CMakeBuild::get_compile_command() {
-  return Config::get().project.cmake.compile_command;
+    return Config::get().project.cmake.compile_command;
 }
 
 boost::filesystem::path Project::CMakeBuild::get_executable(const boost::filesystem::path &path) {
-  return cmake.get_executable(get_default_path(), path).string();
+    return cmake.get_executable(get_default_path(), path).string();
 }
 
 Project::MesonBuild::MesonBuild(const boost::filesystem::path &path) : Project::Build(), meson(path) {
-  project_path=meson.project_path;
+    project_path = meson.project_path;
 }
 
 bool Project::MesonBuild::update_default(bool force) {
-  return meson.update_default_build(get_default_path(), force);
+    return meson.update_default_build(get_default_path(), force);
 }
 
 bool Project::MesonBuild::update_debug(bool force) {
-  return meson.update_debug_build(get_debug_path(), force);
+    return meson.update_debug_build(get_debug_path(), force);
 }
 
 std::string Project::MesonBuild::get_compile_command() {
-  return Config::get().project.meson.compile_command;
+    return Config::get().project.meson.compile_command;
 }
 
 boost::filesystem::path Project::MesonBuild::get_executable(const boost::filesystem::path &path) {
-  return meson.get_executable(get_default_path(), path);
+    return meson.get_executable(get_default_path(), path);
 }
diff --git a/src/project_build.h b/src/project_build.h
index d2128db8..0900a851 100644
--- a/src/project_build.h
+++ b/src/project_build.h
@@ -1,61 +1,79 @@
 #pragma once
+
 #include <boost/filesystem.hpp>
-#include "cmake.h"
-#include "meson.h"
+#include "buildsystem/cmake.h"
+#include "buildsystem/meson.h"
 
 namespace Project {
-  class Build {
-  public:
-    Build() {}
-    virtual ~Build() {}
-    
-    boost::filesystem::path project_path;
-    
-    virtual boost::filesystem::path get_default_path();
-    virtual bool update_default(bool force=false) {return false;}
-    virtual boost::filesystem::path get_debug_path();
-    virtual bool update_debug(bool force=false) {return false;}
-    
-    virtual std::string get_compile_command() { return std::string(); }
-    virtual boost::filesystem::path get_executable(const boost::filesystem::path &path) {return boost::filesystem::path();}
-    
-    static std::unique_ptr<Build> create(const boost::filesystem::path &path);
-  };
-  
-  class CMakeBuild : public Build {
-    ::CMake cmake;
-  public:
-    CMakeBuild(const boost::filesystem::path &path);
-    
-    bool update_default(bool force=false) override;
-    bool update_debug(bool force=false) override;
-    
-    std::string get_compile_command() override;
-    boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
-  };
-  
-  class MesonBuild : public Build {
-    Meson meson;
-  public:
-    MesonBuild(const boost::filesystem::path &path);
-    
-    bool update_default(bool force=false) override;
-    bool update_debug(bool force=false) override;
-    
-    std::string get_compile_command() override;
-    boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
-  };
-
-  class CargoBuild : public Build {
-  public:
-    boost::filesystem::path get_default_path() override { return project_path/"target"/"debug"; }
-    bool update_default(bool force=false) override { return true; }
-    boost::filesystem::path get_debug_path() override { return get_default_path(); }
-    bool update_debug(bool force=false) override { return true; }
-    
-    std::string get_compile_command() override { return "cargo build"; }
-    boost::filesystem::path get_executable(const boost::filesystem::path &path) override { return get_debug_path()/project_path.filename(); }
-  };
-
-  class NpmBuild : public Build {};
+    class Build {
+    public:
+        Build() {}
+
+        virtual ~Build() {}
+
+        boost::filesystem::path project_path;
+
+        virtual boost::filesystem::path get_default_path();
+
+        virtual bool update_default(bool force = false) { return false; }
+
+        virtual boost::filesystem::path get_debug_path();
+
+        virtual bool update_debug(bool force = false) { return false; }
+
+        virtual std::string get_compile_command() { return std::string(); }
+
+        virtual boost::filesystem::path
+        get_executable(const boost::filesystem::path &path) { return boost::filesystem::path(); }
+
+        static std::unique_ptr<Build> create(const boost::filesystem::path &path);
+    };
+
+    class CMakeBuild : public Build {
+        ::CMake cmake;
+    public:
+        CMakeBuild(const boost::filesystem::path &path);
+
+        bool update_default(bool force = false) override;
+
+        bool update_debug(bool force = false) override;
+
+        std::string get_compile_command() override;
+
+        boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
+    };
+
+    class MesonBuild : public Build {
+        Meson meson;
+    public:
+        MesonBuild(const boost::filesystem::path &path);
+
+        bool update_default(bool force = false) override;
+
+        bool update_debug(bool force = false) override;
+
+        std::string get_compile_command() override;
+
+        boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
+    };
+
+    class CargoBuild : public Build {
+    public:
+        boost::filesystem::path get_default_path() override { return project_path / "target" / "debug"; }
+
+        bool update_default(bool force = false) override { return true; }
+
+        boost::filesystem::path get_debug_path() override { return get_default_path(); }
+
+        bool update_debug(bool force = false) override { return true; }
+
+        std::string get_compile_command() override { return "cargo build"; }
+
+        boost::filesystem::path get_executable(const boost::filesystem::path &path) override {
+            return get_debug_path() / project_path.filename();
+        }
+    };
+
+    class NpmBuild : public Build {
+    };
 }
diff --git a/src/selection_dialog.cc b/src/selection_dialog.cc
index 38535d66..5b0461c3 100644
--- a/src/selection_dialog.cc
+++ b/src/selection_dialog.cc
@@ -2,451 +2,471 @@
 #include <algorithm>
 
 SelectionDialogBase::ListViewText::ListViewText(bool use_markup) : Gtk::TreeView(), use_markup(use_markup) {
-  list_store = Gtk::ListStore::create(column_record);
-  set_model(list_store);
-  append_column("", cell_renderer);
-  if(use_markup)
-    get_column(0)->add_attribute(cell_renderer.property_markup(), column_record.text);
-  else
-    get_column(0)->add_attribute(cell_renderer.property_text(), column_record.text);
-  
-  get_selection()->set_mode(Gtk::SelectionMode::SELECTION_BROWSE);
-  set_enable_search(true);
-  set_headers_visible(false);
-  set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL);
-  set_activate_on_single_click(true);
-  set_hover_selection(false);
-  set_rules_hint(true);
+    list_store = Gtk::ListStore::create(column_record);
+    set_model(list_store);
+    append_column("", cell_renderer);
+    if (use_markup)
+        get_column(0)->add_attribute(cell_renderer.property_markup(), column_record.text);
+    else
+        get_column(0)->add_attribute(cell_renderer.property_text(), column_record.text);
+
+    get_selection()->set_mode(Gtk::SelectionMode::SELECTION_BROWSE);
+    set_enable_search(true);
+    set_headers_visible(false);
+    set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL);
+    set_activate_on_single_click(true);
+    set_hover_selection(false);
+    set_rules_hint(true);
 }
 
-void SelectionDialogBase::ListViewText::append(const std::string& value) {
-  auto new_row=list_store->append();
-  new_row->set_value(column_record.text, value);
-  new_row->set_value(column_record.index, size++);
+void SelectionDialogBase::ListViewText::append(const std::string &value) {
+    auto new_row = list_store->append();
+    new_row->set_value(column_record.text, value);
+    new_row->set_value(column_record.index, size++);
 }
 
 void SelectionDialogBase::ListViewText::erase_rows() {
-  list_store->clear();
-  size=0;
+    list_store->clear();
+    size = 0;
 }
 
 void SelectionDialogBase::ListViewText::clear() {
-  unset_model();
-  list_store.reset();
-  size=0;
+    unset_model();
+    list_store.reset();
+    size = 0;
 }
 
-SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry, bool use_markup):
-    start_mark(start_mark), text_view(text_view), window(Gtk::WindowType::WINDOW_POPUP), vbox(Gtk::Orientation::ORIENTATION_VERTICAL), list_view_text(use_markup), show_search_entry(show_search_entry) {
-  auto g_application=g_application_get_default();
-  auto gio_application=Glib::wrap(g_application, true);
-  auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-  window.set_transient_for(*application->get_active_window());
-  
-  window.set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_COMBO);
-  
-  search_entry.signal_changed().connect([this] {
-    if(on_search_entry_changed)
-      on_search_entry_changed(search_entry.get_text());
-  }, false);
-  
-  list_view_text.set_search_entry(search_entry);
-  
-  window.set_default_size(0, 0);
-  window.property_decorated()=false;
-  window.set_skip_taskbar_hint(true);
-  
-  scrolled_window.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC);
-
-  scrolled_window.add(list_view_text);
-  if(show_search_entry)
-    vbox.pack_start(search_entry, false, false);
-  vbox.pack_start(scrolled_window, true, true);
-  window.add(vbox);
-
-  list_view_text.signal_realize().connect([this](){
-    auto g_application=g_application_get_default();
-    auto gio_application=Glib::wrap(g_application, true);
-    auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-    auto application_window=application->get_active_window();
-    
-    int row_width=0, row_height;
-    Gdk::Rectangle rect;
-    list_view_text.get_cell_area(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()), *(list_view_text.get_column(0)), rect);
-    row_width=rect.get_width();
-    row_height=rect.get_height();
-    
-    row_width+=rect.get_x()*2; //TODO: Add correct margin x and y
-    row_height+=rect.get_y()*2;
-    
-    if(this->text_view && row_width>this->text_view->get_width()*2/3)
-      row_width=this->text_view->get_width()*2/3;
-    else if(row_width>application_window->get_width()/2)
-      row_width=application_window->get_width()/2;
-    else
-      scrolled_window.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC);
-    
-    int window_height=std::min(row_height*static_cast<int>(list_view_text.get_model()->children().size()), row_height*10);
-    if(this->show_search_entry)
-      window_height+=search_entry.get_height();
-    int window_width=row_width+1;
-    window.resize(window_width, window_height);
-    
-    if(this->text_view) {
-      Gdk::Rectangle iter_rect;
-      this->text_view->get_iter_location(this->start_mark->get_iter(), iter_rect);
-      Gdk::Rectangle visible_rect;
-      this->text_view->get_visible_rect(visible_rect);
-      int buffer_x=std::max(iter_rect.get_x(), visible_rect.get_x());
-      int buffer_y=iter_rect.get_y()+iter_rect.get_height();
-      int window_x, window_y;
-      this->text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, buffer_x, buffer_y, window_x, window_y);
-      int root_x, root_y;
-      this->text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y, root_x, root_y);
-      window.move(root_x, root_y+1); //TODO: replace 1 with some margin
-    }
-    else {
-      int root_x, root_y;
-      application_window->get_position(root_x, root_y);
-      root_x+=application_window->get_width()/2-window_width/2;
-      root_y+=application_window->get_height()/2-window_height/2;
-      window.move(root_x, root_y);
-    }
-  });
-  
-  list_view_text.signal_cursor_changed().connect([this] {
-    cursor_changed();
-  });
+SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark,
+                                         bool show_search_entry, bool use_markup) :
+        start_mark(start_mark), text_view(text_view), window(Gtk::WindowType::WINDOW_POPUP),
+        vbox(Gtk::Orientation::ORIENTATION_VERTICAL), list_view_text(use_markup), show_search_entry(show_search_entry) {
+    auto g_application = g_application_get_default();
+    auto gio_application = Glib::wrap(g_application, true);
+    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+    window.set_transient_for(*application->get_active_window());
+
+    window.set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_COMBO);
+
+    search_entry.signal_changed().connect([this] {
+        if (on_search_entry_changed)
+            on_search_entry_changed(search_entry.get_text());
+    }, false);
+
+    list_view_text.set_search_entry(search_entry);
+
+    window.set_default_size(0, 0);
+    window.property_decorated() = false;
+    window.set_skip_taskbar_hint(true);
+
+    scrolled_window.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC);
+
+    scrolled_window.add(list_view_text);
+    if (show_search_entry)
+        vbox.pack_start(search_entry, false, false);
+    vbox.pack_start(scrolled_window, true, true);
+    window.add(vbox);
+
+    list_view_text.signal_realize().connect([this]() {
+        auto g_application = g_application_get_default();
+        auto gio_application = Glib::wrap(g_application, true);
+        auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+        auto application_window = application->get_active_window();
+
+        int row_width = 0, row_height;
+        Gdk::Rectangle rect;
+        list_view_text.get_cell_area(
+                list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()),
+                *(list_view_text.get_column(0)), rect);
+        row_width = rect.get_width();
+        row_height = rect.get_height();
+
+        row_width += rect.get_x() * 2; //TODO: Add correct margin x and y
+        row_height += rect.get_y() * 2;
+
+        if (this->text_view && row_width > this->text_view->get_width() * 2 / 3)
+            row_width = this->text_view->get_width() * 2 / 3;
+        else if (row_width > application_window->get_width() / 2)
+            row_width = application_window->get_width() / 2;
+        else
+            scrolled_window.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC);
+
+        int window_height = std::min(row_height * static_cast<int>(list_view_text.get_model()->children().size()),
+                                     row_height * 10);
+        if (this->show_search_entry)
+            window_height += search_entry.get_height();
+        int window_width = row_width + 1;
+        window.resize(window_width, window_height);
+
+        if (this->text_view) {
+            Gdk::Rectangle iter_rect;
+            this->text_view->get_iter_location(this->start_mark->get_iter(), iter_rect);
+            Gdk::Rectangle visible_rect;
+            this->text_view->get_visible_rect(visible_rect);
+            int buffer_x = std::max(iter_rect.get_x(), visible_rect.get_x());
+            int buffer_y = iter_rect.get_y() + iter_rect.get_height();
+            int window_x, window_y;
+            this->text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, buffer_x, buffer_y,
+                                                     window_x, window_y);
+            int root_x, root_y;
+            this->text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y,
+                                                                                                root_x, root_y);
+            window.move(root_x, root_y + 1); //TODO: replace 1 with some margin
+        } else {
+            int root_x, root_y;
+            application_window->get_position(root_x, root_y);
+            root_x += application_window->get_width() / 2 - window_width / 2;
+            root_y += application_window->get_height() / 2 - window_height / 2;
+            window.move(root_x, root_y);
+        }
+    });
+
+    list_view_text.signal_cursor_changed().connect([this] {
+        cursor_changed();
+    });
 }
 
 SelectionDialogBase::~SelectionDialogBase() {
-  if(text_view)
-    text_view->get_buffer()->delete_mark(start_mark);
+    if (text_view)
+        text_view->get_buffer()->delete_mark(start_mark);
 }
 
 void SelectionDialogBase::cursor_changed() {
-  if(!is_visible())
-    return;
-  auto it=list_view_text.get_selection()->get_selected();
-  unsigned int index=static_cast<unsigned int>(-1);
-  if(it)
-    index=it->get_value(list_view_text.column_record.index);
-  if(last_index==index)
-    return;
-  if(on_changed) {
-    std::string text;
-    if(it)
-      text=it->get_value(list_view_text.column_record.text);
-    on_changed(index, text);
-  }
-  last_index=index;
+    if (!is_visible())
+        return;
+    auto it = list_view_text.get_selection()->get_selected();
+    unsigned int index = static_cast<unsigned int>(-1);
+    if (it)
+        index = it->get_value(list_view_text.column_record.index);
+    if (last_index == index)
+        return;
+    if (on_changed) {
+        std::string text;
+        if (it)
+            text = it->get_value(list_view_text.column_record.text);
+        on_changed(index, text);
+    }
+    last_index = index;
 }
-void SelectionDialogBase::add_row(const std::string& row) {
-  list_view_text.append(row);
+
+void SelectionDialogBase::add_row(const std::string &row) {
+    list_view_text.append(row);
 }
 
 void SelectionDialogBase::erase_rows() {
-  list_view_text.erase_rows();
+    list_view_text.erase_rows();
 }
 
 void SelectionDialogBase::show() {
-  window.show_all();
-  if(text_view)
-    text_view->grab_focus();
-  
-  if(list_view_text.get_model()->children().size()>0) {
-    if(!list_view_text.get_selection()->get_selected()) {
-      list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
-      cursor_changed();
-    }
-    else if(list_view_text.get_model()->children().begin()!=list_view_text.get_selection()->get_selected()) {
-      while(Gtk::Main::events_pending())
-        Gtk::Main::iteration(false);
-      if(is_visible())
-        list_view_text.scroll_to_row(list_view_text.get_model()->get_path(list_view_text.get_selection()->get_selected()), 0.5);
+    window.show_all();
+    if (text_view)
+        text_view->grab_focus();
+
+    if (list_view_text.get_model()->children().size() > 0) {
+        if (!list_view_text.get_selection()->get_selected()) {
+            list_view_text.set_cursor(
+                    list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
+            cursor_changed();
+        } else if (list_view_text.get_model()->children().begin() != list_view_text.get_selection()->get_selected()) {
+            while (Gtk::Main::events_pending())
+                Gtk::Main::iteration(false);
+            if (is_visible())
+                list_view_text.scroll_to_row(
+                        list_view_text.get_model()->get_path(list_view_text.get_selection()->get_selected()), 0.5);
+        }
     }
-  }
-  if(on_show)
-    on_show();
+    if (on_show)
+        on_show();
 }
 
 void SelectionDialogBase::set_cursor_at_last_row() {
-  auto children=list_view_text.get_model()->children();
-  if(children.size()>0) {
-    list_view_text.set_cursor(list_view_text.get_model()->get_path(children[children.size()-1]));
-    cursor_changed();
-  }
+    auto children = list_view_text.get_model()->children();
+    if (children.size() > 0) {
+        list_view_text.set_cursor(list_view_text.get_model()->get_path(children[children.size() - 1]));
+        cursor_changed();
+    }
 }
 
 void SelectionDialogBase::hide() {
-  if(!is_visible())
-    return;
-  window.hide();
-  if(on_hide)
-    on_hide();
-  list_view_text.clear();
-  last_index=static_cast<unsigned int>(-1);
+    if (!is_visible())
+        return;
+    window.hide();
+    if (on_hide)
+        on_hide();
+    list_view_text.clear();
+    last_index = static_cast<unsigned int>(-1);
 }
 
 std::unique_ptr<SelectionDialog> SelectionDialog::instance;
 
-SelectionDialog::SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry, bool use_markup) : SelectionDialogBase(text_view, start_mark, show_search_entry, use_markup) {
-  auto search_key=std::make_shared<std::string>();
-  auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model());
-  
-  filter_model->set_visible_func([this, search_key](const Gtk::TreeModel::const_iterator& iter){
-    std::string row_lc;
-    iter->get_value(0, row_lc);
-    auto search_key_lc=*search_key;
-    std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower);
-    std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower);
-    if(list_view_text.use_markup) {
-      size_t pos=0;
-      while((pos=row_lc.find('<', pos))!=std::string::npos) {
-        auto pos2=row_lc.find('>', pos+1);
-        row_lc.erase(pos, pos2-pos+1);
-      }
-      search_key_lc=Glib::Markup::escape_text(search_key_lc);
-    }
-    if(row_lc.find(search_key_lc)!=std::string::npos)
-      return true;
-    return false;
-  });
-  
-  list_view_text.set_model(filter_model);
-  
-  list_view_text.set_search_equal_func([](const Glib::RefPtr<Gtk::TreeModel>& model, int column, const Glib::ustring& key, const Gtk::TreeModel::iterator& iter) {
-    return false;
-  });
-  
-  search_entry.signal_changed().connect([this, search_key, filter_model](){
-    *search_key=search_entry.get_text();
-    filter_model->refilter();
-    list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug)
-    if(search_key->empty()) {
-      if(list_view_text.get_model()->children().size()>0)
-        list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
-    }
-  });
-  
-  auto activate=[this](){
-    auto it=list_view_text.get_selection()->get_selected();
-    if(on_select && it) {
-      auto index=it->get_value(list_view_text.column_record.index);
-      auto text=it->get_value(list_view_text.column_record.text);
-      on_select(index, text, true);
-    }
-    hide();
-  };
-  search_entry.signal_activate().connect([activate](){
-    activate();
-  });
-  list_view_text.signal_row_activated().connect([activate](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*) {
-    activate();
-  });
+SelectionDialog::SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark,
+                                 bool show_search_entry, bool use_markup) : SelectionDialogBase(text_view, start_mark,
+                                                                                                show_search_entry,
+                                                                                                use_markup) {
+    auto search_key = std::make_shared<std::string>();
+    auto filter_model = Gtk::TreeModelFilter::create(list_view_text.get_model());
+
+    filter_model->set_visible_func([this, search_key](const Gtk::TreeModel::const_iterator &iter) {
+        std::string row_lc;
+        iter->get_value(0, row_lc);
+        auto search_key_lc = *search_key;
+        std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower);
+        std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower);
+        if (list_view_text.use_markup) {
+            size_t pos = 0;
+            while ((pos = row_lc.find('<', pos)) != std::string::npos) {
+                auto pos2 = row_lc.find('>', pos + 1);
+                row_lc.erase(pos, pos2 - pos + 1);
+            }
+            search_key_lc = Glib::Markup::escape_text(search_key_lc);
+        }
+        if (row_lc.find(search_key_lc) != std::string::npos)
+            return true;
+        return false;
+    });
+
+    list_view_text.set_model(filter_model);
+
+    list_view_text.set_search_equal_func(
+            [](const Glib::RefPtr<Gtk::TreeModel> &model, int column, const Glib::ustring &key,
+               const Gtk::TreeModel::iterator &iter) {
+                return false;
+            });
+
+    search_entry.signal_changed().connect([this, search_key, filter_model]() {
+        *search_key = search_entry.get_text();
+        filter_model->refilter();
+        list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug)
+        if (search_key->empty()) {
+            if (list_view_text.get_model()->children().size() > 0)
+                list_view_text.set_cursor(
+                        list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
+        }
+    });
+
+    auto activate = [this]() {
+        auto it = list_view_text.get_selection()->get_selected();
+        if (on_select && it) {
+            auto index = it->get_value(list_view_text.column_record.index);
+            auto text = it->get_value(list_view_text.column_record.text);
+            on_select(index, text, true);
+        }
+        hide();
+    };
+    search_entry.signal_activate().connect([activate]() {
+        activate();
+    });
+    list_view_text.signal_row_activated().connect([activate](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *) {
+        activate();
+    });
 }
 
-bool SelectionDialog::on_key_press(GdkEventKey* key) {
-  if((key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down) && list_view_text.get_model()->children().size()>0) {
-    auto it=list_view_text.get_selection()->get_selected();
-    if(it) {
-      it++;
-      if(it)
-        list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
-    }
-    return true;
-  }
-  else if((key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up) && list_view_text.get_model()->children().size()>0) {
-    auto it=list_view_text.get_selection()->get_selected();
-    if(it) {
-      it--;
-      if(it)
-        list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
-    }
-    return true;
-  }
-  else if(key->keyval==GDK_KEY_Return || key-> keyval==GDK_KEY_KP_Enter || key->keyval==GDK_KEY_ISO_Left_Tab || key->keyval==GDK_KEY_Tab) {
-    auto it=list_view_text.get_selection()->get_selected();
-    auto column=list_view_text.get_column(0);
-    list_view_text.row_activated(list_view_text.get_model()->get_path(it), *column);
-    return true;
-  }
-  else if(key->keyval==GDK_KEY_Escape) {
-    hide();
-    return true;
-  }
-  else if(key->keyval==GDK_KEY_Left || key->keyval==GDK_KEY_KP_Left || key->keyval==GDK_KEY_Right || key->keyval==GDK_KEY_KP_Right) {
-    hide();
-    return false;
-  }
-  else if(show_search_entry) {
-#ifdef __APPLE__ //OS X bug most likely: Gtk::Entry will not work if window is of type POPUP
-    int search_entry_length=search_entry.get_text_length();
-    if(key->keyval==GDK_KEY_dead_tilde) {
-      search_entry.insert_text("~", 1, search_entry_length);
-      return true;
-    }
-    else if(key->keyval==GDK_KEY_dead_circumflex) {
-      search_entry.insert_text("^", 1, search_entry_length);
-      return true;
-    }
-    else if(key->is_modifier)
-      return true;
-    else if(key->keyval==GDK_KEY_BackSpace) {
-      auto length=search_entry.get_text_length();
-      if(length>0)
-        search_entry.delete_text(length-1, length);
-      return true;
-    }
-    else {
-      gunichar unicode=gdk_keyval_to_unicode(key->keyval);
-      if(unicode>=32 && unicode!=126) {
-        auto ustr=Glib::ustring(1, unicode);
-        search_entry.insert_text(ustr, ustr.bytes(), search_entry_length);
+bool SelectionDialog::on_key_press(GdkEventKey *key) {
+    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
+        list_view_text.get_model()->children().size() > 0) {
+        auto it = list_view_text.get_selection()->get_selected();
+        if (it) {
+            it++;
+            if (it)
+                list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
+        }
         return true;
-      }
-    }
+    } else if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
+               list_view_text.get_model()->children().size() > 0) {
+        auto it = list_view_text.get_selection()->get_selected();
+        if (it) {
+            it--;
+            if (it)
+                list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
+        }
+        return true;
+    } else if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter ||
+               key->keyval == GDK_KEY_ISO_Left_Tab || key->keyval == GDK_KEY_Tab) {
+        auto it = list_view_text.get_selection()->get_selected();
+        auto column = list_view_text.get_column(0);
+        list_view_text.row_activated(list_view_text.get_model()->get_path(it), *column);
+        return true;
+    } else if (key->keyval == GDK_KEY_Escape) {
+        hide();
+        return true;
+    } else if (key->keyval == GDK_KEY_Left || key->keyval == GDK_KEY_KP_Left || key->keyval == GDK_KEY_Right ||
+               key->keyval == GDK_KEY_KP_Right) {
+        hide();
+        return false;
+    } else if (show_search_entry) {
+#ifdef __APPLE__ //OS X bug most likely: Gtk::Entry will not work if window is of type POPUP
+        int search_entry_length=search_entry.get_text_length();
+        if(key->keyval==GDK_KEY_dead_tilde) {
+          search_entry.insert_text("~", 1, search_entry_length);
+          return true;
+        }
+        else if(key->keyval==GDK_KEY_dead_circumflex) {
+          search_entry.insert_text("^", 1, search_entry_length);
+          return true;
+        }
+        else if(key->is_modifier)
+          return true;
+        else if(key->keyval==GDK_KEY_BackSpace) {
+          auto length=search_entry.get_text_length();
+          if(length>0)
+            search_entry.delete_text(length-1, length);
+          return true;
+        }
+        else {
+          gunichar unicode=gdk_keyval_to_unicode(key->keyval);
+          if(unicode>=32 && unicode!=126) {
+            auto ustr=Glib::ustring(1, unicode);
+            search_entry.insert_text(ustr, ustr.bytes(), search_entry_length);
+            return true;
+          }
+        }
 #else
-    search_entry.on_key_press_event(key);
-    return true;
+        search_entry.on_key_press_event(key);
+        return true;
 #endif
-  }
-  hide();
-  return false;
+    }
+    hide();
+    return false;
 }
 
 std::unique_ptr<CompletionDialog> CompletionDialog::instance;
 
-CompletionDialog::CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark) : SelectionDialogBase(text_view, start_mark, false, false) {
-  show_offset=text_view->get_buffer()->get_insert()->get_iter().get_offset();
-  
-  auto search_key=std::make_shared<std::string>();
-  auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model());  
-  if(show_offset==start_mark->get_iter().get_offset()) {
-    filter_model->set_visible_func([search_key](const Gtk::TreeModel::const_iterator& iter){
-      std::string row_lc;
-      iter->get_value(0, row_lc);
-      auto search_key_lc=*search_key;
-      std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower);
-      std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower);
-      if(row_lc.find(search_key_lc)!=std::string::npos)
-        return true;
-      return false;
+CompletionDialog::CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark)
+        : SelectionDialogBase(text_view, start_mark, false, false) {
+    show_offset = text_view->get_buffer()->get_insert()->get_iter().get_offset();
+
+    auto search_key = std::make_shared<std::string>();
+    auto filter_model = Gtk::TreeModelFilter::create(list_view_text.get_model());
+    if (show_offset == start_mark->get_iter().get_offset()) {
+        filter_model->set_visible_func([search_key](const Gtk::TreeModel::const_iterator &iter) {
+            std::string row_lc;
+            iter->get_value(0, row_lc);
+            auto search_key_lc = *search_key;
+            std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower);
+            std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower);
+            if (row_lc.find(search_key_lc) != std::string::npos)
+                return true;
+            return false;
+        });
+    } else {
+        filter_model->set_visible_func([search_key](const Gtk::TreeModel::const_iterator &iter) {
+            std::string row;
+            iter->get_value(0, row);
+            if (row.find(*search_key) == 0)
+                return true;
+            return false;
+        });
+    }
+    list_view_text.set_model(filter_model);
+    search_entry.signal_changed().connect([this, search_key, filter_model]() {
+        *search_key = search_entry.get_text();
+        filter_model->refilter();
+        list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug)
     });
-  }
-  else {
-    filter_model->set_visible_func([search_key](const Gtk::TreeModel::const_iterator& iter){
-      std::string row;
-      iter->get_value(0, row);
-      if(row.find(*search_key)==0)
-        return true;
-      return false;
+
+    list_view_text.signal_row_activated().connect([this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *) {
+        select();
     });
-  }
-  list_view_text.set_model(filter_model);
-  search_entry.signal_changed().connect([this, search_key, filter_model](){
-    *search_key=search_entry.get_text();
-    filter_model->refilter();
-    list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug)
-  });
-  
-  list_view_text.signal_row_activated().connect([this](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*) {
-    select();
-  });
-  
-  auto text=text_view->get_buffer()->get_text(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter());
-  if(text.size()>0) {
-    search_entry.set_text(text);
-    list_view_text.set_search_entry(search_entry);
-  }
+
+    auto text = text_view->get_buffer()->get_text(start_mark->get_iter(),
+                                                  text_view->get_buffer()->get_insert()->get_iter());
+    if (text.size() > 0) {
+        search_entry.set_text(text);
+        list_view_text.set_search_entry(search_entry);
+    }
 }
 
 void CompletionDialog::select(bool hide_window) {
-  row_in_entry=true;
-  
-  auto it=list_view_text.get_selection()->get_selected();
-  if(on_select && it) {
-    auto index=it->get_value(list_view_text.column_record.index);
-    auto text=it->get_value(list_view_text.column_record.text);
-    on_select(index, text, hide_window);
-  }
-  if(hide_window)
-    hide();
-}
+    row_in_entry = true;
 
-bool CompletionDialog::on_key_release(GdkEventKey* key) {
-  if(key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down || key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up)
-    return false;
-    
-  if(show_offset>text_view->get_buffer()->get_insert()->get_iter().get_offset()) {
-    hide();
-  }
-  else {
-    auto text=text_view->get_buffer()->get_text(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter());
-    search_entry.set_text(text);
-    list_view_text.set_search_entry(search_entry);
-    if(text=="") {
-      if(list_view_text.get_model()->children().size()>0)
-        list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
+    auto it = list_view_text.get_selection()->get_selected();
+    if (on_select && it) {
+        auto index = it->get_value(list_view_text.column_record.index);
+        auto text = it->get_value(list_view_text.column_record.text);
+        on_select(index, text, hide_window);
     }
-    cursor_changed();
-  }
-  return false;
+    if (hide_window)
+        hide();
 }
 
-bool CompletionDialog::on_key_press(GdkEventKey* key) {
-  if((key->keyval>=GDK_KEY_0 && key->keyval<=GDK_KEY_9) || 
-     (key->keyval>=GDK_KEY_A && key->keyval<=GDK_KEY_Z) ||
-     (key->keyval>=GDK_KEY_a && key->keyval<=GDK_KEY_z) ||
-     key->keyval==GDK_KEY_underscore || key->keyval==GDK_KEY_BackSpace) {
-    if(row_in_entry) {
-      text_view->get_buffer()->erase(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter());
-      row_in_entry=false;
-      if(key->keyval==GDK_KEY_BackSpace)
-        return true;
+bool CompletionDialog::on_key_release(GdkEventKey *key) {
+    if (key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down || key->keyval == GDK_KEY_Up ||
+        key->keyval == GDK_KEY_KP_Up)
+        return false;
+
+    if (show_offset > text_view->get_buffer()->get_insert()->get_iter().get_offset()) {
+        hide();
+    } else {
+        auto text = text_view->get_buffer()->get_text(start_mark->get_iter(),
+                                                      text_view->get_buffer()->get_insert()->get_iter());
+        search_entry.set_text(text);
+        list_view_text.set_search_entry(search_entry);
+        if (text == "") {
+            if (list_view_text.get_model()->children().size() > 0)
+                list_view_text.set_cursor(
+                        list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
+        }
+        cursor_changed();
     }
     return false;
-  }
-  if(key->keyval==GDK_KEY_Shift_L || key->keyval==GDK_KEY_Shift_R || key->keyval==GDK_KEY_Alt_L || key->keyval==GDK_KEY_Alt_R || key->keyval==GDK_KEY_Control_L || key->keyval==GDK_KEY_Control_R || key->keyval==GDK_KEY_Meta_L || key->keyval==GDK_KEY_Meta_R)
-    return false;
-  if((key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down) && list_view_text.get_model()->children().size()>0) {
-    auto it=list_view_text.get_selection()->get_selected();
-    if(it) {
-      it++;
-      if(it) {
-        list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
-        cursor_changed();
-      }
+}
+
+bool CompletionDialog::on_key_press(GdkEventKey *key) {
+    if ((key->keyval >= GDK_KEY_0 && key->keyval <= GDK_KEY_9) ||
+        (key->keyval >= GDK_KEY_A && key->keyval <= GDK_KEY_Z) ||
+        (key->keyval >= GDK_KEY_a && key->keyval <= GDK_KEY_z) ||
+        key->keyval == GDK_KEY_underscore || key->keyval == GDK_KEY_BackSpace) {
+        if (row_in_entry) {
+            text_view->get_buffer()->erase(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter());
+            row_in_entry = false;
+            if (key->keyval == GDK_KEY_BackSpace)
+                return true;
+        }
+        return false;
     }
-    else
-      list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
-    select(false);
-    return true;
-  }
-  if((key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up) && list_view_text.get_model()->children().size()>0) {
-    auto it=list_view_text.get_selection()->get_selected();
-    if(it) {
-      it--;
-      if(it) {
-        list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
-        cursor_changed();
-      }
+    if (key->keyval == GDK_KEY_Shift_L || key->keyval == GDK_KEY_Shift_R || key->keyval == GDK_KEY_Alt_L ||
+        key->keyval == GDK_KEY_Alt_R || key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R ||
+        key->keyval == GDK_KEY_Meta_L || key->keyval == GDK_KEY_Meta_R)
+        return false;
+    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
+        list_view_text.get_model()->children().size() > 0) {
+        auto it = list_view_text.get_selection()->get_selected();
+        if (it) {
+            it++;
+            if (it) {
+                list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
+                cursor_changed();
+            }
+        } else
+            list_view_text.set_cursor(
+                    list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
+        select(false);
+        return true;
     }
-    else {
-      auto last_it=list_view_text.get_model()->children().end();
-      last_it--;
-      if(last_it)
-        list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it));
+    if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
+        list_view_text.get_model()->children().size() > 0) {
+        auto it = list_view_text.get_selection()->get_selected();
+        if (it) {
+            it--;
+            if (it) {
+                list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
+                cursor_changed();
+            }
+        } else {
+            auto last_it = list_view_text.get_model()->children().end();
+            last_it--;
+            if (last_it)
+                list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it));
+        }
+        select(false);
+        return true;
     }
-    select(false);
-    return true;
-  }
-  if(key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter || key->keyval==GDK_KEY_ISO_Left_Tab || key->keyval==GDK_KEY_Tab) {
-    select();
-    return true;
-  }
-  hide();
-  if(key->keyval==GDK_KEY_Escape)
-    return true;
-  return false;
+    if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter || key->keyval == GDK_KEY_ISO_Left_Tab ||
+        key->keyval == GDK_KEY_Tab) {
+        select();
+        return true;
+    }
+    hide();
+    if (key->keyval == GDK_KEY_Escape)
+        return true;
+    return false;
 }
diff --git a/src/selection_dialog.h b/src/selection_dialog.h
index c041f4a1..05d33d48 100644
--- a/src/selection_dialog.h
+++ b/src/selection_dialog.h
@@ -1,100 +1,129 @@
 #pragma once
+
 #include "gtkmm.h"
 #include <unordered_map>
 #include <functional>
 
 class SelectionDialogBase {
-  class ListViewText : public Gtk::TreeView {
-    class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
+    class ListViewText : public Gtk::TreeView {
+        class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
+        public:
+            ColumnRecord() {
+                add(text);
+                add(index);
+            }
+
+            Gtk::TreeModelColumn<std::string> text;
+            Gtk::TreeModelColumn<unsigned int> index;
+        };
+
     public:
-      ColumnRecord() {
-        add(text);
-        add(index);
-      }
-      Gtk::TreeModelColumn<std::string> text;
-      Gtk::TreeModelColumn<unsigned int> index;
+        bool use_markup;
+        ColumnRecord column_record;
+
+        ListViewText(bool use_markup);
+
+        void append(const std::string &value);
+
+        void erase_rows();
+
+        void clear();
+
+    private:
+        Glib::RefPtr<Gtk::ListStore> list_store;
+        Gtk::CellRendererText cell_renderer;
+        unsigned int size = 0;
     };
-  public:
-    bool use_markup;
-    ColumnRecord column_record;
-    ListViewText(bool use_markup);
-    void append(const std::string& value);
-    void erase_rows();
-    void clear();
-  private:
-    Glib::RefPtr<Gtk::ListStore> list_store;
-    Gtk::CellRendererText cell_renderer;
-    unsigned int size=0;
-  };
-  
-  class SearchEntry : public Gtk::Entry {
-  public:
-    SearchEntry() : Gtk::Entry() {}
-    bool on_key_press_event(GdkEventKey *event) override { return Gtk::Entry::on_key_press_event(event); };
-  };
-  
+
+    class SearchEntry : public Gtk::Entry {
+    public:
+        SearchEntry() : Gtk::Entry() {}
+
+        bool on_key_press_event(GdkEventKey *event) override { return Gtk::Entry::on_key_press_event(event); };
+    };
+
 public:
-  SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry, bool use_markup);
-  virtual ~SelectionDialogBase();
-  void add_row(const std::string& row);
-  void erase_rows();
-  void set_cursor_at_last_row();
-  void show();
-  void hide();
-  
-  bool is_visible() {return window.is_visible();}
-  void get_position(int &root_x, int &root_y) {window.get_position(root_x, root_y);}
-  
-  std::function<void()> on_show;
-  std::function<void()> on_hide;
-  std::function<void(unsigned int index, const std::string &text, bool hide_window)> on_select;
-  std::function<void(unsigned int index, const std::string &text)> on_changed;
-  std::function<void(const std::string &text)> on_search_entry_changed;
-  Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
-  
+    SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark,
+                        bool show_search_entry, bool use_markup);
+
+    virtual ~SelectionDialogBase();
+
+    void add_row(const std::string &row);
+
+    void erase_rows();
+
+    void set_cursor_at_last_row();
+
+    void show();
+
+    void hide();
+
+    bool is_visible() { return window.is_visible(); }
+
+    void get_position(int &root_x, int &root_y) { window.get_position(root_x, root_y); }
+
+    std::function<void()> on_show;
+    std::function<void()> on_hide;
+    std::function<void(unsigned int index, const std::string &text, bool hide_window)> on_select;
+    std::function<void(unsigned int index, const std::string &text)> on_changed;
+    std::function<void(const std::string &text)> on_search_entry_changed;
+    Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
+
 protected:
-  void cursor_changed();
-  
-  Gtk::TextView *text_view;
-  Gtk::Window window;
-  Gtk::Box vbox;
-  Gtk::ScrolledWindow scrolled_window;
-  ListViewText list_view_text;
-  SearchEntry search_entry;
-  bool show_search_entry;
-  
-  unsigned int last_index=static_cast<unsigned int>(-1);
+    void cursor_changed();
+
+    Gtk::TextView *text_view;
+    Gtk::Window window;
+    Gtk::Box vbox;
+    Gtk::ScrolledWindow scrolled_window;
+    ListViewText list_view_text;
+    SearchEntry search_entry;
+    bool show_search_entry;
+
+    unsigned int last_index = static_cast<unsigned int>(-1);
 };
 
 class SelectionDialog : public SelectionDialogBase {
-  SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry, bool use_markup);
-  static std::unique_ptr<SelectionDialog> instance;
+    SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry,
+                    bool use_markup);
+
+    static std::unique_ptr<SelectionDialog> instance;
 public:
-  bool on_key_press(GdkEventKey* key);
-  
-  static void create(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry=true, bool use_markup=false) {
-    instance=std::unique_ptr<SelectionDialog>(new SelectionDialog(text_view, start_mark, show_search_entry, use_markup));
-  }
-  static void create(bool show_search_entry=true, bool use_markup=false) {
-    instance=std::unique_ptr<SelectionDialog>(new SelectionDialog(nullptr, Glib::RefPtr<Gtk::TextBuffer::Mark>(), show_search_entry, use_markup));
-  }
-  static std::unique_ptr<SelectionDialog> &get() {return instance;}
+    bool on_key_press(GdkEventKey *key);
+
+    static void
+    create(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry = true,
+           bool use_markup = false) {
+        instance = std::unique_ptr<SelectionDialog>(
+                new SelectionDialog(text_view, start_mark, show_search_entry, use_markup));
+    }
+
+    static void create(bool show_search_entry = true, bool use_markup = false) {
+        instance = std::unique_ptr<SelectionDialog>(
+                new SelectionDialog(nullptr, Glib::RefPtr<Gtk::TextBuffer::Mark>(), show_search_entry, use_markup));
+    }
+
+    static std::unique_ptr<SelectionDialog> &get() { return instance; }
 };
 
 class CompletionDialog : public SelectionDialogBase {
-  CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark);
-  static std::unique_ptr<CompletionDialog> instance;
+    CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark);
+
+    static std::unique_ptr<CompletionDialog> instance;
 public:
-  bool on_key_release(GdkEventKey* key);
-  bool on_key_press(GdkEventKey* key);
-  
-  static void create(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark) {
-    instance=std::unique_ptr<CompletionDialog>(new CompletionDialog(text_view, start_mark));
-  }
-  static std::unique_ptr<CompletionDialog> &get() {return instance;}
+    bool on_key_release(GdkEventKey *key);
+
+    bool on_key_press(GdkEventKey *key);
+
+    static void create(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark) {
+        instance = std::unique_ptr<CompletionDialog>(new CompletionDialog(text_view, start_mark));
+    }
+
+    static std::unique_ptr<CompletionDialog> &get() { return instance; }
+
 private:
-  void select(bool hide_window=true);
-  
-  int show_offset;
-  bool row_in_entry=false;
+    void select(bool hide_window = true);
+
+    int show_offset;
+    bool row_in_entry = false;
 };
diff --git a/src/source.cc b/src/source.cc
index 9b770af9..01f7bd06 100644
--- a/src/source.cc
+++ b/src/source.cc
@@ -19,2704 +19,2722 @@
 #include <limits>
 
 Glib::RefPtr<Gsv::LanguageManager> Source::LanguageManager::get_default() {
-  static auto instance = Gsv::LanguageManager::create();
-  return instance;
+    static auto instance = Gsv::LanguageManager::create();
+    return instance;
 }
+
 Glib::RefPtr<Gsv::StyleSchemeManager> Source::StyleSchemeManager::get_default() {
-  static auto instance = Gsv::StyleSchemeManager::create();
-  static bool first = true;
-  if(first) {
-    instance->prepend_search_path((Config::get().home_juci_path/"styles").string());
-    first=false;
-  }
-  return instance;
+    static auto instance = Gsv::StyleSchemeManager::create();
+    static bool first = true;
+    if (first) {
+        instance->prepend_search_path((Config::get().home_juci_path / "styles").string());
+        first = false;
+    }
+    return instance;
 }
 
 Glib::RefPtr<Gsv::Language> Source::guess_language(const boost::filesystem::path &file_path) {
-  auto language_manager=LanguageManager::get_default();
-  bool result_uncertain = false;
-  auto content_type = Gio::content_type_guess(file_path.string(), nullptr, 0, result_uncertain);
-  if(result_uncertain) {
-    content_type.clear();
-  }
-  auto language=language_manager->guess_language(file_path.string(), content_type);
-  if(!language) {
-    auto filename=file_path.filename().string();
-    if(filename=="CMakeLists.txt")
-      language=language_manager->get_language("cmake");
-    else if(filename=="Makefile")
-      language=language_manager->get_language("makefile");
-    else if(file_path.extension()==".tcc")
-      language=language_manager->get_language("cpphdr");
-    else if(file_path.extension()==".ts" || file_path.extension()==".jsx")
-      language=language_manager->get_language("js");
-    else if(!file_path.has_extension()) {
-      for(auto &part: file_path) {
-        if(part=="include") {
-          language=language_manager->get_language("cpphdr");
-          break;
-        }
-      }
+    auto language_manager = LanguageManager::get_default();
+    bool result_uncertain = false;
+    auto content_type = Gio::content_type_guess(file_path.string(), nullptr, 0, result_uncertain);
+    if (result_uncertain) {
+        content_type.clear();
+    }
+    auto language = language_manager->guess_language(file_path.string(), content_type);
+    if (!language) {
+        auto filename = file_path.filename().string();
+        if (filename == "CMakeLists.txt")
+            language = language_manager->get_language("cmake");
+        else if (filename == "Makefile")
+            language = language_manager->get_language("makefile");
+        else if (file_path.extension() == ".tcc")
+            language = language_manager->get_language("cpphdr");
+        else if (file_path.extension() == ".ts" || file_path.extension() == ".jsx")
+            language = language_manager->get_language("js");
+        else if (!file_path.has_extension()) {
+            for (auto &part: file_path) {
+                if (part == "include") {
+                    language = language_manager->get_language("cpphdr");
+                    break;
+                }
+            }
+        }
+    } else if (language->get_id() == "cuda") {
+        if (file_path.extension() == ".cuh")
+            language = language_manager->get_language("cpphdr");
+        else
+            language = language_manager->get_language("cpp");
+    } else if (language->get_id() == "opencl") {
+        language = language_manager->get_language("cpp");
     }
-  }
-  else if(language->get_id()=="cuda") {
-    if(file_path.extension()==".cuh")
-      language=language_manager->get_language("cpphdr");
-    else
-      language=language_manager->get_language("cpp");
-  }
-  else if(language->get_id()=="opencl") {
-    language = language_manager->get_language("cpp");
-  }
-  return language;
+    return language;
 }
 
-Source::FixIt::FixIt(const std::string &source, const std::pair<Offset, Offset> &offsets) : source(source), offsets(offsets) {
-  if(source.size()==0)
-    type=Type::ERASE;
-  else {
-    if(this->offsets.first==this->offsets.second)
-      type=Type::INSERT;
-    else
-      type=Type::REPLACE;
-  }
+Source::FixIt::FixIt(const std::string &source, const std::pair<Offset, Offset> &offsets) : source(source),
+                                                                                            offsets(offsets) {
+    if (source.size() == 0)
+        type = Type::ERASE;
+    else {
+        if (this->offsets.first == this->offsets.second)
+            type = Type::INSERT;
+        else
+            type = Type::REPLACE;
+    }
 }
 
 std::string Source::FixIt::string(Glib::RefPtr<Gtk::TextBuffer> buffer) {
-  auto iter=buffer->get_iter_at_line_index(offsets.first.line, offsets.first.index);
-  unsigned first_line_offset=iter.get_line_offset()+1;
-  iter=buffer->get_iter_at_line_index(offsets.second.line, offsets.second.index);
-  unsigned second_line_offset=iter.get_line_offset()+1;
-  
-  std::string text;
-  if(type==Type::INSERT) {
-    text+="Insert "+source+" at ";
-    text+=std::to_string(offsets.first.line+1)+":"+std::to_string(first_line_offset);
-  }
-  else if(type==Type::REPLACE) {
-    text+="Replace ";
-    text+=std::to_string(offsets.first.line+1)+":"+std::to_string(first_line_offset)+" - ";
-    text+=std::to_string(offsets.second.line+1)+":"+std::to_string(second_line_offset);
-    text+=" with "+source;
-  }
-  else {
-    text+="Erase ";
-    text+=std::to_string(offsets.first.line+1)+":"+std::to_string(first_line_offset)+" - ";
-    text+=std::to_string(offsets.second.line+1)+":"+std::to_string(second_line_offset);
-  }
-  
-  return text;
+    auto iter = buffer->get_iter_at_line_index(offsets.first.line, offsets.first.index);
+    unsigned first_line_offset = iter.get_line_offset() + 1;
+    iter = buffer->get_iter_at_line_index(offsets.second.line, offsets.second.index);
+    unsigned second_line_offset = iter.get_line_offset() + 1;
+
+    std::string text;
+    if (type == Type::INSERT) {
+        text += "Insert " + source + " at ";
+        text += std::to_string(offsets.first.line + 1) + ":" + std::to_string(first_line_offset);
+    } else if (type == Type::REPLACE) {
+        text += "Replace ";
+        text += std::to_string(offsets.first.line + 1) + ":" + std::to_string(first_line_offset) + " - ";
+        text += std::to_string(offsets.second.line + 1) + ":" + std::to_string(second_line_offset);
+        text += " with " + source;
+    } else {
+        text += "Erase ";
+        text += std::to_string(offsets.first.line + 1) + ":" + std::to_string(first_line_offset) + " - ";
+        text += std::to_string(offsets.second.line + 1) + ":" + std::to_string(second_line_offset);
+    }
+
+    return text;
 }
 
 //////////////
 //// View ////
 //////////////
-std::unordered_set<Source::View*> Source::View::non_deleted_views;
-std::unordered_set<Source::View*> Source::View::views;
-
-Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language, bool is_generic_view): BaseView(file_path, language), SpellCheckView(file_path, language), DiffView(file_path, language) {
-  non_deleted_views.emplace(this);
-  views.emplace(this);
-  
-  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);
-  gtk_source_search_context_set_highlight(search_context, true);
-  //TODO: why does this not work?: Might be best to use the styles from sourceview. These has to be read from file, search-matches got style "search-match"
-  //TODO: in header if trying again: GtkSourceStyle* search_match_style;
-  //TODO: We can drop this, only work on newer versions of gtksourceview.
-  //search_match_style=(GtkSourceStyle*)g_object_new(GTK_SOURCE_TYPE_STYLE, "background-set", 1, "background", "#00FF00", nullptr);
-  //gtk_source_search_context_set_match_style(search_context, search_match_style);
-  
-  //TODO: either use lambda if possible or create a gtkmm wrapper around search_context (including search_settings):
-  //TODO: (gtkmm's Gtk::Object has connect_property_changed, so subclassing this might be an idea)
-  g_signal_connect(search_context, "notify::occurrences-count", G_CALLBACK(search_occurrences_updated), this);
-  
-  get_buffer()->create_tag("def:warning");
-  get_buffer()->create_tag("def:warning_underline");
-  get_buffer()->create_tag("def:error");
-  get_buffer()->create_tag("def:error_underline");
-  
-  auto mark_attr_debug_breakpoint=Gsv::MarkAttributes::create();
-  Gdk::RGBA rgba;
-  rgba.set_red(1.0);
-  rgba.set_green(0.5);
-  rgba.set_blue(0.5);
-  rgba.set_alpha(0.3);
-  mark_attr_debug_breakpoint->set_background(rgba);
-  set_mark_attributes("debug_breakpoint", mark_attr_debug_breakpoint, 100);
-  auto mark_attr_debug_stop=Gsv::MarkAttributes::create();
-  rgba.set_red(0.5);
-  rgba.set_green(0.5);
-  rgba.set_blue(1.0);
-  mark_attr_debug_stop->set_background(rgba);
-  set_mark_attributes("debug_stop", mark_attr_debug_stop, 101);
-  auto mark_attr_debug_breakpoint_and_stop=Gsv::MarkAttributes::create();
-  rgba.set_red(0.75);
-  rgba.set_green(0.5);
-  rgba.set_blue(0.75);
-  mark_attr_debug_breakpoint_and_stop->set_background(rgba);
-  set_mark_attributes("debug_breakpoint_and_stop", mark_attr_debug_breakpoint_and_stop, 102);
-  
-  get_buffer()->signal_changed().connect([this](){
-    if(update_status_location)
-      update_status_location(this);
-  });
-  
-  signal_realize().connect([this] {
-    auto gutter=get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT);
-    auto renderer=gutter->get_renderer_at_pos(15, 0);
-    if(renderer) {
-      renderer_activate_connection.disconnect();
-      renderer_activate_connection=renderer->signal_activate().connect([this](const Gtk::TextIter& iter, const Gdk::Rectangle&, GdkEvent*) {
-        if(toggle_breakpoint)
-          toggle_breakpoint(iter.get_line());
-      });
-    }
-  });
-  
-  if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" ||
-                  language->get_id()=="cpp" || language->get_id()=="objc" || language->get_id()=="java" ||
-                  language->get_id()=="js" || language->get_id()=="ts" || language->get_id()=="proto" ||
-                  language->get_id()=="c-sharp" || language->get_id()=="html" || language->get_id()=="cuda" ||
-                  language->get_id()=="php" || language->get_id()=="rust" || language->get_id()=="swift" ||
-                  language->get_id()=="go" || language->get_id()=="scala" || language->get_id()=="opencl" ||
-                  language->get_id()=="json" || language->get_id()=="css"))
-    is_bracket_language=true;
-  
-  setup_tooltip_and_dialog_events();
-  setup_format_style(is_generic_view);
-  
+std::unordered_set<Source::View *> Source::View::non_deleted_views;
+std::unordered_set<Source::View *> Source::View::views;
+
+Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language, bool is_generic_view)
+        : BaseView(file_path, language), SpellCheckView(file_path, language), DiffView(file_path, language) {
+    non_deleted_views.emplace(this);
+    views.emplace(this);
+
+    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);
+    gtk_source_search_context_set_highlight(search_context, true);
+    //TODO: why does this not work?: Might be best to use the styles from sourceview. These has to be read from file, search-matches got style "search-match"
+    //TODO: in header if trying again: GtkSourceStyle* search_match_style;
+    //TODO: We can drop this, only work on newer versions of gtksourceview.
+    //search_match_style=(GtkSourceStyle*)g_object_new(GTK_SOURCE_TYPE_STYLE, "background-set", 1, "background", "#00FF00", nullptr);
+    //gtk_source_search_context_set_match_style(search_context, search_match_style);
+
+    //TODO: either use lambda if possible or create a gtkmm wrapper around search_context (including search_settings):
+    //TODO: (gtkmm's Gtk::Object has connect_property_changed, so subclassing this might be an idea)
+    g_signal_connect(search_context, "notify::occurrences-count", G_CALLBACK(search_occurrences_updated), this);
+
+    get_buffer()->create_tag("def:warning");
+    get_buffer()->create_tag("def:warning_underline");
+    get_buffer()->create_tag("def:error");
+    get_buffer()->create_tag("def:error_underline");
+
+    auto mark_attr_debug_breakpoint = Gsv::MarkAttributes::create();
+    Gdk::RGBA rgba;
+    rgba.set_red(1.0);
+    rgba.set_green(0.5);
+    rgba.set_blue(0.5);
+    rgba.set_alpha(0.3);
+    mark_attr_debug_breakpoint->set_background(rgba);
+    set_mark_attributes("debug_breakpoint", mark_attr_debug_breakpoint, 100);
+    auto mark_attr_debug_stop = Gsv::MarkAttributes::create();
+    rgba.set_red(0.5);
+    rgba.set_green(0.5);
+    rgba.set_blue(1.0);
+    mark_attr_debug_stop->set_background(rgba);
+    set_mark_attributes("debug_stop", mark_attr_debug_stop, 101);
+    auto mark_attr_debug_breakpoint_and_stop = Gsv::MarkAttributes::create();
+    rgba.set_red(0.75);
+    rgba.set_green(0.5);
+    rgba.set_blue(0.75);
+    mark_attr_debug_breakpoint_and_stop->set_background(rgba);
+    set_mark_attributes("debug_breakpoint_and_stop", mark_attr_debug_breakpoint_and_stop, 102);
+
+    get_buffer()->signal_changed().connect([this]() {
+        if (update_status_location)
+            update_status_location(this);
+    });
+
+    signal_realize().connect([this] {
+        auto gutter = get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT);
+        auto renderer = gutter->get_renderer_at_pos(15, 0);
+        if (renderer) {
+            renderer_activate_connection.disconnect();
+            renderer_activate_connection = renderer->signal_activate().connect(
+                    [this](const Gtk::TextIter &iter, const Gdk::Rectangle &, GdkEvent *) {
+                        if (toggle_breakpoint)
+                            toggle_breakpoint(iter.get_line());
+                    });
+        }
+    });
+
+    if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr" || language->get_id() == "c" ||
+                     language->get_id() == "cpp" || language->get_id() == "objc" || language->get_id() == "java" ||
+                     language->get_id() == "js" || language->get_id() == "ts" || language->get_id() == "proto" ||
+                     language->get_id() == "c-sharp" || language->get_id() == "html" || language->get_id() == "cuda" ||
+                     language->get_id() == "php" || language->get_id() == "rust" || language->get_id() == "swift" ||
+                     language->get_id() == "go" || language->get_id() == "scala" || language->get_id() == "opencl" ||
+                     language->get_id() == "json" || language->get_id() == "css"))
+        is_bracket_language = true;
+
+    setup_tooltip_and_dialog_events();
+    setup_format_style(is_generic_view);
+
 #ifndef __APPLE__
-  set_tab_width(4); //Visual size of a \t hardcoded to be equal to visual size of 4 spaces. Buggy on OS X
+    set_tab_width(4); //Visual size of a \t hardcoded to be equal to visual size of 4 spaces. Buggy on OS X
 #endif
-  tab_char=Config::get().source.default_tab_char;
-  tab_size=Config::get().source.default_tab_size;
-  if(Config::get().source.auto_tab_char_and_size) {
-    auto tab_char_and_size=find_tab_char_and_size();
-    if(tab_char_and_size.second!=0) {
-      if(tab_char!=tab_char_and_size.first || tab_size!=tab_char_and_size.second) {
-        std::string tab_str;
-        if(tab_char_and_size.first==' ')
-          tab_str="<space>";
-        else
-          tab_str="<tab>";
-      }
-      
-      tab_char=tab_char_and_size.first;
-      tab_size=tab_char_and_size.second;
+    tab_char = Config::get().source.default_tab_char;
+    tab_size = Config::get().source.default_tab_size;
+    if (Config::get().source.auto_tab_char_and_size) {
+        auto tab_char_and_size = find_tab_char_and_size();
+        if (tab_char_and_size.second != 0) {
+            if (tab_char != tab_char_and_size.first || tab_size != tab_char_and_size.second) {
+                std::string tab_str;
+                if (tab_char_and_size.first == ' ')
+                    tab_str = "<space>";
+                else
+                    tab_str = "<tab>";
+            }
+
+            tab_char = tab_char_and_size.first;
+            tab_size = tab_char_and_size.second;
+        }
     }
-  }
-  set_tab_char_and_size(tab_char, tab_size);
-  
-  std::string comment_characters;
-  if(is_bracket_language)
-    comment_characters="//";
-  else if(language) {
-    if(language->get_id()=="cmake" || language->get_id()=="makefile" || language->get_id()=="python" ||
-       language->get_id()=="python3" || language->get_id()=="sh" || language->get_id()=="perl" ||
-       language->get_id()=="ruby" || language->get_id()=="r" || language->get_id()=="asm" ||
-       language->get_id()=="automake")
-      comment_characters="#";
-    else if(language->get_id()=="latex" || language->get_id()=="matlab" || language->get_id()=="octave" ||
-            language->get_id()=="bibtex")
-      comment_characters="%";
-    else if(language->get_id()=="fortran")
-      comment_characters="!";
-    else if(language->get_id()=="pascal")
-      comment_characters="//";
-    else if(language->get_id()=="lua")
-      comment_characters="--";
-  }
-  if(!comment_characters.empty()) {
-    toggle_comments=[this, comment_characters=std::move(comment_characters)] {
-      std::vector<int> lines;
-      Gtk::TextIter selection_start, selection_end;
-      get_buffer()->get_selection_bounds(selection_start, selection_end);
-      auto line_start=selection_start.get_line();
-      auto line_end=selection_end.get_line();
-      if(line_start!=line_end && selection_end.starts_line())
-        --line_end;
-      bool lines_commented=true;
-      bool extra_spaces=true;
-      int min_indentation=-1;
-      for(auto line=line_start;line<=line_end;++line) {
-        auto iter=get_buffer()->get_iter_at_line(line);
-        bool line_added=false;
-        bool line_commented=false;
-        bool extra_space=false;
-        int indentation=0;
-        for(;;) {
-          if(iter.ends_line())
-            break;
-          else if(*iter==' ' || *iter=='\t') {
-            ++indentation;
-            iter.forward_char();
-            continue;
-          }
-          else {
-            lines.emplace_back(line);
-            line_added=true;
-            for(size_t c=0;c<comment_characters.size();++c) {
-              if(iter.ends_line()) {
-                break;
-              }
-              else if(*iter==static_cast<unsigned int>(comment_characters[c])) {
-                if(c<comment_characters.size()-1) {
-                  iter.forward_char();
-                  continue;
+    set_tab_char_and_size(tab_char, tab_size);
+
+    std::string comment_characters;
+    if (is_bracket_language)
+        comment_characters = "//";
+    else if (language) {
+        if (language->get_id() == "cmake" || language->get_id() == "makefile" || language->get_id() == "python" ||
+            language->get_id() == "python3" || language->get_id() == "sh" || language->get_id() == "perl" ||
+            language->get_id() == "ruby" || language->get_id() == "r" || language->get_id() == "asm" ||
+            language->get_id() == "automake")
+            comment_characters = "#";
+        else if (language->get_id() == "latex" || language->get_id() == "matlab" || language->get_id() == "octave" ||
+                 language->get_id() == "bibtex")
+            comment_characters = "%";
+        else if (language->get_id() == "fortran")
+            comment_characters = "!";
+        else if (language->get_id() == "pascal")
+            comment_characters = "//";
+        else if (language->get_id() == "lua")
+            comment_characters = "--";
+    }
+    if (!comment_characters.empty()) {
+        toggle_comments = [this, comment_characters = std::move(comment_characters)] {
+            std::vector<int> lines;
+            Gtk::TextIter selection_start, selection_end;
+            get_buffer()->get_selection_bounds(selection_start, selection_end);
+            auto line_start = selection_start.get_line();
+            auto line_end = selection_end.get_line();
+            if (line_start != line_end && selection_end.starts_line())
+                --line_end;
+            bool lines_commented = true;
+            bool extra_spaces = true;
+            int min_indentation = -1;
+            for (auto line = line_start; line <= line_end; ++line) {
+                auto iter = get_buffer()->get_iter_at_line(line);
+                bool line_added = false;
+                bool line_commented = false;
+                bool extra_space = false;
+                int indentation = 0;
+                for (;;) {
+                    if (iter.ends_line())
+                        break;
+                    else if (*iter == ' ' || *iter == '\t') {
+                        ++indentation;
+                        iter.forward_char();
+                        continue;
+                    } else {
+                        lines.emplace_back(line);
+                        line_added = true;
+                        for (size_t c = 0; c < comment_characters.size(); ++c) {
+                            if (iter.ends_line()) {
+                                break;
+                            } else if (*iter == static_cast<unsigned int>(comment_characters[c])) {
+                                if (c < comment_characters.size() - 1) {
+                                    iter.forward_char();
+                                    continue;
+                                } else {
+                                    line_commented = true;
+                                    if (!iter.ends_line()) {
+                                        iter.forward_char();
+                                        if (*iter == ' ')
+                                            extra_space = true;
+                                    }
+                                    break;
+                                }
+                            } else
+                                break;
+                        }
+                        break;
+                    }
                 }
-                else {
-                  line_commented=true;
-                  if(!iter.ends_line()) {
-                    iter.forward_char();
-                    if(*iter==' ')
-                      extra_space=true;
-                  }
-                  break;
+                if (line_added) {
+                    lines_commented &= line_commented;
+                    extra_spaces &= extra_space;
+                    if (min_indentation == -1 || indentation < min_indentation)
+                        min_indentation = indentation;
                 }
-              }
-              else
-                break;
             }
-            break;
-          }
-        }
-        if(line_added) {
-          lines_commented&=line_commented;
-          extra_spaces&=extra_space;
-          if(min_indentation==-1 || indentation<min_indentation)
-            min_indentation=indentation;
-        }
-      }
-      if(lines.size()) {
-        auto comment_characters_and_space=comment_characters+' ';
-        get_buffer()->begin_user_action();
-        for(auto &line: lines) {
-          auto iter=get_buffer()->get_iter_at_line(line);
-          iter.forward_chars(min_indentation);
-          if(lines_commented) {
-            auto end_iter=iter;
-            end_iter.forward_chars(comment_characters.size()+static_cast<int>(extra_spaces));
-            while(*iter==' ' || *iter=='\t') {
-              iter.forward_char();
-              end_iter.forward_char();
-            }
-            get_buffer()->erase(iter, end_iter);
-          }
-          else
-            get_buffer()->insert(iter, comment_characters_and_space);
-        }
-        get_buffer()->end_user_action();
-      }
-    };
-  }
+            if (lines.size()) {
+                auto comment_characters_and_space = comment_characters + ' ';
+                get_buffer()->begin_user_action();
+                for (auto &line: lines) {
+                    auto iter = get_buffer()->get_iter_at_line(line);
+                    iter.forward_chars(min_indentation);
+                    if (lines_commented) {
+                        auto end_iter = iter;
+                        end_iter.forward_chars(comment_characters.size() + static_cast<int>(extra_spaces));
+                        while (*iter == ' ' || *iter == '\t') {
+                            iter.forward_char();
+                            end_iter.forward_char();
+                        }
+                        get_buffer()->erase(iter, end_iter);
+                    } else
+                        get_buffer()->insert(iter, comment_characters_and_space);
+                }
+                get_buffer()->end_user_action();
+            }
+        };
+    }
 }
 
 void Source::View::set_tab_char_and_size(char tab_char, unsigned tab_size) {
-  this->tab_char=tab_char;
-  this->tab_size=tab_size;
-      
-  tab.clear();
-  for(unsigned c=0;c<tab_size;c++)
-    tab+=tab_char;
+    this->tab_char = tab_char;
+    this->tab_size = tab_size;
+
+    tab.clear();
+    for (unsigned c = 0; c < tab_size; c++)
+        tab += tab_char;
 }
 
 void Source::View::cleanup_whitespace_characters() {
-  auto buffer=get_buffer();
-  buffer->begin_user_action();
-  for(int line=0;line<buffer->get_line_count();line++) {
-    auto iter=buffer->get_iter_at_line(line);
-    auto end_iter=get_iter_at_line_end(line);
-    if(iter==end_iter)
-      continue;
-    iter=end_iter;
-    while(!iter.starts_line() && (*iter==' ' || *iter=='\t' || iter.ends_line()))
-      iter.backward_char();
-    if(*iter!=' ' && *iter!='\t')
-      iter.forward_char();
-    if(iter==end_iter)
-      continue;
-    buffer->erase(iter, end_iter);
-  }
-  auto iter=buffer->end();
-  if(!iter.starts_line())
-    buffer->insert(buffer->end(), "\n");
-  buffer->end_user_action();
+    auto buffer = get_buffer();
+    buffer->begin_user_action();
+    for (int line = 0; line < buffer->get_line_count(); line++) {
+        auto iter = buffer->get_iter_at_line(line);
+        auto end_iter = get_iter_at_line_end(line);
+        if (iter == end_iter)
+            continue;
+        iter = end_iter;
+        while (!iter.starts_line() && (*iter == ' ' || *iter == '\t' || iter.ends_line()))
+            iter.backward_char();
+        if (*iter != ' ' && *iter != '\t')
+            iter.forward_char();
+        if (iter == end_iter)
+            continue;
+        buffer->erase(iter, end_iter);
+    }
+    auto iter = buffer->end();
+    if (!iter.starts_line())
+        buffer->insert(buffer->end(), "\n");
+    buffer->end_user_action();
 }
 
 Gsv::DrawSpacesFlags Source::View::parse_show_whitespace_characters(const std::string &text) {
-  namespace qi = boost::spirit::qi;
-  
-  qi::symbols<char, Gsv::DrawSpacesFlags> options;
-  options.add
-    ("space",    Gsv::DRAW_SPACES_SPACE)
-    ("tab",      Gsv::DRAW_SPACES_TAB)
-    ("newline",  Gsv::DRAW_SPACES_NEWLINE)
-    ("nbsp",     Gsv::DRAW_SPACES_NBSP)
-    ("leading",  Gsv::DRAW_SPACES_LEADING)
-    ("text",     Gsv::DRAW_SPACES_TEXT)
-    ("trailing", Gsv::DRAW_SPACES_TRAILING)
-    ("all",      Gsv::DRAW_SPACES_ALL);
-
-  std::set<Gsv::DrawSpacesFlags> out;
-  
-  // parse comma-separated list of options
-  qi::phrase_parse(text.begin(), text.end(), options % ',', qi::space, out);
-  
-  return out.count(Gsv::DRAW_SPACES_ALL)>0 ?
-    Gsv::DRAW_SPACES_ALL :
-    static_cast<Gsv::DrawSpacesFlags>(std::accumulate(out.begin(), out.end(), 0));
+    namespace qi = boost::spirit::qi;
+
+    qi::symbols<char, Gsv::DrawSpacesFlags> options;
+    options.add
+            ("space", Gsv::DRAW_SPACES_SPACE)
+            ("tab", Gsv::DRAW_SPACES_TAB)
+            ("newline", Gsv::DRAW_SPACES_NEWLINE)
+            ("nbsp", Gsv::DRAW_SPACES_NBSP)
+            ("leading", Gsv::DRAW_SPACES_LEADING)
+            ("text", Gsv::DRAW_SPACES_TEXT)
+            ("trailing", Gsv::DRAW_SPACES_TRAILING)
+            ("all", Gsv::DRAW_SPACES_ALL);
+
+    std::set<Gsv::DrawSpacesFlags> out;
+
+    // parse comma-separated list of options
+    qi::phrase_parse(text.begin(), text.end(), options % ',', qi::space, out);
+
+    return out.count(Gsv::DRAW_SPACES_ALL) > 0 ?
+           Gsv::DRAW_SPACES_ALL :
+           static_cast<Gsv::DrawSpacesFlags>(std::accumulate(out.begin(), out.end(), 0));
 }
 
 bool Source::View::save() {
-  if(file_path.empty() || !get_buffer()->get_modified())
-    return false;
-  if(Config::get().source.cleanup_whitespace_characters)
-    cleanup_whitespace_characters();
-  
-  if(format_style) {
-    if(Config::get().source.format_style_on_save)
-      format_style(true);
-    else if(Config::get().source.format_style_on_save_if_style_file_found)
-      format_style(false);
-    hide_tooltips();
-  }
-  
-  std::ofstream output(file_path.string(), std::ofstream::binary);
-  if(output) {
-    auto start_iter=get_buffer()->begin();
-    auto end_iter=start_iter;
-    bool end_reached=false;
-    while(!end_reached) {
-      for(size_t c=0;c<131072;c++) {
-        if(!end_iter.forward_char()) {
-          end_reached=true;
-          break;
-        }
-      }
-      output << get_buffer()->get_text(start_iter, end_iter).c_str();
-      start_iter=end_iter;
-    }
-    output.close();
-    boost::system::error_code ec;
-    last_write_time=boost::filesystem::last_write_time(file_path, ec);
-    if(ec)
-      last_write_time=static_cast<std::time_t>(-1);
-    // Remonitor file in case it did not exist before
-    monitor_file();
-    get_buffer()->set_modified(false);
-    Directories::get().on_save_file(file_path);
-    return true;
-  }
-  else {
-    Terminal::get().print("Error: could not save file "+file_path.string()+"\n", true);
-    return false;
-  }
+    if (file_path.empty() || !get_buffer()->get_modified())
+        return false;
+    if (Config::get().source.cleanup_whitespace_characters)
+        cleanup_whitespace_characters();
+
+    if (format_style) {
+        if (Config::get().source.format_style_on_save)
+            format_style(true);
+        else if (Config::get().source.format_style_on_save_if_style_file_found)
+            format_style(false);
+    }
+
+    std::ofstream output(file_path.string(), std::ofstream::binary);
+    if (output) {
+        auto start_iter = get_buffer()->begin();
+        auto end_iter = start_iter;
+        bool end_reached = false;
+        while (!end_reached) {
+            for (size_t c = 0; c < 131072; c++) {
+                if (!end_iter.forward_char()) {
+                    end_reached = true;
+                    break;
+                }
+            }
+            output << get_buffer()->get_text(start_iter, end_iter).c_str();
+            start_iter = end_iter;
+        }
+        output.close();
+        boost::system::error_code ec;
+        last_write_time = boost::filesystem::last_write_time(file_path, ec);
+        if (ec)
+            last_write_time = static_cast<std::time_t>(-1);
+        // Remonitor file in case it did not exist before
+        monitor_file();
+        get_buffer()->set_modified(false);
+        Directories::get().on_save_file(file_path);
+        return true;
+    } else {
+        Terminal::get().print("Error: could not save file " + file_path.string() + "\n", true);
+        return false;
+    }
 }
 
 void Source::View::configure() {
-  SpellCheckView::configure();
-  DiffView::configure();
-  
-  if(Config::get().source.style.size()>0) {
-    auto scheme = StyleSchemeManager::get_default()->get_scheme(Config::get().source.style);
-    if(scheme)
-      get_source_buffer()->set_style_scheme(scheme);
-  }
-  
-  set_draw_spaces(parse_show_whitespace_characters(Config::get().source.show_whitespace_characters));
-  
-  if(Config::get().source.wrap_lines)
-    set_wrap_mode(Gtk::WrapMode::WRAP_CHAR);
-  else
-    set_wrap_mode(Gtk::WrapMode::WRAP_NONE);
-  property_highlight_current_line() = Config::get().source.highlight_current_line;
-  property_show_line_numbers() = Config::get().source.show_line_numbers;
-  if(Config::get().source.font.size()>0)
-    override_font(Pango::FontDescription(Config::get().source.font));
-  if(Config::get().source.show_background_pattern)
-    gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID);
-  else
-    gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE);
-  property_show_right_margin() = Config::get().source.show_right_margin;
-  property_right_margin_position() = Config::get().source.right_margin_position;
-  
-  //Create tags for diagnostic warnings and errors:
-  auto scheme = get_source_buffer()->get_style_scheme();
-  auto tag_table=get_buffer()->get_tag_table();
-  auto style=scheme->get_style("def:warning");
-  auto diagnostic_tag=get_buffer()->get_tag_table()->lookup("def:warning");
-  auto diagnostic_tag_underline=get_buffer()->get_tag_table()->lookup("def:warning_underline");
-  if(style && (style->property_foreground_set() || style->property_background_set())) {
-    Glib::ustring warning_property;
-    if(style->property_foreground_set()) {
-      warning_property=style->property_foreground().get_value();
-      diagnostic_tag->property_foreground() = warning_property;
-    }
-    else if(style->property_background_set())
-      warning_property=style->property_background().get_value();
-  
-    diagnostic_tag_underline->property_underline()=Pango::Underline::UNDERLINE_ERROR;
-    auto tag_class=G_OBJECT_GET_CLASS(diagnostic_tag_underline->gobj()); //For older GTK+ 3 versions:
-    auto param_spec=g_object_class_find_property(tag_class, "underline-rgba");
-    if(param_spec!=nullptr) {
-      diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(warning_property));
+    SpellCheckView::configure();
+    DiffView::configure();
+
+    if (Config::get().source.style.size() > 0) {
+        auto scheme = StyleSchemeManager::get_default()->get_scheme(Config::get().source.style);
+        if (scheme)
+            get_source_buffer()->set_style_scheme(scheme);
+    }
+
+    set_draw_spaces(parse_show_whitespace_characters(Config::get().source.show_whitespace_characters));
+
+    if (Config::get().source.wrap_lines)
+        set_wrap_mode(Gtk::WrapMode::WRAP_CHAR);
+    else
+        set_wrap_mode(Gtk::WrapMode::WRAP_NONE);
+    property_highlight_current_line() = Config::get().source.highlight_current_line;
+    property_show_line_numbers() = Config::get().source.show_line_numbers;
+    if (Config::get().source.font.size() > 0)
+        override_font(Pango::FontDescription(Config::get().source.font));
+    if (Config::get().source.show_background_pattern)
+        gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID);
+    else
+        gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE);
+    property_show_right_margin() = Config::get().source.show_right_margin;
+    property_right_margin_position() = Config::get().source.right_margin_position;
+
+    //Create tags for diagnostic warnings and errors:
+    auto scheme = get_source_buffer()->get_style_scheme();
+    auto tag_table = get_buffer()->get_tag_table();
+    auto style = scheme->get_style("def:warning");
+    auto diagnostic_tag = get_buffer()->get_tag_table()->lookup("def:warning");
+    auto diagnostic_tag_underline = get_buffer()->get_tag_table()->lookup("def:warning_underline");
+    if (style && (style->property_foreground_set() || style->property_background_set())) {
+        Glib::ustring warning_property;
+        if (style->property_foreground_set()) {
+            warning_property = style->property_foreground().get_value();
+            diagnostic_tag->property_foreground() = warning_property;
+        } else if (style->property_background_set())
+            warning_property = style->property_background().get_value();
+
+        diagnostic_tag_underline->property_underline() = Pango::Underline::UNDERLINE_ERROR;
+        auto tag_class = G_OBJECT_GET_CLASS(diagnostic_tag_underline->gobj()); //For older GTK+ 3 versions:
+        auto param_spec = g_object_class_find_property(tag_class, "underline-rgba");
+        if (param_spec != nullptr) {
+            diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(warning_property));
+        }
+    }
+    style = scheme->get_style("def:error");
+    diagnostic_tag = get_buffer()->get_tag_table()->lookup("def:error");
+    diagnostic_tag_underline = get_buffer()->get_tag_table()->lookup("def:error_underline");
+    if (style && (style->property_foreground_set() || style->property_background_set())) {
+        Glib::ustring error_property;
+        if (style->property_foreground_set()) {
+            error_property = style->property_foreground().get_value();
+            diagnostic_tag->property_foreground() = error_property;
+        } else if (style->property_background_set())
+            error_property = style->property_background().get_value();
+
+        diagnostic_tag_underline->property_underline() = Pango::Underline::UNDERLINE_ERROR;
+        diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(error_property));
+    }
+    //TODO: clear tag_class and param_spec?
+
+    if (Config::get().menu.keys["source_show_completion"].empty()) {
+        get_completion()->unblock_interactive();
+        interactive_completion = true;
+    } else {
+        get_completion()->block_interactive();
+        interactive_completion = false;
     }
-  }
-  style=scheme->get_style("def:error");
-  diagnostic_tag=get_buffer()->get_tag_table()->lookup("def:error");
-  diagnostic_tag_underline=get_buffer()->get_tag_table()->lookup("def:error_underline");
-  if(style && (style->property_foreground_set() || style->property_background_set())) {
-    Glib::ustring error_property;
-    if(style->property_foreground_set()) {
-      error_property=style->property_foreground().get_value();
-      diagnostic_tag->property_foreground() = error_property;
-    }
-    else if(style->property_background_set())
-      error_property=style->property_background().get_value();
-    
-    diagnostic_tag_underline->property_underline()=Pango::Underline::UNDERLINE_ERROR;
-    diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(error_property));
-  }
-  //TODO: clear tag_class and param_spec?
-  
-  if(Config::get().menu.keys["source_show_completion"].empty()) {
-    get_completion()->unblock_interactive();
-    interactive_completion=true;
-  }
-  else {
-    get_completion()->block_interactive();
-    interactive_completion=false;
-  }
 }
 
 void Source::View::setup_tooltip_and_dialog_events() {
-  type_tooltips.on_motion=[this] {
-    delayed_tooltips_connection.disconnect();
-  };
-  diagnostic_tooltips.on_motion=[this] {
-    delayed_tooltips_connection.disconnect();
-  };
-  
-  get_buffer()->signal_changed().connect([this] {
-    hide_tooltips();
-  });
-  
-  signal_motion_notify_event().connect([this](GdkEventMotion* event) {
-    if(on_motion_last_x!=event->x || on_motion_last_y!=event->y) {
-      delayed_tooltips_connection.disconnect();
-      if((event->state&GDK_BUTTON1_MASK)==0) {
-        gdouble x=event->x;
-        gdouble y=event->y;
-        delayed_tooltips_connection=Glib::signal_timeout().connect([this, x, y]() {
-          type_tooltips.hide();
-          diagnostic_tooltips.hide();
-          Tooltips::init();
-          Gdk::Rectangle rectangle(x, y, 1, 1);
-          if(parsed) {
-            show_type_tooltips(rectangle);
-            show_diagnostic_tooltips(rectangle);
-          }
-          return false;
-        }, 100);
-      }
-      auto last_mouse_pos = std::make_pair(on_motion_last_x, on_motion_last_y);
-      auto mouse_pos = std::make_pair(event->x, event->y);
-      type_tooltips.hide(last_mouse_pos, mouse_pos);
-      diagnostic_tooltips.hide(last_mouse_pos, mouse_pos);
-    }
-    on_motion_last_x=event->x;
-    on_motion_last_y=event->y;
-    return false;
-  });
-  
-  get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark) {
-    if(get_buffer()->get_has_selection() && mark->get_name()=="selection_bound")
-      delayed_tooltips_connection.disconnect();
-    
-    if(mark->get_name()=="insert") {
-      hide_tooltips();
-      delayed_tooltips_connection=Glib::signal_timeout().connect([this]() {
-        Tooltips::init();
-        Gdk::Rectangle rectangle;
-        get_iter_location(get_buffer()->get_insert()->get_iter(), rectangle);
-        int location_window_x, location_window_y;
-        buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_window_x, location_window_y);
-        rectangle.set_x(location_window_x-2);
-        rectangle.set_y(location_window_y);
-        rectangle.set_width(5);
-        if(parsed) {
-          show_type_tooltips(rectangle);
-          show_diagnostic_tooltips(rectangle);
+    type_tooltips.on_motion = [this] {
+        delayed_tooltips_connection.disconnect();
+    };
+    diagnostic_tooltips.on_motion = [this] {
+        delayed_tooltips_connection.disconnect();
+    };
+
+    get_buffer()->signal_changed().connect([this] {
+        hide_tooltips();
+    });
+
+    signal_motion_notify_event().connect([this](GdkEventMotion *event) {
+        if (on_motion_last_x != event->x || on_motion_last_y != event->y) {
+            delayed_tooltips_connection.disconnect();
+            if ((event->state & GDK_BUTTON1_MASK) == 0) {
+                gdouble x = event->x;
+                gdouble y = event->y;
+                delayed_tooltips_connection = Glib::signal_timeout().connect([this, x, y]() {
+                    type_tooltips.hide();
+                    diagnostic_tooltips.hide();
+                    Tooltips::init();
+                    Gdk::Rectangle rectangle(x, y, 1, 1);
+                    if (parsed) {
+                        show_type_tooltips(rectangle);
+                        show_diagnostic_tooltips(rectangle);
+                    }
+                    return false;
+                }, 100);
+            }
+            auto last_mouse_pos = std::make_pair(on_motion_last_x, on_motion_last_y);
+            auto mouse_pos = std::make_pair(event->x, event->y);
+            type_tooltips.hide(last_mouse_pos, mouse_pos);
+            diagnostic_tooltips.hide(last_mouse_pos, mouse_pos);
         }
+        on_motion_last_x = event->x;
+        on_motion_last_y = event->y;
         return false;
-      }, 500);
-      
-      if(SelectionDialog::get())
-        SelectionDialog::get()->hide();
-      if(CompletionDialog::get())
-        CompletionDialog::get()->hide();
-      
-      if(update_status_location)
-        update_status_location(this);
-    }
-  });
+    });
 
-  signal_scroll_event().connect([this](GdkEventScroll* event) {
-    hide_tooltips();
-    hide_dialogs();
-    return false;
-  });
-  
-  signal_focus_out_event().connect([this](GdkEventFocus* event) {
-    hide_tooltips();
-    return false;
-  });
-  
-  signal_leave_notify_event().connect([this](GdkEventCrossing*) {
-    delayed_tooltips_connection.disconnect();
-    return false;
-  });
+    get_buffer()->signal_mark_set().connect(
+            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+                if (get_buffer()->get_has_selection() && mark->get_name() == "selection_bound")
+                    delayed_tooltips_connection.disconnect();
+
+                if (mark->get_name() == "insert") {
+                    hide_tooltips();
+                    delayed_tooltips_connection = Glib::signal_timeout().connect([this]() {
+                        Tooltips::init();
+                        Gdk::Rectangle rectangle;
+                        get_iter_location(get_buffer()->get_insert()->get_iter(), rectangle);
+                        int location_window_x, location_window_y;
+                        buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(),
+                                                rectangle.get_y(), location_window_x, location_window_y);
+                        rectangle.set_x(location_window_x - 2);
+                        rectangle.set_y(location_window_y);
+                        rectangle.set_width(5);
+                        if (parsed) {
+                            show_type_tooltips(rectangle);
+                            show_diagnostic_tooltips(rectangle);
+                        }
+                        return false;
+                    }, 500);
+
+                    if (SelectionDialog::get())
+                        SelectionDialog::get()->hide();
+                    if (CompletionDialog::get())
+                        CompletionDialog::get()->hide();
+
+                    if (update_status_location)
+                        update_status_location(this);
+                }
+            });
+
+    signal_scroll_event().connect([this](GdkEventScroll *event) {
+        hide_tooltips();
+        hide_dialogs();
+        return false;
+    });
+
+    signal_focus_out_event().connect([this](GdkEventFocus *event) {
+        hide_tooltips();
+        return false;
+    });
+
+    signal_leave_notify_event().connect([this](GdkEventCrossing *) {
+        delayed_tooltips_connection.disconnect();
+        return false;
+    });
 }
 
 void Source::View::setup_format_style(bool is_generic_view) {
-  static auto prettier = filesystem::find_executable("prettier");
-  if(!prettier.empty() && language &&
-     (language->get_id()=="js" || language->get_id()=="json" || language->get_id()=="css")) {
-    if(is_generic_view) {
-      goto_next_diagnostic=[this] {
-        place_cursor_at_next_diagnostic();
-      };
-      get_buffer()->signal_changed().connect([this] {
-        clear_diagnostic_tooltips();
-        status_diagnostics=std::make_tuple<size_t, size_t, size_t>(0, 0, 0);
-        if(update_status_diagnostics)
-          update_status_diagnostics(this);
-      });
-    }
-    format_style=[this, is_generic_view](bool continue_without_style_file) {
-      auto command=prettier.string();
-      if(!continue_without_style_file) {
-        std::stringstream stdin_stream, stdout_stream;
-        auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, command+" --find-config-path "+this->file_path.string());
-        if(exit_status==0) {
-          if(stdout_stream.tellp()==0)
-            return;
-        }
-        else
-          return;
-      }
-      
-      command+=" --stdin-filepath "+this->file_path.string()+" --print-width 120 --config-precedence prefer-file";
-      
-      if(get_buffer()->get_has_selection()) { // Cannot be used together with --cursor-offset
-        Gtk::TextIter start, end;
-        get_buffer()->get_selection_bounds(start, end);
-        command+=" --range-start "+std::to_string(start.get_offset());
-        command+=" --range-end "+std::to_string(end.get_offset());
-      }
-      else
-        command+=" --cursor-offset "+std::to_string(get_buffer()->get_insert()->get_iter().get_offset());
-      
-      size_t num_warnings=0, num_errors=0, num_fix_its=0;
-      if(is_generic_view)
-        clear_diagnostic_tooltips();
-      
-      std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream, stderr_stream;
-      auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, command, this->file_path.parent_path(), &stderr_stream);
-      if(exit_status==0) {
-        replace_text(stdout_stream.str());
-        std::string line;
-        std::getline(stderr_stream, line);
-        if(!line.empty() && line!="NaN") {
-          try {
-            auto offset=atoi(line.c_str());
-            if(offset<get_buffer()->size()) {
-              get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset));
-              hide_tooltips();
-            }
-          }
-          catch(...) {}
-        }
-      }
-      else if(is_generic_view) {
-        static std::regex regex("^\\[error\\] stdin: (.*) \\(([0-9]*):([0-9]*)\\)$");
-        std::string line;
-        std::getline(stderr_stream, line);
-        std::smatch sm;
-        if(std::regex_match(line, sm, regex)) {
-          try {
-            auto start=get_iter_at_line_offset(atoi(sm[2].str().c_str())-1, atoi(sm[3].str().c_str())-1);
-            ++num_errors;
-            if(start.ends_line())
-              start.backward_char();
-            auto end=start;
-            end.forward_char();
-            if(start==end)
-                start.forward_char();
-            
-            add_diagnostic_tooltip(start, end, sm[1].str(), true);
-          }
-          catch(...) {}
-        }
-      }
-      if(is_generic_view) {
-        status_diagnostics=std::make_tuple(num_warnings, num_errors, num_fix_its);
-        if(update_status_diagnostics)
-          update_status_diagnostics(this);
-      }
-    };
-  }
-  else if(is_bracket_language) {
-    format_style=[this](bool continue_without_style_file) {
-      static auto clang_format_command = filesystem::get_executable("clang-format").string();
-      
-      auto command=clang_format_command+" -output-replacements-xml -assume-filename="+filesystem::escape_argument(this->file_path.string());
-      
-      if(get_buffer()->get_has_selection()) {
-        Gtk::TextIter start, end;
-        get_buffer()->get_selection_bounds(start, end);
-        command+=" -lines="+std::to_string(start.get_line()+1)+':'+std::to_string(end.get_line()+1);
-      }
-      
-      bool use_style_file=false;
-      auto style_file_search_path=this->file_path.parent_path();
-      while(true) {
-        if(boost::filesystem::exists(style_file_search_path/".clang-format") || boost::filesystem::exists(style_file_search_path/"_clang-format")) {
-          use_style_file=true;
-          break;
-        }
-        if(style_file_search_path==style_file_search_path.root_directory())
-          break;
-        style_file_search_path=style_file_search_path.parent_path();
-      }
-      
-      if(use_style_file)
-        command+=" -style=file";
-      else {
-        if(!continue_without_style_file)
-          return;
-        unsigned indent_width;
-        std::string tab_style;
-        if(tab_char=='\t') {
-          indent_width=tab_size*8;
-          tab_style="UseTab: Always";
+    static auto prettier = filesystem::find_executable("prettier");
+    if (!prettier.empty() && language &&
+        (language->get_id() == "js" || language->get_id() == "json" || language->get_id() == "css")) {
+        if (is_generic_view) {
+            goto_next_diagnostic = [this] {
+                place_cursor_at_next_diagnostic();
+            };
+            get_buffer()->signal_changed().connect([this] {
+                clear_diagnostic_tooltips();
+                status_diagnostics = std::make_tuple<size_t, size_t, size_t>(0, 0, 0);
+                if (update_status_diagnostics)
+                    update_status_diagnostics(this);
+            });
         }
-        else {
-          indent_width=tab_size;
-          tab_style="UseTab: Never";
-        }
-        command+=" -style=\"{IndentWidth: "+std::to_string(indent_width);
-        command+=", "+tab_style;
-        command+=", "+std::string("AccessModifierOffset: -")+std::to_string(indent_width);
-        if(Config::get().source.clang_format_style!="")
-          command+=", "+Config::get().source.clang_format_style;
-        command+="}\"";
-      }
-      
-      std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream;
-      
-      auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, command, this->file_path.parent_path());
-      if(exit_status==0) {
-        // The following code is complex due to clang-format returning offsets in byte offsets instead of char offsets
-        
-        // Create bytes_in_lines cache to significantly speed up the processing of finding iterators from byte offsets
-        std::vector<size_t> bytes_in_lines;
-        auto line_count=get_buffer()->get_line_count();
-        for(int line_nr=0;line_nr<line_count;++line_nr) {
-          auto iter=get_buffer()->get_iter_at_line(line_nr);
-          bytes_in_lines.emplace_back(iter.get_bytes_in_line());
-        }
-        
-        get_buffer()->begin_user_action();
-        try {
-          boost::property_tree::ptree pt;
-          boost::property_tree::xml_parser::read_xml(stdout_stream, pt);
-          auto replacements_pt=pt.get_child("replacements");
-          for(auto it=replacements_pt.rbegin();it!=replacements_pt.rend();++it) {
-            if(it->first=="replacement") {
-              auto offset=it->second.get<size_t>("<xmlattr>.offset");
-              auto length=it->second.get<size_t>("<xmlattr>.length");
-              auto replacement_str=it->second.get<std::string>("");
-              
-              size_t bytes=0;
-              for(size_t c=0;c<bytes_in_lines.size();++c) {
-                auto previous_bytes=bytes;
-                bytes+=bytes_in_lines[c];
-                if(offset<bytes || (c==bytes_in_lines.size()-1 && offset==bytes)) {
-                  std::pair<size_t, size_t> line_index(c, offset-previous_bytes);
-                  auto start=get_buffer()->get_iter_at_line_index(line_index.first, line_index.second);
-                  
-                  // Use left gravity insert to avoid moving cursor from end of line
-                  bool left_gravity_insert=false;
-                  if(get_buffer()->get_insert()->get_iter()==start) {
-                    auto iter=start;
-                    do {
-                      if(*iter!=' ' && *iter!='\t') {
-                        left_gravity_insert=iter.ends_line();
-                        break;
-                      }
-                    } while(iter.forward_char());
-                  }
-                  
-                  if(length>0) {
-                    auto offset_end=offset+length;
-                    size_t bytes=0;
-                    for(size_t c=0;c<bytes_in_lines.size();++c) {
-                      auto previous_bytes=bytes;
-                      bytes+=bytes_in_lines[c];
-                      if(offset_end<bytes || (c==bytes_in_lines.size()-1 && offset_end==bytes)) {
-                        auto end=get_buffer()->get_iter_at_line_index(c, offset_end-previous_bytes);
-                        get_buffer()->erase(start, end);
-                        start=get_buffer()->get_iter_at_line_index(line_index.first, line_index.second);
-                        break;
-                      }
+        format_style = [this, is_generic_view](bool continue_without_style_file) {
+            auto command = prettier.string();
+            if (!continue_without_style_file) {
+                std::stringstream stdin_stream, stdout_stream;
+                auto exit_status = Terminal::get().process(stdin_stream, stdout_stream,
+                                                           command + " --find-config-path " + this->file_path.string());
+                if (exit_status == 0) {
+                    if (stdout_stream.tellp() == 0)
+                        return;
+                } else
+                    return;
+            }
+
+            command += " --stdin-filepath " + this->file_path.string() +
+                       " --print-width 120 --config-precedence prefer-file";
+
+            if (get_buffer()->get_has_selection()) { // Cannot be used together with --cursor-offset
+                Gtk::TextIter start, end;
+                get_buffer()->get_selection_bounds(start, end);
+                command += " --range-start " + std::to_string(start.get_offset());
+                command += " --range-end " + std::to_string(end.get_offset());
+            } else
+                command += " --cursor-offset " + std::to_string(get_buffer()->get_insert()->get_iter().get_offset());
+
+            size_t num_warnings = 0, num_errors = 0, num_fix_its = 0;
+            if (is_generic_view)
+                clear_diagnostic_tooltips();
+
+            std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream, stderr_stream;
+            auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, command,
+                                                       this->file_path.parent_path(), &stderr_stream);
+            if (exit_status == 0) {
+                replace_text(stdout_stream.str());
+                std::string line;
+                std::getline(stderr_stream, line);
+                if (!line.empty() && line != "NaN") {
+                    try {
+                        auto offset = atoi(line.c_str());
+                        if (offset < get_buffer()->size()) {
+                            get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset));
+                            hide_tooltips();
+                        }
+                    }
+                    catch (...) {}
+                }
+            } else if (is_generic_view) {
+                static std::regex regex("^\\[error\\] stdin: (.*) \\(([0-9]*):([0-9]*)\\)$");
+                std::string line;
+                std::getline(stderr_stream, line);
+                std::smatch sm;
+                if (std::regex_match(line, sm, regex)) {
+                    try {
+                        auto start = get_iter_at_line_offset(atoi(sm[2].str().c_str()) - 1,
+                                                             atoi(sm[3].str().c_str()) - 1);
+                        ++num_errors;
+                        if (start.ends_line())
+                            start.backward_char();
+                        auto end = start;
+                        end.forward_char();
+                        if (start == end)
+                            start.forward_char();
+
+                        add_diagnostic_tooltip(start, end, sm[1].str(), true);
                     }
-                  }
-                  if(left_gravity_insert) {
-                    auto mark=get_buffer()->create_mark(start);
-                    get_buffer()->insert(start, replacement_str);
-                    get_buffer()->place_cursor(mark->get_iter());
-                    get_buffer()->delete_mark(mark);
-                  }
-                  else
-                    get_buffer()->insert(start, replacement_str);
-                  break;
+                    catch (...) {}
                 }
-              }
             }
-          }
-        }
-        catch(const std::exception &e) {
-          Terminal::get().print(std::string("Error: error parsing clang-format output: ")+e.what()+'\n', true);
-        }
-        get_buffer()->end_user_action();
-      }
-    };
-  }
-  else if(language && language->get_id()=="markdown") {
-    // The style file currently has no options, but checking if it exists
-    format_style=[this](bool continue_without_style_file) {
-      bool has_style_file=false;
-      auto style_file_search_path=this->file_path.parent_path();
-      while(true) {
-        if(boost::filesystem::exists(style_file_search_path/".markdown-format")) {
-          has_style_file=true;
-          break;
-        }
-        if(style_file_search_path==style_file_search_path.root_directory())
-          break;
-        style_file_search_path=style_file_search_path.parent_path();
-      }
-      if(!has_style_file && !continue_without_style_file)
-        return;
-      
-      auto special_character=[](Gtk::TextIter iter) {
-        if(*iter=='*' || *iter=='#' || *iter=='<' || *iter=='>' || *iter==' ' || *iter=='=' || *iter=='`' || *iter=='-')
-          return true;
-        // Tests if a line starts with for instance: 2. 
-        if(*iter>='0' && *iter<='9' && iter.forward_char() &&
-           *iter=='.' && iter.forward_char() &&
-           *iter==' ')
-          return true;
-        return false;
-      };
-      
-      get_buffer()->begin_user_action();
-      disable_spellcheck=true;
-      cleanup_whitespace_characters();
-      
-      auto iter=get_buffer()->begin();
-      size_t last_space_offset=-1;
-      bool headline=false;
-      bool monospace=false;
-      bool script=false;
-      bool html_tag=false;
-      int square_brackets=0;
-      do {
-        if(iter.starts_line()) {
-          last_space_offset=-1;
-          auto next_line_iter=iter;
-          if(*iter=='#' || (next_line_iter.forward_line() && *next_line_iter=='='))
-            headline=true;
-          else
-            headline=false;
-          auto test_iter=iter;
-          if(*test_iter=='`' && test_iter.forward_char() &&
-             *test_iter=='`' && test_iter.forward_char() &&
-             *test_iter=='`') {
-            script=!script;
-            iter.forward_chars(3);
-            continue;
-          }
-        }
-        if(!script && *iter=='`')
-          monospace=!monospace;
-        if(!script && !monospace) {
-          if(*iter=='<')
-            html_tag=true;
-          else if(*iter=='>')
-            html_tag=false;
-          else if(*iter=='[')
-            ++square_brackets;
-          else if(*iter==']')
-            --square_brackets;
-        }
-        if(!headline && !script && !monospace && !html_tag && square_brackets==0) {
-          if(*iter==' ' && iter.get_line_offset()<=80)
-            last_space_offset=iter.get_offset();
-          // Insert newline on long lines
-          else if((*iter==' ' || iter.ends_line()) && iter.get_line_offset()>80 && last_space_offset!=static_cast<size_t>(-1)) {
-            auto stored_iter=iter;
-            iter=get_buffer()->get_iter_at_offset(last_space_offset);
-            auto next_iter=iter;
-            next_iter.forward_char();
-            // Do not add newline if the next iter is a special character
-            if(special_character(next_iter)) {
-              iter=stored_iter;
-              if(*iter==' ')
-                last_space_offset=iter.get_offset();
-              continue;
-            }
-            iter=get_buffer()->erase(iter, next_iter);
-            iter=get_buffer()->insert(iter, "\n");
-            iter.backward_char();
-          }
-          // Remove newline on short lines
-          else if(iter.ends_line() && !iter.starts_line() && iter.get_line_offset()<=80) {
-            auto next_line_iter=iter;
-            // Do not remove newline if the next line for instance is a header
-            if(next_line_iter.forward_char() && !next_line_iter.ends_line() && !special_character(next_line_iter)) {
-              auto end_word_iter=next_line_iter;
-              // Do not remove newline if the word on the next line is too long
-              size_t diff=0;
-              while(*end_word_iter!=' ' && !end_word_iter.ends_line() && end_word_iter.forward_char())
-                ++diff;
-              if(iter.get_line_offset()+diff+1<=80) {
-                iter=get_buffer()->erase(iter, next_line_iter);
-                iter=get_buffer()->insert(iter, " ");
-                iter.backward_char();
-                if(iter.get_line_offset()<=80)
-                  last_space_offset=iter.get_offset();
-              }
+            if (is_generic_view) {
+                status_diagnostics = std::make_tuple(num_warnings, num_errors, num_fix_its);
+                if (update_status_diagnostics)
+                    update_status_diagnostics(this);
             }
-          }
-        }
-      } while(iter.forward_char());
-      disable_spellcheck=false;
-      get_buffer()->end_user_action();
-    };
-  }
+            hide_tooltips();
+        };
+    } else if (is_bracket_language) {
+        format_style = [this](bool continue_without_style_file) {
+            static auto clang_format_command = filesystem::get_executable("clang-format").string();
+
+            auto command = clang_format_command + " -output-replacements-xml -assume-filename=" +
+                           filesystem::escape_argument(this->file_path.string());
+
+            if (get_buffer()->get_has_selection()) {
+                Gtk::TextIter start, end;
+                get_buffer()->get_selection_bounds(start, end);
+                command += " -lines=" + std::to_string(start.get_line() + 1) + ':' + std::to_string(end.get_line() + 1);
+            }
+
+            bool use_style_file = false;
+            auto style_file_search_path = this->file_path.parent_path();
+            while (true) {
+                if (boost::filesystem::exists(style_file_search_path / ".clang-format") ||
+                    boost::filesystem::exists(style_file_search_path / "_clang-format")) {
+                    use_style_file = true;
+                    break;
+                }
+                if (style_file_search_path == style_file_search_path.root_directory())
+                    break;
+                style_file_search_path = style_file_search_path.parent_path();
+            }
+
+            if (use_style_file)
+                command += " -style=file";
+            else {
+                if (!continue_without_style_file)
+                    return;
+                unsigned indent_width;
+                std::string tab_style;
+                if (tab_char == '\t') {
+                    indent_width = tab_size * 8;
+                    tab_style = "UseTab: Always";
+                } else {
+                    indent_width = tab_size;
+                    tab_style = "UseTab: Never";
+                }
+                command += " -style=\"{IndentWidth: " + std::to_string(indent_width);
+                command += ", " + tab_style;
+                command += ", " + std::string("AccessModifierOffset: -") + std::to_string(indent_width);
+                if (Config::get().source.clang_format_style != "")
+                    command += ", " + Config::get().source.clang_format_style;
+                command += "}\"";
+            }
+
+            std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream;
+
+            auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, command,
+                                                       this->file_path.parent_path());
+            if (exit_status == 0) {
+                // The following code is complex due to clang-format returning offsets in byte offsets instead of char offsets
+
+                // Create bytes_in_lines cache to significantly speed up the processing of finding iterators from byte offsets
+                std::vector<size_t> bytes_in_lines;
+                auto line_count = get_buffer()->get_line_count();
+                for (int line_nr = 0; line_nr < line_count; ++line_nr) {
+                    auto iter = get_buffer()->get_iter_at_line(line_nr);
+                    bytes_in_lines.emplace_back(iter.get_bytes_in_line());
+                }
+
+                get_buffer()->begin_user_action();
+                try {
+                    boost::property_tree::ptree pt;
+                    boost::property_tree::xml_parser::read_xml(stdout_stream, pt);
+                    auto replacements_pt = pt.get_child("replacements");
+                    for (auto it = replacements_pt.rbegin(); it != replacements_pt.rend(); ++it) {
+                        if (it->first == "replacement") {
+                            auto offset = it->second.get<size_t>("<xmlattr>.offset");
+                            auto length = it->second.get<size_t>("<xmlattr>.length");
+                            auto replacement_str = it->second.get<std::string>("");
+
+                            size_t bytes = 0;
+                            for (size_t c = 0; c < bytes_in_lines.size(); ++c) {
+                                auto previous_bytes = bytes;
+                                bytes += bytes_in_lines[c];
+                                if (offset < bytes || (c == bytes_in_lines.size() - 1 && offset == bytes)) {
+                                    std::pair<size_t, size_t> line_index(c, offset - previous_bytes);
+                                    auto start = get_buffer()->get_iter_at_line_index(line_index.first,
+                                                                                      line_index.second);
+
+                                    // Use left gravity insert to avoid moving cursor from end of line
+                                    bool left_gravity_insert = false;
+                                    if (get_buffer()->get_insert()->get_iter() == start) {
+                                        auto iter = start;
+                                        do {
+                                            if (*iter != ' ' && *iter != '\t') {
+                                                left_gravity_insert = iter.ends_line();
+                                                break;
+                                            }
+                                        } while (iter.forward_char());
+                                    }
+
+                                    if (length > 0) {
+                                        auto offset_end = offset + length;
+                                        size_t bytes = 0;
+                                        for (size_t c = 0; c < bytes_in_lines.size(); ++c) {
+                                            auto previous_bytes = bytes;
+                                            bytes += bytes_in_lines[c];
+                                            if (offset_end < bytes ||
+                                                (c == bytes_in_lines.size() - 1 && offset_end == bytes)) {
+                                                auto end = get_buffer()->get_iter_at_line_index(c, offset_end -
+                                                                                                   previous_bytes);
+                                                get_buffer()->erase(start, end);
+                                                start = get_buffer()->get_iter_at_line_index(line_index.first,
+                                                                                             line_index.second);
+                                                break;
+                                            }
+                                        }
+                                    }
+                                    if (left_gravity_insert) {
+                                        auto mark = get_buffer()->create_mark(start);
+                                        get_buffer()->insert(start, replacement_str);
+                                        get_buffer()->place_cursor(mark->get_iter());
+                                        get_buffer()->delete_mark(mark);
+                                    } else
+                                        get_buffer()->insert(start, replacement_str);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+                catch (const std::exception &e) {
+                    Terminal::get().print(std::string("Error: error parsing clang-format output: ") + e.what() + '\n',
+                                          true);
+                }
+                get_buffer()->end_user_action();
+            }
+        };
+    } else if (language && language->get_id() == "markdown") {
+        // The style file currently has no options, but checking if it exists
+        format_style = [this](bool continue_without_style_file) {
+            bool has_style_file = false;
+            auto style_file_search_path = this->file_path.parent_path();
+            while (true) {
+                if (boost::filesystem::exists(style_file_search_path / ".markdown-format")) {
+                    has_style_file = true;
+                    break;
+                }
+                if (style_file_search_path == style_file_search_path.root_directory())
+                    break;
+                style_file_search_path = style_file_search_path.parent_path();
+            }
+            if (!has_style_file && !continue_without_style_file)
+                return;
+
+            auto special_character = [](Gtk::TextIter iter) {
+                if (*iter == '*' || *iter == '#' || *iter == '<' || *iter == '>' || *iter == ' ' || *iter == '=' ||
+                    *iter == '`' || *iter == '-')
+                    return true;
+                // Tests if a line starts with for instance: 2.
+                if (*iter >= '0' && *iter <= '9' && iter.forward_char() &&
+                    *iter == '.' && iter.forward_char() &&
+                    *iter == ' ')
+                    return true;
+                return false;
+            };
+
+            get_buffer()->begin_user_action();
+            disable_spellcheck = true;
+            cleanup_whitespace_characters();
+
+            auto iter = get_buffer()->begin();
+            size_t last_space_offset = -1;
+            bool headline = false;
+            bool monospace = false;
+            bool script = false;
+            bool html_tag = false;
+            int square_brackets = 0;
+            do {
+                if (iter.starts_line()) {
+                    last_space_offset = -1;
+                    auto next_line_iter = iter;
+                    if (*iter == '#' || (next_line_iter.forward_line() && *next_line_iter == '='))
+                        headline = true;
+                    else
+                        headline = false;
+                    auto test_iter = iter;
+                    if (*test_iter == '`' && test_iter.forward_char() &&
+                        *test_iter == '`' && test_iter.forward_char() &&
+                        *test_iter == '`') {
+                        script = !script;
+                        iter.forward_chars(3);
+                        continue;
+                    }
+                }
+                if (!script && *iter == '`')
+                    monospace = !monospace;
+                if (!script && !monospace) {
+                    if (*iter == '<')
+                        html_tag = true;
+                    else if (*iter == '>')
+                        html_tag = false;
+                    else if (*iter == '[')
+                        ++square_brackets;
+                    else if (*iter == ']')
+                        --square_brackets;
+                }
+                if (!headline && !script && !monospace && !html_tag && square_brackets == 0) {
+                    if (*iter == ' ' && iter.get_line_offset() <= 80)
+                        last_space_offset = iter.get_offset();
+                        // Insert newline on long lines
+                    else if ((*iter == ' ' || iter.ends_line()) && iter.get_line_offset() > 80 &&
+                             last_space_offset != static_cast<size_t>(-1)) {
+                        auto stored_iter = iter;
+                        iter = get_buffer()->get_iter_at_offset(last_space_offset);
+                        auto next_iter = iter;
+                        next_iter.forward_char();
+                        // Do not add newline if the next iter is a special character
+                        if (special_character(next_iter)) {
+                            iter = stored_iter;
+                            if (*iter == ' ')
+                                last_space_offset = iter.get_offset();
+                            continue;
+                        }
+                        iter = get_buffer()->erase(iter, next_iter);
+                        iter = get_buffer()->insert(iter, "\n");
+                        iter.backward_char();
+                    }
+                        // Remove newline on short lines
+                    else if (iter.ends_line() && !iter.starts_line() && iter.get_line_offset() <= 80) {
+                        auto next_line_iter = iter;
+                        // Do not remove newline if the next line for instance is a header
+                        if (next_line_iter.forward_char() && !next_line_iter.ends_line() &&
+                            !special_character(next_line_iter)) {
+                            auto end_word_iter = next_line_iter;
+                            // Do not remove newline if the word on the next line is too long
+                            size_t diff = 0;
+                            while (*end_word_iter != ' ' && !end_word_iter.ends_line() && end_word_iter.forward_char())
+                                ++diff;
+                            if (iter.get_line_offset() + diff + 1 <= 80) {
+                                iter = get_buffer()->erase(iter, next_line_iter);
+                                iter = get_buffer()->insert(iter, " ");
+                                iter.backward_char();
+                                if (iter.get_line_offset() <= 80)
+                                    last_space_offset = iter.get_offset();
+                            }
+                        }
+                    }
+                }
+            } while (iter.forward_char());
+            disable_spellcheck = false;
+            get_buffer()->end_user_action();
+        };
+    }
 }
 
-void Source::View::search_occurrences_updated(GtkWidget* widget, GParamSpec* property, gpointer data) {
-  auto view=static_cast<Source::View*>(data);
-  if(view->update_search_occurrences)
-    view->update_search_occurrences(gtk_source_search_context_get_occurrences_count(view->search_context));
+void Source::View::search_occurrences_updated(GtkWidget *widget, GParamSpec *property, gpointer data) {
+    auto view = static_cast<Source::View *>(data);
+    if (view->update_search_occurrences)
+        view->update_search_occurrences(gtk_source_search_context_get_occurrences_count(view->search_context));
 }
 
 Source::View::~View() {
-  g_clear_object(&search_context);
-  g_clear_object(&search_settings);
-  
-  delayed_tooltips_connection.disconnect();
-  delayed_tag_similar_symbols_connection.disconnect();
-  renderer_activate_connection.disconnect();
-  
-  non_deleted_views.erase(this);
-  views.erase(this);
+    g_clear_object(&search_context);
+    g_clear_object(&search_settings);
+
+    delayed_tooltips_connection.disconnect();
+    renderer_activate_connection.disconnect();
+
+    non_deleted_views.erase(this);
+    views.erase(this);
 }
 
 void Source::View::search_highlight(const std::string &text, bool case_sensitive, bool regex) {
-  gtk_source_search_settings_set_case_sensitive(search_settings, case_sensitive);
-  gtk_source_search_settings_set_regex_enabled(search_settings, regex);
-  gtk_source_search_settings_set_search_text(search_settings, text.c_str());
-  search_occurrences_updated(nullptr, nullptr, this);
+    gtk_source_search_settings_set_case_sensitive(search_settings, case_sensitive);
+    gtk_source_search_settings_set_regex_enabled(search_settings, regex);
+    gtk_source_search_settings_set_search_text(search_settings, text.c_str());
+    search_occurrences_updated(nullptr, nullptr, this);
 }
 
 void Source::View::search_forward() {
-  Gtk::TextIter insert, selection_bound;
-  get_buffer()->get_selection_bounds(insert, selection_bound);
-  auto& start=selection_bound;
-  Gtk::TextIter match_start, match_end;
+    Gtk::TextIter insert, selection_bound;
+    get_buffer()->get_selection_bounds(insert, selection_bound);
+    auto &start = selection_bound;
+    Gtk::TextIter match_start, match_end;
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-  gboolean has_wrapped_around;
-  if(gtk_source_search_context_forward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(), &has_wrapped_around)) {
+    gboolean has_wrapped_around;
+    if (gtk_source_search_context_forward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
+                                           &has_wrapped_around)) {
 #else
-  if(gtk_source_search_context_forward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
+        if(gtk_source_search_context_forward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
 #endif
-    get_buffer()->select_range(match_start, match_end);
-    scroll_to(get_buffer()->get_insert());
-  }
+        get_buffer()->select_range(match_start, match_end);
+        scroll_to(get_buffer()->get_insert());
+    }
 }
 
 void Source::View::search_backward() {
-  Gtk::TextIter insert, selection_bound;
-  get_buffer()->get_selection_bounds(insert, selection_bound);
-  auto &start=insert;
-  Gtk::TextIter match_start, match_end;
+    Gtk::TextIter insert, selection_bound;
+    get_buffer()->get_selection_bounds(insert, selection_bound);
+    auto &start = insert;
+    Gtk::TextIter match_start, match_end;
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-  gboolean has_wrapped_around;
-  if(gtk_source_search_context_backward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(), &has_wrapped_around)) {
+    gboolean has_wrapped_around;
+    if (gtk_source_search_context_backward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
+                                            &has_wrapped_around)) {
 #else
-  if(gtk_source_search_context_backward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
+        if(gtk_source_search_context_backward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
 #endif
-    get_buffer()->select_range(match_start, match_end);
-    scroll_to(get_buffer()->get_insert());
-  }
+        get_buffer()->select_range(match_start, match_end);
+        scroll_to(get_buffer()->get_insert());
+    }
 }
 
 void Source::View::replace_forward(const std::string &replacement) {
-  Gtk::TextIter insert, selection_bound;
-  get_buffer()->get_selection_bounds(insert, selection_bound);
-  auto &start=insert;
-  Gtk::TextIter match_start, match_end;
+    Gtk::TextIter insert, selection_bound;
+    get_buffer()->get_selection_bounds(insert, selection_bound);
+    auto &start = insert;
+    Gtk::TextIter match_start, match_end;
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-  gboolean has_wrapped_around;
-  if(gtk_source_search_context_forward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(), &has_wrapped_around)) {
+    gboolean has_wrapped_around;
+    if (gtk_source_search_context_forward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
+                                           &has_wrapped_around)) {
 #else
-  if(gtk_source_search_context_forward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
+        if(gtk_source_search_context_forward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
 #endif
-    auto offset=match_start.get_offset();
+        auto offset = match_start.get_offset();
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-    gtk_source_search_context_replace2(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
+        gtk_source_search_context_replace2(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(),
+                                           replacement.size(), nullptr);
 #else
-    gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
+        gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
 #endif
-    
-    Glib::ustring replacement_ustring=replacement;
-    get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset), get_buffer()->get_iter_at_offset(offset+replacement_ustring.size()));
-    scroll_to(get_buffer()->get_insert());
-  }
+
+        Glib::ustring replacement_ustring = replacement;
+        get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset),
+                                   get_buffer()->get_iter_at_offset(offset + replacement_ustring.size()));
+        scroll_to(get_buffer()->get_insert());
+    }
 }
 
 void Source::View::replace_backward(const std::string &replacement) {
-  Gtk::TextIter insert, selection_bound;
-  get_buffer()->get_selection_bounds(insert, selection_bound);
-  auto &start=selection_bound;
-  Gtk::TextIter match_start, match_end;
+    Gtk::TextIter insert, selection_bound;
+    get_buffer()->get_selection_bounds(insert, selection_bound);
+    auto &start = selection_bound;
+    Gtk::TextIter match_start, match_end;
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-  gboolean has_wrapped_around;
-  if(gtk_source_search_context_backward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(), &has_wrapped_around)) {
+    gboolean has_wrapped_around;
+    if (gtk_source_search_context_backward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
+                                            &has_wrapped_around)) {
 #else
-  if(gtk_source_search_context_backward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
+        if(gtk_source_search_context_backward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
 #endif
-    auto offset=match_start.get_offset();
+        auto offset = match_start.get_offset();
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-    gtk_source_search_context_replace2(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
+        gtk_source_search_context_replace2(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(),
+                                           replacement.size(), nullptr);
 #else
-    gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
+        gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
 #endif
 
-    get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset), get_buffer()->get_iter_at_offset(offset+replacement.size()));
-    scroll_to(get_buffer()->get_insert());
-  }
+        get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset),
+                                   get_buffer()->get_iter_at_offset(offset + replacement.size()));
+        scroll_to(get_buffer()->get_insert());
+    }
 }
 
 void Source::View::replace_all(const std::string &replacement) {
-  gtk_source_search_context_replace_all(search_context, replacement.c_str(), replacement.size(), nullptr);
+    gtk_source_search_context_replace_all(search_context, replacement.c_str(), replacement.size(), nullptr);
 }
 
 void Source::View::paste() {
-  class Guard {
-  public:
-    bool &value;
-    Guard(bool &value_) : value(value_) { value = true; }
-    ~Guard() { value = false; }
-  };
-  Guard guard{multiple_cursors_use};
-  
-  std::string text=Gtk::Clipboard::get()->wait_for_text();
-  
-  //Replace carriage returns (which leads to crash) with newlines
-  for(size_t c=0;c<text.size();c++) {
-    if(text[c]=='\r') {
-      if((c+1)<text.size() && text[c+1]=='\n')
-        text.replace(c, 2, "\n");
-      else
-        text.replace(c, 1, "\n");
-    }
-  }
-  
-  //Exception for when pasted text is only whitespaces
-  bool only_whitespaces=true;
-  for(auto &chr: text) {
-    if(chr!='\n' && chr!='\r' && chr!=' ' && chr!='\t') {
-      only_whitespaces=false;
-      break;
+    class Guard {
+    public:
+        bool &value;
+
+        Guard(bool &value_) : value(value_) { value = true; }
+
+        ~Guard() { value = false; }
+    };
+    Guard guard{multiple_cursors_use};
+
+    std::string text = Gtk::Clipboard::get()->wait_for_text();
+
+    //Replace carriage returns (which leads to crash) with newlines
+    for (size_t c = 0; c < text.size(); c++) {
+        if (text[c] == '\r') {
+            if ((c + 1) < text.size() && text[c + 1] == '\n')
+                text.replace(c, 2, "\n");
+            else
+                text.replace(c, 1, "\n");
+        }
     }
-  }
-  if(only_whitespaces) {
-    Gtk::Clipboard::get()->set_text(text);
-    get_buffer()->paste_clipboard(Gtk::Clipboard::get());
-    scroll_to_cursor_delayed(this, false, false);
-    return;
-  }
-  
-  get_buffer()->begin_user_action();
-  if(get_buffer()->get_has_selection()) {
-    Gtk::TextIter start, end;
-    get_buffer()->get_selection_bounds(start, end);
-    get_buffer()->erase(start, end);
-  }
-  auto iter=get_buffer()->get_insert()->get_iter();
-  auto tabs_end_iter=get_tabs_end_iter();
-  auto prefix_tabs=get_line_before(iter<tabs_end_iter?iter:tabs_end_iter);
-
-  size_t start_line=0;
-  size_t end_line=0;
-  bool paste_line=false;
-  bool first_paste_line=true;
-  size_t paste_line_tabs=-1;
-  bool first_paste_line_has_tabs=false;
-  for(size_t c=0;c<text.size();c++) {
-    if(text[c]=='\n') {
-      end_line=c;
-      paste_line=true;
-    }
-    else if(c==text.size()-1) {
-      end_line=c+1;
-      paste_line=true;
-    }
-    if(paste_line) {
-      bool empty_line=true;
-      std::string line=text.substr(start_line, end_line-start_line);
-      size_t tabs=0;
-      for(auto chr: line) {
-        if(chr==tab_char)
-          tabs++;
-        else {
-          empty_line=false;
-          break;
+
+    //Exception for when pasted text is only whitespaces
+    bool only_whitespaces = true;
+    for (auto &chr: text) {
+        if (chr != '\n' && chr != '\r' && chr != ' ' && chr != '\t') {
+            only_whitespaces = false;
+            break;
         }
-      }
-      if(first_paste_line) {
-        if(tabs!=0) {
-          first_paste_line_has_tabs=true;
-          paste_line_tabs=tabs;
+    }
+    if (only_whitespaces) {
+        Gtk::Clipboard::get()->set_text(text);
+        get_buffer()->paste_clipboard(Gtk::Clipboard::get());
+        scroll_to_cursor_delayed(this, false, false);
+        return;
+    }
+
+    get_buffer()->begin_user_action();
+    if (get_buffer()->get_has_selection()) {
+        Gtk::TextIter start, end;
+        get_buffer()->get_selection_bounds(start, end);
+        get_buffer()->erase(start, end);
+    }
+    auto iter = get_buffer()->get_insert()->get_iter();
+    auto tabs_end_iter = get_tabs_end_iter();
+    auto prefix_tabs = get_line_before(iter < tabs_end_iter ? iter : tabs_end_iter);
+
+    size_t start_line = 0;
+    size_t end_line = 0;
+    bool paste_line = false;
+    bool first_paste_line = true;
+    size_t paste_line_tabs = -1;
+    bool first_paste_line_has_tabs = false;
+    for (size_t c = 0; c < text.size(); c++) {
+        if (text[c] == '\n') {
+            end_line = c;
+            paste_line = true;
+        } else if (c == text.size() - 1) {
+            end_line = c + 1;
+            paste_line = true;
         }
-        first_paste_line=false;
-      }
-      else if(!empty_line)
-        paste_line_tabs=std::min(paste_line_tabs, tabs);
+        if (paste_line) {
+            bool empty_line = true;
+            std::string line = text.substr(start_line, end_line - start_line);
+            size_t tabs = 0;
+            for (auto chr: line) {
+                if (chr == tab_char)
+                    tabs++;
+                else {
+                    empty_line = false;
+                    break;
+                }
+            }
+            if (first_paste_line) {
+                if (tabs != 0) {
+                    first_paste_line_has_tabs = true;
+                    paste_line_tabs = tabs;
+                }
+                first_paste_line = false;
+            } else if (!empty_line)
+                paste_line_tabs = std::min(paste_line_tabs, tabs);
 
-      start_line=end_line+1;
-      paste_line=false;
+            start_line = end_line + 1;
+            paste_line = false;
+        }
     }
-  }
-  if(paste_line_tabs==static_cast<size_t>(-1))
-    paste_line_tabs=0;
-  start_line=0;
-  end_line=0;
-  paste_line=false;
-  first_paste_line=true;
-  for(size_t c=0;c<text.size();c++) {
-    if(text[c]=='\n') {
-      end_line=c;
-      paste_line=true;
-    }
-    else if(c==text.size()-1) {
-      end_line=c+1;
-      paste_line=true;
-    }
-    if(paste_line) {
-      std::string line=text.substr(start_line, end_line-start_line);
-      size_t line_tabs=0;
-      for(auto chr: line) {
-        if(chr==tab_char)
-          line_tabs++;
-        else
-          break;
-      }
-      auto tabs=paste_line_tabs;
-      if(!(first_paste_line && !first_paste_line_has_tabs) && line_tabs<paste_line_tabs) {
-        tabs=line_tabs;
-      }
-      
-      if(first_paste_line) {
-        if(first_paste_line_has_tabs)
-          get_buffer()->insert_at_cursor(text.substr(start_line+tabs, end_line-start_line-tabs));
-        else
-          get_buffer()->insert_at_cursor(text.substr(start_line, end_line-start_line));
-        first_paste_line=false;
-      }
-      else
-        get_buffer()->insert_at_cursor('\n'+prefix_tabs+text.substr(start_line+tabs, end_line-start_line-tabs));
-      start_line=end_line+1;
-      paste_line=false;
+    if (paste_line_tabs == static_cast<size_t>(-1))
+        paste_line_tabs = 0;
+    start_line = 0;
+    end_line = 0;
+    paste_line = false;
+    first_paste_line = true;
+    for (size_t c = 0; c < text.size(); c++) {
+        if (text[c] == '\n') {
+            end_line = c;
+            paste_line = true;
+        } else if (c == text.size() - 1) {
+            end_line = c + 1;
+            paste_line = true;
+        }
+        if (paste_line) {
+            std::string line = text.substr(start_line, end_line - start_line);
+            size_t line_tabs = 0;
+            for (auto chr: line) {
+                if (chr == tab_char)
+                    line_tabs++;
+                else
+                    break;
+            }
+            auto tabs = paste_line_tabs;
+            if (!(first_paste_line && !first_paste_line_has_tabs) && line_tabs < paste_line_tabs) {
+                tabs = line_tabs;
+            }
+
+            if (first_paste_line) {
+                if (first_paste_line_has_tabs)
+                    get_buffer()->insert_at_cursor(text.substr(start_line + tabs, end_line - start_line - tabs));
+                else
+                    get_buffer()->insert_at_cursor(text.substr(start_line, end_line - start_line));
+                first_paste_line = false;
+            } else
+                get_buffer()->insert_at_cursor(
+                        '\n' + prefix_tabs + text.substr(start_line + tabs, end_line - start_line - tabs));
+            start_line = end_line + 1;
+            paste_line = false;
+        }
     }
-  }
-  // add final newline if present in text
-  if(text.size()>0 && text.back()=='\n')
-    get_buffer()->insert_at_cursor('\n'+prefix_tabs);
-  get_buffer()->place_cursor(get_buffer()->get_insert()->get_iter());
-  get_buffer()->end_user_action();
-  scroll_to_cursor_delayed(this, false, false);
+    // add final newline if present in text
+    if (text.size() > 0 && text.back() == '\n')
+        get_buffer()->insert_at_cursor('\n' + prefix_tabs);
+    get_buffer()->place_cursor(get_buffer()->get_insert()->get_iter());
+    get_buffer()->end_user_action();
+    scroll_to_cursor_delayed(this, false, false);
 }
 
 void Source::View::hide_tooltips() {
-  delayed_tooltips_connection.disconnect();
-  delayed_tag_similar_symbols_connection.disconnect();
-  type_tooltips.hide();
-  diagnostic_tooltips.hide();
+    delayed_tooltips_connection.disconnect();
+    type_tooltips.hide();
+    diagnostic_tooltips.hide();
 }
 
-void Source::View::add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, std::string spelling, bool error) {
-  diagnostic_offsets.emplace(start.get_offset());
-  
-  std::string severity_tag_name = error ? "def:error" : "def:warning";
-  
-  auto create_tooltip_buffer=[this, spelling=std::move(spelling), error, severity_tag_name]() {
-    auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
-    tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), error ? "Error" : "Warning", severity_tag_name);
-    tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), ":\n"+spelling);
-    return tooltip_buffer;
-  };
-  diagnostic_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start), get_buffer()->create_mark(end));
-  
-  get_buffer()->apply_tag_by_name(severity_tag_name+"_underline", start, end);
-  
-  auto iter=get_buffer()->get_insert()->get_iter();
-  if(iter.ends_line()) {
-    auto next_iter=iter;
-    if(next_iter.forward_char())
-      get_buffer()->remove_tag_by_name(severity_tag_name+"_underline", iter, next_iter);
-  }
+void Source::View::add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, std::string spelling,
+                                          bool error) {
+    diagnostic_offsets.emplace(start.get_offset());
+
+    std::string severity_tag_name = error ? "def:error" : "def:warning";
+
+    auto create_tooltip_buffer = [this, spelling = std::move(spelling), error, severity_tag_name]() {
+        auto tooltip_buffer = Gtk::TextBuffer::create(get_buffer()->get_tag_table());
+        tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), error ? "Error" : "Warning",
+                                        severity_tag_name);
+        tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), ":\n" + spelling);
+        return tooltip_buffer;
+    };
+    diagnostic_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start),
+                                     get_buffer()->create_mark(end));
+
+    get_buffer()->apply_tag_by_name(severity_tag_name + "_underline", start, end);
+
+    auto iter = get_buffer()->get_insert()->get_iter();
+    if (iter.ends_line()) {
+        auto next_iter = iter;
+        if (next_iter.forward_char())
+            get_buffer()->remove_tag_by_name(severity_tag_name + "_underline", iter, next_iter);
+    }
 }
 
 void Source::View::clear_diagnostic_tooltips() {
-  diagnostic_offsets.clear();
-  diagnostic_tooltips.clear();
-  get_buffer()->remove_tag_by_name("def:warning_underline", get_buffer()->begin(), get_buffer()->end());
-  get_buffer()->remove_tag_by_name("def:error_underline", get_buffer()->begin(), get_buffer()->end());
+    diagnostic_offsets.clear();
+    diagnostic_tooltips.clear();
+    get_buffer()->remove_tag_by_name("def:warning_underline", get_buffer()->begin(), get_buffer()->end());
+    get_buffer()->remove_tag_by_name("def:error_underline", get_buffer()->begin(), get_buffer()->end());
 }
 
 void Source::View::hide_dialogs() {
-  SpellCheckView::hide_dialogs();
-  if(SelectionDialog::get())
-    SelectionDialog::get()->hide();
-  if(CompletionDialog::get())
-    CompletionDialog::get()->hide();
+    SpellCheckView::hide_dialogs();
+    if (SelectionDialog::get())
+        SelectionDialog::get()->hide();
+    if (CompletionDialog::get())
+        CompletionDialog::get()->hide();
 }
 
 bool Source::View::find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
-  long para_count=0;
-  long square_count=0;
-  long curly_count=0;
-  
-  do {
-    if(*iter=='(' && is_code_iter(iter))
-      para_count++;
-    else if(*iter==')' && is_code_iter(iter))
-      para_count--;
-    else if(*iter=='[' && is_code_iter(iter))
-      square_count++;
-    else if(*iter==']' && is_code_iter(iter))
-      square_count--;
-    else if(*iter=='{' && is_code_iter(iter))
-      curly_count++;
-    else if(*iter=='}' && is_code_iter(iter))
-      curly_count--;
-    
-    if(curly_count>0)
-      break;
-    
-    if(para_count>0 || square_count>0) {
-      found_iter=iter;
-      return true;
-    }
-  } while(iter.backward_char());
-  return false;
-}
+    long para_count = 0;
+    long square_count = 0;
+    long curly_count = 0;
 
-Gtk::TextIter Source::View::find_start_of_sentence(Gtk::TextIter iter) {
-  if(iter.starts_line())
-    return iter;
-  
-  bool stream_operator_test=false;
-  bool colon_test=false;
-  
-  if(*iter==';')
-    stream_operator_test=true;
-  if(*iter=='{') {
-    iter.backward_char();
-    colon_test=true;
-  }
-  
-  int para_count=0;
-  int square_count=0;
-  long curly_count=0;
-  
-  do {
-    if(*iter=='(' && is_code_iter(iter))
-      para_count++;
-    else if(*iter==')' && is_code_iter(iter))
-      para_count--;
-    else if(*iter=='[' && is_code_iter(iter))
-      square_count++;
-    else if(*iter==']' && is_code_iter(iter))
-      square_count--;
-    else if(*iter=='{' && is_code_iter(iter))
-      curly_count++;
-    else if(*iter=='}' && is_code_iter(iter))
-      curly_count--;
-    
-    if(curly_count>0)
-      break;
-    
-    if(iter.starts_line() && para_count==0 && square_count==0) {
-      bool stream_operator_found=false;
-      bool colon_found=false;
-      // Handle << at the beginning of the sentence if iter initially started with ;
-      if(stream_operator_test) {
-        auto test_iter=get_tabs_end_iter(iter);
-        if(!test_iter.starts_line() && *test_iter=='<' && is_code_iter(test_iter) &&
-           test_iter.forward_char() && *test_iter=='<')
-          stream_operator_found=true;
-      }
-      // Handle : at the beginning of the sentence if iter initially started with {
-      else if(colon_test) {
-        auto test_iter=get_tabs_end_iter(iter);
-        if(!test_iter.starts_line() && *test_iter==':' && is_code_iter(test_iter))
-          colon_found=true;
-      }
-      // Handle : and , on previous line
-      if(!stream_operator_found && !colon_found) {
-        auto previous_iter=iter;
-        previous_iter.backward_char();
-        while(!previous_iter.starts_line() && (*previous_iter==' ' || previous_iter.ends_line()) && previous_iter.backward_char()) {}
-        if(*previous_iter!=',' && *previous_iter!=':')
-          return iter;
-        else if(*previous_iter==':') {
-          previous_iter.backward_char();
-          while(!previous_iter.starts_line() && *previous_iter==' ' && previous_iter.backward_char()) {}
-          if(*previous_iter==')') {
-            auto token=get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(previous_iter.get_line())));
-            if(token=="case")
-              return iter;
-          }
-          else
-            return iter;
-        }
-      }
-    }
-  } while(iter.backward_char());
-  
-  return iter;
-}
+    do {
+        if (*iter == '(' && is_code_iter(iter))
+            para_count++;
+        else if (*iter == ')' && is_code_iter(iter))
+            para_count--;
+        else if (*iter == '[' && is_code_iter(iter))
+            square_count++;
+        else if (*iter == ']' && is_code_iter(iter))
+            square_count--;
+        else if (*iter == '{' && is_code_iter(iter))
+            curly_count++;
+        else if (*iter == '}' && is_code_iter(iter))
+            curly_count--;
+
+        if (curly_count > 0)
+            break;
 
-bool Source::View::find_open_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
-  long count=0;
-  
-  do {
-    if(*iter=='{') {
-      if(count==0 && is_code_iter(iter)) {
-        found_iter=iter;
-        return true;
-      }
-      count++;
-    }
-    else if(*iter=='}' && is_code_iter(iter))
-      count--;
-  } while(iter.backward_char());
-  return false;
+        if (para_count > 0 || square_count > 0) {
+            found_iter = iter;
+            return true;
+        }
+    } while (iter.backward_char());
+    return false;
 }
 
-bool Source::View::find_close_curly_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
-  long count=0;
-  
-  do {
-    if(*iter=='}' && is_code_iter(iter)) {
-      if(count==0) {
-        found_iter=iter;
-        return true;
-      }
-      count--;
+Gtk::TextIter Source::View::find_start_of_sentence(Gtk::TextIter iter) {
+    if (iter.starts_line())
+        return iter;
+
+    bool stream_operator_test = false;
+    bool colon_test = false;
+
+    if (*iter == ';')
+        stream_operator_test = true;
+    if (*iter == '{') {
+        iter.backward_char();
+        colon_test = true;
     }
-    else if(*iter=='{' && is_code_iter(iter))
-      count++;
-  } while(iter.forward_char());
-  return false;
+
+    int para_count = 0;
+    int square_count = 0;
+    long curly_count = 0;
+
+    do {
+        if (*iter == '(' && is_code_iter(iter))
+            para_count++;
+        else if (*iter == ')' && is_code_iter(iter))
+            para_count--;
+        else if (*iter == '[' && is_code_iter(iter))
+            square_count++;
+        else if (*iter == ']' && is_code_iter(iter))
+            square_count--;
+        else if (*iter == '{' && is_code_iter(iter))
+            curly_count++;
+        else if (*iter == '}' && is_code_iter(iter))
+            curly_count--;
+
+        if (curly_count > 0)
+            break;
+
+        if (iter.starts_line() && para_count == 0 && square_count == 0) {
+            bool stream_operator_found = false;
+            bool colon_found = false;
+            // Handle << at the beginning of the sentence if iter initially started with ;
+            if (stream_operator_test) {
+                auto test_iter = get_tabs_end_iter(iter);
+                if (!test_iter.starts_line() && *test_iter == '<' && is_code_iter(test_iter) &&
+                    test_iter.forward_char() && *test_iter == '<')
+                    stream_operator_found = true;
+            }
+                // Handle : at the beginning of the sentence if iter initially started with {
+            else if (colon_test) {
+                auto test_iter = get_tabs_end_iter(iter);
+                if (!test_iter.starts_line() && *test_iter == ':' && is_code_iter(test_iter))
+                    colon_found = true;
+            }
+            // Handle : and , on previous line
+            if (!stream_operator_found && !colon_found) {
+                auto previous_iter = iter;
+                previous_iter.backward_char();
+                while (!previous_iter.starts_line() && (*previous_iter == ' ' || previous_iter.ends_line()) &&
+                       previous_iter.backward_char()) {}
+                if (*previous_iter != ',' && *previous_iter != ':')
+                    return iter;
+                else if (*previous_iter == ':') {
+                    previous_iter.backward_char();
+                    while (!previous_iter.starts_line() && *previous_iter == ' ' && previous_iter.backward_char()) {}
+                    if (*previous_iter == ')') {
+                        auto token = get_token(
+                                get_tabs_end_iter(get_buffer()->get_iter_at_line(previous_iter.get_line())));
+                        if (token == "case")
+                            return iter;
+                    } else
+                        return iter;
+                }
+            }
+        }
+    } while (iter.backward_char());
+
+    return iter;
+}
+
+bool Source::View::find_open_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
+    long count = 0;
+
+    do {
+        if (*iter == '{') {
+            if (count == 0 && is_code_iter(iter)) {
+                found_iter = iter;
+                return true;
+            }
+            count++;
+        } else if (*iter == '}' && is_code_iter(iter))
+            count--;
+    } while (iter.backward_char());
+    return false;
+}
+
+bool Source::View::find_close_curly_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
+    long count = 0;
+
+    do {
+        if (*iter == '}' && is_code_iter(iter)) {
+            if (count == 0) {
+                found_iter = iter;
+                return true;
+            }
+            count--;
+        } else if (*iter == '{' && is_code_iter(iter))
+            count++;
+    } while (iter.forward_char());
+    return false;
 }
 
 long Source::View::symbol_count(Gtk::TextIter iter, unsigned int positive_char, unsigned int negative_char) {
-  auto iter_stored=iter;
-  long symbol_count=0;
-  long curly_count=0;
-  bool break_on_curly=true;
-  if(positive_char=='{' || negative_char=='}')
-    break_on_curly=false;
-  bool check_if_next_iter_is_code_iter=false;
-  if(positive_char=='\'' || negative_char=='\'' || positive_char=='"' || negative_char=='"')
-    check_if_next_iter_is_code_iter=true;
-  
-  Gtk::TextIter previous_iter;
-  do {
-    if(*iter==positive_char && is_code_iter(iter))
-      symbol_count++;
-    else if(*iter==negative_char && is_code_iter(iter))
-      symbol_count--;
-    else if(*iter=='{' && is_code_iter(iter))
-      curly_count++;
-    else if(*iter=='}' && is_code_iter(iter))
-      curly_count--;
-    else if(check_if_next_iter_is_code_iter) {
-      auto next_iter=iter;
-      next_iter.forward_char();
-      if(*iter==positive_char && is_code_iter(next_iter))
-        symbol_count++;
-      else if(*iter==negative_char && is_code_iter(next_iter))
-        symbol_count--;
-    }
-    
-    if(break_on_curly && curly_count>0)
-      break;
-  } while(iter.backward_char());
-  
-  iter=iter_stored;
-  if(!iter.forward_char()) {
+    auto iter_stored = iter;
+    long symbol_count = 0;
+    long curly_count = 0;
+    bool break_on_curly = true;
+    if (positive_char == '{' || negative_char == '}')
+        break_on_curly = false;
+    bool check_if_next_iter_is_code_iter = false;
+    if (positive_char == '\'' || negative_char == '\'' || positive_char == '"' || negative_char == '"')
+        check_if_next_iter_is_code_iter = true;
+
+    Gtk::TextIter previous_iter;
+    do {
+        if (*iter == positive_char && is_code_iter(iter))
+            symbol_count++;
+        else if (*iter == negative_char && is_code_iter(iter))
+            symbol_count--;
+        else if (*iter == '{' && is_code_iter(iter))
+            curly_count++;
+        else if (*iter == '}' && is_code_iter(iter))
+            curly_count--;
+        else if (check_if_next_iter_is_code_iter) {
+            auto next_iter = iter;
+            next_iter.forward_char();
+            if (*iter == positive_char && is_code_iter(next_iter))
+                symbol_count++;
+            else if (*iter == negative_char && is_code_iter(next_iter))
+                symbol_count--;
+        }
+
+        if (break_on_curly && curly_count > 0)
+            break;
+    } while (iter.backward_char());
+
+    iter = iter_stored;
+    if (!iter.forward_char()) {
+        return symbol_count;
+    }
+
+    curly_count = 0;
+    do {
+        if (*iter == positive_char && is_code_iter(iter))
+            symbol_count++;
+        else if (*iter == negative_char && is_code_iter(iter))
+            symbol_count--;
+        else if (*iter == '{' && is_code_iter(iter))
+            curly_count++;
+        else if (*iter == '}' && is_code_iter(iter))
+            curly_count--;
+        else if (check_if_next_iter_is_code_iter) {
+            auto next_iter = iter;
+            next_iter.forward_char();
+            if (*iter == positive_char && is_code_iter(next_iter))
+                symbol_count++;
+            else if (*iter == negative_char && is_code_iter(next_iter))
+                symbol_count--;
+        }
+
+        if (break_on_curly && curly_count < 0)
+            break;
+    } while (iter.forward_char());
+
     return symbol_count;
-  }
-  
-  curly_count=0;
-  do {
-    if(*iter==positive_char && is_code_iter(iter))
-      symbol_count++;
-    else if(*iter==negative_char && is_code_iter(iter))
-      symbol_count--;
-    else if(*iter=='{' && is_code_iter(iter))
-      curly_count++;
-    else if(*iter=='}' && is_code_iter(iter))
-      curly_count--;
-    else if(check_if_next_iter_is_code_iter) {
-      auto next_iter=iter;
-      next_iter.forward_char();
-      if(*iter==positive_char && is_code_iter(next_iter))
-        symbol_count++;
-      else if(*iter==negative_char && is_code_iter(next_iter))
-        symbol_count--;
-    }
-    
-    if(break_on_curly && curly_count<0)
-      break;
-  } while(iter.forward_char());
-  
-  return symbol_count;
 }
 
 bool Source::View::is_templated_function(Gtk::TextIter iter, Gtk::TextIter &parenthesis_end_iter) {
-  auto iter_stored=iter;
-  long bracket_count=0;
-  long curly_count=0;
-  
-  if(!(iter.backward_char() && *iter=='>' && *iter_stored=='('))
-    return false;
-  
-  do {
-    if(*iter=='<' && is_code_iter(iter))
-      bracket_count++;
-    else if(*iter=='>' && is_code_iter(iter))
-      bracket_count--;
-    else if(*iter=='{' && is_code_iter(iter))
-      curly_count++;
-    else if(*iter=='}' && is_code_iter(iter))
-      curly_count--;
-    
-    if(bracket_count==0)
-      break;
-    
-    if(curly_count>0)
-      break;
-  } while(iter.backward_char());
-  
-  if(bracket_count!=0)
+    auto iter_stored = iter;
+    long bracket_count = 0;
+    long curly_count = 0;
+
+    if (!(iter.backward_char() && *iter == '>' && *iter_stored == '('))
+        return false;
+
+    do {
+        if (*iter == '<' && is_code_iter(iter))
+            bracket_count++;
+        else if (*iter == '>' && is_code_iter(iter))
+            bracket_count--;
+        else if (*iter == '{' && is_code_iter(iter))
+            curly_count++;
+        else if (*iter == '}' && is_code_iter(iter))
+            curly_count--;
+
+        if (bracket_count == 0)
+            break;
+
+        if (curly_count > 0)
+            break;
+    } while (iter.backward_char());
+
+    if (bracket_count != 0)
+        return false;
+
+    iter = iter_stored;
+    bracket_count = 0;
+    curly_count = 0;
+    do {
+        if (*iter == '(' && is_code_iter(iter))
+            bracket_count++;
+        else if (*iter == ')' && is_code_iter(iter))
+            bracket_count--;
+        else if (*iter == '{' && is_code_iter(iter))
+            curly_count++;
+        else if (*iter == '}' && is_code_iter(iter))
+            curly_count--;
+
+        if (bracket_count == 0) {
+            parenthesis_end_iter = iter;
+            return true;
+        }
+
+        if (curly_count < 0)
+            return false;
+    } while (iter.forward_char());
+
     return false;
-  
-  iter=iter_stored;
-  bracket_count=0;
-  curly_count=0;
-  do {
-    if(*iter=='(' && is_code_iter(iter))
-      bracket_count++;
-    else if(*iter==')' && is_code_iter(iter))
-      bracket_count--;
-    else if(*iter=='{' && is_code_iter(iter))
-      curly_count++;
-    else if(*iter=='}' && is_code_iter(iter))
-      curly_count--;
-    
-    if(bracket_count==0) {
-      parenthesis_end_iter=iter;
-      return true;
-    }
-    
-    if(curly_count<0)
-      return false;
-  } while(iter.forward_char());
-  
-  return false;
 }
 
 std::string Source::View::get_token(Gtk::TextIter iter) {
-  auto start=iter;
-  auto end=iter;
-  
-  while((*iter>='A' && *iter<='Z') || (*iter>='a' && *iter<='z') || (*iter>='0' && *iter<='9') || *iter=='_') {
-    start=iter;
-    if(!iter.backward_char())
-      break;
-  }
-  while((*end>='A' && *end<='Z') || (*end>='a' && *end<='z') || (*end>='0' && *end<='9') || *end=='_') {
-    if(!end.forward_char())
-      break;
-  }
-  
-  return get_buffer()->get_text(start, end);
-}
+    auto start = iter;
+    auto end = iter;
 
-void Source::View::cleanup_whitespace_characters_on_return(const Gtk::TextIter &iter) {
-  auto start_blank_iter=iter;
-  auto end_blank_iter=iter;
-  while((*end_blank_iter==' ' || *end_blank_iter=='\t') &&
-        !end_blank_iter.ends_line() && end_blank_iter.forward_char()) {}
-  if(!start_blank_iter.starts_line()) {
-    start_blank_iter.backward_char();
-    while((*start_blank_iter==' ' || *start_blank_iter=='\t') &&
-          !start_blank_iter.starts_line() && start_blank_iter.backward_char()) {}
-    if(*start_blank_iter!=' ' && *start_blank_iter!='\t')
-      start_blank_iter.forward_char();
-  }
+    while ((*iter >= 'A' && *iter <= 'Z') || (*iter >= 'a' && *iter <= 'z') || (*iter >= '0' && *iter <= '9') ||
+           *iter == '_') {
+        start = iter;
+        if (!iter.backward_char())
+            break;
+    }
+    while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') ||
+           *end == '_') {
+        if (!end.forward_char())
+            break;
+    }
 
-  if(start_blank_iter.starts_line())
-    get_buffer()->erase(iter, end_blank_iter);
-  else
-    get_buffer()->erase(start_blank_iter, end_blank_iter);
+    return get_buffer()->get_text(start, end);
 }
 
-bool Source::View::on_key_press_event(GdkEventKey* key) {
-  class Guard {
-  public:
-    bool &value;
-    Guard(bool &value_) : value(value_) { value = true; }
-    ~Guard() { value = false; }
-  };
-  Guard guard{multiple_cursors_use};
-  
-  if(SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
-    if(SelectionDialog::get()->on_key_press(key))
-      return true;
-  }
-  if(CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
-    if(CompletionDialog::get()->on_key_press(key))
-      return true;
-  }
-  
-  if(last_keyval<GDK_KEY_Shift_L || last_keyval>GDK_KEY_Hyper_R)
-    previous_non_modifier_keyval=last_keyval;
-  last_keyval=key->keyval;
-  
-  if(Config::get().source.enable_multiple_cursors && on_key_press_event_multiple_cursors(key))
-    return true;
-  
-  //Move cursor one paragraph down
-  if((key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down) && (key->state&GDK_CONTROL_MASK)>0) {
-    auto selection_start_iter=get_buffer()->get_selection_bound()->get_iter();
-    auto iter=get_buffer()->get_iter_at_line(get_buffer()->get_insert()->get_iter().get_line());
-    bool empty_line=false;
-    bool text_found=false;
-    for(;;) {
-      if(!iter)
-        break;
-      if(iter.starts_line())
-        empty_line=true;
-      if(empty_line && !iter.ends_line() && *iter!='\n' && *iter!=' ' && *iter!='\t')
-        empty_line=false;
-      if(!text_found && !iter.ends_line() && *iter!='\n' && *iter!=' ' && *iter!='\t')
-        text_found=true;
-      if(empty_line && text_found && iter.ends_line())
-        break;
-      iter.forward_char();
-    }
-    iter=get_buffer()->get_iter_at_line(iter.get_line());
-    if((key->state&GDK_SHIFT_MASK)>0)
-      get_buffer()->select_range(iter, selection_start_iter);
-    else
-      get_buffer()->place_cursor(iter);
-    scroll_to(get_buffer()->get_insert());
-    return true;
-  }
-  //Move cursor one paragraph up
-  else if((key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up) && (key->state&GDK_CONTROL_MASK)>0) {
-    auto selection_start_iter=get_buffer()->get_selection_bound()->get_iter();
-    auto iter=get_buffer()->get_iter_at_line(get_buffer()->get_insert()->get_iter().get_line());
-    iter.backward_char();
-    bool empty_line=false;
-    bool text_found=false;
-    bool move_to_start=false;
-    for(;;) {
-      if(!iter)
-        break;
-      if(iter.ends_line())
-        empty_line=true;
-      if(empty_line && !iter.ends_line() && *iter!='\n' && *iter!=' ' && *iter!='\t')
-        empty_line=false;
-      if(!text_found && !iter.ends_line() && *iter!='\n' && *iter!=' ' && *iter!='\t')
-        text_found=true;
-      if(empty_line && text_found && iter.starts_line())
-        break;
-      if(iter.is_start()) {
-        move_to_start=true;
-        break;
-      }
-      iter.backward_char();
-    }
-    if(empty_line && !move_to_start) {
-      iter=get_iter_at_line_end(iter.get_line());
-      iter.forward_char();
-      if(!iter.starts_line()) // For CR+LF
-        iter.forward_char();
-    }
-    if((key->state&GDK_SHIFT_MASK)>0)
-      get_buffer()->select_range(iter, selection_start_iter);
+void Source::View::cleanup_whitespace_characters_on_return(const Gtk::TextIter &iter) {
+    auto start_blank_iter = iter;
+    auto end_blank_iter = iter;
+    while ((*end_blank_iter == ' ' || *end_blank_iter == '\t') &&
+           !end_blank_iter.ends_line() && end_blank_iter.forward_char()) {}
+    if (!start_blank_iter.starts_line()) {
+        start_blank_iter.backward_char();
+        while ((*start_blank_iter == ' ' || *start_blank_iter == '\t') &&
+               !start_blank_iter.starts_line() && start_blank_iter.backward_char()) {}
+        if (*start_blank_iter != ' ' && *start_blank_iter != '\t')
+            start_blank_iter.forward_char();
+    }
+
+    if (start_blank_iter.starts_line())
+        get_buffer()->erase(iter, end_blank_iter);
     else
-      get_buffer()->place_cursor(iter);
-    scroll_to(get_buffer()->get_insert());
-    return true;
-  }
+        get_buffer()->erase(start_blank_iter, end_blank_iter);
+}
+
+bool Source::View::on_key_press_event(GdkEventKey *key) {
+    class Guard {
+    public:
+        bool &value;
+
+        Guard(bool &value_) : value(value_) { value = true; }
+
+        ~Guard() { value = false; }
+    };
+    Guard guard{multiple_cursors_use};
 
-  get_buffer()->begin_user_action();
-  
-  // Shift+enter: go to end of line and enter
-  if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && (key->state&GDK_SHIFT_MASK)>0) {
-    auto iter=get_buffer()->get_insert()->get_iter();
-    if(!iter.ends_line()) {
-      iter.forward_to_line_end();
-      get_buffer()->place_cursor(iter);
+    if (SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
+        if (SelectionDialog::get()->on_key_press(key))
+            return true;
+    }
+    if (CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
+        if (CompletionDialog::get()->on_key_press(key))
+            return true;
     }
-  }
-  
-  if(Config::get().source.smart_brackets && on_key_press_event_smart_brackets(key)) {
-    get_buffer()->end_user_action();
-    return true;
-  }
-  if(Config::get().source.smart_inserts && on_key_press_event_smart_inserts(key)) {
-    get_buffer()->end_user_action();
-    return true;
-  }
-  
-  if(is_bracket_language && on_key_press_event_bracket_language(key)) {
-    get_buffer()->end_user_action();
-    return true;
-  }
-  else if(on_key_press_event_basic(key)) {
-    get_buffer()->end_user_action();
-    return true;
-  }
-  else {
-    get_buffer()->end_user_action();
-    return Gsv::View::on_key_press_event(key);
-  }
-}
 
-//Basic indentation
-bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
-  auto iter=get_buffer()->get_insert()->get_iter();
-
-  //Indent as in next or previous line
-  if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && !get_buffer()->get_has_selection() && !iter.starts_line()) {
-    cleanup_whitespace_characters_on_return(iter);
-    
-    iter=get_buffer()->get_insert()->get_iter();
-    auto tabs=get_line_before(get_tabs_end_iter(iter));
-    
-    int line_nr=iter.get_line();
-    if(iter.ends_line() && (line_nr+1)<get_buffer()->get_line_count()) {
-      auto next_line_tabs=get_line_before(get_tabs_end_iter(line_nr+1));
-      if(next_line_tabs.size()>tabs.size()) {
-        get_buffer()->insert_at_cursor("\n"+next_line_tabs);
+    if (last_keyval < GDK_KEY_Shift_L || last_keyval > GDK_KEY_Hyper_R)
+        previous_non_modifier_keyval = last_keyval;
+    last_keyval = key->keyval;
+
+    if (Config::get().source.enable_multiple_cursors && on_key_press_event_multiple_cursors(key))
+        return true;
+
+    //Move cursor one paragraph down
+    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) && (key->state & GDK_CONTROL_MASK) > 0) {
+        auto selection_start_iter = get_buffer()->get_selection_bound()->get_iter();
+        auto iter = get_buffer()->get_iter_at_line(get_buffer()->get_insert()->get_iter().get_line());
+        bool empty_line = false;
+        bool text_found = false;
+        for (;;) {
+            if (!iter)
+                break;
+            if (iter.starts_line())
+                empty_line = true;
+            if (empty_line && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
+                empty_line = false;
+            if (!text_found && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
+                text_found = true;
+            if (empty_line && text_found && iter.ends_line())
+                break;
+            iter.forward_char();
+        }
+        iter = get_buffer()->get_iter_at_line(iter.get_line());
+        if ((key->state & GDK_SHIFT_MASK) > 0)
+            get_buffer()->select_range(iter, selection_start_iter);
+        else
+            get_buffer()->place_cursor(iter);
         scroll_to(get_buffer()->get_insert());
         return true;
-      }
     }
-    get_buffer()->insert_at_cursor("\n"+tabs);
-    scroll_to(get_buffer()->get_insert());
-    return true;
-  }
-  else if(key->keyval==GDK_KEY_Tab && (key->state&GDK_SHIFT_MASK)==0) {
-    if(!Config::get().source.tab_indents_line && !get_buffer()->get_has_selection()) {
-      get_buffer()->insert_at_cursor(tab);
-      return true;
-    }
-    //Indent right when clicking tab, no matter where in the line the cursor is. Also works on selected text.
-    //Special case if insert is at beginning of empty line:
-    if(iter.starts_line() && iter.ends_line() && !get_buffer()->get_has_selection()) {
-      auto prev_line_iter=iter;
-      while(prev_line_iter.starts_line() && prev_line_iter.backward_char()) {}
-      auto prev_line_tabs_end_iter=get_tabs_end_iter(prev_line_iter);
-      auto previous_line_tabs=get_line_before(prev_line_tabs_end_iter);
-
-      auto next_line_iter=iter;
-      while(next_line_iter.starts_line() && next_line_iter.forward_char()) {}
-      auto next_line_tabs_end_iter=get_tabs_end_iter(next_line_iter);
-      auto next_line_tabs=get_line_before(next_line_tabs_end_iter);
-      
-      std::string tabs;
-      if(previous_line_tabs.size()<next_line_tabs.size())
-        tabs=previous_line_tabs;
-      else
-        tabs=next_line_tabs;
-      if(tabs.size()>=tab_size) {
-        get_buffer()->insert_at_cursor(tabs);
-        return true;
-      }
-    }
-    
-    Gtk::TextIter selection_start, selection_end;
-    get_buffer()->get_selection_bounds(selection_start, selection_end);
-    auto selection_end_mark=get_buffer()->create_mark(selection_end);
-    int line_start=selection_start.get_line();
-    int line_end=selection_end.get_line();
-    for(int line=line_start;line<=line_end;line++) {
-      Gtk::TextIter line_it = get_buffer()->get_iter_at_line(line);
-      if(!get_buffer()->get_has_selection() || line_it!=selection_end_mark->get_iter())
-        get_buffer()->insert(line_it, tab);
-    }
-    get_buffer()->delete_mark(selection_end_mark);
-    return true;
-  }
-  //Indent left when clicking shift-tab, no matter where in the line the cursor is. Also works on selected text.
-  else if((key->keyval==GDK_KEY_ISO_Left_Tab || key->keyval==GDK_KEY_Tab) && (key->state&GDK_SHIFT_MASK)>0) {
-    Gtk::TextIter selection_start, selection_end;
-    get_buffer()->get_selection_bounds(selection_start, selection_end);
-    int line_start=selection_start.get_line();
-    int line_end=selection_end.get_line();
-    
-    unsigned indent_left_steps=tab_size;
-    std::vector<bool> ignore_line;
-    for(int line_nr=line_start;line_nr<=line_end;line_nr++) {
-      auto line_it = get_buffer()->get_iter_at_line(line_nr);
-      if(!get_buffer()->get_has_selection() || line_it!=selection_end) {        
-        auto tabs_end_iter=get_tabs_end_iter(line_nr);
-        if(tabs_end_iter.starts_line() && tabs_end_iter.ends_line())
-          ignore_line.push_back(true);
-        else {
-          auto line_tabs=get_line_before(tabs_end_iter);
-          
-          if(line_tabs.size()>0) {
-            indent_left_steps=std::min(indent_left_steps, static_cast<unsigned>(line_tabs.size()));
-            ignore_line.push_back(false);
-          }
-          else
-            return true;
+        //Move cursor one paragraph up
+    else if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) && (key->state & GDK_CONTROL_MASK) > 0) {
+        auto selection_start_iter = get_buffer()->get_selection_bound()->get_iter();
+        auto iter = get_buffer()->get_iter_at_line(get_buffer()->get_insert()->get_iter().get_line());
+        iter.backward_char();
+        bool empty_line = false;
+        bool text_found = false;
+        bool move_to_start = false;
+        for (;;) {
+            if (!iter)
+                break;
+            if (iter.ends_line())
+                empty_line = true;
+            if (empty_line && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
+                empty_line = false;
+            if (!text_found && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
+                text_found = true;
+            if (empty_line && text_found && iter.starts_line())
+                break;
+            if (iter.is_start()) {
+                move_to_start = true;
+                break;
+            }
+            iter.backward_char();
         }
-      }
-    }
-    
-    for(int line_nr=line_start;line_nr<=line_end;line_nr++) {
-      Gtk::TextIter line_it = get_buffer()->get_iter_at_line(line_nr);
-      Gtk::TextIter line_plus_it=line_it;
-      if(!get_buffer()->get_has_selection() || line_it!=selection_end) {
-        line_plus_it.forward_chars(indent_left_steps);
-        if(!ignore_line.at(line_nr-line_start))
-          get_buffer()->erase(line_it, line_plus_it);
-      }
-    }
-    return true;
-  }
-  //"Smart" backspace key
-  else if(key->keyval==GDK_KEY_BackSpace && !get_buffer()->get_has_selection()) {
-    auto line=get_line_before();
-    bool do_smart_backspace=true;
-    for(auto &chr: line) {
-      if(chr!=' ' && chr!='\t') {
-        do_smart_backspace=false;
-        break;
-      }
-    }
-    if(iter.get_line()==0) // Special case since there are no previous line
-      do_smart_backspace=false;
-    if(do_smart_backspace) {
-      auto previous_line_end_iter=iter;
-      if(previous_line_end_iter.backward_chars(line.size()+1)) {
-        if(!previous_line_end_iter.ends_line()) // For CR+LF
-          previous_line_end_iter.backward_char();
-        if(previous_line_end_iter.starts_line()) // When previous line is empty, keep tabs in current line
-          get_buffer()->erase(previous_line_end_iter, get_buffer()->get_iter_at_line(iter.get_line()));
+        if (empty_line && !move_to_start) {
+            iter = get_iter_at_line_end(iter.get_line());
+            iter.forward_char();
+            if (!iter.starts_line()) // For CR+LF
+                iter.forward_char();
+        }
+        if ((key->state & GDK_SHIFT_MASK) > 0)
+            get_buffer()->select_range(iter, selection_start_iter);
         else
-          get_buffer()->erase(previous_line_end_iter, iter);
+            get_buffer()->place_cursor(iter);
+        scroll_to(get_buffer()->get_insert());
         return true;
-      }
     }
-  }
-  //"Smart" delete key
-  else if(key->keyval==GDK_KEY_Delete && !get_buffer()->get_has_selection()) {
-    auto insert_iter=iter;
-    bool do_smart_delete=true;
-    do {
-      if(*iter!=' ' && *iter!='\t' && !iter.ends_line()) {
-        do_smart_delete=false;
-        break;
-      }
-      if(iter.ends_line()) {
-        if(*iter=='\r') // For CR+LF
-          iter.forward_char();
-        if(!iter.forward_char())
-          do_smart_delete=false;
-        break;
-      }
-    } while(iter.forward_char());
-    if(do_smart_delete) {
-      if(!insert_iter.starts_line()) {
-        while((*iter==' ' || *iter=='\t') && iter.forward_char()) {}
-      }
-      get_buffer()->erase(insert_iter, iter);
-      return true;
+
+    get_buffer()->begin_user_action();
+
+    // Shift+enter: go to end of line and enter
+    if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) && (key->state & GDK_SHIFT_MASK) > 0) {
+        auto iter = get_buffer()->get_insert()->get_iter();
+        if (!iter.ends_line()) {
+            iter.forward_to_line_end();
+            get_buffer()->place_cursor(iter);
+        }
     }
-  }
-  // Smart Home/End-keys
-  else if((key->keyval==GDK_KEY_Home || key->keyval==GDK_KEY_KP_Home) && (key->state&GDK_CONTROL_MASK)==0) {
-    if((key->state&GDK_SHIFT_MASK)>0)
-      get_buffer()->move_mark_by_name("insert", get_smart_home_iter(iter));
-    else
-      get_buffer()->place_cursor(get_smart_home_iter(iter));
-    scroll_to(get_buffer()->get_insert());
-    return true;
-  }
-  else if((key->keyval==GDK_KEY_End || key->keyval==GDK_KEY_KP_End) && (key->state&GDK_CONTROL_MASK)==0) {
-    if((key->state&GDK_SHIFT_MASK)>0)
-      get_buffer()->move_mark_by_name("insert", get_smart_end_iter(iter));
-    else
-      get_buffer()->place_cursor(get_smart_end_iter(iter));
-    scroll_to(get_buffer()->get_insert());
-    return true;
-  }
 
-  //Workaround for TextView::on_key_press_event bug sometimes causing segmentation faults
-  //TODO: figure out the bug and create pull request to gtk
-  //Have only experienced this on OS X
-  //Note: valgrind reports issues on TextView::on_key_press_event as well
-  auto unicode=gdk_keyval_to_unicode(key->keyval);
-  if((key->state&(GDK_CONTROL_MASK|GDK_META_MASK))==0 && unicode>=32 && unicode!=127 &&
-     (previous_non_modifier_keyval<GDK_KEY_dead_grave || previous_non_modifier_keyval>GDK_KEY_dead_greek)) {
-    if(get_buffer()->get_has_selection()) {
-      Gtk::TextIter selection_start, selection_end;
-      get_buffer()->get_selection_bounds(selection_start, selection_end);
-      get_buffer()->erase(selection_start, selection_end);
-    }
-    get_buffer()->insert_at_cursor(Glib::ustring(1, unicode));
-    scroll_to(get_buffer()->get_insert());
-    
-    //Trick to make the cursor visible right after insertion:
-    set_cursor_visible(false);
-    set_cursor_visible();
-    
-    return true;
-  }
+    if (Config::get().source.smart_brackets && on_key_press_event_smart_brackets(key)) {
+        get_buffer()->end_user_action();
+        return true;
+    }
+    if (Config::get().source.smart_inserts && on_key_press_event_smart_inserts(key)) {
+        get_buffer()->end_user_action();
+        return true;
+    }
 
-  return false;
+    if (is_bracket_language && on_key_press_event_bracket_language(key)) {
+        get_buffer()->end_user_action();
+        return true;
+    } else if (on_key_press_event_basic(key)) {
+        get_buffer()->end_user_action();
+        return true;
+    } else {
+        get_buffer()->end_user_action();
+        return Gsv::View::on_key_press_event(key);
+    }
 }
 
-//Bracket language indentation
-bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
-  const static std::regex no_bracket_statement_regex("^ *(if|for|while) *\\(.*[^;}{] *$|"
-                                                     "^[}]? *else if *\\(.*[^;}{] *$|"
-                                                     "^[}]? *else *$", std::regex::extended);
-
-  auto iter=get_buffer()->get_insert()->get_iter();
+//Basic indentation
+bool Source::View::on_key_press_event_basic(GdkEventKey *key) {
+    auto iter = get_buffer()->get_insert()->get_iter();
 
-  if(get_buffer()->get_has_selection())
-    return false;
-  
-  if(!is_code_iter(iter)) {
-    // Add * at start of line in comment blocks
-    if(key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) {
-      if(!iter.starts_line() && (!string_tag || (!iter.has_tag(string_tag) && !iter.ends_tag(string_tag)))) {
+    //Indent as in next or previous line
+    if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) && !get_buffer()->get_has_selection() &&
+        !iter.starts_line()) {
         cleanup_whitespace_characters_on_return(iter);
-        iter=get_buffer()->get_insert()->get_iter();
-        
-        auto start_iter=get_tabs_end_iter(iter.get_line());
-        auto end_iter=start_iter;
-        end_iter.forward_chars(2);
-        auto start_of_sentence=get_buffer()->get_text(start_iter, end_iter);
-        if(!start_of_sentence.empty()) {
-          if(start_of_sentence=="/*" || start_of_sentence[0]=='*') {
-            auto tabs=get_line_before(start_iter);
-            auto insert_str="\n"+tabs;
-            if(start_of_sentence[0]=='/')
-              insert_str+=' ';
-            insert_str+="* ";
-            
-            get_buffer()->insert_at_cursor(insert_str);
-            return true;
-          }
+
+        iter = get_buffer()->get_insert()->get_iter();
+        auto tabs = get_line_before(get_tabs_end_iter(iter));
+
+        int line_nr = iter.get_line();
+        if (iter.ends_line() && (line_nr + 1) < get_buffer()->get_line_count()) {
+            auto next_line_tabs = get_line_before(get_tabs_end_iter(line_nr + 1));
+            if (next_line_tabs.size() > tabs.size()) {
+                get_buffer()->insert_at_cursor("\n" + next_line_tabs);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
         }
-      }
-      else if(!comment_tag || !iter.ends_tag(comment_tag))
-        return false;
-    }
-    else
-      return false;
-  }
-  
-  // get iter for if expressions below, which is moved backwards past any comment
-  auto get_condition_iter=[this](const Gtk::TextIter &iter) {
-    auto condition_iter=iter;
-    condition_iter.backward_char();
-    if(!comment_tag)
-      return condition_iter;
-    while(!condition_iter.starts_line() && (condition_iter.has_tag(comment_tag) ||
-#if GTKMM_MAJOR_VERSION>3 || (GTKMM_MAJOR_VERSION==3 && GTKMM_MINOR_VERSION>=20)
-                                            condition_iter.starts_tag(comment_tag) ||
-#else
-                                            *condition_iter=='/' ||
-#endif
-                                            *condition_iter==' ' || *condition_iter=='\t') &&
-          condition_iter.backward_char()) {}
-    return condition_iter;
-  };
-  
-  //Indent depending on if/else/etc and brackets
-  if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && !iter.starts_line()) {
-    cleanup_whitespace_characters_on_return(iter);
-    iter=get_buffer()->get_insert()->get_iter();
-    
-    auto condition_iter=get_condition_iter(iter);
-    auto start_iter=condition_iter;
-    if(*start_iter=='{')
-      start_iter.backward_char();
-    Gtk::TextIter open_non_curly_bracket_iter;
-    bool open_non_curly_bracket_iter_found=false;
-    if(find_open_non_curly_bracket_backward(start_iter, open_non_curly_bracket_iter)) {
-      open_non_curly_bracket_iter_found=true;
-      start_iter=get_tabs_end_iter(get_buffer()->get_iter_at_line(open_non_curly_bracket_iter.get_line()));
-    }
-    else
-      start_iter=get_tabs_end_iter(get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
-    auto tabs=get_line_before(start_iter);
-    
-    /*
-     * Change tabs after ending comment block with an extra space (as in this case)
-     */
-    if(tabs.size()%tab_size==1 && !start_iter.ends_line() && !is_code_iter(start_iter)) {
-      auto end_of_line_iter=start_iter;
-      end_of_line_iter.forward_to_line_end();
-      auto line=get_buffer()->get_text(start_iter, end_of_line_iter);
-      if(!line.empty() && line.compare(0, 2, "*/")==0) {
-        tabs.pop_back();
-        get_buffer()->insert_at_cursor("\n"+tabs);
+        get_buffer()->insert_at_cursor("\n" + tabs);
         scroll_to(get_buffer()->get_insert());
         return true;
-      }
-    }
-    
-    if(*condition_iter=='{' && is_code_iter(condition_iter)) {
-      Gtk::TextIter found_iter;
-      // Check if an '}' is needed
-      bool has_right_curly_bracket=false;
-      bool found_right_bracket=find_close_curly_bracket_forward(iter, found_iter);
-      if(found_right_bracket) {
-        auto tabs_end_iter=get_tabs_end_iter(found_iter);
-        auto line_tabs=get_line_before(tabs_end_iter);
-        if(tabs.size()==line_tabs.size())
-          has_right_curly_bracket=true;
-      }
-      // special case for functions and classes with no indentation after: namespace {
-      if(tabs.empty() && has_right_curly_bracket)
-        has_right_curly_bracket=symbol_count(iter, '{', '}')!=1;
-      
-      if(*get_buffer()->get_insert()->get_iter()=='}') {
-        get_buffer()->insert_at_cursor("\n"+tabs+tab+"\n"+tabs);
-        auto insert_it = get_buffer()->get_insert()->get_iter();
-        if(insert_it.backward_chars(tabs.size()+1)) {
-          scroll_to(get_buffer()->get_insert());
-          get_buffer()->place_cursor(insert_it);
+    } else if (key->keyval == GDK_KEY_Tab && (key->state & GDK_SHIFT_MASK) == 0) {
+        if (!Config::get().source.tab_indents_line && !get_buffer()->get_has_selection()) {
+            get_buffer()->insert_at_cursor(tab);
+            return true;
         }
+        //Indent right when clicking tab, no matter where in the line the cursor is. Also works on selected text.
+        //Special case if insert is at beginning of empty line:
+        if (iter.starts_line() && iter.ends_line() && !get_buffer()->get_has_selection()) {
+            auto prev_line_iter = iter;
+            while (prev_line_iter.starts_line() && prev_line_iter.backward_char()) {}
+            auto prev_line_tabs_end_iter = get_tabs_end_iter(prev_line_iter);
+            auto previous_line_tabs = get_line_before(prev_line_tabs_end_iter);
+
+            auto next_line_iter = iter;
+            while (next_line_iter.starts_line() && next_line_iter.forward_char()) {}
+            auto next_line_tabs_end_iter = get_tabs_end_iter(next_line_iter);
+            auto next_line_tabs = get_line_before(next_line_tabs_end_iter);
+
+            std::string tabs;
+            if (previous_line_tabs.size() < next_line_tabs.size())
+                tabs = previous_line_tabs;
+            else
+                tabs = next_line_tabs;
+            if (tabs.size() >= tab_size) {
+                get_buffer()->insert_at_cursor(tabs);
+                return true;
+            }
+        }
+
+        Gtk::TextIter selection_start, selection_end;
+        get_buffer()->get_selection_bounds(selection_start, selection_end);
+        auto selection_end_mark = get_buffer()->create_mark(selection_end);
+        int line_start = selection_start.get_line();
+        int line_end = selection_end.get_line();
+        for (int line = line_start; line <= line_end; line++) {
+            Gtk::TextIter line_it = get_buffer()->get_iter_at_line(line);
+            if (!get_buffer()->get_has_selection() || line_it != selection_end_mark->get_iter())
+                get_buffer()->insert(line_it, tab);
+        }
+        get_buffer()->delete_mark(selection_end_mark);
         return true;
-      }
-      else if(!has_right_curly_bracket) {
-        //Insert new lines with bracket end
-        bool add_semicolon=false;
-        if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" ||
-                        language->get_id()=="c" || language->get_id()=="cpp")) {
-          auto token=get_token(start_iter);
-          if(token.empty()) {
-            auto iter=start_iter;
-            while(!iter.starts_line() && iter.backward_char()) {}
-            if(iter.backward_char())
-              token=get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(iter.get_line())));
-          }
-          //Add semicolon after class or struct
-          if(token=="class" || token=="struct")
-            add_semicolon=true;
-          //Add semicolon after lambda unless it's a parameter
-          else if(!open_non_curly_bracket_iter_found) {
-            auto it=condition_iter;
-            long para_count=0;
-            long square_count=0;
-            bool square_outside_para_found=false;
-            while(it.backward_char()) {
-              if(*it==']' && is_code_iter(it)) {
-                --square_count;
-                if(para_count==0)
-                  square_outside_para_found=true;
-              }
-              else if(*it=='[' && is_code_iter(it))
-                ++square_count;
-              else if(*it==')' && is_code_iter(it))
-                --para_count;
-              else if(*it=='(' && is_code_iter(it))
-                ++para_count;
-              
-              if(square_outside_para_found && square_count==0 && para_count==0) {
-                add_semicolon=true;
-                break;
-              }
-              if(it==start_iter)
-                break;
-              if(!square_outside_para_found && square_count==0 && para_count==0) {
-                if((*it>='A' && *it<='Z') || (*it>='a' && *it<='z') || (*it>='0' && *it<='9') || *it=='_' ||
-                   *it=='-' || *it==' ' || *it=='\t' || *it=='<' || *it=='>' || *it=='(' || *it==':' ||
-                   *it=='*' || *it=='&' || *it=='/' || it.ends_line() || !is_code_iter(it)) {
-                  continue;
+    }
+        //Indent left when clicking shift-tab, no matter where in the line the cursor is. Also works on selected text.
+    else if ((key->keyval == GDK_KEY_ISO_Left_Tab || key->keyval == GDK_KEY_Tab) && (key->state & GDK_SHIFT_MASK) > 0) {
+        Gtk::TextIter selection_start, selection_end;
+        get_buffer()->get_selection_bounds(selection_start, selection_end);
+        int line_start = selection_start.get_line();
+        int line_end = selection_end.get_line();
+
+        unsigned indent_left_steps = tab_size;
+        std::vector<bool> ignore_line;
+        for (int line_nr = line_start; line_nr <= line_end; line_nr++) {
+            auto line_it = get_buffer()->get_iter_at_line(line_nr);
+            if (!get_buffer()->get_has_selection() || line_it != selection_end) {
+                auto tabs_end_iter = get_tabs_end_iter(line_nr);
+                if (tabs_end_iter.starts_line() && tabs_end_iter.ends_line())
+                    ignore_line.push_back(true);
+                else {
+                    auto line_tabs = get_line_before(tabs_end_iter);
+
+                    if (line_tabs.size() > 0) {
+                        indent_left_steps = std::min(indent_left_steps, static_cast<unsigned>(line_tabs.size()));
+                        ignore_line.push_back(false);
+                    } else
+                        return true;
                 }
+            }
+        }
+
+        for (int line_nr = line_start; line_nr <= line_end; line_nr++) {
+            Gtk::TextIter line_it = get_buffer()->get_iter_at_line(line_nr);
+            Gtk::TextIter line_plus_it = line_it;
+            if (!get_buffer()->get_has_selection() || line_it != selection_end) {
+                line_plus_it.forward_chars(indent_left_steps);
+                if (!ignore_line.at(line_nr - line_start))
+                    get_buffer()->erase(line_it, line_plus_it);
+            }
+        }
+        return true;
+    }
+        //"Smart" backspace key
+    else if (key->keyval == GDK_KEY_BackSpace && !get_buffer()->get_has_selection()) {
+        auto line = get_line_before();
+        bool do_smart_backspace = true;
+        for (auto &chr: line) {
+            if (chr != ' ' && chr != '\t') {
+                do_smart_backspace = false;
+                break;
+            }
+        }
+        if (iter.get_line() == 0) // Special case since there are no previous line
+            do_smart_backspace = false;
+        if (do_smart_backspace) {
+            auto previous_line_end_iter = iter;
+            if (previous_line_end_iter.backward_chars(line.size() + 1)) {
+                if (!previous_line_end_iter.ends_line()) // For CR+LF
+                    previous_line_end_iter.backward_char();
+                if (previous_line_end_iter.starts_line()) // When previous line is empty, keep tabs in current line
+                    get_buffer()->erase(previous_line_end_iter, get_buffer()->get_iter_at_line(iter.get_line()));
                 else
-                  break;
-              }
+                    get_buffer()->erase(previous_line_end_iter, iter);
+                return true;
             }
-          }
         }
-        get_buffer()->insert_at_cursor("\n"+tabs+tab+"\n"+tabs+(add_semicolon?"};":"}"));
-        auto insert_it = get_buffer()->get_insert()->get_iter();
-        if(insert_it.backward_chars(tabs.size()+(add_semicolon?3:2))) {
-          scroll_to(get_buffer()->get_insert());
-          get_buffer()->place_cursor(insert_it);
+    }
+        //"Smart" delete key
+    else if (key->keyval == GDK_KEY_Delete && !get_buffer()->get_has_selection()) {
+        auto insert_iter = iter;
+        bool do_smart_delete = true;
+        do {
+            if (*iter != ' ' && *iter != '\t' && !iter.ends_line()) {
+                do_smart_delete = false;
+                break;
+            }
+            if (iter.ends_line()) {
+                if (*iter == '\r') // For CR+LF
+                    iter.forward_char();
+                if (!iter.forward_char())
+                    do_smart_delete = false;
+                break;
+            }
+        } while (iter.forward_char());
+        if (do_smart_delete) {
+            if (!insert_iter.starts_line()) {
+                while ((*iter == ' ' || *iter == '\t') && iter.forward_char()) {}
+            }
+            get_buffer()->erase(insert_iter, iter);
+            return true;
         }
+    }
+        // Smart Home/End-keys
+    else if ((key->keyval == GDK_KEY_Home || key->keyval == GDK_KEY_KP_Home) && (key->state & GDK_CONTROL_MASK) == 0) {
+        if ((key->state & GDK_SHIFT_MASK) > 0)
+            get_buffer()->move_mark_by_name("insert", get_smart_home_iter(iter));
+        else
+            get_buffer()->place_cursor(get_smart_home_iter(iter));
+        scroll_to(get_buffer()->get_insert());
         return true;
-      }
-      else {
-        get_buffer()->insert_at_cursor("\n"+tabs+tab);
+    } else if ((key->keyval == GDK_KEY_End || key->keyval == GDK_KEY_KP_End) && (key->state & GDK_CONTROL_MASK) == 0) {
+        if ((key->state & GDK_SHIFT_MASK) > 0)
+            get_buffer()->move_mark_by_name("insert", get_smart_end_iter(iter));
+        else
+            get_buffer()->place_cursor(get_smart_end_iter(iter));
         scroll_to(get_buffer()->get_insert());
         return true;
-      }
-    }
-    
-    //Indent multiline expressions
-    if(open_non_curly_bracket_iter_found) {
-      auto tabs_end_iter=get_tabs_end_iter(open_non_curly_bracket_iter);
-      auto tabs=get_line_before(get_tabs_end_iter(open_non_curly_bracket_iter));
-      auto iter=tabs_end_iter;
-      while(iter<=open_non_curly_bracket_iter) {
-        tabs+=' ';
-        iter.forward_char();
-      }
-      get_buffer()->insert_at_cursor("\n"+tabs);
-      scroll_to(get_buffer()->get_insert());
-      return true;
-    }
-    auto after_condition_iter=condition_iter;
-    after_condition_iter.forward_char();
-    std::string sentence=get_buffer()->get_text(start_iter, after_condition_iter);
-    std::smatch sm;
-    if(std::regex_match(sentence, sm, no_bracket_statement_regex)) {
-      get_buffer()->insert_at_cursor("\n"+tabs+tab);
-      scroll_to(get_buffer()->get_insert());
-      return true;
-    }
-    //Indenting after for instance if(...)\n...;\n
-    else if(*condition_iter==';' && condition_iter.get_line()>0 && is_code_iter(condition_iter)) {
-      auto previous_end_iter=start_iter;
-      while(previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {}
-      auto condition_iter=get_condition_iter(previous_end_iter);
-      auto previous_start_iter=get_tabs_end_iter(get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
-      auto previous_tabs=get_line_before(previous_start_iter);
-      auto after_condition_iter=condition_iter;
-      after_condition_iter.forward_char();
-      std::string previous_sentence=get_buffer()->get_text(previous_start_iter, after_condition_iter);
-      std::smatch sm2;
-      if(std::regex_match(previous_sentence, sm2, no_bracket_statement_regex)) {
-        get_buffer()->insert_at_cursor("\n"+previous_tabs);
+    }
+
+    //Workaround for TextView::on_key_press_event bug sometimes causing segmentation faults
+    //TODO: figure out the bug and create pull request to gtk
+    //Have only experienced this on OS X
+    //Note: valgrind reports issues on TextView::on_key_press_event as well
+    auto unicode = gdk_keyval_to_unicode(key->keyval);
+    if ((key->state & (GDK_CONTROL_MASK | GDK_META_MASK)) == 0 && unicode >= 32 && unicode != 127 &&
+        (previous_non_modifier_keyval < GDK_KEY_dead_grave || previous_non_modifier_keyval > GDK_KEY_dead_greek)) {
+        if (get_buffer()->get_has_selection()) {
+            Gtk::TextIter selection_start, selection_end;
+            get_buffer()->get_selection_bounds(selection_start, selection_end);
+            get_buffer()->erase(selection_start, selection_end);
+        }
+        get_buffer()->insert_at_cursor(Glib::ustring(1, unicode));
         scroll_to(get_buffer()->get_insert());
+
+        //Trick to make the cursor visible right after insertion:
+        set_cursor_visible(false);
+        set_cursor_visible();
+
         return true;
-      }
-    }
-    //Indenting after ':'
-    else if(*condition_iter==':' && is_code_iter(condition_iter)) {
-      bool perform_indent=true;
-      auto iter=condition_iter;
-      while(!iter.starts_line() && *iter==' ' && iter.backward_char()) {}
-      if(*iter==')') {
-        auto token=get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(iter.get_line())));
-        if(token!="case")
-          perform_indent=false;
-      }
-      if(perform_indent) {
-        Gtk::TextIter found_curly_iter;
-        if(find_open_curly_bracket_backward(iter, found_curly_iter)) {
-          auto tabs_end_iter=get_tabs_end_iter(get_buffer()->get_iter_at_line(found_curly_iter.get_line()));
-          auto tabs_start_of_sentence=get_line_before(tabs_end_iter);
-          if(tabs.size()==(tabs_start_of_sentence.size()+tab_size)) {
-            auto start_line_iter=get_buffer()->get_iter_at_line(iter.get_line());
-            auto start_line_plus_tab_size=start_line_iter;
-            for(size_t c=0;c<tab_size;c++)
-              start_line_plus_tab_size.forward_char();
-            get_buffer()->erase(start_line_iter, start_line_plus_tab_size);
-          }
-          else {
-            get_buffer()->insert_at_cursor("\n"+tabs+tab);
+    }
+
+    return false;
+}
+
+//Bracket language indentation
+bool Source::View::on_key_press_event_bracket_language(GdkEventKey *key) {
+    const static std::regex no_bracket_statement_regex("^ *(if|for|while) *\\(.*[^;}{] *$|"
+                                                       "^[}]? *else if *\\(.*[^;}{] *$|"
+                                                       "^[}]? *else *$", std::regex::extended);
+
+    auto iter = get_buffer()->get_insert()->get_iter();
+
+    if (get_buffer()->get_has_selection())
+        return false;
+
+    if (!is_code_iter(iter)) {
+        // Add * at start of line in comment blocks
+        if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) {
+            if (!iter.starts_line() && (!string_tag || (!iter.has_tag(string_tag) && !iter.ends_tag(string_tag)))) {
+                cleanup_whitespace_characters_on_return(iter);
+                iter = get_buffer()->get_insert()->get_iter();
+
+                auto start_iter = get_tabs_end_iter(iter.get_line());
+                auto end_iter = start_iter;
+                end_iter.forward_chars(2);
+                auto start_of_sentence = get_buffer()->get_text(start_iter, end_iter);
+                if (!start_of_sentence.empty()) {
+                    if (start_of_sentence == "/*" || start_of_sentence[0] == '*') {
+                        auto tabs = get_line_before(start_iter);
+                        auto insert_str = "\n" + tabs;
+                        if (start_of_sentence[0] == '/')
+                            insert_str += ' ';
+                        insert_str += "* ";
+
+                        get_buffer()->insert_at_cursor(insert_str);
+                        return true;
+                    }
+                }
+            } else if (!comment_tag || !iter.ends_tag(comment_tag))
+                return false;
+        } else
+            return false;
+    }
+
+    // get iter for if expressions below, which is moved backwards past any comment
+    auto get_condition_iter = [this](const Gtk::TextIter &iter) {
+        auto condition_iter = iter;
+        condition_iter.backward_char();
+        if (!comment_tag)
+            return condition_iter;
+        while (!condition_iter.starts_line() && (condition_iter.has_tag(comment_tag) ||
+                                                 #if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION >= 20)
+                                                 condition_iter.starts_tag(comment_tag) ||
+                                                 #else
+                                                 *condition_iter=='/' ||
+                                                 #endif
+                                                 *condition_iter == ' ' || *condition_iter == '\t') &&
+               condition_iter.backward_char()) {}
+        return condition_iter;
+    };
+
+    //Indent depending on if/else/etc and brackets
+    if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) && !iter.starts_line()) {
+        cleanup_whitespace_characters_on_return(iter);
+        iter = get_buffer()->get_insert()->get_iter();
+
+        auto condition_iter = get_condition_iter(iter);
+        auto start_iter = condition_iter;
+        if (*start_iter == '{')
+            start_iter.backward_char();
+        Gtk::TextIter open_non_curly_bracket_iter;
+        bool open_non_curly_bracket_iter_found = false;
+        if (find_open_non_curly_bracket_backward(start_iter, open_non_curly_bracket_iter)) {
+            open_non_curly_bracket_iter_found = true;
+            start_iter = get_tabs_end_iter(get_buffer()->get_iter_at_line(open_non_curly_bracket_iter.get_line()));
+        } else
+            start_iter = get_tabs_end_iter(
+                    get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
+        auto tabs = get_line_before(start_iter);
+
+        /*
+     * Change tabs after ending comment block with an extra space (as in this case)
+     */
+        if (tabs.size() % tab_size == 1 && !start_iter.ends_line() && !is_code_iter(start_iter)) {
+            auto end_of_line_iter = start_iter;
+            end_of_line_iter.forward_to_line_end();
+            auto line = get_buffer()->get_text(start_iter, end_of_line_iter);
+            if (!line.empty() && line.compare(0, 2, "*/") == 0) {
+                tabs.pop_back();
+                get_buffer()->insert_at_cursor("\n" + tabs);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+        }
+
+        if (*condition_iter == '{' && is_code_iter(condition_iter)) {
+            Gtk::TextIter found_iter;
+            // Check if an '}' is needed
+            bool has_right_curly_bracket = false;
+            bool found_right_bracket = find_close_curly_bracket_forward(iter, found_iter);
+            if (found_right_bracket) {
+                auto tabs_end_iter = get_tabs_end_iter(found_iter);
+                auto line_tabs = get_line_before(tabs_end_iter);
+                if (tabs.size() == line_tabs.size())
+                    has_right_curly_bracket = true;
+            }
+            // special case for functions and classes with no indentation after: namespace {
+            if (tabs.empty() && has_right_curly_bracket)
+                has_right_curly_bracket = symbol_count(iter, '{', '}') != 1;
+
+            if (*get_buffer()->get_insert()->get_iter() == '}') {
+                get_buffer()->insert_at_cursor("\n" + tabs + tab + "\n" + tabs);
+                auto insert_it = get_buffer()->get_insert()->get_iter();
+                if (insert_it.backward_chars(tabs.size() + 1)) {
+                    scroll_to(get_buffer()->get_insert());
+                    get_buffer()->place_cursor(insert_it);
+                }
+                return true;
+            } else if (!has_right_curly_bracket) {
+                //Insert new lines with bracket end
+                bool add_semicolon = false;
+                if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr" ||
+                                 language->get_id() == "c" || language->get_id() == "cpp")) {
+                    auto token = get_token(start_iter);
+                    if (token.empty()) {
+                        auto iter = start_iter;
+                        while (!iter.starts_line() && iter.backward_char()) {}
+                        if (iter.backward_char())
+                            token = get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(iter.get_line())));
+                    }
+                    //Add semicolon after class or struct
+                    if (token == "class" || token == "struct")
+                        add_semicolon = true;
+                        //Add semicolon after lambda unless it's a parameter
+                    else if (!open_non_curly_bracket_iter_found) {
+                        auto it = condition_iter;
+                        long para_count = 0;
+                        long square_count = 0;
+                        bool square_outside_para_found = false;
+                        while (it.backward_char()) {
+                            if (*it == ']' && is_code_iter(it)) {
+                                --square_count;
+                                if (para_count == 0)
+                                    square_outside_para_found = true;
+                            } else if (*it == '[' && is_code_iter(it))
+                                ++square_count;
+                            else if (*it == ')' && is_code_iter(it))
+                                --para_count;
+                            else if (*it == '(' && is_code_iter(it))
+                                ++para_count;
+
+                            if (square_outside_para_found && square_count == 0 && para_count == 0) {
+                                add_semicolon = true;
+                                break;
+                            }
+                            if (it == start_iter)
+                                break;
+                            if (!square_outside_para_found && square_count == 0 && para_count == 0) {
+                                if ((*it >= 'A' && *it <= 'Z') || (*it >= 'a' && *it <= 'z') ||
+                                    (*it >= '0' && *it <= '9') || *it == '_' ||
+                                    *it == '-' || *it == ' ' || *it == '\t' || *it == '<' || *it == '>' || *it == '(' ||
+                                    *it == ':' ||
+                                    *it == '*' || *it == '&' || *it == '/' || it.ends_line() || !is_code_iter(it)) {
+                                    continue;
+                                } else
+                                    break;
+                            }
+                        }
+                    }
+                }
+                get_buffer()->insert_at_cursor("\n" + tabs + tab + "\n" + tabs + (add_semicolon ? "};" : "}"));
+                auto insert_it = get_buffer()->get_insert()->get_iter();
+                if (insert_it.backward_chars(tabs.size() + (add_semicolon ? 3 : 2))) {
+                    scroll_to(get_buffer()->get_insert());
+                    get_buffer()->place_cursor(insert_it);
+                }
+                return true;
+            } else {
+                get_buffer()->insert_at_cursor("\n" + tabs + tab);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+        }
+
+        //Indent multiline expressions
+        if (open_non_curly_bracket_iter_found) {
+            auto tabs_end_iter = get_tabs_end_iter(open_non_curly_bracket_iter);
+            auto tabs = get_line_before(get_tabs_end_iter(open_non_curly_bracket_iter));
+            auto iter = tabs_end_iter;
+            while (iter <= open_non_curly_bracket_iter) {
+                tabs += ' ';
+                iter.forward_char();
+            }
+            get_buffer()->insert_at_cursor("\n" + tabs);
             scroll_to(get_buffer()->get_insert());
             return true;
-          }
         }
-      }
-    }
-    get_buffer()->insert_at_cursor("\n"+tabs);
-    scroll_to(get_buffer()->get_insert());
-    return true;
-  }
-  //Indent left when writing } on a new line
-  else if(key->keyval==GDK_KEY_braceright) {
-    std::string line=get_line_before();
-    if(line.size()>=tab_size && iter.ends_line()) {
-      bool indent_left=true;
-      for(auto c: line) {
-        if(c!=tab_char) {
-          indent_left=false;
-          break;
-        }
-      }
-      if(indent_left) {
-        Gtk::TextIter insert_it = get_buffer()->get_insert()->get_iter();
-        Gtk::TextIter line_it = get_buffer()->get_iter_at_line(insert_it.get_line());
-        Gtk::TextIter line_plus_it=line_it;
-        line_plus_it.forward_chars(tab_size);
-        get_buffer()->erase(line_it, line_plus_it);
-        get_buffer()->insert_at_cursor("}");
-        return true;
-      }
-    }
-  }
-  //Indent left when writing { on a new line after for instance if(...)\n...
-  else if(key->keyval==GDK_KEY_braceleft) {
-    auto tabs_end_iter=get_tabs_end_iter();
-    auto tabs=get_line_before(tabs_end_iter);
-    size_t line_nr=iter.get_line();
-    if(line_nr>0 && tabs.size()>=tab_size && iter==tabs_end_iter) {
-      auto previous_end_iter=iter;
-      while(previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {}
-      auto condition_iter=get_condition_iter(previous_end_iter);
-      auto previous_start_iter=get_tabs_end_iter(get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
-      auto previous_tabs=get_line_before(previous_start_iter);
-      auto after_condition_iter=condition_iter;
-      after_condition_iter.forward_char();
-      if((tabs.size()-tab_size)==previous_tabs.size()) {
-        std::string previous_sentence=get_buffer()->get_text(previous_start_iter, after_condition_iter);
+        auto after_condition_iter = condition_iter;
+        after_condition_iter.forward_char();
+        std::string sentence = get_buffer()->get_text(start_iter, after_condition_iter);
         std::smatch sm;
-        if(std::regex_match(previous_sentence, sm, no_bracket_statement_regex)) {
-          auto start_iter=iter;
-          start_iter.backward_chars(tab_size);
-          get_buffer()->erase(start_iter, iter);
-          get_buffer()->insert_at_cursor("{");
-          scroll_to(get_buffer()->get_insert());
-          return true;
+        if (std::regex_match(sentence, sm, no_bracket_statement_regex)) {
+            get_buffer()->insert_at_cursor("\n" + tabs + tab);
+            scroll_to(get_buffer()->get_insert());
+            return true;
         }
-      }
-    }
-  }
-  // Mark parameters of templated functions after pressing tab and after writing template argument
-  else if(key->keyval==GDK_KEY_Tab && (key->state&GDK_SHIFT_MASK)==0) {
-    if(*iter=='>') {
-      iter.forward_char();
-      Gtk::TextIter parenthesis_end_iter;
-      if(*iter=='(' && is_templated_function(iter, parenthesis_end_iter)) {
-        iter.forward_char();
-        get_buffer()->select_range(iter, parenthesis_end_iter);
+            //Indenting after for instance if(...)\n...;\n
+        else if (*condition_iter == ';' && condition_iter.get_line() > 0 && is_code_iter(condition_iter)) {
+            auto previous_end_iter = start_iter;
+            while (previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {}
+            auto condition_iter = get_condition_iter(previous_end_iter);
+            auto previous_start_iter = get_tabs_end_iter(
+                    get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
+            auto previous_tabs = get_line_before(previous_start_iter);
+            auto after_condition_iter = condition_iter;
+            after_condition_iter.forward_char();
+            std::string previous_sentence = get_buffer()->get_text(previous_start_iter, after_condition_iter);
+            std::smatch sm2;
+            if (std::regex_match(previous_sentence, sm2, no_bracket_statement_regex)) {
+                get_buffer()->insert_at_cursor("\n" + previous_tabs);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+        }
+            //Indenting after ':'
+        else if (*condition_iter == ':' && is_code_iter(condition_iter)) {
+            bool perform_indent = true;
+            auto iter = condition_iter;
+            while (!iter.starts_line() && *iter == ' ' && iter.backward_char()) {}
+            if (*iter == ')') {
+                auto token = get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(iter.get_line())));
+                if (token != "case")
+                    perform_indent = false;
+            }
+            if (perform_indent) {
+                Gtk::TextIter found_curly_iter;
+                if (find_open_curly_bracket_backward(iter, found_curly_iter)) {
+                    auto tabs_end_iter = get_tabs_end_iter(get_buffer()->get_iter_at_line(found_curly_iter.get_line()));
+                    auto tabs_start_of_sentence = get_line_before(tabs_end_iter);
+                    if (tabs.size() == (tabs_start_of_sentence.size() + tab_size)) {
+                        auto start_line_iter = get_buffer()->get_iter_at_line(iter.get_line());
+                        auto start_line_plus_tab_size = start_line_iter;
+                        for (size_t c = 0; c < tab_size; c++)
+                            start_line_plus_tab_size.forward_char();
+                        get_buffer()->erase(start_line_iter, start_line_plus_tab_size);
+                    } else {
+                        get_buffer()->insert_at_cursor("\n" + tabs + tab);
+                        scroll_to(get_buffer()->get_insert());
+                        return true;
+                    }
+                }
+            }
+        }
+        get_buffer()->insert_at_cursor("\n" + tabs);
         scroll_to(get_buffer()->get_insert());
         return true;
-      }
     }
-  }
-  
-  return false;
+        //Indent left when writing } on a new line
+    else if (key->keyval == GDK_KEY_braceright) {
+        std::string line = get_line_before();
+        if (line.size() >= tab_size && iter.ends_line()) {
+            bool indent_left = true;
+            for (auto c: line) {
+                if (c != tab_char) {
+                    indent_left = false;
+                    break;
+                }
+            }
+            if (indent_left) {
+                Gtk::TextIter insert_it = get_buffer()->get_insert()->get_iter();
+                Gtk::TextIter line_it = get_buffer()->get_iter_at_line(insert_it.get_line());
+                Gtk::TextIter line_plus_it = line_it;
+                line_plus_it.forward_chars(tab_size);
+                get_buffer()->erase(line_it, line_plus_it);
+                get_buffer()->insert_at_cursor("}");
+                return true;
+            }
+        }
+    }
+        //Indent left when writing { on a new line after for instance if(...)\n...
+    else if (key->keyval == GDK_KEY_braceleft) {
+        auto tabs_end_iter = get_tabs_end_iter();
+        auto tabs = get_line_before(tabs_end_iter);
+        size_t line_nr = iter.get_line();
+        if (line_nr > 0 && tabs.size() >= tab_size && iter == tabs_end_iter) {
+            auto previous_end_iter = iter;
+            while (previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {}
+            auto condition_iter = get_condition_iter(previous_end_iter);
+            auto previous_start_iter = get_tabs_end_iter(
+                    get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
+            auto previous_tabs = get_line_before(previous_start_iter);
+            auto after_condition_iter = condition_iter;
+            after_condition_iter.forward_char();
+            if ((tabs.size() - tab_size) == previous_tabs.size()) {
+                std::string previous_sentence = get_buffer()->get_text(previous_start_iter, after_condition_iter);
+                std::smatch sm;
+                if (std::regex_match(previous_sentence, sm, no_bracket_statement_regex)) {
+                    auto start_iter = iter;
+                    start_iter.backward_chars(tab_size);
+                    get_buffer()->erase(start_iter, iter);
+                    get_buffer()->insert_at_cursor("{");
+                    scroll_to(get_buffer()->get_insert());
+                    return true;
+                }
+            }
+        }
+    }
+        // Mark parameters of templated functions after pressing tab and after writing template argument
+    else if (key->keyval == GDK_KEY_Tab && (key->state & GDK_SHIFT_MASK) == 0) {
+        if (*iter == '>') {
+            iter.forward_char();
+            Gtk::TextIter parenthesis_end_iter;
+            if (*iter == '(' && is_templated_function(iter, parenthesis_end_iter)) {
+                iter.forward_char();
+                get_buffer()->select_range(iter, parenthesis_end_iter);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+        }
+    }
+
+    return false;
 }
 
 bool Source::View::on_key_press_event_smart_brackets(GdkEventKey *key) {
-  if(get_buffer()->get_has_selection())
-    return false;
-  
-  auto iter=get_buffer()->get_insert()->get_iter();
-  auto previous_iter=iter;
-  previous_iter.backward_char();
-  if(is_code_iter(iter)) {
-    //Move after ')' if closed expression
-    if(key->keyval==GDK_KEY_parenright) {
-      if(*iter==')' && symbol_count(iter, '(', ')')==0) {
-        iter.forward_char();
-        get_buffer()->place_cursor(iter);
-        scroll_to(get_buffer()->get_insert());
-        return true;
-      }
-    }
-    //Move after '>' if >( and closed expression
-    else if(key->keyval==GDK_KEY_greater) {
-      if(*iter=='>') {
-        iter.forward_char();
-        Gtk::TextIter parenthesis_end_iter;
-        if(*iter=='(' && is_templated_function(iter, parenthesis_end_iter)) {
-          get_buffer()->place_cursor(iter);
-          scroll_to(get_buffer()->get_insert());
-          return true;
-        }
-      }
-    }
-    //Move after '(' if >( and select text inside parentheses
-    else if(key->keyval==GDK_KEY_parenleft) {
-      auto previous_iter=iter;
-      previous_iter.backward_char();
-      if(*previous_iter=='>') {
-        Gtk::TextIter parenthesis_end_iter;
-        if(*iter=='(' && is_templated_function(iter, parenthesis_end_iter)) {
-          iter.forward_char();
-          get_buffer()->select_range(iter, parenthesis_end_iter);
-          scroll_to(iter);
-          return true;
-        }
-      }
+    if (get_buffer()->get_has_selection())
+        return false;
+
+    auto iter = get_buffer()->get_insert()->get_iter();
+    auto previous_iter = iter;
+    previous_iter.backward_char();
+    if (is_code_iter(iter)) {
+        //Move after ')' if closed expression
+        if (key->keyval == GDK_KEY_parenright) {
+            if (*iter == ')' && symbol_count(iter, '(', ')') == 0) {
+                iter.forward_char();
+                get_buffer()->place_cursor(iter);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+        }
+            //Move after '>' if >( and closed expression
+        else if (key->keyval == GDK_KEY_greater) {
+            if (*iter == '>') {
+                iter.forward_char();
+                Gtk::TextIter parenthesis_end_iter;
+                if (*iter == '(' && is_templated_function(iter, parenthesis_end_iter)) {
+                    get_buffer()->place_cursor(iter);
+                    scroll_to(get_buffer()->get_insert());
+                    return true;
+                }
+            }
+        }
+            //Move after '(' if >( and select text inside parentheses
+        else if (key->keyval == GDK_KEY_parenleft) {
+            auto previous_iter = iter;
+            previous_iter.backward_char();
+            if (*previous_iter == '>') {
+                Gtk::TextIter parenthesis_end_iter;
+                if (*iter == '(' && is_templated_function(iter, parenthesis_end_iter)) {
+                    iter.forward_char();
+                    get_buffer()->select_range(iter, parenthesis_end_iter);
+                    scroll_to(iter);
+                    return true;
+                }
+            }
+        }
     }
-  }
-  
-  return false;
+
+    return false;
 }
 
 bool Source::View::on_key_press_event_smart_inserts(GdkEventKey *key) {
-  if(get_buffer()->get_has_selection()) {
-    bool perform_insertion=false;
-    char left_char, right_char;
-    // Insert () around selection
-    if(key->keyval==GDK_KEY_parenleft) {
-      perform_insertion=true;
-      left_char='(';
-      right_char=')';
-    }
-    // Insert [] around selection
-    else if(key->keyval==GDK_KEY_bracketleft) {
-      perform_insertion=true;
-      left_char='[';
-      right_char=']';
-    }
-    // Insert {} around selection
-    else if(key->keyval==GDK_KEY_braceleft) {
-      perform_insertion=true;
-      left_char='{';
-      right_char='}';
-    }
-    // Insert <> around selection
-    else if(key->keyval==GDK_KEY_less) {
-      perform_insertion=true;
-      left_char='<';
-      right_char='>';
-    }
-    // Insert '' around selection
-    else if(key->keyval==GDK_KEY_apostrophe) {
-      perform_insertion=true;
-      left_char='\'';
-      right_char='\'';
-    }
-    // Insert "" around selection
-    else if(key->keyval==GDK_KEY_quotedbl) {
-      perform_insertion=true;
-      left_char='"';
-      right_char='"';
-    }
-    else if(language && language->get_id()=="markdown") {
-      if(key->keyval==GDK_KEY_dead_grave) {
-        perform_insertion=true;
-        left_char='`';
-        right_char='`';
-      }
-      if(key->keyval==GDK_KEY_asterisk) {
-        perform_insertion=true;
-        left_char='*';
-        right_char='*';
-      }
-      if(key->keyval==GDK_KEY_underscore) {
-        perform_insertion=true;
-        left_char='_';
-        right_char='_';
-      }
-      if(key->keyval==GDK_KEY_dead_tilde) {
-        perform_insertion=true;
-        left_char='~';
-        right_char='~';
-      }
-    }
-    if(perform_insertion) {
-      Gtk::TextIter start, end;
-      get_buffer()->get_selection_bounds(start, end);
-      auto start_mark=get_buffer()->create_mark(start);
-      auto end_mark=get_buffer()->create_mark(end);
-      get_buffer()->insert(start, Glib::ustring()+left_char);
-      get_buffer()->insert(end_mark->get_iter(), Glib::ustring()+right_char);
-      auto start_mark_next_iter=start_mark->get_iter();
-      start_mark_next_iter.forward_char();
-      get_buffer()->select_range(start_mark_next_iter, end_mark->get_iter());
-      get_buffer()->delete_mark(start_mark);
-      get_buffer()->delete_mark(end_mark);
-      return true;
+    if (get_buffer()->get_has_selection()) {
+        bool perform_insertion = false;
+        char left_char, right_char;
+        // Insert () around selection
+        if (key->keyval == GDK_KEY_parenleft) {
+            perform_insertion = true;
+            left_char = '(';
+            right_char = ')';
+        }
+            // Insert [] around selection
+        else if (key->keyval == GDK_KEY_bracketleft) {
+            perform_insertion = true;
+            left_char = '[';
+            right_char = ']';
+        }
+            // Insert {} around selection
+        else if (key->keyval == GDK_KEY_braceleft) {
+            perform_insertion = true;
+            left_char = '{';
+            right_char = '}';
+        }
+            // Insert <> around selection
+        else if (key->keyval == GDK_KEY_less) {
+            perform_insertion = true;
+            left_char = '<';
+            right_char = '>';
+        }
+            // Insert '' around selection
+        else if (key->keyval == GDK_KEY_apostrophe) {
+            perform_insertion = true;
+            left_char = '\'';
+            right_char = '\'';
+        }
+            // Insert "" around selection
+        else if (key->keyval == GDK_KEY_quotedbl) {
+            perform_insertion = true;
+            left_char = '"';
+            right_char = '"';
+        } else if (language && language->get_id() == "markdown") {
+            if (key->keyval == GDK_KEY_dead_grave) {
+                perform_insertion = true;
+                left_char = '`';
+                right_char = '`';
+            }
+            if (key->keyval == GDK_KEY_asterisk) {
+                perform_insertion = true;
+                left_char = '*';
+                right_char = '*';
+            }
+            if (key->keyval == GDK_KEY_underscore) {
+                perform_insertion = true;
+                left_char = '_';
+                right_char = '_';
+            }
+            if (key->keyval == GDK_KEY_dead_tilde) {
+                perform_insertion = true;
+                left_char = '~';
+                right_char = '~';
+            }
+        }
+        if (perform_insertion) {
+            Gtk::TextIter start, end;
+            get_buffer()->get_selection_bounds(start, end);
+            auto start_mark = get_buffer()->create_mark(start);
+            auto end_mark = get_buffer()->create_mark(end);
+            get_buffer()->insert(start, Glib::ustring() + left_char);
+            get_buffer()->insert(end_mark->get_iter(), Glib::ustring() + right_char);
+            auto start_mark_next_iter = start_mark->get_iter();
+            start_mark_next_iter.forward_char();
+            get_buffer()->select_range(start_mark_next_iter, end_mark->get_iter());
+            get_buffer()->delete_mark(start_mark);
+            get_buffer()->delete_mark(end_mark);
+            return true;
+        }
+        return false;
     }
-    return false;
-  }
-  
-  auto iter=get_buffer()->get_insert()->get_iter();
-  auto previous_iter=iter;
-  previous_iter.backward_char();
-  auto next_iter=iter;
-  next_iter.forward_char();
-  
-  auto allow_insertion=[](const Gtk::TextIter &iter) {
-    if(iter.ends_line() || *iter==' ' || *iter=='\t' || *iter==';' || *iter==')' || *iter==']' || *iter=='[' || *iter=='{' || *iter=='}')
-      return true;
-    return false;
-  };
-  
-  // Move right when clicking ' before a ' or when clicking " before a "
-  if(((key->keyval==GDK_KEY_apostrophe && *iter=='\'') ||
-      (key->keyval==GDK_KEY_quotedbl && *iter=='\"')) && is_code_iter(next_iter)) {
-    bool perform_move=false;
-    if(*previous_iter!='\\')
-      perform_move=true;
-    else {
-      auto it=previous_iter;
-      long backslash_count=1;
-      while(it.backward_char() && *it=='\\') {
-        ++backslash_count;
-      }
-      if(backslash_count%2==0)
-        perform_move=true;
-    }
-    if(perform_move) {
-      get_buffer()->place_cursor(next_iter);
-      scroll_to(get_buffer()->get_insert());
-      return true;
+
+    auto iter = get_buffer()->get_insert()->get_iter();
+    auto previous_iter = iter;
+    previous_iter.backward_char();
+    auto next_iter = iter;
+    next_iter.forward_char();
+
+    auto allow_insertion = [](const Gtk::TextIter &iter) {
+        if (iter.ends_line() || *iter == ' ' || *iter == '\t' || *iter == ';' || *iter == ')' || *iter == ']' ||
+            *iter == '[' || *iter == '{' || *iter == '}')
+            return true;
+        return false;
+    };
+
+    // Move right when clicking ' before a ' or when clicking " before a "
+    if (((key->keyval == GDK_KEY_apostrophe && *iter == '\'') ||
+         (key->keyval == GDK_KEY_quotedbl && *iter == '\"')) && is_code_iter(next_iter)) {
+        bool perform_move = false;
+        if (*previous_iter != '\\')
+            perform_move = true;
+        else {
+            auto it = previous_iter;
+            long backslash_count = 1;
+            while (it.backward_char() && *it == '\\') {
+                ++backslash_count;
+            }
+            if (backslash_count % 2 == 0)
+                perform_move = true;
+        }
+        if (perform_move) {
+            get_buffer()->place_cursor(next_iter);
+            scroll_to(get_buffer()->get_insert());
+            return true;
+        }
     }
-  }
-  // When to delete '' or ""
-  else if(key->keyval==GDK_KEY_BackSpace) {
-    if(((*previous_iter=='\'' && *iter=='\'') ||
-        (*previous_iter=='"' && *iter=='"')) && is_code_iter(previous_iter)) {
-      get_buffer()->erase(previous_iter, next_iter);
-      scroll_to(get_buffer()->get_insert());
-      return true;
+        // When to delete '' or ""
+    else if (key->keyval == GDK_KEY_BackSpace) {
+        if (((*previous_iter == '\'' && *iter == '\'') ||
+             (*previous_iter == '"' && *iter == '"')) && is_code_iter(previous_iter)) {
+            get_buffer()->erase(previous_iter, next_iter);
+            scroll_to(get_buffer()->get_insert());
+            return true;
+        }
     }
-  }
-  
-  if(is_code_iter(iter)) {
-    // Insert ()
-    if(key->keyval==GDK_KEY_parenleft && allow_insertion(iter)) {
-      if(symbol_count(iter, '(', ')')==0) {
-        get_buffer()->insert_at_cursor(")");
-        iter=get_buffer()->get_insert()->get_iter();
-        iter.backward_char();
-        get_buffer()->place_cursor(iter);
-        get_buffer()->insert_at_cursor("(");
-        scroll_to(get_buffer()->get_insert());
+
+    if (is_code_iter(iter)) {
+        // Insert ()
+        if (key->keyval == GDK_KEY_parenleft && allow_insertion(iter)) {
+            if (symbol_count(iter, '(', ')') == 0) {
+                get_buffer()->insert_at_cursor(")");
+                iter = get_buffer()->get_insert()->get_iter();
+                iter.backward_char();
+                get_buffer()->place_cursor(iter);
+                get_buffer()->insert_at_cursor("(");
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+        }
+            // Insert []
+        else if (key->keyval == GDK_KEY_bracketleft && allow_insertion(iter)) {
+            if (symbol_count(iter, '[', ']') == 0) {
+                get_buffer()->insert_at_cursor("[]");
+                auto iter = get_buffer()->get_insert()->get_iter();
+                iter.backward_char();
+                get_buffer()->place_cursor(iter);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+        }
+            // Move left on ] in []
+        else if (key->keyval == GDK_KEY_bracketright) {
+            if (*iter == ']' && symbol_count(iter, '[', ']') == 0) {
+                iter.forward_char();
+                get_buffer()->place_cursor(iter);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+        }
+            // Insert ''
+        else if (key->keyval == GDK_KEY_apostrophe && allow_insertion(iter) && symbol_count(iter, '\'', -1) % 2 == 0) {
+            get_buffer()->insert_at_cursor("''");
+            auto iter = get_buffer()->get_insert()->get_iter();
+            iter.backward_char();
+            get_buffer()->place_cursor(iter);
+            scroll_to(get_buffer()->get_insert());
+            return true;
+        }
+            // Insert ""
+        else if (key->keyval == GDK_KEY_quotedbl && allow_insertion(iter) && symbol_count(iter, '"', -1) % 2 == 0) {
+            get_buffer()->insert_at_cursor("\"\"");
+            auto iter = get_buffer()->get_insert()->get_iter();
+            iter.backward_char();
+            get_buffer()->place_cursor(iter);
+            scroll_to(get_buffer()->get_insert());
+            return true;
+        }
+            // Insert ; at the end of line, if iter is at the last )
+        else if (key->keyval == GDK_KEY_semicolon) {
+            if (*iter == ')' && symbol_count(iter, '(', ')') == 0) {
+                if (next_iter.ends_line()) {
+                    Gtk::TextIter open_non_curly_bracket_iter;
+                    if (find_open_non_curly_bracket_backward(previous_iter, open_non_curly_bracket_iter)) {
+                        open_non_curly_bracket_iter.backward_char();
+                        if (*open_non_curly_bracket_iter == ' ')
+                            open_non_curly_bracket_iter.backward_char();
+                        if (get_token(open_non_curly_bracket_iter) != "for") {
+                            iter.forward_char();
+                            get_buffer()->place_cursor(iter);
+                            get_buffer()->insert_at_cursor(";");
+                            scroll_to(get_buffer()->get_insert());
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+            // Delete ()
+        else if (key->keyval == GDK_KEY_BackSpace) {
+            if (*previous_iter == '(' && *iter == ')' && symbol_count(iter, '(', ')') == 0) {
+                auto next_iter = iter;
+                next_iter.forward_char();
+                get_buffer()->erase(previous_iter, next_iter);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+                // Delete []
+            else if (*previous_iter == '[' && *iter == ']' && symbol_count(iter, '[', ']') == 0) {
+                auto next_iter = iter;
+                next_iter.forward_char();
+                get_buffer()->erase(previous_iter, next_iter);
+                scroll_to(get_buffer()->get_insert());
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
+    if (!multiple_cursors_signals_set) {
+        multiple_cursors_signals_set = true;
+        multiple_cursors_last_insert = get_buffer()->create_mark(get_buffer()->get_insert()->get_iter(), false);
+        get_buffer()->signal_mark_set().connect(
+                [this](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+                    for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+                        if (extra_cursor.first == mark &&
+                            (!iter.ends_line() || iter.get_line_offset() > extra_cursor.second)) {
+                            extra_cursor.second = iter.get_line_offset();
+                            break;
+                        }
+                    }
+
+                    if (mark->get_name() == "insert") {
+                        if (multiple_cursors_use) {
+                            multiple_cursors_use = false;
+                            auto offset_diff = mark->get_iter().get_offset() -
+                                               multiple_cursors_last_insert->get_iter().get_offset();
+                            if (offset_diff != 0) {
+                                for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+                                    auto iter = extra_cursor.first->get_iter();
+                                    iter.forward_chars(offset_diff);
+                                    get_buffer()->move_mark(extra_cursor.first, iter);
+                                }
+                            }
+                            multiple_cursors_use = true;
+                        }
+                        get_buffer()->delete_mark(multiple_cursors_last_insert);
+                        multiple_cursors_last_insert = get_buffer()->create_mark(mark->get_iter(), false);
+                    }
+                });
+
+        // TODO: this handler should run after signal_insert
+        get_buffer()->signal_insert().connect(
+                [this](const Gtk::TextBuffer::iterator &iter, const Glib::ustring &text, int bytes) {
+                    if (multiple_cursors_use) {
+                        multiple_cursors_use = false;
+                        auto offset = iter.get_offset() - get_buffer()->get_insert()->get_iter().get_offset();
+                        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+                            auto iter = extra_cursor.first->get_iter();
+                            iter.forward_chars(offset);
+                            get_buffer()->insert(iter, text);
+                        }
+                        multiple_cursors_use = true;
+                    }
+                });
+
+        get_buffer()->signal_erase().connect(
+                [this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
+                    if (multiple_cursors_use) {
+                        auto insert_offset = get_buffer()->get_insert()->get_iter().get_offset();
+                        multiple_cursors_erase_backward_length = insert_offset - iter_start.get_offset();
+                        multiple_cursors_erase_forward_length = iter_end.get_offset() - insert_offset;
+                    }
+                }, false);
+
+        get_buffer()->signal_erase().connect(
+                [this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
+                    if (multiple_cursors_use) {
+                        multiple_cursors_use = false;
+                        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+                            auto start_iter = extra_cursor.first->get_iter();
+                            auto end_iter = start_iter;
+                            start_iter.backward_chars(multiple_cursors_erase_backward_length);
+                            end_iter.forward_chars(multiple_cursors_erase_forward_length);
+                            get_buffer()->erase(start_iter, end_iter);
+                        }
+                        multiple_cursors_use = true;
+                    }
+                });
+    }
+
+
+    if (key->keyval == GDK_KEY_Escape && !multiple_cursors_extra_cursors.empty()) {
+        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+            extra_cursor.first->set_visible(false);
+            get_buffer()->delete_mark(extra_cursor.first);
+        }
+        multiple_cursors_extra_cursors.clear();
         return true;
-      }
     }
-    // Insert []
-    else if(key->keyval==GDK_KEY_bracketleft && allow_insertion(iter)) {
-      if(symbol_count(iter, '[', ']')==0) {
-        get_buffer()->insert_at_cursor("[]");
-        auto iter=get_buffer()->get_insert()->get_iter();
+
+    unsigned create_cursor_mask = GDK_MOD1_MASK;
+    unsigned move_last_created_cursor_mask = GDK_SHIFT_MASK | GDK_MOD1_MASK;
+
+    // Move last created cursor
+    if ((key->keyval == GDK_KEY_Left || key->keyval == GDK_KEY_KP_Left) &&
+        (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
+        if (multiple_cursors_extra_cursors.empty())
+            return false;
+        auto &cursor = multiple_cursors_extra_cursors.back().first;
+        auto iter = cursor->get_iter();
         iter.backward_char();
-        get_buffer()->place_cursor(iter);
-        scroll_to(get_buffer()->get_insert());
+        get_buffer()->move_mark(cursor, iter);
         return true;
-      }
     }
-    // Move left on ] in []
-    else if(key->keyval==GDK_KEY_bracketright) {
-      if(*iter==']' && symbol_count(iter, '[', ']')==0) {
+    if ((key->keyval == GDK_KEY_Right || key->keyval == GDK_KEY_KP_Right) &&
+        (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
+        if (multiple_cursors_extra_cursors.empty())
+            return false;
+        auto &cursor = multiple_cursors_extra_cursors.back().first;
+        auto iter = cursor->get_iter();
         iter.forward_char();
-        get_buffer()->place_cursor(iter);
-        scroll_to(get_buffer()->get_insert());
+        get_buffer()->move_mark(cursor, iter);
         return true;
-      }
-    }
-    // Insert ''
-    else if(key->keyval==GDK_KEY_apostrophe && allow_insertion(iter) && symbol_count(iter, '\'', -1)%2==0) {
-      get_buffer()->insert_at_cursor("''");
-      auto iter=get_buffer()->get_insert()->get_iter();
-      iter.backward_char();
-      get_buffer()->place_cursor(iter);
-      scroll_to(get_buffer()->get_insert());
-      return true;
-    }
-    // Insert ""
-    else if(key->keyval==GDK_KEY_quotedbl && allow_insertion(iter) && symbol_count(iter, '"', -1)%2==0) {
-      get_buffer()->insert_at_cursor("\"\"");
-      auto iter=get_buffer()->get_insert()->get_iter();
-      iter.backward_char();
-      get_buffer()->place_cursor(iter);
-      scroll_to(get_buffer()->get_insert());
-      return true;
-    }
-    // Insert ; at the end of line, if iter is at the last )
-    else if(key->keyval==GDK_KEY_semicolon) {
-      if(*iter==')' && symbol_count(iter, '(', ')')==0) {
-        if(next_iter.ends_line()) {
-          Gtk::TextIter open_non_curly_bracket_iter;
-          if(find_open_non_curly_bracket_backward(previous_iter, open_non_curly_bracket_iter)) {
-            open_non_curly_bracket_iter.backward_char();
-            if(*open_non_curly_bracket_iter==' ')
-              open_non_curly_bracket_iter.backward_char();
-            if(get_token(open_non_curly_bracket_iter)!="for") {
-              iter.forward_char();
-              get_buffer()->place_cursor(iter);
-              get_buffer()->insert_at_cursor(";");
-              scroll_to(get_buffer()->get_insert());
-              return true;
-            }
-          }
-        }
-      }
-    }
-    // Delete ()
-    else if(key->keyval==GDK_KEY_BackSpace) {
-      if(*previous_iter=='(' && *iter==')' && symbol_count(iter, '(', ')')==0) {
-        auto next_iter=iter;
-        next_iter.forward_char();
-        get_buffer()->erase(previous_iter, next_iter);
-        scroll_to(get_buffer()->get_insert());
+    }
+    if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
+        (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
+        if (multiple_cursors_extra_cursors.empty())
+            return false;
+        auto &extra_cursor = multiple_cursors_extra_cursors.back();
+        auto iter = extra_cursor.first->get_iter();
+        auto line_offset = extra_cursor.second;
+        if (iter.backward_line()) {
+            auto end_line_iter = iter;
+            if (!end_line_iter.ends_line())
+                end_line_iter.forward_to_line_end();
+            iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
+            get_buffer()->move_mark(extra_cursor.first, iter);
+        }
         return true;
-      }
-      // Delete []
-      else if(*previous_iter=='[' && *iter==']' && symbol_count(iter, '[', ']')==0) {
-        auto next_iter=iter;
-        next_iter.forward_char();
-        get_buffer()->erase(previous_iter, next_iter);
-        scroll_to(get_buffer()->get_insert());
+    }
+    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
+        (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
+        if (multiple_cursors_extra_cursors.empty())
+            return false;
+        auto &extra_cursor = multiple_cursors_extra_cursors.back();
+        auto iter = extra_cursor.first->get_iter();
+        auto line_offset = extra_cursor.second;
+        if (iter.forward_line()) {
+            auto end_line_iter = iter;
+            if (!end_line_iter.ends_line())
+                end_line_iter.forward_to_line_end();
+            iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
+            get_buffer()->move_mark(extra_cursor.first, iter);
+        }
         return true;
-      }
     }
-  }
-  
-  return false;
-}
 
-bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
-  if(!multiple_cursors_signals_set) {
-    multiple_cursors_signals_set=true;
-    multiple_cursors_last_insert=get_buffer()->create_mark(get_buffer()->get_insert()->get_iter(), false);
-    get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-      for(auto &extra_cursor: multiple_cursors_extra_cursors) {
-        if(extra_cursor.first==mark && (!iter.ends_line() || iter.get_line_offset()>extra_cursor.second)) {
-          extra_cursor.second=iter.get_line_offset();
-          break;
-        }
-      }
-      
-      if(mark->get_name()=="insert") {
-        if(multiple_cursors_use) {
-          multiple_cursors_use=false;
-          auto offset_diff=mark->get_iter().get_offset()-multiple_cursors_last_insert->get_iter().get_offset();
-          if(offset_diff!=0) {
-            for(auto &extra_cursor: multiple_cursors_extra_cursors) {
-              auto iter=extra_cursor.first->get_iter();
-              iter.forward_chars(offset_diff);
-              get_buffer()->move_mark(extra_cursor.first, iter);
-            }
-          }
-          multiple_cursors_use=true;
-        }
-        get_buffer()->delete_mark(multiple_cursors_last_insert);
-        multiple_cursors_last_insert=get_buffer()->create_mark(mark->get_iter(), false);
-      }
-    });
-    
-    // TODO: this handler should run after signal_insert
-    get_buffer()->signal_insert().connect([this](const Gtk::TextBuffer::iterator &iter, const Glib::ustring &text, int bytes) {
-      if(multiple_cursors_use) {
-        multiple_cursors_use=false;
-        auto offset=iter.get_offset()-get_buffer()->get_insert()->get_iter().get_offset();
-        for(auto &extra_cursor: multiple_cursors_extra_cursors) {
-          auto iter=extra_cursor.first->get_iter();
-          iter.forward_chars(offset);
-          get_buffer()->insert(iter, text);
-        }
-        multiple_cursors_use=true;
-      }
-    });
-    
-    get_buffer()->signal_erase().connect([this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
-      if(multiple_cursors_use) {
-        auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset();
-        multiple_cursors_erase_backward_length=insert_offset-iter_start.get_offset();
-        multiple_cursors_erase_forward_length=iter_end.get_offset()-insert_offset;
-      }
-    }, false);
-    
-    get_buffer()->signal_erase().connect([this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
-      if(multiple_cursors_use) {
-        multiple_cursors_use=false;
-        for(auto &extra_cursor: multiple_cursors_extra_cursors) {
-          auto start_iter=extra_cursor.first->get_iter();
-          auto end_iter=start_iter;
-          start_iter.backward_chars(multiple_cursors_erase_backward_length);
-          end_iter.forward_chars(multiple_cursors_erase_forward_length);
-          get_buffer()->erase(start_iter, end_iter);
-        }
-        multiple_cursors_use=true;
-      }
-    });
-  }
-  
-  
-  if(key->keyval==GDK_KEY_Escape && !multiple_cursors_extra_cursors.empty()) {
-    for(auto &extra_cursor: multiple_cursors_extra_cursors) {
-      extra_cursor.first->set_visible(false);
-      get_buffer()->delete_mark(extra_cursor.first);
-    }
-    multiple_cursors_extra_cursors.clear();
-    return true;
-  }
-  
-  unsigned create_cursor_mask=GDK_MOD1_MASK;
-  unsigned move_last_created_cursor_mask=GDK_SHIFT_MASK|GDK_MOD1_MASK;
-  
-  // Move last created cursor
-  if((key->keyval==GDK_KEY_Left || key->keyval==GDK_KEY_KP_Left) && (key->state&move_last_created_cursor_mask)==move_last_created_cursor_mask) {
-    if(multiple_cursors_extra_cursors.empty())
-      return false;
-    auto &cursor=multiple_cursors_extra_cursors.back().first;
-    auto iter=cursor->get_iter();
-    iter.backward_char();
-    get_buffer()->move_mark(cursor, iter);
-    return true;
-  }
-  if((key->keyval==GDK_KEY_Right || key->keyval==GDK_KEY_KP_Right) && (key->state&move_last_created_cursor_mask)==move_last_created_cursor_mask) {
-    if(multiple_cursors_extra_cursors.empty())
-      return false;
-    auto &cursor=multiple_cursors_extra_cursors.back().first;
-    auto iter=cursor->get_iter();
-    iter.forward_char();
-    get_buffer()->move_mark(cursor, iter);
-    return true;
-  }
-  if((key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up) && (key->state&move_last_created_cursor_mask)==move_last_created_cursor_mask) {
-    if(multiple_cursors_extra_cursors.empty())
-      return false;
-    auto &extra_cursor=multiple_cursors_extra_cursors.back();
-    auto iter=extra_cursor.first->get_iter();
-    auto line_offset=extra_cursor.second;
-    if(iter.backward_line()) {
-      auto end_line_iter=iter;
-      if(!end_line_iter.ends_line())
-        end_line_iter.forward_to_line_end();
-      iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
-      get_buffer()->move_mark(extra_cursor.first, iter);
+    // Create extra cursor
+    if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
+        (key->state & create_cursor_mask) == create_cursor_mask) {
+        auto insert_iter = get_buffer()->get_insert()->get_iter();
+        auto insert_line_offset = insert_iter.get_line_offset();
+        auto offset = insert_iter.get_offset();
+        for (auto &extra_cursor: multiple_cursors_extra_cursors)
+            offset = std::min(offset, extra_cursor.first->get_iter().get_offset());
+        auto iter = get_buffer()->get_iter_at_offset(offset);
+        if (iter.backward_line()) {
+            auto end_line_iter = iter;
+            if (!end_line_iter.ends_line())
+                end_line_iter.forward_to_line_end();
+            iter.forward_chars(std::min(insert_line_offset, end_line_iter.get_line_offset()));
+            multiple_cursors_extra_cursors.emplace_back(get_buffer()->create_mark(iter, false), insert_line_offset);
+            multiple_cursors_extra_cursors.back().first->set_visible(true);
+        }
+        return true;
     }
-    return true;
-  }
-  if((key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down) && (key->state&move_last_created_cursor_mask)==move_last_created_cursor_mask) {
-    if(multiple_cursors_extra_cursors.empty())
-      return false;
-    auto &extra_cursor=multiple_cursors_extra_cursors.back();
-    auto iter=extra_cursor.first->get_iter();
-    auto line_offset=extra_cursor.second;
-    if(iter.forward_line()) {
-      auto end_line_iter=iter;
-      if(!end_line_iter.ends_line())
-        end_line_iter.forward_to_line_end();
-      iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
-      get_buffer()->move_mark(extra_cursor.first, iter);
+    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
+        (key->state & create_cursor_mask) == create_cursor_mask) {
+        auto insert_iter = get_buffer()->get_insert()->get_iter();
+        auto insert_line_offset = insert_iter.get_line_offset();
+        auto offset = insert_iter.get_offset();
+        for (auto &extra_cursor: multiple_cursors_extra_cursors)
+            offset = std::max(offset, extra_cursor.first->get_iter().get_offset());
+        auto iter = get_buffer()->get_iter_at_offset(offset);
+        if (iter.forward_line()) {
+            auto end_line_iter = iter;
+            if (!end_line_iter.ends_line())
+                end_line_iter.forward_to_line_end();
+            iter.forward_chars(std::min(insert_line_offset, end_line_iter.get_line_offset()));
+            multiple_cursors_extra_cursors.emplace_back(get_buffer()->create_mark(iter, false), insert_line_offset);
+            multiple_cursors_extra_cursors.back().first->set_visible(true);
+        }
+        return true;
     }
-    return true;
-  }
-  
-  // Create extra cursor
-  if((key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up) && (key->state&create_cursor_mask)==create_cursor_mask) {
-    auto insert_iter=get_buffer()->get_insert()->get_iter();
-    auto insert_line_offset=insert_iter.get_line_offset();
-    auto offset=insert_iter.get_offset();
-    for(auto &extra_cursor: multiple_cursors_extra_cursors)
-      offset=std::min(offset, extra_cursor.first->get_iter().get_offset());
-    auto iter=get_buffer()->get_iter_at_offset(offset);
-    if(iter.backward_line()) {
-      auto end_line_iter=iter;
-      if(!end_line_iter.ends_line())
-        end_line_iter.forward_to_line_end();
-      iter.forward_chars(std::min(insert_line_offset, end_line_iter.get_line_offset()));
-      multiple_cursors_extra_cursors.emplace_back(get_buffer()->create_mark(iter, false), insert_line_offset);
-      multiple_cursors_extra_cursors.back().first->set_visible(true);
+
+    // Move cursors left/right
+    if ((key->keyval == GDK_KEY_Left || key->keyval == GDK_KEY_KP_Left) && (key->state & GDK_CONTROL_MASK) > 0) {
+        multiple_cursors_use = false;
+        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+            auto iter = extra_cursor.first->get_iter();
+            iter.backward_word_start();
+            extra_cursor.second = iter.get_line_offset();
+            get_buffer()->move_mark(extra_cursor.first, iter);
+        }
+        auto insert = get_buffer()->get_insert();
+        auto iter = insert->get_iter();
+        iter.backward_word_start();
+        get_buffer()->move_mark(insert, iter);
+        if ((key->state & GDK_SHIFT_MASK) == 0)
+            get_buffer()->move_mark_by_name("selection_bound", iter);
+        return true;
     }
-    return true;
-  }
-  if((key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down) && (key->state&create_cursor_mask)==create_cursor_mask) {
-    auto insert_iter=get_buffer()->get_insert()->get_iter();
-    auto insert_line_offset=insert_iter.get_line_offset();
-    auto offset=insert_iter.get_offset();
-    for(auto &extra_cursor: multiple_cursors_extra_cursors)
-      offset=std::max(offset, extra_cursor.first->get_iter().get_offset());
-    auto iter=get_buffer()->get_iter_at_offset(offset);
-    if(iter.forward_line()) {
-      auto end_line_iter=iter;
-      if(!end_line_iter.ends_line())
-        end_line_iter.forward_to_line_end();
-      iter.forward_chars(std::min(insert_line_offset, end_line_iter.get_line_offset()));
-      multiple_cursors_extra_cursors.emplace_back(get_buffer()->create_mark(iter, false), insert_line_offset);
-      multiple_cursors_extra_cursors.back().first->set_visible(true);
+    if ((key->keyval == GDK_KEY_Right || key->keyval == GDK_KEY_KP_Right) && (key->state & GDK_CONTROL_MASK) > 0) {
+        multiple_cursors_use = false;
+        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+            auto iter = extra_cursor.first->get_iter();
+            iter.forward_visible_word_end();
+            extra_cursor.second = iter.get_line_offset();
+            get_buffer()->move_mark(extra_cursor.first, iter);
+        }
+        auto insert = get_buffer()->get_insert();
+        auto iter = insert->get_iter();
+        iter.forward_visible_word_end();
+        get_buffer()->move_mark(insert, iter);
+        if ((key->state & GDK_SHIFT_MASK) == 0)
+            get_buffer()->move_mark_by_name("selection_bound", iter);
+        return true;
     }
-    return true;
-  }
-  
-  // Move cursors left/right
-  if((key->keyval==GDK_KEY_Left || key->keyval==GDK_KEY_KP_Left) && (key->state&GDK_CONTROL_MASK)>0) {
-    multiple_cursors_use=false;
-    for(auto &extra_cursor: multiple_cursors_extra_cursors) {
-      auto iter=extra_cursor.first->get_iter();
-      iter.backward_word_start();
-      extra_cursor.second=iter.get_line_offset();
-      get_buffer()->move_mark(extra_cursor.first, iter);
-    }
-    auto insert=get_buffer()->get_insert();
-    auto iter=insert->get_iter();
-    iter.backward_word_start();
-    get_buffer()->move_mark(insert, iter);
-    if((key->state&GDK_SHIFT_MASK)==0)
-      get_buffer()->move_mark_by_name("selection_bound", iter);
-    return true;
-  }
-  if((key->keyval==GDK_KEY_Right || key->keyval==GDK_KEY_KP_Right) && (key->state&GDK_CONTROL_MASK)>0) {
-    multiple_cursors_use=false;
-    for(auto &extra_cursor: multiple_cursors_extra_cursors) {
-      auto iter=extra_cursor.first->get_iter();
-      iter.forward_visible_word_end();
-      extra_cursor.second=iter.get_line_offset();
-      get_buffer()->move_mark(extra_cursor.first, iter);
-    }
-    auto insert=get_buffer()->get_insert();
-    auto iter=insert->get_iter();
-    iter.forward_visible_word_end();
-    get_buffer()->move_mark(insert, iter);
-    if((key->state&GDK_SHIFT_MASK)==0)
-      get_buffer()->move_mark_by_name("selection_bound", iter);
-    return true;
-  }
-  
-  // Move cursors up/down
-  if((key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up)) {
-    multiple_cursors_use=false;
-    for(auto &extra_cursor: multiple_cursors_extra_cursors) {
-      auto iter=extra_cursor.first->get_iter();
-      auto line_offset=extra_cursor.second;
-      if(iter.backward_line()) {
-        auto end_line_iter=iter;
-        if(!end_line_iter.ends_line())
-          end_line_iter.forward_to_line_end();
-        iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
-        get_buffer()->move_mark(extra_cursor.first, iter);
-      }
+
+    // Move cursors up/down
+    if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up)) {
+        multiple_cursors_use = false;
+        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+            auto iter = extra_cursor.first->get_iter();
+            auto line_offset = extra_cursor.second;
+            if (iter.backward_line()) {
+                auto end_line_iter = iter;
+                if (!end_line_iter.ends_line())
+                    end_line_iter.forward_to_line_end();
+                iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
+                get_buffer()->move_mark(extra_cursor.first, iter);
+            }
+        }
+        return false;
     }
-    return false;
-  }
-  if((key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down)) {
-    multiple_cursors_use=false;
-    for(auto &extra_cursor: multiple_cursors_extra_cursors) {
-      auto iter=extra_cursor.first->get_iter();
-      auto line_offset=extra_cursor.second;
-      if(iter.forward_line()) {
-        auto end_line_iter=iter;
-        if(!end_line_iter.ends_line())
-          end_line_iter.forward_to_line_end();
-        iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
-        get_buffer()->move_mark(extra_cursor.first, iter);
-      }
+    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down)) {
+        multiple_cursors_use = false;
+        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+            auto iter = extra_cursor.first->get_iter();
+            auto line_offset = extra_cursor.second;
+            if (iter.forward_line()) {
+                auto end_line_iter = iter;
+                if (!end_line_iter.ends_line())
+                    end_line_iter.forward_to_line_end();
+                iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
+                get_buffer()->move_mark(extra_cursor.first, iter);
+            }
+        }
+        return false;
     }
+
+    // Smart Home-key, start of line
+    if ((key->keyval == GDK_KEY_Home || key->keyval == GDK_KEY_KP_Home) && (key->state & GDK_CONTROL_MASK) == 0) {
+        for (auto &extra_cursor: multiple_cursors_extra_cursors)
+            get_buffer()->move_mark(extra_cursor.first, get_smart_home_iter(extra_cursor.first->get_iter()));
+        multiple_cursors_use = false;
+        return false;
+    }
+    // Smart End-key, end of line
+    if ((key->keyval == GDK_KEY_End || key->keyval == GDK_KEY_KP_End) && (key->state & GDK_CONTROL_MASK) == 0) {
+        for (auto &extra_cursor: multiple_cursors_extra_cursors)
+            get_buffer()->move_mark(extra_cursor.first, get_smart_end_iter(extra_cursor.first->get_iter()));
+        multiple_cursors_use = false;
+        return false;
+    }
+
     return false;
-  }
-  
-  // Smart Home-key, start of line
-  if((key->keyval==GDK_KEY_Home || key->keyval==GDK_KEY_KP_Home) && (key->state&GDK_CONTROL_MASK)==0) {
-    for(auto &extra_cursor: multiple_cursors_extra_cursors)
-      get_buffer()->move_mark(extra_cursor.first, get_smart_home_iter(extra_cursor.first->get_iter()));
-    multiple_cursors_use=false;
-    return false;
-  }
-  // Smart End-key, end of line
-  if((key->keyval==GDK_KEY_End || key->keyval==GDK_KEY_KP_End) && (key->state&GDK_CONTROL_MASK)==0) {
-    for(auto &extra_cursor: multiple_cursors_extra_cursors)
-      get_buffer()->move_mark(extra_cursor.first, get_smart_end_iter(extra_cursor.first->get_iter()));
-    multiple_cursors_use=false;
-    return false;
-  }
-  
-  return false;
 }
 
 bool Source::View::on_button_press_event(GdkEventButton *event) {
-  // Select range when double clicking
-  if(event->type==GDK_2BUTTON_PRESS) {
-    Gtk::TextIter start, end;
-    get_buffer()->get_selection_bounds(start, end);
-    auto iter=start;
-    while((*iter>=48 && *iter<=57) || (*iter>=65 && *iter<=90) || (*iter>=97 && *iter<=122) || *iter==95) {
-      start=iter;
-      if(!iter.backward_char())
-        break;
-    }
-    while((*end>=48 && *end<=57) || (*end>=65 && *end<=90) || (*end>=97 && *end<=122) || *end==95) {
-      if(!end.forward_char())
-        break;
-    }
-    get_buffer()->select_range(start, end);
-    return true;
-  }
+    // Select range when double clicking
+    if (event->type == GDK_2BUTTON_PRESS) {
+        Gtk::TextIter start, end;
+        get_buffer()->get_selection_bounds(start, end);
+        auto iter = start;
+        while ((*iter >= 48 && *iter <= 57) || (*iter >= 65 && *iter <= 90) || (*iter >= 97 && *iter <= 122) ||
+               *iter == 95) {
+            start = iter;
+            if (!iter.backward_char())
+                break;
+        }
+        while ((*end >= 48 && *end <= 57) || (*end >= 65 && *end <= 90) || (*end >= 97 && *end <= 122) || *end == 95) {
+            if (!end.forward_char())
+                break;
+        }
+        get_buffer()->select_range(start, end);
+        return true;
+    }
 
-  // Go to implementation or declaration
-  if((event->type == GDK_BUTTON_PRESS) && (event->button == 1)){
+    // Go to implementation or declaration
+    if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)) {
 #ifdef __APPLE__
-    GdkModifierType mask=GDK_MOD2_MASK;
+        GdkModifierType mask=GDK_MOD2_MASK;
 #else
-    GdkModifierType mask=GDK_CONTROL_MASK;
+        GdkModifierType mask = GDK_CONTROL_MASK;
 #endif
-    if(event->state & mask) {
-      int x, y;
-      window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
-      Gtk::TextIter iter;
-      get_iter_at_location(iter, x, y);
-      if(iter)
-        get_buffer()->place_cursor(iter);
-      
-      Menu::get().actions["source_goto_declaration_or_implementation"]->activate();
-      return true;
+        if (event->state & mask) {
+            int x, y;
+            window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
+            Gtk::TextIter iter;
+            get_iter_at_location(iter, x, y);
+            if (iter)
+                get_buffer()->place_cursor(iter);
+
+            Menu::get().actions["source_goto_declaration_or_implementation"]->activate();
+            return true;
+        }
     }
-  }
 
-  // Open right click menu
-  if((event->type == GDK_BUTTON_PRESS) && (event->button == 3)){
-    hide_tooltips();
-    if(!get_buffer()->get_has_selection()){
-      int x,y;
-      window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT,event->x,event->y,x,y);
-      Gtk::TextIter iter;
-      get_iter_at_location(iter,x,y);
-      if(iter)
-        get_buffer()->place_cursor(iter);
-      Menu::get().right_click_line_menu->popup(event->button,event->time);
-    } else {
-      Menu::get().right_click_selected_menu->popup(event->button,event->time);
+    // Open right click menu
+    if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) {
+        hide_tooltips();
+        if (!get_buffer()->get_has_selection()) {
+            int x, y;
+            window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
+            Gtk::TextIter iter;
+            get_iter_at_location(iter, x, y);
+            if (iter)
+                get_buffer()->place_cursor(iter);
+            Menu::get().right_click_line_menu->popup(event->button, event->time);
+        } else {
+            Menu::get().right_click_selected_menu->popup(event->button, event->time);
+        }
+        return true;
     }
-    return true;
-  }
-  return Gsv::View::on_button_press_event(event);
+    return Gsv::View::on_button_press_event(event);
 }
 
 bool Source::View::on_motion_notify_event(GdkEventMotion *event) {
-  // Workaround for drag-and-drop crash on MacOS
-  // TODO 2018: check if this bug has been fixed
+    // Workaround for drag-and-drop crash on MacOS
+    // TODO 2018: check if this bug has been fixed
 #ifdef __APPLE__
-  if((event->state & GDK_BUTTON1_MASK) == 0)
+                                                                                                                            if((event->state & GDK_BUTTON1_MASK) == 0)
     return Gsv::View::on_motion_notify_event(event);
   else {
     int x, y;
@@ -2727,241 +2745,241 @@ bool Source::View::on_motion_notify_event(GdkEventMotion *event) {
     return true;
   }
 #else
-  return Gsv::View::on_motion_notify_event(event);
+    return Gsv::View::on_motion_notify_event(event);
 #endif
 }
 
 std::pair<char, unsigned> Source::View::find_tab_char_and_size() {
-  std::unordered_map<char, size_t> tab_chars;
-  std::unordered_map<unsigned, size_t> tab_sizes;
-  auto iter=get_buffer()->begin();
-  long tab_count=-1;
-  long last_tab_count=0;
-  bool single_quoted=false;
-  bool double_quoted=false;
-  //For bracket languages, TODO: add more language ids
-  if(is_bracket_language && !(language && language->get_id()=="html")) {
-    bool line_comment=false;
-    bool comment=false;
-    bool bracket_last_line=false;
-    char last_char=0;
-    long last_tab_diff=-1;
-    while(iter) {
-      if(iter.starts_line()) {
-        line_comment=false;
-        single_quoted=false;
-        double_quoted=false;
-        tab_count=0;
-        if(last_char=='{')
-          bracket_last_line=true;
-        else
-          bracket_last_line=false;
-      }
-      if(bracket_last_line && tab_count!=-1) {
-        if(*iter==' ') {
-          tab_chars[' ']++;
-          tab_count++;
+    std::unordered_map<char, size_t> tab_chars;
+    std::unordered_map<unsigned, size_t> tab_sizes;
+    auto iter = get_buffer()->begin();
+    long tab_count = -1;
+    long last_tab_count = 0;
+    bool single_quoted = false;
+    bool double_quoted = false;
+    //For bracket languages, TODO: add more language ids
+    if (is_bracket_language && !(language && language->get_id() == "html")) {
+        bool line_comment = false;
+        bool comment = false;
+        bool bracket_last_line = false;
+        char last_char = 0;
+        long last_tab_diff = -1;
+        while (iter) {
+            if (iter.starts_line()) {
+                line_comment = false;
+                single_quoted = false;
+                double_quoted = false;
+                tab_count = 0;
+                if (last_char == '{')
+                    bracket_last_line = true;
+                else
+                    bracket_last_line = false;
+            }
+            if (bracket_last_line && tab_count != -1) {
+                if (*iter == ' ') {
+                    tab_chars[' ']++;
+                    tab_count++;
+                } else if (*iter == '\t') {
+                    tab_chars['\t']++;
+                    tab_count++;
+                } else {
+                    auto line_iter = iter;
+                    char last_line_char = 0;
+                    while (line_iter && !line_iter.ends_line()) {
+                        if (*line_iter != ' ' && *line_iter != '\t')
+                            last_line_char = *line_iter;
+                        if (*line_iter == '(')
+                            break;
+                        line_iter.forward_char();
+                    }
+                    if (last_line_char == ':' || *iter == '#') {
+                        tab_count = 0;
+                        if ((iter.get_line() + 1) < get_buffer()->get_line_count()) {
+                            iter = get_buffer()->get_iter_at_line(iter.get_line() + 1);
+                            continue;
+                        }
+                    } else if (!iter.ends_line()) {
+                        if (tab_count != last_tab_count)
+                            tab_sizes[std::abs(tab_count - last_tab_count)]++;
+                        last_tab_diff = std::abs(tab_count - last_tab_count);
+                        last_tab_count = tab_count;
+                        last_char = 0;
+                    }
+                }
+            }
+
+            auto prev_iter = iter;
+            prev_iter.backward_char();
+            auto prev_prev_iter = prev_iter;
+            prev_prev_iter.backward_char();
+            if (!double_quoted && *iter == '\'' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
+                single_quoted = !single_quoted;
+            else if (!single_quoted && *iter == '\"' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
+                double_quoted = !double_quoted;
+            else if (!single_quoted && !double_quoted) {
+                auto next_iter = iter;
+                next_iter.forward_char();
+                if (*iter == '/' && *next_iter == '/')
+                    line_comment = true;
+                else if (*iter == '/' && *next_iter == '*')
+                    comment = true;
+                else if (*iter == '*' && *next_iter == '/') {
+                    iter.forward_char();
+                    iter.forward_char();
+                    comment = false;
+                }
+            }
+            if (!single_quoted && !double_quoted && !comment && !line_comment && *iter != ' ' && *iter != '\t' &&
+                !iter.ends_line())
+                last_char = *iter;
+            if (!single_quoted && !double_quoted && !comment && !line_comment && *iter == '}' && tab_count != -1 &&
+                last_tab_diff != -1)
+                last_tab_count -= last_tab_diff;
+            if (*iter != ' ' && *iter != '\t')
+                tab_count = -1;
+
+            iter.forward_char();
         }
-        else if(*iter=='\t') {
-          tab_chars['\t']++;
-          tab_count++;
+    } else {
+        long para_count = 0;
+        while (iter) {
+            if (iter.starts_line())
+                tab_count = 0;
+            if (tab_count != -1 && para_count == 0 && single_quoted == false && double_quoted == false) {
+                if (*iter == ' ') {
+                    tab_chars[' ']++;
+                    tab_count++;
+                } else if (*iter == '\t') {
+                    tab_chars['\t']++;
+                    tab_count++;
+                } else if (!iter.ends_line()) {
+                    if (tab_count != last_tab_count)
+                        tab_sizes[std::abs(tab_count - last_tab_count)]++;
+                    last_tab_count = tab_count;
+                }
+            }
+            auto prev_iter = iter;
+            prev_iter.backward_char();
+            auto prev_prev_iter = prev_iter;
+            prev_prev_iter.backward_char();
+            if (!double_quoted && *iter == '\'' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
+                single_quoted = !single_quoted;
+            else if (!single_quoted && *iter == '\"' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
+                double_quoted = !double_quoted;
+            else if (!single_quoted && !double_quoted) {
+                if (*iter == '(')
+                    para_count++;
+                else if (*iter == ')')
+                    para_count--;
+            }
+            if (*iter != ' ' && *iter != '\t')
+                tab_count = -1;
+
+            iter.forward_char();
         }
-        else {
-          auto line_iter=iter;
-          char last_line_char=0;
-          while(line_iter && !line_iter.ends_line()) {
-            if(*line_iter!=' ' && *line_iter!='\t')
-              last_line_char=*line_iter;
-            if(*line_iter=='(')
-              break;
-            line_iter.forward_char();
-          }
-          if(last_line_char==':' || *iter=='#') {
-            tab_count=0;
-            if((iter.get_line()+1) < get_buffer()->get_line_count()) {
-              iter=get_buffer()->get_iter_at_line(iter.get_line()+1);
-              continue;
-            }
-          }
-          else if(!iter.ends_line()) {
-            if(tab_count!=last_tab_count)
-              tab_sizes[std::abs(tab_count-last_tab_count)]++;
-            last_tab_diff=std::abs(tab_count-last_tab_count);
-            last_tab_count=tab_count;
-            last_char=0;
-          }
-        }
-      }
-
-      auto prev_iter=iter;
-      prev_iter.backward_char();
-      auto prev_prev_iter=prev_iter;
-      prev_prev_iter.backward_char();
-      if(!double_quoted && *iter=='\'' && !(*prev_iter=='\\' && *prev_prev_iter!='\\'))
-        single_quoted=!single_quoted;
-      else if(!single_quoted && *iter=='\"' && !(*prev_iter=='\\' && *prev_prev_iter!='\\'))
-        double_quoted=!double_quoted;
-      else if(!single_quoted && !double_quoted) {
-        auto next_iter=iter;
-        next_iter.forward_char();
-        if(*iter=='/' && *next_iter=='/')
-          line_comment=true;
-        else if(*iter=='/' && *next_iter=='*')
-          comment=true;
-        else if(*iter=='*' && *next_iter=='/') {
-          iter.forward_char();
-          iter.forward_char();
-          comment=false;
-        }
-      }
-      if(!single_quoted && !double_quoted && !comment && !line_comment && *iter!=' ' && *iter!='\t' && !iter.ends_line())
-        last_char=*iter;
-      if(!single_quoted && !double_quoted && !comment && !line_comment && *iter=='}' && tab_count!=-1 && last_tab_diff!=-1)
-        last_tab_count-=last_tab_diff;
-      if(*iter!=' ' && *iter!='\t')
-        tab_count=-1;
-
-      iter.forward_char();
-    }
-  }
-  else {
-    long para_count=0;
-    while(iter) {
-      if(iter.starts_line())
-        tab_count=0;
-      if(tab_count!=-1 && para_count==0 && single_quoted==false && double_quoted==false) {
-        if(*iter==' ') {
-          tab_chars[' ']++;
-          tab_count++;
-        }
-        else if(*iter=='\t') {
-          tab_chars['\t']++;
-          tab_count++;
-        }
-        else if(!iter.ends_line()) {
-          if(tab_count!=last_tab_count)
-            tab_sizes[std::abs(tab_count-last_tab_count)]++;
-          last_tab_count=tab_count;
-        }
-      }
-      auto prev_iter=iter;
-      prev_iter.backward_char();
-      auto prev_prev_iter=prev_iter;
-      prev_prev_iter.backward_char();
-      if(!double_quoted && *iter=='\'' && !(*prev_iter=='\\' && *prev_prev_iter!='\\'))
-        single_quoted=!single_quoted;
-      else if(!single_quoted && *iter=='\"' && !(*prev_iter=='\\' && *prev_prev_iter!='\\'))
-        double_quoted=!double_quoted;
-      else if(!single_quoted && !double_quoted) {
-        if(*iter=='(')
-          para_count++;
-        else if(*iter==')')
-          para_count--;
-      }
-      if(*iter!=' ' && *iter!='\t')
-        tab_count=-1;
-
-      iter.forward_char();
     }
-  }
 
-  char found_tab_char=0;
-  size_t occurences=0;
-  for(auto &tab_char: tab_chars) {
-    if(tab_char.second>occurences) {
-      found_tab_char=tab_char.first;
-      occurences=tab_char.second;
+    char found_tab_char = 0;
+    size_t occurences = 0;
+    for (auto &tab_char: tab_chars) {
+        if (tab_char.second > occurences) {
+            found_tab_char = tab_char.first;
+            occurences = tab_char.second;
+        }
     }
-  }
-  unsigned found_tab_size=0;
-  occurences=0;
-  for(auto &tab_size: tab_sizes) {
-    if(tab_size.second>occurences) {
-      found_tab_size=tab_size.first;
-      occurences=tab_size.second;
+    unsigned found_tab_size = 0;
+    occurences = 0;
+    for (auto &tab_size: tab_sizes) {
+        if (tab_size.second > occurences) {
+            found_tab_size = tab_size.first;
+            occurences = tab_size.second;
+        }
     }
-  }
-  return {found_tab_char, found_tab_size};
+    return {found_tab_char, found_tab_size};
 }
 
 
 /////////////////////
 //// GenericView ////
 /////////////////////
-Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) : BaseView(file_path, language), View(file_path, language, true) {
-  configure();
-  spellcheck_all=true;
-  
-  if(language)
-    get_source_buffer()->set_language(language);
-  
-  auto completion=get_completion();
-  completion->property_show_headers()=false;
-  completion->property_show_icons()=false;
-  completion->property_accelerators()=0;
-  
-  auto completion_words=Gsv::CompletionWords::create("", Glib::RefPtr<Gdk::Pixbuf>());
-  completion_words->register_provider(get_buffer());
-  completion->add_provider(completion_words);
-  
-  if(language) {
-    auto language_manager=LanguageManager::get_default();
-    auto search_paths=language_manager->get_search_path();
-    bool found_language_file=false;
-    boost::filesystem::path language_file;
-    for(auto &search_path: search_paths) {
-      boost::filesystem::path p(static_cast<std::string>(search_path)+'/'+static_cast<std::string>(language->get_id())+".lang");
-      if(boost::filesystem::exists(p) && boost::filesystem::is_regular_file(p)) {
-        language_file=p;
-        found_language_file=true;
-        break;
-      }
-    }
-    if(found_language_file) {
-      auto completion_buffer_keywords=CompletionBuffer::create();
-      boost::property_tree::ptree pt;
-      try {
-        boost::property_tree::xml_parser::read_xml(language_file.string(), pt);
-      }
-      catch(const std::exception &e) {
-        Terminal::get().print("Error: error parsing language file "+language_file.string()+": "+e.what()+'\n', true);
-      }
-      bool has_context_class=false;
-      parse_language_file(completion_buffer_keywords, has_context_class, pt);
-      if(!has_context_class)
-        spellcheck_all=false;
-      completion_words->register_provider(completion_buffer_keywords);
+Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language)
+        : BaseView(file_path, language), View(file_path, language, true) {
+    configure();
+    spellcheck_all = true;
+
+    if (language)
+        get_source_buffer()->set_language(language);
+
+    auto completion = get_completion();
+    completion->property_show_headers() = false;
+    completion->property_show_icons() = false;
+    completion->property_accelerators() = 0;
+
+    auto completion_words = Gsv::CompletionWords::create("", Glib::RefPtr<Gdk::Pixbuf>());
+    completion_words->register_provider(get_buffer());
+    completion->add_provider(completion_words);
+
+    if (language) {
+        auto language_manager = LanguageManager::get_default();
+        auto search_paths = language_manager->get_search_path();
+        bool found_language_file = false;
+        boost::filesystem::path language_file;
+        for (auto &search_path: search_paths) {
+            boost::filesystem::path p(
+                    static_cast<std::string>(search_path) + '/' + static_cast<std::string>(language->get_id()) +
+                    ".lang");
+            if (boost::filesystem::exists(p) && boost::filesystem::is_regular_file(p)) {
+                language_file = p;
+                found_language_file = true;
+                break;
+            }
+        }
+        if (found_language_file) {
+            auto completion_buffer_keywords = CompletionBuffer::create();
+            boost::property_tree::ptree pt;
+            try {
+                boost::property_tree::xml_parser::read_xml(language_file.string(), pt);
+            }
+            catch (const std::exception &e) {
+                Terminal::get().print(
+                        "Error: error parsing language file " + language_file.string() + ": " + e.what() + '\n', true);
+            }
+            bool has_context_class = false;
+            parse_language_file(completion_buffer_keywords, has_context_class, pt);
+            if (!has_context_class)
+                spellcheck_all = false;
+            completion_words->register_provider(completion_buffer_keywords);
+        }
     }
-  }
 }
 
-void Source::GenericView::parse_language_file(Glib::RefPtr<CompletionBuffer> &completion_buffer, bool &has_context_class, const boost::property_tree::ptree &pt) {
-  bool case_insensitive=false;
-  for(auto &node: pt) {
-    if(node.first=="<xmlcomment>") {
-      auto data=static_cast<std::string>(node.second.data());
-      std::transform(data.begin(), data.end(), data.begin(), ::tolower);
-      if(data.find("case insensitive")!=std::string::npos)
-        case_insensitive=true;
-    }
-    else if(node.first=="keyword") {
-      auto data=static_cast<std::string>(node.second.data());
-      completion_buffer->insert_at_cursor(data+'\n');
-      if(case_insensitive) {
-        std::transform(data.begin(), data.end(), data.begin(), ::tolower);
-        completion_buffer->insert_at_cursor(data+'\n');
-      }
-    }
-    else if(!has_context_class && node.first=="context") {
-      auto class_attribute=node.second.get<std::string>("<xmlattr>.class", "");
-      auto class_disabled_attribute=node.second.get<std::string>("<xmlattr>.class-disabled", "");
-      if(class_attribute.size()>0 || class_disabled_attribute.size()>0)
-        has_context_class=true;
-    }
-    try {
-      parse_language_file(completion_buffer, has_context_class, node.second);
-    }
-    catch(const std::exception &e) {        
+void
+Source::GenericView::parse_language_file(Glib::RefPtr<CompletionBuffer> &completion_buffer, bool &has_context_class,
+                                         const boost::property_tree::ptree &pt) {
+    bool case_insensitive = false;
+    for (auto &node: pt) {
+        if (node.first == "<xmlcomment>") {
+            auto data = static_cast<std::string>(node.second.data());
+            std::transform(data.begin(), data.end(), data.begin(), ::tolower);
+            if (data.find("case insensitive") != std::string::npos)
+                case_insensitive = true;
+        } else if (node.first == "keyword") {
+            auto data = static_cast<std::string>(node.second.data());
+            completion_buffer->insert_at_cursor(data + '\n');
+            if (case_insensitive) {
+                std::transform(data.begin(), data.end(), data.begin(), ::tolower);
+                completion_buffer->insert_at_cursor(data + '\n');
+            }
+        } else if (!has_context_class && node.first == "context") {
+            auto class_attribute = node.second.get<std::string>("<xmlattr>.class", "");
+            auto class_disabled_attribute = node.second.get<std::string>("<xmlattr>.class-disabled", "");
+            if (class_attribute.size() > 0 || class_disabled_attribute.size() > 0)
+                has_context_class = true;
+        }
+        try {
+            parse_language_file(completion_buffer, has_context_class, node.second);
+        }
+        catch (const std::exception &e) {
+        }
     }
-  }
 }
diff --git a/src/source.h b/src/source.h
index 10b5153e..48d52d2e 100644
--- a/src/source.h
+++ b/src/source.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include "source_spellcheck.h"
 #include "source_diff.h"
 #include "tooltips.h"
@@ -10,167 +11,213 @@
 #include <tuple>
 
 namespace Source {
-  /// Workaround for buggy Gsv::LanguageManager::get_default()
-  class LanguageManager {
-  public:
-    static Glib::RefPtr<Gsv::LanguageManager> get_default();
-  };
-  /// Workaround for buggy Gsv::StyleSchemeManager::get_default()
-  class StyleSchemeManager {
-  public:
-    static Glib::RefPtr<Gsv::StyleSchemeManager> get_default();
-  };
-  
-  Glib::RefPtr<Gsv::Language> guess_language(const boost::filesystem::path &file_path);
-  
-  class Offset {
-  public:
-    Offset() {}
-    Offset(unsigned line, unsigned index, const boost::filesystem::path &file_path=""): line(line), index(index), file_path(file_path) {}
-    operator bool() { return !file_path.empty(); }
-    bool operator==(const Offset &o) {return (line==o.line && index==o.index);}
-    
-    unsigned line;
-    unsigned index;
-    boost::filesystem::path file_path;
-  };
-  
-  class FixIt {
-  public:
-    enum class Type {INSERT, REPLACE, ERASE};
-    
-    FixIt(const std::string &source, const std::pair<Offset, Offset> &offsets);
-    
-    std::string string(Glib::RefPtr<Gtk::TextBuffer> buffer);
-    
-    Type type;
-    std::string source;
-    std::pair<Offset, Offset> offsets;
-  };
-
-  class View : public SpellCheckView, public DiffView {
-  public:
-    static std::unordered_set<View*> non_deleted_views;
-    static std::unordered_set<View*> views;
-    
-    View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language, bool is_generic_view=false);
-    ~View();
-    
-    bool save() override;
-    
-    void configure() override;
-    
-    void search_highlight(const std::string &text, bool case_sensitive, bool regex);
-    std::function<void(int number)> update_search_occurrences;
-    void search_forward();
-    void search_backward();
-    void replace_forward(const std::string &replacement);
-    void replace_backward(const std::string &replacement);
-    void replace_all(const std::string &replacement);
-    
-    void paste();
-    
-    std::function<void()> non_interactive_completion;
-    std::function<void(bool)> format_style;
-    std::function<Offset()> get_declaration_location;
-    std::function<Offset()> get_type_declaration_location;
-    std::function<std::vector<Offset>()> get_implementation_locations;
-    std::function<std::vector<Offset>()> get_declaration_or_implementation_locations;
-    std::function<std::vector<std::pair<Offset, std::string> >()> get_usages;
-    std::function<std::string()> get_method;
-    std::function<std::vector<std::pair<Offset, std::string> >()> get_methods;
-    std::function<std::vector<std::string>()> get_token_data;
-    std::function<std::string()> get_token_spelling;
-    std::function<void(const std::string &text)> rename_similar_tokens;
-    std::function<void()> goto_next_diagnostic;
-    std::function<std::vector<FixIt>()> get_fix_its;
-    std::function<void()> toggle_comments;
-    std::function<std::tuple<Source::Offset, std::string, size_t>()> get_documentation_template;
-    std::function<void(int)> toggle_breakpoint;
-    
-    void hide_tooltips() override;
-    void hide_dialogs() override;
-    
-    void set_tab_char_and_size(char tab_char, unsigned tab_size);
-    std::pair<char, unsigned> get_tab_char_and_size() {return {tab_char, tab_size};}
-    
-    bool soft_reparse_needed=false;
-    bool full_reparse_needed=false;
-    virtual void soft_reparse(bool delayed=false) {soft_reparse_needed=false;}
-    virtual void full_reparse() {full_reparse_needed=false;}
-  protected:
-    bool parsed=true;
-    Tooltips diagnostic_tooltips;
-    Tooltips type_tooltips;
-    sigc::connection delayed_tooltips_connection;
-    sigc::connection delayed_tag_similar_symbols_connection;
-    virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) { diagnostic_tooltips.show(rectangle); }
-    void add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, std::string spelling, bool error);
-    void clear_diagnostic_tooltips();
-    virtual void show_type_tooltips(const Gdk::Rectangle &rectangle) {}
-    gdouble on_motion_last_x=0.0;
-    gdouble on_motion_last_y=0.0;
-    
-    /// Usually returns at start of line, but not always
-    Gtk::TextIter find_start_of_sentence(Gtk::TextIter iter);
-    bool find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
-    bool find_open_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
-    bool find_close_curly_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
-    long symbol_count(Gtk::TextIter iter, unsigned int positive_char, unsigned int negative_char);
-    bool is_templated_function(Gtk::TextIter iter, Gtk::TextIter &parenthesis_end_iter);
-    
-    std::string get_token(Gtk::TextIter iter);
-    
-    void cleanup_whitespace_characters_on_return(const Gtk::TextIter &iter);
-    
-    bool is_bracket_language=false;
-    bool on_key_press_event(GdkEventKey* key) override;
-    bool on_key_press_event_basic(GdkEventKey* key);
-    bool on_key_press_event_bracket_language(GdkEventKey* key);
-    bool on_key_press_event_smart_brackets(GdkEventKey* key);
-    bool on_key_press_event_smart_inserts(GdkEventKey* key);
-    bool on_button_press_event(GdkEventButton *event) override;
-    bool on_motion_notify_event(GdkEventMotion *motion_event) override;
-    
-    std::pair<char, unsigned> find_tab_char_and_size();
-    unsigned tab_size;
-    char tab_char;
-    std::string tab;
-    
-    bool interactive_completion=true;
-    
-    guint previous_non_modifier_keyval=0;
-  private:
-    void setup_tooltip_and_dialog_events();
-    void setup_format_style(bool is_generic_view);
-    
-    void cleanup_whitespace_characters();
-    Gsv::DrawSpacesFlags parse_show_whitespace_characters(const std::string &text);
-    
-    GtkSourceSearchContext *search_context;
-    GtkSourceSearchSettings *search_settings;
-    static void search_occurrences_updated(GtkWidget* widget, GParamSpec* property, gpointer data);
-    
-    sigc::connection renderer_activate_connection;
-    
-    bool multiple_cursors_signals_set=false;
-    bool multiple_cursors_use=false;
-    std::vector<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, int>> multiple_cursors_extra_cursors;
-    Glib::RefPtr<Gtk::TextBuffer::Mark> multiple_cursors_last_insert;
-    int multiple_cursors_erase_backward_length;
-    int multiple_cursors_erase_forward_length;
-    bool on_key_press_event_multiple_cursors(GdkEventKey* key);
-  };
-  
-  class GenericView : public View {
-  private:
-    class CompletionBuffer : public Gtk::TextBuffer {
+    /// Workaround for buggy Gsv::LanguageManager::get_default()
+    class LanguageManager {
+    public:
+        static Glib::RefPtr<Gsv::LanguageManager> get_default();
+    };
+
+    /// Workaround for buggy Gsv::StyleSchemeManager::get_default()
+    class StyleSchemeManager {
+    public:
+        static Glib::RefPtr<Gsv::StyleSchemeManager> get_default();
+    };
+
+    Glib::RefPtr<Gsv::Language> guess_language(const boost::filesystem::path &file_path);
+
+    class Offset {
+    public:
+        Offset() {}
+
+        Offset(unsigned line, unsigned index, const boost::filesystem::path &file_path = "") : line(line), index(index),
+                                                                                               file_path(file_path) {}
+
+        operator bool() { return !file_path.empty(); }
+
+        bool operator==(const Offset &o) { return (line == o.line && index == o.index); }
+
+        unsigned line;
+        unsigned index;
+        boost::filesystem::path file_path;
+    };
+
+    class FixIt {
+    public:
+        enum class Type {
+            INSERT, REPLACE, ERASE
+        };
+
+        FixIt(const std::string &source, const std::pair<Offset, Offset> &offsets);
+
+        std::string string(Glib::RefPtr<Gtk::TextBuffer> buffer);
+
+        Type type;
+        std::string source;
+        std::pair<Offset, Offset> offsets;
+    };
+
+    class View : public SpellCheckView, public DiffView {
+    public:
+        static std::unordered_set<View *> non_deleted_views;
+        static std::unordered_set<View *> views;
+
+        View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language,
+             bool is_generic_view = false);
+
+        ~View();
+
+        bool save() override;
+
+        void configure() override;
+
+        void search_highlight(const std::string &text, bool case_sensitive, bool regex);
+
+        std::function<void(int number)> update_search_occurrences;
+
+        void search_forward();
+
+        void search_backward();
+
+        void replace_forward(const std::string &replacement);
+
+        void replace_backward(const std::string &replacement);
+
+        void replace_all(const std::string &replacement);
+
+        void paste();
+
+        std::function<void()> non_interactive_completion;
+        std::function<void(bool)> format_style;
+        std::function<Offset()> get_declaration_location;
+        std::function<Offset()> get_type_declaration_location;
+        std::function<std::vector<Offset>()> get_implementation_locations;
+        std::function<std::vector<Offset>()> get_declaration_or_implementation_locations;
+        std::function<std::vector<std::pair<Offset, std::string> >()> get_usages;
+        std::function<std::string()> get_method;
+        std::function<std::vector<std::pair<Offset, std::string> >()> get_methods;
+        std::function<std::vector<std::string>()> get_token_data;
+        std::function<std::string()> get_token_spelling;
+        std::function<void(const std::string &text)> rename_similar_tokens;
+        std::function<void()> goto_next_diagnostic;
+        std::function<std::vector<FixIt>()> get_fix_its;
+        std::function<void()> toggle_comments;
+        std::function<std::tuple<Source::Offset, std::string, size_t>()> get_documentation_template;
+        std::function<void(int)> toggle_breakpoint;
+
+        void hide_tooltips() override;
+
+        void hide_dialogs() override;
+
+        void set_tab_char_and_size(char tab_char, unsigned tab_size);
+
+        std::pair<char, unsigned> get_tab_char_and_size() { return {tab_char, tab_size}; }
+
+        bool soft_reparse_needed = false;
+        bool full_reparse_needed = false;
+
+        virtual void soft_reparse(bool delayed = false) { soft_reparse_needed = false; }
+
+        virtual void full_reparse() { full_reparse_needed = false; }
+
+    protected:
+        bool parsed = true;
+        Tooltips diagnostic_tooltips;
+        Tooltips type_tooltips;
+        sigc::connection delayed_tooltips_connection;
+
+        virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) { diagnostic_tooltips.show(rectangle); }
+
+        void
+        add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, std::string spelling, bool error);
+
+        void clear_diagnostic_tooltips();
+
+        virtual void show_type_tooltips(const Gdk::Rectangle &rectangle) {}
+
+        gdouble on_motion_last_x = 0.0;
+        gdouble on_motion_last_y = 0.0;
+
+        /// Usually returns at start of line, but not always
+        Gtk::TextIter find_start_of_sentence(Gtk::TextIter iter);
+
+        bool find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
+
+        bool find_open_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
+
+        bool find_close_curly_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
+
+        long symbol_count(Gtk::TextIter iter, unsigned int positive_char, unsigned int negative_char);
+
+        bool is_templated_function(Gtk::TextIter iter, Gtk::TextIter &parenthesis_end_iter);
+
+        std::string get_token(Gtk::TextIter iter);
+
+        void cleanup_whitespace_characters_on_return(const Gtk::TextIter &iter);
+
+        bool is_bracket_language = false;
+
+        bool on_key_press_event(GdkEventKey *key) override;
+
+        bool on_key_press_event_basic(GdkEventKey *key);
+
+        bool on_key_press_event_bracket_language(GdkEventKey *key);
+
+        bool on_key_press_event_smart_brackets(GdkEventKey *key);
+
+        bool on_key_press_event_smart_inserts(GdkEventKey *key);
+
+        bool on_button_press_event(GdkEventButton *event) override;
+
+        bool on_motion_notify_event(GdkEventMotion *motion_event) override;
+
+        std::pair<char, unsigned> find_tab_char_and_size();
+
+        unsigned tab_size;
+        char tab_char;
+        std::string tab;
+
+        bool interactive_completion = true;
+
+        guint previous_non_modifier_keyval = 0;
+    private:
+        void setup_tooltip_and_dialog_events();
+
+        void setup_format_style(bool is_generic_view);
+
+        void cleanup_whitespace_characters();
+
+        Gsv::DrawSpacesFlags parse_show_whitespace_characters(const std::string &text);
+
+        GtkSourceSearchContext *search_context;
+        GtkSourceSearchSettings *search_settings;
+
+        static void search_occurrences_updated(GtkWidget *widget, GParamSpec *property, gpointer data);
+
+        sigc::connection renderer_activate_connection;
+
+        bool multiple_cursors_signals_set = false;
+        bool multiple_cursors_use = false;
+        std::vector<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, int>> multiple_cursors_extra_cursors;
+        Glib::RefPtr<Gtk::TextBuffer::Mark> multiple_cursors_last_insert;
+        int multiple_cursors_erase_backward_length;
+        int multiple_cursors_erase_forward_length;
+
+        bool on_key_press_event_multiple_cursors(GdkEventKey *key);
+    };
+
+    class GenericView : public View {
+    private:
+        class CompletionBuffer : public Gtk::TextBuffer {
+        public:
+            static Glib::RefPtr<CompletionBuffer> create() {
+                return Glib::RefPtr<CompletionBuffer>(new CompletionBuffer());
+            }
+        };
+
     public:
-      static Glib::RefPtr<CompletionBuffer> create() {return Glib::RefPtr<CompletionBuffer>(new CompletionBuffer());}
+        GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+
+        void parse_language_file(Glib::RefPtr<CompletionBuffer> &completion_buffer, bool &has_context_class,
+                                 const boost::property_tree::ptree &pt);
     };
-  public:
-    GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
-    
-    void parse_language_file(Glib::RefPtr<CompletionBuffer> &completion_buffer, bool &has_context_class, const boost::property_tree::ptree &pt);
-  };
 }
diff --git a/src/source_base.cc b/src/source_base.cc
index 8a6813bd..20778a5b 100644
--- a/src/source_base.cc
+++ b/src/source_base.cc
@@ -5,389 +5,401 @@
 #include "config.h"
 #include <fstream>
 
-Source::BaseView::BaseView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language): Gsv::View(), file_path(file_path), language(language), status_diagnostics(0, 0, 0) {
-  load(true);
-  get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0)); 
-  
-  signal_focus_in_event().connect([this](GdkEventFocus *event) {
-    if(this->last_write_time!=static_cast<std::time_t>(-1))
-      check_last_write_time();
-    return false;
-  });
-  
-  monitor_file();
+Source::BaseView::BaseView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language)
+        : Gsv::View(), file_path(file_path), language(language), status_diagnostics(0, 0, 0) {
+    load(true);
+    get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0));
+
+    signal_focus_in_event().connect([this](GdkEventFocus *event) {
+        if (this->last_write_time != static_cast<std::time_t>(-1))
+            check_last_write_time();
+        return false;
+    });
+
+    monitor_file();
 }
 
 Source::BaseView::~BaseView() {
-  monitor_changed_connection.disconnect();
-  delayed_monitor_changed_connection.disconnect();
+    monitor_changed_connection.disconnect();
+    delayed_monitor_changed_connection.disconnect();
 }
 
 bool Source::BaseView::load(bool not_undoable_action) {
-  boost::system::error_code ec;
-  last_write_time=boost::filesystem::last_write_time(file_path, ec);
-  if(ec)
-    last_write_time=static_cast<std::time_t>(-1);
-  
-  disable_spellcheck=true;
-  if(not_undoable_action)
-    get_source_buffer()->begin_not_undoable_action();
-  
-  class Guard {
-  public:
-    Source::BaseView *view;
-    bool not_undoable_action;
-    ~Guard() {
-      if(not_undoable_action)
-        view->get_source_buffer()->end_not_undoable_action();
-      view->disable_spellcheck=false;
-    }
-  };
-  Guard guard{this, not_undoable_action};
-  
-  if(language) {
-    std::ifstream input(file_path.string(), std::ofstream::binary);
-    if(input) {
-      std::stringstream ss;
-      ss << input.rdbuf();
-      Glib::ustring ustr=ss.str();
-      
-      bool valid=true;
-      Glib::ustring::iterator iter;
-      while(!ustr.validate(iter)) {
-        auto next_char_iter=iter;
-        next_char_iter++;
-        ustr.replace(iter, next_char_iter, "?");
-        valid=false;
-      }
-      
-      if(!valid)
-        Terminal::get().print("Warning: "+file_path.string()+" is not a valid UTF-8 file. Saving might corrupt the file.\n");
-      
-      if(get_buffer()->size()==0)
-        get_buffer()->insert_at_cursor(ustr);
-      else
-        replace_text(ustr.raw());
-    }
-    else
-      return false;
-  }
-  else {
-    std::ifstream input(file_path.string(), std::ofstream::binary);
-    if(input) {
-      std::stringstream ss;
-      ss << input.rdbuf();
-      Glib::ustring ustr=ss.str();
-      
-      if(ustr.validate()) {
-        if(get_buffer()->size()==0)
-          get_buffer()->insert_at_cursor(ustr);
-        else
-          replace_text(ustr.raw());
-      }
-      else {
-        Terminal::get().print("Error: "+file_path.string()+" is not a valid UTF-8 file.\n", true);
-        return false;
-      }
+    boost::system::error_code ec;
+    last_write_time = boost::filesystem::last_write_time(file_path, ec);
+    if (ec)
+        last_write_time = static_cast<std::time_t>(-1);
+
+    disable_spellcheck = true;
+    if (not_undoable_action)
+        get_source_buffer()->begin_not_undoable_action();
+
+    class Guard {
+    public:
+        Source::BaseView *view;
+        bool not_undoable_action;
+
+        ~Guard() {
+            if (not_undoable_action)
+                view->get_source_buffer()->end_not_undoable_action();
+            view->disable_spellcheck = false;
+        }
+    };
+    Guard guard{this, not_undoable_action};
+
+    if (language) {
+        std::ifstream input(file_path.string(), std::ofstream::binary);
+        if (input) {
+            std::stringstream ss;
+            ss << input.rdbuf();
+            Glib::ustring ustr = ss.str();
+
+            bool valid = true;
+            Glib::ustring::iterator iter;
+            while (!ustr.validate(iter)) {
+                auto next_char_iter = iter;
+                next_char_iter++;
+                ustr.replace(iter, next_char_iter, "?");
+                valid = false;
+            }
+
+            if (!valid)
+                Terminal::get().print("Warning: " + file_path.string() +
+                                      " is not a valid UTF-8 file. Saving might corrupt the file.\n");
+
+            if (get_buffer()->size() == 0)
+                get_buffer()->insert_at_cursor(ustr);
+            else
+                replace_text(ustr.raw());
+        } else
+            return false;
+    } else {
+        std::ifstream input(file_path.string(), std::ofstream::binary);
+        if (input) {
+            std::stringstream ss;
+            ss << input.rdbuf();
+            Glib::ustring ustr = ss.str();
+
+            if (ustr.validate()) {
+                if (get_buffer()->size() == 0)
+                    get_buffer()->insert_at_cursor(ustr);
+                else
+                    replace_text(ustr.raw());
+            } else {
+                Terminal::get().print("Error: " + file_path.string() + " is not a valid UTF-8 file.\n", true);
+                return false;
+            }
+        } else
+            return false;
     }
-    else
-      return false;
-  }
-  
-  get_buffer()->set_modified(false);
-  return true;
+
+    get_buffer()->set_modified(false);
+    return true;
 }
 
 void Source::BaseView::replace_text(const std::string &new_text) {
-  get_buffer()->begin_user_action();
-  
-  if(get_buffer()->size()==0) {
-    get_buffer()->insert_at_cursor(new_text);
-    get_buffer()->end_user_action();
-    return;
-  }
-  else if(new_text.empty()) {
-    get_buffer()->set_text(new_text);
-    get_buffer()->end_user_action();
-    return;
-  }
-  
-  auto iter=get_buffer()->get_insert()->get_iter();
-  int cursor_line_nr=iter.get_line();
-  int cursor_line_offset=iter.ends_line() ? std::numeric_limits<int>::max() : iter.get_line_offset();
-  
-  std::vector<std::pair<const char*, const char*>> new_lines;
-  
-  const char* line_start=new_text.c_str();
-  for(size_t i=0;i<new_text.size();++i) {
-    if(new_text[i]=='\n') {
-      new_lines.emplace_back(line_start, &new_text[i]+1);
-      line_start = &new_text[i]+1;
+    get_buffer()->begin_user_action();
+
+    if (get_buffer()->size() == 0) {
+        get_buffer()->insert_at_cursor(new_text);
+        get_buffer()->end_user_action();
+        return;
+    } else if (new_text.empty()) {
+        get_buffer()->set_text(new_text);
+        get_buffer()->end_user_action();
+        return;
     }
-  }
-  if(new_text.empty() || new_text.back()!='\n')
-    new_lines.emplace_back(line_start, &new_text[new_text.size()]);
-  
-  try {
-    auto hunks = Git::Repository::Diff::get_hunks(get_buffer()->get_text().raw(), new_text);
-    
-    for(auto it=hunks.rbegin();it!=hunks.rend();++it) {
-      bool place_cursor=false;
-      Gtk::TextIter start;
-      if(it->old_lines.second!=0) {
-        start=get_buffer()->get_iter_at_line(it->old_lines.first-1);
-        auto end=get_buffer()->get_iter_at_line(it->old_lines.first-1+it->old_lines.second);
-        
-        if(cursor_line_nr>=start.get_line() && cursor_line_nr<end.get_line()) {
-          if(it->new_lines.second!=0) {
-            place_cursor = true;
-            int line_diff=cursor_line_nr-start.get_line();
-            cursor_line_nr+=static_cast<int>(0.5+(static_cast<float>(line_diff)/it->old_lines.second)*it->new_lines.second)-line_diff;
-          }
+
+    auto iter = get_buffer()->get_insert()->get_iter();
+    int cursor_line_nr = iter.get_line();
+    int cursor_line_offset = iter.ends_line() ? std::numeric_limits<int>::max() : iter.get_line_offset();
+
+    std::vector<std::pair<const char *, const char *>> new_lines;
+
+    const char *line_start = new_text.c_str();
+    for (size_t i = 0; i < new_text.size(); ++i) {
+        if (new_text[i] == '\n') {
+            new_lines.emplace_back(line_start, &new_text[i] + 1);
+            line_start = &new_text[i] + 1;
         }
-        
-        get_buffer()->erase(start, end);
-        start=get_buffer()->get_iter_at_line(it->old_lines.first-1);
-      }
-      else
-        start=get_buffer()->get_iter_at_line(it->old_lines.first);
-      if(it->new_lines.second!=0) {
-        get_buffer()->insert(start, new_lines[it->new_lines.first-1].first, new_lines[it->new_lines.first-1+it->new_lines.second-1].second);
-        if(place_cursor)
-          place_cursor_at_line_offset(cursor_line_nr, cursor_line_offset);
-      }
     }
-  }
-  catch(...) {
-    Terminal::get().print("Error: Could not replace text in buffer\n", true);
-  }
-  
-  get_buffer()->end_user_action();
+    if (new_text.empty() || new_text.back() != '\n')
+        new_lines.emplace_back(line_start, &new_text[new_text.size()]);
+
+    try {
+        auto hunks = Git::Repository::Diff::get_hunks(get_buffer()->get_text().raw(), new_text);
+
+        for (auto it = hunks.rbegin(); it != hunks.rend(); ++it) {
+            bool place_cursor = false;
+            Gtk::TextIter start;
+            if (it->old_lines.second != 0) {
+                start = get_buffer()->get_iter_at_line(it->old_lines.first - 1);
+                auto end = get_buffer()->get_iter_at_line(it->old_lines.first - 1 + it->old_lines.second);
+
+                if (cursor_line_nr >= start.get_line() && cursor_line_nr < end.get_line()) {
+                    if (it->new_lines.second != 0) {
+                        place_cursor = true;
+                        int line_diff = cursor_line_nr - start.get_line();
+                        cursor_line_nr += static_cast<int>(0.5 +
+                                                           (static_cast<float>(line_diff) / it->old_lines.second) *
+                                                           it->new_lines.second) - line_diff;
+                    }
+                }
+
+                get_buffer()->erase(start, end);
+                start = get_buffer()->get_iter_at_line(it->old_lines.first - 1);
+            } else
+                start = get_buffer()->get_iter_at_line(it->old_lines.first);
+            if (it->new_lines.second != 0) {
+                get_buffer()->insert(start, new_lines[it->new_lines.first - 1].first,
+                                     new_lines[it->new_lines.first - 1 + it->new_lines.second - 1].second);
+                if (place_cursor)
+                    place_cursor_at_line_offset(cursor_line_nr, cursor_line_offset);
+            }
+        }
+    }
+    catch (...) {
+        Terminal::get().print("Error: Could not replace text in buffer\n", true);
+    }
+
+    get_buffer()->end_user_action();
 }
 
 void Source::BaseView::rename(const boost::filesystem::path &path) {
-  file_path=path;
-  
-  if(update_status_file_path)
-    update_status_file_path(this);
-  if(update_tab_label)
-    update_tab_label(this);
+    file_path = path;
+
+    if (update_status_file_path)
+        update_status_file_path(this);
+    if (update_tab_label)
+        update_tab_label(this);
 }
 
 void Source::BaseView::monitor_file() {
 #ifdef __APPLE__ // TODO: Gio file monitor is bugged on MacOS
-  class Recursive {
-  public:
-    static void f(BaseView *view, std::time_t last_write_time_) {
-      view->delayed_monitor_changed_connection.disconnect();
-      view->delayed_monitor_changed_connection=Glib::signal_timeout().connect([view, last_write_time_]() {
-        boost::system::error_code ec;
-        auto last_write_time=boost::filesystem::last_write_time(view->file_path, ec);
-        if(last_write_time!=last_write_time_)
-          view->check_last_write_time(last_write_time);
-        Recursive::f(view, last_write_time);
-        return false;
-      }, 1000);
-    }
-  };
-  delayed_monitor_changed_connection.disconnect();
-  if(this->last_write_time!=static_cast<std::time_t>(-1))
-    Recursive::f(this, last_write_time);
-#else
-  if(this->last_write_time!=static_cast<std::time_t>(-1)) {
-    monitor=Gio::File::create_for_path(file_path.string())->monitor_file(Gio::FileMonitorFlags::FILE_MONITOR_NONE);
-    monitor_changed_connection.disconnect();
-    monitor_changed_connection=monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
-                                                                        const Glib::RefPtr<Gio::File>&,
-                                                                        Gio::FileMonitorEvent monitor_event) {
-      if(monitor_event!=Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-        delayed_monitor_changed_connection.disconnect();
-        delayed_monitor_changed_connection=Glib::signal_timeout().connect([this]() {
-          check_last_write_time();
+    class Recursive {
+    public:
+      static void f(BaseView *view, std::time_t last_write_time_) {
+        view->delayed_monitor_changed_connection.disconnect();
+        view->delayed_monitor_changed_connection=Glib::signal_timeout().connect([view, last_write_time_]() {
+          boost::system::error_code ec;
+          auto last_write_time=boost::filesystem::last_write_time(view->file_path, ec);
+          if(last_write_time!=last_write_time_)
+            view->check_last_write_time(last_write_time);
+          Recursive::f(view, last_write_time);
           return false;
-        }, 500);
+        }, 1000);
       }
-    });
-  }
+    };
+    delayed_monitor_changed_connection.disconnect();
+    if(this->last_write_time!=static_cast<std::time_t>(-1))
+      Recursive::f(this, last_write_time);
+#else
+    if (this->last_write_time != static_cast<std::time_t>(-1)) {
+        monitor = Gio::File::create_for_path(file_path.string())->monitor_file(
+                Gio::FileMonitorFlags::FILE_MONITOR_NONE);
+        monitor_changed_connection.disconnect();
+        monitor_changed_connection = monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
+                                                                              const Glib::RefPtr<Gio::File> &,
+                                                                              Gio::FileMonitorEvent monitor_event) {
+            if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+                delayed_monitor_changed_connection.disconnect();
+                delayed_monitor_changed_connection = Glib::signal_timeout().connect([this]() {
+                    check_last_write_time();
+                    return false;
+                }, 500);
+            }
+        });
+    }
 #endif
 }
 
 void Source::BaseView::check_last_write_time(std::time_t last_write_time_) {
-  if(this->last_write_time==static_cast<std::time_t>(-1))
-    return;
-  
-  if(Config::get().source.auto_reload_changed_files && !get_buffer()->get_modified()) {
-    boost::system::error_code ec;
-    auto last_write_time=last_write_time_!=static_cast<std::time_t>(-1) ? last_write_time_ : boost::filesystem::last_write_time(file_path, ec);
-    if(!ec && last_write_time!=this->last_write_time) {
-      if(load())
+    if (this->last_write_time == static_cast<std::time_t>(-1))
         return;
+
+    if (Config::get().source.auto_reload_changed_files && !get_buffer()->get_modified()) {
+        boost::system::error_code ec;
+        auto last_write_time = last_write_time_ != static_cast<std::time_t>(-1) ? last_write_time_
+                                                                                : boost::filesystem::last_write_time(
+                        file_path, ec);
+        if (!ec && last_write_time != this->last_write_time) {
+            if (load())
+                return;
+        }
+    } else if (has_focus()) {
+        boost::system::error_code ec;
+        auto last_write_time = last_write_time_ != static_cast<std::time_t>(-1) ? last_write_time_
+                                                                                : boost::filesystem::last_write_time(
+                        file_path, ec);
+        if (!ec && last_write_time != this->last_write_time)
+            Info::get().print("Caution: " + file_path.filename().string() + " was changed outside of juCi++");
     }
-  }
-  else if(has_focus()) {
-    boost::system::error_code ec;
-    auto last_write_time=last_write_time_!=static_cast<std::time_t>(-1) ? last_write_time_ : boost::filesystem::last_write_time(file_path, ec);
-    if(!ec && last_write_time!=this->last_write_time)
-      Info::get().print("Caution: " + file_path.filename().string() + " was changed outside of juCi++");
-  }
 }
 
 Gtk::TextIter Source::BaseView::get_iter_at_line_pos(int line, int pos) {
-  return get_iter_at_line_index(line, pos);
+    return get_iter_at_line_index(line, pos);
 }
 
 Gtk::TextIter Source::BaseView::get_iter_at_line_offset(int line, int offset) {
-  line=std::min(line, get_buffer()->get_line_count()-1);
-  if(line<0)
-    line=0;
-  auto iter=get_iter_at_line_end(line);
-  offset=std::min(offset, iter.get_line_offset());
-  if(offset<0)
-    offset=0;
-  return get_buffer()->get_iter_at_line_offset(line, offset);
+    line = std::min(line, get_buffer()->get_line_count() - 1);
+    if (line < 0)
+        line = 0;
+    auto iter = get_iter_at_line_end(line);
+    offset = std::min(offset, iter.get_line_offset());
+    if (offset < 0)
+        offset = 0;
+    return get_buffer()->get_iter_at_line_offset(line, offset);
 }
 
 Gtk::TextIter Source::BaseView::get_iter_at_line_index(int line, int index) {
-  line=std::min(line, get_buffer()->get_line_count()-1);
-  if(line<0)
-    line=0;
-  auto iter=get_iter_at_line_end(line);
-  index=std::min(index, iter.get_line_index());
-  if(index<0)
-    index=0;
-  return get_buffer()->get_iter_at_line_index(line, index);
+    line = std::min(line, get_buffer()->get_line_count() - 1);
+    if (line < 0)
+        line = 0;
+    auto iter = get_iter_at_line_end(line);
+    index = std::min(index, iter.get_line_index());
+    if (index < 0)
+        index = 0;
+    return get_buffer()->get_iter_at_line_index(line, index);
 }
 
 Gtk::TextIter Source::BaseView::get_iter_at_line_end(int line_nr) {
-  if(line_nr>=get_buffer()->get_line_count())
-    return get_buffer()->end();
-  else if(line_nr+1<get_buffer()->get_line_count()) {
-    auto iter=get_buffer()->get_iter_at_line(line_nr+1);
-    iter.backward_char();
-    if(!iter.ends_line()) // for CR+LF
-      iter.backward_char();
-    return iter;
-  }
-  else {
-    auto iter=get_buffer()->get_iter_at_line(line_nr);
-    while(!iter.ends_line() && iter.forward_char()) {}
-    return iter;
-  }
+    if (line_nr >= get_buffer()->get_line_count())
+        return get_buffer()->end();
+    else if (line_nr + 1 < get_buffer()->get_line_count()) {
+        auto iter = get_buffer()->get_iter_at_line(line_nr + 1);
+        iter.backward_char();
+        if (!iter.ends_line()) // for CR+LF
+            iter.backward_char();
+        return iter;
+    } else {
+        auto iter = get_buffer()->get_iter_at_line(line_nr);
+        while (!iter.ends_line() && iter.forward_char()) {}
+        return iter;
+    }
 }
 
 Gtk::TextIter Source::BaseView::get_iter_for_dialog() {
-  auto iter=get_buffer()->get_insert()->get_iter();
-  Gdk::Rectangle visible_rect;
-  get_visible_rect(visible_rect);
-  Gdk::Rectangle iter_rect;
-  get_iter_location(iter, iter_rect);
-  iter_rect.set_width(1);
-  if(iter.get_line_offset()>=80) {
-    get_iter_at_location(iter, visible_rect.get_x(), iter_rect.get_y());
+    auto iter = get_buffer()->get_insert()->get_iter();
+    Gdk::Rectangle visible_rect;
+    get_visible_rect(visible_rect);
+    Gdk::Rectangle iter_rect;
     get_iter_location(iter, iter_rect);
-  }
-  if(!visible_rect.intersects(iter_rect))
-    get_iter_at_location(iter, visible_rect.get_x(), visible_rect.get_y()+visible_rect.get_height()/3);
-  return iter;
+    iter_rect.set_width(1);
+    if (iter.get_line_offset() >= 80) {
+        get_iter_at_location(iter, visible_rect.get_x(), iter_rect.get_y());
+        get_iter_location(iter, iter_rect);
+    }
+    if (!visible_rect.intersects(iter_rect))
+        get_iter_at_location(iter, visible_rect.get_x(), visible_rect.get_y() + visible_rect.get_height() / 3);
+    return iter;
 }
 
 void Source::BaseView::place_cursor_at_line_pos(int line, int pos) {
-  get_buffer()->place_cursor(get_iter_at_line_pos(line, pos));
+    get_buffer()->place_cursor(get_iter_at_line_pos(line, pos));
 }
 
 void Source::BaseView::place_cursor_at_line_offset(int line, int offset) {
-  get_buffer()->place_cursor(get_iter_at_line_offset(line, offset));
+    get_buffer()->place_cursor(get_iter_at_line_offset(line, offset));
 }
 
 void Source::BaseView::place_cursor_at_line_index(int line, int index) {
-  get_buffer()->place_cursor(get_iter_at_line_index(line, index));
+    get_buffer()->place_cursor(get_iter_at_line_index(line, index));
 }
 
 Gtk::TextIter Source::BaseView::get_smart_home_iter(const Gtk::TextIter &iter) {
-  auto start_line_iter=get_buffer()->get_iter_at_line(iter.get_line());
-  auto start_sentence_iter=start_line_iter;
-  while(!start_sentence_iter.ends_line() && 
-        (*start_sentence_iter==' ' || *start_sentence_iter=='\t') &&
-        start_sentence_iter.forward_char()) {}
-  
-  if(iter>start_sentence_iter || iter==start_line_iter)
-    return start_sentence_iter;
-  else
-    return start_line_iter;
+    auto start_line_iter = get_buffer()->get_iter_at_line(iter.get_line());
+    auto start_sentence_iter = start_line_iter;
+    while (!start_sentence_iter.ends_line() &&
+           (*start_sentence_iter == ' ' || *start_sentence_iter == '\t') &&
+           start_sentence_iter.forward_char()) {}
+
+    if (iter > start_sentence_iter || iter == start_line_iter)
+        return start_sentence_iter;
+    else
+        return start_line_iter;
 }
 
 Gtk::TextIter Source::BaseView::get_smart_end_iter(const Gtk::TextIter &iter) {
-  auto end_line_iter=get_iter_at_line_end(iter.get_line());
-  auto end_sentence_iter=end_line_iter;
-  while(!end_sentence_iter.starts_line() && 
-        (*end_sentence_iter==' ' || *end_sentence_iter=='\t' || end_sentence_iter.ends_line()) &&
-        end_sentence_iter.backward_char()) {}
-  if(!end_sentence_iter.ends_line() && *end_sentence_iter!=' ' && *end_sentence_iter!='\t')
-    end_sentence_iter.forward_char();
-  
-  if(iter==end_line_iter)
-    return end_sentence_iter;
-  else
-    return end_line_iter;
+    auto end_line_iter = get_iter_at_line_end(iter.get_line());
+    auto end_sentence_iter = end_line_iter;
+    while (!end_sentence_iter.starts_line() &&
+           (*end_sentence_iter == ' ' || *end_sentence_iter == '\t' || end_sentence_iter.ends_line()) &&
+           end_sentence_iter.backward_char()) {}
+    if (!end_sentence_iter.ends_line() && *end_sentence_iter != ' ' && *end_sentence_iter != '\t')
+        end_sentence_iter.forward_char();
+
+    if (iter == end_line_iter)
+        return end_sentence_iter;
+    else
+        return end_line_iter;
 }
 
 std::string Source::BaseView::get_line(const Gtk::TextIter &iter) {
-  auto line_start_it = get_buffer()->get_iter_at_line(iter.get_line());
-  auto line_end_it = get_iter_at_line_end(iter.get_line());
-  std::string line(get_buffer()->get_text(line_start_it, line_end_it));
-  return line;
+    auto line_start_it = get_buffer()->get_iter_at_line(iter.get_line());
+    auto line_end_it = get_iter_at_line_end(iter.get_line());
+    std::string line(get_buffer()->get_text(line_start_it, line_end_it));
+    return line;
 }
+
 std::string Source::BaseView::get_line(Glib::RefPtr<Gtk::TextBuffer::Mark> mark) {
-  return get_line(mark->get_iter());
+    return get_line(mark->get_iter());
 }
+
 std::string Source::BaseView::get_line(int line_nr) {
-  return get_line(get_buffer()->get_iter_at_line(line_nr));
+    return get_line(get_buffer()->get_iter_at_line(line_nr));
 }
+
 std::string Source::BaseView::get_line() {
-  return get_line(get_buffer()->get_insert());
+    return get_line(get_buffer()->get_insert());
 }
 
 std::string Source::BaseView::get_line_before(const Gtk::TextIter &iter) {
-  auto line_it = get_buffer()->get_iter_at_line(iter.get_line());
-  std::string line(get_buffer()->get_text(line_it, iter));
-  return line;
+    auto line_it = get_buffer()->get_iter_at_line(iter.get_line());
+    std::string line(get_buffer()->get_text(line_it, iter));
+    return line;
 }
+
 std::string Source::BaseView::get_line_before(Glib::RefPtr<Gtk::TextBuffer::Mark> mark) {
-  return get_line_before(mark->get_iter());
+    return get_line_before(mark->get_iter());
 }
+
 std::string Source::BaseView::get_line_before() {
-  return get_line_before(get_buffer()->get_insert());
+    return get_line_before(get_buffer()->get_insert());
 }
 
 Gtk::TextIter Source::BaseView::get_tabs_end_iter(const Gtk::TextIter &iter) {
-  return get_tabs_end_iter(iter.get_line());
+    return get_tabs_end_iter(iter.get_line());
 }
+
 Gtk::TextIter Source::BaseView::get_tabs_end_iter(Glib::RefPtr<Gtk::TextBuffer::Mark> mark) {
-  return get_tabs_end_iter(mark->get_iter());
+    return get_tabs_end_iter(mark->get_iter());
 }
+
 Gtk::TextIter Source::BaseView::get_tabs_end_iter(int line_nr) {
-  auto sentence_iter = get_buffer()->get_iter_at_line(line_nr);
-  while((*sentence_iter==' ' || *sentence_iter=='\t') && !sentence_iter.ends_line() && sentence_iter.forward_char()) {}
-  return sentence_iter;
+    auto sentence_iter = get_buffer()->get_iter_at_line(line_nr);
+    while ((*sentence_iter == ' ' || *sentence_iter == '\t') && !sentence_iter.ends_line() &&
+           sentence_iter.forward_char()) {}
+    return sentence_iter;
 }
+
 Gtk::TextIter Source::BaseView::get_tabs_end_iter() {
-  return get_tabs_end_iter(get_buffer()->get_insert());
+    return get_tabs_end_iter(get_buffer()->get_insert());
 }
 
 void Source::BaseView::place_cursor_at_next_diagnostic() {
-  auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset();
-  for(auto offset: diagnostic_offsets) {
-    if(offset>insert_offset) {
-      get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset));
-      scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-      return;
+    auto insert_offset = get_buffer()->get_insert()->get_iter().get_offset();
+    for (auto offset: diagnostic_offsets) {
+        if (offset > insert_offset) {
+            get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset));
+            scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+            return;
+        }
+    }
+    if (diagnostic_offsets.size() == 0)
+        Info::get().print("No diagnostics found in current buffer");
+    else {
+        auto iter = get_buffer()->get_iter_at_offset(*diagnostic_offsets.begin());
+        get_buffer()->place_cursor(iter);
+        scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
     }
-  }
-  if(diagnostic_offsets.size()==0)
-    Info::get().print("No diagnostics found in current buffer");
-  else {
-    auto iter=get_buffer()->get_iter_at_offset(*diagnostic_offsets.begin());
-    get_buffer()->place_cursor(iter);
-    scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-  }
 }
diff --git a/src/source_base.h b/src/source_base.h
index 0ded18af..34d4ca90 100644
--- a/src/source_base.h
+++ b/src/source_base.h
@@ -6,85 +6,113 @@
 #include <boost/filesystem.hpp>
 
 namespace Source {
-  class BaseView : public Gsv::View {
-  public:
-    BaseView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
-    ~BaseView();
-    boost::filesystem::path file_path;
-    
-    Glib::RefPtr<Gsv::Language> language;
-    
-    bool load(bool not_undoable_action=false);
-    /// Set new text more optimally and without unnecessary scrolling
-    void replace_text(const std::string &new_text);
-    virtual void rename(const boost::filesystem::path &path);
-    virtual bool save() = 0;
-    
-    Glib::RefPtr<Gio::FileMonitor> monitor;
-    sigc::connection monitor_changed_connection;
-    sigc::connection delayed_monitor_changed_connection;
-    
-    virtual void configure() = 0;
-    virtual void hide_tooltips() = 0;
-    virtual void hide_dialogs() = 0;
-    
-    std::function<void(BaseView* view, bool center, bool show_tooltips)> scroll_to_cursor_delayed=[](BaseView* view, bool center, bool show_tooltips) {};
-    
-    /// Safely returns iter given line and an offset using either byte index or character offset. Defaults to using byte index.
-    virtual Gtk::TextIter get_iter_at_line_pos(int line, int pos);
-    /// Safely returns iter given line and character offset
-    Gtk::TextIter get_iter_at_line_offset(int line, int offset);
-    /// Safely returns iter given line and byte index
-    Gtk::TextIter get_iter_at_line_index(int line, int index);
-    
-    Gtk::TextIter get_iter_at_line_end(int line_nr);
-    Gtk::TextIter get_iter_for_dialog();
-    
-    /// Safely places cursor at line using get_iter_at_line_pos.
-    void place_cursor_at_line_pos(int line, int pos);
-    /// Safely places cursor at line offset
-    void place_cursor_at_line_offset(int line, int offset);
-    /// Safely places cursor at line index
-    void place_cursor_at_line_index(int line, int index);
-    
-  protected:
-    std::time_t last_write_time;
-    void monitor_file();
-    void check_last_write_time(std::time_t last_write_time_=static_cast<std::time_t>(-1));
-    
-    /// Move iter to line start. Depending on iter position, before or after indentation.
-    /// Works with wrapped lines. 
-    Gtk::TextIter get_smart_home_iter(const Gtk::TextIter &iter);
-    /// Move iter to line end. Depending on iter position, before or after indentation.
-    /// Works with wrapped lines. 
-    /// Note that smart end goes FIRST to end of line to avoid hiding empty chars after expressions.
-    Gtk::TextIter get_smart_end_iter(const Gtk::TextIter &iter);
-    
-    std::string get_line(const Gtk::TextIter &iter);
-    std::string get_line(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
-    std::string get_line(int line_nr);
-    std::string get_line();
-    std::string get_line_before(const Gtk::TextIter &iter);
-    std::string get_line_before(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
-    std::string get_line_before();
-    Gtk::TextIter get_tabs_end_iter(const Gtk::TextIter &iter);
-    Gtk::TextIter get_tabs_end_iter(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
-    Gtk::TextIter get_tabs_end_iter(int line_nr);
-    Gtk::TextIter get_tabs_end_iter();
-    
-    std::set<int> diagnostic_offsets;
-    void place_cursor_at_next_diagnostic();
-  public:
-    std::function<void(BaseView *view)> update_tab_label;
-    std::function<void(BaseView *view)> update_status_location;
-    std::function<void(BaseView *view)> update_status_file_path;
-    std::function<void(BaseView *view)> update_status_diagnostics;
-    std::function<void(BaseView *view)> update_status_state;
-    std::tuple<size_t, size_t, size_t> status_diagnostics;
-    std::string status_state;
-    std::function<void(BaseView *view)> update_status_branch;
-    std::string status_branch;
-    
-    bool disable_spellcheck=false;
-  };
+    class BaseView : public Gsv::View {
+    public:
+        BaseView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+
+        ~BaseView();
+
+        boost::filesystem::path file_path;
+
+        Glib::RefPtr<Gsv::Language> language;
+
+        bool load(bool not_undoable_action = false);
+
+        /// Set new text more optimally and without unnecessary scrolling
+        void replace_text(const std::string &new_text);
+
+        virtual void rename(const boost::filesystem::path &path);
+
+        virtual bool save() = 0;
+
+        Glib::RefPtr<Gio::FileMonitor> monitor;
+        sigc::connection monitor_changed_connection;
+        sigc::connection delayed_monitor_changed_connection;
+
+        virtual void configure() = 0;
+
+        virtual void hide_tooltips() = 0;
+
+        virtual void hide_dialogs() = 0;
+
+        std::function<void(BaseView *view, bool center, bool show_tooltips)> scroll_to_cursor_delayed = [](
+                BaseView *view, bool center, bool show_tooltips) {};
+
+        /// Safely returns iter given line and an offset using either byte index or character offset. Defaults to using byte index.
+        virtual Gtk::TextIter get_iter_at_line_pos(int line, int pos);
+
+        /// Safely returns iter given line and character offset
+        Gtk::TextIter get_iter_at_line_offset(int line, int offset);
+
+        /// Safely returns iter given line and byte index
+        Gtk::TextIter get_iter_at_line_index(int line, int index);
+
+        Gtk::TextIter get_iter_at_line_end(int line_nr);
+
+        Gtk::TextIter get_iter_for_dialog();
+
+        /// Safely places cursor at line using get_iter_at_line_pos.
+        void place_cursor_at_line_pos(int line, int pos);
+
+        /// Safely places cursor at line offset
+        void place_cursor_at_line_offset(int line, int offset);
+
+        /// Safely places cursor at line index
+        void place_cursor_at_line_index(int line, int index);
+
+    protected:
+        std::time_t last_write_time;
+
+        void monitor_file();
+
+        void check_last_write_time(std::time_t last_write_time_ = static_cast<std::time_t>(-1));
+
+        /// Move iter to line start. Depending on iter position, before or after indentation.
+        /// Works with wrapped lines.
+        Gtk::TextIter get_smart_home_iter(const Gtk::TextIter &iter);
+
+        /// Move iter to line end. Depending on iter position, before or after indentation.
+        /// Works with wrapped lines.
+        /// Note that smart end goes FIRST to end of line to avoid hiding empty chars after expressions.
+        Gtk::TextIter get_smart_end_iter(const Gtk::TextIter &iter);
+
+        std::string get_line(const Gtk::TextIter &iter);
+
+        std::string get_line(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
+
+        std::string get_line(int line_nr);
+
+        std::string get_line();
+
+        std::string get_line_before(const Gtk::TextIter &iter);
+
+        std::string get_line_before(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
+
+        std::string get_line_before();
+
+        Gtk::TextIter get_tabs_end_iter(const Gtk::TextIter &iter);
+
+        Gtk::TextIter get_tabs_end_iter(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
+
+        Gtk::TextIter get_tabs_end_iter(int line_nr);
+
+        Gtk::TextIter get_tabs_end_iter();
+
+        std::set<int> diagnostic_offsets;
+
+        void place_cursor_at_next_diagnostic();
+
+    public:
+        std::function<void(BaseView *view)> update_tab_label;
+        std::function<void(BaseView *view)> update_status_location;
+        std::function<void(BaseView *view)> update_status_file_path;
+        std::function<void(BaseView *view)> update_status_diagnostics;
+        std::function<void(BaseView *view)> update_status_state;
+        std::tuple<size_t, size_t, size_t> status_diagnostics;
+        std::string status_state;
+        std::function<void(BaseView *view)> update_status_branch;
+        std::string status_branch;
+
+        bool disable_spellcheck = false;
+    };
 }
diff --git a/src/source_clang.cc b/src/source_clang.cc
index affe5812..68c39bbe 100644
--- a/src/source_clang.cc
+++ b/src/source_clang.cc
@@ -2,9 +2,11 @@
 #include "config.h"
 #include "terminal.h"
 #include "project_build.h"
+
 #ifdef JUCI_ENABLE_DEBUG
 #include "debug_lldb.h"
 #endif
+
 #include "info.h"
 #include "dialogs.h"
 #include "ctags.h"
@@ -16,375 +18,377 @@
 
 clangmm::Index Source::ClangViewParse::clang_index(0, 0);
 
-Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language):
-    BaseView(file_path, language), Source::View(file_path, language) {
-  Usages::Clang::erase_cache(file_path);
-  
-  auto tag_table=get_buffer()->get_tag_table();
-  for (auto &item : clang_types()) {
-    if(!tag_table->lookup(item.second)) {
-      get_buffer()->create_tag(item.second);
+Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) :
+        BaseView(file_path, language), Source::View(file_path, language) {
+    Usages::Clang::erase_cache(file_path);
+
+    auto tag_table = get_buffer()->get_tag_table();
+    for (auto &item : clang_types()) {
+        if (!tag_table->lookup(item.second)) {
+            get_buffer()->create_tag(item.second);
+        }
+    }
+    configure();
+
+    if (get_buffer()->size() == 0 && (language->get_id() == "chdr" || language->get_id() == "cpphdr")) {
+        disable_spellcheck = true;
+        get_buffer()->insert_at_cursor("#pragma once\n");
+        disable_spellcheck = false;
+        Info::get().print("Added \"#pragma once\" to empty C/C++ header file");
     }
-  }
-  configure();
-  
-  if(get_buffer()->size()==0 && (language->get_id()=="chdr" || language->get_id()=="cpphdr")) {
-    disable_spellcheck=true;
-    get_buffer()->insert_at_cursor("#pragma once\n");
-    disable_spellcheck=false;
-    Info::get().print("Added \"#pragma once\" to empty C/C++ header file");
-  }
-  
-  parse_initialize();
-  
-  get_buffer()->signal_changed().connect([this]() {
-    soft_reparse(true);
-  });
+
+    parse_initialize();
+
+    get_buffer()->signal_changed().connect([this]() {
+        soft_reparse(true);
+    });
 }
 
 bool Source::ClangViewParse::save() {
-  if(!Source::View::save())
-     return false;
-  
-  if(language->get_id()=="chdr" || language->get_id()=="cpphdr") {
-    for(auto &view: views) {
-      if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
-        if(this!=clang_view)
-          clang_view->soft_reparse_needed=true;
-      }
+    if (!Source::View::save())
+        return false;
+
+    if (language->get_id() == "chdr" || language->get_id() == "cpphdr") {
+        for (auto &view: views) {
+            if (auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
+                if (this != clang_view)
+                    clang_view->soft_reparse_needed = true;
+            }
+        }
     }
-  }
-  return true;
+    return true;
 }
 
 void Source::ClangViewParse::configure() {
-  Source::View::configure();
-  
-  auto scheme = get_source_buffer()->get_style_scheme();
-  auto tag_table=get_buffer()->get_tag_table();
-  for (auto &item : clang_types()) {
-    auto tag = get_buffer()->get_tag_table()->lookup(item.second);
-    if(tag) {
-      auto style = scheme->get_style(item.second);
-      if (style) {
-        if (style->property_foreground_set())
-          tag->property_foreground()  = style->property_foreground();
-        if (style->property_background_set())
-          tag->property_background() = style->property_background();
-        if (style->property_strikethrough_set())
-          tag->property_strikethrough() = style->property_strikethrough();
-        //   //    if (style->property_bold_set()) tag->property_weight() = style->property_bold();
-        //   //    if (style->property_italic_set()) tag->property_italic() = style->property_italic();
-        //   //    if (style->property_line_background_set()) tag->property_line_background() = style->property_line_background();
-        //   // if (style->property_underline_set()) tag->property_underline() = style->property_underline();
-      }
+    Source::View::configure();
+
+    auto scheme = get_source_buffer()->get_style_scheme();
+    auto tag_table = get_buffer()->get_tag_table();
+    for (auto &item : clang_types()) {
+        auto tag = get_buffer()->get_tag_table()->lookup(item.second);
+        if (tag) {
+            auto style = scheme->get_style(item.second);
+            if (style) {
+                if (style->property_foreground_set())
+                    tag->property_foreground() = style->property_foreground();
+                if (style->property_background_set())
+                    tag->property_background() = style->property_background();
+                if (style->property_strikethrough_set())
+                    tag->property_strikethrough() = style->property_strikethrough();
+                //   //    if (style->property_bold_set()) tag->property_weight() = style->property_bold();
+                //   //    if (style->property_italic_set()) tag->property_italic() = style->property_italic();
+                //   //    if (style->property_line_background_set()) tag->property_line_background() = style->property_line_background();
+                //   // if (style->property_underline_set()) tag->property_underline() = style->property_underline();
+            }
+        }
     }
-  }
 }
 
 void Source::ClangViewParse::parse_initialize() {
-  hide_tooltips();
-  parsed=false;
-  if(parse_thread.joinable())
-    parse_thread.join();
-  parse_state=ParseState::PROCESSING;
-  parse_process_state=ParseProcessState::STARTING;
-  
-  auto buffer=get_buffer()->get_text();
-  //Remove includes for first parse for initial syntax highlighting
-  std::size_t pos=0;
-  while((pos=buffer.find("#include", pos))!=std::string::npos) {
-    auto start_pos=pos;
-    pos=buffer.find('\n', pos+8);
-    if(pos==std::string::npos)
-      break;
-    if(start_pos==0 || buffer[start_pos-1]=='\n') {
-      buffer.replace(start_pos, pos-start_pos, pos-start_pos, ' ');
+    hide_tooltips();
+    parsed = false;
+    if (parse_thread.joinable())
+        parse_thread.join();
+    parse_state = ParseState::PROCESSING;
+    parse_process_state = ParseProcessState::STARTING;
+
+    auto buffer = get_buffer()->get_text();
+    //Remove includes for first parse for initial syntax highlighting
+    std::size_t pos = 0;
+    while ((pos = buffer.find("#include", pos)) != std::string::npos) {
+        auto start_pos = pos;
+        pos = buffer.find('\n', pos + 8);
+        if (pos == std::string::npos)
+            break;
+        if (start_pos == 0 || buffer[start_pos - 1] == '\n') {
+            buffer.replace(start_pos, pos - start_pos, pos - start_pos, ' ');
+        }
+        pos++;
     }
-    pos++;
-  }
-  auto &buffer_raw=const_cast<std::string&>(buffer.raw());
-  if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr"))
-    clangmm::remove_include_guard(buffer_raw);
-  
-  auto build=Project::Build::create(file_path);
-  if(build->project_path.empty())
-    Info::get().print(file_path.filename().string()+": could not find a supported build system");
-  build->update_default();
-  auto arguments=CompileCommands::get_arguments(build->get_default_path(), file_path);
-  clang_tu = std::make_unique<clangmm::TranslationUnit>(clang_index, file_path.string(), arguments, buffer_raw);
-  clang_tokens=clang_tu->get_tokens();
-  clang_tokens_offsets.clear();
-  clang_tokens_offsets.reserve(clang_tokens->size());
-  for(auto &token: *clang_tokens)
-    clang_tokens_offsets.emplace_back(token.get_source_range().get_offsets());
-  update_syntax();
-  
-  status_state="parsing...";
-  if(update_status_state)
-    update_status_state(this);
-  parse_thread=std::thread([this]() {
-    while(true) {
-      while(parse_state==ParseState::PROCESSING && parse_process_state!=ParseProcessState::STARTING && parse_process_state!=ParseProcessState::PROCESSING)
-        std::this_thread::sleep_for(std::chrono::milliseconds(10));
-      if(parse_state!=ParseState::PROCESSING)
-        break;
-      auto expected=ParseProcessState::STARTING;
-      std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-      if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) {
-        dispatcher.post([this] {
-          auto expected=ParseProcessState::PREPROCESSING;
-          std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-          if(parse_lock.try_lock()) {
-            if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING))
-              parse_thread_buffer=get_buffer()->get_text();
-            parse_lock.unlock();
-          }
-          else
-            parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING);
-        });
-      }
-      else if (parse_process_state==ParseProcessState::PROCESSING && parse_lock.try_lock()) {
-        auto &parse_thread_buffer_raw=const_cast<std::string&>(parse_thread_buffer.raw());
-        if(this->language && (this->language->get_id()=="chdr" || this->language->get_id()=="cpphdr"))
-          clangmm::remove_include_guard(parse_thread_buffer_raw);
-        auto status=clang_tu->reparse(parse_thread_buffer_raw);
-        if(status==0) {
-          auto expected=ParseProcessState::PROCESSING;
-          if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) {
-            clang_tokens=clang_tu->get_tokens();
-            clang_tokens_offsets.clear();
-            clang_tokens_offsets.reserve(clang_tokens->size());
-            for(auto &token: *clang_tokens)
-              clang_tokens_offsets.emplace_back(token.get_source_range().get_offsets());
-            clang_diagnostics=clang_tu->get_diagnostics();
-            parse_lock.unlock();
-            dispatcher.post([this] {
-              std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-              if(parse_lock.try_lock()) {
-                auto expected=ParseProcessState::POSTPROCESSING;
-                if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) {
-                  update_syntax();
-                  update_diagnostics();
-                  parsed=true;
-                  status_state="";
-                  if(update_status_state)
-                    update_status_state(this);
+    auto &buffer_raw = const_cast<std::string &>(buffer.raw());
+    if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr"))
+        clangmm::remove_include_guard(buffer_raw);
+
+    auto build = Project::Build::create(file_path);
+    if (build->project_path.empty())
+        Info::get().print(file_path.filename().string() + ": could not find a supported build system");
+    build->update_default();
+    auto arguments = CompileCommands::get_arguments(build->get_default_path(), file_path);
+    clang_tu = std::make_unique<clangmm::TranslationUnit>(clang_index, file_path.string(), arguments, buffer_raw);
+    clang_tokens = clang_tu->get_tokens();
+    clang_tokens_offsets.clear();
+    clang_tokens_offsets.reserve(clang_tokens->size());
+    for (auto &token: *clang_tokens)
+        clang_tokens_offsets.emplace_back(token.get_source_range().get_offsets());
+    update_syntax();
+
+    status_state = "parsing...";
+    if (update_status_state)
+        update_status_state(this);
+    parse_thread = std::thread([this]() {
+        while (true) {
+            while (parse_state == ParseState::PROCESSING && parse_process_state != ParseProcessState::STARTING &&
+                   parse_process_state != ParseProcessState::PROCESSING)
+                std::this_thread::sleep_for(std::chrono::milliseconds(10));
+            if (parse_state != ParseState::PROCESSING)
+                break;
+            auto expected = ParseProcessState::STARTING;
+            std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+            if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) {
+                dispatcher.post([this] {
+                    auto expected = ParseProcessState::PREPROCESSING;
+                    std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+                    if (parse_lock.try_lock()) {
+                        if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING))
+                            parse_thread_buffer = get_buffer()->get_text();
+                        parse_lock.unlock();
+                    } else
+                        parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING);
+                });
+            } else if (parse_process_state == ParseProcessState::PROCESSING && parse_lock.try_lock()) {
+                auto &parse_thread_buffer_raw = const_cast<std::string &>(parse_thread_buffer.raw());
+                if (this->language && (this->language->get_id() == "chdr" || this->language->get_id() == "cpphdr"))
+                    clangmm::remove_include_guard(parse_thread_buffer_raw);
+                auto status = clang_tu->reparse(parse_thread_buffer_raw);
+                if (status == 0) {
+                    auto expected = ParseProcessState::PROCESSING;
+                    if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) {
+                        clang_tokens = clang_tu->get_tokens();
+                        clang_tokens_offsets.clear();
+                        clang_tokens_offsets.reserve(clang_tokens->size());
+                        for (auto &token: *clang_tokens)
+                            clang_tokens_offsets.emplace_back(token.get_source_range().get_offsets());
+                        clang_diagnostics = clang_tu->get_diagnostics();
+                        parse_lock.unlock();
+                        dispatcher.post([this] {
+                            std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+                            if (parse_lock.try_lock()) {
+                                auto expected = ParseProcessState::POSTPROCESSING;
+                                if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) {
+                                    update_syntax();
+                                    update_diagnostics();
+                                    parsed = true;
+                                    status_state = "";
+                                    if (update_status_state)
+                                        update_status_state(this);
+                                }
+                                parse_lock.unlock();
+                            }
+                        });
+                    } else
+                        parse_lock.unlock();
+                } else {
+                    parse_state = ParseState::STOP;
+                    parse_lock.unlock();
+                    dispatcher.post([this] {
+                        Terminal::get().print("Error: failed to reparse " + this->file_path.string() + ".\n", true);
+                        status_state = "";
+                        if (update_status_state)
+                            update_status_state(this);
+                        status_diagnostics = std::make_tuple(0, 0, 0);
+                        if (update_status_diagnostics)
+                            update_status_diagnostics(this);
+                    });
                 }
-                parse_lock.unlock();
-              }
-            });
-          }
-          else
-            parse_lock.unlock();
-        }
-        else {
-          parse_state=ParseState::STOP;
-          parse_lock.unlock();
-          dispatcher.post([this] {
-            Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true);
-            status_state="";
-            if(update_status_state)
-              update_status_state(this);
-            status_diagnostics=std::make_tuple(0, 0, 0);
-            if(update_status_diagnostics)
-              update_status_diagnostics(this);
-          });
+            }
         }
-      }
-    }
-  });
+    });
 }
 
 void Source::ClangViewParse::soft_reparse(bool delayed) {
-  soft_reparse_needed=false;
-  parsed=false;
-  if(parse_state!=ParseState::PROCESSING)
-    return;
-  parse_process_state=ParseProcessState::IDLE;
-  delayed_reparse_connection.disconnect();
-  delayed_reparse_connection=Glib::signal_timeout().connect([this]() {
-    parsed=false;
-    auto expected=ParseProcessState::IDLE;
-    if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING)) {
-      status_state="parsing...";
-      if(update_status_state)
-        update_status_state(this);
-    }
-    return false;
-  }, delayed?1000:0);
+    soft_reparse_needed = false;
+    parsed = false;
+    if (parse_state != ParseState::PROCESSING)
+        return;
+    parse_process_state = ParseProcessState::IDLE;
+    delayed_reparse_connection.disconnect();
+    delayed_reparse_connection = Glib::signal_timeout().connect([this]() {
+        parsed = false;
+        auto expected = ParseProcessState::IDLE;
+        if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING)) {
+            status_state = "parsing...";
+            if (update_status_state)
+                update_status_state(this);
+        }
+        return false;
+    }, delayed ? 1000 : 0);
 }
 
 const std::unordered_map<int, std::string> &Source::ClangViewParse::clang_types() {
-  static std::unordered_map<int, std::string> types{
-      {8, "def:function"},
-      {21, "def:function"},
-      {22, "def:identifier"},
-      {24, "def:function"},
-      {25, "def:function"},
-      {43, "def:type"},
-      {44, "def:type"},
-      {45, "def:type"},
-      {46, "def:identifier"},
-      {109, "def:string"},
-      {702, "def:statement"},
-      {705, "def:comment"}
-  };
-  return types;
+    static std::unordered_map<int, std::string> types{
+            {8,   "def:function"},
+            {21,  "def:function"},
+            {22,  "def:identifier"},
+            {24,  "def:function"},
+            {25,  "def:function"},
+            {43,  "def:type"},
+            {44,  "def:type"},
+            {45,  "def:type"},
+            {46,  "def:identifier"},
+            {109, "def:string"},
+            {702, "def:statement"},
+            {705, "def:comment"}
+    };
+    return types;
 }
 
 void Source::ClangViewParse::update_syntax() {
-  auto buffer=get_buffer();
-  const auto apply_tag=[this, buffer](const std::pair<clangmm::Offset, clangmm::Offset> &offsets, int type) {
-    auto type_it=clang_types().find(type);
-    if(type_it!=clang_types().end()) {
-      last_syntax_tags.emplace(type_it->second);
-      Gtk::TextIter begin_iter = buffer->get_iter_at_line_index(offsets.first.line-1, offsets.first.index-1);
-      Gtk::TextIter end_iter  = buffer->get_iter_at_line_index(offsets.second.line-1, offsets.second.index-1);
-      buffer->apply_tag_by_name(type_it->second, begin_iter, end_iter);
-    }
-  };
-  
-  for(auto &tag: last_syntax_tags)
-    buffer->remove_tag_by_name(tag, buffer->begin(), buffer->end());
-  last_syntax_tags.clear();
-  
-  for(size_t c=0;c<clang_tokens->size();++c) {
-    auto &token=(*clang_tokens)[c];
-    auto &token_offsets=clang_tokens_offsets[c];
-    //if(token.get_kind()==clangmm::Token::Kind::Token_Punctuation)
-      //ranges.emplace_back(token_offset, static_cast<int>(token.get_cursor().get_kind()));
-    auto token_kind=token.get_kind();
-    if(token_kind==clangmm::Token::Kind::Keyword)
-      apply_tag(token_offsets, 702);
-    else if(token_kind==clangmm::Token::Kind::Identifier) {
-      auto cursor_kind=token.get_cursor().get_kind();
-      if(cursor_kind==clangmm::Cursor::Kind::DeclRefExpr || cursor_kind==clangmm::Cursor::Kind::MemberRefExpr)
-        cursor_kind=token.get_cursor().get_referenced().get_kind();
-      if(cursor_kind!=clangmm::Cursor::Kind::PreprocessingDirective)
-        apply_tag(token_offsets, static_cast<int>(cursor_kind));
+    auto buffer = get_buffer();
+    const auto apply_tag = [this, buffer](const std::pair<clangmm::Offset, clangmm::Offset> &offsets, int type) {
+        auto type_it = clang_types().find(type);
+        if (type_it != clang_types().end()) {
+            last_syntax_tags.emplace(type_it->second);
+            Gtk::TextIter begin_iter = buffer->get_iter_at_line_index(offsets.first.line - 1, offsets.first.index - 1);
+            Gtk::TextIter end_iter = buffer->get_iter_at_line_index(offsets.second.line - 1, offsets.second.index - 1);
+            buffer->apply_tag_by_name(type_it->second, begin_iter, end_iter);
+        }
+    };
+
+    for (auto &tag: last_syntax_tags)
+        buffer->remove_tag_by_name(tag, buffer->begin(), buffer->end());
+    last_syntax_tags.clear();
+
+    for (size_t c = 0; c < clang_tokens->size(); ++c) {
+        auto &token = (*clang_tokens)[c];
+        auto &token_offsets = clang_tokens_offsets[c];
+        //if(token.get_kind()==clangmm::Token::Kind::Token_Punctuation)
+        //ranges.emplace_back(token_offset, static_cast<int>(token.get_cursor().get_kind()));
+        auto token_kind = token.get_kind();
+        if (token_kind == clangmm::Token::Kind::Keyword)
+            apply_tag(token_offsets, 702);
+        else if (token_kind == clangmm::Token::Kind::Identifier) {
+            auto cursor_kind = token.get_cursor().get_kind();
+            if (cursor_kind == clangmm::Cursor::Kind::DeclRefExpr ||
+                cursor_kind == clangmm::Cursor::Kind::MemberRefExpr)
+                cursor_kind = token.get_cursor().get_referenced().get_kind();
+            if (cursor_kind != clangmm::Cursor::Kind::PreprocessingDirective)
+                apply_tag(token_offsets, static_cast<int>(cursor_kind));
+        } else if (token_kind == clangmm::Token::Kind::Literal)
+            apply_tag(token_offsets, static_cast<int>(clangmm::Cursor::Kind::StringLiteral));
+        else if (token_kind == clangmm::Token::Kind::Comment)
+            apply_tag(token_offsets, 705);
     }
-    else if(token_kind==clangmm::Token::Kind::Literal)
-      apply_tag(token_offsets, static_cast<int>(clangmm::Cursor::Kind::StringLiteral));
-    else if(token_kind==clangmm::Token::Kind::Comment)
-      apply_tag(token_offsets, 705);
-  }
 }
 
 void Source::ClangViewParse::update_diagnostics() {
-  clear_diagnostic_tooltips();
-  fix_its.clear();
-  size_t num_warnings=0;
-  size_t num_errors=0;
-  size_t num_fix_its=0;
-  for(auto &diagnostic: clang_diagnostics) {
-    if(diagnostic.path==file_path.string()) {      
-      int line=diagnostic.offsets.first.line-1;
-      if(line<0 || line>=get_buffer()->get_line_count())
-        line=get_buffer()->get_line_count()-1;
-      auto start=get_iter_at_line_end(line);
-      int index=diagnostic.offsets.first.index-1;
-      if(index>=0 && index<start.get_line_index())
-        start=get_buffer()->get_iter_at_line_index(line, index);
-      if(start.ends_line()) {
-        while(!start.is_start() && start.ends_line())
-          start.backward_char();
-      }
-      diagnostic_offsets.emplace(start.get_offset());
-      
-      line=diagnostic.offsets.second.line-1;
-      if(line<0 || line>=get_buffer()->get_line_count())
-        line=get_buffer()->get_line_count()-1;
-      auto end=get_iter_at_line_end(line);
-      index=diagnostic.offsets.second.index-1;
-      if(index>=0 && index<end.get_line_index())
-        end=get_buffer()->get_iter_at_line_index(line, index);
-      
-      bool error=false;
-      std::string severity_tag_name;
-      if(diagnostic.severity<=clangmm::Diagnostic::Severity::Warning) {
-        severity_tag_name="def:warning";
-        num_warnings++;
-      }
-      else {
-        severity_tag_name="def:error";
-        num_errors++;
-        error=true;
-      }
-      
-      std::string fix_its_string;
-      unsigned fix_its_count=0;
-      for(auto &fix_it: diagnostic.fix_its) {
-        auto clang_offsets=fix_it.offsets;
-        std::pair<Offset, Offset> offsets;
-        offsets.first.line=clang_offsets.first.line-1;
-        offsets.first.index=clang_offsets.first.index-1;
-        offsets.second.line=clang_offsets.second.line-1;
-        offsets.second.index=clang_offsets.second.index-1;
-        
-        fix_its.emplace_back(fix_it.source, offsets);
-        
-        if(fix_its_string.size()>0)
-          fix_its_string+='\n';
-        fix_its_string+=fix_its.back().string(get_buffer());
-        fix_its_count++;
-        num_fix_its++;
-      }
-      
-      if(fix_its_count==1)
-        fix_its_string.insert(0, "Fix-it:\n");
-      else if(fix_its_count>1)
-        fix_its_string.insert(0, "Fix-its:\n");
-      
-      if(!fix_its_string.empty())
-        diagnostic.spelling+="\n\n"+fix_its_string;
-      
-      add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
+    clear_diagnostic_tooltips();
+    fix_its.clear();
+    size_t num_warnings = 0;
+    size_t num_errors = 0;
+    size_t num_fix_its = 0;
+    for (auto &diagnostic: clang_diagnostics) {
+        if (diagnostic.path == file_path.string()) {
+            int line = diagnostic.offsets.first.line - 1;
+            if (line < 0 || line >= get_buffer()->get_line_count())
+                line = get_buffer()->get_line_count() - 1;
+            auto start = get_iter_at_line_end(line);
+            int index = diagnostic.offsets.first.index - 1;
+            if (index >= 0 && index < start.get_line_index())
+                start = get_buffer()->get_iter_at_line_index(line, index);
+            if (start.ends_line()) {
+                while (!start.is_start() && start.ends_line())
+                    start.backward_char();
+            }
+            diagnostic_offsets.emplace(start.get_offset());
+
+            line = diagnostic.offsets.second.line - 1;
+            if (line < 0 || line >= get_buffer()->get_line_count())
+                line = get_buffer()->get_line_count() - 1;
+            auto end = get_iter_at_line_end(line);
+            index = diagnostic.offsets.second.index - 1;
+            if (index >= 0 && index < end.get_line_index())
+                end = get_buffer()->get_iter_at_line_index(line, index);
+
+            bool error = false;
+            std::string severity_tag_name;
+            if (diagnostic.severity <= clangmm::Diagnostic::Severity::Warning) {
+                severity_tag_name = "def:warning";
+                num_warnings++;
+            } else {
+                severity_tag_name = "def:error";
+                num_errors++;
+                error = true;
+            }
+
+            std::string fix_its_string;
+            unsigned fix_its_count = 0;
+            for (auto &fix_it: diagnostic.fix_its) {
+                auto clang_offsets = fix_it.offsets;
+                std::pair<Offset, Offset> offsets;
+                offsets.first.line = clang_offsets.first.line - 1;
+                offsets.first.index = clang_offsets.first.index - 1;
+                offsets.second.line = clang_offsets.second.line - 1;
+                offsets.second.index = clang_offsets.second.index - 1;
+
+                fix_its.emplace_back(fix_it.source, offsets);
+
+                if (fix_its_string.size() > 0)
+                    fix_its_string += '\n';
+                fix_its_string += fix_its.back().string(get_buffer());
+                fix_its_count++;
+                num_fix_its++;
+            }
+
+            if (fix_its_count == 1)
+                fix_its_string.insert(0, "Fix-it:\n");
+            else if (fix_its_count > 1)
+                fix_its_string.insert(0, "Fix-its:\n");
+
+            if (!fix_its_string.empty())
+                diagnostic.spelling += "\n\n" + fix_its_string;
+
+            add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
+        }
     }
-  }
-  status_diagnostics=std::make_tuple(num_warnings, num_errors, num_fix_its);
-  if(update_status_diagnostics)
-    update_status_diagnostics(this);
+    status_diagnostics = std::make_tuple(num_warnings, num_errors, num_fix_its);
+    if (update_status_diagnostics)
+        update_status_diagnostics(this);
 }
 
 void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) {
-  if(parsed) {
-    Gtk::TextIter iter;
-    int location_x, location_y;
-    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x, location_y);
-    location_x+=(rectangle.get_width()-1)/2;
-    get_iter_at_location(iter, location_x, location_y);
-    Gdk::Rectangle iter_rectangle;
-    get_iter_location(iter, iter_rectangle);
-    if(iter.ends_line() && location_x>iter_rectangle.get_x())
-      return;
-    
-    auto line=static_cast<unsigned>(iter.get_line());
-    auto index=static_cast<unsigned>(iter.get_line_index());
-    type_tooltips.clear();
-    for(size_t c=clang_tokens->size()-1;c!=static_cast<size_t>(-1);--c) {
-      auto &token=(*clang_tokens)[c];
-      auto &token_offsets=clang_tokens_offsets[c];
-      if(token.is_identifier() || token.get_spelling() == "auto" ) {
-        if(line==token_offsets.first.line-1 && index>=token_offsets.first.index-1 && index <=token_offsets.second.index-1) {
-          auto cursor=token.get_cursor();
-          auto referenced=cursor.get_referenced();
-          if(referenced) {
-            auto start=get_buffer()->get_iter_at_line_index(token_offsets.first.line-1, token_offsets.first.index-1);
-            auto end=get_buffer()->get_iter_at_line_index(token_offsets.second.line-1, token_offsets.second.index-1);
-            auto create_tooltip_buffer=[this, &token, &start, &end]() {
-              auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
-              tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "Type: "+token.get_cursor().get_type_description());
-              auto brief_comment=token.get_cursor().get_brief_comments();
-              if(brief_comment!="")
-                tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+brief_comment);
-  
+    if (parsed) {
+        Gtk::TextIter iter;
+        int location_x, location_y;
+        window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x,
+                                location_y);
+        location_x += (rectangle.get_width() - 1) / 2;
+        get_iter_at_location(iter, location_x, location_y);
+        Gdk::Rectangle iter_rectangle;
+        get_iter_location(iter, iter_rectangle);
+        if (iter.ends_line() && location_x > iter_rectangle.get_x())
+            return;
+
+        auto line = static_cast<unsigned>(iter.get_line());
+        auto index = static_cast<unsigned>(iter.get_line_index());
+        type_tooltips.clear();
+        for (size_t c = clang_tokens->size() - 1; c != static_cast<size_t>(-1); --c) {
+            auto &token = (*clang_tokens)[c];
+            auto &token_offsets = clang_tokens_offsets[c];
+            if (token.is_identifier() || token.get_spelling() == "auto") {
+                if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
+                    index <= token_offsets.second.index - 1) {
+                    auto cursor = token.get_cursor();
+                    auto referenced = cursor.get_referenced();
+                    if (referenced) {
+                        auto start = get_buffer()->get_iter_at_line_index(token_offsets.first.line - 1,
+                                                                          token_offsets.first.index - 1);
+                        auto end = get_buffer()->get_iter_at_line_index(token_offsets.second.line - 1,
+                                                                        token_offsets.second.index - 1);
+                        auto create_tooltip_buffer = [this, &token, &start, &end]() {
+                            auto tooltip_buffer = Gtk::TextBuffer::create(get_buffer()->get_tag_table());
+                            tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(),
+                                                   "Type: " + token.get_cursor().get_type_description());
+                            auto brief_comment = token.get_cursor().get_brief_comments();
+                            if (brief_comment != "")
+                                tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(),
+                                                       "\n\n" + brief_comment);
+
 #ifdef JUCI_ENABLE_DEBUG
-              if(Debug::LLDB::get().is_stopped()) {
+                                                                                                                                                    if(Debug::LLDB::get().is_stopped()) {
                 auto referenced=token.get_cursor().get_referenced();
                 auto location=referenced.get_source_location();
                 Glib::ustring value_type="Value";
-                
+
                 auto iter=start;
                 while((*iter>='a' && *iter<='z') || (*iter>='A' && *iter<='Z') || (*iter>='0' && *iter<='9') || *iter=='_' || *iter=='.') {
                   start=iter;
@@ -400,7 +404,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
                   }
                 }
                 auto spelling=get_buffer()->get_text(start, end).raw();
-                
+
                 Glib::ustring debug_value;
                 auto cursor_kind=referenced.get_kind();
                 if(cursor_kind!=clangmm::Cursor::Kind::FunctionDecl && cursor_kind!=clangmm::Cursor::Kind::CXXMethod &&
@@ -427,1430 +431,1487 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
                 }
               }
 #endif
-              
-              return tooltip_buffer;
-            };
-            
-            type_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start), get_buffer()->create_mark(end));
-            type_tooltips.show();
-            return;
-          }
+
+                            return tooltip_buffer;
+                        };
+
+                        type_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start),
+                                                   get_buffer()->create_mark(end));
+                        type_tooltips.show();
+                        return;
+                    }
+                }
+            }
         }
-      }
     }
-  }
 }
 
 
-Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language):
-    BaseView(file_path, language), Source::ClangViewParse(file_path, language), autocomplete(this, interactive_completion, last_keyval, true) {
-  non_interactive_completion=[this] {
-    if(CompletionDialog::get() && CompletionDialog::get()->is_visible())
-      return;
-    autocomplete.run();
-  };
-  
-  autocomplete.is_processing=[this] {
-    return parse_state==ParseState::PROCESSING;
-  };
-  
-  autocomplete.reparse=[this] {
-    selected_completion_string=nullptr;
-    code_complete_results=nullptr;
-    soft_reparse(true);
-  };
-  
-  autocomplete.cancel_reparse=[this] {
-    delayed_reparse_connection.disconnect();
-  };
-  
-  autocomplete.get_parse_lock=[this]() {
-    return std::make_unique<std::lock_guard<std::mutex>>(parse_mutex);
-  };
-  
-  autocomplete.stop_parse=[this]() {
-    parse_process_state=ParseProcessState::IDLE;
-  };
-  
-  // Activate argument completions
-  get_buffer()->signal_changed().connect([this] {
-    if(!interactive_completion)
-      return;
-    if(CompletionDialog::get() && CompletionDialog::get()->is_visible())
-      return;
-    if(!has_focus())
-      return;
-    if(show_arguments)
-      autocomplete.stop();
-    show_arguments=false;
-    delayed_show_arguments_connection.disconnect();
-    delayed_show_arguments_connection=Glib::signal_timeout().connect([this]() {
-      if(get_buffer()->get_has_selection())
+Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path,
+                                                     Glib::RefPtr<Gsv::Language> language) :
+        BaseView(file_path, language), Source::ClangViewParse(file_path, language),
+        autocomplete(this, interactive_completion, last_keyval, true) {
+    non_interactive_completion = [this] {
+        if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
+            return;
+        autocomplete.run();
+    };
+
+    autocomplete.is_processing = [this] {
+        return parse_state == ParseState::PROCESSING;
+    };
+
+    autocomplete.reparse = [this] {
+        selected_completion_string = nullptr;
+        code_complete_results = nullptr;
+        soft_reparse(true);
+    };
+
+    autocomplete.cancel_reparse = [this] {
+        delayed_reparse_connection.disconnect();
+    };
+
+    autocomplete.get_parse_lock = [this]() {
+        return std::make_unique<std::lock_guard<std::mutex>>(parse_mutex);
+    };
+
+    autocomplete.stop_parse = [this]() {
+        parse_process_state = ParseProcessState::IDLE;
+    };
+
+    // Activate argument completions
+    get_buffer()->signal_changed().connect([this] {
+        if (!interactive_completion)
+            return;
+        if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
+            return;
+        if (!has_focus())
+            return;
+        if (show_arguments)
+            autocomplete.stop();
+        show_arguments = false;
+        delayed_show_arguments_connection.disconnect();
+        delayed_show_arguments_connection = Glib::signal_timeout().connect([this]() {
+            if (get_buffer()->get_has_selection())
+                return false;
+            if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
+                return false;
+            if (!has_focus())
+                return false;
+            if (is_possible_parameter()) {
+                autocomplete.stop();
+                autocomplete.run();
+            }
+            return false;
+        }, 500);
+    }, false);
+
+    // Remove argument completions
+    signal_key_press_event().connect([this](GdkEventKey *key) {
+        if (show_arguments && CompletionDialog::get() && CompletionDialog::get()->is_visible() &&
+            key->keyval != GDK_KEY_Down && key->keyval != GDK_KEY_Up &&
+            key->keyval != GDK_KEY_Return && key->keyval != GDK_KEY_KP_Enter &&
+            key->keyval != GDK_KEY_ISO_Left_Tab && key->keyval != GDK_KEY_Tab &&
+            (key->keyval < GDK_KEY_Shift_L || key->keyval > GDK_KEY_Hyper_R)) {
+            get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(),
+                                get_buffer()->get_insert()->get_iter());
+            CompletionDialog::get()->hide();
+        }
         return false;
-      if(CompletionDialog::get() && CompletionDialog::get()->is_visible())
+    }, false);
+
+    autocomplete.is_continue_key = [](guint keyval) {
+        if ((keyval >= '0' && keyval <= '9') || (keyval >= 'a' && keyval <= 'z') || (keyval >= 'A' && keyval <= 'Z') ||
+            keyval == '_')
+            return true;
+
         return false;
-      if(!has_focus())
+    };
+
+    autocomplete.is_restart_key = [this](guint keyval) {
+        auto iter = get_buffer()->get_insert()->get_iter();
+        iter.backward_chars(2);
+        if (keyval == '.' || (keyval == ':' && *iter == ':') || (keyval == '>' && *iter == '-'))
+            return true;
         return false;
-      if(is_possible_parameter()) {
-        autocomplete.stop();
-        autocomplete.run();
-      }
-      return false;
-    }, 500);
-  }, false);
-
-  // Remove argument completions
-  signal_key_press_event().connect([this](GdkEventKey *key) {
-    if(show_arguments && CompletionDialog::get() && CompletionDialog::get()->is_visible() &&
-       key->keyval != GDK_KEY_Down && key->keyval != GDK_KEY_Up &&
-       key->keyval != GDK_KEY_Return && key->keyval != GDK_KEY_KP_Enter &&
-       key->keyval != GDK_KEY_ISO_Left_Tab && key->keyval != GDK_KEY_Tab &&
-       (key->keyval < GDK_KEY_Shift_L || key->keyval > GDK_KEY_Hyper_R)) {
-      get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
-      CompletionDialog::get()->hide();
-    }
-    return false;
-  }, false);
+    };
 
-  autocomplete.is_continue_key=[](guint keyval) {
-    if((keyval>='0' && keyval<='9') || (keyval>='a' && keyval<='z') || (keyval>='A' && keyval<='Z') || keyval=='_')
-      return true;
-    
-    return false;
-  };
-  
-  autocomplete.is_restart_key=[this](guint keyval) {
-    auto iter=get_buffer()->get_insert()->get_iter();
-    iter.backward_chars(2);
-    if(keyval=='.' || (keyval==':' && *iter==':') || (keyval=='>' && *iter=='-'))
-      return true;
-    return false;
-  };
-  
-  autocomplete.run_check=[this]() {
-    auto iter=get_buffer()->get_insert()->get_iter();
-    iter.backward_char();
-    if(!is_code_iter(iter))
-      return false;
-    
-    show_arguments=false;
-    
-    std::string line=" "+get_line_before();
-    const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>](\\.|->)([a-zA-Z0-9_]*)$");
-    const static std::regex colon_colon("^.*::([a-zA-Z0-9_]*)$");
-    const static std::regex part_of_symbol("^.*[^a-zA-Z0-9_]+([a-zA-Z0-9_]{3,})$");
-    std::smatch sm;
-    if(std::regex_match(line, sm, dot_or_arrow)) {
-      {
-        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-        autocomplete.prefix=sm[2].str();
-      }
-      if(autocomplete.prefix.size()==0 || autocomplete.prefix[0]<'0' || autocomplete.prefix[0]>'9')
-        return true;
-    }
-    else if(std::regex_match(line, sm, colon_colon)) {
-      {
-        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-        autocomplete.prefix=sm[1].str();
-      }
-      if(autocomplete.prefix.size()==0 || autocomplete.prefix[0]<'0' || autocomplete.prefix[0]>'9')
-        return true;
-    }
-    else if(std::regex_match(line, sm, part_of_symbol)) {
-      {
-        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-        autocomplete.prefix=sm[1].str();
-      }
-      if(autocomplete.prefix.size()==0 || autocomplete.prefix[0]<'0' || autocomplete.prefix[0]>'9')
-        return true;
-    }
-    else if(is_possible_parameter()) {
-      show_arguments=true;
-      std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-      autocomplete.prefix="";
-      return true;
-    }
-    else if(!interactive_completion) {
-      auto end_iter=get_buffer()->get_insert()->get_iter();
-      auto iter=end_iter;
-      while(iter.backward_char() && autocomplete.is_continue_key(*iter)) {}
-      if(iter!=end_iter)
-        iter.forward_char();
-      std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-      autocomplete.prefix=get_buffer()->get_text(iter, end_iter);
-      return true;
-    }
-    
-    return false;
-  };
-  
-  autocomplete.before_add_rows=[this] {
-    status_state="autocomplete...";
-    if(update_status_state)
-      update_status_state(this);
-  };
-  
-  autocomplete.after_add_rows=[this] {
-    status_state="";
-    if(update_status_state)
-      update_status_state(this);
-  };
-  
-  autocomplete.on_add_rows_error=[this] {
-    Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true);
-    selected_completion_string=nullptr;
-    code_complete_results=nullptr;
-    full_reparse();
-  };
-  
-  autocomplete.add_rows=[this](std::string &buffer, int line_number, int column) {
-    if(this->language && (this->language->get_id()=="chdr" || this->language->get_id()=="cpphdr"))
-      clangmm::remove_include_guard(buffer);
-    code_complete_results=std::make_unique<clangmm::CodeCompleteResults>(clang_tu->get_code_completions(buffer, line_number, column));
-    if(code_complete_results->cx_results==nullptr) {
-      auto expected=ParseState::PROCESSING;
-      parse_state.compare_exchange_strong(expected, ParseState::RESTARTING);
-      return;
-    }
-    
-    if(autocomplete.state==Autocomplete::State::STARTING) {
-      std::string prefix_copy;
-      {
-        std::lock_guard<std::mutex> lock(autocomplete.prefix_mutex);
-        prefix_copy=autocomplete.prefix;
-      }
-      
-      completion_strings.clear();
-      for (unsigned i = 0; i < code_complete_results->size(); ++i) {
-        auto result=code_complete_results->get(i);
-        if(result.available()) {
-          std::string text;
-          if(show_arguments) {
-            class Recursive {
-            public:
-              static void f(const clangmm::CompletionString &completion_string, std::string &text) {
-                for(unsigned i = 0; i < completion_string.get_num_chunks(); ++i) {
-                  auto kind=static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(completion_string.cx_completion_string, i));
-                  if(kind==clangmm::CompletionChunk_Optional)
-                    f(clangmm::CompletionString(clang_getCompletionChunkCompletionString(completion_string.cx_completion_string, i)), text);
-                  else if(kind==clangmm::CompletionChunk_CurrentParameter) {
-                    auto chunk_cstr=clangmm::String(clang_getCompletionChunkText(completion_string.cx_completion_string, i));
-                    text+=chunk_cstr.c_str;
-                  }
-                }
-              }
-            };
-            Recursive::f(result, text);
-            if(!text.empty()) {
-              bool already_added=false;
-              for(auto &row: autocomplete.rows) {
-                if(row==text) {
-                  already_added=true;
-                  break;
-                }
-              }
-              if(!already_added) {
-                autocomplete.rows.emplace_back(std::move(text));
-                completion_strings.emplace_back(result.cx_completion_string);
-              }
+    autocomplete.run_check = [this]() {
+        auto iter = get_buffer()->get_insert()->get_iter();
+        iter.backward_char();
+        if (!is_code_iter(iter))
+            return false;
+
+        show_arguments = false;
+
+        std::string line = " " + get_line_before();
+        const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>](\\.|->)([a-zA-Z0-9_]*)$");
+        const static std::regex colon_colon("^.*::([a-zA-Z0-9_]*)$");
+        const static std::regex part_of_symbol("^.*[^a-zA-Z0-9_]+([a-zA-Z0-9_]{3,})$");
+        std::smatch sm;
+        if (std::regex_match(line, sm, dot_or_arrow)) {
+            {
+                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+                autocomplete.prefix = sm[2].str();
             }
-          }
-          else {
-            std::string return_text;
-            bool match=false;
-            for(unsigned i = 0; i < result.get_num_chunks(); ++i) {
-              auto kind=static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(result.cx_completion_string, i));
-              if(kind!=clangmm::CompletionChunk_Informative) {
-                auto chunk_cstr=clangmm::String(clang_getCompletionChunkText(result.cx_completion_string, i));
-                if(kind==clangmm::CompletionChunk_TypedText) {
-                  if(strlen(chunk_cstr.c_str)>=prefix_copy.size() && prefix_copy.compare(0, prefix_copy.size(), chunk_cstr.c_str, prefix_copy.size())==0)
-                    match = true;
-                  else
-                    break;
-                }
-                if(kind==clangmm::CompletionChunk_ResultType)
-                  return_text=std::string("  →  ")+chunk_cstr.c_str;
-                else
-                  text+=chunk_cstr.c_str;
-              }
+            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+                return true;
+        } else if (std::regex_match(line, sm, colon_colon)) {
+            {
+                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+                autocomplete.prefix = sm[1].str();
             }
-            if(match && !text.empty()) {
-              if(!return_text.empty())
-                text+=return_text;
-              autocomplete.rows.emplace_back(std::move(text));
-              completion_strings.emplace_back(result.cx_completion_string);
+            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+                return true;
+        } else if (std::regex_match(line, sm, part_of_symbol)) {
+            {
+                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+                autocomplete.prefix = sm[1].str();
             }
-          }
-        }
-      }
-    }
-  };
-  
-  autocomplete.on_show = [this] {
-    hide_tooltips();
-  };
-  
-  autocomplete.on_hide = [this] {
-    selected_completion_string=nullptr;
-    code_complete_results=nullptr;
-  };
-  
-  autocomplete.on_changed = [this](unsigned int index, const std::string &text) {
-    selected_completion_string=completion_strings[index];
-  };
-  
-  autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
-    std::string row;
-    auto pos=text.find("  →  ");
-    if(pos!=std::string::npos)
-      row=text.substr(0, pos);
-    else
-      row=text;
-    //erase existing variable or function before insert iter
-    get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
-    //do not insert template argument or function parameters if they already exist
-    auto iter=get_buffer()->get_insert()->get_iter();
-    if(*iter=='<' || *iter=='(') {
-      auto bracket_pos=row.find(*iter);
-      if(bracket_pos!=std::string::npos) {
-        row=row.substr(0, bracket_pos);
-      }
-    }
-    //Fixes for the most commonly used stream manipulators
-    auto manipulators_map=autocomplete_manipulators_map();
-    auto it=manipulators_map.find(row);
-    if(it!=manipulators_map.end())
-      row=it->second;
-    //Do not insert template argument, function parameters or ':' unless hide_window is true
-    if(!hide_window) {
-      for(size_t c=0;c<row.size();++c) {
-        if(row[c]=='<' || row[c]=='(' || row[c]==':') {
-          row.erase(c);
-          break;
+            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+                return true;
+        } else if (is_possible_parameter()) {
+            show_arguments = true;
+            std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+            autocomplete.prefix = "";
+            return true;
+        } else if (!interactive_completion) {
+            auto end_iter = get_buffer()->get_insert()->get_iter();
+            auto iter = end_iter;
+            while (iter.backward_char() && autocomplete.is_continue_key(*iter)) {}
+            if (iter != end_iter)
+                iter.forward_char();
+            std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+            autocomplete.prefix = get_buffer()->get_text(iter, end_iter);
+            return true;
         }
-      }
-    }
-    get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), row);
-    //if selection is finalized, select text inside template arguments or function parameters
-    if(hide_window) {
-      size_t start_pos=std::string::npos;
-      size_t end_pos=std::string::npos;
-      if(show_arguments) {
-        start_pos=0;
-        end_pos=row.size();
-      }
-      else {
-        auto para_pos=row.find('(');
-        auto angle_pos=row.find('<');
-        if(angle_pos<para_pos) {
-          start_pos=angle_pos+1;
-          end_pos=row.find('>');
+
+        return false;
+    };
+
+    autocomplete.before_add_rows = [this] {
+        status_state = "autocomplete...";
+        if (update_status_state)
+            update_status_state(this);
+    };
+
+    autocomplete.after_add_rows = [this] {
+        status_state = "";
+        if (update_status_state)
+            update_status_state(this);
+    };
+
+    autocomplete.on_add_rows_error = [this] {
+        Terminal::get().print("Error: autocomplete failed, reparsing " + this->file_path.string() + "\n", true);
+        selected_completion_string = nullptr;
+        code_complete_results = nullptr;
+        full_reparse();
+    };
+
+    autocomplete.add_rows = [this](std::string &buffer, int line_number, int column) {
+        if (this->language && (this->language->get_id() == "chdr" || this->language->get_id() == "cpphdr"))
+            clangmm::remove_include_guard(buffer);
+        code_complete_results = std::make_unique<clangmm::CodeCompleteResults>(
+                clang_tu->get_code_completions(buffer, line_number, column));
+        if (code_complete_results->cx_results == nullptr) {
+            auto expected = ParseState::PROCESSING;
+            parse_state.compare_exchange_strong(expected, ParseState::RESTARTING);
+            return;
         }
-        else if(para_pos!=std::string::npos) {
-          start_pos=para_pos+1;
-          end_pos=row.size()-1;
+
+        if (autocomplete.state == Autocomplete::State::STARTING) {
+            std::string prefix_copy;
+            {
+                std::lock_guard<std::mutex> lock(autocomplete.prefix_mutex);
+                prefix_copy = autocomplete.prefix;
+            }
+
+            completion_strings.clear();
+            for (unsigned i = 0; i < code_complete_results->size(); ++i) {
+                auto result = code_complete_results->get(i);
+                if (result.available()) {
+                    std::string text;
+                    if (show_arguments) {
+                        class Recursive {
+                        public:
+                            static void f(const clangmm::CompletionString &completion_string, std::string &text) {
+                                for (unsigned i = 0; i < completion_string.get_num_chunks(); ++i) {
+                                    auto kind = static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(
+                                            completion_string.cx_completion_string, i));
+                                    if (kind == clangmm::CompletionChunk_Optional)
+                                        f(clangmm::CompletionString(clang_getCompletionChunkCompletionString(
+                                                completion_string.cx_completion_string, i)), text);
+                                    else if (kind == clangmm::CompletionChunk_CurrentParameter) {
+                                        auto chunk_cstr = clangmm::String(
+                                                clang_getCompletionChunkText(completion_string.cx_completion_string,
+                                                                             i));
+                                        text += chunk_cstr.c_str;
+                                    }
+                                }
+                            }
+                        };
+                        Recursive::f(result, text);
+                        if (!text.empty()) {
+                            bool already_added = false;
+                            for (auto &row: autocomplete.rows) {
+                                if (row == text) {
+                                    already_added = true;
+                                    break;
+                                }
+                            }
+                            if (!already_added) {
+                                autocomplete.rows.emplace_back(std::move(text));
+                                completion_strings.emplace_back(result.cx_completion_string);
+                            }
+                        }
+                    } else {
+                        std::string return_text;
+                        bool match = false;
+                        for (unsigned i = 0; i < result.get_num_chunks(); ++i) {
+                            auto kind = static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(
+                                    result.cx_completion_string, i));
+                            if (kind != clangmm::CompletionChunk_Informative) {
+                                auto chunk_cstr = clangmm::String(
+                                        clang_getCompletionChunkText(result.cx_completion_string, i));
+                                if (kind == clangmm::CompletionChunk_TypedText) {
+                                    if (strlen(chunk_cstr.c_str) >= prefix_copy.size() &&
+                                        prefix_copy.compare(0, prefix_copy.size(), chunk_cstr.c_str,
+                                                            prefix_copy.size()) == 0)
+                                        match = true;
+                                    else
+                                        break;
+                                }
+                                if (kind == clangmm::CompletionChunk_ResultType)
+                                    return_text = std::string("  →  ") + chunk_cstr.c_str;
+                                else
+                                    text += chunk_cstr.c_str;
+                            }
+                        }
+                        if (match && !text.empty()) {
+                            if (!return_text.empty())
+                                text += return_text;
+                            autocomplete.rows.emplace_back(std::move(text));
+                            completion_strings.emplace_back(result.cx_completion_string);
+                        }
+                    }
+                }
+            }
         }
-        if(start_pos==std::string::npos || end_pos==std::string::npos) {
-          if((start_pos=row.find('\"'))!=std::string::npos) {
-            end_pos=row.find('\"', start_pos+1);
-            ++start_pos;
-          }
+    };
+
+    autocomplete.on_show = [this] {
+        hide_tooltips();
+    };
+
+    autocomplete.on_hide = [this] {
+        selected_completion_string = nullptr;
+        code_complete_results = nullptr;
+    };
+
+    autocomplete.on_changed = [this](unsigned int index, const std::string &text) {
+        selected_completion_string = completion_strings[index];
+    };
+
+    autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
+        std::string row;
+        auto pos = text.find("  →  ");
+        if (pos != std::string::npos)
+            row = text.substr(0, pos);
+        else
+            row = text;
+        //erase existing variable or function before insert iter
+        get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
+        //do not insert template argument or function parameters if they already exist
+        auto iter = get_buffer()->get_insert()->get_iter();
+        if (*iter == '<' || *iter == '(') {
+            auto bracket_pos = row.find(*iter);
+            if (bracket_pos != std::string::npos) {
+                row = row.substr(0, bracket_pos);
+            }
         }
-      }
-      if(start_pos==std::string::npos || end_pos==std::string::npos) {
-        if((start_pos=row.find(' '))!=std::string::npos) {
-          std::vector<std::string> parameters={"expression", "arguments", "identifier", "type name", "qualifier::name", "macro", "condition"};
-          for(auto &parameter: parameters) {
-            if((start_pos=row.find(parameter, start_pos+1))!=std::string::npos) {
-              end_pos=start_pos+parameter.size();
-              break;
+        //Fixes for the most commonly used stream manipulators
+        auto manipulators_map = autocomplete_manipulators_map();
+        auto it = manipulators_map.find(row);
+        if (it != manipulators_map.end())
+            row = it->second;
+        //Do not insert template argument, function parameters or ':' unless hide_window is true
+        if (!hide_window) {
+            for (size_t c = 0; c < row.size(); ++c) {
+                if (row[c] == '<' || row[c] == '(' || row[c] == ':') {
+                    row.erase(c);
+                    break;
+                }
             }
-          }
         }
-      }
-      
-      if(start_pos!=std::string::npos && end_pos!=std::string::npos) {
-        int start_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+start_pos;
-        int end_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+end_pos;
-        auto size=get_buffer()->size();
-        if(start_offset!=end_offset && start_offset<size && end_offset<size)
-          get_buffer()->select_range(get_buffer()->get_iter_at_offset(start_offset), get_buffer()->get_iter_at_offset(end_offset));
-      }
-      else {
-        //new autocomplete after for instance when selecting "std::"
-        auto iter=get_buffer()->get_insert()->get_iter();
-        if(iter.backward_char() && *iter==':') {
-          autocomplete.run();
-          return;
+        get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), row);
+        //if selection is finalized, select text inside template arguments or function parameters
+        if (hide_window) {
+            size_t start_pos = std::string::npos;
+            size_t end_pos = std::string::npos;
+            if (show_arguments) {
+                start_pos = 0;
+                end_pos = row.size();
+            } else {
+                auto para_pos = row.find('(');
+                auto angle_pos = row.find('<');
+                if (angle_pos < para_pos) {
+                    start_pos = angle_pos + 1;
+                    end_pos = row.find('>');
+                } else if (para_pos != std::string::npos) {
+                    start_pos = para_pos + 1;
+                    end_pos = row.size() - 1;
+                }
+                if (start_pos == std::string::npos || end_pos == std::string::npos) {
+                    if ((start_pos = row.find('\"')) != std::string::npos) {
+                        end_pos = row.find('\"', start_pos + 1);
+                        ++start_pos;
+                    }
+                }
+            }
+            if (start_pos == std::string::npos || end_pos == std::string::npos) {
+                if ((start_pos = row.find(' ')) != std::string::npos) {
+                    std::vector<std::string> parameters = {"expression", "arguments", "identifier", "type name",
+                                                           "qualifier::name", "macro", "condition"};
+                    for (auto &parameter: parameters) {
+                        if ((start_pos = row.find(parameter, start_pos + 1)) != std::string::npos) {
+                            end_pos = start_pos + parameter.size();
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (start_pos != std::string::npos && end_pos != std::string::npos) {
+                int start_offset = CompletionDialog::get()->start_mark->get_iter().get_offset() + start_pos;
+                int end_offset = CompletionDialog::get()->start_mark->get_iter().get_offset() + end_pos;
+                auto size = get_buffer()->size();
+                if (start_offset != end_offset && start_offset < size && end_offset < size)
+                    get_buffer()->select_range(get_buffer()->get_iter_at_offset(start_offset),
+                                               get_buffer()->get_iter_at_offset(end_offset));
+            } else {
+                //new autocomplete after for instance when selecting "std::"
+                auto iter = get_buffer()->get_insert()->get_iter();
+                if (iter.backward_char() && *iter == ':') {
+                    autocomplete.run();
+                    return;
+                }
+            }
         }
-      }
-    }
-  };
-  
-  autocomplete.get_tooltip = [this](unsigned int index) {
-    return clangmm::to_string(clang_getCompletionBriefComment(completion_strings[index]));
-  };
+    };
+
+    autocomplete.get_tooltip = [this](unsigned int index) {
+        return clangmm::to_string(clang_getCompletionBriefComment(completion_strings[index]));
+    };
 }
 
 bool Source::ClangViewAutocomplete::is_possible_parameter() {
-  auto iter=get_buffer()->get_insert()->get_iter();
-  if(iter.backward_char() && (!interactive_completion || last_keyval=='(' || last_keyval==',' || last_keyval==' ' ||
-                              last_keyval==GDK_KEY_Return || last_keyval==GDK_KEY_KP_Enter)) {
-    while((*iter==' ' || *iter=='\t' || *iter=='\n' || *iter=='\r') && iter.backward_char()) {}
-    if(*iter=='(' || *iter==',')
-      return true;
-  }
-  return false;
+    auto iter = get_buffer()->get_insert()->get_iter();
+    if (iter.backward_char() &&
+        (!interactive_completion || last_keyval == '(' || last_keyval == ',' || last_keyval == ' ' ||
+         last_keyval == GDK_KEY_Return || last_keyval == GDK_KEY_KP_Enter)) {
+        while ((*iter == ' ' || *iter == '\t' || *iter == '\n' || *iter == '\r') && iter.backward_char()) {}
+        if (*iter == '(' || *iter == ',')
+            return true;
+    }
+    return false;
 }
 
 const std::unordered_map<std::string, std::string> &Source::ClangViewAutocomplete::autocomplete_manipulators_map() {
-  //TODO: feel free to add more
-  static std::unordered_map<std::string, std::string> map={
-    {"endl(basic_ostream<_CharT, _Traits> &__os)", "endl"},
-    {"flush(basic_ostream<_CharT, _Traits> &__os)", "flush"},
-    {"hex(std::ios_base &__str)", "hex"}, //clang++ headers
-    {"hex(std::ios_base &__base)", "hex"}, //g++ headers
-    {"dec(std::ios_base &__str)", "dec"},
-    {"dec(std::ios_base &__base)", "dec"}
-  };
-  return map;
+    //TODO: feel free to add more
+    static std::unordered_map<std::string, std::string> map = {
+            {"endl(basic_ostream<_CharT, _Traits> &__os)",  "endl"},
+            {"flush(basic_ostream<_CharT, _Traits> &__os)", "flush"},
+            {"hex(std::ios_base &__str)",                   "hex"}, //clang++ headers
+            {"hex(std::ios_base &__base)",                  "hex"}, //g++ headers
+            {"dec(std::ios_base &__str)",                   "dec"},
+            {"dec(std::ios_base &__base)",                  "dec"}
+    };
+    return map;
 }
 
 
-Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) :
-    BaseView(file_path, language), Source::ClangViewParse(file_path, language) {
-  similar_identifiers_tag=get_buffer()->create_tag();
-  similar_identifiers_tag->property_weight()=Pango::WEIGHT_ULTRAHEAVY;
-  
-  get_buffer()->signal_changed().connect([this]() {
-    if(last_tagged_identifier) {
-      for(auto &mark: similar_identifiers_marks) {
-        get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
-        get_buffer()->delete_mark(mark.first);
-        get_buffer()->delete_mark(mark.second);
-      }
-      similar_identifiers_marks.clear();
-      last_tagged_identifier=Identifier();
-    }
-  });
-  
-  get_token_spelling=[this]() {
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return std::string();
-    }
-    auto identifier=get_identifier();
-    if(identifier.spelling.empty() ||
-       identifier.spelling=="::" || identifier.spelling=="," || identifier.spelling=="=" ||
-       identifier.spelling=="(" || identifier.spelling==")" ||
-       identifier.spelling=="[" || identifier.spelling=="]") {
-      Info::get().print("No valid symbol found at current cursor location");
-      return std::string();
-    }
-    return identifier.spelling;
-  };
-  
-  rename_similar_tokens=[this](const std::string &text) {
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return;
-    }
-    auto identifier=get_identifier();
-    if(identifier) {
-      wait_parsing();
-      
-      std::vector<clangmm::TranslationUnit*> translation_units;
-      translation_units.emplace_back(clang_tu.get());
-      for(auto &view: views) {
-        if(view!=this) {
-          if(auto clang_view=dynamic_cast<Source::ClangView*>(view))
-            translation_units.emplace_back(clang_view->clang_tu.get());
+Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path,
+                                             Glib::RefPtr<Gsv::Language> language) :
+        BaseView(file_path, language), Source::ClangViewParse(file_path, language) {
+    similar_identifiers_tag = get_buffer()->create_tag();
+    similar_identifiers_tag->property_weight() = Pango::WEIGHT_ULTRAHEAVY;
+
+    get_buffer()->signal_changed().connect([this]() {
+        if (last_tagged_identifier) {
+            for (auto &mark: similar_identifiers_marks) {
+                get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
+                get_buffer()->delete_mark(mark.first);
+                get_buffer()->delete_mark(mark.second);
+            }
+            similar_identifiers_marks.clear();
+            last_tagged_identifier = Identifier();
         }
-      }
-      
-      auto build=Project::Build::create(this->file_path);
-      auto usages=Usages::Clang::get_usages(build->project_path, build->get_default_path(), build->get_debug_path(), identifier.spelling, identifier.cursor, translation_units);
-      
-      std::vector<Source::View*> renamed_views;
-      std::vector<Usages::Clang::Usages*> usages_renamed;
-      for(auto &usage: usages) {
-        size_t line_c=usage.lines.size()-1;
-        auto view_it=views.end();
-        for(auto it=views.begin();it!=views.end();++it) {
-          if((*it)->file_path==usage.path) {
-            view_it=it;
-            break;
-          }
+    });
+
+    get_token_spelling = [this]() {
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return std::string();
+        }
+        auto identifier = get_identifier();
+        if (identifier.spelling.empty() ||
+            identifier.spelling == "::" || identifier.spelling == "," || identifier.spelling == "=" ||
+            identifier.spelling == "(" || identifier.spelling == ")" ||
+            identifier.spelling == "[" || identifier.spelling == "]") {
+            Info::get().print("No valid symbol found at current cursor location");
+            return std::string();
         }
-        if(view_it!=views.end()) {
-          (*view_it)->get_buffer()->begin_user_action();
-          for(auto offset_it=usage.offsets.rbegin();offset_it!=usage.offsets.rend();++offset_it) {
-            auto start_iter=(*view_it)->get_buffer()->get_iter_at_line_index(offset_it->first.line-1, offset_it->first.index-1);
-            auto end_iter=(*view_it)->get_buffer()->get_iter_at_line_index(offset_it->second.line-1, offset_it->second.index-1);
-            (*view_it)->get_buffer()->erase(start_iter, end_iter);
-            start_iter=(*view_it)->get_buffer()->get_iter_at_line_index(offset_it->first.line-1, offset_it->first.index-1);
-            (*view_it)->get_buffer()->insert(start_iter, text);
-            if(offset_it->first.index-1<usage.lines[line_c].size())
-              usage.lines[line_c].replace(offset_it->first.index-1, offset_it->second.index-offset_it->first.index, text);
-            --line_c;
-          }
-          (*view_it)->get_buffer()->end_user_action();
-          (*view_it)->save();
-          renamed_views.emplace_back(*view_it);
-          usages_renamed.emplace_back(&usage);
+        return identifier.spelling;
+    };
+
+    rename_similar_tokens = [this](const std::string &text) {
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return;
         }
-        else {
-          std::string buffer;
-          {
-            std::ifstream stream(usage.path.string(), std::ifstream::binary);
-            if(stream)
-              buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
-          }
-          std::ofstream stream(usage.path.string(), std::ifstream::binary);
-          if(!buffer.empty() && stream) {
-            std::vector<size_t> lines_start_pos={0};
-            for(size_t c=0;c<buffer.size();++c) {
-              if(buffer[c]=='\n')
-                lines_start_pos.emplace_back(c+1);
+        auto identifier = get_identifier();
+        if (identifier) {
+            wait_parsing();
+
+            std::vector<clangmm::TranslationUnit *> translation_units;
+            translation_units.emplace_back(clang_tu.get());
+            for (auto &view: views) {
+                if (view != this) {
+                    if (auto clang_view = dynamic_cast<Source::ClangView *>(view))
+                        translation_units.emplace_back(clang_view->clang_tu.get());
+                }
             }
-            for(auto offset_it=usage.offsets.rbegin();offset_it!=usage.offsets.rend();++offset_it) {
-              auto start_line=offset_it->first.line-1;
-              auto end_line=offset_it->second.line-1;
-              if(start_line<lines_start_pos.size() && end_line<lines_start_pos.size()) {
-                auto start=lines_start_pos[start_line]+offset_it->first.index-1;
-                auto end=lines_start_pos[end_line]+offset_it->second.index-1;
-                if(start<buffer.size() && end<=buffer.size())
-                  buffer.replace(start, end-start, text);
-              }
-              if(offset_it->first.index-1<usage.lines[line_c].size())
-                usage.lines[line_c].replace(offset_it->first.index-1, offset_it->second.index-offset_it->first.index, text);
-              --line_c;
+
+            auto build = Project::Build::create(this->file_path);
+            auto usages = Usages::Clang::get_usages(build->project_path, build->get_default_path(),
+                                                    build->get_debug_path(), identifier.spelling, identifier.cursor,
+                                                    translation_units);
+
+            std::vector<Source::View *> renamed_views;
+            std::vector<Usages::Clang::Usages *> usages_renamed;
+            for (auto &usage: usages) {
+                size_t line_c = usage.lines.size() - 1;
+                auto view_it = views.end();
+                for (auto it = views.begin(); it != views.end(); ++it) {
+                    if ((*it)->file_path == usage.path) {
+                        view_it = it;
+                        break;
+                    }
+                }
+                if (view_it != views.end()) {
+                    (*view_it)->get_buffer()->begin_user_action();
+                    for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
+                        auto start_iter = (*view_it)->get_buffer()->get_iter_at_line_index(offset_it->first.line - 1,
+                                                                                           offset_it->first.index - 1);
+                        auto end_iter = (*view_it)->get_buffer()->get_iter_at_line_index(offset_it->second.line - 1,
+                                                                                         offset_it->second.index - 1);
+                        (*view_it)->get_buffer()->erase(start_iter, end_iter);
+                        start_iter = (*view_it)->get_buffer()->get_iter_at_line_index(offset_it->first.line - 1,
+                                                                                      offset_it->first.index - 1);
+                        (*view_it)->get_buffer()->insert(start_iter, text);
+                        if (offset_it->first.index - 1 < usage.lines[line_c].size())
+                            usage.lines[line_c].replace(offset_it->first.index - 1,
+                                                        offset_it->second.index - offset_it->first.index, text);
+                        --line_c;
+                    }
+                    (*view_it)->get_buffer()->end_user_action();
+                    (*view_it)->save();
+                    renamed_views.emplace_back(*view_it);
+                    usages_renamed.emplace_back(&usage);
+                } else {
+                    std::string buffer;
+                    {
+                        std::ifstream stream(usage.path.string(), std::ifstream::binary);
+                        if (stream)
+                            buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
+                    }
+                    std::ofstream stream(usage.path.string(), std::ifstream::binary);
+                    if (!buffer.empty() && stream) {
+                        std::vector<size_t> lines_start_pos = {0};
+                        for (size_t c = 0; c < buffer.size(); ++c) {
+                            if (buffer[c] == '\n')
+                                lines_start_pos.emplace_back(c + 1);
+                        }
+                        for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
+                            auto start_line = offset_it->first.line - 1;
+                            auto end_line = offset_it->second.line - 1;
+                            if (start_line < lines_start_pos.size() && end_line < lines_start_pos.size()) {
+                                auto start = lines_start_pos[start_line] + offset_it->first.index - 1;
+                                auto end = lines_start_pos[end_line] + offset_it->second.index - 1;
+                                if (start < buffer.size() && end <= buffer.size())
+                                    buffer.replace(start, end - start, text);
+                            }
+                            if (offset_it->first.index - 1 < usage.lines[line_c].size())
+                                usage.lines[line_c].replace(offset_it->first.index - 1,
+                                                            offset_it->second.index - offset_it->first.index, text);
+                            --line_c;
+                        }
+                        stream.write(buffer.data(), buffer.size());
+                        usages_renamed.emplace_back(&usage);
+                    } else
+                        Terminal::get().print("Error: could not write to file " + usage.path.string() + '\n', true);
+                }
+            }
+
+            if (!usages_renamed.empty()) {
+                Terminal::get().print("Renamed ");
+                Terminal::get().print(identifier.spelling, true);
+                Terminal::get().print(" to ");
+                Terminal::get().print(text, true);
+                Terminal::get().print(" at:\n");
             }
-            stream.write(buffer.data(), buffer.size());
-            usages_renamed.emplace_back(&usage);
-          }
-          else
-            Terminal::get().print("Error: could not write to file "+usage.path.string()+'\n', true);
+            for (auto &usage: usages_renamed) {
+                size_t line_c = 0;
+                for (auto &offset: usage->offsets) {
+                    Terminal::get().print(
+                            filesystem::get_short_path(usage->path).string() + ':' + std::to_string(offset.first.line) +
+                            ':' + std::to_string(offset.first.index) + ": ");
+                    auto &line = usage->lines[line_c];
+                    auto index = offset.first.index - 1;
+                    unsigned start = 0;
+                    for (auto &chr: line) {
+                        if (chr != ' ' && chr != '\t')
+                            break;
+                        ++start;
+                    }
+                    if (start < line.size() && index + text.size() < line.size()) {
+                        Terminal::get().print(line.substr(start, index - start));
+                        Terminal::get().print(line.substr(index, text.size()), true);
+                        Terminal::get().print(line.substr(index + text.size()));
+                    }
+                    Terminal::get().print("\n");
+                    ++line_c;
+                }
+            }
+
+            for (auto &view: renamed_views)
+                view->soft_reparse_needed = false;
         }
-      }
-      
-      if(!usages_renamed.empty()) {
-        Terminal::get().print("Renamed ");
-        Terminal::get().print(identifier.spelling, true);
-        Terminal::get().print(" to ");
-        Terminal::get().print(text, true);
-        Terminal::get().print(" at:\n");
-      }
-      for(auto &usage: usages_renamed) {
-        size_t line_c=0;
-        for(auto &offset: usage->offsets) {
-          Terminal::get().print(filesystem::get_short_path(usage->path).string()+':'+std::to_string(offset.first.line)+':'+std::to_string(offset.first.index)+": ");
-          auto &line=usage->lines[line_c];
-          auto index=offset.first.index-1;
-          unsigned start=0;
-          for(auto &chr: line) {
-            if(chr!=' ' && chr!='\t')
-              break;
-            ++start;
-          }
-          if(start<line.size() && index+text.size()<line.size()) {
-            Terminal::get().print(line.substr(start, index-start));
-            Terminal::get().print(line.substr(index, text.size()), true);
-            Terminal::get().print(line.substr(index+text.size()));
-          }
-          Terminal::get().print("\n");
-          ++line_c;
+    };
+
+    get_buffer()->signal_mark_set().connect(
+            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+                if (mark->get_name() == "insert") {
+                    delayed_tag_similar_identifiers_connection.disconnect();
+                    delayed_tag_similar_identifiers_connection = Glib::signal_timeout().connect([this]() {
+                        auto identifier = get_identifier();
+                        tag_similar_identifiers(identifier);
+                        return false;
+                    }, 100);
+                }
+            });
+
+    auto declaration_location = [this]() {
+        auto identifier = get_identifier();
+        if (identifier) {
+            auto source_location = identifier.cursor.get_canonical().get_source_location();
+            auto offset = source_location.get_offset();
+            return Offset(offset.line - 1, offset.index - 1, source_location.get_path());
+        } else {
+            // If cursor is at an include line, return offset to included file
+            const static std::regex include_regex("^[ \t]*#[ \t]*include[ \t]*[<\"]([^<>\"]+)[>\"].*$");
+            std::smatch sm;
+            auto line = get_line();
+            if (std::regex_match(line, sm, include_regex)) {
+                struct ClientData {
+                    boost::filesystem::path &file_path;
+                    std::string found_include;
+                    int line_nr;
+                    std::string sm_str;
+                };
+                ClientData client_data{this->file_path, std::string(),
+                                       get_buffer()->get_insert()->get_iter().get_line(), sm[1].str()};
+
+                // Attempt to find the 100% correct include file first
+                clang_getInclusions(clang_tu->cx_tu,
+                                    [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len,
+                                       CXClientData client_data_) {
+                                        auto client_data = static_cast<ClientData *>(client_data_);
+                                        if (client_data->found_include.empty() && include_len > 0) {
+                                            auto source_location = clangmm::SourceLocation(inclusion_stack[0]);
+                                            if (static_cast<int>(source_location.get_offset().line) - 1 ==
+                                                client_data->line_nr &&
+                                                filesystem::get_normal_path(source_location.get_path()) ==
+                                                client_data->file_path)
+                                                client_data->found_include = clangmm::to_string(
+                                                        clang_getFileName(included_file));
+                                        }
+                                    }, &client_data);
+
+                if (!client_data.found_include.empty())
+                    return Offset(0, 0, client_data.found_include);
+
+                // Find a matching include file if no include was found previously
+                clang_getInclusions(clang_tu->cx_tu,
+                                    [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len,
+                                       CXClientData client_data_) {
+                                        auto client_data = static_cast<ClientData *>(client_data_);
+                                        if (client_data->found_include.empty()) {
+                                            for (unsigned c = 1; c < include_len; ++c) {
+                                                auto source_location = clangmm::SourceLocation(inclusion_stack[c]);
+                                                if (static_cast<int>(source_location.get_offset().line) - 1 <=
+                                                    client_data->line_nr &&
+                                                    filesystem::get_normal_path(source_location.get_path()) ==
+                                                    client_data->file_path) {
+                                                    auto included_file_str = clangmm::to_string(
+                                                            clang_getFileName(included_file));
+                                                    if (included_file_str.size() >= client_data->sm_str.size() &&
+                                                        included_file_str.compare(
+                                                                included_file_str.size() - client_data->sm_str.size(),
+                                                                client_data->sm_str.size(), client_data->sm_str) == 0) {
+                                                        client_data->found_include = included_file_str;
+                                                        break;
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }, &client_data);
+
+                if (!client_data.found_include.empty())
+                    return Offset(0, 0, client_data.found_include);
+            }
         }
-      }
-      
-      for(auto &view: renamed_views)
-        view->soft_reparse_needed=false;
-    }
-  };
-  
-  get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark){
-    if(mark->get_name()=="insert") {
-      delayed_tag_similar_symbols_connection.disconnect();
-      delayed_tag_similar_symbols_connection=Glib::signal_timeout().connect([this]() {
-        auto identifier=get_identifier();
-        tag_similar_identifiers(identifier);
-        return false;
-      }, 100);
-    }
-  });
-    
-  auto declaration_location=[this]() {
-    auto identifier=get_identifier();
-    if(identifier) {
-      auto source_location=identifier.cursor.get_canonical().get_source_location();
-      auto offset=source_location.get_offset();
-      return Offset(offset.line-1, offset.index-1, source_location.get_path());
-    }
-    else {
-      // If cursor is at an include line, return offset to included file
-      const static std::regex include_regex("^[ \t]*#[ \t]*include[ \t]*[<\"]([^<>\"]+)[>\"].*$");
-      std::smatch sm;
-      auto line=get_line();
-      if(std::regex_match(line, sm, include_regex)) {
-        struct ClientData {
-          boost::filesystem::path &file_path;
-          std::string found_include;
-          int line_nr;
-          std::string sm_str;
-        };
-        ClientData client_data{this->file_path, std::string(), get_buffer()->get_insert()->get_iter().get_line(), sm[1].str()};
-        
-        // Attempt to find the 100% correct include file first
-        clang_getInclusions(clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) {
-          auto client_data=static_cast<ClientData*>(client_data_);
-          if(client_data->found_include.empty() && include_len>0) {
-            auto source_location=clangmm::SourceLocation(inclusion_stack[0]);
-            if(static_cast<int>(source_location.get_offset().line)-1==client_data->line_nr &&
-               filesystem::get_normal_path(source_location.get_path())==client_data->file_path)
-              client_data->found_include=clangmm::to_string(clang_getFileName(included_file));
-          }
-        }, &client_data);
-        
-        if(!client_data.found_include.empty())
-          return Offset(0, 0, client_data.found_include);
-        
-        // Find a matching include file if no include was found previously
-        clang_getInclusions(clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) {
-          auto client_data=static_cast<ClientData*>(client_data_);
-          if(client_data->found_include.empty()) {
-            for(unsigned c=1;c<include_len;++c) {
-              auto source_location=clangmm::SourceLocation(inclusion_stack[c]);
-              if(static_cast<int>(source_location.get_offset().line)-1<=client_data->line_nr &&
-                 filesystem::get_normal_path(source_location.get_path())==client_data->file_path) {
-                auto included_file_str=clangmm::to_string(clang_getFileName(included_file));
-                if(included_file_str.size()>=client_data->sm_str.size() &&
-                   included_file_str.compare(included_file_str.size()-client_data->sm_str.size(), client_data->sm_str.size(), client_data->sm_str)==0) {
-                  client_data->found_include=included_file_str;
-                  break;
+        return Offset();
+    };
+
+    get_declaration_location = [this, declaration_location]() {
+        if (!parsed) {
+            if (selected_completion_string) {
+                auto completion_cursor = clangmm::CompletionString(selected_completion_string).get_cursor(
+                        clang_tu->cx_tu);
+                if (completion_cursor) {
+                    auto source_location = completion_cursor.get_source_location();
+                    auto source_location_offset = source_location.get_offset();
+                    if (CompletionDialog::get())
+                        CompletionDialog::get()->hide();
+                    auto offset = Offset(source_location_offset.line - 1, source_location_offset.index - 1,
+                                         source_location.get_path());
+
+                    // Workaround for bug in ArchLinux's clang_getFileName()
+                    // TODO: remove the workaround when this is fixed
+                    auto include_path = filesystem::get_normal_path(offset.file_path);
+                    boost::system::error_code ec;
+                    if (!boost::filesystem::exists(include_path, ec))
+                        offset.file_path = "/usr/include" / include_path;
+
+                    return offset;
+                } else {
+                    Info::get().print("No declaration found");
+                    return Offset();
                 }
-              }
             }
-          }
-        }, &client_data);
-        
-        if(!client_data.found_include.empty())
-          return Offset(0, 0, client_data.found_include);
-      }
-    }
-    return Offset();
-  };
-  
-  get_declaration_location=[this, declaration_location](){
-    if(!parsed) {
-      if(selected_completion_string) {
-        auto completion_cursor=clangmm::CompletionString(selected_completion_string).get_cursor(clang_tu->cx_tu);
-        if(completion_cursor) {
-          auto source_location=completion_cursor.get_source_location();
-          auto source_location_offset=source_location.get_offset();
-          if(CompletionDialog::get())
-            CompletionDialog::get()->hide();
-          auto offset=Offset(source_location_offset.line-1, source_location_offset.index-1, source_location.get_path());
-          
-          // Workaround for bug in ArchLinux's clang_getFileName()
-          // TODO: remove the workaround when this is fixed
-          auto include_path=filesystem::get_normal_path(offset.file_path);
-          boost::system::error_code ec;
-          if(!boost::filesystem::exists(include_path, ec))
-            offset.file_path="/usr/include"/include_path;
-          
-          return offset;
+
+            Info::get().print("Buffer is parsing");
+            return Offset();
         }
-        else {
-          Info::get().print("No declaration found");
-          return Offset();
+        auto offset = declaration_location();
+        if (!offset)
+            Info::get().print("No declaration found");
+
+        // Workaround for bug in ArchLinux's clang_getFileName()
+        // TODO: remove the workaround when this is fixed
+        auto include_path = filesystem::get_normal_path(offset.file_path);
+        boost::system::error_code ec;
+        if (!boost::filesystem::exists(include_path, ec))
+            offset.file_path = "/usr/include" / include_path;
+
+        return offset;
+    };
+
+    get_type_declaration_location = [this]() {
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return Offset();
         }
-      }
-      
-      Info::get().print("Buffer is parsing");
-      return Offset();
-    }
-    auto offset=declaration_location();
-    if(!offset)
-      Info::get().print("No declaration found");
-    
-    // Workaround for bug in ArchLinux's clang_getFileName()
-    // TODO: remove the workaround when this is fixed
-    auto include_path=filesystem::get_normal_path(offset.file_path);
-    boost::system::error_code ec;
-    if(!boost::filesystem::exists(include_path, ec))
-      offset.file_path="/usr/include"/include_path;
-    
-    return offset;
-  };
-  
-  get_type_declaration_location=[this](){
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return Offset();
-    }
-    auto identifier=get_identifier();
-    if(identifier) {
-      auto type_cursor=identifier.cursor.get_type().get_cursor();
-      if(type_cursor) {
-        auto source_location=type_cursor.get_source_location();
-        auto path=source_location.get_path();
-        if(!path.empty()) {
-          auto source_location_offset=source_location.get_offset();
-          auto offset=Offset(source_location_offset.line-1, source_location_offset.index-1, path);
-          
-          // Workaround for bug in ArchLinux's clang_getFileName()
-          // TODO: remove the workaround when this is fixed
-          auto include_path=filesystem::get_normal_path(offset.file_path);
-          boost::system::error_code ec;
-          if(!boost::filesystem::exists(include_path, ec))
-            offset.file_path="/usr/include"/include_path;
-          
-          return offset;
+        auto identifier = get_identifier();
+        if (identifier) {
+            auto type_cursor = identifier.cursor.get_type().get_cursor();
+            if (type_cursor) {
+                auto source_location = type_cursor.get_source_location();
+                auto path = source_location.get_path();
+                if (!path.empty()) {
+                    auto source_location_offset = source_location.get_offset();
+                    auto offset = Offset(source_location_offset.line - 1, source_location_offset.index - 1, path);
+
+                    // Workaround for bug in ArchLinux's clang_getFileName()
+                    // TODO: remove the workaround when this is fixed
+                    auto include_path = filesystem::get_normal_path(offset.file_path);
+                    boost::system::error_code ec;
+                    if (!boost::filesystem::exists(include_path, ec))
+                        offset.file_path = "/usr/include" / include_path;
+
+                    return offset;
+                }
+            }
         }
-      }
-    }
-    Info::get().print("No type declaration found");
-    return Offset();
-  };
-  
-  auto implementation_locations=[this](const Identifier &identifier) {
-    std::vector<Offset> offsets;
-    if(identifier) {
-      wait_parsing();
-      
-      //First, look for a definition cursor that is equal
-      auto identifier_usr=identifier.cursor.get_usr();
-      for(auto &view: views) {
-        if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
-          for(auto &token: *clang_view->clang_tokens) {
-            auto cursor=token.get_cursor();
-            auto cursor_kind=cursor.get_kind();
-            if((cursor_kind==clangmm::Cursor::Kind::FunctionDecl || cursor_kind==clangmm::Cursor::Kind::CXXMethod ||
-                cursor_kind==clangmm::Cursor::Kind::Constructor || cursor_kind==clangmm::Cursor::Kind::Destructor ||
-                cursor_kind==clangmm::Cursor::Kind::FunctionTemplate || cursor_kind==clangmm::Cursor::Kind::ConversionFunction) &&
-               token.is_identifier()) {
-              auto token_spelling=token.get_spelling();
-              if(identifier.kind==cursor.get_kind() && identifier.spelling==token_spelling && identifier_usr==cursor.get_usr()) {
-                if(clang_isCursorDefinition(cursor.cx_cursor)) {
-                  Offset offset;
-                  auto location=cursor.get_source_location();
-                  auto clang_offset=location.get_offset();
-                  offset.file_path=location.get_path();
-                  offset.line=clang_offset.line-1;
-                  offset.index=clang_offset.index-1;
-                  offsets.emplace_back(offset);
+        Info::get().print("No type declaration found");
+        return Offset();
+    };
+
+    auto implementation_locations = [this](const Identifier &identifier) {
+        std::vector<Offset> offsets;
+        if (identifier) {
+            wait_parsing();
+
+            //First, look for a definition cursor that is equal
+            auto identifier_usr = identifier.cursor.get_usr();
+            for (auto &view: views) {
+                if (auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
+                    for (auto &token: *clang_view->clang_tokens) {
+                        auto cursor = token.get_cursor();
+                        auto cursor_kind = cursor.get_kind();
+                        if ((cursor_kind == clangmm::Cursor::Kind::FunctionDecl ||
+                             cursor_kind == clangmm::Cursor::Kind::CXXMethod ||
+                             cursor_kind == clangmm::Cursor::Kind::Constructor ||
+                             cursor_kind == clangmm::Cursor::Kind::Destructor ||
+                             cursor_kind == clangmm::Cursor::Kind::FunctionTemplate ||
+                             cursor_kind == clangmm::Cursor::Kind::ConversionFunction) &&
+                            token.is_identifier()) {
+                            auto token_spelling = token.get_spelling();
+                            if (identifier.kind == cursor.get_kind() && identifier.spelling == token_spelling &&
+                                identifier_usr == cursor.get_usr()) {
+                                if (clang_isCursorDefinition(cursor.cx_cursor)) {
+                                    Offset offset;
+                                    auto location = cursor.get_source_location();
+                                    auto clang_offset = location.get_offset();
+                                    offset.file_path = location.get_path();
+                                    offset.line = clang_offset.line - 1;
+                                    offset.index = clang_offset.index - 1;
+                                    offsets.emplace_back(offset);
+                                }
+                            }
+                        }
+                    }
                 }
-              }
             }
-          }
+            if (!offsets.empty())
+                return offsets;
+
+            //If no implementation was found, try using clang_getCursorDefinition
+            auto definition = identifier.cursor.get_definition();
+            if (definition) {
+                auto location = definition.get_source_location();
+                Offset offset;
+                offset.file_path = location.get_path();
+                auto clang_offset = location.get_offset();
+                offset.line = clang_offset.line - 1;
+                offset.index = clang_offset.index - 1;
+                offsets.emplace_back(offset);
+                return offsets;
+            }
+
+            //If no implementation was found, use declaration if it is a function template
+            auto canonical = identifier.cursor.get_canonical();
+            auto cursor = clang_tu->get_cursor(canonical.get_source_location());
+            if (cursor && cursor.get_kind() == clangmm::Cursor::Kind::FunctionTemplate) {
+                auto location = cursor.get_source_location();
+                Offset offset;
+                offset.file_path = location.get_path();
+                auto clang_offset = location.get_offset();
+                offset.line = clang_offset.line - 1;
+                offset.index = clang_offset.index - 1;
+                offsets.emplace_back(offset);
+                return offsets;
+            }
+
+            //If no implementation was found, try using Ctags
+            auto name = identifier.cursor.get_spelling();
+            auto parent = identifier.cursor.get_semantic_parent();
+            while (parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {
+                auto spelling = parent.get_spelling() + "::";
+                name.insert(0, spelling);
+                parent = parent.get_semantic_parent();
+            }
+            auto ctags_locations = Ctags::get_locations(this->file_path, name,
+                                                        identifier.cursor.get_type_description());
+            if (!ctags_locations.empty()) {
+                for (auto &ctags_location: ctags_locations) {
+                    Offset offset;
+                    offset.file_path = ctags_location.file_path;
+                    offset.line = ctags_location.line;
+                    offset.index = ctags_location.index;
+                    offsets.emplace_back(offset);
+                }
+                return offsets;
+            }
         }
-      }
-      if(!offsets.empty())
-        return offsets;
-      
-      //If no implementation was found, try using clang_getCursorDefinition
-      auto definition=identifier.cursor.get_definition();
-      if(definition) {
-        auto location=definition.get_source_location();
-        Offset offset;
-        offset.file_path=location.get_path();
-        auto clang_offset=location.get_offset();
-        offset.line=clang_offset.line-1;
-        offset.index=clang_offset.index-1;
-        offsets.emplace_back(offset);
-        return offsets;
-      }
-      
-      //If no implementation was found, use declaration if it is a function template
-      auto canonical=identifier.cursor.get_canonical();
-      auto cursor=clang_tu->get_cursor(canonical.get_source_location());
-      if(cursor && cursor.get_kind()==clangmm::Cursor::Kind::FunctionTemplate) {
-        auto location=cursor.get_source_location();
-        Offset offset;
-        offset.file_path=location.get_path();
-        auto clang_offset=location.get_offset();
-        offset.line=clang_offset.line-1;
-        offset.index=clang_offset.index-1;
-        offsets.emplace_back(offset);
         return offsets;
-      }
-      
-      //If no implementation was found, try using Ctags
-      auto name=identifier.cursor.get_spelling();
-      auto parent=identifier.cursor.get_semantic_parent();
-      while(parent && parent.get_kind()!=clangmm::Cursor::Kind::TranslationUnit) {
-        auto spelling=parent.get_spelling()+"::";
-        name.insert(0, spelling);
-        parent=parent.get_semantic_parent();
-      }
-      auto ctags_locations=Ctags::get_locations(this->file_path, name, identifier.cursor.get_type_description());
-      if(!ctags_locations.empty()) {
-        for(auto &ctags_location: ctags_locations) {
-          Offset offset;
-          offset.file_path=ctags_location.file_path;
-          offset.line=ctags_location.line;
-          offset.index=ctags_location.index;
-          offsets.emplace_back(offset);
+    };
+
+    get_implementation_locations = [this, implementation_locations]() {
+        if (!parsed) {
+            if (selected_completion_string) {
+                auto completion_cursor = clangmm::CompletionString(selected_completion_string).get_cursor(
+                        clang_tu->cx_tu);
+                if (completion_cursor) {
+                    auto offsets = implementation_locations(
+                            Identifier(completion_cursor.get_token_spelling(), completion_cursor));
+                    if (offsets.empty()) {
+                        Info::get().print("No implementation found");
+                        return std::vector<Offset>();
+                    }
+                    if (CompletionDialog::get())
+                        CompletionDialog::get()->hide();
+
+                    // Workaround for bug in ArchLinux's clang_getFileName()
+                    // TODO: remove the workaround when this is fixed
+                    for (auto &offset: offsets) {
+                        auto include_path = filesystem::get_normal_path(offset.file_path);
+                        boost::system::error_code ec;
+                        if (!boost::filesystem::exists(include_path, ec))
+                            offset.file_path = "/usr/include" / include_path;
+                    }
+
+                    return offsets;
+                } else {
+                    Info::get().print("No implementation found");
+                    return std::vector<Offset>();
+                }
+            }
+
+            Info::get().print("Buffer is parsing");
+            return std::vector<Offset>();
         }
-        return offsets;
-      }
-    }
-    return offsets;
-  };
-  
-  get_implementation_locations=[this, implementation_locations](){
-    if(!parsed) {
-      if(selected_completion_string) {
-        auto completion_cursor=clangmm::CompletionString(selected_completion_string).get_cursor(clang_tu->cx_tu);
-        if(completion_cursor) {
-          auto offsets=implementation_locations(Identifier(completion_cursor.get_token_spelling(), completion_cursor));
-          if(offsets.empty()) {
+        auto offsets = implementation_locations(get_identifier());
+        if (offsets.empty())
             Info::get().print("No implementation found");
-            return std::vector<Offset>();
-          }
-          if(CompletionDialog::get())
-            CompletionDialog::get()->hide();
-          
-          // Workaround for bug in ArchLinux's clang_getFileName()
-          // TODO: remove the workaround when this is fixed
-          for(auto &offset: offsets) {
-            auto include_path=filesystem::get_normal_path(offset.file_path);
+
+        // Workaround for bug in ArchLinux's clang_getFileName()
+        // TODO: remove the workaround when this is fixed
+        for (auto &offset: offsets) {
+            auto include_path = filesystem::get_normal_path(offset.file_path);
             boost::system::error_code ec;
-            if(!boost::filesystem::exists(include_path, ec))
-              offset.file_path="/usr/include"/include_path;
-          }
-          
-          return offsets;
+            if (!boost::filesystem::exists(include_path, ec))
+                offset.file_path = "/usr/include" / include_path;
         }
-        else {
-          Info::get().print("No implementation found");
-          return std::vector<Offset>();
+
+        return offsets;
+    };
+
+    get_declaration_or_implementation_locations = [this, declaration_location, implementation_locations]() {
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return std::vector<Offset>();
         }
-      }
-      
-      Info::get().print("Buffer is parsing");
-      return std::vector<Offset>();
-    }
-    auto offsets=implementation_locations(get_identifier());
-    if(offsets.empty())
-      Info::get().print("No implementation found");
-    
-    // Workaround for bug in ArchLinux's clang_getFileName()
-    // TODO: remove the workaround when this is fixed
-    for(auto &offset: offsets) {
-      auto include_path=filesystem::get_normal_path(offset.file_path);
-      boost::system::error_code ec;
-      if(!boost::filesystem::exists(include_path, ec))
-        offset.file_path="/usr/include"/include_path;
-    }
-    
-    return offsets;
-  };
-  
-  get_declaration_or_implementation_locations=[this, declaration_location, implementation_locations]() {
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return std::vector<Offset>();
-    }
-    
-    std::vector<Offset> offsets;
-    
-    bool is_implementation=false;
-    auto iter=get_buffer()->get_insert()->get_iter();
-    auto line=static_cast<unsigned>(iter.get_line());
-    auto index=static_cast<unsigned>(iter.get_line_index());
-    for(size_t c=0;c<clang_tokens->size();++c) {
-      auto &token=(*clang_tokens)[c];
-      if(token.is_identifier()) {
-        auto &token_offsets=clang_tokens_offsets[c];
-        if(line==token_offsets.first.line-1 && index>=token_offsets.first.index-1 && index<=token_offsets.second.index-1) {
-          if(clang_isCursorDefinition(token.get_cursor().cx_cursor)>0)
-            is_implementation=true;
-          break;
+
+        std::vector<Offset> offsets;
+
+        bool is_implementation = false;
+        auto iter = get_buffer()->get_insert()->get_iter();
+        auto line = static_cast<unsigned>(iter.get_line());
+        auto index = static_cast<unsigned>(iter.get_line_index());
+        for (size_t c = 0; c < clang_tokens->size(); ++c) {
+            auto &token = (*clang_tokens)[c];
+            if (token.is_identifier()) {
+                auto &token_offsets = clang_tokens_offsets[c];
+                if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
+                    index <= token_offsets.second.index - 1) {
+                    if (clang_isCursorDefinition(token.get_cursor().cx_cursor) > 0)
+                        is_implementation = true;
+                    break;
+                }
+            }
         }
-      }
-    }
-    // If cursor is at implementation, return declaration_location
-    if(is_implementation) {
-      auto offset=declaration_location();
-      if(offset)
-        offsets.emplace_back(offset);
-    }
-    else {
-      auto implementation_offsets=implementation_locations(get_identifier());
-      if(!implementation_offsets.empty()) {
-        offsets=std::move(implementation_offsets);
-      }
-      else {
-        auto offset=declaration_location();
-        if(offset)
-          offsets.emplace_back(offset);
-      }
-    }
-    
-    if(offsets.empty())
-      Info::get().print("No declaration or implementation found");
-    
-    // Workaround for bug in ArchLinux's clang_getFileName()
-    // TODO: remove the workaround when this is fixed
-    for(auto &offset: offsets) {
-      auto include_path=filesystem::get_normal_path(offset.file_path);
-      boost::system::error_code ec;
-      if(!boost::filesystem::exists(include_path, ec))
-        offset.file_path="/usr/include"/include_path;
-    }
-    
-    return offsets;
-  };
-  
-  get_usages=[this]() {
-    std::vector<std::pair<Offset, std::string> > usages;
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return usages;
-    }
-    auto identifier=get_identifier();
-    if(identifier) {
-      wait_parsing();
-      
-      auto embolden_token=[](std::string &line, unsigned token_start_pos, unsigned token_end_pos) {
-        //markup token as bold
-        size_t pos=0;
-        while((pos=line.find('&', pos))!=std::string::npos) {
-          size_t pos2=line.find(';', pos+2);
-          if(token_start_pos>pos) {
-            token_start_pos+=pos2-pos;
-            token_end_pos+=pos2-pos;
-          }
-          else if(token_end_pos>pos)
-            token_end_pos+=pos2-pos;
-          else
-            break;
-          pos=pos2+1;
+        // If cursor is at implementation, return declaration_location
+        if (is_implementation) {
+            auto offset = declaration_location();
+            if (offset)
+                offsets.emplace_back(offset);
+        } else {
+            auto implementation_offsets = implementation_locations(get_identifier());
+            if (!implementation_offsets.empty()) {
+                offsets = std::move(implementation_offsets);
+            } else {
+                auto offset = declaration_location();
+                if (offset)
+                    offsets.emplace_back(offset);
+            }
         }
-        line.insert(token_end_pos, "</b>");
-        line.insert(token_start_pos, "<b>");
-        
-        size_t start_pos=0;
-        while(start_pos<line.size() && (line[start_pos]==' ' || line[start_pos]=='\t'))
-          ++start_pos;
-        if(start_pos>0)
-          line.erase(0, start_pos);
-      };
-      
-      std::vector<clangmm::TranslationUnit*> translation_units;
-      translation_units.emplace_back(clang_tu.get());
-      for(auto &view: views) {
-        if(view!=this) {
-          if(auto clang_view=dynamic_cast<Source::ClangView*>(view))
-            translation_units.emplace_back(clang_view->clang_tu.get());
+
+        if (offsets.empty())
+            Info::get().print("No declaration or implementation found");
+
+        // Workaround for bug in ArchLinux's clang_getFileName()
+        // TODO: remove the workaround when this is fixed
+        for (auto &offset: offsets) {
+            auto include_path = filesystem::get_normal_path(offset.file_path);
+            boost::system::error_code ec;
+            if (!boost::filesystem::exists(include_path, ec))
+                offset.file_path = "/usr/include" / include_path;
         }
-      }
-      
-      auto build=Project::Build::create(this->file_path);
-      auto usages_clang=Usages::Clang::get_usages(build->project_path, build->get_default_path(), build->get_debug_path(), {identifier.spelling}, {identifier.cursor}, translation_units);
-      for(auto &usage: usages_clang) {
-        for(size_t c=0;c<usage.offsets.size();++c) {
-          std::string line=Glib::Markup::escape_text(usage.lines[c]);
-          embolden_token(line, usage.offsets[c].first.index-1, usage.offsets[c].second.index-1);
-          usages.emplace_back(Offset(usage.offsets[c].first.line-1, usage.offsets[c].first.index-1, usage.path), line);
+
+        return offsets;
+    };
+
+    get_usages = [this]() {
+        std::vector<std::pair<Offset, std::string> > usages;
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return usages;
         }
-      }
-    }
-    
-    if(usages.empty())
-      Info::get().print("No symbol found at current cursor location");
-    return usages;
-  };
-  
-  get_method=[this] {
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return std::string();
-    }
-    auto iter=get_buffer()->get_insert()->get_iter();
-    auto line=static_cast<unsigned>(iter.get_line());
-    auto index=static_cast<unsigned>(iter.get_line_index());
-    for(size_t c=clang_tokens->size()-1;c!=static_cast<size_t>(-1);--c) {
-      auto &token=(*clang_tokens)[c];
-      if(token.is_identifier()) {
-        auto &token_offsets=clang_tokens_offsets[c];
-        if(line==token_offsets.first.line-1 && index>=token_offsets.first.index-1 && index<=token_offsets.second.index-1) {
-          auto token_spelling=token.get_spelling();
-          if(!token_spelling.empty() &&
-             (token_spelling.size()>1 || (token_spelling.back()>='a' && token_spelling.back()<='z') ||
-              (token_spelling.back()>='A' && token_spelling.back()<='Z') ||
-              token_spelling.back()=='_')) {
-            auto cursor=token.get_cursor();
-            auto kind=cursor.get_kind();
-            if(kind==clangmm::Cursor::Kind::FunctionDecl || kind==clangmm::Cursor::Kind::CXXMethod ||
-               kind==clangmm::Cursor::Kind::Constructor || kind==clangmm::Cursor::Kind::Destructor ||
-               kind==clangmm::Cursor::Kind::ConversionFunction) {
-              auto referenced=cursor.get_referenced();
-              if(referenced && referenced==cursor) {
-                std::string result;
-                std::string specifier;
-                if(kind==clangmm::Cursor::Kind::FunctionDecl || kind==clangmm::Cursor::Kind::CXXMethod) {
-                  auto start_offset=cursor.get_source_range().get_start().get_offset();
-                  auto end_offset=token_offsets.first;
-                  
-                  // To accurately get result type with needed namespace and class/struct names:
-                  int angle_brackets=0;
-                  for(size_t c=0;c<clang_tokens->size();++c) {
-                    auto &token=(*clang_tokens)[c];
-                    auto &token_offsets=clang_tokens_offsets[c];
-                    if((token_offsets.first.line==start_offset.line && token_offsets.second.line!=end_offset.line && token_offsets.first.index>=start_offset.index) ||
-                       (token_offsets.first.line>start_offset.line && token_offsets.second.line<end_offset.line) ||
-                       (token_offsets.first.line!=start_offset.line && token_offsets.second.line==end_offset.line && token_offsets.second.index<=end_offset.index) ||
-                       (token_offsets.first.line==start_offset.line && token_offsets.second.line==end_offset.line &&
-                        token_offsets.first.index>=start_offset.index && token_offsets.second.index<=end_offset.index)) {                     
-                      auto token_spelling=token.get_spelling();
-                      if(token.get_kind()==clangmm::Token::Kind::Identifier) {
-                        if(c==0 || (*clang_tokens)[c-1].get_spelling()!="::") {
-                          auto name=token_spelling;
-                          auto parent=token.get_cursor().get_type().get_cursor().get_semantic_parent();
-                          while(parent && parent.get_kind()!=clangmm::Cursor::Kind::TranslationUnit) {
-                            auto spelling=parent.get_token_spelling();
-                            name.insert(0, spelling+"::");
-                            parent=parent.get_semantic_parent();
-                          }
-                          result+=name;
+        auto identifier = get_identifier();
+        if (identifier) {
+            wait_parsing();
+
+            auto embolden_token = [](std::string &line, unsigned token_start_pos, unsigned token_end_pos) {
+                //markup token as bold
+                size_t pos = 0;
+                while ((pos = line.find('&', pos)) != std::string::npos) {
+                    size_t pos2 = line.find(';', pos + 2);
+                    if (token_start_pos > pos) {
+                        token_start_pos += pos2 - pos;
+                        token_end_pos += pos2 - pos;
+                    } else if (token_end_pos > pos)
+                        token_end_pos += pos2 - pos;
+                    else
+                        break;
+                    pos = pos2 + 1;
+                }
+                line.insert(token_end_pos, "</b>");
+                line.insert(token_start_pos, "<b>");
+
+                size_t start_pos = 0;
+                while (start_pos < line.size() && (line[start_pos] == ' ' || line[start_pos] == '\t'))
+                    ++start_pos;
+                if (start_pos > 0)
+                    line.erase(0, start_pos);
+            };
+
+            std::vector<clangmm::TranslationUnit *> translation_units;
+            translation_units.emplace_back(clang_tu.get());
+            for (auto &view: views) {
+                if (view != this) {
+                    if (auto clang_view = dynamic_cast<Source::ClangView *>(view))
+                        translation_units.emplace_back(clang_view->clang_tu.get());
+                }
+            }
+
+            auto build = Project::Build::create(this->file_path);
+            auto usages_clang = Usages::Clang::get_usages(build->project_path, build->get_default_path(),
+                                                          build->get_debug_path(), {identifier.spelling},
+                                                          {identifier.cursor}, translation_units);
+            for (auto &usage: usages_clang) {
+                for (size_t c = 0; c < usage.offsets.size(); ++c) {
+                    std::string line = Glib::Markup::escape_text(usage.lines[c]);
+                    embolden_token(line, usage.offsets[c].first.index - 1, usage.offsets[c].second.index - 1);
+                    usages.emplace_back(
+                            Offset(usage.offsets[c].first.line - 1, usage.offsets[c].first.index - 1, usage.path),
+                            line);
+                }
+            }
+        }
+
+        if (usages.empty())
+            Info::get().print("No symbol found at current cursor location");
+        return usages;
+    };
+
+    get_method = [this] {
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return std::string();
+        }
+        auto iter = get_buffer()->get_insert()->get_iter();
+        auto line = static_cast<unsigned>(iter.get_line());
+        auto index = static_cast<unsigned>(iter.get_line_index());
+        for (size_t c = clang_tokens->size() - 1; c != static_cast<size_t>(-1); --c) {
+            auto &token = (*clang_tokens)[c];
+            if (token.is_identifier()) {
+                auto &token_offsets = clang_tokens_offsets[c];
+                if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
+                    index <= token_offsets.second.index - 1) {
+                    auto token_spelling = token.get_spelling();
+                    if (!token_spelling.empty() &&
+                        (token_spelling.size() > 1 || (token_spelling.back() >= 'a' && token_spelling.back() <= 'z') ||
+                         (token_spelling.back() >= 'A' && token_spelling.back() <= 'Z') ||
+                         token_spelling.back() == '_')) {
+                        auto cursor = token.get_cursor();
+                        auto kind = cursor.get_kind();
+                        if (kind == clangmm::Cursor::Kind::FunctionDecl || kind == clangmm::Cursor::Kind::CXXMethod ||
+                            kind == clangmm::Cursor::Kind::Constructor || kind == clangmm::Cursor::Kind::Destructor ||
+                            kind == clangmm::Cursor::Kind::ConversionFunction) {
+                            auto referenced = cursor.get_referenced();
+                            if (referenced && referenced == cursor) {
+                                std::string result;
+                                std::string specifier;
+                                if (kind == clangmm::Cursor::Kind::FunctionDecl ||
+                                    kind == clangmm::Cursor::Kind::CXXMethod) {
+                                    auto start_offset = cursor.get_source_range().get_start().get_offset();
+                                    auto end_offset = token_offsets.first;
+
+                                    // To accurately get result type with needed namespace and class/struct names:
+                                    int angle_brackets = 0;
+                                    for (size_t c = 0; c < clang_tokens->size(); ++c) {
+                                        auto &token = (*clang_tokens)[c];
+                                        auto &token_offsets = clang_tokens_offsets[c];
+                                        if ((token_offsets.first.line == start_offset.line &&
+                                             token_offsets.second.line != end_offset.line &&
+                                             token_offsets.first.index >= start_offset.index) ||
+                                            (token_offsets.first.line > start_offset.line &&
+                                             token_offsets.second.line < end_offset.line) ||
+                                            (token_offsets.first.line != start_offset.line &&
+                                             token_offsets.second.line == end_offset.line &&
+                                             token_offsets.second.index <= end_offset.index) ||
+                                            (token_offsets.first.line == start_offset.line &&
+                                             token_offsets.second.line == end_offset.line &&
+                                             token_offsets.first.index >= start_offset.index &&
+                                             token_offsets.second.index <= end_offset.index)) {
+                                            auto token_spelling = token.get_spelling();
+                                            if (token.get_kind() == clangmm::Token::Kind::Identifier) {
+                                                if (c == 0 || (*clang_tokens)[c - 1].get_spelling() != "::") {
+                                                    auto name = token_spelling;
+                                                    auto parent = token.get_cursor().get_type().get_cursor().get_semantic_parent();
+                                                    while (parent && parent.get_kind() !=
+                                                                     clangmm::Cursor::Kind::TranslationUnit) {
+                                                        auto spelling = parent.get_token_spelling();
+                                                        name.insert(0, spelling + "::");
+                                                        parent = parent.get_semantic_parent();
+                                                    }
+                                                    result += name;
+                                                } else
+                                                    result += token_spelling;
+                                            } else if ((token_spelling == "*" || token_spelling == "&") &&
+                                                       !result.empty() && result.back() != '*' && result.back() != '&')
+                                                result += ' ' + token_spelling;
+                                            else if (token_spelling == "extern" || token_spelling == "static" ||
+                                                     token_spelling == "virtual" || token_spelling == "friend")
+                                                continue;
+                                            else if (token_spelling == "," ||
+                                                     (token_spelling.size() > 1 && token_spelling != "::" &&
+                                                      angle_brackets == 0))
+                                                result += token_spelling + ' ';
+                                            else {
+                                                if (token_spelling == "<")
+                                                    ++angle_brackets;
+                                                else if (token_spelling == ">")
+                                                    --angle_brackets;
+                                                result += token_spelling;
+                                            }
+                                        }
+                                    }
+
+                                    if (!result.empty() && result.back() != '*' && result.back() != '&' &&
+                                        result.back() != ' ')
+                                        result += ' ';
+
+                                    if (clang_CXXMethod_isConst(cursor.cx_cursor))
+                                        specifier = " const";
+                                }
+
+                                auto name = cursor.get_spelling();
+                                auto parent = cursor.get_semantic_parent();
+                                std::vector<std::string> semantic_parents;
+                                while (parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {
+                                    auto spelling = parent.get_spelling() + "::";
+                                    if (spelling != "::") {
+                                        semantic_parents.emplace_back(spelling);
+                                        name.insert(0, spelling);
+                                    }
+                                    parent = parent.get_semantic_parent();
+                                }
+
+                                std::string arguments;
+                                for (auto &argument_cursor: cursor.get_arguments()) {
+                                    auto argument_type = argument_cursor.get_type().get_spelling();
+                                    for (auto it = semantic_parents.rbegin(); it != semantic_parents.rend(); ++it) {
+                                        size_t pos = argument_type.find(*it);
+                                        if (pos == 0 || (pos != std::string::npos && argument_type[pos - 1] == ' '))
+                                            argument_type.erase(pos, it->size());
+                                    }
+                                    auto argument = argument_cursor.get_spelling();
+                                    if (!arguments.empty())
+                                        arguments += ", ";
+                                    arguments += argument_type;
+                                    if (!arguments.empty() && arguments.back() != '*' && arguments.back() != '&')
+                                        arguments += ' ';
+                                    arguments += argument;
+                                }
+                                return result + name + '(' + arguments + ")" + specifier + " {}";
+                            }
                         }
-                        else
-                          result+=token_spelling;
-                      }
-                      else if((token_spelling=="*" || token_spelling=="&") && !result.empty() && result.back()!='*' && result.back()!='&')
-                        result+=' '+token_spelling;
-                      else if(token_spelling=="extern" || token_spelling=="static" || token_spelling=="virtual" || token_spelling=="friend")
-                        continue;
-                      else if(token_spelling=="," || (token_spelling.size()>1 && token_spelling!="::" && angle_brackets==0))
-                        result+=token_spelling+' ';
-                      else {
-                        if(token_spelling=="<")
-                          ++angle_brackets;
-                        else if(token_spelling==">")
-                          --angle_brackets;
-                        result+=token_spelling;
-                      }
                     }
-                  }
-                  
-                  if(!result.empty() && result.back()!='*' && result.back()!='&' && result.back()!=' ')
-                    result+=' ';
-                  
-                  if(clang_CXXMethod_isConst(cursor.cx_cursor))
-                    specifier=" const";
                 }
-                
-                auto name=cursor.get_spelling();
-                auto parent=cursor.get_semantic_parent();
-                std::vector<std::string> semantic_parents;
-                while(parent && parent.get_kind()!=clangmm::Cursor::Kind::TranslationUnit) {
-                  auto spelling=parent.get_spelling()+"::";
-                  if(spelling!="::") {
-                    semantic_parents.emplace_back(spelling);
-                    name.insert(0, spelling);
-                  }
-                  parent=parent.get_semantic_parent();
+            }
+        }
+        Info::get().print("No method found at current cursor location");
+        return std::string();
+    };
+
+    get_methods = [this]() {
+        std::vector<std::pair<Offset, std::string> > methods;
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return methods;
+        }
+        clangmm::Offset last_offset{static_cast<unsigned>(-1), static_cast<unsigned>(-1)};
+        for (auto &token: *clang_tokens) {
+            if (token.is_identifier()) {
+                auto cursor = token.get_cursor();
+                auto kind = cursor.get_kind();
+                if (kind == clangmm::Cursor::Kind::FunctionDecl || kind == clangmm::Cursor::Kind::CXXMethod ||
+                    kind == clangmm::Cursor::Kind::Constructor || kind == clangmm::Cursor::Kind::Destructor ||
+                    kind == clangmm::Cursor::Kind::FunctionTemplate ||
+                    kind == clangmm::Cursor::Kind::ConversionFunction) {
+                    auto offset = cursor.get_source_location().get_offset();
+                    if (offset == last_offset)
+                        continue;
+                    last_offset = offset;
+
+                    std::string method;
+                    if (kind != clangmm::Cursor::Kind::Constructor && kind != clangmm::Cursor::Kind::Destructor) {
+                        method += cursor.get_type().get_result().get_spelling();
+                        auto pos = method.find(" ");
+                        if (pos != std::string::npos)
+                            method.erase(pos, 1);
+                        method += " ";
+                    }
+                    method += cursor.get_display_name();
+
+                    std::string prefix;
+                    auto parent = cursor.get_semantic_parent();
+                    while (parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {
+                        prefix.insert(0, parent.get_display_name() + (prefix.empty() ? "" : "::"));
+                        parent = parent.get_semantic_parent();
+                    }
+
+                    method = Glib::Markup::escape_text(method);
+                    //Add bold method token
+                    size_t token_end_pos = method.find('(');
+                    if (token_end_pos == std::string::npos)
+                        continue;
+                    auto token_start_pos = token_end_pos;
+                    while (token_start_pos != 0 && method[token_start_pos] != ' ')
+                        --token_start_pos;
+                    method.insert(token_end_pos, "</b>");
+                    method.insert(token_start_pos, "<b>");
+
+                    if (!prefix.empty())
+                        prefix += ':';
+                    prefix += std::to_string(offset.line) + ": ";
+                    prefix = Glib::Markup::escape_text(prefix);
+
+                    methods.emplace_back(Offset(offset.line - 1, offset.index - 1), prefix + method);
                 }
-                
-                std::string arguments;
-                for(auto &argument_cursor: cursor.get_arguments()) {
-                  auto argument_type=argument_cursor.get_type().get_spelling();
-                  for(auto it=semantic_parents.rbegin();it!=semantic_parents.rend();++it) {
-                    size_t pos=argument_type.find(*it);
-                    if(pos==0 || (pos!=std::string::npos && argument_type[pos-1]==' '))
-                      argument_type.erase(pos, it->size());
-                  }
-                  auto argument=argument_cursor.get_spelling();
-                  if(!arguments.empty())
-                    arguments+=", ";
-                  arguments+=argument_type;
-                  if(!arguments.empty() && arguments.back()!='*' && arguments.back()!='&')
-                    arguments+=' ';
-                  arguments+=argument;
+            }
+        }
+        if (methods.empty())
+            Info::get().print("No methods found in current buffer");
+
+        return methods;
+    };
+
+    get_token_data = [this]() -> std::vector<std::string> {
+        clangmm::Cursor cursor;
+
+        std::vector<std::string> data;
+        if (!parsed) {
+            if (selected_completion_string) {
+                cursor = clangmm::CompletionString(selected_completion_string).get_cursor(clang_tu->cx_tu);
+                if (!cursor) {
+                    Info::get().print("No symbol found");
+                    return data;
                 }
-                return result+name+'('+arguments+")"+specifier+" {}";
-              }
+            } else {
+                Info::get().print("Buffer is parsing");
+                return data;
             }
-          }
         }
-      }
-    }
-    Info::get().print("No method found at current cursor location");
-    return std::string();
-  };
-  
-  get_methods=[this](){
-    std::vector<std::pair<Offset, std::string> > methods;
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return methods;
-    }
-    clangmm::Offset last_offset{static_cast<unsigned>(-1), static_cast<unsigned>(-1)};
-    for(auto &token: *clang_tokens) {
-      if(token.is_identifier()) {
-        auto cursor=token.get_cursor();
-        auto kind=cursor.get_kind();
-        if(kind==clangmm::Cursor::Kind::FunctionDecl || kind==clangmm::Cursor::Kind::CXXMethod ||
-           kind==clangmm::Cursor::Kind::Constructor || kind==clangmm::Cursor::Kind::Destructor ||
-           kind==clangmm::Cursor::Kind::FunctionTemplate || kind==clangmm::Cursor::Kind::ConversionFunction) {
-          auto offset=cursor.get_source_location().get_offset();
-          if(offset==last_offset)
-            continue;
-          last_offset=offset;
-          
-          std::string method;
-          if(kind!=clangmm::Cursor::Kind::Constructor && kind!=clangmm::Cursor::Kind::Destructor) {
-            method+=cursor.get_type().get_result().get_spelling();
-            auto pos=method.find(" ");
-            if(pos!=std::string::npos)
-              method.erase(pos, 1);
-            method+=" ";
-          }
-          method+=cursor.get_display_name();
-          
-          std::string prefix;
-          auto parent=cursor.get_semantic_parent();
-          while(parent && parent.get_kind()!=clangmm::Cursor::Kind::TranslationUnit) {
-            prefix.insert(0, parent.get_display_name()+(prefix.empty()?"":"::"));
-            parent=parent.get_semantic_parent();
-          }
-          
-          method=Glib::Markup::escape_text(method);
-          //Add bold method token
-          size_t token_end_pos=method.find('(');
-          if(token_end_pos==std::string::npos)
-            continue;
-          auto token_start_pos=token_end_pos;
-          while(token_start_pos!=0 && method[token_start_pos]!=' ')
-            --token_start_pos;
-          method.insert(token_end_pos, "</b>");
-          method.insert(token_start_pos, "<b>");
-          
-          if(!prefix.empty())
-            prefix+=':';
-          prefix+=std::to_string(offset.line)+": ";
-          prefix=Glib::Markup::escape_text(prefix);
-          
-          methods.emplace_back(Offset(offset.line-1, offset.index-1), prefix+method);
+
+        if (!cursor) {
+            auto identifier = get_identifier();
+            if (identifier)
+                cursor = identifier.cursor.get_canonical();
         }
-      }
-    }
-    if(methods.empty())
-      Info::get().print("No methods found in current buffer");
-    
-    return methods;
-  };
-  
-  get_token_data=[this]() -> std::vector<std::string> {
-    clangmm::Cursor cursor;
-    
-    std::vector<std::string> data;
-    if(!parsed) {
-      if(selected_completion_string) {
-        cursor=clangmm::CompletionString(selected_completion_string).get_cursor(clang_tu->cx_tu);
-        if(!cursor) {
-          Info::get().print("No symbol found");
-          return data;
+
+        if (cursor) {
+            data.emplace_back("clang");
+
+            std::string symbol;
+            clangmm::Cursor last_cursor;
+            auto it = data.end();
+            do {
+                auto token_spelling = cursor.get_token_spelling();
+                if (!token_spelling.empty() && token_spelling != "__1" && token_spelling.compare(0, 5, "__cxx") != 0) {
+                    it = data.emplace(it, token_spelling);
+                    if (symbol.empty())
+                        symbol = token_spelling;
+                    else
+                        symbol.insert(0, token_spelling + "::");
+                }
+                last_cursor = cursor;
+                cursor = cursor.get_semantic_parent();
+            } while (cursor.get_kind() != clangmm::Cursor::Kind::TranslationUnit);
+
+            if (last_cursor.get_kind() != clangmm::Cursor::Kind::Namespace)
+                data.emplace(++data.begin(), "");
+
+            auto url = Documentation::CppReference::get_url(symbol);
+            if (!url.empty())
+                return {url};
         }
-      }
-      else {
-        Info::get().print("Buffer is parsing");
+
+        if (data.empty())
+            Info::get().print("No symbol found at current cursor location");
+
         return data;
-      }
-    }
-    
-    if(!cursor) {
-      auto identifier=get_identifier();
-      if(identifier)
-        cursor=identifier.cursor.get_canonical();
-    }
-    
-    if(cursor) {
-      data.emplace_back("clang");
-      
-      std::string symbol;
-      clangmm::Cursor last_cursor;
-      auto it=data.end();
-      do {
-        auto token_spelling=cursor.get_token_spelling();
-        if(!token_spelling.empty() && token_spelling!="__1" && token_spelling.compare(0, 5, "__cxx")!=0) {
-          it=data.emplace(it, token_spelling);
-          if(symbol.empty())
-            symbol=token_spelling;
-          else
-            symbol.insert(0, token_spelling+"::");
+    };
+
+    goto_next_diagnostic = [this]() {
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return;
         }
-        last_cursor=cursor;
-        cursor=cursor.get_semantic_parent();
-      } while(cursor.get_kind()!=clangmm::Cursor::Kind::TranslationUnit);
-      
-      if(last_cursor.get_kind()!=clangmm::Cursor::Kind::Namespace)
-        data.emplace(++data.begin(), "");
-      
-      auto url=Documentation::CppReference::get_url(symbol);
-      if(!url.empty())
-        return {url};
-    }
-    
-    if(data.empty())
-      Info::get().print("No symbol found at current cursor location");
-    
-    return data;
-  };
-  
-  goto_next_diagnostic=[this]() {
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return;
-    }
-    place_cursor_at_next_diagnostic();
-  };
-  
-  get_fix_its=[this]() {
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return std::vector<FixIt>();
-    }
-    if(fix_its.empty())
-      Info::get().print("No fix-its found in current buffer");
-    return fix_its;
-  };
-  
-  get_documentation_template=[this]() {
-    if(!parsed) {
-      Info::get().print("Buffer is parsing");
-      return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
-    }
-    auto identifier=get_identifier();
-    if(identifier) {
-      auto cursor=identifier.cursor.get_canonical();
-      if(!clang_Range_isNull(clang_Cursor_getCommentRange(cursor.cx_cursor))) {
-        Info::get().print("Symbol is already documented");
-        return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
-      }
-      auto clang_offsets=cursor.get_source_range().get_offsets();
-      auto source_offset=Offset(clang_offsets.first.line-1, 0, cursor.get_source_location().get_path());
-      std::string tabs;
-      for(size_t c=0;c<clang_offsets.first.index-1;++c)
-        tabs+=' ';
-      auto first_line=tabs+"/**\n";
-      auto second_line=tabs+" * \n";
-      auto iter_offset=first_line.size()+second_line.size()-1;
-      
-      std::string param_lines;
-      for(int c=0;c<clang_Cursor_getNumArguments(cursor.cx_cursor);++c)
-        param_lines+=tabs+" * @param "+clangmm::Cursor(clang_Cursor_getArgument(cursor.cx_cursor, c)).get_spelling()+'\n';
-      
-      std::string return_line;
-      auto return_spelling=cursor.get_type().get_result().get_spelling();
-      if(!return_spelling.empty() && return_spelling!="void")
-        return_line+=tabs+" * @return\n";
-      
-      auto documentation=first_line+second_line;
-      if(!param_lines.empty() || !return_line.empty())
-        documentation+=tabs+" *\n";
-      
-      documentation+=param_lines+return_line+tabs+" */\n";
-      
-      return std::tuple<Source::Offset, std::string, size_t>(source_offset, documentation, iter_offset);
-    }
-    else {
-      Info::get().print("No symbol found at current cursor location");
-      return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
-    }
-  };
+        place_cursor_at_next_diagnostic();
+    };
+
+    get_fix_its = [this]() {
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return std::vector<FixIt>();
+        }
+        if (fix_its.empty())
+            Info::get().print("No fix-its found in current buffer");
+        return fix_its;
+    };
+
+    get_documentation_template = [this]() {
+        if (!parsed) {
+            Info::get().print("Buffer is parsing");
+            return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
+        }
+        auto identifier = get_identifier();
+        if (identifier) {
+            auto cursor = identifier.cursor.get_canonical();
+            if (!clang_Range_isNull(clang_Cursor_getCommentRange(cursor.cx_cursor))) {
+                Info::get().print("Symbol is already documented");
+                return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
+            }
+            auto clang_offsets = cursor.get_source_range().get_offsets();
+            auto source_offset = Offset(clang_offsets.first.line - 1, 0, cursor.get_source_location().get_path());
+            std::string tabs;
+            for (size_t c = 0; c < clang_offsets.first.index - 1; ++c)
+                tabs += ' ';
+            auto first_line = tabs + "/**\n";
+            auto second_line = tabs + " * \n";
+            auto iter_offset = first_line.size() + second_line.size() - 1;
+
+            std::string param_lines;
+            for (int c = 0; c < clang_Cursor_getNumArguments(cursor.cx_cursor); ++c)
+                param_lines += tabs + " * @param " +
+                               clangmm::Cursor(clang_Cursor_getArgument(cursor.cx_cursor, c)).get_spelling() + '\n';
+
+            std::string return_line;
+            auto return_spelling = cursor.get_type().get_result().get_spelling();
+            if (!return_spelling.empty() && return_spelling != "void")
+                return_line += tabs + " * @return\n";
+
+            auto documentation = first_line + second_line;
+            if (!param_lines.empty() || !return_line.empty())
+                documentation += tabs + " *\n";
+
+            documentation += param_lines + return_line + tabs + " */\n";
+
+            return std::tuple<Source::Offset, std::string, size_t>(source_offset, documentation, iter_offset);
+        } else {
+            Info::get().print("No symbol found at current cursor location");
+            return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
+        }
+    };
 }
 
 Source::ClangViewRefactor::Identifier Source::ClangViewRefactor::get_identifier() {
-  if(!parsed)
-    return Identifier();
-  auto iter=get_buffer()->get_insert()->get_iter();
-  auto line=static_cast<unsigned>(iter.get_line());
-  auto index=static_cast<unsigned>(iter.get_line_index());
-  for(size_t c=clang_tokens->size()-1;c!=static_cast<size_t>(-1);--c) {
-    auto &token=(*clang_tokens)[c];
-    if(token.is_identifier()) {
-      auto &token_offsets=clang_tokens_offsets[c];
-      if(line==token_offsets.first.line-1 && index>=token_offsets.first.index-1 && index <=token_offsets.second.index-1) {
-        auto referenced=token.get_cursor().get_referenced();
-        if(referenced)
-          return Identifier(token.get_spelling(), referenced);
-      }
+    if (!parsed)
+        return Identifier();
+    auto iter = get_buffer()->get_insert()->get_iter();
+    auto line = static_cast<unsigned>(iter.get_line());
+    auto index = static_cast<unsigned>(iter.get_line_index());
+    for (size_t c = clang_tokens->size() - 1; c != static_cast<size_t>(-1); --c) {
+        auto &token = (*clang_tokens)[c];
+        if (token.is_identifier()) {
+            auto &token_offsets = clang_tokens_offsets[c];
+            if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
+                index <= token_offsets.second.index - 1) {
+                auto referenced = token.get_cursor().get_referenced();
+                if (referenced)
+                    return Identifier(token.get_spelling(), referenced);
+            }
+        }
     }
-  }
-  return Identifier();
+    return Identifier();
 }
 
 void Source::ClangViewRefactor::wait_parsing() {
-  std::unique_ptr<Dialog::Message> message;
-  std::vector<Source::ClangView*> clang_views;
-  for(auto &view: views) {
-    if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
-      if(!clang_view->parsed && !clang_view->selected_completion_string) {
-        clang_views.emplace_back(clang_view);
-        if(!message)
-          message=std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing");
-      }
+    std::unique_ptr<Dialog::Message> message;
+    std::vector<Source::ClangView *> clang_views;
+    for (auto &view: views) {
+        if (auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
+            if (!clang_view->parsed && !clang_view->selected_completion_string) {
+                clang_views.emplace_back(clang_view);
+                if (!message)
+                    message = std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing");
+            }
+        }
     }
-  }
-  if(message) {
-    for(;;) {
-      while(Gtk::Main::events_pending())
-        Gtk::Main::iteration(false);
-      bool all_parsed=true;
-      for(auto &clang_view: clang_views) {
-        if(!clang_view->parsed) {
-          all_parsed=false;
-          break;
+    if (message) {
+        for (;;) {
+            while (Gtk::Main::events_pending())
+                Gtk::Main::iteration(false);
+            bool all_parsed = true;
+            for (auto &clang_view: clang_views) {
+                if (!clang_view->parsed) {
+                    all_parsed = false;
+                    break;
+                }
+            }
+            if (all_parsed)
+                break;
+            std::this_thread::sleep_for(std::chrono::milliseconds(10));
         }
-      }
-      if(all_parsed)
-        break;
-      std::this_thread::sleep_for(std::chrono::milliseconds(10));
+        message->hide();
     }
-    message->hide();
-  }
 }
 
 void Source::ClangViewRefactor::tag_similar_identifiers(const Identifier &identifier) {
-  if(parsed) {
-    if(identifier && last_tagged_identifier!=identifier) {
-      for(auto &mark: similar_identifiers_marks) {
-        get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
-        get_buffer()->delete_mark(mark.first);
-        get_buffer()->delete_mark(mark.second);
-      }
-      similar_identifiers_marks.clear();
-      auto offsets=clang_tokens->get_similar_token_offsets(identifier.kind, identifier.spelling, identifier.cursor.get_all_usr_extended());
-      for(auto &offset: offsets) {
-        auto start_iter=get_buffer()->get_iter_at_line_index(offset.first.line-1, offset.first.index-1);
-        auto end_iter=get_buffer()->get_iter_at_line_index(offset.second.line-1, offset.second.index-1);
-        get_buffer()->apply_tag(similar_identifiers_tag, start_iter, end_iter);
-        similar_identifiers_marks.emplace_back(get_buffer()->create_mark(start_iter), get_buffer()->create_mark(end_iter)); 
-      }
-      last_tagged_identifier=identifier;
+    if (parsed) {
+        if (identifier && last_tagged_identifier != identifier) {
+            for (auto &mark: similar_identifiers_marks) {
+                get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
+                get_buffer()->delete_mark(mark.first);
+                get_buffer()->delete_mark(mark.second);
+            }
+            similar_identifiers_marks.clear();
+            auto offsets = clang_tokens->get_similar_token_offsets(identifier.kind, identifier.spelling,
+                                                                   identifier.cursor.get_all_usr_extended());
+            for (auto &offset: offsets) {
+                auto start_iter = get_buffer()->get_iter_at_line_index(offset.first.line - 1, offset.first.index - 1);
+                auto end_iter = get_buffer()->get_iter_at_line_index(offset.second.line - 1, offset.second.index - 1);
+                get_buffer()->apply_tag(similar_identifiers_tag, start_iter, end_iter);
+                similar_identifiers_marks.emplace_back(get_buffer()->create_mark(start_iter),
+                                                       get_buffer()->create_mark(end_iter));
+            }
+            last_tagged_identifier = identifier;
+        }
     }
-  }
-  if(!identifier && last_tagged_identifier) {
-    for(auto &mark: similar_identifiers_marks) {
-      get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
-      get_buffer()->delete_mark(mark.first);
-      get_buffer()->delete_mark(mark.second);
+    if (!identifier && last_tagged_identifier) {
+        for (auto &mark: similar_identifiers_marks) {
+            get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
+            get_buffer()->delete_mark(mark.first);
+            get_buffer()->delete_mark(mark.second);
+        }
+        similar_identifiers_marks.clear();
+        last_tagged_identifier = Identifier();
     }
-    similar_identifiers_marks.clear();
-    last_tagged_identifier=Identifier();
-  }
 }
 
 
-Source::ClangView::ClangView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language):
-    BaseView(file_path, language), ClangViewParse(file_path, language), ClangViewAutocomplete(file_path, language), ClangViewRefactor(file_path, language) {
-  if(language) {
-    get_source_buffer()->set_highlight_syntax(true);
-    get_source_buffer()->set_language(language);
-  }
-  
-  do_delete_object.connect([this]() {
-    if(delete_thread.joinable())
-      delete_thread.join();
-    delete this;
-  });
+Source::ClangView::ClangView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) :
+        BaseView(file_path, language), ClangViewParse(file_path, language), ClangViewAutocomplete(file_path, language),
+        ClangViewRefactor(file_path, language) {
+    if (language) {
+        get_source_buffer()->set_highlight_syntax(true);
+        get_source_buffer()->set_language(language);
+    }
+
+    do_delete_object.connect([this]() {
+        if (delete_thread.joinable())
+            delete_thread.join();
+        delete this;
+    });
 }
 
 void Source::ClangView::full_reparse() {
-  auto print_error=[this] {
-    Terminal::get().async_print("Error: failed to reparse "+file_path.string()+". Please reopen the file manually.\n", true);
-  };
-  full_reparse_needed=false;
-  if(full_reparse_running) {
-    print_error();
-    return;
-  }
-  else {
-    auto expected=ParseState::PROCESSING;
-    if(!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) {
-      expected=ParseState::RESTARTING;
-      if(!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) {
+    auto print_error = [this] {
+        Terminal::get().async_print(
+                "Error: failed to reparse " + file_path.string() + ". Please reopen the file manually.\n", true);
+    };
+    full_reparse_needed = false;
+    if (full_reparse_running) {
         print_error();
         return;
-      }
+    } else {
+        auto expected = ParseState::PROCESSING;
+        if (!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) {
+            expected = ParseState::RESTARTING;
+            if (!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) {
+                print_error();
+                return;
+            }
+        }
+        autocomplete.state = Autocomplete::State::IDLE;
+        soft_reparse_needed = false;
+        full_reparse_running = true;
+        if (full_reparse_thread.joinable())
+            full_reparse_thread.join();
+        full_reparse_thread = std::thread([this]() {
+            if (parse_thread.joinable())
+                parse_thread.join();
+            if (autocomplete.thread.joinable())
+                autocomplete.thread.join();
+            dispatcher.post([this] {
+                parse_initialize();
+                full_reparse_running = false;
+            });
+        });
     }
-    autocomplete.state=Autocomplete::State::IDLE;
-    soft_reparse_needed=false;
-    full_reparse_running=true;
-    if(full_reparse_thread.joinable())
-      full_reparse_thread.join();
-    full_reparse_thread=std::thread([this](){
-      if(parse_thread.joinable())
-        parse_thread.join();
-      if(autocomplete.thread.joinable())
-        autocomplete.thread.join();
-      dispatcher.post([this] {
-        parse_initialize();
-        full_reparse_running=false;
-      });
-    });
-  }
 }
 
 void Source::ClangView::async_delete() {
-  delayed_show_arguments_connection.disconnect();
-  
-  views.erase(this);
-  std::set<boost::filesystem::path> project_paths_in_use;
-  for(auto &view: views) {
-    if(dynamic_cast<ClangView*>(view)) {
-      auto build=Project::Build::create(view->file_path);
-      if(!build->project_path.empty())
-        project_paths_in_use.emplace(build->project_path);
-    }
-  }
-  Usages::Clang::erase_unused_caches(project_paths_in_use);
-  Usages::Clang::cache_in_progress();
-  
-  if(!get_buffer()->get_modified()) {
-    if(full_reparse_needed)
-      full_reparse();
-    else if(soft_reparse_needed)
-      soft_reparse();
-  }
-  
-  auto before_parse_time=std::time(nullptr);
-  delete_thread=std::thread([this, before_parse_time, project_paths_in_use=std::move(project_paths_in_use)] {
-    while(!parsed)
-      std::this_thread::sleep_for(std::chrono::milliseconds(10));
-    
-    delayed_reparse_connection.disconnect();
-    parse_state=ParseState::STOP;
-    dispatcher.disconnect();
-    
-    if(get_buffer()->get_modified()) {
-      std::ifstream stream(file_path.string(), std::ios::binary);
-      if(stream) {
-        std::string buffer;
-        buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
-        if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr"))
-          clangmm::remove_include_guard(buffer);
-        clang_tu->reparse(buffer);
-        clang_tokens = clang_tu->get_tokens();
-      }
-      else
-        clang_tokens=nullptr;
+    delayed_show_arguments_connection.disconnect();
+    delayed_tag_similar_identifiers_connection.disconnect();
+
+    views.erase(this);
+    std::set<boost::filesystem::path> project_paths_in_use;
+    for (auto &view: views) {
+        if (dynamic_cast<ClangView *>(view)) {
+            auto build = Project::Build::create(view->file_path);
+            if (!build->project_path.empty())
+                project_paths_in_use.emplace(build->project_path);
+        }
     }
-    
-    if(clang_tokens) {
-      auto build=Project::Build::create(file_path);
-      Usages::Clang::cache(build->project_path, build->get_default_path(), file_path, before_parse_time, project_paths_in_use, clang_tu.get(), clang_tokens.get());
+    Usages::Clang::erase_unused_caches(project_paths_in_use);
+    Usages::Clang::cache_in_progress();
+
+    if (!get_buffer()->get_modified()) {
+        if (full_reparse_needed)
+            full_reparse();
+        else if (soft_reparse_needed)
+            soft_reparse();
     }
-    
-    if(full_reparse_thread.joinable())
-      full_reparse_thread.join();
-    if(parse_thread.joinable())
-      parse_thread.join();
-    if(autocomplete.thread.joinable())
-      autocomplete.thread.join();
-    do_delete_object();
-  });
+
+    auto before_parse_time = std::time(nullptr);
+    delete_thread = std::thread([this, before_parse_time, project_paths_in_use = std::move(project_paths_in_use)] {
+        while (!parsed)
+            std::this_thread::sleep_for(std::chrono::milliseconds(10));
+
+        delayed_reparse_connection.disconnect();
+        parse_state = ParseState::STOP;
+        dispatcher.disconnect();
+
+        if (get_buffer()->get_modified()) {
+            std::ifstream stream(file_path.string(), std::ios::binary);
+            if (stream) {
+                std::string buffer;
+                buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
+                if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr"))
+                    clangmm::remove_include_guard(buffer);
+                clang_tu->reparse(buffer);
+                clang_tokens = clang_tu->get_tokens();
+            } else
+                clang_tokens = nullptr;
+        }
+
+        if (clang_tokens) {
+            auto build = Project::Build::create(file_path);
+            Usages::Clang::cache(build->project_path, build->get_default_path(), file_path, before_parse_time,
+                                 project_paths_in_use, clang_tu.get(), clang_tokens.get());
+        }
+
+        if (full_reparse_thread.joinable())
+            full_reparse_thread.join();
+        if (parse_thread.joinable())
+            parse_thread.join();
+        if (autocomplete.thread.joinable())
+            autocomplete.thread.join();
+        do_delete_object();
+    });
 }
diff --git a/src/source_clang.h b/src/source_clang.h
index 76aeef8d..b4184525 100644
--- a/src/source_clang.h
+++ b/src/source_clang.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <thread>
 #include <atomic>
 #include <mutex>
@@ -10,102 +11,134 @@
 #include "autocomplete.h"
 
 namespace Source {
-  class ClangViewParse : public View {
-  protected:
-    enum class ParseState {PROCESSING, RESTARTING, STOP};
-    enum class ParseProcessState {IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING};
-    
-  public:
-    ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
-    
-    bool save() override;
-    void configure() override;
-    
-    void soft_reparse(bool delayed=false) override;
-  protected:
-    Dispatcher dispatcher;
-    void parse_initialize();
-    std::unique_ptr<clangmm::TranslationUnit> clang_tu;
-    std::unique_ptr<clangmm::Tokens> clang_tokens;
-    std::vector<std::pair<clangmm::Offset, clangmm::Offset>> clang_tokens_offsets;
-    sigc::connection delayed_reparse_connection;
-    
-    void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
-    
-    std::vector<FixIt> fix_its;
-    
-    std::thread parse_thread;
-    std::mutex parse_mutex;
-    std::atomic<ParseState> parse_state;
-    std::atomic<ParseProcessState> parse_process_state;
-    
-    CXCompletionString selected_completion_string=nullptr;
-  private:
-    Glib::ustring parse_thread_buffer;
-    
-    static const std::unordered_map<int, std::string> &clang_types();
-    void update_syntax();
-    std::set<std::string> last_syntax_tags;
-
-    void update_diagnostics();
-    std::vector<clangmm::Diagnostic> clang_diagnostics;
-    
-    static clangmm::Index clang_index;
-  };
-    
-  class ClangViewAutocomplete : public virtual ClangViewParse {
-  public:
-    ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
-  protected:
-    Autocomplete autocomplete;
-    std::unique_ptr<clangmm::CodeCompleteResults> code_complete_results;
-    std::vector<CXCompletionString> completion_strings;
-    sigc::connection delayed_show_arguments_connection;
-  private:
-    bool is_possible_parameter();
-    bool show_arguments;
-    const std::unordered_map<std::string, std::string> &autocomplete_manipulators_map();
-  };
-
-  class ClangViewRefactor : public virtual ClangViewParse {
-    class Identifier {
+    class ClangViewParse : public View {
+    protected:
+        enum class ParseState {
+            PROCESSING, RESTARTING, STOP
+        };
+        enum class ParseProcessState {
+            IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING
+        };
+
     public:
-      Identifier(const std::string &spelling, const clangmm::Cursor &cursor)
-          : kind(cursor.get_kind()), spelling(spelling), usr_extended(cursor.get_usr_extended()), cursor(cursor) {}
-      Identifier() : kind(static_cast<clangmm::Cursor::Kind>(0)) {}
-      
-      operator bool() const { return static_cast<int>(kind)!=0; }
-      bool operator==(const Identifier &rhs) const { return spelling==rhs.spelling && usr_extended==rhs.usr_extended; }
-      bool operator!=(const Identifier &rhs) const { return !(*this==rhs); }
-      bool operator<(const Identifier &rhs) const { return spelling<rhs.spelling || (spelling==rhs.spelling && usr_extended<rhs.usr_extended); }
-      clangmm::Cursor::Kind kind;
-      std::string spelling;
-      std::string usr_extended;
-      clangmm::Cursor cursor;
+        ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+
+        bool save() override;
+
+        void configure() override;
+
+        void soft_reparse(bool delayed = false) override;
+
+    protected:
+        Dispatcher dispatcher;
+
+        void parse_initialize();
+
+        std::unique_ptr<clangmm::TranslationUnit> clang_tu;
+        std::unique_ptr<clangmm::Tokens> clang_tokens;
+        std::vector<std::pair<clangmm::Offset, clangmm::Offset>> clang_tokens_offsets;
+        sigc::connection delayed_reparse_connection;
+
+        void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
+
+        std::vector<FixIt> fix_its;
+
+        std::thread parse_thread;
+        std::mutex parse_mutex;
+        std::atomic<ParseState> parse_state;
+        std::atomic<ParseProcessState> parse_process_state;
+
+        CXCompletionString selected_completion_string = nullptr;
+    private:
+        Glib::ustring parse_thread_buffer;
+
+        static const std::unordered_map<int, std::string> &clang_types();
+
+        void update_syntax();
+
+        std::set<std::string> last_syntax_tags;
+
+        void update_diagnostics();
+
+        std::vector<clangmm::Diagnostic> clang_diagnostics;
+
+        static clangmm::Index clang_index;
+    };
+
+    class ClangViewAutocomplete : public virtual ClangViewParse {
+    public:
+        ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+
+    protected:
+        Autocomplete autocomplete;
+        std::unique_ptr<clangmm::CodeCompleteResults> code_complete_results;
+        std::vector<CXCompletionString> completion_strings;
+        sigc::connection delayed_show_arguments_connection;
+    private:
+        bool is_possible_parameter();
+
+        bool show_arguments;
+
+        const std::unordered_map<std::string, std::string> &autocomplete_manipulators_map();
+    };
+
+    class ClangViewRefactor : public virtual ClangViewParse {
+        class Identifier {
+        public:
+            Identifier(const std::string &spelling, const clangmm::Cursor &cursor)
+                    : kind(cursor.get_kind()), spelling(spelling), usr_extended(cursor.get_usr_extended()),
+                      cursor(cursor) {}
+
+            Identifier() : kind(static_cast<clangmm::Cursor::Kind>(0)) {}
+
+            operator bool() const { return static_cast<int>(kind) != 0; }
+
+            bool operator==(const Identifier &rhs) const {
+                return spelling == rhs.spelling && usr_extended == rhs.usr_extended;
+            }
+
+            bool operator!=(const Identifier &rhs) const { return !(*this == rhs); }
+
+            bool operator<(const Identifier &rhs) const {
+                return spelling < rhs.spelling || (spelling == rhs.spelling && usr_extended < rhs.usr_extended);
+            }
+
+            clangmm::Cursor::Kind kind;
+            std::string spelling;
+            std::string usr_extended;
+            clangmm::Cursor cursor;
+        };
+
+    public:
+        ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+
+    protected:
+        sigc::connection delayed_tag_similar_identifiers_connection;
+    private:
+        Identifier get_identifier();
+
+        void wait_parsing();
+
+        std::list<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > similar_identifiers_marks;
+
+        void tag_similar_identifiers(const Identifier &identifier);
+
+        Glib::RefPtr<Gtk::TextTag> similar_identifiers_tag;
+        Identifier last_tagged_identifier;
+    };
+
+    class ClangView : public ClangViewAutocomplete, public ClangViewRefactor {
+    public:
+        ClangView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+
+        void full_reparse() override;
+
+        void async_delete();
+
+    private:
+        Glib::Dispatcher do_delete_object;
+        std::thread delete_thread;
+        std::thread full_reparse_thread;
+        bool full_reparse_running = false;
     };
-  public:
-    ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
-  private:
-    Identifier get_identifier();
-    void wait_parsing();
-    
-    std::list<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > similar_identifiers_marks;
-    void tag_similar_identifiers(const Identifier &identifier);
-    Glib::RefPtr<Gtk::TextTag> similar_identifiers_tag;
-    Identifier last_tagged_identifier;
-  };
-  
-  class ClangView : public ClangViewAutocomplete, public ClangViewRefactor {
-  public:
-    ClangView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
-    
-    void full_reparse() override;
-    void async_delete();
-    
-  private:
-    Glib::Dispatcher do_delete_object;
-    std::thread delete_thread;
-    std::thread full_reparse_thread;
-    bool full_reparse_running=false;
-  };
 }
diff --git a/src/source_diff.cc b/src/source_diff.cc
index 2ed28dc2..e0bec547 100644
--- a/src/source_diff.cc
+++ b/src/source_diff.cc
@@ -6,362 +6,366 @@
 #include <boost/version.hpp>
 
 Source::DiffView::Renderer::Renderer() : Gsv::GutterRenderer() {
-  set_padding(4, 0);
+    set_padding(4, 0);
 }
 
-void Source::DiffView::Renderer::draw_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area,
-                                            const Gdk::Rectangle &cell_area, Gtk::TextIter &start, Gtk::TextIter &end,
-                                            Gsv::GutterRendererState p6) {
-  if(start.has_tag(tag_added) || end.has_tag(tag_added)) {
-    cr->set_source_rgba(0.0, 1.0, 0.0, 0.5);
-    cr->rectangle(cell_area.get_x(), cell_area.get_y(), 4, cell_area.get_height());
-    cr->fill();
-  }
-  else if(start.has_tag(tag_modified) || end.has_tag(tag_modified)) {
-    cr->set_source_rgba(0.9, 0.9, 0.0, 0.75);
-    cr->rectangle(cell_area.get_x(), cell_area.get_y(), 4, cell_area.get_height());
-    cr->fill();
-  }
-  if(start.has_tag(tag_removed_below) || end.has_tag(tag_removed_below)) {
-    cr->set_source_rgba(0.75, 0.0, 0.0, 0.5);
-    cr->rectangle(cell_area.get_x()-4, cell_area.get_y()+cell_area.get_height()-2, 8, 2);
-    cr->fill();
-  }
-  if(start.has_tag(tag_removed_above) || end.has_tag(tag_removed_above)) {
-    cr->set_source_rgba(0.75, 0.0, 0.0, 0.5);
-    cr->rectangle(cell_area.get_x()-4, cell_area.get_y(), 8, 2);
-    cr->fill();
-  }
+void
+Source::DiffView::Renderer::draw_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area,
+                                       const Gdk::Rectangle &cell_area, Gtk::TextIter &start, Gtk::TextIter &end,
+                                       Gsv::GutterRendererState p6) {
+    if (start.has_tag(tag_added) || end.has_tag(tag_added)) {
+        cr->set_source_rgba(0.0, 1.0, 0.0, 0.5);
+        cr->rectangle(cell_area.get_x(), cell_area.get_y(), 4, cell_area.get_height());
+        cr->fill();
+    } else if (start.has_tag(tag_modified) || end.has_tag(tag_modified)) {
+        cr->set_source_rgba(0.9, 0.9, 0.0, 0.75);
+        cr->rectangle(cell_area.get_x(), cell_area.get_y(), 4, cell_area.get_height());
+        cr->fill();
+    }
+    if (start.has_tag(tag_removed_below) || end.has_tag(tag_removed_below)) {
+        cr->set_source_rgba(0.75, 0.0, 0.0, 0.5);
+        cr->rectangle(cell_area.get_x() - 4, cell_area.get_y() + cell_area.get_height() - 2, 8, 2);
+        cr->fill();
+    }
+    if (start.has_tag(tag_removed_above) || end.has_tag(tag_removed_above)) {
+        cr->set_source_rgba(0.75, 0.0, 0.0, 0.5);
+        cr->rectangle(cell_area.get_x() - 4, cell_area.get_y(), 8, 2);
+        cr->fill();
+    }
 }
 
-Source::DiffView::DiffView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) : BaseView(file_path, language), renderer(new Renderer()) {
-  boost::system::error_code ec;
-  canonical_file_path=boost::filesystem::canonical(file_path, ec);
-  if(ec)
-    canonical_file_path=file_path;
-  
-  renderer->tag_added=get_buffer()->create_tag("git_added");
-  renderer->tag_modified=get_buffer()->create_tag("git_modified");
-  renderer->tag_removed=get_buffer()->create_tag("git_removed");
-  renderer->tag_removed_below=get_buffer()->create_tag();
-  renderer->tag_removed_above=get_buffer()->create_tag();
-  
-  configure();
+Source::DiffView::DiffView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) : BaseView(
+        file_path, language), renderer(new Renderer()) {
+    boost::system::error_code ec;
+    canonical_file_path = boost::filesystem::canonical(file_path, ec);
+    if (ec)
+        canonical_file_path = file_path;
+
+    renderer->tag_added = get_buffer()->create_tag("git_added");
+    renderer->tag_modified = get_buffer()->create_tag("git_modified");
+    renderer->tag_removed = get_buffer()->create_tag("git_removed");
+    renderer->tag_removed_below = get_buffer()->create_tag();
+    renderer->tag_removed_above = get_buffer()->create_tag();
+
+    configure();
 }
 
 Source::DiffView::~DiffView() {
-  dispatcher.disconnect();
-  if(repository) {
-    get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->remove(renderer.get());
-    buffer_insert_connection.disconnect();
-    buffer_erase_connection.disconnect();
-    monitor_changed_connection.disconnect();
-    delayed_buffer_changed_connection.disconnect();
-    delayed_monitor_changed_connection.disconnect();
-    
-    parse_stop=true;
-    if(parse_thread.joinable())
-      parse_thread.join();
-  }
+    dispatcher.disconnect();
+    if (repository) {
+        get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->remove(renderer.get());
+        buffer_insert_connection.disconnect();
+        buffer_erase_connection.disconnect();
+        monitor_changed_connection.disconnect();
+        delayed_buffer_changed_connection.disconnect();
+        delayed_monitor_changed_connection.disconnect();
+
+        parse_stop = true;
+        if (parse_thread.joinable())
+            parse_thread.join();
+    }
 }
 
 void Source::DiffView::configure() {
-  if(Config::get().source.show_git_diff) {
-    if(repository)
-      return;
-  }
-  else if(repository) {
-    get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->remove(renderer.get());
-    buffer_insert_connection.disconnect();
-    buffer_erase_connection.disconnect();
-    monitor_changed_connection.disconnect();
-    delayed_buffer_changed_connection.disconnect();
-    delayed_monitor_changed_connection.disconnect();
-    
-    parse_stop=true;
-    if(parse_thread.joinable())
-      parse_thread.join();
-    repository=nullptr;
-    diff=nullptr;
-    
-    return;
-  }
-  else
-    return;
-  
-  try {
-    repository=Git::get_repository(this->file_path.parent_path());
-  }
-  catch(const std::exception &) {
-    return;
-  }
-  
-  get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->insert(renderer.get(), -40);
-  parse_state=ParseState::STARTING;
-  parse_stop=false;
-  monitor_changed=false;
-  
-  buffer_insert_connection=get_buffer()->signal_insert().connect([this](const Gtk::TextBuffer::iterator &iter ,const Glib::ustring &text, int) {
-    //Do not perform git diff if no newline is added and line is already marked as added
-    if(!iter.starts_line() && iter.has_tag(renderer->tag_added)) {
-      bool newline=false;
-      for(auto &c: text.raw()) {
-        if(c=='\n') {
-          newline=true;
-          break;
-        }
-      }
-      if(!newline)
+    if (Config::get().source.show_git_diff) {
+        if (repository)
+            return;
+    } else if (repository) {
+        get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->remove(renderer.get());
+        buffer_insert_connection.disconnect();
+        buffer_erase_connection.disconnect();
+        monitor_changed_connection.disconnect();
+        delayed_buffer_changed_connection.disconnect();
+        delayed_monitor_changed_connection.disconnect();
+
+        parse_stop = true;
+        if (parse_thread.joinable())
+            parse_thread.join();
+        repository = nullptr;
+        diff = nullptr;
+
         return;
-    }
-    //Remove tag_removed_above/below if newline is inserted
-    else if(!text.empty() && text[0]=='\n' && iter.has_tag(renderer->tag_removed)) {
-      auto start_iter=get_buffer()->get_iter_at_line(iter.get_line());
-      auto end_iter=get_iter_at_line_end(iter.get_line());
-      end_iter.forward_char();
-      get_buffer()->remove_tag(renderer->tag_removed_above, start_iter, end_iter);
-      get_buffer()->remove_tag(renderer->tag_removed_below, start_iter, end_iter);
-    }
-    parse_state=ParseState::IDLE;
-    delayed_buffer_changed_connection.disconnect();
-    delayed_buffer_changed_connection=Glib::signal_timeout().connect([this]() {
-      parse_state=ParseState::STARTING;
-      return false;
-    }, 250);
-  }, false);
-  
-  buffer_erase_connection=get_buffer()->signal_erase().connect([this](const Gtk::TextBuffer::iterator &start_iter, const Gtk::TextBuffer::iterator &end_iter) {
-    //Do not perform git diff if start_iter and end_iter is at the same line in addition to the line is tagged added
-    if(start_iter.get_line()==end_iter.get_line() && start_iter.has_tag(renderer->tag_added))
-      return;
-    
-    parse_state=ParseState::IDLE;
-    delayed_buffer_changed_connection.disconnect();
-    delayed_buffer_changed_connection=Glib::signal_timeout().connect([this]() {
-      parse_state=ParseState::STARTING;
-      return false;
-    }, 250);
-  }, false);
-  
-  monitor_changed_connection=repository->monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
-                                                                                  const Glib::RefPtr<Gio::File>&,
-                                                                                  Gio::FileMonitorEvent monitor_event) {
-    if(monitor_event!=Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-      delayed_monitor_changed_connection.disconnect();
-      delayed_monitor_changed_connection=Glib::signal_timeout().connect([this]() {
-        monitor_changed=true;
-        parse_state=ParseState::STARTING;
-        std::unique_lock<std::mutex> lock(parse_mutex);
-        diff=nullptr;
-        return false;
-      }, 500);
-    }
-  });
-  
-  parse_thread=std::thread([this]() {
-    std::string status_branch;
+    } else
+        return;
+
     try {
-      diff=get_diff();
-      status_branch=repository->get_branch();
+        repository = Git::get_repository(this->file_path.parent_path());
     }
-    catch(const std::exception &) {
-      status_branch="";
+    catch (const std::exception &) {
+        return;
     }
-    dispatcher.post([this, status_branch=std::move(status_branch)] {
-      this->status_branch=status_branch;
-      if(update_status_branch)
-        update_status_branch(this);
-    });
-    
-    try {
-      while(true) {
-        while(!parse_stop && parse_state!=ParseState::STARTING && parse_state!=ParseState::PROCESSING)
-          std::this_thread::sleep_for(std::chrono::milliseconds(10));
-        if(parse_stop)
-          break;
-        std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-        auto expected=ParseState::STARTING;
-        if(parse_state.compare_exchange_strong(expected, ParseState::PREPROCESSING)) {
-          dispatcher.post([this] {
-            auto expected=ParseState::PREPROCESSING;
-            std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-            if(parse_lock.try_lock()) {
-              if(parse_state.compare_exchange_strong(expected, ParseState::PROCESSING))
-                parse_buffer=get_buffer()->get_text();
-              parse_lock.unlock();
-            }
-            else
-              parse_state.compare_exchange_strong(expected, ParseState::STARTING);
-          });
+
+    get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->insert(renderer.get(), -40);
+    parse_state = ParseState::STARTING;
+    parse_stop = false;
+    monitor_changed = false;
+
+    buffer_insert_connection = get_buffer()->signal_insert().connect(
+            [this](const Gtk::TextBuffer::iterator &iter, const Glib::ustring &text, int) {
+                //Do not perform git diff if no newline is added and line is already marked as added
+                if (!iter.starts_line() && iter.has_tag(renderer->tag_added)) {
+                    bool newline = false;
+                    for (auto &c: text.raw()) {
+                        if (c == '\n') {
+                            newline = true;
+                            break;
+                        }
+                    }
+                    if (!newline)
+                        return;
+                }
+                    //Remove tag_removed_above/below if newline is inserted
+                else if (!text.empty() && text[0] == '\n' && iter.has_tag(renderer->tag_removed)) {
+                    auto start_iter = get_buffer()->get_iter_at_line(iter.get_line());
+                    auto end_iter = get_iter_at_line_end(iter.get_line());
+                    end_iter.forward_char();
+                    get_buffer()->remove_tag(renderer->tag_removed_above, start_iter, end_iter);
+                    get_buffer()->remove_tag(renderer->tag_removed_below, start_iter, end_iter);
+                }
+                parse_state = ParseState::IDLE;
+                delayed_buffer_changed_connection.disconnect();
+                delayed_buffer_changed_connection = Glib::signal_timeout().connect([this]() {
+                    parse_state = ParseState::STARTING;
+                    return false;
+                }, 250);
+            }, false);
+
+    buffer_erase_connection = get_buffer()->signal_erase().connect(
+            [this](const Gtk::TextBuffer::iterator &start_iter, const Gtk::TextBuffer::iterator &end_iter) {
+                //Do not perform git diff if start_iter and end_iter is at the same line in addition to the line is tagged added
+                if (start_iter.get_line() == end_iter.get_line() && start_iter.has_tag(renderer->tag_added))
+                    return;
+
+                parse_state = ParseState::IDLE;
+                delayed_buffer_changed_connection.disconnect();
+                delayed_buffer_changed_connection = Glib::signal_timeout().connect([this]() {
+                    parse_state = ParseState::STARTING;
+                    return false;
+                }, 250);
+            }, false);
+
+    monitor_changed_connection = repository->monitor->signal_changed().connect(
+            [this](const Glib::RefPtr<Gio::File> &file,
+                   const Glib::RefPtr<Gio::File> &,
+                   Gio::FileMonitorEvent monitor_event) {
+                if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+                    delayed_monitor_changed_connection.disconnect();
+                    delayed_monitor_changed_connection = Glib::signal_timeout().connect([this]() {
+                        monitor_changed = true;
+                        parse_state = ParseState::STARTING;
+                        std::unique_lock<std::mutex> lock(parse_mutex);
+                        diff = nullptr;
+                        return false;
+                    }, 500);
+                }
+            });
+
+    parse_thread = std::thread([this]() {
+        std::string status_branch;
+        try {
+            diff = get_diff();
+            status_branch = repository->get_branch();
         }
-        else if (parse_state==ParseState::PROCESSING && parse_lock.try_lock()) {
-          bool expected_monitor_changed=true;
-          if(monitor_changed.compare_exchange_strong(expected_monitor_changed, false)) {
-            try {
-              diff=get_diff();
-              dispatcher.post([this, status_branch=repository->get_branch()] {
-                this->status_branch=status_branch;
-                if(update_status_branch)
-                  update_status_branch(this);
-              });
+        catch (const std::exception &) {
+            status_branch = "";
+        }
+        dispatcher.post([this, status_branch = std::move(status_branch)] {
+            this->status_branch = status_branch;
+            if (update_status_branch)
+                update_status_branch(this);
+        });
+
+        try {
+            while (true) {
+                while (!parse_stop && parse_state != ParseState::STARTING && parse_state != ParseState::PROCESSING)
+                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
+                if (parse_stop)
+                    break;
+                std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+                auto expected = ParseState::STARTING;
+                if (parse_state.compare_exchange_strong(expected, ParseState::PREPROCESSING)) {
+                    dispatcher.post([this] {
+                        auto expected = ParseState::PREPROCESSING;
+                        std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+                        if (parse_lock.try_lock()) {
+                            if (parse_state.compare_exchange_strong(expected, ParseState::PROCESSING))
+                                parse_buffer = get_buffer()->get_text();
+                            parse_lock.unlock();
+                        } else
+                            parse_state.compare_exchange_strong(expected, ParseState::STARTING);
+                    });
+                } else if (parse_state == ParseState::PROCESSING && parse_lock.try_lock()) {
+                    bool expected_monitor_changed = true;
+                    if (monitor_changed.compare_exchange_strong(expected_monitor_changed, false)) {
+                        try {
+                            diff = get_diff();
+                            dispatcher.post([this, status_branch = repository->get_branch()] {
+                                this->status_branch = status_branch;
+                                if (update_status_branch)
+                                    update_status_branch(this);
+                            });
+                        }
+                        catch (const std::exception &) {
+                            dispatcher.post([this] {
+                                get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(),
+                                                         get_buffer()->end());
+                                get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(),
+                                                         get_buffer()->end());
+                                get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(),
+                                                         get_buffer()->end());
+                                get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(),
+                                                         get_buffer()->end());
+                                get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(),
+                                                         get_buffer()->end());
+                                renderer->queue_draw();
+                                this->status_branch = "";
+                                if (update_status_branch)
+                                    update_status_branch(this);
+                            });
+                        }
+                    }
+                    if (diff)
+                        lines = diff->get_lines(parse_buffer.raw());
+                    else {
+                        lines.added.clear();
+                        lines.modified.clear();
+                        lines.removed.clear();
+                    }
+                    auto expected = ParseState::PROCESSING;
+                    if (parse_state.compare_exchange_strong(expected, ParseState::POSTPROCESSING)) {
+                        parse_lock.unlock();
+                        dispatcher.post([this] {
+                            std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+                            if (parse_lock.try_lock()) {
+                                auto expected = ParseState::POSTPROCESSING;
+                                if (parse_state.compare_exchange_strong(expected, ParseState::IDLE))
+                                    update_lines();
+                            }
+                        });
+                    }
+                }
             }
-            catch(const std::exception &) {
-              dispatcher.post([this] {
+        }
+        catch (const std::exception &e) {
+            dispatcher.post([this, e_what = e.what()] {
                 get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(), get_buffer()->end());
                 get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(), get_buffer()->end());
                 get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(), get_buffer()->end());
                 get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
                 get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
                 renderer->queue_draw();
-                this->status_branch="";
-                if(update_status_branch)
-                  update_status_branch(this);
-              });
-            }
-          }
-          if(diff)
-            lines=diff->get_lines(parse_buffer.raw());
-          else {
-            lines.added.clear();
-            lines.modified.clear();
-            lines.removed.clear();
-          }
-          auto expected=ParseState::PROCESSING;
-          if(parse_state.compare_exchange_strong(expected, ParseState::POSTPROCESSING)) {
-            parse_lock.unlock();
-            dispatcher.post([this] {
-              std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-              if(parse_lock.try_lock()) {
-                auto expected=ParseState::POSTPROCESSING;
-                if(parse_state.compare_exchange_strong(expected, ParseState::IDLE))
-                  update_lines();
-              }
+                Terminal::get().print(std::string("Error (git): ") + e_what + '\n', true);
             });
-          }
         }
-      }
-    }
-    catch(const std::exception &e) {
-      dispatcher.post([this, e_what=e.what()] {
-        get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(), get_buffer()->end());
-        get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(), get_buffer()->end());
-        get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(), get_buffer()->end());
-        get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
-        get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
-        renderer->queue_draw();
-        Terminal::get().print(std::string("Error (git): ")+e_what+'\n', true);
-      });
-    }
-  });
+    });
 }
 
 void Source::DiffView::rename(const boost::filesystem::path &path) {
-  Source::BaseView::rename(path);
-  
-  std::lock_guard<std::mutex> lock(canonical_file_path_mutex);
-  boost::system::error_code ec;
-  canonical_file_path=boost::filesystem::canonical(path, ec);
-  if(ec)
-    canonical_file_path=path;
+    Source::BaseView::rename(path);
+
+    std::lock_guard<std::mutex> lock(canonical_file_path_mutex);
+    boost::system::error_code ec;
+    canonical_file_path = boost::filesystem::canonical(path, ec);
+    if (ec)
+        canonical_file_path = path;
 }
 
 void Source::DiffView::git_goto_next_diff() {
-  auto iter=get_buffer()->get_insert()->get_iter();
-  auto insert_iter=iter;
-  bool wrapped=false;
-  iter.forward_char();
-  for(;;) {
-    auto toggled_tags=iter.get_toggled_tags();
-    for(auto &toggled_tag: toggled_tags) {
-      if(toggled_tag->property_name()=="git_added" ||
-         toggled_tag->property_name()=="git_modified" ||
-         toggled_tag->property_name()=="git_removed") {
-        get_buffer()->place_cursor(iter);
-        scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-        return;
-      }
-    }
-    if(wrapped && (iter==insert_iter || iter==get_buffer()->end()))
-      break;
-    if(!wrapped && iter==get_buffer()->end()) {
-      iter=get_buffer()->begin();
-      wrapped=true;
+    auto iter = get_buffer()->get_insert()->get_iter();
+    auto insert_iter = iter;
+    bool wrapped = false;
+    iter.forward_char();
+    for (;;) {
+        auto toggled_tags = iter.get_toggled_tags();
+        for (auto &toggled_tag: toggled_tags) {
+            if (toggled_tag->property_name() == "git_added" ||
+                toggled_tag->property_name() == "git_modified" ||
+                toggled_tag->property_name() == "git_removed") {
+                get_buffer()->place_cursor(iter);
+                scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+                return;
+            }
+        }
+        if (wrapped && (iter == insert_iter || iter == get_buffer()->end()))
+            break;
+        if (!wrapped && iter == get_buffer()->end()) {
+            iter = get_buffer()->begin();
+            wrapped = true;
+        } else
+            iter.forward_char();
     }
-    else
-      iter.forward_char();
-  }
-  Info::get().print("No changes found in current buffer");
+    Info::get().print("No changes found in current buffer");
 }
 
 std::string Source::DiffView::git_get_diff_details() {
-  std::string details;
-  if(diff) {
-    auto line_nr=get_buffer()->get_insert()->get_iter().get_line();
-    auto iter=get_buffer()->get_iter_at_line(line_nr);
-    if(iter.has_tag(renderer->tag_removed_above))
-      --line_nr;
-    std::unique_lock<std::mutex> lock(parse_mutex);
-    parse_buffer=get_buffer()->get_text();
-    details=diff->get_details(parse_buffer.raw(), line_nr);
-  }
-  if(details.empty())
-    Info::get().print("No changes found at current line");
-  return details;
+    std::string details;
+    if (diff) {
+        auto line_nr = get_buffer()->get_insert()->get_iter().get_line();
+        auto iter = get_buffer()->get_iter_at_line(line_nr);
+        if (iter.has_tag(renderer->tag_removed_above))
+            --line_nr;
+        std::unique_lock<std::mutex> lock(parse_mutex);
+        parse_buffer = get_buffer()->get_text();
+        details = diff->get_details(parse_buffer.raw(), line_nr);
+    }
+    if (details.empty())
+        Info::get().print("No changes found at current line");
+    return details;
 }
 
 ///Return repository diff instance. Throws exception on error
 std::unique_ptr<Git::Repository::Diff> Source::DiffView::get_diff() {
-  auto work_path=filesystem::get_normal_path(repository->get_work_path());
-  boost::filesystem::path relative_path;
-  {
-    std::unique_lock<std::mutex> lock(canonical_file_path_mutex);
-    relative_path=filesystem::get_relative_path(canonical_file_path, work_path);
-    if(relative_path.empty())
-      throw std::runtime_error("not a relative path");
-  }
-  return std::make_unique<Git::Repository::Diff>(repository->get_diff(relative_path));
+    auto work_path = filesystem::get_normal_path(repository->get_work_path());
+    boost::filesystem::path relative_path;
+    {
+        std::unique_lock<std::mutex> lock(canonical_file_path_mutex);
+        relative_path = filesystem::get_relative_path(canonical_file_path, work_path);
+        if (relative_path.empty())
+            throw std::runtime_error("not a relative path");
+    }
+    return std::make_unique<Git::Repository::Diff>(repository->get_diff(relative_path));
 }
 
 void Source::DiffView::update_lines() {
-  get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(), get_buffer()->end());
-  get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(), get_buffer()->end());
-  get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(), get_buffer()->end());
-  get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
-  get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
-  
-  for(auto &added: lines.added) {
-    auto start_iter=get_buffer()->get_iter_at_line(added.first);
-    auto end_iter=get_iter_at_line_end(added.second-1);
-    end_iter.forward_char();
-    get_buffer()->apply_tag(renderer->tag_added, start_iter, end_iter);
-  }
-  for(auto &modified: lines.modified) {
-    auto start_iter=get_buffer()->get_iter_at_line(modified.first);
-    auto end_iter=get_iter_at_line_end(modified.second-1);
-    end_iter.forward_char();
-    get_buffer()->apply_tag(renderer->tag_modified, start_iter, end_iter);
-  }
-  for(auto &line_nr: lines.removed) {
-    Gtk::TextIter removed_start, removed_end;
-    if(line_nr>=0) {
-      auto start_iter=get_buffer()->get_iter_at_line(line_nr);
-      removed_start=start_iter;
-      auto end_iter=get_iter_at_line_end(line_nr);
-      end_iter.forward_char();
-      removed_end=end_iter;
-      get_buffer()->apply_tag(renderer->tag_removed_below, start_iter, end_iter);
+    get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(), get_buffer()->end());
+    get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(), get_buffer()->end());
+    get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(), get_buffer()->end());
+    get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
+    get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
+
+    for (auto &added: lines.added) {
+        auto start_iter = get_buffer()->get_iter_at_line(added.first);
+        auto end_iter = get_iter_at_line_end(added.second - 1);
+        end_iter.forward_char();
+        get_buffer()->apply_tag(renderer->tag_added, start_iter, end_iter);
     }
-    if(line_nr+1<get_buffer()->get_line_count()) {
-      auto start_iter=get_buffer()->get_iter_at_line(line_nr+1);
-      if(line_nr<0)
-        removed_start=start_iter;
-      auto end_iter=get_iter_at_line_end(line_nr+1);
-      end_iter.forward_char();
-      removed_end=end_iter;
-      get_buffer()->apply_tag(renderer->tag_removed_above, start_iter, end_iter);
+    for (auto &modified: lines.modified) {
+        auto start_iter = get_buffer()->get_iter_at_line(modified.first);
+        auto end_iter = get_iter_at_line_end(modified.second - 1);
+        end_iter.forward_char();
+        get_buffer()->apply_tag(renderer->tag_modified, start_iter, end_iter);
     }
-    get_buffer()->apply_tag(renderer->tag_removed, removed_start, removed_end);
-  }
-  
-  renderer->queue_draw();
+    for (auto &line_nr: lines.removed) {
+        Gtk::TextIter removed_start, removed_end;
+        if (line_nr >= 0) {
+            auto start_iter = get_buffer()->get_iter_at_line(line_nr);
+            removed_start = start_iter;
+            auto end_iter = get_iter_at_line_end(line_nr);
+            end_iter.forward_char();
+            removed_end = end_iter;
+            get_buffer()->apply_tag(renderer->tag_removed_below, start_iter, end_iter);
+        }
+        if (line_nr + 1 < get_buffer()->get_line_count()) {
+            auto start_iter = get_buffer()->get_iter_at_line(line_nr + 1);
+            if (line_nr < 0)
+                removed_start = start_iter;
+            auto end_iter = get_iter_at_line_end(line_nr + 1);
+            end_iter.forward_char();
+            removed_end = end_iter;
+            get_buffer()->apply_tag(renderer->tag_removed_above, start_iter, end_iter);
+        }
+        get_buffer()->apply_tag(renderer->tag_removed, removed_start, removed_end);
+    }
+
+    renderer->queue_draw();
 }
diff --git a/src/source_diff.h b/src/source_diff.h
index d1a7ece8..5f48f931 100644
--- a/src/source_diff.h
+++ b/src/source_diff.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include "source_base.h"
 #include <boost/filesystem.hpp>
 #include "dispatcher.h"
@@ -10,60 +11,67 @@
 #include "git.h"
 
 namespace Source {
-  class DiffView : virtual public Source::BaseView {
-    enum class ParseState {IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING};
-    
-    class Renderer : public Gsv::GutterRenderer {
+    class DiffView : virtual public Source::BaseView {
+        enum class ParseState {
+            IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING
+        };
+
+        class Renderer : public Gsv::GutterRenderer {
+        public:
+            Renderer();
+
+            Glib::RefPtr<Gtk::TextTag> tag_added;
+            Glib::RefPtr<Gtk::TextTag> tag_modified;
+            Glib::RefPtr<Gtk::TextTag> tag_removed;
+            Glib::RefPtr<Gtk::TextTag> tag_removed_below;
+            Glib::RefPtr<Gtk::TextTag> tag_removed_above;
+
+        protected:
+            void draw_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area,
+                            const Gdk::Rectangle &cell_area, Gtk::TextIter &start, Gtk::TextIter &end,
+                            Gsv::GutterRendererState p6) override;
+        };
+
     public:
-      Renderer();
-      
-      Glib::RefPtr<Gtk::TextTag> tag_added;
-      Glib::RefPtr<Gtk::TextTag> tag_modified;
-      Glib::RefPtr<Gtk::TextTag> tag_removed;
-      Glib::RefPtr<Gtk::TextTag> tag_removed_below;
-      Glib::RefPtr<Gtk::TextTag> tag_removed_above;
-      
-    protected:
-      void draw_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area,
-                      const Gdk::Rectangle &cell_area, Gtk::TextIter &start, Gtk::TextIter &end,
-                      Gsv::GutterRendererState p6) override;
+        DiffView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+
+        ~DiffView();
+
+        void configure() override;
+
+        void rename(const boost::filesystem::path &path) override;
+
+        void git_goto_next_diff();
+
+        std::string git_get_diff_details();
+
+        /// Use canonical path to follow symbolic links
+        boost::filesystem::path canonical_file_path;
+    private:
+        std::mutex canonical_file_path_mutex;
+
+        std::unique_ptr<Renderer> renderer;
+        Dispatcher dispatcher;
+
+        std::shared_ptr<Git::Repository> repository;
+        std::unique_ptr<Git::Repository::Diff> diff;
+
+        std::unique_ptr<Git::Repository::Diff> get_diff();
+
+        std::thread parse_thread;
+        std::atomic<ParseState> parse_state;
+        std::mutex parse_mutex;
+        std::atomic<bool> parse_stop;
+        Glib::ustring parse_buffer;
+        sigc::connection buffer_insert_connection;
+        sigc::connection buffer_erase_connection;
+        sigc::connection monitor_changed_connection;
+        sigc::connection delayed_buffer_changed_connection;
+        sigc::connection delayed_monitor_changed_connection;
+        std::atomic<bool> monitor_changed;
+
+        Git::Repository::Diff::Lines lines;
+
+        void update_lines();
     };
-  public:
-    DiffView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
-    ~DiffView();
-    
-    void configure() override;
-    
-    void rename(const boost::filesystem::path &path) override;
-    
-    void git_goto_next_diff();
-    std::string git_get_diff_details();
-    
-    /// Use canonical path to follow symbolic links
-    boost::filesystem::path canonical_file_path;
-  private:
-    std::mutex canonical_file_path_mutex;
-    
-    std::unique_ptr<Renderer> renderer;
-    Dispatcher dispatcher;
-    
-    std::shared_ptr<Git::Repository> repository;
-    std::unique_ptr<Git::Repository::Diff> diff;
-    std::unique_ptr<Git::Repository::Diff> get_diff();
-    
-    std::thread parse_thread;
-    std::atomic<ParseState> parse_state;
-    std::mutex parse_mutex;
-    std::atomic<bool> parse_stop;
-    Glib::ustring parse_buffer;
-    sigc::connection buffer_insert_connection;
-    sigc::connection buffer_erase_connection;
-    sigc::connection monitor_changed_connection;
-    sigc::connection delayed_buffer_changed_connection;
-    sigc::connection delayed_monitor_changed_connection;
-    std::atomic<bool> monitor_changed;
-    
-    Git::Repository::Diff::Lines lines;
-    void update_lines();
-  };
 }
diff --git a/src/source_language_protocol.cc b/src/source_language_protocol.cc
index d6d40eee..68c3b37c 100644
--- a/src/source_language_protocol.cc
+++ b/src/source_language_protocol.cc
@@ -4,1405 +4,1549 @@
 #include "terminal.h"
 #include "project.h"
 #include "filesystem.h"
+
 #ifdef JUCI_ENABLE_DEBUG
 #include "debug_lldb.h"
 #endif
+
 #include "menu.h"
 #include <regex>
 #include <future>
 #include <limits>
 
-const bool output_messages_and_errors=false;
+const bool output_messages_and_errors = false;
 
-LanguageProtocol::Client::Client(std::string root_uri_, std::string language_id_) : root_uri(std::move(root_uri_)), language_id(std::move(language_id_)) {
-  process = std::make_unique<TinyProcessLib::Process>(language_id+"-language-server", root_uri,
-                                                      [this](const char *bytes, size_t n) {
-    server_message_stream.write(bytes, n);
-    parse_server_message();
-  }, [](const char *bytes, size_t n) {
-    std::cerr.write(bytes, n);
-  }, true);
+LanguageProtocol::Client::Client(std::string root_uri_, std::string language_id_) : root_uri(std::move(root_uri_)),
+                                                                                    language_id(
+                                                                                            std::move(language_id_)) {
+    process = std::make_unique<TinyProcessLib::Process>(language_id + "-language-server", root_uri,
+                                                        [this](const char *bytes, size_t n) {
+                                                            server_message_stream.write(bytes, n);
+                                                            parse_server_message();
+                                                        }, [](const char *bytes, size_t n) {
+                std::cerr.write(bytes, n);
+            }, true);
 }
 
-std::shared_ptr<LanguageProtocol::Client> LanguageProtocol::Client::get(const boost::filesystem::path &file_path, const std::string &language_id) {
-  std::string root_uri;
-  auto build=Project::Build::create(file_path);
-  if(!build->project_path.empty())
-    root_uri=build->project_path.string();
-  else
-    root_uri=file_path.parent_path().string();
-  
-  auto cache_id=root_uri+'|'+language_id;
-  
-  static std::unordered_map<std::string, std::weak_ptr<Client>> cache;
-  static std::mutex mutex;
-  std::lock_guard<std::mutex> lock(mutex);
-  auto it=cache.find(cache_id);
-  if(it==cache.end())
-    it=cache.emplace(cache_id, std::weak_ptr<Client>()).first;
-  auto instance=it->second.lock();
-  if(!instance)
-    it->second=instance=std::shared_ptr<Client>(new Client(root_uri, language_id), [](Client *client_ptr) {
-      std::thread delete_thread([client_ptr] {
-        delete client_ptr;
-      });
-      delete_thread.detach();
-    });
-  return instance;
+std::shared_ptr<LanguageProtocol::Client>
+LanguageProtocol::Client::get(const boost::filesystem::path &file_path, const std::string &language_id) {
+    std::string root_uri;
+    auto build = Project::Build::create(file_path);
+    if (!build->project_path.empty())
+        root_uri = build->project_path.string();
+    else
+        root_uri = file_path.parent_path().string();
+
+    auto cache_id = root_uri + '|' + language_id;
+
+    static std::unordered_map<std::string, std::weak_ptr<Client>> cache;
+    static std::mutex mutex;
+    std::lock_guard<std::mutex> lock(mutex);
+    auto it = cache.find(cache_id);
+    if (it == cache.end())
+        it = cache.emplace(cache_id, std::weak_ptr<Client>()).first;
+    auto instance = it->second.lock();
+    if (!instance)
+        it->second = instance = std::shared_ptr<Client>(new Client(root_uri, language_id), [](Client *client_ptr) {
+            std::thread delete_thread([client_ptr] {
+                delete client_ptr;
+            });
+            delete_thread.detach();
+        });
+    return instance;
 }
 
 LanguageProtocol::Client::~Client() {
-  std::promise<void> result_processed;
-  write_request(nullptr, "shutdown", "", [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
-    if(!error)
-      this->write_notification("exit", "");
-    result_processed.set_value();
-  });
-  result_processed.get_future().get();
-  
-  std::unique_lock<std::mutex> lock(timeout_threads_mutex);
-  for(auto &thread: timeout_threads)
-    thread.join();
-  
-  int exit_status=-1;
-  for(size_t c=0;c<20;++c) {
-    std::this_thread::sleep_for(std::chrono::milliseconds(500));
-    if(process->try_get_exit_status(exit_status))
-      break;
-  }
-  if(output_messages_and_errors)
-    std::cout << "Language server exit status: " << exit_status << std::endl;
-  if(exit_status==-1)
-    process->kill();
+    std::promise<void> result_processed;
+    write_request(nullptr, "shutdown", "",
+                  [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
+                      if (!error)
+                          this->write_notification("exit", "");
+                      result_processed.set_value();
+                  });
+    result_processed.get_future().get();
+
+    std::unique_lock<std::mutex> lock(timeout_threads_mutex);
+    for (auto &thread: timeout_threads)
+        thread.join();
+
+    int exit_status = -1;
+    for (size_t c = 0; c < 20; ++c) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(500));
+        if (process->try_get_exit_status(exit_status))
+            break;
+    }
+    if (output_messages_and_errors)
+        std::cout << "Language server exit status: " << exit_status << std::endl;
+    if (exit_status == -1)
+        process->kill();
 }
 
 LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::LanguageProtocolView *view) {
-  if(view) {
-    std::unique_lock<std::mutex> lock(views_mutex);
-    views.emplace(view);
-  }
-  
-  std::lock_guard<std::mutex> lock(initialize_mutex);
-  
-  if(initialized)
-    return capabilities;
-  
-  std::promise<void> result_processed;
-  write_request(nullptr, "initialize", "\"processId\":"+std::to_string(process->get_id())+",\"rootUri\":\"file://"+root_uri+"\",\"capabilities\":{\"workspace\":{\"didChangeConfiguration\":{\"dynamicRegistration\":true},\"didChangeWatchedFiles\":{\"dynamicRegistration\":true},\"symbol\":{\"dynamicRegistration\":true},\"executeCommand\":{\"dynamicRegistration\":true}},\"textDocument\":{\"synchronization\":{\"dynamicRegistration\":true,\"willSave\":true,\"willSaveWaitUntil\":true,\"didSave\":true},\"completion\":{\"dynamicRegistration\":true,\"completionItem\":{\"snippetSupport\":true}},\"hover\":{\"dynamicRegistration\":true},\"signatureHelp\":{\"dynamicRegistration\":true},\"definition\":{\"dynamicRegistration\":true},\"references\":{\"dynamicRegistration\":true},\"documentHighlight\":{\"dynamicRegistration\":true},\"documentSymbol\":{\"dynamicRegistration\":true},\"codeAction\":{\"dynamicRegistration\":true},\"codeLens\":{\"dynamicRegistration\":true},\"formatting\":{\"dynamicRegistration\":true},\"rangeFormatting\":{\"dynamicRegistration\":true},\"onTypeFormatting\":{\"dynamicRegistration\":true},\"rename\":{\"dynamicRegistration\":true},\"documentLink\":{\"dynamicRegistration\":true}}},\"initializationOptions\":{\"omitInitBuild\":true},\"trace\":\"off\"", [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
-    if(!error) {
-      auto capabilities_pt=result.find("capabilities");
-      if(capabilities_pt!=result.not_found()) {
-        capabilities.text_document_sync=static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->second.get<unsigned>("textDocumentSync", 0));
-        capabilities.hover=capabilities_pt->second.get<bool>("hoverProvider", false);
-        capabilities.completion=capabilities_pt->second.find("completionProvider")!=capabilities_pt->second.not_found()?true:false;
-        capabilities.definition=capabilities_pt->second.get<bool>("definitionProvider", false);
-        capabilities.references=capabilities_pt->second.get<bool>("referencesProvider", false);
-        capabilities.document_highlight=capabilities_pt->second.get<bool>("documentHighlightProvider", false);
-        capabilities.workspace_symbol=capabilities_pt->second.get<bool>("workspaceSymbolProvider", false);
-        capabilities.document_formatting=capabilities_pt->second.get<bool>("documentFormattingProvider", false);
-        capabilities.document_range_formatting=capabilities_pt->second.get<bool>("documentRangeFormattingProvider", false);
-        capabilities.rename=capabilities_pt->second.get<bool>("renameProvider", false);
-      }
-      
-      write_notification("initialized", "");
-      if(language_id=="rust")
-        write_notification("workspace/didChangeConfiguration", "\"settings\":{\"rust\":{\"sysroot\":null,\"target\":null,\"rustflags\":null,\"clear_env_rust_log\":true,\"build_lib\":null,\"build_bin\":null,\"cfg_test\":false,\"unstable_features\":false,\"wait_to_build\":500,\"show_warnings\":true,\"goto_def_racer_fallback\":false,\"use_crate_blacklist\":true,\"build_on_save\":false,\"workspace_mode\":true,\"analyze_package\":null,\"features\":[],\"all_features\":false,\"no_default_features\":false}}");
+    if (view) {
+        std::unique_lock<std::mutex> lock(views_mutex);
+        views.emplace(view);
     }
-    result_processed.set_value();
-  });
-  result_processed.get_future().get();
-  
-  initialized=true;
-  return capabilities;
+
+    std::lock_guard<std::mutex> lock(initialize_mutex);
+
+    if (initialized)
+        return capabilities;
+
+    std::promise<void> result_processed;
+    write_request(nullptr, "initialize",
+                  "\"processId\":" + std::to_string(process->get_id()) + ",\"rootUri\":\"file://" + root_uri +
+                  "\",\"capabilities\":{\"workspace\":{\"didChangeConfiguration\":{\"dynamicRegistration\":true},\"didChangeWatchedFiles\":{\"dynamicRegistration\":true},\"symbol\":{\"dynamicRegistration\":true},\"executeCommand\":{\"dynamicRegistration\":true}},\"textDocument\":{\"synchronization\":{\"dynamicRegistration\":true,\"willSave\":true,\"willSaveWaitUntil\":true,\"didSave\":true},\"completion\":{\"dynamicRegistration\":true,\"completionItem\":{\"snippetSupport\":true}},\"hover\":{\"dynamicRegistration\":true},\"signatureHelp\":{\"dynamicRegistration\":true},\"definition\":{\"dynamicRegistration\":true},\"references\":{\"dynamicRegistration\":true},\"documentHighlight\":{\"dynamicRegistration\":true},\"documentSymbol\":{\"dynamicRegistration\":true},\"codeAction\":{\"dynamicRegistration\":true},\"codeLens\":{\"dynamicRegistration\":true},\"formatting\":{\"dynamicRegistration\":true},\"rangeFormatting\":{\"dynamicRegistration\":true},\"onTypeFormatting\":{\"dynamicRegistration\":true},\"rename\":{\"dynamicRegistration\":true},\"documentLink\":{\"dynamicRegistration\":true}}},\"initializationOptions\":{\"omitInitBuild\":true},\"trace\":\"off\"",
+                  [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
+                      if (!error) {
+                          auto capabilities_pt = result.find("capabilities");
+                          if (capabilities_pt != result.not_found()) {
+                              capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->second.get<unsigned>(
+                                      "textDocumentSync", 0));
+                              capabilities.hover = capabilities_pt->second.get<bool>("hoverProvider", false);
+                              capabilities.completion = capabilities_pt->second.find("completionProvider") !=
+                                                        capabilities_pt->second.not_found() ? true : false;
+                              capabilities.definition = capabilities_pt->second.get<bool>("definitionProvider", false);
+                              capabilities.references = capabilities_pt->second.get<bool>("referencesProvider", false);
+                              capabilities.document_highlight = capabilities_pt->second.get<bool>(
+                                      "documentHighlightProvider", false);
+                              capabilities.workspace_symbol = capabilities_pt->second.get<bool>(
+                                      "workspaceSymbolProvider", false);
+                              capabilities.document_formatting = capabilities_pt->second.get<bool>(
+                                      "documentFormattingProvider", false);
+                              capabilities.document_range_formatting = capabilities_pt->second.get<bool>(
+                                      "documentRangeFormattingProvider", false);
+                              capabilities.rename = capabilities_pt->second.get<bool>("renameProvider", false);
+                          }
+
+                          write_notification("initialized", "");
+                          if (language_id == "rust")
+                              write_notification("workspace/didChangeConfiguration",
+                                                 "\"settings\":{\"rust\":{\"sysroot\":null,\"target\":null,\"rustflags\":null,\"clear_env_rust_log\":true,\"build_lib\":null,\"build_bin\":null,\"cfg_test\":false,\"unstable_features\":false,\"wait_to_build\":500,\"show_warnings\":true,\"goto_def_racer_fallback\":false,\"use_crate_blacklist\":true,\"build_on_save\":false,\"workspace_mode\":true,\"analyze_package\":null,\"features\":[],\"all_features\":false,\"no_default_features\":false}}");
+                      }
+                      result_processed.set_value();
+                  });
+    result_processed.get_future().get();
+
+    initialized = true;
+    return capabilities;
 }
 
 void LanguageProtocol::Client::close(Source::LanguageProtocolView *view) {
-  {
-    std::unique_lock<std::mutex> lock(views_mutex);
-    auto it=views.find(view);
-    if(it!=views.end())
-      views.erase(it);
-  }
-  std::unique_lock<std::mutex> lock(read_write_mutex);
-  for(auto it=handlers.begin();it!=handlers.end();) {
-    if(it->second.first==view)
-      it=handlers.erase(it);
-    else
-      it++;
-  }
+    {
+        std::unique_lock<std::mutex> lock(views_mutex);
+        auto it = views.find(view);
+        if (it != views.end())
+            views.erase(it);
+    }
+    std::unique_lock<std::mutex> lock(read_write_mutex);
+    for (auto it = handlers.begin(); it != handlers.end();) {
+        if (it->second.first == view)
+            it = handlers.erase(it);
+        else
+            it++;
+    }
 }
 
 void LanguageProtocol::Client::parse_server_message() {
-  if(!header_read) {
-    std::string line;
-    while(!header_read && std::getline(server_message_stream, line)) {
-      if(!line.empty()) {
-        if(line.back()=='\r')
-          line.pop_back();
-        if(line.compare(0, 16, "Content-Length: ")==0) {
-          try {
-            server_message_size=static_cast<size_t>(std::stoul(line.substr(16)));
-          }
-          catch(...) {}
+    if (!header_read) {
+        std::string line;
+        while (!header_read && std::getline(server_message_stream, line)) {
+            if (!line.empty()) {
+                if (line.back() == '\r')
+                    line.pop_back();
+                if (line.compare(0, 16, "Content-Length: ") == 0) {
+                    try {
+                        server_message_size = static_cast<size_t>(std::stoul(line.substr(16)));
+                    }
+                    catch (...) {}
+                }
+            }
+            if (line.empty()) {
+                server_message_content_pos = server_message_stream.tellg();
+                server_message_size += server_message_content_pos;
+                header_read = true;
+            }
         }
-      }
-      if(line.empty()) {
-        server_message_content_pos=server_message_stream.tellg();
-        server_message_size+=server_message_content_pos;
-        header_read=true;
-      }
     }
-  }
-  
-  if(header_read) {
-    server_message_stream.seekg(0, std::ios::end);
-    size_t read_size=server_message_stream.tellg();
-    std::stringstream tmp;
-    if(read_size>=server_message_size) {
-      if(read_size>server_message_size) {
-        server_message_stream.seekg(server_message_size, std::ios::beg);
-        server_message_stream.seekp(server_message_size, std::ios::beg);
-        for(size_t c=server_message_size;c<read_size;++c) {
-          tmp.put(server_message_stream.get());
-          server_message_stream.put(' ');
-        }
-      }
-      
-      server_message_stream.seekg(server_message_content_pos, std::ios::beg);
-      boost::property_tree::ptree pt;
-      boost::property_tree::read_json(server_message_stream, pt);
-      
-      if(output_messages_and_errors) {
-        std::cout << "language server: ";
-        boost::property_tree::write_json(std::cout, pt);
-      }
-      
-      auto message_id=pt.get<size_t>("id", 0);
-      auto result_it=pt.find("result");
-      auto error_it=pt.find("error");
-      {
-        std::unique_lock<std::mutex> lock(read_write_mutex);
-        if(result_it!=pt.not_found()) {
-          if(message_id) {
-            auto id_it=handlers.find(message_id);
-            if(id_it!=handlers.end()) {
-              auto function=std::move(id_it->second.second);
-              handlers.erase(id_it->first);
-              lock.unlock();
-              function(result_it->second, false);
-              lock.lock();
+
+    if (header_read) {
+        server_message_stream.seekg(0, std::ios::end);
+        size_t read_size = server_message_stream.tellg();
+        std::stringstream tmp;
+        if (read_size >= server_message_size) {
+            if (read_size > server_message_size) {
+                server_message_stream.seekg(server_message_size, std::ios::beg);
+                server_message_stream.seekp(server_message_size, std::ios::beg);
+                for (size_t c = server_message_size; c < read_size; ++c) {
+                    tmp.put(server_message_stream.get());
+                    server_message_stream.put(' ');
+                }
             }
-          }
-        }
-        else if(error_it!=pt.not_found()) {
-          if(!output_messages_and_errors)
-            boost::property_tree::write_json(std::cerr, pt);
-          if(message_id) {
-            auto id_it=handlers.find(message_id);
-            if(id_it!=handlers.end()) {
-              auto function=std::move(id_it->second.second);
-              handlers.erase(id_it->first);
-              lock.unlock();
-              function(result_it->second, true);
-              lock.lock();
+
+            server_message_stream.seekg(server_message_content_pos, std::ios::beg);
+            boost::property_tree::ptree pt;
+            boost::property_tree::read_json(server_message_stream, pt);
+
+            if (output_messages_and_errors) {
+                std::cout << "language server: ";
+                boost::property_tree::write_json(std::cout, pt);
             }
-          }
-        }
-        else {
-          auto method_it=pt.find("method");
-          if(method_it!=pt.not_found()) {
-            auto params_it=pt.find("params");
-            if(params_it!=pt.not_found()) {
-              lock.unlock();
-              handle_server_request(method_it->second.get_value<std::string>(""), params_it->second);
-              lock.lock();
+
+            auto message_id = pt.get<size_t>("id", 0);
+            auto result_it = pt.find("result");
+            auto error_it = pt.find("error");
+            {
+                std::unique_lock<std::mutex> lock(read_write_mutex);
+                if (result_it != pt.not_found()) {
+                    if (message_id) {
+                        auto id_it = handlers.find(message_id);
+                        if (id_it != handlers.end()) {
+                            auto function = std::move(id_it->second.second);
+                            handlers.erase(id_it->first);
+                            lock.unlock();
+                            function(result_it->second, false);
+                            lock.lock();
+                        }
+                    }
+                } else if (error_it != pt.not_found()) {
+                    if (!output_messages_and_errors)
+                        boost::property_tree::write_json(std::cerr, pt);
+                    if (message_id) {
+                        auto id_it = handlers.find(message_id);
+                        if (id_it != handlers.end()) {
+                            auto function = std::move(id_it->second.second);
+                            handlers.erase(id_it->first);
+                            lock.unlock();
+                            function(result_it->second, true);
+                            lock.lock();
+                        }
+                    }
+                } else {
+                    auto method_it = pt.find("method");
+                    if (method_it != pt.not_found()) {
+                        auto params_it = pt.find("params");
+                        if (params_it != pt.not_found()) {
+                            lock.unlock();
+                            handle_server_request(method_it->second.get_value<std::string>(""), params_it->second);
+                            lock.lock();
+                        }
+                    }
+                }
+            }
+
+            server_message_stream = std::stringstream();
+            header_read = false;
+            server_message_size = static_cast<size_t>(-1);
+
+            tmp.seekg(0, std::ios::end);
+            if (tmp.tellg() > 0) {
+                tmp.seekg(0, std::ios::beg);
+                server_message_stream << tmp.rdbuf();
+                parse_server_message();
             }
-          }
         }
-      }
-      
-      server_message_stream=std::stringstream();
-      header_read=false;
-      server_message_size=static_cast<size_t>(-1);
-      
-      tmp.seekg(0, std::ios::end);
-      if(tmp.tellg()>0) {
-        tmp.seekg(0, std::ios::beg);
-        server_message_stream << tmp.rdbuf();
-        parse_server_message();
-      }
     }
-  }
 }
 
-void LanguageProtocol::Client::write_request(Source::LanguageProtocolView *view, const std::string &method, const std::string &params, std::function<void(const boost::property_tree::ptree &, bool error)> &&function) {
-  std::unique_lock<std::mutex> lock(read_write_mutex);
-  if(function) {
-    handlers.emplace(message_id, std::make_pair(view, std::move(function)));
-    
-    auto message_id=this->message_id;
-    std::unique_lock<std::mutex> lock(timeout_threads_mutex);
-    timeout_threads.emplace_back([this, message_id] {
-      for(size_t c=0;c<20;++c) {
-        std::this_thread::sleep_for(std::chrono::milliseconds(500));
-        std::unique_lock<std::mutex> lock(read_write_mutex);
-        auto id_it=handlers.find(message_id);
-        if(id_it==handlers.end())
-          return;
-      }
-      std::unique_lock<std::mutex> lock(read_write_mutex);
-      auto id_it=handlers.find(message_id);
-      if(id_it!=handlers.end()) {
-        auto function=std::move(id_it->second.second);
-        handlers.erase(id_it->first);
-        lock.unlock();
-        function(boost::property_tree::ptree(), false);
-        lock.lock();
-      }
-    });
-  }
-  std::string content("{\"jsonrpc\":\"2.0\",\"id\":"+std::to_string(message_id++)+",\"method\":\""+method+"\",\"params\":{"+params+"}}");
-  auto message="Content-Length: "+std::to_string(content.size())+"\r\n\r\n"+content;
-  if(output_messages_and_errors)
-    std::cout << "Language client: " << content << std::endl;
-  if(!process->write(message)) {
-    Terminal::get().async_print("Error writing to language protocol server. Please close and reopen all project source files.\n", true);
-    auto id_it=handlers.find(message_id-1);
-    if(id_it!=handlers.end()) {
-      auto function=std::move(id_it->second.second);
-      handlers.erase(id_it->first);
-      lock.unlock();
-      function(boost::property_tree::ptree(), false);
-      lock.lock();
+void LanguageProtocol::Client::write_request(Source::LanguageProtocolView *view, const std::string &method,
+                                             const std::string &params,
+                                             std::function<void(const boost::property_tree::ptree &,
+                                                                bool error)> &&function) {
+    std::unique_lock<std::mutex> lock(read_write_mutex);
+    if (function) {
+        handlers.emplace(message_id, std::make_pair(view, std::move(function)));
+
+        auto message_id = this->message_id;
+        std::unique_lock<std::mutex> lock(timeout_threads_mutex);
+        timeout_threads.emplace_back([this, message_id] {
+            for (size_t c = 0; c < 20; ++c) {
+                std::this_thread::sleep_for(std::chrono::milliseconds(500));
+                std::unique_lock<std::mutex> lock(read_write_mutex);
+                auto id_it = handlers.find(message_id);
+                if (id_it == handlers.end())
+                    return;
+            }
+            std::unique_lock<std::mutex> lock(read_write_mutex);
+            auto id_it = handlers.find(message_id);
+            if (id_it != handlers.end()) {
+                auto function = std::move(id_it->second.second);
+                handlers.erase(id_it->first);
+                lock.unlock();
+                function(boost::property_tree::ptree(), false);
+                lock.lock();
+            }
+        });
+    }
+    std::string content("{\"jsonrpc\":\"2.0\",\"id\":" + std::to_string(message_id++) + ",\"method\":\"" + method +
+                        "\",\"params\":{" + params + "}}");
+    auto message = "Content-Length: " + std::to_string(content.size()) + "\r\n\r\n" + content;
+    if (output_messages_and_errors)
+        std::cout << "Language client: " << content << std::endl;
+    if (!process->write(message)) {
+        Terminal::get().async_print(
+                "Error writing to language protocol server. Please close and reopen all project source files.\n", true);
+        auto id_it = handlers.find(message_id - 1);
+        if (id_it != handlers.end()) {
+            auto function = std::move(id_it->second.second);
+            handlers.erase(id_it->first);
+            lock.unlock();
+            function(boost::property_tree::ptree(), false);
+            lock.lock();
+        }
     }
-  }
 }
 
 void LanguageProtocol::Client::write_notification(const std::string &method, const std::string &params) {
-  std::unique_lock<std::mutex> lock(read_write_mutex);
-  std::string content("{\"jsonrpc\":\"2.0\",\"method\":\""+method+"\",\"params\":{"+params+"}}");
-  auto message="Content-Length: "+std::to_string(content.size())+"\r\n\r\n"+content;
-  if(output_messages_and_errors)
-    std::cout << "Language client: " << content << std::endl;
-  process->write(message);
+    std::unique_lock<std::mutex> lock(read_write_mutex);
+    std::string content("{\"jsonrpc\":\"2.0\",\"method\":\"" + method + "\",\"params\":{" + params + "}}");
+    auto message = "Content-Length: " + std::to_string(content.size()) + "\r\n\r\n" + content;
+    if (output_messages_and_errors)
+        std::cout << "Language client: " << content << std::endl;
+    process->write(message);
 }
 
-void LanguageProtocol::Client::handle_server_request(const std::string &method, const boost::property_tree::ptree &params) {
-  if(method=="textDocument/publishDiagnostics") {
-    std::vector<Diagnostic> diagnostics;
-    auto uri=params.get<std::string>("uri", "");
-    if(!uri.empty()) {
-      auto diagnostics_pt=params.get_child("diagnostics", boost::property_tree::ptree());
-      for(auto it=diagnostics_pt.begin();it!=diagnostics_pt.end();++it) {
-        auto range_it=it->second.find("range");
-        if(range_it!=it->second.not_found()) {
-          auto start_it=range_it->second.find("start");
-          auto end_it=range_it->second.find("end");
-          if(start_it!=range_it->second.not_found() && start_it!=range_it->second.not_found()) {
-            diagnostics.emplace_back(Diagnostic{it->second.get<std::string>("message", ""),
-                                                std::make_pair<Source::Offset, Source::Offset>(Source::Offset(start_it->second.get<unsigned>("line", 0), start_it->second.get<unsigned>("character", 0)),
-                                                                                               Source::Offset(end_it->second.get<unsigned>("line", 0), end_it->second.get<unsigned>("character", 0))),
-                                                it->second.get<unsigned>("severity", 0), uri});
-          }
-        }
-      }
-      std::unique_lock<std::mutex> lock(views_mutex);
-      for(auto view: views) {
-        if(view->uri==uri) {
-          view->update_diagnostics(std::move(diagnostics));
-          break;
+void
+LanguageProtocol::Client::handle_server_request(const std::string &method, const boost::property_tree::ptree &params) {
+    if (method == "textDocument/publishDiagnostics") {
+        std::vector<Diagnostic> diagnostics;
+        auto uri = params.get<std::string>("uri", "");
+        if (!uri.empty()) {
+            auto diagnostics_pt = params.get_child("diagnostics", boost::property_tree::ptree());
+            for (auto it = diagnostics_pt.begin(); it != diagnostics_pt.end(); ++it) {
+                auto range_it = it->second.find("range");
+                if (range_it != it->second.not_found()) {
+                    auto start_it = range_it->second.find("start");
+                    auto end_it = range_it->second.find("end");
+                    if (start_it != range_it->second.not_found() && start_it != range_it->second.not_found()) {
+                        diagnostics.emplace_back(Diagnostic{it->second.get<std::string>("message", ""),
+                                                            std::make_pair<Source::Offset, Source::Offset>(
+                                                                    Source::Offset(
+                                                                            start_it->second.get<unsigned>("line", 0),
+                                                                            start_it->second.get<unsigned>("character",
+                                                                                                           0)),
+                                                                    Source::Offset(
+                                                                            end_it->second.get<unsigned>("line", 0),
+                                                                            end_it->second.get<unsigned>("character",
+                                                                                                         0))),
+                                                            it->second.get<unsigned>("severity", 0), uri});
+                    }
+                }
+            }
+            std::unique_lock<std::mutex> lock(views_mutex);
+            for (auto view: views) {
+                if (view->uri == uri) {
+                    view->update_diagnostics(std::move(diagnostics));
+                    break;
+                }
+            }
         }
-      }
     }
-  }
 }
 
-Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language, std::string language_id_)
-    : Source::BaseView(file_path, language), Source::View(file_path, language), uri("file://"+file_path.string()), language_id(std::move(language_id_)), client(LanguageProtocol::Client::get(file_path, language_id)), autocomplete(this, interactive_completion, last_keyval, false) {
-  configure();
-  get_source_buffer()->set_language(language);
-  get_source_buffer()->set_highlight_syntax(true);
-  
-  similar_symbol_tag=get_buffer()->create_tag();
-  similar_symbol_tag->property_weight()=Pango::WEIGHT_ULTRAHEAVY;
-  
-  status_state="initializing...";
-  if(update_status_state)
-    update_status_state(this);
-  
-  if(language_id=="javascript") {
-    boost::filesystem::path project_path;
-    auto build=Project::Build::create(file_path);
-    if(auto npm_build=dynamic_cast<Project::NpmBuild*>(build.get())) {
-      boost::system::error_code ec;
-      if(!npm_build->project_path.empty() && boost::filesystem::exists(npm_build->project_path/".flowconfig", ec)) {
-        auto executable=npm_build->project_path/"node_modules"/".bin"/"flow"; // It is recommended to use Flow binary installed in project, despite the security risk of doing so...
-        if(boost::filesystem::exists(executable, ec))
-          flow_coverage_executable=executable;
-        else
-          flow_coverage_executable=filesystem::find_executable("flow");
-      }
+Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path &file_path,
+                                                   Glib::RefPtr<Gsv::Language> language, std::string language_id_)
+        : Source::BaseView(file_path, language), Source::View(file_path, language), uri("file://" + file_path.string()),
+          language_id(std::move(language_id_)), client(LanguageProtocol::Client::get(file_path, language_id)),
+          autocomplete(this, interactive_completion, last_keyval, false) {
+    configure();
+    get_source_buffer()->set_language(language);
+    get_source_buffer()->set_highlight_syntax(true);
+
+    similar_symbol_tag = get_buffer()->create_tag();
+    similar_symbol_tag->property_weight() = Pango::WEIGHT_ULTRAHEAVY;
+
+    status_state = "initializing...";
+    if (update_status_state)
+        update_status_state(this);
+
+    if (language_id == "javascript") {
+        boost::filesystem::path project_path;
+        auto build = Project::Build::create(file_path);
+        if (auto npm_build = dynamic_cast<Project::NpmBuild *>(build.get())) {
+            boost::system::error_code ec;
+            if (!npm_build->project_path.empty() &&
+                boost::filesystem::exists(npm_build->project_path / ".flowconfig", ec)) {
+                auto executable = npm_build->project_path / "node_modules" / ".bin" /
+                                  "flow"; // It is recommended to use Flow binary installed in project, despite the security risk of doing so...
+                if (boost::filesystem::exists(executable, ec))
+                    flow_coverage_executable = executable;
+                else
+                    flow_coverage_executable = filesystem::find_executable("flow");
+            }
+        }
     }
-  }
-  
-  initialize_thread=std::thread([this] {
-    auto capabilities=client->initialize(this);
-    
-    if(!flow_coverage_executable.empty())
-      add_flow_coverage_tooltips(true);
-    
-    dispatcher.post([this, capabilities] {
-      this->capabilities=capabilities;
-      
-      std::string text=get_buffer()->get_text();
-      escape_text(text);
-      client->write_notification("textDocument/didOpen", "\"textDocument\":{\"uri\":\""+uri+"\",\"languageId\":\""+language_id+"\",\"version\":"+std::to_string(document_version++)+",\"text\":\""+text+"\"}");
-      
-      setup_autocomplete();
-      setup_navigation_and_refactoring();
-      Menu::get().toggle_menu_items();
-      
-      if(status_state=="initializing...") {
-        status_state="";
-        if(update_status_state)
-          update_status_state(this);
-      }
+
+    initialize_thread = std::thread([this] {
+        auto capabilities = client->initialize(this);
+
+        if (!flow_coverage_executable.empty())
+            add_flow_coverage_tooltips(true);
+
+        dispatcher.post([this, capabilities] {
+            this->capabilities = capabilities;
+
+            std::string text = get_buffer()->get_text();
+            escape_text(text);
+            client->write_notification("textDocument/didOpen",
+                                       "\"textDocument\":{\"uri\":\"" + uri + "\",\"languageId\":\"" + language_id +
+                                       "\",\"version\":" + std::to_string(document_version++) + ",\"text\":\"" + text +
+                                       "\"}");
+
+            setup_autocomplete();
+            setup_navigation_and_refactoring();
+            Menu::get().toggle_menu_items();
+
+            if (status_state == "initializing...") {
+                status_state = "";
+                if (update_status_state)
+                    update_status_state(this);
+            }
+        });
     });
-  });
-  
-  get_buffer()->signal_changed().connect([this] {
-    get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(), get_buffer()->end());
-  });
-  
-  get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-    if(mark->get_name() == "insert") {
-      delayed_tag_similar_symbols_connection.disconnect();
-      delayed_tag_similar_symbols_connection=Glib::signal_timeout().connect([this]() {
-        tag_similar_symbols();
-        return false;
-      }, 200);
-    }
-  });
-
-  get_buffer()->signal_insert().connect([this](const Gtk::TextBuffer::iterator &start, const Glib::ustring &text_, int bytes) {
-    std::string content_changes;
-    if(capabilities.text_document_sync==LanguageProtocol::Capabilities::TextDocumentSync::NONE)
-      return;
-    if(capabilities.text_document_sync==LanguageProtocol::Capabilities::TextDocumentSync::INCREMENTAL) {
-      std::string text=text_;
-      escape_text(text);
-      content_changes="{\"range\":{\"start\":{\"line\": "+std::to_string(start.get_line())+",\"character\":"+std::to_string(start.get_line_offset())+"},\"end\":{\"line\":"+std::to_string(start.get_line())+",\"character\":"+std::to_string(start.get_line_offset())+"}},\"text\":\""+text+"\"}";
-    }
-    else {
-      std::string text=get_buffer()->get_text();
-      escape_text(text);
-      content_changes="{\"text\":\""+text+"\"}";
-    }
-    client->write_notification("textDocument/didChange", "\"textDocument\":{\"uri\":\""+uri+"\",\"version\":"+std::to_string(document_version++)+"},\"contentChanges\":["+content_changes+"]");
-  }, false);
-
-  get_buffer()->signal_erase().connect([this](const Gtk::TextBuffer::iterator &start, const Gtk::TextBuffer::iterator &end) {
-    std::string content_changes;
-    if(capabilities.text_document_sync==LanguageProtocol::Capabilities::TextDocumentSync::NONE)
-      return;
-    if(capabilities.text_document_sync==LanguageProtocol::Capabilities::TextDocumentSync::INCREMENTAL)
-      content_changes="{\"range\":{\"start\":{\"line\": "+std::to_string(start.get_line())+",\"character\":"+std::to_string(start.get_line_offset())+"},\"end\":{\"line\":"+std::to_string(end.get_line())+",\"character\":"+std::to_string(end.get_line_offset())+"}},\"text\":\"\"}";
-    else {
-      std::string text=get_buffer()->get_text();
-      escape_text(text);
-      content_changes="{\"text\":\""+text+"\"}";
-    }
-    client->write_notification("textDocument/didChange", "\"textDocument\":{\"uri\":\""+uri+"\",\"version\":"+std::to_string(document_version++)+"},\"contentChanges\":["+content_changes+"]");
-  }, false);
+
+    get_buffer()->signal_changed().connect([this] {
+        get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(), get_buffer()->end());
+    });
+
+    get_buffer()->signal_mark_set().connect(
+            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+                if (mark->get_name() == "insert") {
+                    delayed_tag_similar_symbols_connection.disconnect();
+                    delayed_tag_similar_symbols_connection = Glib::signal_timeout().connect([this]() {
+                        tag_similar_symbols();
+                        return false;
+                    }, 200);
+                }
+            });
+
+    get_buffer()->signal_insert().connect(
+            [this](const Gtk::TextBuffer::iterator &start, const Glib::ustring &text_, int bytes) {
+                std::string content_changes;
+                if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::NONE)
+                    return;
+                if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::INCREMENTAL) {
+                    std::string text = text_;
+                    escape_text(text);
+                    content_changes =
+                            "{\"range\":{\"start\":{\"line\": " + std::to_string(start.get_line()) + ",\"character\":" +
+                            std::to_string(start.get_line_offset()) + "},\"end\":{\"line\":" +
+                            std::to_string(start.get_line()) + ",\"character\":" +
+                            std::to_string(start.get_line_offset()) + "}},\"text\":\"" + text + "\"}";
+                } else {
+                    std::string text = get_buffer()->get_text();
+                    escape_text(text);
+                    content_changes = "{\"text\":\"" + text + "\"}";
+                }
+                client->write_notification("textDocument/didChange",
+                                           "\"textDocument\":{\"uri\":\"" + uri + "\",\"version\":" +
+                                           std::to_string(document_version++) + "},\"contentChanges\":[" +
+                                           content_changes + "]");
+            }, false);
+
+    get_buffer()->signal_erase().connect(
+            [this](const Gtk::TextBuffer::iterator &start, const Gtk::TextBuffer::iterator &end) {
+                std::string content_changes;
+                if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::NONE)
+                    return;
+                if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::INCREMENTAL)
+                    content_changes =
+                            "{\"range\":{\"start\":{\"line\": " + std::to_string(start.get_line()) + ",\"character\":" +
+                            std::to_string(start.get_line_offset()) + "},\"end\":{\"line\":" +
+                            std::to_string(end.get_line()) + ",\"character\":" + std::to_string(end.get_line_offset()) +
+                            "}},\"text\":\"\"}";
+                else {
+                    std::string text = get_buffer()->get_text();
+                    escape_text(text);
+                    content_changes = "{\"text\":\"" + text + "\"}";
+                }
+                client->write_notification("textDocument/didChange",
+                                           "\"textDocument\":{\"uri\":\"" + uri + "\",\"version\":" +
+                                           std::to_string(document_version++) + "},\"contentChanges\":[" +
+                                           content_changes + "]");
+            }, false);
 }
 
 Source::LanguageProtocolView::~LanguageProtocolView() {
-  if(initialize_thread.joinable())
-    initialize_thread.join();
-  
-  autocomplete.state=Autocomplete::State::IDLE;
-  if(autocomplete.thread.joinable())
-    autocomplete.thread.join();
-  
-  client->write_notification("textDocument/didClose", "\"textDocument\":{\"uri\":\""+uri+"\"}");
-  client->close(this);
-  
-  client=nullptr;
+    delayed_tag_similar_symbols_connection.disconnect();
+
+    if (initialize_thread.joinable())
+        initialize_thread.join();
+
+    autocomplete.state = Autocomplete::State::IDLE;
+    if (autocomplete.thread.joinable())
+        autocomplete.thread.join();
+
+    client->write_notification("textDocument/didClose", "\"textDocument\":{\"uri\":\"" + uri + "\"}");
+    client->close(this);
+
+    client = nullptr;
 }
 
 bool Source::LanguageProtocolView::save() {
-  if(!Source::View::save())
-    return false;
-  
-  if(!flow_coverage_executable.empty())
-    add_flow_coverage_tooltips(false);
-  
-  return true;
+    if (!Source::View::save())
+        return false;
+
+    if (!flow_coverage_executable.empty())
+        add_flow_coverage_tooltips(false);
+
+    return true;
 }
 
 void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
-  if(capabilities.document_formatting) {
-    format_style=[this](bool continue_without_style_file) {
-      if(!continue_without_style_file) {
-        bool has_style_file=false;
-        auto style_file_search_path=this->file_path.parent_path();
-        auto style_file='.'+language_id+"-format";
-        
-        while(true) {
-          if(boost::filesystem::exists(style_file_search_path/style_file)) {
-            has_style_file=true;
-            break;
-          }
-          if(style_file_search_path==style_file_search_path.root_directory())
-            break;
-          style_file_search_path=style_file_search_path.parent_path();
-        }
-        
-        if(!has_style_file && !continue_without_style_file)
-          return;
-      }
-      
-      class Replace {
-      public:
-        Offset start, end;
-        std::string text;
-      };
-      std::vector<Replace> replaces;
-      std::promise<void> result_processed;
-      
-      std::string method;
-      std::string params;
-      std::string options("\"tabSize\":"+std::to_string(tab_size)+",\"insertSpaces\":"+(tab_char==' '?"true":"false"));
-      if(get_buffer()->get_has_selection() && capabilities.document_range_formatting) {
-        method="textDocument/rangeFormatting";
-        Gtk::TextIter start, end;
-        get_buffer()->get_selection_bounds(start, end);
-        params="\"textDocument\":{\"uri\":\""+uri+"\"},\"range\":{\"start\":{\"line\":"+std::to_string(start.get_line())+",\"character\":"+std::to_string(start.get_line_offset())+"},\"end\":{\"line\":"+std::to_string(end.get_line())+",\"character\":"+std::to_string(end.get_line_offset())+"}},\"options\":{"+options+"}";
-      }
-      else {
-        method="textDocument/formatting";
-        params="\"textDocument\":{\"uri\":\""+uri+"\"},\"options\":{"+options+"}";
-      }
-      
-      client->write_request(this, method, params, [&replaces, &result_processed](const boost::property_tree::ptree &result, bool error) {
-        if(!error) {
-          for(auto it=result.begin();it!=result.end();++it) {
-            auto range_it=it->second.find("range");
-            auto text_it=it->second.find("newText");
-            if(range_it!=it->second.not_found() && text_it!=it->second.not_found()) {
-              auto start_it=range_it->second.find("start");
-              auto end_it=range_it->second.find("end");
-              if(start_it!=range_it->second.not_found() && end_it!=range_it->second.not_found()) {
-                try {
-                  replaces.emplace_back(Replace{Offset(start_it->second.get<unsigned>("line"), start_it->second.get<unsigned>("character")),
-                                                Offset(end_it->second.get<unsigned>("line"), end_it->second.get<unsigned>("character")),
-                                                text_it->second.get_value<std::string>()});
-                }
-                catch(...) {}
-              }
-            }
-          }
-        }
-        result_processed.set_value();
-      });
-      result_processed.get_future().get();
-      
-      auto end_iter=get_buffer()->end();
-      if(replaces.size()==1 &&
-         replaces[0].start.line==0 && replaces[0].start.index==0 &&
-         (replaces[0].end.line>static_cast<unsigned>(end_iter.get_line()) ||
-          (replaces[0].end.line==static_cast<unsigned>(end_iter.get_line()) && replaces[0].end.index>=static_cast<unsigned>(end_iter.get_line_offset())))) {
-        unescape_text(replaces[0].text);
-        replace_text(replaces[0].text);
-      }
-      else {
-        get_buffer()->begin_user_action();
-        for(auto it=replaces.rbegin();it!=replaces.rend();++it) {
-          auto start=get_iter_at_line_pos(it->start.line, it->start.index);
-          auto end=get_iter_at_line_pos(it->end.line, it->end.index);
-          get_buffer()->erase(start, end);
-          start=get_iter_at_line_pos(it->start.line, it->start.index);
-          unescape_text(it->text);
-          get_buffer()->insert(start, it->text);
-        }
-        get_buffer()->end_user_action();
-      }
-    };
-  }
-  
-  if(capabilities.definition) {
-    get_declaration_location=[this]() {
-      auto offset=get_declaration(get_buffer()->get_insert()->get_iter());
-      if(!offset)
-        Info::get().print("No declaration found");
-      return offset;
-    };
-    get_declaration_or_implementation_locations=[this]() {
-      std::vector<Offset> offsets;
-      auto offset=get_declaration_location();
-      if(offset)
-        offsets.emplace_back(std::move(offset));
-      return offsets;
-    };
-  }
-  
-  if(capabilities.references) {
-    get_usages=[this] {
-      auto iter=get_buffer()->get_insert()->get_iter();
-      std::vector<std::pair<Offset, std::string>> usages;
-      std::vector<Offset> end_offsets;
-      std::promise<void> result_processed;
-      client->write_request(this, "textDocument/references", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}, \"context\": {\"includeDeclaration\": true}", [&usages, &end_offsets, &result_processed](const boost::property_tree::ptree &result, bool error) {
-        if(!error) {
-          try {
-            for(auto it=result.begin();it!=result.end();++it) {
-              auto path=it->second.get<std::string>("uri", "");
-              if(path.size()>=7) {
-                path.erase(0, 7);
-                auto range_it=it->second.find("range");
-                if(range_it!=it->second.not_found()) {
-                  auto start_it=range_it->second.find("start");
-                  auto end_it=range_it->second.find("end");
-                  if(start_it!=range_it->second.not_found() && end_it!=range_it->second.not_found()) {
-                    usages.emplace_back(std::make_pair(Offset(start_it->second.get<unsigned>("line"), start_it->second.get<unsigned>("character"), path), ""));
-                    end_offsets.emplace_back(end_it->second.get<unsigned>("line"), end_it->second.get<unsigned>("character"));
-                  }
+    if (capabilities.document_formatting) {
+        format_style = [this](bool continue_without_style_file) {
+            if (!continue_without_style_file) {
+                bool has_style_file = false;
+                auto style_file_search_path = this->file_path.parent_path();
+                auto style_file = '.' + language_id + "-format";
+
+                while (true) {
+                    if (boost::filesystem::exists(style_file_search_path / style_file)) {
+                        has_style_file = true;
+                        break;
+                    }
+                    if (style_file_search_path == style_file_search_path.root_directory())
+                        break;
+                    style_file_search_path = style_file_search_path.parent_path();
                 }
-              }
+
+                if (!has_style_file && !continue_without_style_file)
+                    return;
             }
-          }
-          catch(...) {
-            usages.clear();
-            end_offsets.clear();
-          }
-        }
-        result_processed.set_value();
-      });
-      result_processed.get_future().get();
-      
-      auto embolden_token=[](std::string &line_, unsigned token_start_pos, unsigned token_end_pos) {
-        Glib::ustring line=line_;
-        if(token_start_pos>=line.size() || token_end_pos>=line.size())
-          return;
-    
-        //markup token as bold
-        size_t pos=0;
-        while((pos=line.find('&', pos))!=Glib::ustring::npos) {
-          size_t pos2=line.find(';', pos+2);
-          if(token_start_pos>pos) {
-            token_start_pos+=pos2-pos;
-            token_end_pos+=pos2-pos;
-          }
-          else if(token_end_pos>pos)
-            token_end_pos+=pos2-pos;
-          else
-            break;
-          pos=pos2+1;
-        }
-        line.insert(token_end_pos, "</b>");
-        line.insert(token_start_pos, "<b>");
-        
-        size_t start_pos=0;
-        while(start_pos<line.size() && (line[start_pos]==' ' || line[start_pos]=='\t'))
-          ++start_pos;
-        if(start_pos>0)
-          line.erase(0, start_pos);
-        
-        line_=line.raw();
-      };
-      
-      std::map<boost::filesystem::path, std::vector<std::string>> file_lines;
-      size_t c=static_cast<size_t>(-1);
-      for(auto &usage: usages) {
-        ++c;
-        auto view_it=views.end();
-        for(auto it=views.begin();it!=views.end();++it) {
-          if(usage.first.file_path==(*it)->file_path) {
-            view_it=it;
-            break;
-          }
-        }
-        if(view_it!=views.end()) {
-          if(usage.first.line<static_cast<unsigned>((*view_it)->get_buffer()->get_line_count())) {
-            auto start=(*view_it)->get_buffer()->get_iter_at_line(usage.first.line);
-            auto end=start;
-            end.forward_to_line_end();
-            usage.second=Glib::Markup::escape_text((*view_it)->get_buffer()->get_text(start, end));
-            embolden_token(usage.second, usage.first.index, end_offsets[c].index);
-          }
-        }
-        else {
-          auto it=file_lines.find(usage.first.file_path);
-          if(it==file_lines.end()) {
-            std::ifstream ifs(usage.first.file_path.string());
-            if(ifs) {
-              std::vector<std::string> lines;
-              std::string line;
-              while(std::getline(ifs, line)) {
-                if(!line.empty() && line.back()=='\r')
-                  line.pop_back();
-                lines.emplace_back(line);
-              }
-              auto pair=file_lines.emplace(usage.first.file_path, lines);
-              it=pair.first;
+
+            class Replace {
+            public:
+                Offset start, end;
+                std::string text;
+            };
+            std::vector<Replace> replaces;
+            std::promise<void> result_processed;
+
+            std::string method;
+            std::string params;
+            std::string options("\"tabSize\":" + std::to_string(tab_size) + ",\"insertSpaces\":" +
+                                (tab_char == ' ' ? "true" : "false"));
+            if (get_buffer()->get_has_selection() && capabilities.document_range_formatting) {
+                method = "textDocument/rangeFormatting";
+                Gtk::TextIter start, end;
+                get_buffer()->get_selection_bounds(start, end);
+                params = "\"textDocument\":{\"uri\":\"" + uri + "\"},\"range\":{\"start\":{\"line\":" +
+                         std::to_string(start.get_line()) + ",\"character\":" +
+                         std::to_string(start.get_line_offset()) + "},\"end\":{\"line\":" +
+                         std::to_string(end.get_line()) + ",\"character\":" + std::to_string(end.get_line_offset()) +
+                         "}},\"options\":{" + options + "}";
+            } else {
+                method = "textDocument/formatting";
+                params = "\"textDocument\":{\"uri\":\"" + uri + "\"},\"options\":{" + options + "}";
             }
-            else {
-              auto pair=file_lines.emplace(usage.first.file_path, std::vector<std::string>());
-              it=pair.first;
+
+            client->write_request(this, method, params,
+                                  [&replaces, &result_processed](const boost::property_tree::ptree &result,
+                                                                 bool error) {
+                                      if (!error) {
+                                          for (auto it = result.begin(); it != result.end(); ++it) {
+                                              auto range_it = it->second.find("range");
+                                              auto text_it = it->second.find("newText");
+                                              if (range_it != it->second.not_found() &&
+                                                  text_it != it->second.not_found()) {
+                                                  auto start_it = range_it->second.find("start");
+                                                  auto end_it = range_it->second.find("end");
+                                                  if (start_it != range_it->second.not_found() &&
+                                                      end_it != range_it->second.not_found()) {
+                                                      try {
+                                                          replaces.emplace_back(
+                                                                  Replace{Offset(start_it->second.get<unsigned>("line"),
+                                                                                 start_it->second.get<unsigned>(
+                                                                                         "character")),
+                                                                          Offset(end_it->second.get<unsigned>("line"),
+                                                                                 end_it->second.get<unsigned>(
+                                                                                         "character")),
+                                                                          text_it->second.get_value<std::string>()});
+                                                      }
+                                                      catch (...) {}
+                                                  }
+                                              }
+                                          }
+                                      }
+                                      result_processed.set_value();
+                                  });
+            result_processed.get_future().get();
+
+            auto end_iter = get_buffer()->end();
+            if (replaces.size() == 1 &&
+                replaces[0].start.line == 0 && replaces[0].start.index == 0 &&
+                (replaces[0].end.line > static_cast<unsigned>(end_iter.get_line()) ||
+                 (replaces[0].end.line == static_cast<unsigned>(end_iter.get_line()) &&
+                  replaces[0].end.index >= static_cast<unsigned>(end_iter.get_line_offset())))) {
+                unescape_text(replaces[0].text);
+                replace_text(replaces[0].text);
+            } else {
+                get_buffer()->begin_user_action();
+                for (auto it = replaces.rbegin(); it != replaces.rend(); ++it) {
+                    auto start = get_iter_at_line_pos(it->start.line, it->start.index);
+                    auto end = get_iter_at_line_pos(it->end.line, it->end.index);
+                    get_buffer()->erase(start, end);
+                    start = get_iter_at_line_pos(it->start.line, it->start.index);
+                    unescape_text(it->text);
+                    get_buffer()->insert(start, it->text);
+                }
+                get_buffer()->end_user_action();
             }
-          }
-          
-          if(usage.first.line<it->second.size()) {
-            usage.second=it->second[usage.first.line];
-            embolden_token(usage.second, usage.first.index, end_offsets[c].index);
-          }
-        }
-      }
-      
-      if(usages.empty())
-        Info::get().print("No symbol found at current cursor location");
-      
-      return usages;
-    };
-  }
-  
-  get_token_spelling=[this]() -> std::string {
-    auto start=get_buffer()->get_insert()->get_iter();
-    auto end=start;
-    auto previous=start;
-    while(previous.backward_char() && ((*previous>='A' && *previous<='Z') || (*previous>='a' && *previous<='z') || (*previous>='0' && *previous<='9') || *previous=='_') && start.backward_char()) {}
-    while(((*end>='A' && *end<='Z') || (*end>='a' && *end<='z') || (*end>='0' && *end<='9') || *end=='_') && end.forward_char()) {}
-    
-    if(start==end) {
-      Info::get().print("No valid symbol found at current cursor location");
-      return "";
+            hide_tooltips();
+        };
     }
-    
-    return get_buffer()->get_text(start, end);
-  };
-  
-  if(capabilities.rename) {
-    rename_similar_tokens=[this](const std::string &text) {
-      class Usages {
-      public:
-        boost::filesystem::path path;
-        std::unique_ptr<std::string> new_text;
-        std::vector<std::pair<Offset, Offset>> offsets;
-      };
-      
-      auto previous_text=get_token_spelling();
-      if(previous_text.empty())
-        return;
-      
-      auto iter=get_buffer()->get_insert()->get_iter();
-      std::vector<Usages> usages;
-      std::promise<void> result_processed;
-      client->write_request(this, "textDocument/rename", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}, \"newName\": \""+text+"\"", [this, &usages, &result_processed](const boost::property_tree::ptree &result, bool error) {
-        if(!error) {
-          boost::filesystem::path project_path;
-          auto build=Project::Build::create(file_path);
-          if(!build->project_path.empty())
-            project_path=build->project_path;
-          else
-            project_path=file_path.parent_path();
-          try {
-            auto changes_it=result.find("changes");
-            if(changes_it!=result.not_found()) {
-              for(auto file_it=changes_it->second.begin();file_it!=changes_it->second.end();++file_it) {
-                auto path=file_it->first;
-                if(path.size()>=7) {
-                  path.erase(0, 7);
-                  if(filesystem::file_in_path(path, project_path)) {
-                    usages.emplace_back(Usages{path, nullptr, std::vector<std::pair<Offset, Offset>>()});
-                    for(auto edit_it=file_it->second.begin();edit_it!=file_it->second.end();++edit_it) {
-                      auto range_it=edit_it->second.find("range");
-                      if(range_it!=edit_it->second.not_found()) {
-                        auto start_it=range_it->second.find("start");
-                        auto end_it=range_it->second.find("end");
-                        if(start_it!=range_it->second.not_found() && end_it!=range_it->second.not_found())
-                          usages.back().offsets.emplace_back(std::make_pair(Offset(start_it->second.get<unsigned>("line"), start_it->second.get<unsigned>("character")),
-                                                                            Offset(end_it->second.get<unsigned>("line"), end_it->second.get<unsigned>("character"))));
-                      }
+
+    if (capabilities.definition) {
+        get_declaration_location = [this]() {
+            auto offset = get_declaration(get_buffer()->get_insert()->get_iter());
+            if (!offset)
+                Info::get().print("No declaration found");
+            return offset;
+        };
+        get_declaration_or_implementation_locations = [this]() {
+            std::vector<Offset> offsets;
+            auto offset = get_declaration_location();
+            if (offset)
+                offsets.emplace_back(std::move(offset));
+            return offsets;
+        };
+    }
+
+    if (capabilities.references) {
+        get_usages = [this] {
+            auto iter = get_buffer()->get_insert()->get_iter();
+            std::vector<std::pair<Offset, std::string>> usages;
+            std::vector<Offset> end_offsets;
+            std::promise<void> result_processed;
+            client->write_request(this, "textDocument/references",
+                                  "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                                  std::to_string(iter.get_line()) + ", \"character\": " +
+                                  std::to_string(iter.get_line_offset()) +
+                                  "}, \"context\": {\"includeDeclaration\": true}",
+                                  [&usages, &end_offsets, &result_processed](const boost::property_tree::ptree &result,
+                                                                             bool error) {
+                                      if (!error) {
+                                          try {
+                                              for (auto it = result.begin(); it != result.end(); ++it) {
+                                                  auto path = it->second.get<std::string>("uri", "");
+                                                  if (path.size() >= 7) {
+                                                      path.erase(0, 7);
+                                                      auto range_it = it->second.find("range");
+                                                      if (range_it != it->second.not_found()) {
+                                                          auto start_it = range_it->second.find("start");
+                                                          auto end_it = range_it->second.find("end");
+                                                          if (start_it != range_it->second.not_found() &&
+                                                              end_it != range_it->second.not_found()) {
+                                                              usages.emplace_back(std::make_pair(
+                                                                      Offset(start_it->second.get<unsigned>("line"),
+                                                                             start_it->second.get<unsigned>(
+                                                                                     "character"), path), ""));
+                                                              end_offsets.emplace_back(
+                                                                      end_it->second.get<unsigned>("line"),
+                                                                      end_it->second.get<unsigned>("character"));
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                          catch (...) {
+                                              usages.clear();
+                                              end_offsets.clear();
+                                          }
+                                      }
+                                      result_processed.set_value();
+                                  });
+            result_processed.get_future().get();
+
+            auto embolden_token = [](std::string &line_, unsigned token_start_pos, unsigned token_end_pos) {
+                Glib::ustring line = line_;
+                if (token_start_pos >= line.size() || token_end_pos >= line.size())
+                    return;
+
+                //markup token as bold
+                size_t pos = 0;
+                while ((pos = line.find('&', pos)) != Glib::ustring::npos) {
+                    size_t pos2 = line.find(';', pos + 2);
+                    if (token_start_pos > pos) {
+                        token_start_pos += pos2 - pos;
+                        token_end_pos += pos2 - pos;
+                    } else if (token_end_pos > pos)
+                        token_end_pos += pos2 - pos;
+                    else
+                        break;
+                    pos = pos2 + 1;
+                }
+                line.insert(token_end_pos, "</b>");
+                line.insert(token_start_pos, "<b>");
+
+                size_t start_pos = 0;
+                while (start_pos < line.size() && (line[start_pos] == ' ' || line[start_pos] == '\t'))
+                    ++start_pos;
+                if (start_pos > 0)
+                    line.erase(0, start_pos);
+
+                line_ = line.raw();
+            };
+
+            std::map<boost::filesystem::path, std::vector<std::string>> file_lines;
+            size_t c = static_cast<size_t>(-1);
+            for (auto &usage: usages) {
+                ++c;
+                auto view_it = views.end();
+                for (auto it = views.begin(); it != views.end(); ++it) {
+                    if (usage.first.file_path == (*it)->file_path) {
+                        view_it = it;
+                        break;
                     }
-                  }
                 }
-              }
-            }
-            else {
-              auto changes_pt=result.get_child("documentChanges", boost::property_tree::ptree());
-              for(auto change_it=changes_pt.begin();change_it!=changes_pt.end();++change_it) {
-                auto document_it=change_it->second.find("textDocument");
-                if(document_it!=change_it->second.not_found()) {
-                  auto path=document_it->second.get<std::string>("uri", "");
-                  if(path.size()>=7) {
-                    path.erase(0, 7);
-                    if(filesystem::file_in_path(path, project_path)) {
-                      usages.emplace_back(Usages{path, std::make_unique<std::string>(), std::vector<std::pair<Offset, Offset>>()});
-                      auto edits_pt=change_it->second.get_child("edits", boost::property_tree::ptree());
-                      for(auto edit_it=edits_pt.begin();edit_it!=edits_pt.end();++edit_it) {
-                        auto new_text_it=edit_it->second.find("newText");
-                        if(new_text_it!=edit_it->second.not_found()) {
-                          auto range_it=edit_it->second.find("range");
-                          if(range_it!=edit_it->second.not_found()) {
-                            auto start_it=range_it->second.find("start");
-                            auto end_it=range_it->second.find("end");
-                            if(start_it!=range_it->second.not_found() && end_it!=range_it->second.not_found()) {
-                              auto end_line=end_it->second.get<size_t>("line");
-                              if(end_line>std::numeric_limits<int>::max())
-                                end_line=std::numeric_limits<int>::max();
-                              *usages.back().new_text=new_text_it->second.get_value<std::string>();
-                              usages.back().offsets.emplace_back(std::make_pair(Offset(start_it->second.get<unsigned>("line"), start_it->second.get<unsigned>("character")),
-                                                                                Offset(static_cast<unsigned>(end_line), end_it->second.get<unsigned>("character"))));
+                if (view_it != views.end()) {
+                    if (usage.first.line < static_cast<unsigned>((*view_it)->get_buffer()->get_line_count())) {
+                        auto start = (*view_it)->get_buffer()->get_iter_at_line(usage.first.line);
+                        auto end = start;
+                        end.forward_to_line_end();
+                        usage.second = Glib::Markup::escape_text((*view_it)->get_buffer()->get_text(start, end));
+                        embolden_token(usage.second, usage.first.index, end_offsets[c].index);
+                    }
+                } else {
+                    auto it = file_lines.find(usage.first.file_path);
+                    if (it == file_lines.end()) {
+                        std::ifstream ifs(usage.first.file_path.string());
+                        if (ifs) {
+                            std::vector<std::string> lines;
+                            std::string line;
+                            while (std::getline(ifs, line)) {
+                                if (!line.empty() && line.back() == '\r')
+                                    line.pop_back();
+                                lines.emplace_back(line);
                             }
-                          }
+                            auto pair = file_lines.emplace(usage.first.file_path, lines);
+                            it = pair.first;
+                        } else {
+                            auto pair = file_lines.emplace(usage.first.file_path, std::vector<std::string>());
+                            it = pair.first;
                         }
-                      }
                     }
-                  }
+
+                    if (usage.first.line < it->second.size()) {
+                        usage.second = it->second[usage.first.line];
+                        embolden_token(usage.second, usage.first.index, end_offsets[c].index);
+                    }
                 }
-              }
             }
-          }
-          catch(...) {
-            usages.clear();
-          }
-        }
-        result_processed.set_value();
-      });
-      result_processed.get_future().get();
-      
-      std::vector<Usages*> usages_renamed;
-      for(auto &usage: usages) {
-        auto view_it=views.end();
-        for(auto it=views.begin();it!=views.end();++it) {
-          if((*it)->file_path==usage.path) {
-            view_it=it;
-            break;
-          }
-        }
-        if(view_it!=views.end()) {
-          (*view_it)->get_buffer()->begin_user_action();
-          auto iter=get_buffer()->get_insert()->get_iter();
-          auto line=iter.get_line();
-          auto offset=iter.get_line_offset();
-          for(auto offset_it=usage.offsets.rbegin();offset_it!=usage.offsets.rend();++offset_it) {
-            auto start_iter=(*view_it)->get_iter_at_line_pos(offset_it->first.line, offset_it->first.index);
-            auto end_iter=(*view_it)->get_iter_at_line_pos(offset_it->second.line, offset_it->second.index);
-            (*view_it)->get_buffer()->erase(start_iter, end_iter);
-            start_iter=(*view_it)->get_iter_at_line_pos(offset_it->first.line, offset_it->first.index);
-            if(usage.new_text)
-              (*view_it)->get_buffer()->insert(start_iter, *usage.new_text);
-            else
-              (*view_it)->get_buffer()->insert(start_iter, text);
-          }
-          if(usage.new_text && get_buffer()->get_insert()->get_iter().is_end()) {
-            place_cursor_at_line_offset(line, offset);
-            hide_tooltips();
-            scroll_to_cursor_delayed(this, true, false);
-          }
-          (*view_it)->get_buffer()->end_user_action();
-          (*view_it)->save();
-          usages_renamed.emplace_back(&usage);
+
+            if (usages.empty())
+                Info::get().print("No symbol found at current cursor location");
+
+            return usages;
+        };
+    }
+
+    get_token_spelling = [this]() -> std::string {
+        auto start = get_buffer()->get_insert()->get_iter();
+        auto end = start;
+        auto previous = start;
+        while (previous.backward_char() &&
+               ((*previous >= 'A' && *previous <= 'Z') || (*previous >= 'a' && *previous <= 'z') ||
+                (*previous >= '0' && *previous <= '9') || *previous == '_') && start.backward_char()) {}
+        while (((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') ||
+                *end == '_') && end.forward_char()) {}
+
+        if (start == end) {
+            Info::get().print("No valid symbol found at current cursor location");
+            return "";
         }
-        else {
-          Glib::ustring buffer;
-          {
-            std::ifstream stream(usage.path.string(), std::ifstream::binary);
-            if(stream)
-              buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
-          }
-          std::ofstream stream(usage.path.string(), std::ifstream::binary);
-          if(!buffer.empty() && stream) {
-            std::vector<size_t> lines_start_pos={0};
-            for(size_t c=0;c<buffer.size();++c) {
-              if(buffer[c]=='\n')
-                lines_start_pos.emplace_back(c+1);
-            }
-            for(auto offset_it=usage.offsets.rbegin();offset_it!=usage.offsets.rend();++offset_it) {
-              auto start_line=offset_it->first.line;
-              auto end_line=offset_it->second.line;
-              if(start_line<lines_start_pos.size()) {
-                auto start=lines_start_pos[start_line]+offset_it->first.index;
-                unsigned end;
-                if(end_line>=lines_start_pos.size())
-                  end=buffer.size();
-                else
-                  end=lines_start_pos[end_line]+offset_it->second.index;
-                if(start<buffer.size() && end<=buffer.size()) {
-                  if(usage.new_text)
-                    buffer.replace(start, end-start, *usage.new_text);
-                  else
-                    buffer.replace(start, end-start, text);
+
+        return get_buffer()->get_text(start, end);
+    };
+
+    if (capabilities.rename) {
+        rename_similar_tokens = [this](const std::string &text) {
+            class Usages {
+            public:
+                boost::filesystem::path path;
+                std::unique_ptr<std::string> new_text;
+                std::vector<std::pair<Offset, Offset>> offsets;
+            };
+
+            auto previous_text = get_token_spelling();
+            if (previous_text.empty())
+                return;
+
+            auto iter = get_buffer()->get_insert()->get_iter();
+            std::vector<Usages> usages;
+            std::promise<void> result_processed;
+            client->write_request(this, "textDocument/rename",
+                                  "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                                  std::to_string(iter.get_line()) + ", \"character\": " +
+                                  std::to_string(iter.get_line_offset()) + "}, \"newName\": \"" + text + "\"",
+                                  [this, &usages, &result_processed](const boost::property_tree::ptree &result,
+                                                                     bool error) {
+                                      if (!error) {
+                                          boost::filesystem::path project_path;
+                                          auto build = Project::Build::create(file_path);
+                                          if (!build->project_path.empty())
+                                              project_path = build->project_path;
+                                          else
+                                              project_path = file_path.parent_path();
+                                          try {
+                                              auto changes_it = result.find("changes");
+                                              if (changes_it != result.not_found()) {
+                                                  for (auto file_it = changes_it->second.begin();
+                                                       file_it != changes_it->second.end(); ++file_it) {
+                                                      auto path = file_it->first;
+                                                      if (path.size() >= 7) {
+                                                          path.erase(0, 7);
+                                                          if (filesystem::file_in_path(path, project_path)) {
+                                                              usages.emplace_back(Usages{path, nullptr,
+                                                                                         std::vector<std::pair<Offset, Offset>>()});
+                                                              for (auto edit_it = file_it->second.begin();
+                                                                   edit_it != file_it->second.end(); ++edit_it) {
+                                                                  auto range_it = edit_it->second.find("range");
+                                                                  if (range_it != edit_it->second.not_found()) {
+                                                                      auto start_it = range_it->second.find("start");
+                                                                      auto end_it = range_it->second.find("end");
+                                                                      if (start_it != range_it->second.not_found() &&
+                                                                          end_it != range_it->second.not_found())
+                                                                          usages.back().offsets.emplace_back(
+                                                                                  std::make_pair(
+                                                                                          Offset(start_it->second.get<unsigned>(
+                                                                                                  "line"),
+                                                                                                 start_it->second.get<unsigned>(
+                                                                                                         "character")),
+                                                                                          Offset(end_it->second.get<unsigned>(
+                                                                                                  "line"),
+                                                                                                 end_it->second.get<unsigned>(
+                                                                                                         "character"))));
+                                                                  }
+                                                              }
+                                                          }
+                                                      }
+                                                  }
+                                              } else {
+                                                  auto changes_pt = result.get_child("documentChanges",
+                                                                                     boost::property_tree::ptree());
+                                                  for (auto change_it = changes_pt.begin();
+                                                       change_it != changes_pt.end(); ++change_it) {
+                                                      auto document_it = change_it->second.find("textDocument");
+                                                      if (document_it != change_it->second.not_found()) {
+                                                          auto path = document_it->second.get<std::string>("uri", "");
+                                                          if (path.size() >= 7) {
+                                                              path.erase(0, 7);
+                                                              if (filesystem::file_in_path(path, project_path)) {
+                                                                  usages.emplace_back(
+                                                                          Usages{path, std::make_unique<std::string>(),
+                                                                                 std::vector<std::pair<Offset, Offset>>()});
+                                                                  auto edits_pt = change_it->second.get_child("edits",
+                                                                                                              boost::property_tree::ptree());
+                                                                  for (auto edit_it = edits_pt.begin();
+                                                                       edit_it != edits_pt.end(); ++edit_it) {
+                                                                      auto new_text_it = edit_it->second.find(
+                                                                              "newText");
+                                                                      if (new_text_it != edit_it->second.not_found()) {
+                                                                          auto range_it = edit_it->second.find("range");
+                                                                          if (range_it != edit_it->second.not_found()) {
+                                                                              auto start_it = range_it->second.find(
+                                                                                      "start");
+                                                                              auto end_it = range_it->second.find(
+                                                                                      "end");
+                                                                              if (start_it !=
+                                                                                  range_it->second.not_found() &&
+                                                                                  end_it !=
+                                                                                  range_it->second.not_found()) {
+                                                                                  auto end_line = end_it->second.get<size_t>(
+                                                                                          "line");
+                                                                                  if (end_line >
+                                                                                      std::numeric_limits<int>::max())
+                                                                                      end_line = std::numeric_limits<int>::max();
+                                                                                  *usages.back().new_text = new_text_it->second.get_value<std::string>();
+                                                                                  usages.back().offsets.emplace_back(
+                                                                                          std::make_pair(
+                                                                                                  Offset(start_it->second.get<unsigned>(
+                                                                                                          "line"),
+                                                                                                         start_it->second.get<unsigned>(
+                                                                                                                 "character")),
+                                                                                                  Offset(static_cast<unsigned>(end_line),
+                                                                                                         end_it->second.get<unsigned>(
+                                                                                                                 "character"))));
+                                                                              }
+                                                                          }
+                                                                      }
+                                                                  }
+                                                              }
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                          catch (...) {
+                                              usages.clear();
+                                          }
+                                      }
+                                      result_processed.set_value();
+                                  });
+            result_processed.get_future().get();
+
+            std::vector<Usages *> usages_renamed;
+            for (auto &usage: usages) {
+                auto view_it = views.end();
+                for (auto it = views.begin(); it != views.end(); ++it) {
+                    if ((*it)->file_path == usage.path) {
+                        view_it = it;
+                        break;
+                    }
+                }
+                if (view_it != views.end()) {
+                    (*view_it)->get_buffer()->begin_user_action();
+                    auto iter = get_buffer()->get_insert()->get_iter();
+                    auto line = iter.get_line();
+                    auto offset = iter.get_line_offset();
+                    for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
+                        auto start_iter = (*view_it)->get_iter_at_line_pos(offset_it->first.line,
+                                                                           offset_it->first.index);
+                        auto end_iter = (*view_it)->get_iter_at_line_pos(offset_it->second.line,
+                                                                         offset_it->second.index);
+                        (*view_it)->get_buffer()->erase(start_iter, end_iter);
+                        start_iter = (*view_it)->get_iter_at_line_pos(offset_it->first.line, offset_it->first.index);
+                        if (usage.new_text)
+                            (*view_it)->get_buffer()->insert(start_iter, *usage.new_text);
+                        else
+                            (*view_it)->get_buffer()->insert(start_iter, text);
+                    }
+                    if (usage.new_text && get_buffer()->get_insert()->get_iter().is_end()) {
+                        place_cursor_at_line_offset(line, offset);
+                        hide_tooltips();
+                        scroll_to_cursor_delayed(this, true, false);
+                    }
+                    (*view_it)->get_buffer()->end_user_action();
+                    (*view_it)->save();
+                    usages_renamed.emplace_back(&usage);
+                } else {
+                    Glib::ustring buffer;
+                    {
+                        std::ifstream stream(usage.path.string(), std::ifstream::binary);
+                        if (stream)
+                            buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
+                    }
+                    std::ofstream stream(usage.path.string(), std::ifstream::binary);
+                    if (!buffer.empty() && stream) {
+                        std::vector<size_t> lines_start_pos = {0};
+                        for (size_t c = 0; c < buffer.size(); ++c) {
+                            if (buffer[c] == '\n')
+                                lines_start_pos.emplace_back(c + 1);
+                        }
+                        for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
+                            auto start_line = offset_it->first.line;
+                            auto end_line = offset_it->second.line;
+                            if (start_line < lines_start_pos.size()) {
+                                auto start = lines_start_pos[start_line] + offset_it->first.index;
+                                unsigned end;
+                                if (end_line >= lines_start_pos.size())
+                                    end = buffer.size();
+                                else
+                                    end = lines_start_pos[end_line] + offset_it->second.index;
+                                if (start < buffer.size() && end <= buffer.size()) {
+                                    if (usage.new_text)
+                                        buffer.replace(start, end - start, *usage.new_text);
+                                    else
+                                        buffer.replace(start, end - start, text);
+                                }
+                            }
+                        }
+                        stream.write(buffer.data(), buffer.bytes());
+                        usages_renamed.emplace_back(&usage);
+                    } else
+                        Terminal::get().print("Error: could not write to file " + usage.path.string() + '\n', true);
                 }
-              }
             }
-            stream.write(buffer.data(), buffer.bytes());
-            usages_renamed.emplace_back(&usage);
-          }
-          else
-            Terminal::get().print("Error: could not write to file "+usage.path.string()+'\n', true);
-        }
-      }
-      
-      if(!usages_renamed.empty()) {
-        Terminal::get().print("Renamed ");
-        Terminal::get().print(previous_text, true);
-        Terminal::get().print(" to ");
-        Terminal::get().print(text, true);
-        Terminal::get().print("\n");
-      }
+
+            if (!usages_renamed.empty()) {
+                Terminal::get().print("Renamed ");
+                Terminal::get().print(previous_text, true);
+                Terminal::get().print(" to ");
+                Terminal::get().print(text, true);
+                Terminal::get().print("\n");
+            }
+        };
+    }
+
+    goto_next_diagnostic = [this]() {
+        place_cursor_at_next_diagnostic();
     };
-  }
-  
-  goto_next_diagnostic=[this]() {
-    place_cursor_at_next_diagnostic();
-  };
 }
 
 void Source::LanguageProtocolView::escape_text(std::string &text) {
-  for(size_t c=0;c<text.size();++c) {
-    if(text[c]=='\n') {
-      text.replace(c, 1, "\\n");
-      ++c;
-    }
-    else if(text[c]=='\r') {
-      text.replace(c, 1, "\\r");
-      ++c;
-    }
-    else if(text[c]=='\"') {
-      text.replace(c, 1, "\\\"");
-      ++c;
+    for (size_t c = 0; c < text.size(); ++c) {
+        if (text[c] == '\n') {
+            text.replace(c, 1, "\\n");
+            ++c;
+        } else if (text[c] == '\r') {
+            text.replace(c, 1, "\\r");
+            ++c;
+        } else if (text[c] == '\"') {
+            text.replace(c, 1, "\\\"");
+            ++c;
+        }
     }
-  }
 }
 
 void Source::LanguageProtocolView::unescape_text(std::string &text) {
-  for(size_t c=0;c<text.size();++c) {
-    if(text[c]=='\\' && c+1<text.size()) {
-      if(text[c+1]=='n')
-        text.replace(c, 2, "\n");
-      else if(text[c+1]=='r')
-        text.replace(c, 2, "\r");
-      else
-        text.erase(c, 1);
+    for (size_t c = 0; c < text.size(); ++c) {
+        if (text[c] == '\\' && c + 1 < text.size()) {
+            if (text[c + 1] == 'n')
+                text.replace(c, 2, "\n");
+            else if (text[c + 1] == 'r')
+                text.replace(c, 2, "\r");
+            else
+                text.erase(c, 1);
+        }
     }
-  }
 }
 
 void Source::LanguageProtocolView::update_diagnostics(std::vector<LanguageProtocol::Diagnostic> &&diagnostics) {
-  dispatcher.post([this, diagnostics=std::move(diagnostics)] {
-    clear_diagnostic_tooltips();
-    num_warnings=0;
-    num_errors=0;
-    num_fix_its=0;
-    for(auto &diagnostic: diagnostics) {
-      if(diagnostic.uri==uri) {
-        auto start=get_iter_at_line_pos(diagnostic.offsets.first.line, diagnostic.offsets.first.index);
-        auto end=get_iter_at_line_pos(diagnostic.offsets.second.line, diagnostic.offsets.second.index);
-        
-        if(start==end) {
-          if(!end.is_end())
-            end.forward_char();
-          else
-            start.forward_char();
-        }
-        
-        bool error=false;
-        std::string severity_tag_name;
-        if(diagnostic.severity>=2) {
-          severity_tag_name="def:warning";
-          num_warnings++;
-        }
-        else {
-          severity_tag_name="def:error";
-          num_errors++;
-          error=true;
+    dispatcher.post([this, diagnostics = std::move(diagnostics)] {
+        clear_diagnostic_tooltips();
+        num_warnings = 0;
+        num_errors = 0;
+        num_fix_its = 0;
+        for (auto &diagnostic: diagnostics) {
+            if (diagnostic.uri == uri) {
+                auto start = get_iter_at_line_pos(diagnostic.offsets.first.line, diagnostic.offsets.first.index);
+                auto end = get_iter_at_line_pos(diagnostic.offsets.second.line, diagnostic.offsets.second.index);
+
+                if (start == end) {
+                    if (!end.is_end())
+                        end.forward_char();
+                    else
+                        start.forward_char();
+                }
+
+                bool error = false;
+                std::string severity_tag_name;
+                if (diagnostic.severity >= 2) {
+                    severity_tag_name = "def:warning";
+                    num_warnings++;
+                } else {
+                    severity_tag_name = "def:error";
+                    num_errors++;
+                    error = true;
+                }
+
+                add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
+            }
         }
-        
-        add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
-      }
-    }
-    
-    for(auto &mark: flow_coverage_marks)
-      add_diagnostic_tooltip(mark.first->get_iter(), mark.second->get_iter(), flow_coverage_message, false);
-    
-    status_diagnostics=std::make_tuple(num_warnings+num_flow_coverage_warnings, num_errors, num_fix_its);
-    if(update_status_diagnostics)
-      update_status_diagnostics(this);
-  });
+
+        for (auto &mark: flow_coverage_marks)
+            add_diagnostic_tooltip(mark.first->get_iter(), mark.second->get_iter(), flow_coverage_message, false);
+
+        status_diagnostics = std::make_tuple(num_warnings + num_flow_coverage_warnings, num_errors, num_fix_its);
+        if (update_status_diagnostics)
+            update_status_diagnostics(this);
+    });
 }
 
 Gtk::TextIter Source::LanguageProtocolView::get_iter_at_line_pos(int line, int pos) {
-  return get_iter_at_line_offset(line, pos);
+    return get_iter_at_line_offset(line, pos);
 }
 
 void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rectangle) {
-  if(!capabilities.hover)
-    return;
-  
-  Gtk::TextIter iter;
-  int location_x, location_y;
-  window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x, location_y);
-  location_x += (rectangle.get_width() - 1) / 2;
-  get_iter_at_location(iter, location_x, location_y);
-  Gdk::Rectangle iter_rectangle;
-  get_iter_location(iter, iter_rectangle);
-  if(iter.ends_line() && location_x > iter_rectangle.get_x())
-    return;
-  
-  auto offset=iter.get_offset();
-  
-  static int request_count=0;
-  request_count++;
-  auto current_request=request_count;
-  client->write_request(this, "textDocument/hover", "\"textDocument\": {\"uri\":\"file://"+file_path.string()+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}", [this, offset, current_request](const boost::property_tree::ptree &result, bool error) {
-    if(!error) {
-      // hover result structure vary significantly from the different language servers
-      std::string content;
-      auto contents_pt=result.get_child("contents", boost::property_tree::ptree());
-      for(auto it=contents_pt.begin();it!=contents_pt.end();++it) {
-        auto value=it->second.get<std::string>("value", "");
-        if(!value.empty())
-          content.insert(0, value+(content.empty()?"":"\n\n"));
-        else {
-          value=it->second.get_value<std::string>("");
-          if(!value.empty())
-            content+=(content.empty()?"":"\n\n")+value;
-        }
-      }
-      if(content.empty()) {
-        auto contents_it=result.find("contents");
-        if(contents_it!=result.not_found()) {
-          content=contents_it->second.get<std::string>("value", "");
-          if(content.empty())
-            content=contents_it->second.get_value<std::string>("");
-        }
-      }
-      if(!content.empty()) {
-        while(!content.empty() && content.back()=='\n') { content.pop_back(); } // Remove unnecessary newlines
-        dispatcher.post([this, offset, content=std::move(content), current_request] {
-          if(current_request!=request_count)
-            return;
-          if(offset>=get_buffer()->get_char_count())
-            return;
-          type_tooltips.clear();
-          auto create_tooltip_buffer=[this, offset, content=std::move(content)]() {
-            auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
-            tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), content);
-            
+    if (!capabilities.hover)
+        return;
+
+    Gtk::TextIter iter;
+    int location_x, location_y;
+    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x,
+                            location_y);
+    location_x += (rectangle.get_width() - 1) / 2;
+    get_iter_at_location(iter, location_x, location_y);
+    Gdk::Rectangle iter_rectangle;
+    get_iter_location(iter, iter_rectangle);
+    if (iter.ends_line() && location_x > iter_rectangle.get_x())
+        return;
+
+    auto offset = iter.get_offset();
+
+    static int request_count = 0;
+    request_count++;
+    auto current_request = request_count;
+    client->write_request(this, "textDocument/hover", "\"textDocument\": {\"uri\":\"file://" + file_path.string() +
+                                                      "\"}, \"position\": {\"line\": " +
+                                                      std::to_string(iter.get_line()) + ", \"character\": " +
+                                                      std::to_string(iter.get_line_offset()) + "}",
+                          [this, offset, current_request](const boost::property_tree::ptree &result, bool error) {
+                              if (!error) {
+                                  // hover result structure vary significantly from the different language servers
+                                  std::string content;
+                                  auto contents_pt = result.get_child("contents", boost::property_tree::ptree());
+                                  for (auto it = contents_pt.begin(); it != contents_pt.end(); ++it) {
+                                      auto value = it->second.get<std::string>("value", "");
+                                      if (!value.empty())
+                                          content.insert(0, value + (content.empty() ? "" : "\n\n"));
+                                      else {
+                                          value = it->second.get_value<std::string>("");
+                                          if (!value.empty())
+                                              content += (content.empty() ? "" : "\n\n") + value;
+                                      }
+                                  }
+                                  if (content.empty()) {
+                                      auto contents_it = result.find("contents");
+                                      if (contents_it != result.not_found()) {
+                                          content = contents_it->second.get<std::string>("value", "");
+                                          if (content.empty())
+                                              content = contents_it->second.get_value<std::string>("");
+                                      }
+                                  }
+                                  if (!content.empty()) {
+                                      dispatcher.post([this, offset, content = std::move(content), current_request] {
+                                          if (current_request != request_count)
+                                              return;
+                                          if (offset >= get_buffer()->get_char_count())
+                                              return;
+                                          type_tooltips.clear();
+                                          auto create_tooltip_buffer = [this, offset, content = std::move(content)]() {
+                                              auto tooltip_buffer = Gtk::TextBuffer::create(
+                                                      get_buffer()->get_tag_table());
+                                              tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), content);
+
 #ifdef JUCI_ENABLE_DEBUG
-            if(language_id=="rust" && capabilities.definition) {
-              if(Debug::LLDB::get().is_stopped()) {
-                Glib::ustring value_type="Value";
-                
-                auto start=get_buffer()->get_iter_at_offset(offset);
-                auto end=start;
-                auto previous=start;
-                while(previous.backward_char() && ((*previous>='A' && *previous<='Z') || (*previous>='a' && *previous<='z') || (*previous>='0' && *previous<='9') || *previous=='_') && start.backward_char()) {}
-                while(((*end>='A' && *end<='Z') || (*end>='a' && *end<='z') || (*end>='0' && *end<='9') || *end=='_') && end.forward_char()) {}
-                
-                auto offset=get_declaration(start);
-                Glib::ustring debug_value=Debug::LLDB::get().get_value(get_buffer()->get_text(start, end), offset.file_path, offset.line+1, offset.index+1);
-                if(debug_value.empty()) {
-                  value_type="Return value";
-                  debug_value=Debug::LLDB::get().get_return_value(file_path, start.get_line()+1, start.get_line_index()+1);
-                }
-                if(!debug_value.empty()) {
-                  size_t pos=debug_value.find(" = ");
-                  if(pos!=Glib::ustring::npos) {
-                    Glib::ustring::iterator iter;
-                    while(!debug_value.validate(iter)) {
-                      auto next_char_iter=iter;
-                      next_char_iter++;
-                      debug_value.replace(iter, next_char_iter, "?");
-                    }
-                    tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1));
-                  }
-                }
-              }
-            }
+                                              if(language_id=="rust" && capabilities.definition) {
+                                                if(Debug::LLDB::get().is_stopped()) {
+                                                  Glib::ustring value_type="Value";
+
+                                                  auto start=get_buffer()->get_iter_at_offset(offset);
+                                                  auto end=start;
+                                                  auto previous=start;
+                                                  while(previous.backward_char() && ((*previous>='A' && *previous<='Z') || (*previous>='a' && *previous<='z') || (*previous>='0' && *previous<='9') || *previous=='_') && start.backward_char()) {}
+                                                  while(((*end>='A' && *end<='Z') || (*end>='a' && *end<='z') || (*end>='0' && *end<='9') || *end=='_') && end.forward_char()) {}
+
+                                                  auto offset=get_declaration(start);
+                                                  Glib::ustring debug_value=Debug::LLDB::get().get_value(get_buffer()->get_text(start, end), offset.file_path, offset.line+1, offset.index+1);
+                                                  if(debug_value.empty()) {
+                                                    value_type="Return value";
+                                                    debug_value=Debug::LLDB::get().get_return_value(file_path, start.get_line()+1, start.get_line_index()+1);
+                                                  }
+                                                  if(!debug_value.empty()) {
+                                                    size_t pos=debug_value.find(" = ");
+                                                    if(pos!=Glib::ustring::npos) {
+                                                      Glib::ustring::iterator iter;
+                                                      while(!debug_value.validate(iter)) {
+                                                        auto next_char_iter=iter;
+                                                        next_char_iter++;
+                                                        debug_value.replace(iter, next_char_iter, "?");
+                                                      }
+                                                      tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1));
+                                                    }
+                                                  }
+                                                }
+                                              }
 #endif
-            
-            return tooltip_buffer;
-          };
-          
-          auto start=get_buffer()->get_iter_at_offset(offset);
-          auto end=start;
-          auto previous=start;
-          while(previous.backward_char() && ((*previous>='A' && *previous<='Z') || (*previous>='a' && *previous<='z') || (*previous>='0' && *previous<='9') || *previous=='_') && start.backward_char()) {}
-          while(((*end>='A' && *end<='Z') || (*end>='a' && *end<='z') || (*end>='0' && *end<='9') || *end=='_') && end.forward_char()) {}
-          type_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start), get_buffer()->create_mark(end));
-          type_tooltips.show();
-        });
-      }
-    }
-  });
+
+                                              return tooltip_buffer;
+                                          };
+
+                                          auto start = get_buffer()->get_iter_at_offset(offset);
+                                          auto end = start;
+                                          auto previous = start;
+                                          while (previous.backward_char() && ((*previous >= 'A' && *previous <= 'Z') ||
+                                                                              (*previous >= 'a' && *previous <= 'z') ||
+                                                                              (*previous >= '0' && *previous <= '9') ||
+                                                                              *previous == '_') &&
+                                                 start.backward_char()) {}
+                                          while (((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') ||
+                                                  (*end >= '0' && *end <= '9') || *end == '_') && end.forward_char()) {}
+                                          type_tooltips.emplace_back(create_tooltip_buffer, this,
+                                                                     get_buffer()->create_mark(start),
+                                                                     get_buffer()->create_mark(end));
+                                          type_tooltips.show();
+                                      });
+                                  }
+                              }
+                          });
 }
 
 void Source::LanguageProtocolView::tag_similar_symbols() {
-  if(!capabilities.document_highlight && !capabilities.references)
-    return;
-  
-  auto iter=get_buffer()->get_insert()->get_iter();
-  std::string method;
-  if(capabilities.document_highlight)
-    method="textDocument/documentHighlight";
-  else
-    method="textDocument/references";
-  
-  static int request_count=0;
-  request_count++;
-  auto current_request=request_count;
-  client->write_request(this, method, "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}, \"context\": {\"includeDeclaration\": true}", [this, current_request](const boost::property_tree::ptree &result, bool error) {
-    if(!error) {
-      std::vector<std::pair<Offset, Offset>> offsets;
-      for(auto it=result.begin();it!=result.end();++it) {
-        if(capabilities.document_highlight || it->second.get<std::string>("uri", "")==uri) {
-          auto range_it=it->second.find("range");
-          if(range_it!=it->second.not_found()) {
-            auto start_it=range_it->second.find("start");
-            auto end_it=range_it->second.find("end");
-            if(start_it!=range_it->second.not_found() && end_it!=range_it->second.not_found()) {
-              try {
-                offsets.emplace_back(std::make_pair(Offset(start_it->second.get<unsigned>("line"), start_it->second.get<unsigned>("character")),
-                                                    Offset(end_it->second.get<unsigned>("line"), end_it->second.get<unsigned>("character"))));
-              }
-              catch(...) {}
-            }
-          }
-        }
-      }
-      dispatcher.post([this, offsets=std::move(offsets), current_request] {
-        if(current_request!=request_count)
-          return;
-        get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(), get_buffer()->end());
-        for(auto &pair: offsets) {
-          auto start=get_iter_at_line_pos(pair.first.line, pair.first.index);
-          auto end=get_iter_at_line_pos(pair.second.line, pair.second.index);
-          get_buffer()->apply_tag(similar_symbol_tag, start, end);
-        }
-      });
-    }
-  });
+    if (!capabilities.document_highlight && !capabilities.references)
+        return;
+
+    auto iter = get_buffer()->get_insert()->get_iter();
+    std::string method;
+    if (capabilities.document_highlight)
+        method = "textDocument/documentHighlight";
+    else
+        method = "textDocument/references";
+
+    static int request_count = 0;
+    request_count++;
+    auto current_request = request_count;
+    client->write_request(this, method, "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                                        std::to_string(iter.get_line()) + ", \"character\": " +
+                                        std::to_string(iter.get_line_offset()) +
+                                        "}, \"context\": {\"includeDeclaration\": true}",
+                          [this, current_request](const boost::property_tree::ptree &result, bool error) {
+                              if (!error) {
+                                  std::vector<std::pair<Offset, Offset>> offsets;
+                                  for (auto it = result.begin(); it != result.end(); ++it) {
+                                      if (capabilities.document_highlight ||
+                                          it->second.get<std::string>("uri", "") == uri) {
+                                          auto range_it = it->second.find("range");
+                                          if (range_it != it->second.not_found()) {
+                                              auto start_it = range_it->second.find("start");
+                                              auto end_it = range_it->second.find("end");
+                                              if (start_it != range_it->second.not_found() &&
+                                                  end_it != range_it->second.not_found()) {
+                                                  try {
+                                                      offsets.emplace_back(std::make_pair(
+                                                              Offset(start_it->second.get<unsigned>("line"),
+                                                                     start_it->second.get<unsigned>("character")),
+                                                              Offset(end_it->second.get<unsigned>("line"),
+                                                                     end_it->second.get<unsigned>("character"))));
+                                                  }
+                                                  catch (...) {}
+                                              }
+                                          }
+                                      }
+                                  }
+                                  dispatcher.post([this, offsets = std::move(offsets), current_request] {
+                                      if (current_request != request_count)
+                                          return;
+                                      get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(),
+                                                               get_buffer()->end());
+                                      for (auto &pair: offsets) {
+                                          auto start = get_iter_at_line_pos(pair.first.line, pair.first.index);
+                                          auto end = get_iter_at_line_pos(pair.second.line, pair.second.index);
+                                          get_buffer()->apply_tag(similar_symbol_tag, start, end);
+                                      }
+                                  });
+                              }
+                          });
 }
 
 Source::Offset Source::LanguageProtocolView::get_declaration(const Gtk::TextIter &iter) {
-  auto offset=std::make_shared<Offset>();
-  std::promise<void> result_processed;
-  client->write_request(this, "textDocument/definition", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}", [offset, &result_processed](const boost::property_tree::ptree &result, bool error) {
-    if(!error) {
-      for(auto it=result.begin();it!=result.end();++it) {
-        auto uri=it->second.get<std::string>("uri", "");
-        if(uri.compare(0, 7, "file://")==0)
-          uri.erase(0, 7);
-        auto range=it->second.find("range");
-        if(range!=it->second.not_found()) {
-          auto start=range->second.find("start");
-          if(start!=range->second.not_found())
-            *offset=Offset(start->second.get<unsigned>("line", 0), start->second.get<unsigned>("character", 0), uri);
-        }
-        break; // TODO: can a language server return several definitions?
-      }
-    }
-    result_processed.set_value();
-  });
-  result_processed.get_future().get();
-  return *offset;
+    auto offset = std::make_shared<Offset>();
+    std::promise<void> result_processed;
+    client->write_request(this, "textDocument/definition",
+                          "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                          std::to_string(iter.get_line()) + ", \"character\": " +
+                          std::to_string(iter.get_line_offset()) + "}",
+                          [offset, &result_processed](const boost::property_tree::ptree &result, bool error) {
+                              if (!error) {
+                                  for (auto it = result.begin(); it != result.end(); ++it) {
+                                      auto uri = it->second.get<std::string>("uri", "");
+                                      if (uri.compare(0, 7, "file://") == 0)
+                                          uri.erase(0, 7);
+                                      auto range = it->second.find("range");
+                                      if (range != it->second.not_found()) {
+                                          auto start = range->second.find("start");
+                                          if (start != range->second.not_found())
+                                              *offset = Offset(start->second.get<unsigned>("line", 0),
+                                                               start->second.get<unsigned>("character", 0), uri);
+                                      }
+                                      break; // TODO: can a language server return several definitions?
+                                  }
+                              }
+                              result_processed.set_value();
+                          });
+    result_processed.get_future().get();
+    return *offset;
 }
 
 void Source::LanguageProtocolView::setup_autocomplete() {
-  if(!capabilities.completion)
-    return;
-  
-  non_interactive_completion=[this] {
-    if(CompletionDialog::get() && CompletionDialog::get()->is_visible())
-      return;
-    autocomplete.run();
-  };
-  
-  autocomplete.reparse=[this] {
-    autocomplete_comment.clear();
-    autocomplete_insert.clear();
-  };
-  
-  autocomplete.is_continue_key=[](guint keyval) {
-    if((keyval>='0' && keyval<='9') || (keyval>='a' && keyval<='z') || (keyval>='A' && keyval<='Z') || keyval=='_')
-      return true;
-    
-    return false;
-  };
-  
-  autocomplete.is_restart_key=[this](guint keyval) {
-    auto iter=get_buffer()->get_insert()->get_iter();
-    iter.backward_chars(2);
-    if(keyval=='.' || (keyval==':' && *iter==':'))
-      return true;
-    return false;
-  };
-  
-  autocomplete.run_check=[this]() {
-    auto iter=get_buffer()->get_insert()->get_iter();
-    iter.backward_char();
-    if(!is_code_iter(iter))
-      return false;
-    
-    std::string line=" "+get_line_before();
-    const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>\"'](\\.)([a-zA-Z0-9_]*)$");
-    const static std::regex colon_colon("^.*::([a-zA-Z0-9_]*)$");
-    const static std::regex part_of_symbol("^.*[^a-zA-Z0-9_]+([a-zA-Z0-9_]{3,})$");
-    std::smatch sm;
-    if(std::regex_match(line, sm, dot_or_arrow)) {
-      {
-        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-        autocomplete.prefix=sm[2].str();
-      }
-      if(autocomplete.prefix.size()==0 || autocomplete.prefix[0]<'0' || autocomplete.prefix[0]>'9')
-        return true;
-    }
-    else if(std::regex_match(line, sm, colon_colon)) {
-      {
-        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-        autocomplete.prefix=sm[1].str();
-      }
-      if(autocomplete.prefix.size()==0 || autocomplete.prefix[0]<'0' || autocomplete.prefix[0]>'9')
-        return true;
-    }
-    else if(std::regex_match(line, sm, part_of_symbol)) {
-      {
-        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-        autocomplete.prefix=sm[1].str();
-      }
-      if(autocomplete.prefix.size()==0 || autocomplete.prefix[0]<'0' || autocomplete.prefix[0]>'9')
-        return true;
-    }
-    else if(!interactive_completion) {
-      auto end_iter=get_buffer()->get_insert()->get_iter();
-      auto iter=end_iter;
-      while(iter.backward_char() && autocomplete.is_continue_key(*iter)) {}
-      if(iter!=end_iter)
-        iter.forward_char();
-      std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-      autocomplete.prefix=get_buffer()->get_text(iter, end_iter);
-      return true;
-    }
-    
-    return false;
-  };
-  
-  autocomplete.before_add_rows=[this] {
-    status_state="autocomplete...";
-    if(update_status_state)
-      update_status_state(this);
-  };
-  
-  autocomplete.after_add_rows=[this] {
-    status_state="";
-    if(update_status_state)
-      update_status_state(this);
-  };
-  
-  autocomplete.on_add_rows_error=[this] {
-    autocomplete_comment.clear();
-    autocomplete_insert.clear();
-  };
-  
-  autocomplete.add_rows=[this](std::string &buffer, int line_number, int column) {
-    if(autocomplete.state==Autocomplete::State::STARTING) {
-      autocomplete_comment.clear();
-      autocomplete_insert.clear();
-      std::promise<void> result_processed;
-      client->write_request(this, "textDocument/completion", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(line_number-1)+", \"character\": "+std::to_string(column-1)+"}", [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
-        if(!error) {
-          auto begin=result.begin(); // rust language server is bugged
-          auto end=result.end();
-          auto items_it=result.find("items"); // correct
-          if(items_it!=result.not_found()) {
-            begin=items_it->second.begin();
-            end=items_it->second.end();
-          }
-          for(auto it=begin;it!=end;++it) {
-            auto label=it->second.get<std::string>("label", "");
-            auto detail=it->second.get<std::string>("detail", "");
-            auto documentation=it->second.get<std::string>("documentation", "");
-            auto insert=it->second.get<std::string>("insertText", "");
-            if(insert.empty()) {
-              insert=label;
-              auto kind=it->second.get<unsigned>("kind", 0);
-              if(kind>=2 && kind<=3) {
-                bool found_bracket=false;
-                for(auto &chr: insert) {
-                  if(chr=='(' || chr=='{') {
-                    found_bracket=true;
-                    break;
-                  }
-                }
-                if(!found_bracket)
-                  insert+="(${1:})";
-              }
+    if (!capabilities.completion)
+        return;
+
+    non_interactive_completion = [this] {
+        if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
+            return;
+        autocomplete.run();
+    };
+
+    autocomplete.reparse = [this] {
+        autocomplete_comment.clear();
+        autocomplete_insert.clear();
+    };
+
+    autocomplete.is_continue_key = [](guint keyval) {
+        if ((keyval >= '0' && keyval <= '9') || (keyval >= 'a' && keyval <= 'z') || (keyval >= 'A' && keyval <= 'Z') ||
+            keyval == '_')
+            return true;
+
+        return false;
+    };
+
+    autocomplete.is_restart_key = [this](guint keyval) {
+        auto iter = get_buffer()->get_insert()->get_iter();
+        iter.backward_chars(2);
+        if (keyval == '.' || (keyval == ':' && *iter == ':'))
+            return true;
+        return false;
+    };
+
+    autocomplete.run_check = [this]() {
+        auto iter = get_buffer()->get_insert()->get_iter();
+        iter.backward_char();
+        if (!is_code_iter(iter))
+            return false;
+
+        std::string line = " " + get_line_before();
+        const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>\"'](\\.)([a-zA-Z0-9_]*)$");
+        const static std::regex colon_colon("^.*::([a-zA-Z0-9_]*)$");
+        const static std::regex part_of_symbol("^.*[^a-zA-Z0-9_]+([a-zA-Z0-9_]{3,})$");
+        std::smatch sm;
+        if (std::regex_match(line, sm, dot_or_arrow)) {
+            {
+                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+                autocomplete.prefix = sm[2].str();
             }
-            if(!label.empty()) {
-              autocomplete.rows.emplace_back(std::move(label));
-              autocomplete_comment.emplace_back(std::move(detail));
-              if(!documentation.empty()) {
-                if(!autocomplete_comment.back().empty())
-                  autocomplete_comment.back()+="\n\n";
-                autocomplete_comment.back()+=documentation;
-              }
-              autocomplete_insert.emplace_back(std::move(insert));
+            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+                return true;
+        } else if (std::regex_match(line, sm, colon_colon)) {
+            {
+                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+                autocomplete.prefix = sm[1].str();
             }
-          }
+            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+                return true;
+        } else if (std::regex_match(line, sm, part_of_symbol)) {
+            {
+                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+                autocomplete.prefix = sm[1].str();
+            }
+            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+                return true;
+        } else if (!interactive_completion) {
+            auto end_iter = get_buffer()->get_insert()->get_iter();
+            auto iter = end_iter;
+            while (iter.backward_char() && autocomplete.is_continue_key(*iter)) {}
+            if (iter != end_iter)
+                iter.forward_char();
+            std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+            autocomplete.prefix = get_buffer()->get_text(iter, end_iter);
+            return true;
         }
-        result_processed.set_value();
-      });
-      result_processed.get_future().get();
-    }
-  };
-  
-  signal_key_press_event().connect([this](GdkEventKey *event) {
-    if((event->keyval==GDK_KEY_Tab || event->keyval==GDK_KEY_ISO_Left_Tab) && (event->state&GDK_SHIFT_MASK)==0) {
-      if(!autocomplete_marks.empty()) {
-        auto it=autocomplete_marks.begin();
-        auto start=it->first->get_iter();
-        auto end=it->second->get_iter();
-        if(start==end)
-          return false;
-        autocomplete_keep_marks=true;
-        get_buffer()->select_range(it->first->get_iter(), it->second->get_iter());
-        autocomplete_keep_marks=false;
-        get_buffer()->delete_mark(it->first);
-        get_buffer()->delete_mark(it->second);
-        autocomplete_marks.erase(it);
-        return true;
-      }
-    }
-    return false;
-  }, false);
-  
-  get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-    if(mark->get_name() == "insert") {
-      if(!autocomplete_keep_marks) {
-        for(auto &pair: autocomplete_marks) {
-          get_buffer()->delete_mark(pair.first);
-          get_buffer()->delete_mark(pair.second);
+
+        return false;
+    };
+
+    autocomplete.before_add_rows = [this] {
+        status_state = "autocomplete...";
+        if (update_status_state)
+            update_status_state(this);
+    };
+
+    autocomplete.after_add_rows = [this] {
+        status_state = "";
+        if (update_status_state)
+            update_status_state(this);
+    };
+
+    autocomplete.on_add_rows_error = [this] {
+        autocomplete_comment.clear();
+        autocomplete_insert.clear();
+    };
+
+    autocomplete.add_rows = [this](std::string &buffer, int line_number, int column) {
+        if (autocomplete.state == Autocomplete::State::STARTING) {
+            autocomplete_comment.clear();
+            autocomplete_insert.clear();
+            std::promise<void> result_processed;
+            client->write_request(this, "textDocument/completion",
+                                  "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                                  std::to_string(line_number - 1) + ", \"character\": " + std::to_string(column - 1) +
+                                  "}",
+                                  [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
+                                      if (!error) {
+                                          auto begin = result.begin(); // rust language server is bugged
+                                          auto end = result.end();
+                                          auto items_it = result.find("items"); // correct
+                                          if (items_it != result.not_found()) {
+                                              begin = items_it->second.begin();
+                                              end = items_it->second.end();
+                                          }
+                                          for (auto it = begin; it != end; ++it) {
+                                              auto label = it->second.get<std::string>("label", "");
+                                              auto detail = it->second.get<std::string>("detail", "");
+                                              auto documentation = it->second.get<std::string>("documentation", "");
+                                              auto insert = it->second.get<std::string>("insertText", "");
+                                              if (insert.empty()) {
+                                                  insert = label;
+                                                  auto kind = it->second.get<unsigned>("kind", 0);
+                                                  if (kind >= 2 && kind <= 3) {
+                                                      bool found_bracket = false;
+                                                      for (auto &chr: insert) {
+                                                          if (chr == '(' || chr == '{') {
+                                                              found_bracket = true;
+                                                              break;
+                                                          }
+                                                      }
+                                                      if (!found_bracket)
+                                                          insert += "(${1:})";
+                                                  }
+                                              }
+                                              if (!label.empty()) {
+                                                  autocomplete.rows.emplace_back(std::move(label));
+                                                  autocomplete_comment.emplace_back(std::move(detail));
+                                                  if (!documentation.empty()) {
+                                                      if (!autocomplete_comment.back().empty())
+                                                          autocomplete_comment.back() += "\n\n";
+                                                      autocomplete_comment.back() += documentation;
+                                                  }
+                                                  autocomplete_insert.emplace_back(std::move(insert));
+                                              }
+                                          }
+                                      }
+                                      result_processed.set_value();
+                                  });
+            result_processed.get_future().get();
         }
-        autocomplete_marks.clear();
-      }
-    }
-  });
-  
-  autocomplete.on_show = [this] {
-    for(auto &pair: autocomplete_marks) {
-      get_buffer()->delete_mark(pair.first);
-      get_buffer()->delete_mark(pair.second);
-    }
-    autocomplete_marks.clear();
-    hide_tooltips();
-  };
-  
-  autocomplete.on_hide = [this] {
-    autocomplete_comment.clear();
-    autocomplete_insert.clear();
-  };
-  
-  autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
-    get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
-    if(hide_window) {
-      Glib::ustring insert=autocomplete_insert[index];
-      
-      // Do not insert function/template parameters if they already exist
-      auto iter=get_buffer()->get_insert()->get_iter();
-      if(*iter=='(' || *iter=='<') {
-        auto bracket_pos=insert.find(*iter);
-        if(bracket_pos!=std::string::npos) {
-          insert=insert.substr(0, bracket_pos);
+    };
+
+    signal_key_press_event().connect([this](GdkEventKey *event) {
+        if ((event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_ISO_Left_Tab) &&
+            (event->state & GDK_SHIFT_MASK) == 0) {
+            if (!autocomplete_marks.empty()) {
+                auto it = autocomplete_marks.begin();
+                auto start = it->first->get_iter();
+                auto end = it->second->get_iter();
+                if (start == end)
+                    return false;
+                autocomplete_keep_marks = true;
+                get_buffer()->select_range(it->first->get_iter(), it->second->get_iter());
+                autocomplete_keep_marks = false;
+                get_buffer()->delete_mark(it->first);
+                get_buffer()->delete_mark(it->second);
+                autocomplete_marks.erase(it);
+                return true;
+            }
         }
-      }
-      
-      // Find and add position marks that one can move to using tab-key
-      size_t pos1=0;
-      std::vector<std::pair<size_t, size_t>> mark_offsets;
-      while((pos1=insert.find("${"), pos1)!=Glib::ustring::npos) {
-        size_t pos2=insert.find(":", pos1+2);
-        if(pos2!=Glib::ustring::npos) {
-          size_t pos3=insert.find("}", pos2+1);
-          if(pos3!=Glib::ustring::npos) {
-            size_t length=pos3-pos2-1;
-            insert.erase(pos3, 1);
-            insert.erase(pos1, pos2-pos1+1);
-            mark_offsets.emplace_back(pos1, pos1+length);
-            pos1+=length;
-          }
-          else
-            break;
+        return false;
+    }, false);
+
+    get_buffer()->signal_mark_set().connect(
+            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+                if (mark->get_name() == "insert") {
+                    if (!autocomplete_keep_marks) {
+                        for (auto &pair: autocomplete_marks) {
+                            get_buffer()->delete_mark(pair.first);
+                            get_buffer()->delete_mark(pair.second);
+                        }
+                        autocomplete_marks.clear();
+                    }
+                }
+            });
+
+    autocomplete.on_show = [this] {
+        for (auto &pair: autocomplete_marks) {
+            get_buffer()->delete_mark(pair.first);
+            get_buffer()->delete_mark(pair.second);
         }
-        else
-          break;
-      }
-      get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), insert);
-      for(auto &offset: mark_offsets) {
-        auto start=CompletionDialog::get()->start_mark->get_iter();
-        auto end=start;
-        start.forward_chars(offset.first);
-        end.forward_chars(offset.second);
-        autocomplete_marks.emplace_back(get_buffer()->create_mark(start), get_buffer()->create_mark(end));
-      }
-      if(!autocomplete_marks.empty()) {
-        auto it=autocomplete_marks.begin();
-        autocomplete_keep_marks=true;
-        get_buffer()->select_range(it->first->get_iter(), it->second->get_iter());
-        autocomplete_keep_marks=false;
-        get_buffer()->delete_mark(it->first);
-        get_buffer()->delete_mark(it->second);
-        autocomplete_marks.erase(it);
-      }
-    }
-    else
-      get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), text);
-  };
-  
-  autocomplete.get_tooltip = [this](unsigned int index) {
-    return autocomplete_comment[index];
-  };
+        autocomplete_marks.clear();
+        hide_tooltips();
+    };
+
+    autocomplete.on_hide = [this] {
+        autocomplete_comment.clear();
+        autocomplete_insert.clear();
+    };
+
+    autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
+        get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
+        if (hide_window) {
+            Glib::ustring insert = autocomplete_insert[index];
+
+            // Do not insert function/template parameters if they already exist
+            auto iter = get_buffer()->get_insert()->get_iter();
+            if (*iter == '(' || *iter == '<') {
+                auto bracket_pos = insert.find(*iter);
+                if (bracket_pos != std::string::npos) {
+                    insert = insert.substr(0, bracket_pos);
+                }
+            }
+
+            // Find and add position marks that one can move to using tab-key
+            size_t pos1 = 0;
+            std::vector<std::pair<size_t, size_t>> mark_offsets;
+            while ((pos1 = insert.find("${"), pos1) != Glib::ustring::npos) {
+                size_t pos2 = insert.find(":", pos1 + 2);
+                if (pos2 != Glib::ustring::npos) {
+                    size_t pos3 = insert.find("}", pos2 + 1);
+                    if (pos3 != Glib::ustring::npos) {
+                        size_t length = pos3 - pos2 - 1;
+                        insert.erase(pos3, 1);
+                        insert.erase(pos1, pos2 - pos1 + 1);
+                        mark_offsets.emplace_back(pos1, pos1 + length);
+                        pos1 += length;
+                    } else
+                        break;
+                } else
+                    break;
+            }
+            get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), insert);
+            for (auto &offset: mark_offsets) {
+                auto start = CompletionDialog::get()->start_mark->get_iter();
+                auto end = start;
+                start.forward_chars(offset.first);
+                end.forward_chars(offset.second);
+                autocomplete_marks.emplace_back(get_buffer()->create_mark(start), get_buffer()->create_mark(end));
+            }
+            if (!autocomplete_marks.empty()) {
+                auto it = autocomplete_marks.begin();
+                autocomplete_keep_marks = true;
+                get_buffer()->select_range(it->first->get_iter(), it->second->get_iter());
+                autocomplete_keep_marks = false;
+                get_buffer()->delete_mark(it->first);
+                get_buffer()->delete_mark(it->second);
+                autocomplete_marks.erase(it);
+            }
+        } else
+            get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), text);
+    };
+
+    autocomplete.get_tooltip = [this](unsigned int index) {
+        return autocomplete_comment[index];
+    };
 }
 
 void Source::LanguageProtocolView::add_flow_coverage_tooltips(bool called_in_thread) {
-  std::stringstream stdin_stream, stderr_stream;
-  auto stdout_stream=std::make_shared<std::stringstream>();
-  auto exit_status=Terminal::get().process(stdin_stream, *stdout_stream, flow_coverage_executable.string()+" coverage --json "+file_path.string(), "", &stderr_stream);
-  auto f=[this, exit_status, stdout_stream] {
-    clear_diagnostic_tooltips();
-    num_flow_coverage_warnings=0;
-    for(auto &mark: flow_coverage_marks) {
-      get_buffer()->delete_mark(mark.first);
-      get_buffer()->delete_mark(mark.second);
-    }
-    flow_coverage_marks.clear();
-    
-    if(exit_status==0) {
-      boost::property_tree::ptree pt;
-      try {
-        boost::property_tree::read_json(*stdout_stream, pt);
-        auto uncovered_locs_pt=pt.get_child("expressions.uncovered_locs");
-        for(auto it=uncovered_locs_pt.begin();it!=uncovered_locs_pt.end();++it) {
-          auto start_pt=it->second.get_child("start");
-          auto start=get_iter_at_line_offset(start_pt.get<int>("line")-1, start_pt.get<int>("column")-1);
-          auto end_pt=it->second.get_child("end");
-          auto end=get_iter_at_line_offset(end_pt.get<int>("line")-1, end_pt.get<int>("column"));
-          
-          add_diagnostic_tooltip(start, end, flow_coverage_message, false);
-          ++num_flow_coverage_warnings;
-          
-          flow_coverage_marks.emplace_back(get_buffer()->create_mark(start), get_buffer()->create_mark(end));
+    std::stringstream stdin_stream, stderr_stream;
+    auto stdout_stream = std::make_shared<std::stringstream>();
+    auto exit_status = Terminal::get().process(stdin_stream, *stdout_stream,
+                                               flow_coverage_executable.string() + " coverage --json " +
+                                               file_path.string(), "", &stderr_stream);
+    auto f = [this, exit_status, stdout_stream] {
+        clear_diagnostic_tooltips();
+        num_flow_coverage_warnings = 0;
+        for (auto &mark: flow_coverage_marks) {
+            get_buffer()->delete_mark(mark.first);
+            get_buffer()->delete_mark(mark.second);
         }
-      }
-      catch(...) {}
-    }
-    status_diagnostics=std::make_tuple(num_warnings+num_flow_coverage_warnings, num_errors, num_fix_its);
-    if(update_status_diagnostics)
-      update_status_diagnostics(this);
-  };
-  if(called_in_thread)
-    dispatcher.post(std::move(f));
-  else
-    f();
+        flow_coverage_marks.clear();
+
+        if (exit_status == 0) {
+            boost::property_tree::ptree pt;
+            try {
+                boost::property_tree::read_json(*stdout_stream, pt);
+                auto uncovered_locs_pt = pt.get_child("expressions.uncovered_locs");
+                for (auto it = uncovered_locs_pt.begin(); it != uncovered_locs_pt.end(); ++it) {
+                    auto start_pt = it->second.get_child("start");
+                    auto start = get_iter_at_line_offset(start_pt.get<int>("line") - 1,
+                                                         start_pt.get<int>("column") - 1);
+                    auto end_pt = it->second.get_child("end");
+                    auto end = get_iter_at_line_offset(end_pt.get<int>("line") - 1, end_pt.get<int>("column"));
+
+                    add_diagnostic_tooltip(start, end, flow_coverage_message, false);
+                    ++num_flow_coverage_warnings;
+
+                    flow_coverage_marks.emplace_back(get_buffer()->create_mark(start), get_buffer()->create_mark(end));
+                }
+            }
+            catch (...) {}
+        }
+        status_diagnostics = std::make_tuple(num_warnings + num_flow_coverage_warnings, num_errors, num_fix_its);
+        if (update_status_diagnostics)
+            update_status_diagnostics(this);
+    };
+    if (called_in_thread)
+        dispatcher.post(std::move(f));
+    else
+        f();
 }
diff --git a/src/source_language_protocol.h b/src/source_language_protocol.h
index 967c6fc6..dccd3574 100644
--- a/src/source_language_protocol.h
+++ b/src/source_language_protocol.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include "autocomplete.h"
 #include "process.hpp"
 #include "source.h"
@@ -10,125 +11,144 @@
 #include <unordered_set>
 
 namespace Source {
-  class LanguageProtocolView;
+    class LanguageProtocolView;
 }
 
 namespace LanguageProtocol {
-  class Diagnostic {
-  public:
-    std::string spelling;
-    std::pair<Source::Offset, Source::Offset> offsets;
-    unsigned severity;
-    std::string uri;
-  };
-
-  class Capabilities {
-  public:
-    enum class TextDocumentSync { NONE = 0,
-                                  FULL,
-                                  INCREMENTAL };
-    TextDocumentSync text_document_sync;
-    bool hover;
-    bool completion;
-    bool definition;
-    bool references;
-    bool document_highlight;
-    bool workspace_symbol;
-    bool document_formatting;
-    bool document_range_formatting;
-    bool rename;
-  };
-
-  class Client {
-    Client(std::string root_uri, std::string language_id);
-    std::string root_uri;
-    std::string language_id;
-
-    Capabilities capabilities;
-
-    std::unordered_set<Source::LanguageProtocolView *> views;
-    std::mutex views_mutex;
-    
-    std::mutex initialize_mutex;
-
-    std::unique_ptr<TinyProcessLib::Process> process;
-    std::mutex read_write_mutex;
-
-    std::stringstream server_message_stream;
-    size_t server_message_size = static_cast<size_t>(-1);
-    size_t server_message_content_pos;
-    bool header_read = false;
-
-    size_t message_id = 1;
-
-    std::unordered_map<size_t, std::pair<Source::LanguageProtocolView*, std::function<void(const boost::property_tree::ptree &, bool error)>>> handlers;
-    std::vector<std::thread> timeout_threads;
-    std::mutex timeout_threads_mutex;
-
-  public:
-    static std::shared_ptr<Client> get(const boost::filesystem::path &file_path, const std::string &language_id);
-
-    ~Client();
-
-    bool initialized = false;
-    Capabilities initialize(Source::LanguageProtocolView *view);
-    void close(Source::LanguageProtocolView *view);
-    
-    void parse_server_message();
-    void write_request(Source::LanguageProtocolView *view, const std::string &method, const std::string &params, std::function<void(const boost::property_tree::ptree &, bool)> &&function = nullptr);
-    void write_notification(const std::string &method, const std::string &params);
-    void handle_server_request(const std::string &method, const boost::property_tree::ptree &params);
-  };
+    class Diagnostic {
+    public:
+        std::string spelling;
+        std::pair<Source::Offset, Source::Offset> offsets;
+        unsigned severity;
+        std::string uri;
+    };
+
+    class Capabilities {
+    public:
+        enum class TextDocumentSync {
+            NONE = 0,
+            FULL,
+            INCREMENTAL
+        };
+        TextDocumentSync text_document_sync;
+        bool hover;
+        bool completion;
+        bool definition;
+        bool references;
+        bool document_highlight;
+        bool workspace_symbol;
+        bool document_formatting;
+        bool document_range_formatting;
+        bool rename;
+    };
+
+    class Client {
+        Client(std::string root_uri, std::string language_id);
+
+        std::string root_uri;
+        std::string language_id;
+
+        Capabilities capabilities;
+
+        std::unordered_set<Source::LanguageProtocolView *> views;
+        std::mutex views_mutex;
+
+        std::mutex initialize_mutex;
+
+        std::unique_ptr<TinyProcessLib::Process> process;
+        std::mutex read_write_mutex;
+
+        std::stringstream server_message_stream;
+        size_t server_message_size = static_cast<size_t>(-1);
+        size_t server_message_content_pos;
+        bool header_read = false;
+
+        size_t message_id = 1;
+
+        std::unordered_map<size_t, std::pair<Source::LanguageProtocolView *, std::function<void(
+                const boost::property_tree::ptree &, bool error)>>> handlers;
+        std::vector<std::thread> timeout_threads;
+        std::mutex timeout_threads_mutex;
+
+    public:
+        static std::shared_ptr<Client> get(const boost::filesystem::path &file_path, const std::string &language_id);
+
+        ~Client();
+
+        bool initialized = false;
+
+        Capabilities initialize(Source::LanguageProtocolView *view);
+
+        void close(Source::LanguageProtocolView *view);
+
+        void parse_server_message();
+
+        void write_request(Source::LanguageProtocolView *view, const std::string &method, const std::string &params,
+                           std::function<void(const boost::property_tree::ptree &, bool)> &&function = nullptr);
+
+        void write_notification(const std::string &method, const std::string &params);
+
+        void handle_server_request(const std::string &method, const boost::property_tree::ptree &params);
+    };
 } // namespace LanguageProtocol
 
 namespace Source {
-  class LanguageProtocolView : public View {
-  public:
-    LanguageProtocolView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language, std::string language_id_);
-    ~LanguageProtocolView();
-    std::string uri;
-    
-    bool save() override;
-
-    void update_diagnostics(std::vector<LanguageProtocol::Diagnostic> &&diagnostics);
-    
-    Gtk::TextIter get_iter_at_line_pos(int line, int pos) override;
-
-  protected:
-    void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
-
-  private:
-    std::string language_id;
-    LanguageProtocol::Capabilities capabilities;
-    
-    std::shared_ptr<LanguageProtocol::Client> client;
-
-    size_t document_version = 1;
-
-    std::thread initialize_thread;
-    Dispatcher dispatcher;
-    
-    void setup_navigation_and_refactoring();
-
-    void escape_text(std::string &text);
-    void unescape_text(std::string &text);
-    
-    Glib::RefPtr<Gtk::TextTag> similar_symbol_tag;
-    void tag_similar_symbols();
-    
-    Offset get_declaration(const Gtk::TextIter &iter);
-
-    Autocomplete autocomplete;
-    void setup_autocomplete();
-    std::vector<std::string> autocomplete_comment;
-    std::vector<std::string> autocomplete_insert;
-    std::list<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, Glib::RefPtr<Gtk::TextBuffer::Mark>>> autocomplete_marks;
-    bool autocomplete_keep_marks = false;
-    
-    boost::filesystem::path flow_coverage_executable;
-    std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark>>> flow_coverage_marks;
-    const std::string flow_coverage_message="Not covered by Flow";
-    size_t num_warnings=0, num_errors=0, num_fix_its=0, num_flow_coverage_warnings=0;
-    void add_flow_coverage_tooltips(bool called_in_thread);
-  };
+    class LanguageProtocolView : public View {
+    public:
+        LanguageProtocolView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language,
+                             std::string language_id_);
+
+        ~LanguageProtocolView();
+
+        std::string uri;
+
+        bool save() override;
+
+        void update_diagnostics(std::vector<LanguageProtocol::Diagnostic> &&diagnostics);
+
+        Gtk::TextIter get_iter_at_line_pos(int line, int pos) override;
+
+    protected:
+        void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
+
+    private:
+        std::string language_id;
+        LanguageProtocol::Capabilities capabilities;
+
+        std::shared_ptr<LanguageProtocol::Client> client;
+
+        size_t document_version = 1;
+
+        std::thread initialize_thread;
+        Dispatcher dispatcher;
+
+        void setup_navigation_and_refactoring();
+
+        void escape_text(std::string &text);
+
+        void unescape_text(std::string &text);
+
+        Glib::RefPtr<Gtk::TextTag> similar_symbol_tag;
+        sigc::connection delayed_tag_similar_symbols_connection;
+
+        void tag_similar_symbols();
+
+        Offset get_declaration(const Gtk::TextIter &iter);
+
+        Autocomplete autocomplete;
+
+        void setup_autocomplete();
+
+        std::vector<std::string> autocomplete_comment;
+        std::vector<std::string> autocomplete_insert;
+        std::list<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, Glib::RefPtr<Gtk::TextBuffer::Mark>>> autocomplete_marks;
+        bool autocomplete_keep_marks = false;
+
+        boost::filesystem::path flow_coverage_executable;
+        std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark>>> flow_coverage_marks;
+        const std::string flow_coverage_message = "Not covered by Flow";
+        size_t num_warnings = 0, num_errors = 0, num_fix_its = 0, num_flow_coverage_warnings = 0;
+
+        void add_flow_coverage_tooltips(bool called_in_thread);
+    };
 } // namespace Source
diff --git a/src/source_spellcheck.cc b/src/source_spellcheck.cc
index f9247e46..ff2bb227 100644
--- a/src/source_spellcheck.cc
+++ b/src/source_spellcheck.cc
@@ -4,496 +4,509 @@
 #include "selection_dialog.h"
 #include <iostream>
 
-AspellConfig* Source::SpellCheckView::spellcheck_config=nullptr;
-
-Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language): BaseView(file_path, language) {
-  if(spellcheck_config==nullptr)
-    spellcheck_config=new_aspell_config();
-  spellcheck_checker=nullptr;
-  spellcheck_error_tag=get_buffer()->create_tag("spellcheck_error");
-  spellcheck_error_tag->property_underline()=Pango::Underline::UNDERLINE_ERROR;
-  
-  signal_key_press_event().connect([](GdkEventKey *event) {
-    if(SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
-      if(SelectionDialog::get()->on_key_press(event))
-        return true;
-    }
-    
-    return false;
-  }, false);
-  
-  //The following signal is added in case SpellCheckView is not subclassed
-  signal_key_press_event().connect([this](GdkEventKey *event) {
-    last_keyval=event->keyval;
-    return false;
-  });
-  
-  get_buffer()->signal_changed().connect([this]() {
-    if(spellcheck_checker==nullptr)
-      return;
-    
-    delayed_spellcheck_suggestions_connection.disconnect();
-    
-    auto iter=get_buffer()->get_insert()->get_iter();
-    if(!is_word_iter(iter) && !iter.starts_line())
-      iter.backward_char();
-    
-    if(disable_spellcheck) {
-      if(is_word_iter(iter)) {
-        auto word=get_word(iter);
-        get_buffer()->remove_tag(spellcheck_error_tag, word.first, word.second);
-      }
-      return;
-    }
-    
-    if(!is_code_iter(iter)) {
-      if(last_keyval==GDK_KEY_Return || last_keyval==GDK_KEY_KP_Enter) {
-        auto previous_line_iter=iter;
-        while(previous_line_iter.backward_char() && !previous_line_iter.ends_line()) {}
-        if(previous_line_iter.backward_char()) {
-          get_buffer()->remove_tag(spellcheck_error_tag, previous_line_iter, iter);
-          if(!is_code_iter(previous_line_iter)) {
-            auto word=get_word(previous_line_iter);
-            spellcheck_word(word.first, word.second);
-          }
-          auto word=get_word(iter);
-          spellcheck_word(word.first, word.second);
-        }
-      }
-      else {
-        auto previous_iter=iter;
-        //When for instance using space to split two words
-        if(!iter.starts_line() && !iter.ends_line() && is_word_iter(iter) &&
-           previous_iter.backward_char() && !previous_iter.starts_line() && !is_word_iter(previous_iter)) {
-          auto first=previous_iter;
-          auto second=iter;
-          if(first.backward_char()) {
-            get_buffer()->remove_tag(spellcheck_error_tag, first, second);
-            auto word=get_word(first);
-            spellcheck_word(word.first, word.second);
-            word=get_word(second);
-            spellcheck_word(word.first, word.second);
-          }
+AspellConfig *Source::SpellCheckView::spellcheck_config = nullptr;
+
+Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language)
+        : BaseView(file_path, language) {
+    if (spellcheck_config == nullptr)
+        spellcheck_config = new_aspell_config();
+    spellcheck_checker = nullptr;
+    spellcheck_error_tag = get_buffer()->create_tag("spellcheck_error");
+    spellcheck_error_tag->property_underline() = Pango::Underline::UNDERLINE_ERROR;
+
+    signal_key_press_event().connect([](GdkEventKey *event) {
+        if (SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
+            if (SelectionDialog::get()->on_key_press(event))
+                return true;
         }
-        else {
-          auto word=get_word(iter);
-          spellcheck_word(word.first, word.second);
+
+        return false;
+    }, false);
+
+    //The following signal is added in case SpellCheckView is not subclassed
+    signal_key_press_event().connect([this](GdkEventKey *event) {
+        last_keyval = event->keyval;
+        return false;
+    });
+
+    get_buffer()->signal_changed().connect([this]() {
+        if (spellcheck_checker == nullptr)
+            return;
+
+        delayed_spellcheck_suggestions_connection.disconnect();
+
+        auto iter = get_buffer()->get_insert()->get_iter();
+        if (!is_word_iter(iter) && !iter.starts_line())
+            iter.backward_char();
+
+        if (disable_spellcheck) {
+            if (is_word_iter(iter)) {
+                auto word = get_word(iter);
+                get_buffer()->remove_tag(spellcheck_error_tag, word.first, word.second);
+            }
+            return;
         }
-      }
-    }
-    delayed_spellcheck_error_clear.disconnect();
-    delayed_spellcheck_error_clear=Glib::signal_timeout().connect([this]() {
-      auto iter=get_buffer()->begin();
-      Gtk::TextIter begin_no_spellcheck_iter;
-      if(spellcheck_all) {
-        bool spell_check=!get_source_buffer()->iter_has_context_class(iter, "no-spell-check");
-        if(!spell_check)
-          begin_no_spellcheck_iter=iter;
-        while(iter!=get_buffer()->end()) {
-          if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
-            iter=get_buffer()->end();
-          
-          spell_check=!spell_check;
-          if(!spell_check)
-            begin_no_spellcheck_iter=iter;
-          else
-            get_buffer()->remove_tag(spellcheck_error_tag, begin_no_spellcheck_iter, iter);
+
+        if (!is_code_iter(iter)) {
+            if (last_keyval == GDK_KEY_Return || last_keyval == GDK_KEY_KP_Enter) {
+                auto previous_line_iter = iter;
+                while (previous_line_iter.backward_char() && !previous_line_iter.ends_line()) {}
+                if (previous_line_iter.backward_char()) {
+                    get_buffer()->remove_tag(spellcheck_error_tag, previous_line_iter, iter);
+                    if (!is_code_iter(previous_line_iter)) {
+                        auto word = get_word(previous_line_iter);
+                        spellcheck_word(word.first, word.second);
+                    }
+                    auto word = get_word(iter);
+                    spellcheck_word(word.first, word.second);
+                }
+            } else {
+                auto previous_iter = iter;
+                //When for instance using space to split two words
+                if (!iter.starts_line() && !iter.ends_line() && is_word_iter(iter) &&
+                    previous_iter.backward_char() && !previous_iter.starts_line() && !is_word_iter(previous_iter)) {
+                    auto first = previous_iter;
+                    auto second = iter;
+                    if (first.backward_char()) {
+                        get_buffer()->remove_tag(spellcheck_error_tag, first, second);
+                        auto word = get_word(first);
+                        spellcheck_word(word.first, word.second);
+                        word = get_word(second);
+                        spellcheck_word(word.first, word.second);
+                    }
+                } else {
+                    auto word = get_word(iter);
+                    spellcheck_word(word.first, word.second);
+                }
+            }
         }
-        return false;
-      }
-      
-      bool spell_check=get_source_buffer()->iter_has_context_class(iter, "string") || get_source_buffer()->iter_has_context_class(iter, "comment");
-      if(!spell_check)
-        begin_no_spellcheck_iter=iter;
-      while(iter!=get_buffer()->end()) {
-        auto iter1=iter;
-        auto iter2=iter;
-        if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string"))
-          iter1=get_buffer()->end();
-        if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
-          iter2=get_buffer()->end();
-        
-        if(iter2<iter1)
-          iter=iter2;
-        else
-          iter=iter1;
-        spell_check=!spell_check;
-        if(!spell_check)
-          begin_no_spellcheck_iter=iter;
-        else
-          get_buffer()->remove_tag(spellcheck_error_tag, begin_no_spellcheck_iter, iter);
-      }
-      return false;
-    }, 1000);
-  });
-  
-  // In case of for instance text paste or undo/redo
-  get_buffer()->signal_insert().connect([this](const Gtk::TextIter &start_iter, const Glib::ustring &inserted_string, int) {
-    if(spellcheck_checker==nullptr)
-      return;
-    
-    if(!disable_spellcheck)
-      return;
-    
-    auto iter=start_iter;
-    if(!is_word_iter(iter) && !iter.starts_line())
-      iter.backward_char();
-    if(is_word_iter(iter)) {
-      auto word=get_word(iter);
-      get_buffer()->remove_tag(spellcheck_error_tag, word.first, word.second);
-    }
-  }, false);
-  
-  get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iter, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark) {
-    if(spellcheck_checker==nullptr)
-      return;
-    
-    if(mark->get_name()=="insert") {
-      if(SelectionDialog::get())
-        SelectionDialog::get()->hide();
-      delayed_spellcheck_suggestions_connection.disconnect();
-      delayed_spellcheck_suggestions_connection=Glib::signal_timeout().connect([this]() {
-        if(get_buffer()->get_insert()->get_iter().has_tag(spellcheck_error_tag)) {
-          SelectionDialog::create(this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false);
-          auto word=get_word(get_buffer()->get_insert()->get_iter());
-          if(*word.first=='\'' && word.second.get_offset()-word.first.get_offset()>=3) {
-            auto before_end=word.second;
-            if(before_end.backward_char() && *before_end=='\'') {
-              word.first.forward_char();
-              word.second.backward_char();
+        delayed_spellcheck_error_clear.disconnect();
+        delayed_spellcheck_error_clear = Glib::signal_timeout().connect([this]() {
+            auto iter = get_buffer()->begin();
+            Gtk::TextIter begin_no_spellcheck_iter;
+            if (spellcheck_all) {
+                bool spell_check = !get_source_buffer()->iter_has_context_class(iter, "no-spell-check");
+                if (!spell_check)
+                    begin_no_spellcheck_iter = iter;
+                while (iter != get_buffer()->end()) {
+                    if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
+                        iter = get_buffer()->end();
+
+                    spell_check = !spell_check;
+                    if (!spell_check)
+                        begin_no_spellcheck_iter = iter;
+                    else
+                        get_buffer()->remove_tag(spellcheck_error_tag, begin_no_spellcheck_iter, iter);
+                }
+                return false;
+            }
+
+            bool spell_check = get_source_buffer()->iter_has_context_class(iter, "string") ||
+                               get_source_buffer()->iter_has_context_class(iter, "comment");
+            if (!spell_check)
+                begin_no_spellcheck_iter = iter;
+            while (iter != get_buffer()->end()) {
+                auto iter1 = iter;
+                auto iter2 = iter;
+                if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string"))
+                    iter1 = get_buffer()->end();
+                if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
+                    iter2 = get_buffer()->end();
+
+                if (iter2 < iter1)
+                    iter = iter2;
+                else
+                    iter = iter1;
+                spell_check = !spell_check;
+                if (!spell_check)
+                    begin_no_spellcheck_iter = iter;
+                else
+                    get_buffer()->remove_tag(spellcheck_error_tag, begin_no_spellcheck_iter, iter);
             }
-          }
-          auto suggestions=get_spellcheck_suggestions(word.first, word.second);
-          if(suggestions.size()==0)
             return false;
-          for(auto &suggestion: suggestions)
-            SelectionDialog::get()->add_row(suggestion);
-          SelectionDialog::get()->on_select=[this, word](unsigned int index, const std::string &text, bool hide_window) {
-            get_buffer()->begin_user_action();
-            get_buffer()->erase(word.first, word.second);
-            get_buffer()->insert(get_buffer()->get_insert()->get_iter(), text);
-            get_buffer()->end_user_action();
-          };
-          hide_tooltips();
-          SelectionDialog::get()->show();
-        }
+        }, 1000);
+    });
+
+    // In case of for instance text paste or undo/redo
+    get_buffer()->signal_insert().connect(
+            [this](const Gtk::TextIter &start_iter, const Glib::ustring &inserted_string, int) {
+                if (spellcheck_checker == nullptr)
+                    return;
+
+                if (!disable_spellcheck)
+                    return;
+
+                auto iter = start_iter;
+                if (!is_word_iter(iter) && !iter.starts_line())
+                    iter.backward_char();
+                if (is_word_iter(iter)) {
+                    auto word = get_word(iter);
+                    get_buffer()->remove_tag(spellcheck_error_tag, word.first, word.second);
+                }
+            }, false);
+
+    get_buffer()->signal_mark_set().connect(
+            [this](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+                if (spellcheck_checker == nullptr)
+                    return;
+
+                if (mark->get_name() == "insert") {
+                    if (SelectionDialog::get())
+                        SelectionDialog::get()->hide();
+                    delayed_spellcheck_suggestions_connection.disconnect();
+                    delayed_spellcheck_suggestions_connection = Glib::signal_timeout().connect([this]() {
+                        if (get_buffer()->get_insert()->get_iter().has_tag(spellcheck_error_tag)) {
+                            SelectionDialog::create(this,
+                                                    get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()),
+                                                    false);
+                            auto word = get_word(get_buffer()->get_insert()->get_iter());
+                            if (*word.first == '\'' && word.second.get_offset() - word.first.get_offset() >= 3) {
+                                auto before_end = word.second;
+                                if (before_end.backward_char() && *before_end == '\'') {
+                                    word.first.forward_char();
+                                    word.second.backward_char();
+                                }
+                            }
+                            auto suggestions = get_spellcheck_suggestions(word.first, word.second);
+                            if (suggestions.size() == 0)
+                                return false;
+                            for (auto &suggestion: suggestions)
+                                SelectionDialog::get()->add_row(suggestion);
+                            SelectionDialog::get()->on_select = [this, word](unsigned int index,
+                                                                             const std::string &text,
+                                                                             bool hide_window) {
+                                get_buffer()->begin_user_action();
+                                get_buffer()->erase(word.first, word.second);
+                                get_buffer()->insert(get_buffer()->get_insert()->get_iter(), text);
+                                get_buffer()->end_user_action();
+                            };
+                            hide_tooltips();
+                            SelectionDialog::get()->show();
+                        }
+                        return false;
+                    }, 500);
+                }
+            });
+
+    get_buffer()->signal_mark_set().connect(
+            [](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+                if (mark->get_name() == "insert") {
+                    if (SelectionDialog::get())
+                        SelectionDialog::get()->hide();
+                }
+            });
+
+    signal_focus_out_event().connect([this](GdkEventFocus *event) {
+        delayed_spellcheck_suggestions_connection.disconnect();
         return false;
-      }, 500);
-    }
-  });
-  
-  get_buffer()->signal_mark_set().connect([](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark) {
-    if(mark->get_name()=="insert") {
-      if(SelectionDialog::get())
-        SelectionDialog::get()->hide();
-    }
-  });
-  
-  signal_focus_out_event().connect([this](GdkEventFocus* event) {
-    delayed_spellcheck_suggestions_connection.disconnect();
-    return false;
-  });
-  
-  signal_leave_notify_event().connect([this](GdkEventCrossing*) {
-    delayed_spellcheck_suggestions_connection.disconnect();
-    return false;
-  });
-  
-  signal_tag_added_connection=get_buffer()->get_tag_table()->signal_tag_added().connect([this](const Glib::RefPtr<Gtk::TextTag> &tag) {
-    if(tag->property_name()=="gtksourceview:context-classes:comment")
-      comment_tag=tag;
-    else if(tag->property_name()=="gtksourceview:context-classes:string")
-      string_tag=tag;
-    else if(tag->property_name()=="gtksourceview:context-classes:no-spell-check")
-      no_spell_check_tag=tag;
-  });
-  signal_tag_removed_connection=get_buffer()->get_tag_table()->signal_tag_removed().connect([this](const Glib::RefPtr<Gtk::TextTag> &tag) {
-    if(tag->property_name()=="gtksourceview:context-classes:comment")
-      comment_tag.reset();
-    else if(tag->property_name()=="gtksourceview:context-classes:string")
-      string_tag.reset();
-    else if(tag->property_name()=="gtksourceview:context-classes:no-spell-check")
-      no_spell_check_tag.reset();
-  });
+    });
+
+    signal_leave_notify_event().connect([this](GdkEventCrossing *) {
+        delayed_spellcheck_suggestions_connection.disconnect();
+        return false;
+    });
+
+    signal_tag_added_connection = get_buffer()->get_tag_table()->signal_tag_added().connect(
+            [this](const Glib::RefPtr<Gtk::TextTag> &tag) {
+                if (tag->property_name() == "gtksourceview:context-classes:comment")
+                    comment_tag = tag;
+                else if (tag->property_name() == "gtksourceview:context-classes:string")
+                    string_tag = tag;
+                else if (tag->property_name() == "gtksourceview:context-classes:no-spell-check")
+                    no_spell_check_tag = tag;
+            });
+    signal_tag_removed_connection = get_buffer()->get_tag_table()->signal_tag_removed().connect(
+            [this](const Glib::RefPtr<Gtk::TextTag> &tag) {
+                if (tag->property_name() == "gtksourceview:context-classes:comment")
+                    comment_tag.reset();
+                else if (tag->property_name() == "gtksourceview:context-classes:string")
+                    string_tag.reset();
+                else if (tag->property_name() == "gtksourceview:context-classes:no-spell-check")
+                    no_spell_check_tag.reset();
+            });
 }
 
 Source::SpellCheckView::~SpellCheckView() {
-  delayed_spellcheck_suggestions_connection.disconnect();
-  delayed_spellcheck_error_clear.disconnect();
-  
-  if(spellcheck_checker!=nullptr)
-    delete_aspell_speller(spellcheck_checker);
-  
-  signal_tag_added_connection.disconnect();
-  signal_tag_removed_connection.disconnect();
+    delayed_spellcheck_suggestions_connection.disconnect();
+    delayed_spellcheck_error_clear.disconnect();
+
+    if (spellcheck_checker != nullptr)
+        delete_aspell_speller(spellcheck_checker);
+
+    signal_tag_added_connection.disconnect();
+    signal_tag_removed_connection.disconnect();
 }
 
 void Source::SpellCheckView::configure() {
-  if(Config::get().source.spellcheck_language.size()>0) {
-    aspell_config_replace(spellcheck_config, "lang", Config::get().source.spellcheck_language.c_str());
-    aspell_config_replace(spellcheck_config, "encoding", "utf-8");
-  }
-  spellcheck_possible_err=new_aspell_speller(spellcheck_config);
-  if(spellcheck_checker!=nullptr)
-    delete_aspell_speller(spellcheck_checker);
-  spellcheck_checker=nullptr;
-  if (aspell_error_number(spellcheck_possible_err) != 0)
-    std::cerr << "Spell check error: " << aspell_error_message(spellcheck_possible_err) << std::endl;
-  else
-    spellcheck_checker = to_aspell_speller(spellcheck_possible_err);
-  get_buffer()->remove_tag(spellcheck_error_tag, get_buffer()->begin(), get_buffer()->end());
+    if (Config::get().source.spellcheck_language.size() > 0) {
+        aspell_config_replace(spellcheck_config, "lang", Config::get().source.spellcheck_language.c_str());
+        aspell_config_replace(spellcheck_config, "encoding", "utf-8");
+    }
+    spellcheck_possible_err = new_aspell_speller(spellcheck_config);
+    if (spellcheck_checker != nullptr)
+        delete_aspell_speller(spellcheck_checker);
+    spellcheck_checker = nullptr;
+    if (aspell_error_number(spellcheck_possible_err) != 0)
+        std::cerr << "Spell check error: " << aspell_error_message(spellcheck_possible_err) << std::endl;
+    else
+        spellcheck_checker = to_aspell_speller(spellcheck_possible_err);
+    get_buffer()->remove_tag(spellcheck_error_tag, get_buffer()->begin(), get_buffer()->end());
 }
 
 void Source::SpellCheckView::hide_dialogs() {
-  delayed_spellcheck_suggestions_connection.disconnect();
-  if(SelectionDialog::get())
-    SelectionDialog::get()->hide();
+    delayed_spellcheck_suggestions_connection.disconnect();
+    if (SelectionDialog::get())
+        SelectionDialog::get()->hide();
 }
 
-void Source::SpellCheckView::spellcheck(const Gtk::TextIter& start, const Gtk::TextIter& end) {
-  if(spellcheck_checker==nullptr)
-    return;
-  auto iter=start;
-  while(iter && iter<end) {
-    if(is_word_iter(iter)) {
-      auto word=get_word(iter);
-      spellcheck_word(word.first, word.second);
-      iter=word.second; 
+void Source::SpellCheckView::spellcheck(const Gtk::TextIter &start, const Gtk::TextIter &end) {
+    if (spellcheck_checker == nullptr)
+        return;
+    auto iter = start;
+    while (iter && iter < end) {
+        if (is_word_iter(iter)) {
+            auto word = get_word(iter);
+            spellcheck_word(word.first, word.second);
+            iter = word.second;
+        }
+        iter.forward_char();
     }
-    iter.forward_char();
-  }
 }
 
 void Source::SpellCheckView::spellcheck() {
-  auto iter=get_buffer()->begin();
-  Gtk::TextIter begin_spellcheck_iter;
-  if(spellcheck_all) {
-    bool spell_check=!get_source_buffer()->iter_has_context_class(iter, "no-spell-check");
-    if(spell_check)
-      begin_spellcheck_iter=iter;
-    while(iter!=get_buffer()->end()) {
-      if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
-        iter=get_buffer()->end();
-      
-      spell_check=!spell_check;
-      if(spell_check)
-        begin_spellcheck_iter=iter;
-      else
-        spellcheck(begin_spellcheck_iter, iter);
-    }
-  }
-  else {
-    bool spell_check=!is_code_iter(iter);
-    if(spell_check)
-      begin_spellcheck_iter=iter;
-    while(iter!=get_buffer()->end()) {
-      auto iter1=iter;
-      auto iter2=iter;
-      if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string"))
-        iter1=get_buffer()->end();
-      if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
-        iter2=get_buffer()->end();
-      
-      if(iter2<iter1)
-        iter=iter2;
-      else
-        iter=iter1;
-      spell_check=!spell_check;
-      if(spell_check)
-        begin_spellcheck_iter=iter;
-      else
-        spellcheck(begin_spellcheck_iter, iter);
+    auto iter = get_buffer()->begin();
+    Gtk::TextIter begin_spellcheck_iter;
+    if (spellcheck_all) {
+        bool spell_check = !get_source_buffer()->iter_has_context_class(iter, "no-spell-check");
+        if (spell_check)
+            begin_spellcheck_iter = iter;
+        while (iter != get_buffer()->end()) {
+            if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
+                iter = get_buffer()->end();
+
+            spell_check = !spell_check;
+            if (spell_check)
+                begin_spellcheck_iter = iter;
+            else
+                spellcheck(begin_spellcheck_iter, iter);
+        }
+    } else {
+        bool spell_check = !is_code_iter(iter);
+        if (spell_check)
+            begin_spellcheck_iter = iter;
+        while (iter != get_buffer()->end()) {
+            auto iter1 = iter;
+            auto iter2 = iter;
+            if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string"))
+                iter1 = get_buffer()->end();
+            if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
+                iter2 = get_buffer()->end();
+
+            if (iter2 < iter1)
+                iter = iter2;
+            else
+                iter = iter1;
+            spell_check = !spell_check;
+            if (spell_check)
+                begin_spellcheck_iter = iter;
+            else
+                spellcheck(begin_spellcheck_iter, iter);
+        }
     }
-  }
 }
 
 void Source::SpellCheckView::remove_spellcheck_errors() {
-  get_buffer()->remove_tag(spellcheck_error_tag, get_buffer()->begin(), get_buffer()->end());
+    get_buffer()->remove_tag(spellcheck_error_tag, get_buffer()->begin(), get_buffer()->end());
 }
 
 void Source::SpellCheckView::goto_next_spellcheck_error() {
-  auto iter=get_buffer()->get_insert()->get_iter();
-  auto insert_iter=iter;
-  bool wrapped=false;
-  iter.forward_char();
-  while(!wrapped || iter<insert_iter) {
-    auto toggled_tags=iter.get_toggled_tags();
-    for(auto &toggled_tag: toggled_tags) {
-      if(toggled_tag==spellcheck_error_tag) {
-        get_buffer()->place_cursor(iter);
-        scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-        return;
-      }
-    }
+    auto iter = get_buffer()->get_insert()->get_iter();
+    auto insert_iter = iter;
+    bool wrapped = false;
     iter.forward_char();
-    if(!wrapped && iter==get_buffer()->end()) {
-      iter=get_buffer()->begin();
-      wrapped=true;
+    while (!wrapped || iter < insert_iter) {
+        auto toggled_tags = iter.get_toggled_tags();
+        for (auto &toggled_tag: toggled_tags) {
+            if (toggled_tag == spellcheck_error_tag) {
+                get_buffer()->place_cursor(iter);
+                scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+                return;
+            }
+        }
+        iter.forward_char();
+        if (!wrapped && iter == get_buffer()->end()) {
+            iter = get_buffer()->begin();
+            wrapped = true;
+        }
     }
-  }
-  Info::get().print("No spelling errors found in current buffer");
+    Info::get().print("No spelling errors found in current buffer");
 }
 
 bool Source::SpellCheckView::is_code_iter(const Gtk::TextIter &iter) {
-  if(*iter=='\'') {
-    auto previous_iter=iter;
-    if(!iter.starts_line() && previous_iter.backward_char() && *previous_iter=='\'')
-      return false;
-  }
-  if(spellcheck_all) {
-    if(no_spell_check_tag && (iter.has_tag(no_spell_check_tag) || iter.begins_tag(no_spell_check_tag) || iter.ends_tag(no_spell_check_tag)))
-      return true;
-    // workaround for gtksourceview bug
-    if(iter.ends_line()) {
-      auto previous_iter=iter;
-      if(previous_iter.backward_char()) {
-        if(*previous_iter=='\'' || *previous_iter=='"') {
-          auto next_iter=iter;
-          next_iter.forward_char();
-          if(next_iter.begins_tag(no_spell_check_tag) || next_iter.is_end())
-            return true;
-        }
-      }
-    }
-    // for example, mark first " as code iter in this case: r""
-    if(*iter=='\'' || *iter=='"') {
-      auto previous_iter=iter;
-      if(previous_iter.backward_char() && *previous_iter!='\'' && *previous_iter!='\"' && previous_iter.ends_tag(no_spell_check_tag))
-        return true;
+    if (*iter == '\'') {
+        auto previous_iter = iter;
+        if (!iter.starts_line() && previous_iter.backward_char() && *previous_iter == '\'')
+            return false;
     }
-    return false;
-  }
-  if(comment_tag) {
-    if(iter.has_tag(comment_tag) && !iter.begins_tag(comment_tag))
-      return false;
-    //Exception at the end of /**/
-    else if(iter.ends_tag(comment_tag)) {
-      auto previous_iter=iter;
-      if(previous_iter.backward_char() && *previous_iter=='/') {
-        auto previous_previous_iter=previous_iter;
-        if(previous_previous_iter.backward_char() && *previous_previous_iter=='*') {
-          auto it=previous_iter;
-          while(!it.begins_tag(comment_tag) && it.backward_to_tag_toggle(comment_tag)) {}
-          auto next_iter=it;
-          if(it.begins_tag(comment_tag) && next_iter.forward_char() && *it=='/' && *next_iter=='*' && previous_iter!=it)
+    if (spellcheck_all) {
+        if (no_spell_check_tag && (iter.has_tag(no_spell_check_tag) || iter.begins_tag(no_spell_check_tag) ||
+                                   iter.ends_tag(no_spell_check_tag)))
             return true;
+        // workaround for gtksourceview bug
+        if (iter.ends_line()) {
+            auto previous_iter = iter;
+            if (previous_iter.backward_char()) {
+                if (*previous_iter == '\'' || *previous_iter == '"') {
+                    auto next_iter = iter;
+                    next_iter.forward_char();
+                    if (next_iter.begins_tag(no_spell_check_tag) || next_iter.is_end())
+                        return true;
+                }
+            }
         }
-      }
-      return false;
-    }
-  }
-  if(string_tag) {
-    if(iter.has_tag(string_tag)) {
-      // When ending an open ''-string with ', the last '-iter is not correctly marked as end iter for string_tag
-      // For instance 'test, when inserting ' at end, would lead to spellcheck error of test'
-      if(*iter=='\'') {
-        long backslash_count=0;
-        auto it=iter;
-        while(it.backward_char() && *it=='\\')
-          ++backslash_count;
-        if(backslash_count%2==0) {
-          auto it=iter;
-          while(!it.begins_tag(string_tag) && it.backward_to_tag_toggle(string_tag)) {}
-          if(it.begins_tag(string_tag) && *it=='\'' && iter!=it)
-            return true;
+        // for example, mark first " as code iter in this case: r""
+        if (*iter == '\'' || *iter == '"') {
+            auto previous_iter = iter;
+            if (previous_iter.backward_char() && *previous_iter != '\'' && *previous_iter != '\"' &&
+                previous_iter.ends_tag(no_spell_check_tag))
+                return true;
         }
-      }
-      if(!iter.begins_tag(string_tag))
         return false;
     }
-    // If iter is at the end of string_tag, with exception of after " and '
-    else if(iter.ends_tag(string_tag)) {
-      auto previous_iter=iter;
-      if(!iter.starts_line() && previous_iter.backward_char()) {
-        if((*previous_iter=='"' || *previous_iter=='\'')) {
-          long backslash_count=0;
-          auto it=previous_iter;
-          while(it.backward_char() && *it=='\\')
-            ++backslash_count;
-          if(backslash_count%2==0) {
-            auto it=previous_iter;
-            while(!it.begins_tag(string_tag) && it.backward_to_tag_toggle(string_tag)) {}
-            if(it.begins_tag(string_tag) && *previous_iter==*it && previous_iter!=it)
-              return true;
-          }
+    if (comment_tag) {
+        if (iter.has_tag(comment_tag) && !iter.begins_tag(comment_tag))
+            return false;
+            //Exception at the end of /**/
+        else if (iter.ends_tag(comment_tag)) {
+            auto previous_iter = iter;
+            if (previous_iter.backward_char() && *previous_iter == '/') {
+                auto previous_previous_iter = previous_iter;
+                if (previous_previous_iter.backward_char() && *previous_previous_iter == '*') {
+                    auto it = previous_iter;
+                    while (!it.begins_tag(comment_tag) && it.backward_to_tag_toggle(comment_tag)) {}
+                    auto next_iter = it;
+                    if (it.begins_tag(comment_tag) && next_iter.forward_char() && *it == '/' && *next_iter == '*' &&
+                        previous_iter != it)
+                        return true;
+                }
+            }
+            return false;
         }
-        return false;
-      }
     }
-  }
-  return true;
+    if (string_tag) {
+        if (iter.has_tag(string_tag)) {
+            // When ending an open ''-string with ', the last '-iter is not correctly marked as end iter for string_tag
+            // For instance 'test, when inserting ' at end, would lead to spellcheck error of test'
+            if (*iter == '\'') {
+                long backslash_count = 0;
+                auto it = iter;
+                while (it.backward_char() && *it == '\\')
+                    ++backslash_count;
+                if (backslash_count % 2 == 0) {
+                    auto it = iter;
+                    while (!it.begins_tag(string_tag) && it.backward_to_tag_toggle(string_tag)) {}
+                    if (it.begins_tag(string_tag) && *it == '\'' && iter != it)
+                        return true;
+                }
+            }
+            if (!iter.begins_tag(string_tag))
+                return false;
+        }
+            // If iter is at the end of string_tag, with exception of after " and '
+        else if (iter.ends_tag(string_tag)) {
+            auto previous_iter = iter;
+            if (!iter.starts_line() && previous_iter.backward_char()) {
+                if ((*previous_iter == '"' || *previous_iter == '\'')) {
+                    long backslash_count = 0;
+                    auto it = previous_iter;
+                    while (it.backward_char() && *it == '\\')
+                        ++backslash_count;
+                    if (backslash_count % 2 == 0) {
+                        auto it = previous_iter;
+                        while (!it.begins_tag(string_tag) && it.backward_to_tag_toggle(string_tag)) {}
+                        if (it.begins_tag(string_tag) && *previous_iter == *it && previous_iter != it)
+                            return true;
+                    }
+                }
+                return false;
+            }
+        }
+    }
+    return true;
 }
 
-bool Source::SpellCheckView::is_word_iter(const Gtk::TextIter& iter) {
-  auto previous_iter=iter;
-  size_t backslash_count=0;
-  while(previous_iter.backward_char() && *previous_iter=='\\')
-    ++backslash_count;
-  if(backslash_count%2==1)
+bool Source::SpellCheckView::is_word_iter(const Gtk::TextIter &iter) {
+    auto previous_iter = iter;
+    size_t backslash_count = 0;
+    while (previous_iter.backward_char() && *previous_iter == '\\')
+        ++backslash_count;
+    if (backslash_count % 2 == 1)
+        return false;
+    if (((*iter >= 'A' && *iter <= 'Z') || (*iter >= 'a' && *iter <= 'z') || *iter >= 128))
+        return true;
+    if (*iter == '\'') {
+        if (is_code_iter(iter))
+            return false;
+        auto next_iter = iter;
+        if (next_iter.forward_char() && is_code_iter(next_iter) &&
+            !(comment_tag && iter.ends_tag(comment_tag))) // additional check for end of line comment
+            return false;
+        return true;
+    }
     return false;
-  if(((*iter>='A' && *iter<='Z') || (*iter>='a' && *iter<='z') || *iter>=128))
-    return true;
-  if(*iter=='\'') {
-    if(is_code_iter(iter))
-      return false;
-    auto next_iter=iter;
-    if(next_iter.forward_char() && is_code_iter(next_iter) &&
-       !(comment_tag && iter.ends_tag(comment_tag))) // additional check for end of line comment
-      return false;
-    return true;
-  }
-  return false;
 }
 
 std::pair<Gtk::TextIter, Gtk::TextIter> Source::SpellCheckView::get_word(Gtk::TextIter iter) {
-  auto start=iter;
-  auto end=iter;
-  
-  while(is_word_iter(iter)) {
-    start=iter;
-    if(!iter.backward_char())
-      break;
-  }
-  while(is_word_iter(end)) {
-    if(!end.forward_char())
-      break;
-  }
-  
-  return {start, end};
+    auto start = iter;
+    auto end = iter;
+
+    while (is_word_iter(iter)) {
+        start = iter;
+        if (!iter.backward_char())
+            break;
+    }
+    while (is_word_iter(end)) {
+        if (!end.forward_char())
+            break;
+    }
+
+    return {start, end};
 }
 
 void Source::SpellCheckView::spellcheck_word(Gtk::TextIter start, Gtk::TextIter end) {
-  if(*start=='\'' && end.get_offset()-start.get_offset()>=3) {
-    auto before_end=end;
-    if(before_end.backward_char() && *before_end=='\'') {
-      get_buffer()->remove_tag(spellcheck_error_tag, start, end);
-      start.forward_char();
-      end.backward_char();
+    if (*start == '\'' && end.get_offset() - start.get_offset() >= 3) {
+        auto before_end = end;
+        if (before_end.backward_char() && *before_end == '\'') {
+            get_buffer()->remove_tag(spellcheck_error_tag, start, end);
+            start.forward_char();
+            end.backward_char();
+        }
+    }
+
+    auto word = get_buffer()->get_text(start, end);
+    if (word.size() > 0) {
+        auto correct = aspell_speller_check(spellcheck_checker, word.data(), word.bytes());
+        if (correct == 0)
+            get_buffer()->apply_tag(spellcheck_error_tag, start, end);
+        else
+            get_buffer()->remove_tag(spellcheck_error_tag, start, end);
     }
-  }
-  
-  auto word=get_buffer()->get_text(start, end);
-  if(word.size()>0) {
-    auto correct = aspell_speller_check(spellcheck_checker, word.data(), word.bytes());
-    if(correct==0)
-      get_buffer()->apply_tag(spellcheck_error_tag, start, end);
-    else
-      get_buffer()->remove_tag(spellcheck_error_tag, start, end);
-  }
 }
 
-std::vector<std::string> Source::SpellCheckView::get_spellcheck_suggestions(const Gtk::TextIter& start, const Gtk::TextIter& end) {
-  auto word_with_error=get_buffer()->get_text(start, end);
-  
-  const AspellWordList *suggestions = aspell_speller_suggest(spellcheck_checker, word_with_error.data(), word_with_error.bytes());
-  AspellStringEnumeration *elements = aspell_word_list_elements(suggestions);
-  
-  std::vector<std::string> words;
-  const char *word;
-  while ((word = aspell_string_enumeration_next(elements))!= nullptr) {
-    words.emplace_back(word);
-  }
-  delete_aspell_string_enumeration(elements);
-  
-  return words;
+std::vector<std::string>
+Source::SpellCheckView::get_spellcheck_suggestions(const Gtk::TextIter &start, const Gtk::TextIter &end) {
+    auto word_with_error = get_buffer()->get_text(start, end);
+
+    const AspellWordList *suggestions = aspell_speller_suggest(spellcheck_checker, word_with_error.data(),
+                                                               word_with_error.bytes());
+    AspellStringEnumeration *elements = aspell_word_list_elements(suggestions);
+
+    std::vector<std::string> words;
+    const char *word;
+    while ((word = aspell_string_enumeration_next(elements)) != nullptr) {
+        words.emplace_back(word);
+    }
+    delete_aspell_string_enumeration(elements);
+
+    return words;
 }
diff --git a/src/source_spellcheck.h b/src/source_spellcheck.h
index a320760d..1b6b476e 100644
--- a/src/source_spellcheck.h
+++ b/src/source_spellcheck.h
@@ -1,44 +1,55 @@
 #pragma once
+
 #include "source_base.h"
 #include <aspell.h>
 
 namespace Source {
-  class SpellCheckView : virtual public Source::BaseView {
-  public:
-    SpellCheckView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
-    ~SpellCheckView();
-    
-    void configure() override;
-    void hide_dialogs() override;
-    
-    void spellcheck();
-    void remove_spellcheck_errors();
-    void goto_next_spellcheck_error();
-    
-  protected:
-    bool is_code_iter(const Gtk::TextIter &iter);
-    bool spellcheck_all=false;
-    guint last_keyval=0;
-    
-    Glib::RefPtr<Gtk::TextTag> comment_tag;
-    Glib::RefPtr<Gtk::TextTag> string_tag;
-    Glib::RefPtr<Gtk::TextTag> no_spell_check_tag;
-  private:
-    Glib::RefPtr<Gtk::TextTag> spellcheck_error_tag;
-    
-    sigc::connection signal_tag_added_connection;
-    sigc::connection signal_tag_removed_connection;
-    
-    static AspellConfig* spellcheck_config;
-    AspellCanHaveError *spellcheck_possible_err;
-    AspellSpeller *spellcheck_checker;
-    bool is_word_iter(const Gtk::TextIter& iter);
-    std::pair<Gtk::TextIter, Gtk::TextIter> get_word(Gtk::TextIter iter);
-    void spellcheck_word(Gtk::TextIter start, Gtk::TextIter end);
-    std::vector<std::string> get_spellcheck_suggestions(const Gtk::TextIter& start, const Gtk::TextIter& end);
-    sigc::connection delayed_spellcheck_suggestions_connection;
-    sigc::connection delayed_spellcheck_error_clear;
-    
-    void spellcheck(const Gtk::TextIter& start, const Gtk::TextIter& end);
-  };
+    class SpellCheckView : virtual public Source::BaseView {
+    public:
+        SpellCheckView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+
+        ~SpellCheckView();
+
+        void configure() override;
+
+        void hide_dialogs() override;
+
+        void spellcheck();
+
+        void remove_spellcheck_errors();
+
+        void goto_next_spellcheck_error();
+
+    protected:
+        bool is_code_iter(const Gtk::TextIter &iter);
+
+        bool spellcheck_all = false;
+        guint last_keyval = 0;
+
+        Glib::RefPtr<Gtk::TextTag> comment_tag;
+        Glib::RefPtr<Gtk::TextTag> string_tag;
+        Glib::RefPtr<Gtk::TextTag> no_spell_check_tag;
+    private:
+        Glib::RefPtr<Gtk::TextTag> spellcheck_error_tag;
+
+        sigc::connection signal_tag_added_connection;
+        sigc::connection signal_tag_removed_connection;
+
+        static AspellConfig *spellcheck_config;
+        AspellCanHaveError *spellcheck_possible_err;
+        AspellSpeller *spellcheck_checker;
+
+        bool is_word_iter(const Gtk::TextIter &iter);
+
+        std::pair<Gtk::TextIter, Gtk::TextIter> get_word(Gtk::TextIter iter);
+
+        void spellcheck_word(Gtk::TextIter start, Gtk::TextIter end);
+
+        std::vector<std::string> get_spellcheck_suggestions(const Gtk::TextIter &start, const Gtk::TextIter &end);
+
+        sigc::connection delayed_spellcheck_suggestions_connection;
+        sigc::connection delayed_spellcheck_error_clear;
+
+        void spellcheck(const Gtk::TextIter &start, const Gtk::TextIter &end);
+    };
 }
diff --git a/src/terminal.cc b/src/terminal.cc
index 909c37dd..ab285590 100644
--- a/src/terminal.cc
+++ b/src/terminal.cc
@@ -9,427 +9,426 @@
 #include <thread>
 
 Terminal::Terminal() {
-  set_editable(false);
-  
-  bold_tag=get_buffer()->create_tag();
-  bold_tag->property_weight()=Pango::WEIGHT_ULTRAHEAVY;
-  
-  link_tag=get_buffer()->create_tag();
-  link_tag->property_underline()=Pango::Underline::UNDERLINE_SINGLE;
-  
-  link_mouse_cursor=Gdk::Cursor::create(Gdk::CursorType::HAND1);
-  default_mouse_cursor=Gdk::Cursor::create(Gdk::CursorType::XTERM);
-}
+    set_editable(false);
 
-int Terminal::process(const std::string &command, const boost::filesystem::path &path, bool use_pipes) {  
-  std::unique_ptr<TinyProcessLib::Process> process;
-  if(use_pipes)
-    process=std::make_unique<TinyProcessLib::Process>(command, path.string(), [this](const char* bytes, size_t n) {
-      async_print(std::string(bytes, n));
-    }, [this](const char* bytes, size_t n) {
-      async_print(std::string(bytes, n), true);
-    });
-  else
-    process=std::make_unique<TinyProcessLib::Process>(command, path.string());
-    
-  if(process->get_id()<=0) {
-    async_print("Error: failed to run command: " + command + "\n", true);
-    return -1;
-  }
-  
-  return process->get_exit_status();
+    bold_tag = get_buffer()->create_tag();
+    bold_tag->property_weight() = Pango::WEIGHT_ULTRAHEAVY;
+
+    link_tag = get_buffer()->create_tag();
+    link_tag->property_underline() = Pango::Underline::UNDERLINE_SINGLE;
+
+    link_mouse_cursor = Gdk::Cursor::create(Gdk::CursorType::HAND1);
+    default_mouse_cursor = Gdk::Cursor::create(Gdk::CursorType::XTERM);
 }
 
-int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path, std::ostream *stderr_stream) {
-  TinyProcessLib::Process process(command, path.string(), [&stdout_stream](const char* bytes, size_t n) {
-    Glib::ustring umessage(std::string(bytes, n));
-    Glib::ustring::iterator iter;
-    while(!umessage.validate(iter)) {
-      auto next_char_iter=iter;
-      next_char_iter++;
-      umessage.replace(iter, next_char_iter, "?");
-    }
-    stdout_stream.write(umessage.data(), n);
-  }, [this, stderr_stream](const char* bytes, size_t n) {
-    if(stderr_stream)
-      stderr_stream->write(bytes, n);
+int Terminal::process(const std::string &command, const boost::filesystem::path &path, bool use_pipes) {
+    std::unique_ptr<TinyProcessLib::Process> process;
+    if (use_pipes)
+        process = std::make_unique<TinyProcessLib::Process>(command, path.string(),
+                                                            [this](const char *bytes, size_t n) {
+                                                                async_print(std::string(bytes, n));
+                                                            }, [this](const char *bytes, size_t n) {
+                    async_print(std::string(bytes, n), true);
+                });
     else
-      async_print(std::string(bytes, n), true);
-  }, true);
-  
-  if(process.get_id()<=0) {
-    async_print("Error: failed to run command: " + command + "\n", true);
-    return -1;
-  }
-  
-  char buffer[131072];
-  for(;;) {
-    stdin_stream.readsome(buffer, 131072);
-    auto read_n=stdin_stream.gcount();
-    if(read_n==0)
-      break;
-    if(!process.write(buffer, read_n)) {
-      break;
+        process = std::make_unique<TinyProcessLib::Process>(command, path.string());
+
+    if (process->get_id() <= 0) {
+        async_print("Error: failed to run command: " + command + "\n", true);
+        return -1;
     }
-  }
-  process.close_stdin();
-  
-  return process.get_exit_status();
+
+    return process->get_exit_status();
 }
 
-void Terminal::async_process(const std::string &command, const boost::filesystem::path &path, std::function<void(int exit_status)> callback, bool quiet) {
-  std::thread async_execute_thread([this, command, path, callback, quiet]() {
-    std::unique_lock<std::mutex> processes_lock(processes_mutex);
-    stdin_buffer.clear();
-    auto process=std::make_shared<TinyProcessLib::Process>(command, path.string(), [this, quiet](const char* bytes, size_t n) {
-      if(!quiet)
-        async_print(std::string(bytes, n));
-    }, [this, quiet](const char* bytes, size_t n) {
-      if(!quiet)
-        async_print(std::string(bytes, n), true);
+int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command,
+                      const boost::filesystem::path &path, std::ostream *stderr_stream) {
+    TinyProcessLib::Process process(command, path.string(), [&stdout_stream](const char *bytes, size_t n) {
+        Glib::ustring umessage(std::string(bytes, n));
+        Glib::ustring::iterator iter;
+        while (!umessage.validate(iter)) {
+            auto next_char_iter = iter;
+            next_char_iter++;
+            umessage.replace(iter, next_char_iter, "?");
+        }
+        stdout_stream.write(umessage.data(), n);
+    }, [this, stderr_stream](const char *bytes, size_t n) {
+        if (stderr_stream)
+            stderr_stream->write(bytes, n);
+        else
+            async_print(std::string(bytes, n), true);
     }, true);
-    auto pid=process->get_id();
-    if (pid<=0) {
-      processes_lock.unlock();
-      async_print("Error: failed to run command: " + command + "\n", true);
-      if(callback)
-        callback(-1);
-      return;
-    }
-    else {
-      processes.emplace_back(process);
-      processes_lock.unlock();
+
+    if (process.get_id() <= 0) {
+        async_print("Error: failed to run command: " + command + "\n", true);
+        return -1;
     }
-      
-    auto exit_status=process->get_exit_status();
-    
-    processes_lock.lock();
-    for(auto it=processes.begin();it!=processes.end();it++) {
-      if((*it)->get_id()==pid) {
-        processes.erase(it);
-        break;
-      }
+
+    char buffer[131072];
+    for (;;) {
+        stdin_stream.readsome(buffer, 131072);
+        auto read_n = stdin_stream.gcount();
+        if (read_n == 0)
+            break;
+        if (!process.write(buffer, read_n)) {
+            break;
+        }
     }
-    stdin_buffer.clear();
-    processes_lock.unlock();
-      
-    if(callback)
-      callback(exit_status);
-  });
-  async_execute_thread.detach();
+    process.close_stdin();
+
+    return process.get_exit_status();
+}
+
+void Terminal::async_process(const std::string &command, const boost::filesystem::path &path,
+                             std::function<void(int exit_status)> callback, bool quiet) {
+    std::thread async_execute_thread([this, command, path, callback, quiet]() {
+        std::unique_lock<std::mutex> processes_lock(processes_mutex);
+        stdin_buffer.clear();
+        auto process = std::make_shared<TinyProcessLib::Process>(command, path.string(),
+                                                                 [this, quiet](const char *bytes, size_t n) {
+                                                                     if (!quiet)
+                                                                         async_print(std::string(bytes, n));
+                                                                 }, [this, quiet](const char *bytes, size_t n) {
+                    if (!quiet)
+                        async_print(std::string(bytes, n), true);
+                }, true);
+        auto pid = process->get_id();
+        if (pid <= 0) {
+            processes_lock.unlock();
+            async_print("Error: failed to run command: " + command + "\n", true);
+            if (callback)
+                callback(-1);
+            return;
+        } else {
+            processes.emplace_back(process);
+            processes_lock.unlock();
+        }
+
+        auto exit_status = process->get_exit_status();
+
+        processes_lock.lock();
+        for (auto it = processes.begin(); it != processes.end(); it++) {
+            if ((*it)->get_id() == pid) {
+                processes.erase(it);
+                break;
+            }
+        }
+        stdin_buffer.clear();
+        processes_lock.unlock();
+
+        if (callback)
+            callback(exit_status);
+    });
+    async_execute_thread.detach();
 }
 
 void Terminal::kill_last_async_process(bool force) {
-  std::unique_lock<std::mutex> lock(processes_mutex);
-  if(processes.empty())
-    Info::get().print("No running processes");
-  else
-    processes.back()->kill(force);
+    std::unique_lock<std::mutex> lock(processes_mutex);
+    if (processes.empty())
+        Info::get().print("No running processes");
+    else
+        processes.back()->kill(force);
 }
 
 void Terminal::kill_async_processes(bool force) {
-  std::unique_lock<std::mutex> lock(processes_mutex);
-  for(auto &process: processes)
-    process->kill(force);
+    std::unique_lock<std::mutex> lock(processes_mutex);
+    for (auto &process: processes)
+        process->kill(force);
 }
 
 bool Terminal::on_motion_notify_event(GdkEventMotion *event) {
-  Gtk::TextIter iter;
-  int location_x, location_y;
-  window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, location_x, location_y);
-  get_iter_at_location(iter, location_x, location_y);
-  if(iter.has_tag(link_tag))
-    get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(link_mouse_cursor);
-  else
-    get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(default_mouse_cursor);
-  
-  // Workaround for drag-and-drop crash on MacOS
-  // TODO 2018: check if this bug has been fixed
-#ifdef __APPLE__
-  if((event->state & GDK_BUTTON1_MASK) == 0)
-    return Gtk::TextView::on_motion_notify_event(event);
-  else {
-    int x, y;
-    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
     Gtk::TextIter iter;
-    get_iter_at_location(iter, x, y);
-    get_buffer()->select_range(get_buffer()->get_insert()->get_iter(), iter);
-    return true;
-  }
+    int location_x, location_y;
+    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, location_x, location_y);
+    get_iter_at_location(iter, location_x, location_y);
+    if (iter.has_tag(link_tag))
+        get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(link_mouse_cursor);
+    else
+        get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(default_mouse_cursor);
+
+    // Workaround for drag-and-drop crash on MacOS
+    // TODO 2018: check if this bug has been fixed
+#ifdef __APPLE__
+    if((event->state & GDK_BUTTON1_MASK) == 0)
+      return Gtk::TextView::on_motion_notify_event(event);
+    else {
+      int x, y;
+      window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
+      Gtk::TextIter iter;
+      get_iter_at_location(iter, x, y);
+      get_buffer()->select_range(get_buffer()->get_insert()->get_iter(), iter);
+      return true;
+    }
 #else
-  return Gtk::TextView::on_motion_notify_event(event);
+    return Gtk::TextView::on_motion_notify_event(event);
 #endif
-  
-  return Gtk::TextView::on_motion_notify_event(event);
+
+    return Gtk::TextView::on_motion_notify_event(event);
 }
 
 std::tuple<size_t, size_t, std::string, std::string, std::string> Terminal::find_link(const std::string &line) {
-  const static std::regex link_regex("^([A-Z]:)?([^:]+):([0-9]+):([0-9]+): .*$|" //compile warning/error/rename usages
-                                     "^Assertion failed: .*file ([A-Z]:)?([^:]+), line ([0-9]+)\\.$|" //clang assert()
-                                     "^[^:]*: ([A-Z]:)?([^:]+):([0-9]+): .* Assertion .* failed\\.$|" //gcc assert()
-                                     "^ERROR:([A-Z]:)?([^:]+):([0-9]+):.*$"); //g_assert (glib.h)
-  size_t start_position=-1, end_position=-1;
-  std::string path, line_number, line_offset;
-  std::smatch sm;
-  if(std::regex_match(line, sm, link_regex)) {
-    for(size_t sub=1;sub<link_regex.mark_count();) {
-      size_t subs=sub==1?4:3;
-      if(sm.length(sub+1)) {
-        start_position=sm.position(sub+1)-sm.length(sub);
-        end_position=sm.position(sub+subs-1)+sm.length(sub+subs-1);
-        if(sm.length(sub))
-          path+=sm[sub].str();
-        path+=sm[sub+1].str();
-        line_number=sm[sub+2].str();
-        line_offset=subs==4?sm[sub+3].str():"1";
-        break;
-      }
-      sub+=subs;
+    const static std::regex link_regex("^([A-Z]:)?([^:]+):([0-9]+):([0-9]+): .*$|" //compile warning/error/rename usages
+                                       "^Assertion failed: .*file ([A-Z]:)?([^:]+), line ([0-9]+)\\.$|" //clang assert()
+                                       "^[^:]*: ([A-Z]:)?([^:]+):([0-9]+): .* Assertion .* failed\\.$|" //gcc assert()
+                                       "^ERROR:([A-Z]:)?([^:]+):([0-9]+):.*$"); //g_assert (glib.h)
+    size_t start_position = -1, end_position = -1;
+    std::string path, line_number, line_offset;
+    std::smatch sm;
+    if (std::regex_match(line, sm, link_regex)) {
+        for (size_t sub = 1; sub < link_regex.mark_count();) {
+            size_t subs = sub == 1 ? 4 : 3;
+            if (sm.length(sub + 1)) {
+                start_position = sm.position(sub + 1) - sm.length(sub);
+                end_position = sm.position(sub + subs - 1) + sm.length(sub + subs - 1);
+                if (sm.length(sub))
+                    path += sm[sub].str();
+                path += sm[sub + 1].str();
+                line_number = sm[sub + 2].str();
+                line_offset = subs == 4 ? sm[sub + 3].str() : "1";
+                break;
+            }
+            sub += subs;
+        }
     }
-  }
-  return std::make_tuple(start_position, end_position, path, line_number, line_offset);
+    return std::make_tuple(start_position, end_position, path, line_number, line_offset);
 }
 
 void Terminal::apply_link_tags(Gtk::TextIter start_iter, Gtk::TextIter end_iter) {
-  auto iter=start_iter;
-  Gtk::TextIter line_start;
-  bool line_start_set=false;
-  bool delimiter_found=false;
-  bool dot_found=false;
-  bool number_found=false;
-  do {
-    if(iter.starts_line()) {
-      line_start=iter;
-      line_start_set=true;
-      delimiter_found=false;
-      dot_found=false;
-      number_found=false;
-    }
-    if(line_start_set && (*iter=='\\' || *iter=='/'))
-      delimiter_found=true;
-    else if(line_start_set && *iter=='.')
-      dot_found=true;
-    else if(line_start_set && (*iter>='0' && *iter<='9'))
-      number_found=true;
-    else if(line_start_set && delimiter_found && dot_found && number_found && iter.ends_line()) {
-      auto line=get_buffer()->get_text(line_start, iter);
-      //Convert to ascii for std::regex and Gtk::Iter::forward_chars
-      for(size_t c=0;c<line.size();++c) {
-        if(line[c]>127)
-          line.replace(c, 1, "a");
-      }
-      auto link=find_link(line.raw());
-      if(std::get<0>(link)!=static_cast<size_t>(-1)) {
-        auto link_start=line_start;
-        auto link_end=line_start;
-        link_start.forward_chars(std::get<0>(link));
-        link_end.forward_chars(std::get<1>(link));
-        get_buffer()->apply_tag(link_tag, link_start, link_end);
-      }
-      line_start_set=false;
-    }
-  } while(iter.forward_char() && iter!=end_iter);
+    auto iter = start_iter;
+    Gtk::TextIter line_start;
+    bool line_start_set = false;
+    bool delimiter_found = false;
+    bool dot_found = false;
+    bool number_found = false;
+    do {
+        if (iter.starts_line()) {
+            line_start = iter;
+            line_start_set = true;
+            delimiter_found = false;
+            dot_found = false;
+            number_found = false;
+        }
+        if (line_start_set && (*iter == '\\' || *iter == '/'))
+            delimiter_found = true;
+        else if (line_start_set && *iter == '.')
+            dot_found = true;
+        else if (line_start_set && (*iter >= '0' && *iter <= '9'))
+            number_found = true;
+        else if (line_start_set && delimiter_found && dot_found && number_found && iter.ends_line()) {
+            auto line = get_buffer()->get_text(line_start, iter);
+            //Convert to ascii for std::regex and Gtk::Iter::forward_chars
+            for (size_t c = 0; c < line.size(); ++c) {
+                if (line[c] > 127)
+                    line.replace(c, 1, "a");
+            }
+            auto link = find_link(line.raw());
+            if (std::get<0>(link) != static_cast<size_t>(-1)) {
+                auto link_start = line_start;
+                auto link_end = line_start;
+                link_start.forward_chars(std::get<0>(link));
+                link_end.forward_chars(std::get<1>(link));
+                get_buffer()->apply_tag(link_tag, link_start, link_end);
+            }
+            line_start_set = false;
+        }
+    } while (iter.forward_char() && iter != end_iter);
 }
 
-size_t Terminal::print(const std::string &message, bool bold){
+size_t Terminal::print(const std::string &message, bool bold) {
 #ifdef _WIN32
-  //Remove color codes
-  auto message_no_color=message; //copy here since operations on Glib::ustring is too slow
-  size_t pos=0;
-  while((pos=message_no_color.find('\e', pos))!=std::string::npos) {
-    if((pos+2)>=message_no_color.size())
-      break;
-    if(message_no_color[pos+1]=='[') {
-      size_t end_pos=pos+2;
-      bool color_code_found=false;
-      while(end_pos<message_no_color.size()) {
-        if((message_no_color[end_pos]>='0' && message_no_color[end_pos]<='9') || message_no_color[end_pos]==';')
-          end_pos++;
-        else if(message_no_color[end_pos]=='m') {
-          color_code_found=true;
-          break;
+    //Remove color codes
+    auto message_no_color = message; //copy here since operations on Glib::ustring is too slow
+    size_t pos = 0;
+    while ((pos = message_no_color.find('\e', pos)) != std::string::npos) {
+        if ((pos + 2) >= message_no_color.size())
+            break;
+        if (message_no_color[pos + 1] == '[') {
+            size_t end_pos = pos + 2;
+            bool color_code_found = false;
+            while (end_pos < message_no_color.size()) {
+                if ((message_no_color[end_pos] >= '0' && message_no_color[end_pos] <= '9') ||
+                    message_no_color[end_pos] == ';')
+                    end_pos++;
+                else if (message_no_color[end_pos] == 'm') {
+                    color_code_found = true;
+                    break;
+                } else
+                    break;
+            }
+            if (color_code_found)
+                message_no_color.erase(pos, end_pos - pos + 1);
         }
-        else
-          break;
-      }
-      if(color_code_found)
-        message_no_color.erase(pos, end_pos-pos+1);
     }
-  }
-  Glib::ustring umessage=message_no_color;
+    Glib::ustring umessage = message_no_color;
 #else
-  Glib::ustring umessage=message;
+    Glib::ustring umessage=message;
 #endif
-  
-  Glib::ustring::iterator iter;
-  while(!umessage.validate(iter)) {
-    auto next_char_iter=iter;
-    next_char_iter++;
-    umessage.replace(iter, next_char_iter, "?");
-  }
-  
-  auto start_mark=get_buffer()->create_mark(get_buffer()->get_iter_at_line(get_buffer()->end().get_line()));
-  if(bold)
-    get_buffer()->insert_with_tag(get_buffer()->end(), umessage, bold_tag);
-  else
-    get_buffer()->insert(get_buffer()->end(), umessage);
-  auto start_iter=start_mark->get_iter();
-  get_buffer()->delete_mark(start_mark);
-  auto end_iter=get_buffer()->get_insert()->get_iter();
-  
-  apply_link_tags(start_iter, end_iter);
-  
-  if(get_buffer()->get_line_count()>Config::get().terminal.history_size) {
-    int lines=get_buffer()->get_line_count()-Config::get().terminal.history_size;
-    get_buffer()->erase(get_buffer()->begin(), get_buffer()->get_iter_at_line(lines));
-    deleted_lines+=static_cast<size_t>(lines);
-  }
-  
-  return static_cast<size_t>(get_buffer()->end().get_line())+deleted_lines;
+
+    Glib::ustring::iterator iter;
+    while (!umessage.validate(iter)) {
+        auto next_char_iter = iter;
+        next_char_iter++;
+        umessage.replace(iter, next_char_iter, "?");
+    }
+
+    auto start_mark = get_buffer()->create_mark(get_buffer()->get_iter_at_line(get_buffer()->end().get_line()));
+    if (bold)
+        get_buffer()->insert_with_tag(get_buffer()->end(), umessage, bold_tag);
+    else
+        get_buffer()->insert(get_buffer()->end(), umessage);
+    auto start_iter = start_mark->get_iter();
+    get_buffer()->delete_mark(start_mark);
+    auto end_iter = get_buffer()->get_insert()->get_iter();
+
+    apply_link_tags(start_iter, end_iter);
+
+    if (get_buffer()->get_line_count() > Config::get().terminal.history_size) {
+        int lines = get_buffer()->get_line_count() - Config::get().terminal.history_size;
+        get_buffer()->erase(get_buffer()->begin(), get_buffer()->get_iter_at_line(lines));
+        deleted_lines += static_cast<size_t>(lines);
+    }
+
+    return static_cast<size_t>(get_buffer()->end().get_line()) + deleted_lines;
 }
 
 void Terminal::async_print(const std::string &message, bool bold) {
-  dispatcher.post([message, bold] {
-    Terminal::get().print(message, bold);
-  });
+    dispatcher.post([message, bold] {
+        Terminal::get().print(message, bold);
+    });
 }
 
 void Terminal::async_print(size_t line_nr, const std::string &message) {
-  dispatcher.post([this, line_nr, message] {
-    if(line_nr<deleted_lines)
-      return;
-    
-    Glib::ustring umessage=message;
-    Glib::ustring::iterator iter;
-    while(!umessage.validate(iter)) {
-      auto next_char_iter=iter;
-      next_char_iter++;
-      umessage.replace(iter, next_char_iter, "?");
-    }
-    
-    auto end_line_iter=get_buffer()->get_iter_at_line(static_cast<int>(line_nr-deleted_lines));
-    while(!end_line_iter.ends_line() && end_line_iter.forward_char()) {}
-    get_buffer()->insert(end_line_iter, umessage);
-  });
+    dispatcher.post([this, line_nr, message] {
+        if (line_nr < deleted_lines)
+            return;
+
+        Glib::ustring umessage = message;
+        Glib::ustring::iterator iter;
+        while (!umessage.validate(iter)) {
+            auto next_char_iter = iter;
+            next_char_iter++;
+            umessage.replace(iter, next_char_iter, "?");
+        }
+
+        auto end_line_iter = get_buffer()->get_iter_at_line(static_cast<int>(line_nr - deleted_lines));
+        while (!end_line_iter.ends_line() && end_line_iter.forward_char()) {}
+        get_buffer()->insert(end_line_iter, umessage);
+    });
 }
 
 void Terminal::configure() {
-  link_tag->property_foreground_rgba()=get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_LINK);
-  
-  if(Config::get().terminal.font.size()>0) {
-    override_font(Pango::FontDescription(Config::get().terminal.font));
-  }
-  else if(Config::get().source.font.size()>0) {
-    Pango::FontDescription font_description(Config::get().source.font);
-    auto font_description_size=font_description.get_size();
-    if(font_description_size==0) {
-      Pango::FontDescription default_font_description(Gtk::Settings::get_default()->property_gtk_font_name());
-      font_description_size=default_font_description.get_size();
+    link_tag->property_foreground_rgba() = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_LINK);
+
+    if (Config::get().terminal.font.size() > 0) {
+        override_font(Pango::FontDescription(Config::get().terminal.font));
+    } else if (Config::get().source.font.size() > 0) {
+        Pango::FontDescription font_description(Config::get().source.font);
+        auto font_description_size = font_description.get_size();
+        if (font_description_size == 0) {
+            Pango::FontDescription default_font_description(Gtk::Settings::get_default()->property_gtk_font_name());
+            font_description_size = default_font_description.get_size();
+        }
+        if (font_description_size > 0)
+            font_description.set_size(font_description_size * 0.95);
+        override_font(font_description);
     }
-    if(font_description_size>0)
-      font_description.set_size(font_description_size*0.95);
-    override_font(font_description);
-  }
 }
 
 void Terminal::clear() {
-  get_buffer()->set_text("");
+    get_buffer()->set_text("");
 }
 
-bool Terminal::on_button_press_event(GdkEventButton* button_event) {
-  //open clicked link in terminal
-  if(button_event->type==GDK_BUTTON_PRESS && button_event->button==GDK_BUTTON_PRIMARY) {
-    Gtk::TextIter iter;
-    int location_x, location_y;
-    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, button_event->x, button_event->y, location_x, location_y);
-    get_iter_at_location(iter, location_x, location_y);
-    if(iter.has_tag(link_tag)) {
-      auto start_iter=get_buffer()->get_iter_at_line(iter.get_line());
-      auto end_iter=start_iter;
-      while(!end_iter.ends_line() && end_iter.forward_char()) {}
-      auto link=find_link(get_buffer()->get_text(start_iter, end_iter).raw());
-      if(std::get<0>(link)!=static_cast<size_t>(-1)) {
-        boost::filesystem::path path=std::get<2>(link);
-        std::string line=std::get<3>(link);
-        std::string index=std::get<4>(link);
-        
-        if(!path.empty() && *path.begin()=="~") { // boost::filesystem does not recognize ~
-          boost::filesystem::path corrected_path;
-          corrected_path=filesystem::get_home_path();
-          if(!corrected_path.empty()) {
-            auto it=path.begin();
-            ++it;
-            for(;it!=path.end();++it)
-              corrected_path/=*it;
-            path=corrected_path;
-          }
-        }
-        
-        if(path.is_relative()) {
-          if(Project::current) {
-            auto absolute_path=Project::current->build->get_default_path()/path;
-            if(boost::filesystem::exists(absolute_path))
-              path=absolute_path;
-            else
-              path=Project::current->build->get_debug_path()/path;
-          }
-          else
-            return Gtk::TextView::on_button_press_event(button_event);
-        }
-        if(boost::filesystem::is_regular_file(path)) {
-          Notebook::get().open(path);
-          if(auto view=Notebook::get().get_current_view()) {
-            try {
-              int line_int = std::stoi(line)-1;
-              int index_int = std::stoi(index)-1;
-              view->place_cursor_at_line_index(line_int, index_int);
-              view->scroll_to_cursor_delayed(view, true, true);
-              return true;
+bool Terminal::on_button_press_event(GdkEventButton *button_event) {
+    //open clicked link in terminal
+    if (button_event->type == GDK_BUTTON_PRESS && button_event->button == GDK_BUTTON_PRIMARY) {
+        Gtk::TextIter iter;
+        int location_x, location_y;
+        window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, button_event->x, button_event->y, location_x,
+                                location_y);
+        get_iter_at_location(iter, location_x, location_y);
+        if (iter.has_tag(link_tag)) {
+            auto start_iter = get_buffer()->get_iter_at_line(iter.get_line());
+            auto end_iter = start_iter;
+            while (!end_iter.ends_line() && end_iter.forward_char()) {}
+            auto link = find_link(get_buffer()->get_text(start_iter, end_iter).raw());
+            if (std::get<0>(link) != static_cast<size_t>(-1)) {
+                boost::filesystem::path path = std::get<2>(link);
+                std::string line = std::get<3>(link);
+                std::string index = std::get<4>(link);
+
+                if (!path.empty() && *path.begin() == "~") { // boost::filesystem does not recognize ~
+                    boost::filesystem::path corrected_path;
+                    corrected_path = filesystem::get_home_path();
+                    if (!corrected_path.empty()) {
+                        auto it = path.begin();
+                        ++it;
+                        for (; it != path.end(); ++it)
+                            corrected_path /= *it;
+                        path = corrected_path;
+                    }
+                }
+
+                if (path.is_relative()) {
+                    if (Project::current) {
+                        auto absolute_path = Project::current->build->get_default_path() / path;
+                        if (boost::filesystem::exists(absolute_path))
+                            path = absolute_path;
+                        else
+                            path = Project::current->build->get_debug_path() / path;
+                    } else
+                        return Gtk::TextView::on_button_press_event(button_event);
+                }
+                if (boost::filesystem::is_regular_file(path)) {
+                    Notebook::get().open(path);
+                    if (auto view = Notebook::get().get_current_view()) {
+                        try {
+                            int line_int = std::stoi(line) - 1;
+                            int index_int = std::stoi(index) - 1;
+                            view->place_cursor_at_line_index(line_int, index_int);
+                            view->scroll_to_cursor_delayed(view, true, true);
+                            return true;
+                        }
+                        catch (...) {}
+                    }
+                }
             }
-            catch(...) {}
-          }
         }
-      }
     }
-  }
-  return Gtk::TextView::on_button_press_event(button_event);
+    return Gtk::TextView::on_button_press_event(button_event);
 }
 
 bool Terminal::on_key_press_event(GdkEventKey *event) {
-  std::unique_lock<std::mutex> lock(processes_mutex);
-  bool debug_is_running=false;
+    std::unique_lock<std::mutex> lock(processes_mutex);
+    bool debug_is_running = false;
 #ifdef JUCI_ENABLE_DEBUG
-  debug_is_running=Project::current?Project::current->debug_is_running():false;
+    debug_is_running=Project::current?Project::current->debug_is_running():false;
 #endif
-  if(processes.size()>0 || debug_is_running) {
-    auto unicode=gdk_keyval_to_unicode(event->keyval);
-    if(unicode>=32 && unicode!=126 && unicode!=0) {
-      get_buffer()->place_cursor(get_buffer()->end());
-      stdin_buffer+=unicode;
-      get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size()-1));
-    }
-    else if(event->keyval==GDK_KEY_BackSpace) {
-      get_buffer()->place_cursor(get_buffer()->end());
-      if(stdin_buffer.size()>0 && get_buffer()->get_char_count()>0) {
-        auto iter=get_buffer()->end();
-        iter--;
-        stdin_buffer.erase(stdin_buffer.size()-1);
-        get_buffer()->erase(iter, get_buffer()->end());
-      }
-    }
-    else if(event->keyval==GDK_KEY_Return || event->keyval==GDK_KEY_KP_Enter) {
-      get_buffer()->place_cursor(get_buffer()->end());
-      stdin_buffer+='\n';
-      if(debug_is_running) {
+    if (processes.size() > 0 || debug_is_running) {
+        auto unicode = gdk_keyval_to_unicode(event->keyval);
+        if (unicode >= 32 && unicode != 126 && unicode != 0) {
+            get_buffer()->place_cursor(get_buffer()->end());
+            stdin_buffer += unicode;
+            get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size() - 1));
+        } else if (event->keyval == GDK_KEY_BackSpace) {
+            get_buffer()->place_cursor(get_buffer()->end());
+            if (stdin_buffer.size() > 0 && get_buffer()->get_char_count() > 0) {
+                auto iter = get_buffer()->end();
+                iter--;
+                stdin_buffer.erase(stdin_buffer.size() - 1);
+                get_buffer()->erase(iter, get_buffer()->end());
+            }
+        } else if (event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) {
+            get_buffer()->place_cursor(get_buffer()->end());
+            stdin_buffer += '\n';
+            if (debug_is_running) {
 #ifdef JUCI_ENABLE_DEBUG
-        Project::current->debug_write(stdin_buffer);
+                Project::current->debug_write(stdin_buffer);
 #endif
-      }
-      else
-        processes.back()->write(stdin_buffer);
-      get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size()-1));
-      stdin_buffer.clear();
+            } else
+                processes.back()->write(stdin_buffer);
+            get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size() - 1));
+            stdin_buffer.clear();
+        }
     }
-  }
-  return true;
+    return true;
 }
diff --git a/src/terminal.h b/src/terminal.h
index 8499cbd1..88eb03df 100644
--- a/src/terminal.h
+++ b/src/terminal.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <mutex>
 #include <functional>
 #include "gtkmm.h"
@@ -9,42 +10,56 @@
 #include <tuple>
 
 class Terminal : public Gtk::TextView {
-  Terminal();
+    Terminal();
+
 public:
-  static Terminal &get() {
-    static Terminal singleton;
-    return singleton;
-  }
-  
-  int process(const std::string &command, const boost::filesystem::path &path="", bool use_pipes=true);
-  int process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path="", std::ostream *stderr_stream=nullptr);
-  void async_process(const std::string &command, const boost::filesystem::path &path="", std::function<void(int exit_status)> callback=nullptr, bool quiet=false);
-  void kill_last_async_process(bool force=false);
-  void kill_async_processes(bool force=false);
-  
-  size_t print(const std::string &message, bool bold=false);
-  void async_print(const std::string &message, bool bold=false);
-  void async_print(size_t line_nr, const std::string &message);
-  
-  void configure();
-  
-  void clear();
+    static Terminal &get() {
+        static Terminal singleton;
+        return singleton;
+    }
+
+    int process(const std::string &command, const boost::filesystem::path &path = "", bool use_pipes = true);
+
+    int process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command,
+                const boost::filesystem::path &path = "", std::ostream *stderr_stream = nullptr);
+
+    void async_process(const std::string &command, const boost::filesystem::path &path = "",
+                       std::function<void(int exit_status)> callback = nullptr, bool quiet = false);
+
+    void kill_last_async_process(bool force = false);
+
+    void kill_async_processes(bool force = false);
+
+    size_t print(const std::string &message, bool bold = false);
+
+    void async_print(const std::string &message, bool bold = false);
+
+    void async_print(size_t line_nr, const std::string &message);
+
+    void configure();
+
+    void clear();
+
 protected:
-  bool on_motion_notify_event (GdkEventMotion* motion_event) override;
-  bool on_button_press_event(GdkEventButton* button_event) override;
-  bool on_key_press_event(GdkEventKey *event) override;
+    bool on_motion_notify_event(GdkEventMotion *motion_event) override;
+
+    bool on_button_press_event(GdkEventButton *button_event) override;
+
+    bool on_key_press_event(GdkEventKey *event) override;
+
 private:
-  Dispatcher dispatcher;
-  Glib::RefPtr<Gtk::TextTag> bold_tag;
-  Glib::RefPtr<Gtk::TextTag> link_tag;
-  Glib::RefPtr<Gdk::Cursor> link_mouse_cursor;
-  Glib::RefPtr<Gdk::Cursor> default_mouse_cursor;
-  size_t deleted_lines=0;
-  
-  std::tuple<size_t, size_t, std::string, std::string, std::string> find_link(const std::string &line);
-  void apply_link_tags(Gtk::TextIter start_iter, Gtk::TextIter end_iter);
-
-  std::vector<std::shared_ptr<TinyProcessLib::Process>> processes;
-  std::mutex processes_mutex;
-  Glib::ustring stdin_buffer;
+    Dispatcher dispatcher;
+    Glib::RefPtr<Gtk::TextTag> bold_tag;
+    Glib::RefPtr<Gtk::TextTag> link_tag;
+    Glib::RefPtr<Gdk::Cursor> link_mouse_cursor;
+    Glib::RefPtr<Gdk::Cursor> default_mouse_cursor;
+    size_t deleted_lines = 0;
+
+    std::tuple<size_t, size_t, std::string, std::string, std::string> find_link(const std::string &line);
+
+    void apply_link_tags(Gtk::TextIter start_iter, Gtk::TextIter end_iter);
+
+    std::vector<std::shared_ptr<TinyProcessLib::Process>> processes;
+    std::mutex processes_mutex;
+    Glib::ustring stdin_buffer;
 };
diff --git a/src/tooltips.cc b/src/tooltips.cc
index 7e612217..22437cba 100644
--- a/src/tooltips.cc
+++ b/src/tooltips.cc
@@ -1,245 +1,254 @@
 #include "tooltips.h"
 #include "selection_dialog.h"
 
-std::set<Tooltip*> Tooltips::shown_tooltips;
-Gdk::Rectangle Tooltips::drawn_tooltips_rectangle=Gdk::Rectangle();
+std::set<Tooltip *> Tooltips::shown_tooltips;
+Gdk::Rectangle Tooltips::drawn_tooltips_rectangle = Gdk::Rectangle();
 
-Tooltip::Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer, Gtk::TextView *text_view, 
-Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark)
-    : start_mark(start_mark), end_mark(end_mark), create_tooltip_buffer(create_tooltip_buffer), text_view(text_view) {}
+Tooltip::Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer, Gtk::TextView *text_view,
+                 Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark)
+        : start_mark(start_mark), end_mark(end_mark), create_tooltip_buffer(create_tooltip_buffer),
+          text_view(text_view) {}
 
 Tooltip::~Tooltip() {
-  Tooltips::shown_tooltips.erase(this);
-  if(text_view) {
-    text_view->get_buffer()->delete_mark(start_mark);
-    text_view->get_buffer()->delete_mark(end_mark);
-  }
+    Tooltips::shown_tooltips.erase(this);
+    if (text_view) {
+        text_view->get_buffer()->delete_mark(start_mark);
+        text_view->get_buffer()->delete_mark(end_mark);
+    }
 }
 
 void Tooltip::update() {
-  if(text_view) {
-    auto iter=start_mark->get_iter();
-    auto end_iter=end_mark->get_iter();
-    text_view->get_iter_location(iter, activation_rectangle);
-    if(iter.get_offset()<end_iter.get_offset()) {
-      while(iter.forward_char() && iter!=end_iter) {
-        Gdk::Rectangle rectangle;
-        text_view->get_iter_location(iter, rectangle);
-        activation_rectangle.join(rectangle);
-      }
+    if (text_view) {
+        auto iter = start_mark->get_iter();
+        auto end_iter = end_mark->get_iter();
+        text_view->get_iter_location(iter, activation_rectangle);
+        if (iter.get_offset() < end_iter.get_offset()) {
+            while (iter.forward_char() && iter != end_iter) {
+                Gdk::Rectangle rectangle;
+                text_view->get_iter_location(iter, rectangle);
+                activation_rectangle.join(rectangle);
+            }
+        }
+        int location_window_x, location_window_y;
+        text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, activation_rectangle.get_x(),
+                                           activation_rectangle.get_y(), location_window_x, location_window_y);
+        activation_rectangle.set_x(location_window_x);
+        activation_rectangle.set_y(location_window_y);
     }
-    int location_window_x, location_window_y;
-    text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, activation_rectangle.get_x(), activation_rectangle.get_y(), location_window_x, location_window_y);
-    activation_rectangle.set_x(location_window_x);
-    activation_rectangle.set_y(location_window_y);
-  }
 }
 
 void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion) {
-  Tooltips::shown_tooltips.emplace(this);
-  
-  if(!window) {
-    //init window
-    window=std::make_unique<Gtk::Window>(Gtk::WindowType::WINDOW_POPUP);
-    
-    auto g_application=g_application_get_default();
-    auto gio_application=Glib::wrap(g_application, true);
-    auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-    window->set_transient_for(*application->get_active_window());
-    
-    window->set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_TOOLTIP);
-    
-    window->set_events(Gdk::POINTER_MOTION_MASK);
-    window->property_decorated()=false;
-    window->set_accept_focus(false);
-    window->set_skip_taskbar_hint(true);
-    window->set_default_size(0, 0);
-    
-    window->signal_motion_notify_event().connect([on_motion](GdkEventMotion *event) {
-      if(on_motion)
-        on_motion();
-      return false;
-    });
-    
-    window->get_style_context()->add_class("juci_tooltip_window");
-    auto visual = window->get_screen()->get_rgba_visual();
-    if(visual)
-      gtk_widget_set_visual(reinterpret_cast<GtkWidget*>(window->gobj()), visual->gobj());
-
-    auto box=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-    box->get_style_context()->add_class("juci_tooltip_box");
-    window->add(*box);
-
-    text_buffer=create_tooltip_buffer();
-    wrap_lines();
-    
-    auto tooltip_text_view=Gtk::manage(new Gtk::TextView(text_buffer));
-    tooltip_text_view->get_style_context()->add_class("juci_tooltip_text_view");
-    tooltip_text_view->set_editable(false);
-    
+    Tooltips::shown_tooltips.emplace(this);
+
+    if (!window) {
+        //init window
+        window = std::make_unique<Gtk::Window>(Gtk::WindowType::WINDOW_POPUP);
+
+        auto g_application = g_application_get_default();
+        auto gio_application = Glib::wrap(g_application, true);
+        auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+        window->set_transient_for(*application->get_active_window());
+
+        window->set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_TOOLTIP);
+
+        window->set_events(Gdk::POINTER_MOTION_MASK);
+        window->property_decorated() = false;
+        window->set_accept_focus(false);
+        window->set_skip_taskbar_hint(true);
+        window->set_default_size(0, 0);
+
+        window->signal_motion_notify_event().connect([on_motion](GdkEventMotion *event) {
+            if (on_motion)
+                on_motion();
+            return false;
+        });
+
+        window->get_style_context()->add_class("juci_tooltip_window");
+        auto visual = window->get_screen()->get_rgba_visual();
+        if (visual)
+            gtk_widget_set_visual(reinterpret_cast<GtkWidget *>(window->gobj()), visual->gobj());
+
+        auto box = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+        box->get_style_context()->add_class("juci_tooltip_box");
+        window->add(*box);
+
+        text_buffer = create_tooltip_buffer();
+        wrap_lines();
+
+        auto tooltip_text_view = Gtk::manage(new Gtk::TextView(text_buffer));
+        tooltip_text_view->get_style_context()->add_class("juci_tooltip_text_view");
+        tooltip_text_view->set_editable(false);
+
 #if GTK_VERSION_GE(3, 20)
-    box->add(*tooltip_text_view);
+        box->add(*tooltip_text_view);
 #else
-    auto box2=Gtk::manage(new Gtk::Box());
-    box2->pack_start(*tooltip_text_view, true, true, 3);
-    box->pack_start(*box2, true, true, 3);
+        auto box2=Gtk::manage(new Gtk::Box());
+        box2->pack_start(*tooltip_text_view, true, true, 3);
+        box->pack_start(*box2, true, true, 3);
 #endif
 
-    auto layout=Pango::Layout::create(tooltip_text_view->get_pango_context());
-    layout->set_text(text_buffer->get_text());
-    layout->get_pixel_size(size.first, size.second);
-    size.first+=6; // 2xpadding
-    size.second+=8; // 2xpadding + 2
-    
-    window->signal_realize().connect([this] {
-      if(!text_view) {
-        auto &dialog=SelectionDialog::get();
-        if(dialog && dialog->is_visible()) {
-          int root_x, root_y;
-          dialog->get_position(root_x, root_y);
-          root_x-=3; // -1xpadding
-          rectangle.set_x(root_x);
-          rectangle.set_y(root_y-size.second);
-          if(rectangle.get_y()<0)
-            rectangle.set_y(0);
-        }
-      }
-      window->move(rectangle.get_x(), rectangle.get_y());
-    });
-  }
-  
-  int root_x=0, root_y=0;
-  if(text_view) {
-    //Adjust if tooltip is left of text_view
-    Gdk::Rectangle visible_rect;
-    text_view->get_visible_rect(visible_rect);
-    int visible_x, visible_y;
-    text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(), visible_rect.get_y(), visible_x, visible_y);
-    auto activation_rectangle_x=std::max(activation_rectangle.get_x(), visible_x);
-    
-    text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle_x, activation_rectangle.get_y(), root_x, root_y);
-    root_x-=3; // -1xpadding
-    if(root_y<size.second)
-      root_x+=visible_rect.get_width()*0.1;
-  }
-  rectangle.set_x(root_x);
-  rectangle.set_y(std::max(0, root_y-size.second));
-  rectangle.set_width(size.first);
-  rectangle.set_height(size.second);
-  
-  if(!disregard_drawn) {
-    if(Tooltips::drawn_tooltips_rectangle.get_width()!=0) {
-      if(rectangle.intersects(Tooltips::drawn_tooltips_rectangle)) {
-        int new_y=Tooltips::drawn_tooltips_rectangle.get_y()-size.second;
-        if(new_y>=0)
-          rectangle.set_y(new_y);
-        else
-          rectangle.set_x(Tooltips::drawn_tooltips_rectangle.get_x()+Tooltips::drawn_tooltips_rectangle.get_width()+2);
-      }
-      Tooltips::drawn_tooltips_rectangle.join(rectangle);
+        auto layout = Pango::Layout::create(tooltip_text_view->get_pango_context());
+        layout->set_text(text_buffer->get_text());
+        layout->get_pixel_size(size.first, size.second);
+        size.first += 6; // 2xpadding
+        size.second += 8; // 2xpadding + 2
+
+        window->signal_realize().connect([this] {
+            if (!text_view) {
+                auto &dialog = SelectionDialog::get();
+                if (dialog && dialog->is_visible()) {
+                    int root_x, root_y;
+                    dialog->get_position(root_x, root_y);
+                    root_x -= 3; // -1xpadding
+                    rectangle.set_x(root_x);
+                    rectangle.set_y(root_y - size.second);
+                    if (rectangle.get_y() < 0)
+                        rectangle.set_y(0);
+                }
+            }
+            window->move(rectangle.get_x(), rectangle.get_y());
+        });
+    }
+
+    int root_x = 0, root_y = 0;
+    if (text_view) {
+        //Adjust if tooltip is left of text_view
+        Gdk::Rectangle visible_rect;
+        text_view->get_visible_rect(visible_rect);
+        int visible_x, visible_y;
+        text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(),
+                                           visible_rect.get_y(), visible_x, visible_y);
+        auto activation_rectangle_x = std::max(activation_rectangle.get_x(), visible_x);
+
+        text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle_x,
+                                                                                      activation_rectangle.get_y(),
+                                                                                      root_x, root_y);
+        root_x -= 3; // -1xpadding
+        if (root_y < size.second)
+            root_x += visible_rect.get_width() * 0.1;
     }
-    else
-      Tooltips::drawn_tooltips_rectangle=rectangle;
-  }
-  
-  if(window->get_realized())
-    window->move(rectangle.get_x(), rectangle.get_y());
-  window->show_all();
-  shown=true;
+    rectangle.set_x(root_x);
+    rectangle.set_y(std::max(0, root_y - size.second));
+    rectangle.set_width(size.first);
+    rectangle.set_height(size.second);
+
+    if (!disregard_drawn) {
+        if (Tooltips::drawn_tooltips_rectangle.get_width() != 0) {
+            if (rectangle.intersects(Tooltips::drawn_tooltips_rectangle)) {
+                int new_y = Tooltips::drawn_tooltips_rectangle.get_y() - size.second;
+                if (new_y >= 0)
+                    rectangle.set_y(new_y);
+                else
+                    rectangle.set_x(Tooltips::drawn_tooltips_rectangle.get_x() +
+                                    Tooltips::drawn_tooltips_rectangle.get_width() + 2);
+            }
+            Tooltips::drawn_tooltips_rectangle.join(rectangle);
+        } else
+            Tooltips::drawn_tooltips_rectangle = rectangle;
+    }
+
+    if (window->get_realized())
+        window->move(rectangle.get_x(), rectangle.get_y());
+    window->show_all();
+    shown = true;
 }
 
 void Tooltip::hide(const std::pair<int, int> &last_mouse_pos, const std::pair<int, int> &mouse_pos) {
-  // Keep tooltip if mouse is moving towards it
-  // Calculated using dot product between the mouse_pos vector and the corners of the tooltip window
-  if(text_view && window && shown && last_mouse_pos.first!=-1 && last_mouse_pos.second!=-1 && mouse_pos.first!=-1 && mouse_pos.second!=-1) {
-    static int root_x, root_y;
-    text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(last_mouse_pos.first, last_mouse_pos.second, root_x, root_y);
-    int diff_x=mouse_pos.first-last_mouse_pos.first;
-    int diff_y=mouse_pos.second-last_mouse_pos.second;
-    class Corner {
-    public:
-      Corner(int x, int y): x(x-root_x), y(y-root_y) {}
-      int x, y;
-    };
-    std::vector<Corner> corners;
-    corners.emplace_back(rectangle.get_x(), rectangle.get_y());
-    corners.emplace_back(rectangle.get_x()+rectangle.get_width(), rectangle.get_y());
-    corners.emplace_back(rectangle.get_x(), rectangle.get_y()+rectangle.get_height());
-    corners.emplace_back(rectangle.get_x()+rectangle.get_width(), rectangle.get_y()+rectangle.get_height());
-    for(auto &corner: corners) {
-      if(diff_x*corner.x + diff_y*corner.y >= 0)
-        return;
+    // Keep tooltip if mouse is moving towards it
+    // Calculated using dot product between the mouse_pos vector and the corners of the tooltip window
+    if (text_view && window && shown && last_mouse_pos.first != -1 && last_mouse_pos.second != -1 &&
+        mouse_pos.first != -1 && mouse_pos.second != -1) {
+        static int root_x, root_y;
+        text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(last_mouse_pos.first,
+                                                                                      last_mouse_pos.second, root_x,
+                                                                                      root_y);
+        int diff_x = mouse_pos.first - last_mouse_pos.first;
+        int diff_y = mouse_pos.second - last_mouse_pos.second;
+        class Corner {
+        public:
+            Corner(int x, int y) : x(x - root_x), y(y - root_y) {}
+
+            int x, y;
+        };
+        std::vector<Corner> corners;
+        corners.emplace_back(rectangle.get_x(), rectangle.get_y());
+        corners.emplace_back(rectangle.get_x() + rectangle.get_width(), rectangle.get_y());
+        corners.emplace_back(rectangle.get_x(), rectangle.get_y() + rectangle.get_height());
+        corners.emplace_back(rectangle.get_x() + rectangle.get_width(), rectangle.get_y() + rectangle.get_height());
+        for (auto &corner: corners) {
+            if (diff_x * corner.x + diff_y * corner.y >= 0)
+                return;
+        }
     }
-  }
-  Tooltips::shown_tooltips.erase(this);
-  if(window)
-    window->hide();
-  shown=false;
+    Tooltips::shown_tooltips.erase(this);
+    if (window)
+        window->hide();
+    shown = false;
 }
 
 void Tooltip::wrap_lines() {
-  if(!text_buffer)
-    return;
-  
-  auto iter=text_buffer->begin();
-  
-  while(iter) {
-    auto last_space=text_buffer->end();
-    bool end=false;
-    for(unsigned c=0;c<=80;c++) {
-      if(!iter) {
-        end=true;
-        break;
-      }
-      if(*iter==' ')
-        last_space=iter;
-      if(*iter=='\n') {
-        end=true;
-        iter.forward_char();
-        break;
-      }
-      iter.forward_char();
-    }
-    if(!end) {
-      while(!last_space && iter) { //If no space (word longer than 80)
-        iter.forward_char();
-        if(iter && *iter==' ')
-          last_space=iter;
-      }
-      if(iter && last_space) {
-        auto mark=text_buffer->create_mark(last_space);
-        auto last_space_p=last_space;
-        last_space.forward_char();
-        text_buffer->erase(last_space_p, last_space);
-        text_buffer->insert(mark->get_iter(), "\n");
-        
-        iter=mark->get_iter();
-        iter.forward_char();
-
-        text_buffer->delete_mark(mark);
-      }
+    if (!text_buffer)
+        return;
+
+    auto iter = text_buffer->begin();
+
+    while (iter) {
+        auto last_space = text_buffer->end();
+        bool end = false;
+        for (unsigned c = 0; c <= 80; c++) {
+            if (!iter) {
+                end = true;
+                break;
+            }
+            if (*iter == ' ')
+                last_space = iter;
+            if (*iter == '\n') {
+                end = true;
+                iter.forward_char();
+                break;
+            }
+            iter.forward_char();
+        }
+        if (!end) {
+            while (!last_space && iter) { //If no space (word longer than 80)
+                iter.forward_char();
+                if (iter && *iter == ' ')
+                    last_space = iter;
+            }
+            if (iter && last_space) {
+                auto mark = text_buffer->create_mark(last_space);
+                auto last_space_p = last_space;
+                last_space.forward_char();
+                text_buffer->erase(last_space_p, last_space);
+                text_buffer->insert(mark->get_iter(), "\n");
+
+                iter = mark->get_iter();
+                iter.forward_char();
+
+                text_buffer->delete_mark(mark);
+            }
+        }
     }
-  }
 }
 
-void Tooltips::show(const Gdk::Rectangle& rectangle, bool disregard_drawn) {
-  for(auto &tooltip : tooltip_list) {
-    tooltip.update();
-    if(rectangle.intersects(tooltip.activation_rectangle))
-      tooltip.show(disregard_drawn, on_motion);
-    else
-      tooltip.hide();
-  }
+void Tooltips::show(const Gdk::Rectangle &rectangle, bool disregard_drawn) {
+    for (auto &tooltip : tooltip_list) {
+        tooltip.update();
+        if (rectangle.intersects(tooltip.activation_rectangle))
+            tooltip.show(disregard_drawn, on_motion);
+        else
+            tooltip.hide();
+    }
 }
 
 void Tooltips::show(bool disregard_drawn) {
-  for(auto &tooltip : tooltip_list) {
-    tooltip.update();
-    tooltip.show(disregard_drawn, on_motion);
-  }
+    for (auto &tooltip : tooltip_list) {
+        tooltip.update();
+        tooltip.show(disregard_drawn, on_motion);
+    }
 }
 
 void Tooltips::hide(const std::pair<int, int> &last_mouse_pos, const std::pair<int, int> &mouse_pos) {
-  for(auto &tooltip : tooltip_list)
-    tooltip.hide(last_mouse_pos, mouse_pos);
+    for (auto &tooltip : tooltip_list)
+        tooltip.hide(last_mouse_pos, mouse_pos);
 }
diff --git a/src/tooltips.h b/src/tooltips.h
index a032cb27..2cca4554 100644
--- a/src/tooltips.h
+++ b/src/tooltips.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include "gtkmm.h"
 #include <string>
 #include <list>
@@ -7,49 +8,62 @@
 
 class Tooltip {
 public:
-  Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer, Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark);
-  Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer) : Tooltip(create_tooltip_buffer, nullptr, Glib::RefPtr<Gtk::TextBuffer::Mark>(), Glib::RefPtr<Gtk::TextBuffer::Mark>()) {}
-  ~Tooltip();
-  
-  void update();
-  void show(bool disregard_drawn=false, const std::function<void()> &on_motion=nullptr);
-  void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
-  
-  Gdk::Rectangle activation_rectangle;
-  Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
-  Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
-  
-  Glib::RefPtr<Gtk::TextBuffer> text_buffer;
+    Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer, Gtk::TextView *text_view,
+            Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark);
+
+    Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer) : Tooltip(create_tooltip_buffer,
+                                                                                            nullptr,
+                                                                                            Glib::RefPtr<Gtk::TextBuffer::Mark>(),
+                                                                                            Glib::RefPtr<Gtk::TextBuffer::Mark>()) {}
+
+    ~Tooltip();
+
+    void update();
+
+    void show(bool disregard_drawn = false, const std::function<void()> &on_motion = nullptr);
+
+    void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
+
+    Gdk::Rectangle activation_rectangle;
+    Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
+    Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
+
+    Glib::RefPtr<Gtk::TextBuffer> text_buffer;
 private:
-  std::unique_ptr<Gtk::Window> window;
-  void wrap_lines();
-  
-  std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer;
-  Gtk::TextView *text_view;
-  std::pair<int, int> size;
-  Gdk::Rectangle rectangle;
-  
-  bool shown=false;
+    std::unique_ptr<Gtk::Window> window;
+
+    void wrap_lines();
+
+    std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer;
+    Gtk::TextView *text_view;
+    std::pair<int, int> size;
+    Gdk::Rectangle rectangle;
+
+    bool shown = false;
 };
 
 class Tooltips {
 public:
-  static std::set<Tooltip*> shown_tooltips;
-  static Gdk::Rectangle drawn_tooltips_rectangle;
-  static void init() {drawn_tooltips_rectangle=Gdk::Rectangle();}
-  
-  void show(const Gdk::Rectangle& rectangle, bool disregard_drawn=false);
-  void show(bool disregard_drawn=false);
-  void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
-  void clear() {tooltip_list.clear();};
-  
-  template<typename... Ts>
-  void emplace_back(Ts&&... params) {
-    tooltip_list.emplace_back(std::forward<Ts>(params)...);
-  }
-  
-  std::function<void()> on_motion;
-  
+    static std::set<Tooltip *> shown_tooltips;
+    static Gdk::Rectangle drawn_tooltips_rectangle;
+
+    static void init() { drawn_tooltips_rectangle = Gdk::Rectangle(); }
+
+    void show(const Gdk::Rectangle &rectangle, bool disregard_drawn = false);
+
+    void show(bool disregard_drawn = false);
+
+    void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
+
+    void clear() { tooltip_list.clear(); };
+
+    template<typename... Ts>
+    void emplace_back(Ts &&... params) {
+        tooltip_list.emplace_back(std::forward<Ts>(params)...);
+    }
+
+    std::function<void()> on_motion;
+
 private:
-  std::list<Tooltip> tooltip_list;
+    std::list<Tooltip> tooltip_list;
 };
diff --git a/src/usages_clang.cc b/src/usages_clang.cc
index 6b861b14..71719539 100644
--- a/src/usages_clang.cc
+++ b/src/usages_clang.cc
@@ -9,10 +9,13 @@
 #include <thread>
 
 #ifdef _WIN32
+
 #include <windows.h>
+
 DWORD get_current_process_id() {
-  return GetCurrentProcessId();
+    return GetCurrentProcessId();
 }
+
 #else
 #include <unistd.h>
 pid_t get_current_process_id() {
@@ -26,726 +29,753 @@ std::mutex Usages::Clang::caches_mutex;
 std::atomic<size_t> Usages::Clang::cache_in_progress_count(0);
 
 bool Usages::Clang::Cache::Cursor::operator==(const Cursor &o) {
-  for(auto &usr : usrs) {
-    if(clangmm::Cursor::is_similar_kind(o.kind, kind) && o.usrs.count(usr))
-      return true;
-  }
-  return false;
+    for (auto &usr : usrs) {
+        if (clangmm::Cursor::is_similar_kind(o.kind, kind) && o.usrs.count(usr))
+            return true;
+    }
+    return false;
 }
 
-Usages::Clang::Cache::Cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &path,
-                            std::time_t before_parse_time, clangmm::TranslationUnit *translation_unit, clangmm::Tokens *clang_tokens)
-    : project_path(project_path), build_path(build_path) {
-  for(auto &clang_token : *clang_tokens) {
-    tokens.emplace_back(Token{clang_token.get_spelling(), clang_token.get_source_range().get_offsets(), static_cast<size_t>(-1)});
-
-    if(clang_token.is_identifier()) {
-      auto clang_cursor = clang_token.get_cursor().get_referenced();
-      if(clang_cursor) {
-        Cursor cursor{clang_cursor.get_kind(), clang_cursor.get_all_usr_extended()};
-        for(size_t c = 0; c < cursors.size(); ++c) {
-          if(cursor == cursors[c]) {
-            tokens.back().cursor_id = c;
-            break;
-          }
-        }
-        if(tokens.back().cursor_id == static_cast<size_t>(-1)) {
-          cursors.emplace_back(cursor);
-          tokens.back().cursor_id = cursors.size() - 1;
+Usages::Clang::Cache::Cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                            const boost::filesystem::path &path,
+                            std::time_t before_parse_time, clangmm::TranslationUnit *translation_unit,
+                            clangmm::Tokens *clang_tokens)
+        : project_path(project_path), build_path(build_path) {
+    for (auto &clang_token : *clang_tokens) {
+        tokens.emplace_back(Token{clang_token.get_spelling(), clang_token.get_source_range().get_offsets(),
+                                  static_cast<size_t>(-1)});
+
+        if (clang_token.is_identifier()) {
+            auto clang_cursor = clang_token.get_cursor().get_referenced();
+            if (clang_cursor) {
+                Cursor cursor{clang_cursor.get_kind(), clang_cursor.get_all_usr_extended()};
+                for (size_t c = 0; c < cursors.size(); ++c) {
+                    if (cursor == cursors[c]) {
+                        tokens.back().cursor_id = c;
+                        break;
+                    }
+                }
+                if (tokens.back().cursor_id == static_cast<size_t>(-1)) {
+                    cursors.emplace_back(cursor);
+                    tokens.back().cursor_id = cursors.size() - 1;
+                }
+            }
         }
-      }
     }
-  }
-  boost::system::error_code ec;
-  auto last_write_time = boost::filesystem::last_write_time(path, ec);
-  if(ec)
-    last_write_time = 0;
-  if(last_write_time > before_parse_time)
-    last_write_time = 0;
-  paths_and_last_write_times.emplace(path, last_write_time);
-
-  class VisitorData {
-  public:
-    const boost::filesystem::path &project_path;
-    const boost::filesystem::path &path;
-    std::time_t before_parse_time;
-    std::map<boost::filesystem::path, std::time_t> &paths_and_last_write_times;
-  };
-  VisitorData visitor_data{project_path, path, before_parse_time, paths_and_last_write_times};
-
-  clang_getInclusions(translation_unit->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData data) {
-    auto visitor_data = static_cast<VisitorData *>(data);
-    auto path = filesystem::get_normal_path(clangmm::to_string(clang_getFileName(included_file)));
-    if(filesystem::file_in_path(path, visitor_data->project_path)) {
-      for(unsigned c = 0; c < include_len; ++c) {
-        auto from_path = filesystem::get_normal_path(clangmm::SourceLocation(inclusion_stack[c]).get_path());
-        if(from_path == visitor_data->path) {
-          boost::system::error_code ec;
-          auto last_write_time = boost::filesystem::last_write_time(path, ec);
-          if(ec)
-            last_write_time = 0;
-          if(last_write_time > visitor_data->before_parse_time)
-            last_write_time = 0;
-          visitor_data->paths_and_last_write_times.emplace(path, last_write_time);
-          break;
-        }
-      }
-    }
-  },
-                      &visitor_data);
+    boost::system::error_code ec;
+    auto last_write_time = boost::filesystem::last_write_time(path, ec);
+    if (ec)
+        last_write_time = 0;
+    if (last_write_time > before_parse_time)
+        last_write_time = 0;
+    paths_and_last_write_times.emplace(path, last_write_time);
+
+    class VisitorData {
+    public:
+        const boost::filesystem::path &project_path;
+        const boost::filesystem::path &path;
+        std::time_t before_parse_time;
+        std::map<boost::filesystem::path, std::time_t> &paths_and_last_write_times;
+    };
+    VisitorData visitor_data{project_path, path, before_parse_time, paths_and_last_write_times};
+
+    clang_getInclusions(translation_unit->cx_tu,
+                        [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len,
+                           CXClientData data) {
+                            auto visitor_data = static_cast<VisitorData *>(data);
+                            auto path = filesystem::get_normal_path(
+                                    clangmm::to_string(clang_getFileName(included_file)));
+                            if (filesystem::file_in_path(path, visitor_data->project_path)) {
+                                for (unsigned c = 0; c < include_len; ++c) {
+                                    auto from_path = filesystem::get_normal_path(
+                                            clangmm::SourceLocation(inclusion_stack[c]).get_path());
+                                    if (from_path == visitor_data->path) {
+                                        boost::system::error_code ec;
+                                        auto last_write_time = boost::filesystem::last_write_time(path, ec);
+                                        if (ec)
+                                            last_write_time = 0;
+                                        if (last_write_time > visitor_data->before_parse_time)
+                                            last_write_time = 0;
+                                        visitor_data->paths_and_last_write_times.emplace(path, last_write_time);
+                                        break;
+                                    }
+                                }
+                            }
+                        },
+                        &visitor_data);
 }
 
-std::vector<std::pair<clangmm::Offset, clangmm::Offset>> Usages::Clang::Cache::get_similar_token_offsets(clangmm::Cursor::Kind kind, const std::string &spelling,
-                                                                                                         const std::unordered_set<std::string> &usrs) const {
-  std::vector<std::pair<clangmm::Offset, clangmm::Offset>> offsets;
-  for(auto &token : tokens) {
-    if(token.cursor_id != static_cast<size_t>(-1)) {
-      auto &cursor = cursors[token.cursor_id];
-      if(clangmm::Cursor::is_similar_kind(cursor.kind, kind) && token.spelling == spelling) {
-        for(auto &usr : cursor.usrs) {
-          if(usrs.count(usr)) {
-            offsets.emplace_back(token.offsets);
-            break;
-          }
+std::vector<std::pair<clangmm::Offset, clangmm::Offset>>
+Usages::Clang::Cache::get_similar_token_offsets(clangmm::Cursor::Kind kind, const std::string &spelling,
+                                                const std::unordered_set<std::string> &usrs) const {
+    std::vector<std::pair<clangmm::Offset, clangmm::Offset>> offsets;
+    for (auto &token : tokens) {
+        if (token.cursor_id != static_cast<size_t>(-1)) {
+            auto &cursor = cursors[token.cursor_id];
+            if (clangmm::Cursor::is_similar_kind(cursor.kind, kind) && token.spelling == spelling) {
+                for (auto &usr : cursor.usrs) {
+                    if (usrs.count(usr)) {
+                        offsets.emplace_back(token.offsets);
+                        break;
+                    }
+                }
+            }
         }
-      }
     }
-  }
-  return offsets;
+    return offsets;
 }
 
-std::vector<Usages::Clang::Usages> Usages::Clang::get_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &debug_path,
-                                                             const std::string &spelling, const clangmm::Cursor &cursor, const std::vector<clangmm::TranslationUnit *> &translation_units) {
-  std::vector<Usages> usages;
-
-  if(spelling.empty())
-    return usages;
-
-  PathSet visited;
-
-  auto usr_extended = cursor.get_usr_extended();
-  if(!usr_extended.empty() && usr_extended[0] >= '0' && usr_extended[0] <= '9') { //if declared within a function, return
-    if(!translation_units.empty())
-      add_usages(project_path, build_path, boost::filesystem::path(), usages, visited, spelling, cursor, translation_units.front(), false);
-    return usages;
-  }
-
-  for(auto &translation_unit : translation_units)
-    add_usages(project_path, build_path, boost::filesystem::path(), usages, visited, spelling, cursor, translation_unit, false);
-
-  for(auto &translation_unit : translation_units)
-    add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor, translation_unit, false);
-
-  if(project_path.empty())
-    return usages;
-
-  auto paths = find_paths(project_path, build_path, debug_path);
-  auto pair = parse_paths(spelling, paths);
-  PathSet all_cursors_paths;
-  auto canonical=cursor.get_canonical();
-  all_cursors_paths.emplace(canonical.get_source_location().get_path());
-  for(auto &cursor: canonical.get_all_overridden_cursors())
-    all_cursors_paths.emplace(cursor.get_source_location().get_path());
-  auto pair2 = find_potential_paths(all_cursors_paths, project_path, pair.first, pair.second);
-  auto &potential_paths = pair2.first;
-  auto &all_includes = pair2.second;
-
-  // Remove visited paths
-  for(auto it = potential_paths.begin(); it != potential_paths.end();) {
-    if(visited.find(*it) != visited.end())
-      it = potential_paths.erase(it);
-    else
-      ++it;
-  }
-
-  // Wait for current caching to finish
-  std::unique_ptr<Dialog::Message> message;
-  const std::string message_string = "Please wait while finding usages";
-  if(cache_in_progress_count != 0) {
-    message = std::make_unique<Dialog::Message>(message_string);
-    while(cache_in_progress_count != 0) {
-      while(Gtk::Main::events_pending())
-        Gtk::Main::iteration(false);
+std::vector<Usages::Clang::Usages>
+Usages::Clang::get_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                          const boost::filesystem::path &debug_path,
+                          const std::string &spelling, const clangmm::Cursor &cursor,
+                          const std::vector<clangmm::TranslationUnit *> &translation_units) {
+    std::vector<Usages> usages;
+
+    if (spelling.empty())
+        return usages;
+
+    PathSet visited;
+
+    auto usr_extended = cursor.get_usr_extended();
+    if (!usr_extended.empty() && usr_extended[0] >= '0' &&
+        usr_extended[0] <= '9') { //if declared within a function, return
+        if (!translation_units.empty())
+            add_usages(project_path, build_path, boost::filesystem::path(), usages, visited, spelling, cursor,
+                       translation_units.front(), false);
+        return usages;
     }
-  }
 
-  // Use cache
-  for(auto it = potential_paths.begin(); it != potential_paths.end();) {
-    std::unique_lock<std::mutex> lock(caches_mutex);
-    auto caches_it = caches.find(*it);
-
-    // Load cache from file if not found in memory and if cache file exists
-    if(caches_it == caches.end()) {
-      auto cache = read_cache(project_path, build_path, *it);
-      if(cache) {
-        auto pair = caches.emplace(*it, std::move(cache));
-        caches_it = pair.first;
-      }
+    for (auto &translation_unit : translation_units)
+        add_usages(project_path, build_path, boost::filesystem::path(), usages, visited, spelling, cursor,
+                   translation_unit, false);
+
+    for (auto &translation_unit : translation_units)
+        add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor, translation_unit, false);
+
+    if (project_path.empty())
+        return usages;
+
+    auto paths = find_paths(project_path, build_path, debug_path);
+    auto pair = parse_paths(spelling, paths);
+    PathSet all_cursors_paths;
+    auto canonical = cursor.get_canonical();
+    all_cursors_paths.emplace(canonical.get_source_location().get_path());
+    for (auto &cursor: canonical.get_all_overridden_cursors())
+        all_cursors_paths.emplace(cursor.get_source_location().get_path());
+    auto pair2 = find_potential_paths(all_cursors_paths, project_path, pair.first, pair.second);
+    auto &potential_paths = pair2.first;
+    auto &all_includes = pair2.second;
+
+    // Remove visited paths
+    for (auto it = potential_paths.begin(); it != potential_paths.end();) {
+        if (visited.find(*it) != visited.end())
+            it = potential_paths.erase(it);
+        else
+            ++it;
     }
 
-    if(caches_it != caches.end()) {
-      if(add_usages_from_cache(caches_it->first, usages, visited, spelling, cursor, caches_it->second))
-        it = potential_paths.erase(it);
-      else {
-        caches.erase(caches_it);
-        ++it;
-      }
+    // Wait for current caching to finish
+    std::unique_ptr<Dialog::Message> message;
+    const std::string message_string = "Please wait while finding usages";
+    if (cache_in_progress_count != 0) {
+        message = std::make_unique<Dialog::Message>(message_string);
+        while (cache_in_progress_count != 0) {
+            while (Gtk::Main::events_pending())
+                Gtk::Main::iteration(false);
+        }
     }
-    else
-      ++it;
-  }
 
-  // Remove paths that has been included
-  for(auto it = potential_paths.begin(); it != potential_paths.end();) {
-    if(all_includes.find(*it) != all_includes.end())
-      it = potential_paths.erase(it);
-    else
-      ++it;
-  }
-
-  // Parse potential paths
-  if(!potential_paths.empty()) {
-    if(!message)
-      message = std::make_unique<Dialog::Message>(message_string);
-
-    std::vector<std::thread> threads;
-    auto it = potential_paths.begin();
-    auto number_of_threads = Config::get().source.clang_usages_threads;
-    if(number_of_threads == static_cast<unsigned>(-1)) {
-      number_of_threads = std::thread::hardware_concurrency();
-      if(number_of_threads == 0)
-        number_of_threads = 1;
+    // Use cache
+    for (auto it = potential_paths.begin(); it != potential_paths.end();) {
+        std::unique_lock<std::mutex> lock(caches_mutex);
+        auto caches_it = caches.find(*it);
+
+        // Load cache from file if not found in memory and if cache file exists
+        if (caches_it == caches.end()) {
+            auto cache = read_cache(project_path, build_path, *it);
+            if (cache) {
+                auto pair = caches.emplace(*it, std::move(cache));
+                caches_it = pair.first;
+            }
+        }
+
+        if (caches_it != caches.end()) {
+            if (add_usages_from_cache(caches_it->first, usages, visited, spelling, cursor, caches_it->second))
+                it = potential_paths.erase(it);
+            else {
+                caches.erase(caches_it);
+                ++it;
+            }
+        } else
+            ++it;
     }
-    for(unsigned thread_id = 0; thread_id < number_of_threads; ++thread_id) {
-      threads.emplace_back([&potential_paths, &it, &build_path,
-                            &project_path, &usages, &visited, &spelling, &cursor] {
-        while(true) {
-          boost::filesystem::path path;
-          {
-            static std::mutex mutex;
-            std::unique_lock<std::mutex> lock(mutex);
-            if(it == potential_paths.end())
-              return;
-            path = *it;
+
+    // Remove paths that has been included
+    for (auto it = potential_paths.begin(); it != potential_paths.end();) {
+        if (all_includes.find(*it) != all_includes.end())
+            it = potential_paths.erase(it);
+        else
             ++it;
-          }
-          clangmm::Index index(0, 0);
-
-          {
-            static std::mutex mutex;
-            std::unique_lock<std::mutex> lock(mutex);
-            // std::cout << "parsing: " << path << std::endl;
-          }
-          // auto before_time = std::chrono::system_clock::now();
-
-          std::ifstream stream(path.string(), std::ifstream::binary);
-          std::string buffer;
-          buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
-
-          auto arguments = CompileCommands::get_arguments(build_path, path);
-          arguments.emplace_back("-w"); // Disable all warnings
-          for(auto it = arguments.begin(); it != arguments.end();) { // remove comments from system headers
-            if(*it == "-fretain-comments-from-system-headers")
-              it = arguments.erase(it);
-            else
-              ++it;
-          }
-          int flags = CXTranslationUnit_Incomplete;
+    }
+
+    // Parse potential paths
+    if (!potential_paths.empty()) {
+        if (!message)
+            message = std::make_unique<Dialog::Message>(message_string);
+
+        std::vector<std::thread> threads;
+        auto it = potential_paths.begin();
+        auto number_of_threads = Config::get().source.clang_usages_threads;
+        if (number_of_threads == static_cast<unsigned>(-1)) {
+            number_of_threads = std::thread::hardware_concurrency();
+            if (number_of_threads == 0)
+                number_of_threads = 1;
+        }
+        for (unsigned thread_id = 0; thread_id < number_of_threads; ++thread_id) {
+            threads.emplace_back([&potential_paths, &it, &build_path,
+                                         &project_path, &usages, &visited, &spelling, &cursor] {
+                while (true) {
+                    boost::filesystem::path path;
+                    {
+                        static std::mutex mutex;
+                        std::unique_lock<std::mutex> lock(mutex);
+                        if (it == potential_paths.end())
+                            return;
+                        path = *it;
+                        ++it;
+                    }
+                    clangmm::Index index(0, 0);
+
+                    {
+                        static std::mutex mutex;
+                        std::unique_lock<std::mutex> lock(mutex);
+                        // std::cout << "parsing: " << path << std::endl;
+                    }
+                    // auto before_time = std::chrono::system_clock::now();
+
+                    std::ifstream stream(path.string(), std::ifstream::binary);
+                    std::string buffer;
+                    buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
+
+                    auto arguments = CompileCommands::get_arguments(build_path, path);
+                    arguments.emplace_back("-w"); // Disable all warnings
+                    for (auto it = arguments.begin(); it != arguments.end();) { // remove comments from system headers
+                        if (*it == "-fretain-comments-from-system-headers")
+                            it = arguments.erase(it);
+                        else
+                            ++it;
+                    }
+                    int flags = CXTranslationUnit_Incomplete;
 #if CINDEX_VERSION_MAJOR > 0 || (CINDEX_VERSION_MAJOR == 0 && CINDEX_VERSION_MINOR >= 35)
-          flags |= CXTranslationUnit_KeepGoing;
+                    flags |= CXTranslationUnit_KeepGoing;
 #endif
 
-          clangmm::TranslationUnit translation_unit(index, path.string(), arguments, buffer, flags);
-
-          {
-            static std::mutex mutex;
-            std::unique_lock<std::mutex> lock(mutex);
-            add_usages(project_path, build_path, path, usages, visited, spelling, cursor, &translation_unit, true);
-            add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor, &translation_unit, true);
-          }
-
-          // auto time = std::chrono::system_clock::now();
-          // std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(time - before_time).count() << std::endl;
+                    clangmm::TranslationUnit translation_unit(index, path.string(), arguments, buffer, flags);
+
+                    {
+                        static std::mutex mutex;
+                        std::unique_lock<std::mutex> lock(mutex);
+                        add_usages(project_path, build_path, path, usages, visited, spelling, cursor, &translation_unit,
+                                   true);
+                        add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor,
+                                                 &translation_unit, true);
+                    }
+
+                    // auto time = std::chrono::system_clock::now();
+                    // std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(time - before_time).count() << std::endl;
+                }
+            });
         }
-      });
+        for (auto &thread : threads)
+            thread.join();
     }
-    for(auto &thread : threads)
-      thread.join();
-  }
 
-  if(message)
-    message->hide();
+    if (message)
+        message->hide();
 
-  return usages;
+    return usages;
 }
 
-void Usages::Clang::cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &path,
-                          std::time_t before_parse_time, const PathSet &project_paths_in_use, clangmm::TranslationUnit *translation_unit, clangmm::Tokens *tokens) {
-  class ScopeExit {
-  public:
-    std::function<void()> f;
-    ~ScopeExit() {
-      f();
-    }
-  };
-  ScopeExit scope_exit{[] {
-    --cache_in_progress_count;
-  }};
-
-  if(project_path.empty())
-    return;
+void Usages::Clang::cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                          const boost::filesystem::path &path,
+                          std::time_t before_parse_time, const PathSet &project_paths_in_use,
+                          clangmm::TranslationUnit *translation_unit, clangmm::Tokens *tokens) {
+    class ScopeExit {
+    public:
+        std::function<void()> f;
 
-  {
-    std::unique_lock<std::mutex> lock(caches_mutex);
-    if(project_paths_in_use.count(project_path)) {
-      caches.erase(path);
-      caches.emplace(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens));
+        ~ScopeExit() {
+            f();
+        }
+    };
+    ScopeExit scope_exit{[] {
+        --cache_in_progress_count;
+    }};
+
+    if (project_path.empty())
+        return;
+
+    {
+        std::unique_lock<std::mutex> lock(caches_mutex);
+        if (project_paths_in_use.count(project_path)) {
+            caches.erase(path);
+            caches.emplace(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens));
+        } else
+            write_cache(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens));
     }
-    else
-      write_cache(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens));
-  }
 
-  class VisitorData {
-  public:
-    const boost::filesystem::path &project_path;
-    PathSet paths;
-  };
-  VisitorData visitor_data{project_path, {}};
+    class VisitorData {
+    public:
+        const boost::filesystem::path &project_path;
+        PathSet paths;
+    };
+    VisitorData visitor_data{project_path, {}};
 
-  auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
-  clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
-    auto visitor_data = static_cast<VisitorData *>(data);
+    auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
+    clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
+                            auto visitor_data = static_cast<VisitorData *>(data);
 
-    auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
-    if(filesystem::file_in_path(path, visitor_data->project_path))
-      visitor_data->paths.emplace(path);
+                            auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
+                            if (filesystem::file_in_path(path, visitor_data->project_path))
+                                visitor_data->paths.emplace(path);
 
-    return CXChildVisit_Continue;
-  },
-                      &visitor_data);
+                            return CXChildVisit_Continue;
+                        },
+                        &visitor_data);
 
-  visitor_data.paths.erase(path);
+    visitor_data.paths.erase(path);
 
-  for(auto &path : visitor_data.paths) {
-    boost::system::error_code ec;
-    auto file_size = boost::filesystem::file_size(path, ec);
-    if(file_size == static_cast<boost::uintmax_t>(-1) || ec)
-      continue;
-    auto tokens = translation_unit->get_tokens(path.string(), 0, file_size - 1);
-    std::unique_lock<std::mutex> lock(caches_mutex);
-    if(project_paths_in_use.count(project_path)) {
-      caches.erase(path);
-      caches.emplace(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
+    for (auto &path : visitor_data.paths) {
+        boost::system::error_code ec;
+        auto file_size = boost::filesystem::file_size(path, ec);
+        if (file_size == static_cast<boost::uintmax_t>(-1) || ec)
+            continue;
+        auto tokens = translation_unit->get_tokens(path.string(), 0, file_size - 1);
+        std::unique_lock<std::mutex> lock(caches_mutex);
+        if (project_paths_in_use.count(project_path)) {
+            caches.erase(path);
+            caches.emplace(path,
+                           Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
+        } else
+            write_cache(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
     }
-    else
-      write_cache(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
-  }
 }
 
 void Usages::Clang::erase_unused_caches(const PathSet &project_paths_in_use) {
-  std::unique_lock<std::mutex> lock(caches_mutex);
-  for(auto it = caches.begin(); it != caches.end();) {
-    bool found = false;
-    for(auto &project_path : project_paths_in_use) {
-      if(filesystem::file_in_path(it->first, project_path)) {
-        found = true;
-        break;
-      }
-    }
-    if(!found) {
-      write_cache(it->first, it->second);
-      it = caches.erase(it);
+    std::unique_lock<std::mutex> lock(caches_mutex);
+    for (auto it = caches.begin(); it != caches.end();) {
+        bool found = false;
+        for (auto &project_path : project_paths_in_use) {
+            if (filesystem::file_in_path(it->first, project_path)) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            write_cache(it->first, it->second);
+            it = caches.erase(it);
+        } else
+            ++it;
     }
-    else
-      ++it;
-  }
 }
 
 void Usages::Clang::erase_cache(const boost::filesystem::path &path) {
-  std::unique_lock<std::mutex> lock(caches_mutex);
+    std::unique_lock<std::mutex> lock(caches_mutex);
 
-  auto it = caches.find(path);
-  if(it == caches.end())
-    return;
+    auto it = caches.find(path);
+    if (it == caches.end())
+        return;
 
-  auto paths_and_last_write_times = std::move(it->second.paths_and_last_write_times);
-  for(auto &path_and_last_write_time : paths_and_last_write_times)
-    caches.erase(path_and_last_write_time.first);
+    auto paths_and_last_write_times = std::move(it->second.paths_and_last_write_times);
+    for (auto &path_and_last_write_time : paths_and_last_write_times)
+        caches.erase(path_and_last_write_time.first);
 }
 
-void Usages::Clang::erase_all_caches_for_project(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path) {
-  if(project_path.empty())
-    return;
+void Usages::Clang::erase_all_caches_for_project(const boost::filesystem::path &project_path,
+                                                 const boost::filesystem::path &build_path) {
+    if (project_path.empty())
+        return;
 
-  if(cache_in_progress_count != 0)
-    std::this_thread::sleep_for(std::chrono::milliseconds(10));
+    if (cache_in_progress_count != 0)
+        std::this_thread::sleep_for(std::chrono::milliseconds(10));
 
-  std::unique_lock<std::mutex> lock(caches_mutex);
-  boost::system::error_code ec;
-  auto usages_clang_path = build_path / cache_folder;
-  if(boost::filesystem::exists(usages_clang_path, ec) && boost::filesystem::is_directory(usages_clang_path, ec)) {
-    for(boost::filesystem::directory_iterator it(usages_clang_path), end; it != end; ++it) {
-      if(it->path().extension() == ".usages")
-        boost::filesystem::remove(it->path(), ec);
+    std::unique_lock<std::mutex> lock(caches_mutex);
+    boost::system::error_code ec;
+    auto usages_clang_path = build_path / cache_folder;
+    if (boost::filesystem::exists(usages_clang_path, ec) && boost::filesystem::is_directory(usages_clang_path, ec)) {
+        for (boost::filesystem::directory_iterator it(usages_clang_path), end; it != end; ++it) {
+            if (it->path().extension() == ".usages")
+                boost::filesystem::remove(it->path(), ec);
+        }
     }
-  }
 
-  for(auto it = caches.begin(); it != caches.end();) {
-    if(filesystem::file_in_path(it->first, project_path))
-      it = caches.erase(it);
-    else
-      ++it;
-  }
+    for (auto it = caches.begin(); it != caches.end();) {
+        if (filesystem::file_in_path(it->first, project_path))
+            it = caches.erase(it);
+        else
+            ++it;
+    }
 }
 
 void Usages::Clang::cache_in_progress() {
-  ++cache_in_progress_count;
+    ++cache_in_progress_count;
 }
 
-void Usages::Clang::add_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &path_,
-                               std::vector<Usages> &usages, PathSet &visited, const std::string &spelling, clangmm::Cursor cursor,
+void Usages::Clang::add_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                               const boost::filesystem::path &path_,
+                               std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
+                               clangmm::Cursor cursor,
                                clangmm::TranslationUnit *translation_unit, bool store_in_cache) {
-  std::unique_ptr<clangmm::Tokens> tokens;
-  boost::filesystem::path path;
-  auto before_parse_time = std::time(nullptr);
-  auto all_usr_extended = cursor.get_all_usr_extended();
-  if(path_.empty()) {
-    path = clangmm::to_string(clang_getTranslationUnitSpelling(translation_unit->cx_tu));
-    if(visited.find(path) != visited.end() || !filesystem::file_in_path(path, project_path))
-      return;
-    tokens = translation_unit->get_tokens();
-  }
-  else {
-    path = path_;
-    if(visited.find(path) != visited.end() || !filesystem::file_in_path(path, project_path))
-      return;
-    boost::system::error_code ec;
-    auto file_size = boost::filesystem::file_size(path, ec);
-    if(file_size == static_cast<boost::uintmax_t>(-1) || ec)
-      return;
-    tokens = translation_unit->get_tokens(path.string(), 0, file_size - 1);
-  }
-
-  auto offsets = tokens->get_similar_token_offsets(cursor.get_kind(), spelling, all_usr_extended);
-  std::vector<std::string> lines;
-  for(auto &offset : offsets) {
-    std::string line;
-    auto line_nr = offset.second.line;
-    for(auto &token : *tokens) {
-      auto offset = token.get_source_location().get_offset();
-      if(offset.line == line_nr) {
-        while(line.size() < offset.index - 1)
-          line += ' ';
-        line += token.get_spelling();
-      }
+    std::unique_ptr<clangmm::Tokens> tokens;
+    boost::filesystem::path path;
+    auto before_parse_time = std::time(nullptr);
+    auto all_usr_extended = cursor.get_all_usr_extended();
+    if (path_.empty()) {
+        path = clangmm::to_string(clang_getTranslationUnitSpelling(translation_unit->cx_tu));
+        if (visited.find(path) != visited.end() || !filesystem::file_in_path(path, project_path))
+            return;
+        tokens = translation_unit->get_tokens();
+    } else {
+        path = path_;
+        if (visited.find(path) != visited.end() || !filesystem::file_in_path(path, project_path))
+            return;
+        boost::system::error_code ec;
+        auto file_size = boost::filesystem::file_size(path, ec);
+        if (file_size == static_cast<boost::uintmax_t>(-1) || ec)
+            return;
+        tokens = translation_unit->get_tokens(path.string(), 0, file_size - 1);
     }
-    lines.emplace_back(std::move(line));
-  }
 
-  if(store_in_cache && filesystem::file_in_path(path, project_path)) {
-    std::unique_lock<std::mutex> lock(caches_mutex);
-    caches.erase(path);
-    caches.emplace(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
-  }
+    auto offsets = tokens->get_similar_token_offsets(cursor.get_kind(), spelling, all_usr_extended);
+    std::vector<std::string> lines;
+    for (auto &offset : offsets) {
+        std::string line;
+        auto line_nr = offset.second.line;
+        for (auto &token : *tokens) {
+            auto offset = token.get_source_location().get_offset();
+            if (offset.line == line_nr) {
+                while (line.size() < offset.index - 1)
+                    line += ' ';
+                line += token.get_spelling();
+            }
+        }
+        lines.emplace_back(std::move(line));
+    }
+
+    if (store_in_cache && filesystem::file_in_path(path, project_path)) {
+        std::unique_lock<std::mutex> lock(caches_mutex);
+        caches.erase(path);
+        caches.emplace(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
+    }
 
-  visited.emplace(path);
-  if(!offsets.empty())
-    usages.emplace_back(Usages{std::move(path), std::move(offsets), lines});
+    visited.emplace(path);
+    if (!offsets.empty())
+        usages.emplace_back(Usages{std::move(path), std::move(offsets), lines});
 }
 
-bool Usages::Clang::add_usages_from_cache(const boost::filesystem::path &path, std::vector<Usages> &usages, PathSet &visited,
-                                          const std::string &spelling, const clangmm::Cursor &cursor, const Cache &cache) {
-  for(auto &path_and_last_write_time : cache.paths_and_last_write_times) {
-    boost::system::error_code ec;
-    auto last_write_time = boost::filesystem::last_write_time(path_and_last_write_time.first, ec);
-    if(ec || last_write_time != path_and_last_write_time.second) {
-      // std::cout << "updated file: " << path_and_last_write_time.first << ", included from " << path << std::endl;
-      return false;
+bool
+Usages::Clang::add_usages_from_cache(const boost::filesystem::path &path, std::vector<Usages> &usages, PathSet &visited,
+                                     const std::string &spelling, const clangmm::Cursor &cursor, const Cache &cache) {
+    for (auto &path_and_last_write_time : cache.paths_and_last_write_times) {
+        boost::system::error_code ec;
+        auto last_write_time = boost::filesystem::last_write_time(path_and_last_write_time.first, ec);
+        if (ec || last_write_time != path_and_last_write_time.second) {
+            // std::cout << "updated file: " << path_and_last_write_time.first << ", included from " << path << std::endl;
+            return false;
+        }
     }
-  }
-
-  auto offsets = cache.get_similar_token_offsets(cursor.get_kind(), spelling, cursor.get_all_usr_extended());
-
-  std::vector<std::string> lines;
-  for(auto &offset : offsets) {
-    std::string line;
-    auto line_nr = offset.second.line;
-    for(auto &token : cache.tokens) {
-      auto &offset = token.offsets.first;
-      if(offset.line == line_nr) {
-        while(line.size() < offset.index - 1)
-          line += ' ';
-        line += token.spelling;
-      }
+
+    auto offsets = cache.get_similar_token_offsets(cursor.get_kind(), spelling, cursor.get_all_usr_extended());
+
+    std::vector<std::string> lines;
+    for (auto &offset : offsets) {
+        std::string line;
+        auto line_nr = offset.second.line;
+        for (auto &token : cache.tokens) {
+            auto &offset = token.offsets.first;
+            if (offset.line == line_nr) {
+                while (line.size() < offset.index - 1)
+                    line += ' ';
+                line += token.spelling;
+            }
+        }
+        lines.emplace_back(std::move(line));
     }
-    lines.emplace_back(std::move(line));
-  }
 
-  visited.emplace(path);
-  if(!offsets.empty())
-    usages.emplace_back(Usages{path, std::move(offsets), lines});
-  return true;
+    visited.emplace(path);
+    if (!offsets.empty())
+        usages.emplace_back(Usages{path, std::move(offsets), lines});
+    return true;
 }
 
-void Usages::Clang::add_usages_from_includes(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
-                                             std::vector<Usages> &usages, PathSet &visited, const std::string &spelling, const clangmm::Cursor &cursor,
+void Usages::Clang::add_usages_from_includes(const boost::filesystem::path &project_path,
+                                             const boost::filesystem::path &build_path,
+                                             std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
+                                             const clangmm::Cursor &cursor,
                                              clangmm::TranslationUnit *translation_unit, bool store_in_cache) {
-  if(project_path.empty())
-    return;
-
-  class VisitorData {
-  public:
-    const boost::filesystem::path &project_path;
-    const std::string &spelling;
-    PathSet &visited;
-    PathSet paths;
-  };
-  VisitorData visitor_data{project_path, spelling, visited, {}};
-
-  auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
-  clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
-    auto visitor_data = static_cast<VisitorData *>(data);
-
-    auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
-    if(visitor_data->visited.find(path) == visitor_data->visited.end() && filesystem::file_in_path(path, visitor_data->project_path))
-      visitor_data->paths.emplace(path);
-
-    return CXChildVisit_Continue;
-  },
-                      &visitor_data);
-
-  for(auto &path : visitor_data.paths)
-    add_usages(project_path, build_path, path, usages, visited, spelling, cursor, translation_unit, store_in_cache);
+    if (project_path.empty())
+        return;
+
+    class VisitorData {
+    public:
+        const boost::filesystem::path &project_path;
+        const std::string &spelling;
+        PathSet &visited;
+        PathSet paths;
+    };
+    VisitorData visitor_data{project_path, spelling, visited, {}};
+
+    auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
+    clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
+                            auto visitor_data = static_cast<VisitorData *>(data);
+
+                            auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
+                            if (visitor_data->visited.find(path) == visitor_data->visited.end() &&
+                                filesystem::file_in_path(path, visitor_data->project_path))
+                                visitor_data->paths.emplace(path);
+
+                            return CXChildVisit_Continue;
+                        },
+                        &visitor_data);
+
+    for (auto &path : visitor_data.paths)
+        add_usages(project_path, build_path, path, usages, visited, spelling, cursor, translation_unit, store_in_cache);
 }
 
 Usages::Clang::PathSet Usages::Clang::find_paths(const boost::filesystem::path &project_path,
-                                                 const boost::filesystem::path &build_path, const boost::filesystem::path &debug_path) {
-  PathSet paths;
+                                                 const boost::filesystem::path &build_path,
+                                                 const boost::filesystem::path &debug_path) {
+    PathSet paths;
 
-  CompileCommands compile_commands(build_path);
+    CompileCommands compile_commands(build_path);
 
-  for(boost::filesystem::recursive_directory_iterator it(project_path), end; it != end; ++it) {
-    auto &path = it->path();
-    if(!boost::filesystem::is_regular_file(path)) {
-      if(path == build_path || path == debug_path || path.filename() == ".git")
-        it.no_push();
-      continue;
-    }
+    for (boost::filesystem::recursive_directory_iterator it(project_path), end; it != end; ++it) {
+        auto &path = it->path();
+        if (!boost::filesystem::is_regular_file(path)) {
+            if (path == build_path || path == debug_path || path.filename() == ".git")
+                it.no_push();
+            continue;
+        }
 
-    if(is_header(path))
-      paths.emplace(path);
-    else if(is_source(path)) {
-      for(auto &command : compile_commands.commands) {
-        if(filesystem::get_normal_path(command.file) == path) {
-          paths.emplace(path);
-          break;
+        if (is_header(path))
+            paths.emplace(path);
+        else if (is_source(path)) {
+            for (auto &command : compile_commands.commands) {
+                if (filesystem::get_normal_path(command.file) == path) {
+                    paths.emplace(path);
+                    break;
+                }
+            }
         }
-      }
     }
-  }
 
-  return paths;
+    return paths;
 }
 
 bool Usages::Clang::is_header(const boost::filesystem::path &path) {
-  auto ext = path.extension();
-  if(ext == ".h" || // c headers
-     ext == ".hh" || ext == ".hp" || ext == ".hpp" || ext == ".h++" || ext == ".tcc" || // c++ headers
-     ext == ".cuh") // CUDA headers
-    return true;
-  else
-    return false;
+    auto ext = path.extension();
+    if (ext == ".h" || // c headers
+        ext == ".hh" || ext == ".hp" || ext == ".hpp" || ext == ".h++" || ext == ".tcc" || // c++ headers
+        ext == ".cuh") // CUDA headers
+        return true;
+    else
+        return false;
 }
 
 bool Usages::Clang::is_source(const boost::filesystem::path &path) {
-  auto ext = path.extension();
-  if(ext == ".c" || // c sources
-     ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".C" || ext == ".c++" || // c++ sources
-     ext == ".cu" || // CUDA sources
-     ext == ".cl") // OpenCL sources
-    return true;
-  else
-    return false;
+    auto ext = path.extension();
+    if (ext == ".c" || // c sources
+        ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".C" || ext == ".c++" || // c++ sources
+        ext == ".cu" || // CUDA sources
+        ext == ".cl") // OpenCL sources
+        return true;
+    else
+        return false;
 }
 
-std::pair<std::map<boost::filesystem::path, Usages::Clang::PathSet>, Usages::Clang::PathSet> Usages::Clang::parse_paths(const std::string &spelling, const PathSet &paths) {
-  std::map<boost::filesystem::path, PathSet> paths_includes;
-  PathSet paths_with_spelling;
-
-  const static std::regex include_regex("^[ \t]*#[ \t]*include[ \t]*[\"]([^\"]+)[\"].*$");
-
-  auto is_spelling_char = [](char chr) {
-    return (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr == '_';
-  };
-
-  for(auto &path : paths) {
-    auto paths_includes_it = paths_includes.emplace(path, PathSet()).first;
-    bool paths_with_spelling_emplaced = false;
-
-    std::ifstream stream(path.string(), std::ifstream::binary);
-    if(!stream)
-      continue;
-    std::string line;
-    while(std::getline(stream, line)) {
-      std::smatch sm;
-      if(std::regex_match(line, sm, include_regex)) {
-        boost::filesystem::path path(sm[1].str());
-        boost::filesystem::path include_path;
-        // remove .. and .
-        for(auto &part : path) {
-          if(part == "..")
-            include_path = include_path.parent_path();
-          else if(part == ".")
+std::pair<std::map<boost::filesystem::path, Usages::Clang::PathSet>, Usages::Clang::PathSet>
+Usages::Clang::parse_paths(const std::string &spelling, const PathSet &paths) {
+    std::map<boost::filesystem::path, PathSet> paths_includes;
+    PathSet paths_with_spelling;
+
+    const static std::regex include_regex("^[ \t]*#[ \t]*include[ \t]*[\"]([^\"]+)[\"].*$");
+
+    auto is_spelling_char = [](char chr) {
+        return (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr == '_';
+    };
+
+    for (auto &path : paths) {
+        auto paths_includes_it = paths_includes.emplace(path, PathSet()).first;
+        bool paths_with_spelling_emplaced = false;
+
+        std::ifstream stream(path.string(), std::ifstream::binary);
+        if (!stream)
             continue;
-          else
-            include_path /= part;
+        std::string line;
+        while (std::getline(stream, line)) {
+            std::smatch sm;
+            if (std::regex_match(line, sm, include_regex)) {
+                boost::filesystem::path path(sm[1].str());
+                boost::filesystem::path include_path;
+                // remove .. and .
+                for (auto &part : path) {
+                    if (part == "..")
+                        include_path = include_path.parent_path();
+                    else if (part == ".")
+                        continue;
+                    else
+                        include_path /= part;
+                }
+                auto distance = std::distance(include_path.begin(), include_path.end());
+                for (auto &path : paths) {
+                    auto path_distance = std::distance(path.begin(), path.end());
+                    if (path_distance >= distance) {
+                        auto it = path.begin();
+                        std::advance(it, path_distance - distance);
+                        if (std::equal(it, path.end(), include_path.begin(), include_path.end()))
+                            paths_includes_it->second.emplace(path);
+                    }
+                }
+            } else if (!paths_with_spelling_emplaced) {
+                auto pos = line.find(spelling);
+                if (pos != std::string::npos &&
+                    ((!spelling.empty() && !is_spelling_char(spelling[0])) ||
+                     ((pos == 0 || !is_spelling_char(line[pos - 1])) &&
+                      (pos + spelling.size() >= line.size() - 1 || !is_spelling_char(line[pos + spelling.size()]))))) {
+                    paths_with_spelling.emplace(path);
+                    paths_with_spelling_emplaced = true;
+                }
+            }
         }
-        auto distance = std::distance(include_path.begin(), include_path.end());
-        for(auto &path : paths) {
-          auto path_distance = std::distance(path.begin(), path.end());
-          if(path_distance >= distance) {
-            auto it = path.begin();
-            std::advance(it, path_distance - distance);
-            if(std::equal(it, path.end(), include_path.begin(), include_path.end()))
-              paths_includes_it->second.emplace(path);
-          }
-        }
-      }
-      else if(!paths_with_spelling_emplaced) {
-        auto pos = line.find(spelling);
-        if(pos != std::string::npos &&
-           ((!spelling.empty() && !is_spelling_char(spelling[0])) ||
-            ((pos == 0 || !is_spelling_char(line[pos - 1])) &&
-             (pos + spelling.size() >= line.size() - 1 || !is_spelling_char(line[pos + spelling.size()]))))) {
-          paths_with_spelling.emplace(path);
-          paths_with_spelling_emplaced = true;
-        }
-      }
     }
-  }
-  return {paths_includes, paths_with_spelling};
+    return {paths_includes, paths_with_spelling};
 }
 
-Usages::Clang::PathSet Usages::Clang::get_all_includes(const boost::filesystem::path &path, const std::map<boost::filesystem::path, PathSet> &paths_includes) {
-  PathSet all_includes;
-
-  class Recursive {
-  public:
-    static void f(PathSet &all_includes, const boost::filesystem::path &path,
-                  const std::map<boost::filesystem::path, PathSet> &paths_includes) {
-      auto paths_includes_it = paths_includes.find(path);
-      if(paths_includes_it != paths_includes.end()) {
-        for(auto &include : paths_includes_it->second) {
-          auto pair = all_includes.emplace(include);
-          if(pair.second)
-            f(all_includes, include, paths_includes);
+Usages::Clang::PathSet Usages::Clang::get_all_includes(const boost::filesystem::path &path,
+                                                       const std::map<boost::filesystem::path, PathSet> &paths_includes) {
+    PathSet all_includes;
+
+    class Recursive {
+    public:
+        static void f(PathSet &all_includes, const boost::filesystem::path &path,
+                      const std::map<boost::filesystem::path, PathSet> &paths_includes) {
+            auto paths_includes_it = paths_includes.find(path);
+            if (paths_includes_it != paths_includes.end()) {
+                for (auto &include : paths_includes_it->second) {
+                    auto pair = all_includes.emplace(include);
+                    if (pair.second)
+                        f(all_includes, include, paths_includes);
+                }
+            }
         }
-      }
-    }
-  };
-  Recursive::f(all_includes, path, paths_includes);
+    };
+    Recursive::f(all_includes, path, paths_includes);
 
-  return all_includes;
+    return all_includes;
 }
 
-std::pair<Usages::Clang::PathSet, Usages::Clang::PathSet> Usages::Clang::find_potential_paths(const PathSet &paths, const boost::filesystem::path &project_path,
-                                                                                              const std::map<boost::filesystem::path, PathSet> &paths_includes, const PathSet &paths_with_spelling) {
-  PathSet potential_paths;
-  PathSet all_includes;
-
-  bool first=true;
-  for(auto &path: paths) {
-    if(filesystem::file_in_path(path, project_path)) {
-      for(auto &path_with_spelling : paths_with_spelling) {
-        auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
-        if((path_all_includes.find(path) != path_all_includes.end() || path_with_spelling == path)) {
-          potential_paths.emplace(path_with_spelling);
-  
-          for(auto &include : path_all_includes)
-            all_includes.emplace(include);
+std::pair<Usages::Clang::PathSet, Usages::Clang::PathSet>
+Usages::Clang::find_potential_paths(const PathSet &paths, const boost::filesystem::path &project_path,
+                                    const std::map<boost::filesystem::path, PathSet> &paths_includes,
+                                    const PathSet &paths_with_spelling) {
+    PathSet potential_paths;
+    PathSet all_includes;
+
+    bool first = true;
+    for (auto &path: paths) {
+        if (filesystem::file_in_path(path, project_path)) {
+            for (auto &path_with_spelling : paths_with_spelling) {
+                auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
+                if ((path_all_includes.find(path) != path_all_includes.end() || path_with_spelling == path)) {
+                    potential_paths.emplace(path_with_spelling);
+
+                    for (auto &include : path_all_includes)
+                        all_includes.emplace(include);
+                }
+            }
+        } else {
+            if (first) {
+                for (auto &path_with_spelling : paths_with_spelling) {
+                    potential_paths.emplace(path_with_spelling);
+
+                    auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
+                    for (auto &include : path_all_includes)
+                        all_includes.emplace(include);
+                }
+                first = false;
+            }
         }
-      }
     }
-    else {
-      if(first) {
-        for(auto &path_with_spelling : paths_with_spelling) {
-          potential_paths.emplace(path_with_spelling);
-    
-          auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
-          for(auto &include : path_all_includes)
-            all_includes.emplace(include);
-        }
-        first=false;
-      }
-    }
-  }
 
-  return {potential_paths, all_includes};
+    return {potential_paths, all_includes};
 }
 
 void Usages::Clang::write_cache(const boost::filesystem::path &path, const Clang::Cache &cache) {
-  auto cache_path = cache.build_path / cache_folder;
-  boost::system::error_code ec;
-  if(!boost::filesystem::exists(cache_path, ec)) {
-    boost::filesystem::create_directory(cache_path, ec);
-    if(ec)
-      return;
-  }
-  else if(!boost::filesystem::is_directory(cache_path, ec) || ec)
-    return;
-
-  auto path_str = filesystem::get_relative_path(path, cache.project_path).string();
-  for(auto &chr : path_str) {
-    if(chr == '/' || chr == '\\')
-      chr = '_';
-  }
-  path_str += ".usages";
-
-  auto full_cache_path = cache_path / path_str;
-  auto tmp_file = boost::filesystem::temp_directory_path(ec);
-  if(ec)
-    return;
-  tmp_file /= ("jucipp" + std::to_string(get_current_process_id()) + path_str);
-
-  std::ofstream stream(tmp_file.string());
-  if(stream) {
-    try {
-      boost::archive::text_oarchive text_oarchive(stream);
-      text_oarchive << cache;
-      stream.close();
-      boost::filesystem::rename(tmp_file, full_cache_path, ec);
-      if(ec) {
-        boost::filesystem::copy_file(tmp_file, full_cache_path, boost::filesystem::copy_option::overwrite_if_exists);
-        boost::filesystem::remove(tmp_file, ec);
-      }
+    auto cache_path = cache.build_path / cache_folder;
+    boost::system::error_code ec;
+    if (!boost::filesystem::exists(cache_path, ec)) {
+        boost::filesystem::create_directory(cache_path, ec);
+        if (ec)
+            return;
+    } else if (!boost::filesystem::is_directory(cache_path, ec) || ec)
+        return;
+
+    auto path_str = filesystem::get_relative_path(path, cache.project_path).string();
+    for (auto &chr : path_str) {
+        if (chr == '/' || chr == '\\')
+            chr = '_';
     }
-    catch(...) {
-      boost::filesystem::remove(tmp_file, ec);
+    path_str += ".usages";
+
+    auto full_cache_path = cache_path / path_str;
+    auto tmp_file = boost::filesystem::temp_directory_path(ec);
+    if (ec)
+        return;
+    tmp_file /= ("jucipp" + std::to_string(get_current_process_id()) + path_str);
+
+    std::ofstream stream(tmp_file.string());
+    if (stream) {
+        try {
+            boost::archive::text_oarchive text_oarchive(stream);
+            text_oarchive << cache;
+            stream.close();
+            boost::filesystem::rename(tmp_file, full_cache_path, ec);
+            if (ec) {
+                boost::filesystem::copy_file(tmp_file, full_cache_path,
+                                             boost::filesystem::copy_option::overwrite_if_exists);
+                boost::filesystem::remove(tmp_file, ec);
+            }
+        }
+        catch (...) {
+            boost::filesystem::remove(tmp_file, ec);
+        }
     }
-  }
 }
 
-Usages::Clang::Cache Usages::Clang::read_cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &path) {
-  auto path_str = filesystem::get_relative_path(path, project_path).string();
-  for(auto &chr : path_str) {
-    if(chr == '/' || chr == '\\')
-      chr = '_';
-  }
-  auto cache_path = build_path / cache_folder / (path_str + ".usages");
-
-  boost::system::error_code ec;
-  if(boost::filesystem::exists(cache_path, ec)) {
-    std::ifstream stream(cache_path.string());
-    if(stream) {
-      Cache cache;
-      boost::archive::text_iarchive text_iarchive(stream);
-      try {
-        text_iarchive >> cache;
-        return cache;
-      }
-      catch(...) {
-      }
+Usages::Clang::Cache
+Usages::Clang::read_cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                          const boost::filesystem::path &path) {
+    auto path_str = filesystem::get_relative_path(path, project_path).string();
+    for (auto &chr : path_str) {
+        if (chr == '/' || chr == '\\')
+            chr = '_';
+    }
+    auto cache_path = build_path / cache_folder / (path_str + ".usages");
+
+    boost::system::error_code ec;
+    if (boost::filesystem::exists(cache_path, ec)) {
+        std::ifstream stream(cache_path.string());
+        if (stream) {
+            Cache cache;
+            boost::archive::text_iarchive text_iarchive(stream);
+            try {
+                text_iarchive >> cache;
+                return cache;
+            }
+            catch (...) {
+            }
+        }
     }
-  }
-  return Cache();
+    return Cache();
 }
diff --git a/src/usages_clang.h b/src/usages_clang.h
index 492a21c7..61f127fa 100644
--- a/src/usages_clang.h
+++ b/src/usages_clang.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include "clangmm.h"
 #include <atomic>
 #include <boost/archive/text_iarchive.hpp>
@@ -14,138 +15,167 @@
 #include <unordered_set>
 
 namespace boost {
-  namespace serialization {
-    template <class Archive>
-    void serialize(Archive &ar, boost::filesystem::path &path, const unsigned int version) {
-      std::string path_str;
-      if(Archive::is_saving::value)
-        path_str = path.string();
-      ar &path_str;
-      if(Archive::is_loading::value)
-        path = path_str;
-    }
-  } // namespace serialization
+    namespace serialization {
+        template<class Archive>
+        void serialize(Archive &ar, boost::filesystem::path &path, const unsigned int version) {
+            std::string path_str;
+            if (Archive::is_saving::value)
+                path_str = path.string();
+            ar & path_str;
+            if (Archive::is_loading::value)
+                path = path_str;
+        }
+    } // namespace serialization
 } // namespace boost
 
 namespace Usages {
-  class Clang {
-  public:
-    typedef std::set<boost::filesystem::path> PathSet;
-
-    class Usages {
+    class Clang {
     public:
-      boost::filesystem::path path;
-      std::vector<std::pair<clangmm::Offset, clangmm::Offset>> offsets;
-      std::vector<std::string> lines;
-    };
-
-    class Cache {
-      friend class boost::serialization::access;
-      template <class Archive>
-      void serialize(Archive &ar, const unsigned int version) {
-        ar &project_path;
-        ar &build_path;
-        ar &tokens;
-        ar &cursors;
-        ar &paths_and_last_write_times;
-      }
+        typedef std::set<boost::filesystem::path> PathSet;
+
+        class Usages {
+        public:
+            boost::filesystem::path path;
+            std::vector<std::pair<clangmm::Offset, clangmm::Offset>> offsets;
+            std::vector<std::string> lines;
+        };
+
+        class Cache {
+            friend class boost::serialization::access;
+
+            template<class Archive>
+            void serialize(Archive &ar, const unsigned int version) {
+                ar & project_path;
+                ar & build_path;
+                ar & tokens;
+                ar & cursors;
+                ar & paths_and_last_write_times;
+            }
+
+        public:
+            class Cursor {
+                friend class boost::serialization::access;
+
+                template<class Archive>
+                void serialize(Archive &ar, const unsigned int version) {
+                    ar & kind;
+                    ar & usrs;
+                }
+
+            public:
+                clangmm::Cursor::Kind kind;
+                std::unordered_set<std::string> usrs;
+
+                bool operator==(const Cursor &o);
+            };
+
+            class Token {
+                friend class boost::serialization::access;
+
+                template<class Archive>
+                void serialize(Archive &ar, const unsigned int version) {
+                    ar & spelling;
+                    ar & offsets.first.line & offsets.first.index;
+                    ar & offsets.second.line & offsets.second.index;
+                    ar & cursor_id;
+                }
+
+            public:
+                std::string spelling;
+                std::pair<clangmm::Offset, clangmm::Offset> offsets;
+                size_t cursor_id;
+            };
+
+            boost::filesystem::path project_path;
+            boost::filesystem::path build_path;
+
+            std::vector<Token> tokens;
+            std::vector<Cursor> cursors;
+            std::map<boost::filesystem::path, std::time_t> paths_and_last_write_times;
+
+            Cache() {}
+
+            Cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                  const boost::filesystem::path &path,
+                  std::time_t before_parse_time, clangmm::TranslationUnit *translation_unit,
+                  clangmm::Tokens *clang_tokens);
+
+            operator bool() const { return !paths_and_last_write_times.empty(); }
+
+            std::vector<std::pair<clangmm::Offset, clangmm::Offset>>
+            get_similar_token_offsets(clangmm::Cursor::Kind kind, const std::string &spelling,
+                                      const std::unordered_set<std::string> &usrs) const;
+        };
+
+    private:
+        const static boost::filesystem::path cache_folder;
+
+        static std::map<boost::filesystem::path, Cache> caches;
+        static std::mutex caches_mutex;
+
+        static std::atomic<size_t> cache_in_progress_count;
 
     public:
-      class Cursor {
-        friend class boost::serialization::access;
-        template <class Archive>
-        void serialize(Archive &ar, const unsigned int version) {
-          ar &kind;
-          ar &usrs;
-        }
-
-      public:
-        clangmm::Cursor::Kind kind;
-        std::unordered_set<std::string> usrs;
-
-        bool operator==(const Cursor &o);
-      };
-
-      class Token {
-        friend class boost::serialization::access;
-        template <class Archive>
-        void serialize(Archive &ar, const unsigned int version) {
-          ar &spelling;
-          ar &offsets.first.line &offsets.first.index;
-          ar &offsets.second.line &offsets.second.index;
-          ar &cursor_id;
-        }
-
-      public:
-        std::string spelling;
-        std::pair<clangmm::Offset, clangmm::Offset> offsets;
-        size_t cursor_id;
-      };
+        static std::vector<Usages>
+        get_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                   const boost::filesystem::path &debug_path,
+                   const std::string &spelling, const clangmm::Cursor &cursor,
+                   const std::vector<clangmm::TranslationUnit *> &translation_units);
 
-      boost::filesystem::path project_path;
-      boost::filesystem::path build_path;
+        static void cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                          const boost::filesystem::path &path,
+                          std::time_t before_parse_time, const PathSet &project_paths_in_use,
+                          clangmm::TranslationUnit *translation_unit, clangmm::Tokens *tokens);
 
-      std::vector<Token> tokens;
-      std::vector<Cursor> cursors;
-      std::map<boost::filesystem::path, std::time_t> paths_and_last_write_times;
+        static void erase_unused_caches(const PathSet &project_paths_in_use);
 
-      Cache() {}
-      Cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &path,
-            std::time_t before_parse_time, clangmm::TranslationUnit *translation_unit, clangmm::Tokens *clang_tokens);
+        static void erase_cache(const boost::filesystem::path &path);
 
-      operator bool() const { return !paths_and_last_write_times.empty(); }
-
-      std::vector<std::pair<clangmm::Offset, clangmm::Offset>> get_similar_token_offsets(clangmm::Cursor::Kind kind, const std::string &spelling,
-                                                                                         const std::unordered_set<std::string> &usrs) const;
-    };
+        static void erase_all_caches_for_project(const boost::filesystem::path &project_path,
+                                                 const boost::filesystem::path &build_path);
 
-  private:
-    const static boost::filesystem::path cache_folder;
+        static void cache_in_progress();
 
-    static std::map<boost::filesystem::path, Cache> caches;
-    static std::mutex caches_mutex;
+    private:
+        static void add_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                               const boost::filesystem::path &path_,
+                               std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
+                               clangmm::Cursor cursor,
+                               clangmm::TranslationUnit *translation_unit, bool store_in_cache);
 
-    static std::atomic<size_t> cache_in_progress_count;
+        static bool
+        add_usages_from_cache(const boost::filesystem::path &path, std::vector<Usages> &usages, PathSet &visited,
+                              const std::string &spelling, const clangmm::Cursor &cursor, const Cache &cache);
 
-  public:
-    static std::vector<Usages> get_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &debug_path,
-                                          const std::string &spelling, const clangmm::Cursor &cursor, const std::vector<clangmm::TranslationUnit *> &translation_units);
+        static void
+        add_usages_from_includes(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                                 std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
+                                 const clangmm::Cursor &cursor,
+                                 clangmm::TranslationUnit *translation_unit, bool store_in_cache);
 
-    static void cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &path,
-                      std::time_t before_parse_time, const PathSet &project_paths_in_use, clangmm::TranslationUnit *translation_unit, clangmm::Tokens *tokens);
-    static void erase_unused_caches(const PathSet &project_paths_in_use);
-    static void erase_cache(const boost::filesystem::path &path);
-    static void erase_all_caches_for_project(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path);
-    static void cache_in_progress();
+        static PathSet find_paths(const boost::filesystem::path &project_path,
+                                  const boost::filesystem::path &build_path, const boost::filesystem::path &debug_path);
 
-  private:
-    static void add_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &path_,
-                           std::vector<Usages> &usages, PathSet &visited, const std::string &spelling, clangmm::Cursor cursor,
-                           clangmm::TranslationUnit *translation_unit, bool store_in_cache);
+        static bool is_header(const boost::filesystem::path &path);
 
-    static bool add_usages_from_cache(const boost::filesystem::path &path, std::vector<Usages> &usages, PathSet &visited,
-                                      const std::string &spelling, const clangmm::Cursor &cursor, const Cache &cache);
+        static bool is_source(const boost::filesystem::path &path);
 
-    static void add_usages_from_includes(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
-                                         std::vector<Usages> &usages, PathSet &visited, const std::string &spelling, const clangmm::Cursor &cursor,
-                                         clangmm::TranslationUnit *translation_unit, bool store_in_cache);
+        static std::pair<std::map<boost::filesystem::path, PathSet>, PathSet>
+        parse_paths(const std::string &spelling, const PathSet &paths);
 
-    static PathSet find_paths(const boost::filesystem::path &project_path,
-                              const boost::filesystem::path &build_path, const boost::filesystem::path &debug_path);
+        /// Recursively find and return all the include paths of path
+        static PathSet get_all_includes(const boost::filesystem::path &path,
+                                        const std::map<boost::filesystem::path, PathSet> &paths_includes);
 
-    static bool is_header(const boost::filesystem::path &path);
-    static bool is_source(const boost::filesystem::path &path);
+        /// Based on cursor paths, paths_includes and paths_with_spelling return potential paths that might contain the sought after symbol
+        static std::pair<Clang::PathSet, Clang::PathSet>
+        find_potential_paths(const PathSet &paths, const boost::filesystem::path &project_path,
+                             const std::map<boost::filesystem::path, PathSet> &paths_includes,
+                             const PathSet &paths_with_spelling);
 
-    static std::pair<std::map<boost::filesystem::path, PathSet>, PathSet> parse_paths(const std::string &spelling, const PathSet &paths);
+        static void write_cache(const boost::filesystem::path &path, const Cache &cache);
 
-    /// Recursively find and return all the include paths of path
-    static PathSet get_all_includes(const boost::filesystem::path &path, const std::map<boost::filesystem::path, PathSet> &paths_includes);
-
-    /// Based on cursor paths, paths_includes and paths_with_spelling return potential paths that might contain the sought after symbol
-    static std::pair<Clang::PathSet, Clang::PathSet> find_potential_paths(const PathSet &paths, const boost::filesystem::path &project_path,
-                                                                          const std::map<boost::filesystem::path, PathSet> &paths_includes, const PathSet &paths_with_spelling);
-
-    static void write_cache(const boost::filesystem::path &path, const Cache &cache);
-    static Cache read_cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path, const boost::filesystem::path &path);
-  };
+        static Cache read_cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                                const boost::filesystem::path &path);
+    };
 } // namespace Usages
diff --git a/src/window.cc b/src/window.cc
index e9f3311c..9371207a 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -12,1752 +12,1776 @@
 #include "terminal.h"
 
 Window::Window() {
-  Gsv::init();
-  
-  set_title("juCi++");
-  set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK|Gdk::LEAVE_NOTIFY_MASK);
-  
-  auto provider = Gtk::CssProvider::create();
-  auto screen = get_screen();
-  std::string border_radius_style;
-  if(screen->get_rgba_visual())
-    border_radius_style="border-radius: 5px; ";
+    Gsv::init();
+
+    set_title("juCi++");
+    set_events(Gdk::POINTER_MOTION_MASK | Gdk::FOCUS_CHANGE_MASK | Gdk::SCROLL_MASK | Gdk::LEAVE_NOTIFY_MASK);
+
+    auto provider = Gtk::CssProvider::create();
+    auto screen = get_screen();
+    std::string border_radius_style;
+    if (screen->get_rgba_visual())
+        border_radius_style = "border-radius: 5px; ";
 #if GTK_VERSION_GE(3, 20)
-  std::string notebook_style(".juci_notebook tab {border-radius: 5px 5px 0 0; padding: 0 4px; margin: 0;}");
+    std::string notebook_style(".juci_notebook tab {border-radius: 5px 5px 0 0; padding: 0 4px; margin: 0;}");
 #else
-  std::string notebook_style(".juci_notebook {-GtkNotebook-tab-overlap: 0px;} .juci_notebook tab {border-radius: 5px 5px 0 0; padding: 4px 4px;}");
+    std::string notebook_style(".juci_notebook {-GtkNotebook-tab-overlap: 0px;} .juci_notebook tab {border-radius: 5px 5px 0 0; padding: 4px 4px;}");
 #endif
-  provider->load_from_data(R"(
+    provider->load_from_data(R"(
     .juci_directories *:selected {border-left-color: inherit; color: inherit; background-color: rgba(128, 128, 128 , 0.2); background-image: inherit;}
-    )"+notebook_style+R"(
+    )" + notebook_style + R"(
     .juci_info {border-radius: 5px;}
     .juci_tooltip_window {background-color: transparent;}
-    .juci_tooltip_box {)"+border_radius_style+R"(padding: 3px;}
+    .juci_tooltip_box {)" + border_radius_style + R"(padding: 3px;}
   )");
-  get_style_context()->add_provider_for_screen(screen, provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-  
-  set_menu_actions();
-  configure();
-  Menu::get().toggle_menu_items();
-  
-  Menu::get().right_click_line_menu->attach_to_widget(*this);
-  Menu::get().right_click_selected_menu->attach_to_widget(*this);
-  
-  EntryBox::get().signal_hide().connect([]() {
-    if(auto view=Notebook::get().get_current_view())
-      view->grab_focus();
-  });
-
-  Notebook::get().on_change_page=[this](Source::View *view) {
-    if(search_entry_shown && EntryBox::get().labels.size()>0) {
-      view->update_search_occurrences=[](int number){
-        EntryBox::get().labels.begin()->update(0, std::to_string(number));
-      };
-      view->search_highlight(last_search, case_sensitive_search, regex_search);
-    }
+    get_style_context()->add_provider_for_screen(screen, provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 
+    set_menu_actions();
+    configure();
     Menu::get().toggle_menu_items();
-    
-    Directories::get().select(view->file_path);
-    
-    if(view->full_reparse_needed)
-      view->full_reparse();
-    else if(view->soft_reparse_needed)
-      view->soft_reparse();
-    
-    Notebook::get().update_status(view);
-    
+
+    Menu::get().right_click_line_menu->attach_to_widget(*this);
+    Menu::get().right_click_selected_menu->attach_to_widget(*this);
+
+    EntryBox::get().signal_hide().connect([]() {
+        if (auto view = Notebook::get().get_current_view())
+            view->grab_focus();
+    });
+
+    Notebook::get().on_change_page = [this](Source::View *view) {
+        if (search_entry_shown && EntryBox::get().labels.size() > 0) {
+            view->update_search_occurrences = [](int number) {
+                EntryBox::get().labels.begin()->update(0, std::to_string(number));
+            };
+            view->search_highlight(last_search, case_sensitive_search, regex_search);
+        }
+
+        Menu::get().toggle_menu_items();
+
+        Directories::get().select(view->file_path);
+
+        if (view->full_reparse_needed)
+            view->full_reparse();
+        else if (view->soft_reparse_needed)
+            view->soft_reparse();
+
+        Notebook::get().update_status(view);
+
 #ifdef JUCI_ENABLE_DEBUG
-    if(Project::debugging)
-      Project::debug_update_stop();
+        if(Project::debugging)
+          Project::debug_update_stop();
 #endif
-  };
-  Notebook::get().on_close_page=[](Source::View *view) {
+    };
+    Notebook::get().on_close_page = [](Source::View *view) {
 #ifdef JUCI_ENABLE_DEBUG
-    if(Project::current && Project::debugging) {
-      auto iter=view->get_buffer()->begin();
-      while(view->get_source_buffer()->forward_iter_to_source_mark(iter, "debug_breakpoint") ||
-         view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size()) {
-        auto end_iter=view->get_iter_at_line_end(iter.get_line());
-        view->get_source_buffer()->remove_source_marks(iter, end_iter, "debug_breakpoint");
-        Project::current->debug_remove_breakpoint(view->file_path, iter.get_line()+1, view->get_buffer()->get_line_count()+1);
-      }
-    }
+        if(Project::current && Project::debugging) {
+          auto iter=view->get_buffer()->begin();
+          while(view->get_source_buffer()->forward_iter_to_source_mark(iter, "debug_breakpoint") ||
+             view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size()) {
+            auto end_iter=view->get_iter_at_line_end(iter.get_line());
+            view->get_source_buffer()->remove_source_marks(iter, end_iter, "debug_breakpoint");
+            Project::current->debug_remove_breakpoint(view->file_path, iter.get_line()+1, view->get_buffer()->get_line_count()+1);
+          }
+        }
 #endif
-    EntryBox::get().hide();
-    if(auto view=Notebook::get().get_current_view())
-      Notebook::get().update_status(view);
-    else {
-      Notebook::get().clear_status();
-      
-      Menu::get().toggle_menu_items();
-    }
-  };
-  
-  signal_focus_out_event().connect([](GdkEventFocus *event) {
-    if(auto view=Notebook::get().get_current_view()) {
-      view->hide_tooltips();
-      view->hide_dialogs();
-    }
-    return false;
-  });
-  
-  signal_hide().connect([]{
-    while(!Source::View::non_deleted_views.empty()) {
-      while(Gtk::Main::events_pending())
-        Gtk::Main::iteration(false);
-    }
-    // TODO 2022 (after Debian Stretch LTS has ended, see issue #354): remove:
-    Project::current=nullptr;
-  });
-  
-  Gtk::Settings::get_default()->connect_property_changed("gtk-theme-name", [] {
-    Directories::get().update();
-    if(auto view=Notebook::get().get_current_view())
-      Notebook::get().update_status(view);
-  });
-  
-  about.signal_response().connect([this](int d){
-    about.hide();
-  });
-  
-  about.set_logo_icon_name("juci");
-  about.set_version(Config::get().window.version);
-  about.set_authors({"(in order of appearance)",
-                     "Ted Johan Kristoffersen", 
-                     "Jørgen Lien Sellæg",
-                     "Geir Morten Larsen",
-                     "Ole Christian Eidheim"});
-  about.set_name("About juCi++");
-  about.set_program_name("juCi++");
-  about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy");
-  about.set_license_type(Gtk::License::LICENSE_MIT_X11);
-  about.set_transient_for(*this);
+        EntryBox::get().hide();
+        if (auto view = Notebook::get().get_current_view())
+            Notebook::get().update_status(view);
+        else {
+            Notebook::get().clear_status();
+
+            Menu::get().toggle_menu_items();
+        }
+    };
+
+    signal_focus_out_event().connect([](GdkEventFocus *event) {
+        if (auto view = Notebook::get().get_current_view()) {
+            view->hide_tooltips();
+            view->hide_dialogs();
+        }
+        return false;
+    });
+
+    signal_hide().connect([] {
+        while (!Source::View::non_deleted_views.empty()) {
+            while (Gtk::Main::events_pending())
+                Gtk::Main::iteration(false);
+        }
+        // TODO 2022 (after Debian Stretch LTS has ended, see issue #354): remove:
+        Project::current = nullptr;
+    });
+
+    Gtk::Settings::get_default()->connect_property_changed("gtk-theme-name", [] {
+        Directories::get().update();
+        if (auto view = Notebook::get().get_current_view())
+            Notebook::get().update_status(view);
+    });
+
+    about.signal_response().connect([this](int d) {
+        about.hide();
+    });
+
+    about.set_logo_icon_name("juci");
+    about.set_version(Config::get().window.version);
+    about.set_authors({"(in order of appearance)",
+                       "Ted Johan Kristoffersen",
+                       "Jørgen Lien Sellæg",
+                       "Geir Morten Larsen",
+                       "Ole Christian Eidheim"});
+    about.set_name("About juCi++");
+    about.set_program_name("juCi++");
+    about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy");
+    about.set_license_type(Gtk::License::LICENSE_MIT_X11);
+    about.set_transient_for(*this);
 } // Window constructor
 
 void Window::configure() {
-  Config::get().load();
-  auto screen = get_screen();
-  if(css_provider_theme)
-    Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_theme);
-  if(Config::get().window.theme_name.empty()) {
-    css_provider_theme=Gtk::CssProvider::create();
-    Gtk::Settings::get_default()->property_gtk_application_prefer_dark_theme()=(Config::get().window.theme_variant=="dark");
-  }
-  else
-    css_provider_theme=Gtk::CssProvider::get_named(Config::get().window.theme_name, Config::get().window.theme_variant);
-  //TODO: add check if theme exists, or else write error to terminal
-  Gtk::StyleContext::add_provider_for_screen(screen, css_provider_theme, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
-  
-  auto style_scheme_manager=Source::StyleSchemeManager::get_default();
-  if(css_provider_tooltips)
-    Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_tooltips);
-  else
-    css_provider_tooltips=Gtk::CssProvider::create();
-  Glib::RefPtr<Gsv::Style> style;
-  if(Config::get().source.style.size()>0) {
-    auto scheme = style_scheme_manager->get_scheme(Config::get().source.style);
-    if(scheme)
-      style = scheme->get_style("def:note");
-    else {
-      Terminal::get().print("Error: Could not find gtksourceview style: "+Config::get().source.style+'\n', true);
+    Config::get().load();
+    auto screen = get_screen();
+    if (css_provider_theme)
+        Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_theme);
+    if (Config::get().window.theme_name.empty()) {
+        css_provider_theme = Gtk::CssProvider::create();
+        Gtk::Settings::get_default()->property_gtk_application_prefer_dark_theme() = (
+                Config::get().window.theme_variant == "dark");
+    } else
+        css_provider_theme = Gtk::CssProvider::get_named(Config::get().window.theme_name,
+                                                         Config::get().window.theme_variant);
+    //TODO: add check if theme exists, or else write error to terminal
+    Gtk::StyleContext::add_provider_for_screen(screen, css_provider_theme, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
+
+    auto style_scheme_manager = Source::StyleSchemeManager::get_default();
+    if (css_provider_tooltips)
+        Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_tooltips);
+    else
+        css_provider_tooltips = Gtk::CssProvider::create();
+    Glib::RefPtr<Gsv::Style> style;
+    if (Config::get().source.style.size() > 0) {
+        auto scheme = style_scheme_manager->get_scheme(Config::get().source.style);
+        if (scheme)
+            style = scheme->get_style("def:note");
+        else {
+            Terminal::get().print("Error: Could not find gtksourceview style: " + Config::get().source.style + '\n',
+                                  true);
+        }
     }
-  }
-  auto foreground_value = style && style->property_foreground_set() ? style->property_foreground().get_value() : get_style_context()->get_color().to_string();
-  auto background_value = style && style->property_background_set() ? style->property_background().get_value() : get_style_context()->get_background_color().to_string();
+    auto foreground_value = style && style->property_foreground_set() ? style->property_foreground().get_value()
+                                                                      : get_style_context()->get_color().to_string();
+    auto background_value = style && style->property_background_set() ? style->property_background().get_value()
+                                                                      : get_style_context()->get_background_color().to_string();
 #if GTK_VERSION_GE(3, 20)
-  css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: "+background_value+";}"
-                                        ".juci_tooltip_text_view text {color: "+foreground_value+";background-color: "+background_value+";}");
+    css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: " + background_value + ";}"
+                                                                                                       ".juci_tooltip_text_view text {color: " +
+                                          foreground_value + ";background-color: " + background_value + ";}");
 #else
-  css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: "+background_value+";}"
-                                        ".juci_tooltip_text_view *:not(:selected) {color: "+foreground_value+";background-color: "+background_value+";}");
+    css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: "+background_value+";}"
+                                          ".juci_tooltip_text_view *:not(:selected) {color: "+foreground_value+";background-color: "+background_value+";}");
 #endif
-  get_style_context()->add_provider_for_screen(screen, css_provider_tooltips, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-  
-  Menu::get().set_keys();
-  Terminal::get().configure();
-  Directories::get().update();
-  if(auto view=Notebook::get().get_current_view())
-    Notebook::get().update_status(view);
+    get_style_context()->add_provider_for_screen(screen, css_provider_tooltips,
+                                                 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+    Menu::get().set_keys();
+    Terminal::get().configure();
+    Directories::get().update();
+    if (auto view = Notebook::get().get_current_view())
+        Notebook::get().update_status(view);
 }
 
 void Window::set_menu_actions() {
-  auto &menu = Menu::get();
-  
-  menu.add_action("about", [this]() {
-    about.show();
-    about.present();
-  });
-  menu.add_action("preferences", []() {
-    Notebook::get().open(Config::get().home_juci_path/"config"/"config.json");
-  });
-  menu.add_action("quit", [this]() {
-    close();
-  });
-  
-  menu.add_action("file_new_file", []() {
-    boost::filesystem::path path = Dialog::new_file(Notebook::get().get_current_folder());
-    if(path!="") {
-      if(boost::filesystem::exists(path)) {
-        Terminal::get().print("Error: "+path.string()+" already exists.\n", true);
-      }
-      else {
-        if(filesystem::write(path)) {
-          if(Directories::get().path!="")
-            Directories::get().update();
-          Notebook::get().open(path);
-          if(Directories::get().path!="")
-            Directories::get().on_save_file(path);
-          Terminal::get().print("New file "+path.string()+" created.\n");
+    auto &menu = Menu::get();
+
+    menu.add_action("about", [this]() {
+        about.show();
+        about.present();
+    });
+    menu.add_action("preferences", []() {
+        Notebook::get().open(Config::get().home_juci_path / "config" / "config.json");
+    });
+    menu.add_action("quit", [this]() {
+        close();
+    });
+
+    menu.add_action("file_new_file", []() {
+        boost::filesystem::path path = Dialog::new_file(Notebook::get().get_current_folder());
+        if (path != "") {
+            if (boost::filesystem::exists(path)) {
+                Terminal::get().print("Error: " + path.string() + " already exists.\n", true);
+            } else {
+                if (filesystem::write(path)) {
+                    if (Directories::get().path != "")
+                        Directories::get().update();
+                    Notebook::get().open(path);
+                    if (Directories::get().path != "")
+                        Directories::get().on_save_file(path);
+                    Terminal::get().print("New file " + path.string() + " created.\n");
+                } else
+                    Terminal::get().print("Error: could not create new file " + path.string() + ".\n", true);
+            }
         }
-        else
-          Terminal::get().print("Error: could not create new file "+path.string()+".\n", true);
-      }
-    }
-  });
-  menu.add_action("file_new_folder", []() {
-    auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
-    boost::filesystem::path path = Dialog::new_folder(Notebook::get().get_current_folder());
-    if(path!="" && boost::filesystem::exists(path)) {
-      boost::system::error_code ec;
-      auto last_write_time=boost::filesystem::last_write_time(path, ec);
-      if(!ec && last_write_time>=time_now) {
-        if(Directories::get().path!="")
-          Directories::get().update();
-        Terminal::get().print("New folder "+path.string()+" created.\n");
-      }
-      else
-        Terminal::get().print("Error: "+path.string()+" already exists.\n", true);
-      Directories::get().select(path);
-    }
-  });
-  menu.add_action("file_new_project_c", []() {
-    boost::filesystem::path project_path = Dialog::new_folder(Notebook::get().get_current_folder());
-    if(project_path!="") {
-      auto project_name=project_path.filename().string();
-      for(size_t c=0;c<project_name.size();c++) {
-        if(project_name[c]==' ')
-          project_name[c]='_';
-      }
-      auto cmakelists_path=project_path;
-      cmakelists_path/="CMakeLists.txt";
-      auto c_main_path=project_path;
-      c_main_path/="main.c";
-      if(boost::filesystem::exists(cmakelists_path)) {
-        Terminal::get().print("Error: "+cmakelists_path.string()+" already exists.\n", true);
-        return;
-      }
-      if(boost::filesystem::exists(c_main_path)) {
-        Terminal::get().print("Error: "+c_main_path.string()+" already exists.\n", true);
-        return;
-      }
-      std::string cmakelists="cmake_minimum_required(VERSION 2.8)\n\nproject("+project_name+")\n\nset(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -std=c11 -Wall -Wextra\")\n\nadd_executable("+project_name+" main.c)\n";
-      std::string c_main="#include <stdio.h>\n\nint main() {\n  printf(\"Hello World!\\n\");\n}\n";
-      if(filesystem::write(cmakelists_path, cmakelists) && filesystem::write(c_main_path, c_main)) {
-        Directories::get().open(project_path);
-        Notebook::get().open(c_main_path);
-        Directories::get().update();
-        Terminal::get().print("C project "+project_name+" created.\n");
-      }
-      else
-        Terminal::get().print("Error: Could not create project "+project_path.string()+"\n", true);
-    }
-  });
-  menu.add_action("file_new_project_cpp", []() {
-    boost::filesystem::path project_path = Dialog::new_folder(Notebook::get().get_current_folder());
-    if(project_path!="") {
-      auto project_name=project_path.filename().string();
-      for(size_t c=0;c<project_name.size();c++) {
-        if(project_name[c]==' ')
-          project_name[c]='_';
-      }
-      auto cmakelists_path=project_path;
-      cmakelists_path/="CMakeLists.txt";
-      auto cpp_main_path=project_path;
-      cpp_main_path/="main.cpp";
-      if(boost::filesystem::exists(cmakelists_path)) {
-        Terminal::get().print("Error: "+cmakelists_path.string()+" already exists.\n", true);
-        return;
-      }
-      if(boost::filesystem::exists(cpp_main_path)) {
-        Terminal::get().print("Error: "+cpp_main_path.string()+" already exists.\n", true);
-        return;
-      }
-      std::string cmakelists="cmake_minimum_required(VERSION 2.8)\n\nproject("+project_name+")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra\")\n\nadd_executable("+project_name+" main.cpp)\n";
-      std::string cpp_main="#include <iostream>\n\nint main() {\n  std::cout << \"Hello World!\\n\";\n}\n";
-      if(filesystem::write(cmakelists_path, cmakelists) && filesystem::write(cpp_main_path, cpp_main)) {
-        Directories::get().open(project_path);
-        Notebook::get().open(cpp_main_path);
-        Directories::get().update();
-        Terminal::get().print("C++ project "+project_name+" created.\n");
-      }
-      else
-        Terminal::get().print("Error: Could not create project "+project_path.string()+"\n", true);
-    }
-  });
-  
-  menu.add_action("file_open_file", []() {
-    auto folder_path=Notebook::get().get_current_folder();
-    if(auto view=Notebook::get().get_current_view()) {
-      if(!Directories::get().path.empty() && !filesystem::file_in_path(view->file_path, Directories::get().path))
-        folder_path=view->file_path.parent_path();
-    }
-    auto path=Dialog::open_file(folder_path);
-    if(path!="")
-      Notebook::get().open(path);
-  });
-  menu.add_action("file_open_folder", []() {
-    auto path = Dialog::open_folder(Notebook::get().get_current_folder());
-    if (path!="" && boost::filesystem::exists(path))
-      Directories::get().open(path);
-  });
-  
-  menu.add_action("file_reload_file", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(boost::filesystem::exists(view->file_path)) {
-        std::ifstream can_read(view->file_path.string());
-        if(!can_read) {
-          Terminal::get().print("Error: could not read "+view->file_path.string()+"\n", true);
-          return;
+    });
+    menu.add_action("file_new_folder", []() {
+        auto time_now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+        boost::filesystem::path path = Dialog::new_folder(Notebook::get().get_current_folder());
+        if (path != "" && boost::filesystem::exists(path)) {
+            boost::system::error_code ec;
+            auto last_write_time = boost::filesystem::last_write_time(path, ec);
+            if (!ec && last_write_time >= time_now) {
+                if (Directories::get().path != "")
+                    Directories::get().update();
+                Terminal::get().print("New folder " + path.string() + " created.\n");
+            } else
+                Terminal::get().print("Error: " + path.string() + " already exists.\n", true);
+            Directories::get().select(path);
         }
-        can_read.close();
-      }
-      else {
-        Terminal::get().print("Error: "+view->file_path.string()+" does not exist\n", true);
-        return;
-      }
-      
-      if(view->load())
-        view->full_reparse();
-    }
-  });
-  
-  menu.add_action("file_save", [this]() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(Notebook::get().save_current()) {
-        if(view->file_path==Config::get().home_juci_path/"config"/"config.json") {
-          configure();
-          for(size_t c=0;c<Notebook::get().size();c++) {
-            Notebook::get().get_view(c)->configure();
-            Notebook::get().configure(c);
-          }
+    });
+    menu.add_action("file_new_project_c", []() {
+        boost::filesystem::path project_path = Dialog::new_folder(Notebook::get().get_current_folder());
+        if (project_path != "") {
+            auto project_name = project_path.filename().string();
+            for (size_t c = 0; c < project_name.size(); c++) {
+                if (project_name[c] == ' ')
+                    project_name[c] = '_';
+            }
+            auto cmakelists_path = project_path;
+            cmakelists_path /= "CMakeLists.txt";
+            auto c_main_path = project_path;
+            c_main_path /= "main.c";
+            if (boost::filesystem::exists(cmakelists_path)) {
+                Terminal::get().print("Error: " + cmakelists_path.string() + " already exists.\n", true);
+                return;
+            }
+            if (boost::filesystem::exists(c_main_path)) {
+                Terminal::get().print("Error: " + c_main_path.string() + " already exists.\n", true);
+                return;
+            }
+            std::string cmakelists = "cmake_minimum_required(VERSION 2.8)\n\nproject(" + project_name +
+                                     ")\n\nset(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -std=c11 -Wall -Wextra\")\n\nadd_executable(" +
+                                     project_name + " main.c)\n";
+            std::string c_main = "#include <stdio.h>\n\nint main() {\n  printf(\"Hello World!\\n\");\n}\n";
+            if (filesystem::write(cmakelists_path, cmakelists) && filesystem::write(c_main_path, c_main)) {
+                Directories::get().open(project_path);
+                Notebook::get().open(c_main_path);
+                Directories::get().update();
+                Terminal::get().print("C project " + project_name + " created.\n");
+            } else
+                Terminal::get().print("Error: Could not create project " + project_path.string() + "\n", true);
         }
-      }
-    }
-  });
-  menu.add_action("file_save_as", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      auto path = Dialog::save_file_as(view->file_path);
-      if(path!="") {
-        std::ofstream file(path, std::ofstream::binary);
-        if(file) {
-          file << view->get_buffer()->get_text().raw();
-          file.close();
-          if(Directories::get().path!="")
-            Directories::get().update();
-          Notebook::get().open(path);
-          Terminal::get().print("File saved to: " + Notebook::get().get_current_view()->file_path.string()+"\n");
+    });
+    menu.add_action("file_new_project_cpp", []() {
+        boost::filesystem::path project_path = Dialog::new_folder(Notebook::get().get_current_folder());
+        if (project_path != "") {
+            auto project_name = project_path.filename().string();
+            for (size_t c = 0; c < project_name.size(); c++) {
+                if (project_name[c] == ' ')
+                    project_name[c] = '_';
+            }
+            auto cmakelists_path = project_path;
+            cmakelists_path /= "CMakeLists.txt";
+            auto cpp_main_path = project_path;
+            cpp_main_path /= "main.cpp";
+            if (boost::filesystem::exists(cmakelists_path)) {
+                Terminal::get().print("Error: " + cmakelists_path.string() + " already exists.\n", true);
+                return;
+            }
+            if (boost::filesystem::exists(cpp_main_path)) {
+                Terminal::get().print("Error: " + cpp_main_path.string() + " already exists.\n", true);
+                return;
+            }
+            std::string cmakelists = "cmake_minimum_required(VERSION 2.8)\n\nproject(" + project_name +
+                                     ")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra\")\n\nadd_executable(" +
+                                     project_name + " main.cpp)\n";
+            std::string cpp_main = "#include <iostream>\n\nint main() {\n  std::cout << \"Hello World!\\n\";\n}\n";
+            if (filesystem::write(cmakelists_path, cmakelists) && filesystem::write(cpp_main_path, cpp_main)) {
+                Directories::get().open(project_path);
+                Notebook::get().open(cpp_main_path);
+                Directories::get().update();
+                Terminal::get().print("C++ project " + project_name + " created.\n");
+            } else
+                Terminal::get().print("Error: Could not create project " + project_path.string() + "\n", true);
         }
-        else
-          Terminal::get().print("Error saving file\n", true);
-      }
-    }
-  });
-  
-  menu.add_action("file_print", [this]() {
-    if(auto view=Notebook::get().get_current_view()) {
-      auto print_operation=Gtk::PrintOperation::create();
-      auto print_compositor=Gsv::PrintCompositor::create(*view);
-      
-      print_operation->set_job_name(view->file_path.filename().string());
-      print_compositor->set_wrap_mode(Gtk::WrapMode::WRAP_WORD_CHAR);
-      
-      print_operation->signal_begin_print().connect([print_operation, print_compositor](const Glib::RefPtr<Gtk::PrintContext>& print_context) {
-        while(!print_compositor->paginate(print_context));
-        print_operation->set_n_pages(print_compositor->get_n_pages());
-      });
-      print_operation->signal_draw_page().connect([print_compositor](const Glib::RefPtr<Gtk::PrintContext>& print_context, int page_nr) {
-        print_compositor->draw_page(print_context, page_nr);
-      });
-      
-      print_operation->run(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG, *this);
-    }
-  });
-  
-  menu.add_action("edit_undo", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      auto undo_manager = view->get_source_buffer()->get_undo_manager();
-      if (undo_manager->can_undo()) {
-        view->disable_spellcheck=true;
-        undo_manager->undo();
-        view->disable_spellcheck=false;
-        view->hide_tooltips();
-        view->scroll_to(view->get_buffer()->get_insert());
-      }
-    }
-  });
-  menu.add_action("edit_redo", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      auto undo_manager = view->get_source_buffer()->get_undo_manager();
-      if(undo_manager->can_redo()) {
-        view->disable_spellcheck=true;
-        undo_manager->redo();
-        view->disable_spellcheck=false;
-        view->hide_tooltips();
-        view->scroll_to(view->get_buffer()->get_insert());
-      }
-    }
-  });
-  
-  menu.add_action("edit_cut", [this]() {
-    // Return if a shown tooltip has selected text
-    for(auto tooltip: Tooltips::shown_tooltips) {
-      auto buffer=tooltip->text_buffer;
-      if(buffer && buffer->get_has_selection())
-        return;
-    }
-    
-    auto widget=get_focus();
-    if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
-      entry->cut_clipboard();
-    else if(auto view=dynamic_cast<Gtk::TextView*>(widget)) {
-      if(!view->get_editable())
-        return;
-      auto source_view=dynamic_cast<Source::View*>(view);
-      if(source_view)
-        source_view->disable_spellcheck=true;
-      if(!view->get_buffer()->get_has_selection()) {
-        auto start=view->get_buffer()->get_iter_at_line(view->get_buffer()->get_insert()->get_iter().get_line());
-        auto end=start;
-        if(!end.ends_line())
-          end.forward_to_line_end();
-        end.forward_char();
-        if(!end.starts_line()) // In case of \r\n
-          end.forward_char();
-        Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
-        view->get_buffer()->erase(start, end);
-      }
-      else
-        view->get_buffer()->cut_clipboard(Gtk::Clipboard::get());
-      if(source_view)
-        source_view->disable_spellcheck=false;
-    }
-  });
-  menu.add_action("edit_copy", [this]() {
-    // Copy from a tooltip if it has selected text
-    for(auto tooltip: Tooltips::shown_tooltips) {
-      auto buffer=tooltip->text_buffer;
-      if(buffer && buffer->get_has_selection()) {
-        buffer->copy_clipboard(Gtk::Clipboard::get());
-        return;
-      }
-    }
-    
-    auto widget=get_focus();
-    if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
-      entry->copy_clipboard();
-    else if(auto view=dynamic_cast<Gtk::TextView*>(widget)) {
-      if(!view->get_buffer()->get_has_selection()) {
-        auto start=view->get_buffer()->get_iter_at_line(view->get_buffer()->get_insert()->get_iter().get_line());
-        auto end=start;
-        if(!end.ends_line())
-          end.forward_to_line_end();
-        end.forward_char();
-        if(!end.starts_line()) // In case of \r\n
-          end.forward_char();
-        Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
-      }
-      else
-        view->get_buffer()->copy_clipboard(Gtk::Clipboard::get());
-    }
-  });
-  menu.add_action("edit_paste", [this]() {
-    auto widget=get_focus();
-    if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
-      entry->paste_clipboard();
-    else if(auto view=dynamic_cast<Gtk::TextView*>(widget)) {
-      auto source_view=dynamic_cast<Source::View*>(view);
-      if(source_view) {
-        source_view->disable_spellcheck=true;
-        source_view->paste();
-        source_view->disable_spellcheck=false;
-        source_view->hide_tooltips();
-      }
-      else if(view->get_editable())
-        view->get_buffer()->paste_clipboard(Gtk::Clipboard::get());
-    }
-  });
-  
-  menu.add_action("edit_find", [this]() {
-    search_and_replace_entry();
-  });
-  
-  menu.add_action("source_spellcheck", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      view->remove_spellcheck_errors();
-      view->spellcheck();
-    }
-  });
-  menu.add_action("source_spellcheck_clear", []() {
-    if(auto view=Notebook::get().get_current_view())
-      view->remove_spellcheck_errors();
-  });
-  menu.add_action("source_spellcheck_next_error", []() {
-    if(auto view=Notebook::get().get_current_view())
-      view->goto_next_spellcheck_error();
-  });
-  
-  menu.add_action("source_git_next_diff", []() {
-    if(auto view=Notebook::get().get_current_view())
-      view->git_goto_next_diff();
-  });
-  menu.add_action("source_git_show_diff", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      auto diff_details=view->git_get_diff_details();
-      if(diff_details.empty())
-        return;
-      std::string postfix;
-      if(diff_details.size()>2) {
-        size_t pos=diff_details.find("@@", 2);
-        if(pos!=std::string::npos)
-          postfix=diff_details.substr(0, pos+2);
-      }
-      Notebook::get().open(view->file_path.string()+postfix+".diff");
-      if(auto new_view=Notebook::get().get_current_view()) {
-        if(new_view->get_buffer()->get_text().empty()) {
-          new_view->get_source_buffer()->begin_not_undoable_action();
-          new_view->get_buffer()->set_text(diff_details);
-          new_view->get_source_buffer()->end_not_undoable_action();
-          new_view->get_buffer()->set_modified(false);
+    });
+
+    menu.add_action("file_open_file", []() {
+        auto folder_path = Notebook::get().get_current_folder();
+        if (auto view = Notebook::get().get_current_view()) {
+            if (!Directories::get().path.empty() && !filesystem::file_in_path(view->file_path, Directories::get().path))
+                folder_path = view->file_path.parent_path();
         }
-      }
-    }
-  });
-  
-  menu.add_action("source_indentation_set_buffer_tab", [this]() {
-    set_tab_entry();
-  });
-  menu.add_action("source_indentation_auto_indent_buffer", []() {
-    auto view=Notebook::get().get_current_view();
-    if(view && view->format_style) {
-      view->disable_spellcheck=true;
-      view->format_style(true);
-      view->disable_spellcheck=false;
-      view->hide_tooltips();
-    }
-  });
-  
-  menu.add_action("source_goto_line", [this]() {
-    goto_line_entry();
-  });
-  menu.add_action("source_center_cursor", []() {
-    if(auto view=Notebook::get().get_current_view())
-      view->scroll_to_cursor_delayed(view, true, false);
-  });
-  menu.add_action("source_cursor_history_back", []() {
-    if(Notebook::get().cursor_locations.size()==0)
-      return;
-    if(Notebook::get().current_cursor_location==static_cast<size_t>(-1))
-      Notebook::get().current_cursor_location=Notebook::get().cursor_locations.size()-1;
-    
-    auto cursor_location=&Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
-    // Move to current position if current position's view is not current view
-    // (in case one is looking at a new file but has not yet placed the cursor within the file)
-    if(cursor_location->view!=Notebook::get().get_current_view())
-      Notebook::get().open(cursor_location->view->file_path);
-    else {
-      if(Notebook::get().cursor_locations.size()<=1)
-        return;
-      if(Notebook::get().current_cursor_location==0)
-        return;
-      
-      --Notebook::get().current_cursor_location;
-      cursor_location=&Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
-      if(Notebook::get().get_current_view()!=cursor_location->view)
-        Notebook::get().open(cursor_location->view->file_path);
-    }
-    Notebook::get().disable_next_update_cursor_locations=true;
-    cursor_location->view->get_buffer()->place_cursor(cursor_location->mark->get_iter());
-    cursor_location->view->scroll_to_cursor_delayed(cursor_location->view, true, false);
-  });
-  menu.add_action("source_cursor_history_forward", []() {
-    if(Notebook::get().cursor_locations.size()<=1)
-      return;
-    if(Notebook::get().current_cursor_location==static_cast<size_t>(-1))
-      Notebook::get().current_cursor_location=Notebook::get().cursor_locations.size()-1;
-    if(Notebook::get().current_cursor_location==Notebook::get().cursor_locations.size()-1)
-      return;
-    
-    ++Notebook::get().current_cursor_location;
-    auto &cursor_location=Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
-    if(Notebook::get().get_current_view()!=cursor_location.view)
-      Notebook::get().open(cursor_location.view->file_path);
-    Notebook::get().disable_next_update_cursor_locations=true;
-    cursor_location.view->get_buffer()->place_cursor(cursor_location.mark->get_iter());
-    cursor_location.view->scroll_to_cursor_delayed(cursor_location.view, true, false);
-  });
-  
-  menu.add_action("source_show_completion", [] {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->non_interactive_completion)
-        view->non_interactive_completion();
-      else
-        g_signal_emit_by_name(view->gobj(), "show-completion");
-    }
-  });
-  
-  menu.add_action("source_find_symbol", []() {
-    auto project=Project::create();
-    project->show_symbols();
-  });
-  
-  menu.add_action("source_find_file", []() {
-    auto view = Notebook::get().get_current_view();
-
-    boost::filesystem::path search_path;
-    if(view)
-      search_path=view->file_path.parent_path();
-    else if(!Directories::get().path.empty())
-      search_path=Directories::get().path;
-    else {
-      boost::system::error_code ec;
-      search_path=boost::filesystem::current_path(ec);
-      if(ec) {
-        Terminal::get().print("Error: could not find current path\n", true);
-        return;
-      }
-    }
-    auto build=Project::Build::create(search_path);
-    auto project_path=build->project_path;
-    boost::filesystem::path default_path, debug_path;
-    if(!project_path.empty()) {
-      search_path=project_path;
-      default_path = build->get_default_path();
-      debug_path = build->get_debug_path();
-    }
-  
-    if(view) {
-      auto dialog_iter=view->get_iter_for_dialog();
-      SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-    }
-    else
-      SelectionDialog::create(true, true);
-    
-    std::unordered_set<std::string> buffer_paths;
-    for(auto view: Notebook::get().get_views())
-      buffer_paths.emplace(view->file_path.string());
-    
-    std::vector<boost::filesystem::path> paths;
-    // populate with all files in search_path
-    for (boost::filesystem::recursive_directory_iterator iter(search_path), end; iter != end; iter++) {
-      auto path = iter->path();
-      // ignore folders
-      if (!boost::filesystem::is_regular_file(path)) {
-        if(path==default_path || path==debug_path || path.filename()==".git")
-          iter.no_push();
-        continue;
-      }
-        
-      // remove project base path
-      auto row_str = filesystem::get_relative_path(path, search_path).string();
-      if(buffer_paths.count(path.string()))
-        row_str="<b>"+row_str+"</b>";
-      paths.emplace_back(path);
-      SelectionDialog::get()->add_row(row_str);
-    }
-    
-    if(paths.empty()) {
-      Info::get().print("No files found in current project");
-      return;
-    }
-  
-    SelectionDialog::get()->on_select=[paths=std::move(paths)](unsigned int index, const std::string &text, bool hide_window) {
-      if(index>=paths.size())
-        return;
-      Notebook::get().open(paths[index]);
-      if (auto view=Notebook::get().get_current_view())
-        view->hide_tooltips();
-    };
-  
-    if(view)
-      view->hide_tooltips();
-    SelectionDialog::get()->show();
-  
-  });
-  
-  menu.add_action("source_comments_toggle", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->toggle_comments) {
-        view->toggle_comments();
-      }
-    }
-  });
-  menu.add_action("source_comments_add_documentation", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_documentation_template) {
-        auto documentation_template=view->get_documentation_template();
-        auto offset=std::get<0>(documentation_template);
-        if(offset) {
-          if(!boost::filesystem::is_regular_file(offset.file_path))
+        auto path = Dialog::open_file(folder_path);
+        if (path != "")
+            Notebook::get().open(path);
+    });
+    menu.add_action("file_open_folder", []() {
+        auto path = Dialog::open_folder(Notebook::get().get_current_folder());
+        if (path != "" && boost::filesystem::exists(path))
+            Directories::get().open(path);
+    });
+
+    menu.add_action("file_reload_file", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (boost::filesystem::exists(view->file_path)) {
+                std::ifstream can_read(view->file_path.string());
+                if (!can_read) {
+                    Terminal::get().print("Error: could not read " + view->file_path.string() + "\n", true);
+                    return;
+                }
+                can_read.close();
+            } else {
+                Terminal::get().print("Error: " + view->file_path.string() + " does not exist\n", true);
+                return;
+            }
+
+            if (view->load())
+                view->full_reparse();
+        }
+    });
+
+    menu.add_action("file_save", [this]() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (Notebook::get().save_current()) {
+                if (view->file_path == Config::get().home_juci_path / "config" / "config.json") {
+                    configure();
+                    for (size_t c = 0; c < Notebook::get().size(); c++) {
+                        Notebook::get().get_view(c)->configure();
+                        Notebook::get().configure(c);
+                    }
+                }
+            }
+        }
+    });
+    menu.add_action("file_save_as", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            auto path = Dialog::save_file_as(view->file_path);
+            if (path != "") {
+                std::ofstream file(path, std::ofstream::binary);
+                if (file) {
+                    file << view->get_buffer()->get_text().raw();
+                    file.close();
+                    if (Directories::get().path != "")
+                        Directories::get().update();
+                    Notebook::get().open(path);
+                    Terminal::get().print(
+                            "File saved to: " + Notebook::get().get_current_view()->file_path.string() + "\n");
+                } else
+                    Terminal::get().print("Error saving file\n", true);
+            }
+        }
+    });
+
+    menu.add_action("file_print", [this]() {
+        if (auto view = Notebook::get().get_current_view()) {
+            auto print_operation = Gtk::PrintOperation::create();
+            auto print_compositor = Gsv::PrintCompositor::create(*view);
+
+            print_operation->set_job_name(view->file_path.filename().string());
+            print_compositor->set_wrap_mode(Gtk::WrapMode::WRAP_WORD_CHAR);
+
+            print_operation->signal_begin_print().connect(
+                    [print_operation, print_compositor](const Glib::RefPtr<Gtk::PrintContext> &print_context) {
+                        while (!print_compositor->paginate(print_context));
+                        print_operation->set_n_pages(print_compositor->get_n_pages());
+                    });
+            print_operation->signal_draw_page().connect(
+                    [print_compositor](const Glib::RefPtr<Gtk::PrintContext> &print_context, int page_nr) {
+                        print_compositor->draw_page(print_context, page_nr);
+                    });
+
+            print_operation->run(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG, *this);
+        }
+    });
+
+    menu.add_action("edit_undo", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            auto undo_manager = view->get_source_buffer()->get_undo_manager();
+            if (undo_manager->can_undo()) {
+                view->disable_spellcheck = true;
+                undo_manager->undo();
+                view->disable_spellcheck = false;
+                view->scroll_to(view->get_buffer()->get_insert());
+            }
+        }
+    });
+    menu.add_action("edit_redo", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            auto undo_manager = view->get_source_buffer()->get_undo_manager();
+            if (undo_manager->can_redo()) {
+                view->disable_spellcheck = true;
+                undo_manager->redo();
+                view->disable_spellcheck = false;
+                view->scroll_to(view->get_buffer()->get_insert());
+            }
+        }
+    });
+
+    menu.add_action("edit_cut", [this]() {
+        // Return if a shown tooltip has selected text
+        for (auto tooltip: Tooltips::shown_tooltips) {
+            auto buffer = tooltip->text_buffer;
+            if (buffer && buffer->get_has_selection())
+                return;
+        }
+
+        auto widget = get_focus();
+        if (auto entry = dynamic_cast<Gtk::Entry *>(widget))
+            entry->cut_clipboard();
+        else if (auto view = dynamic_cast<Gtk::TextView *>(widget)) {
+            if (!view->get_editable())
+                return;
+            auto source_view = dynamic_cast<Source::View *>(view);
+            if (source_view)
+                source_view->disable_spellcheck = true;
+            if (!view->get_buffer()->get_has_selection()) {
+                auto start = view->get_buffer()->get_iter_at_line(
+                        view->get_buffer()->get_insert()->get_iter().get_line());
+                auto end = start;
+                if (!end.ends_line())
+                    end.forward_to_line_end();
+                end.forward_char();
+                if (!end.starts_line()) // In case of \r\n
+                    end.forward_char();
+                Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
+                view->get_buffer()->erase(start, end);
+            } else
+                view->get_buffer()->cut_clipboard(Gtk::Clipboard::get());
+            if (source_view)
+                source_view->disable_spellcheck = false;
+        }
+    });
+    menu.add_action("edit_copy", [this]() {
+        // Copy from a tooltip if it has selected text
+        for (auto tooltip: Tooltips::shown_tooltips) {
+            auto buffer = tooltip->text_buffer;
+            if (buffer && buffer->get_has_selection()) {
+                buffer->copy_clipboard(Gtk::Clipboard::get());
+                return;
+            }
+        }
+
+        auto widget = get_focus();
+        if (auto entry = dynamic_cast<Gtk::Entry *>(widget))
+            entry->copy_clipboard();
+        else if (auto view = dynamic_cast<Gtk::TextView *>(widget)) {
+            if (!view->get_buffer()->get_has_selection()) {
+                auto start = view->get_buffer()->get_iter_at_line(
+                        view->get_buffer()->get_insert()->get_iter().get_line());
+                auto end = start;
+                if (!end.ends_line())
+                    end.forward_to_line_end();
+                end.forward_char();
+                if (!end.starts_line()) // In case of \r\n
+                    end.forward_char();
+                Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
+            } else
+                view->get_buffer()->copy_clipboard(Gtk::Clipboard::get());
+        }
+    });
+    menu.add_action("edit_paste", [this]() {
+        auto widget = get_focus();
+        if (auto entry = dynamic_cast<Gtk::Entry *>(widget))
+            entry->paste_clipboard();
+        else if (auto view = dynamic_cast<Gtk::TextView *>(widget)) {
+            auto source_view = dynamic_cast<Source::View *>(view);
+            if (source_view) {
+                source_view->disable_spellcheck = true;
+                source_view->paste();
+                source_view->disable_spellcheck = false;
+            } else if (view->get_editable())
+                view->get_buffer()->paste_clipboard(Gtk::Clipboard::get());
+        }
+    });
+
+    menu.add_action("edit_find", [this]() {
+        search_and_replace_entry();
+    });
+
+    menu.add_action("source_spellcheck", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            view->remove_spellcheck_errors();
+            view->spellcheck();
+        }
+    });
+    menu.add_action("source_spellcheck_clear", []() {
+        if (auto view = Notebook::get().get_current_view())
+            view->remove_spellcheck_errors();
+    });
+    menu.add_action("source_spellcheck_next_error", []() {
+        if (auto view = Notebook::get().get_current_view())
+            view->goto_next_spellcheck_error();
+    });
+
+    menu.add_action("source_git_next_diff", []() {
+        if (auto view = Notebook::get().get_current_view())
+            view->git_goto_next_diff();
+    });
+    menu.add_action("source_git_show_diff", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            auto diff_details = view->git_get_diff_details();
+            if (diff_details.empty())
+                return;
+            std::string postfix;
+            if (diff_details.size() > 2) {
+                size_t pos = diff_details.find("@@", 2);
+                if (pos != std::string::npos)
+                    postfix = diff_details.substr(0, pos + 2);
+            }
+            Notebook::get().open(view->file_path.string() + postfix + ".diff");
+            if (auto new_view = Notebook::get().get_current_view()) {
+                if (new_view->get_buffer()->get_text().empty()) {
+                    new_view->get_source_buffer()->begin_not_undoable_action();
+                    new_view->get_buffer()->set_text(diff_details);
+                    new_view->get_source_buffer()->end_not_undoable_action();
+                    new_view->get_buffer()->set_modified(false);
+                }
+            }
+        }
+    });
+
+    menu.add_action("source_indentation_set_buffer_tab", [this]() {
+        set_tab_entry();
+    });
+    menu.add_action("source_indentation_auto_indent_buffer", []() {
+        auto view = Notebook::get().get_current_view();
+        if (view && view->format_style) {
+            view->disable_spellcheck = true;
+            view->format_style(true);
+            view->disable_spellcheck = false;
+        }
+    });
+
+    menu.add_action("source_goto_line", [this]() {
+        goto_line_entry();
+    });
+    menu.add_action("source_center_cursor", []() {
+        if (auto view = Notebook::get().get_current_view())
+            view->scroll_to_cursor_delayed(view, true, false);
+    });
+    menu.add_action("source_cursor_history_back", []() {
+        if (Notebook::get().cursor_locations.size() == 0)
             return;
-          Notebook::get().open(offset.file_path);
-          auto view=Notebook::get().get_current_view();
-          auto iter=view->get_iter_at_line_pos(offset.line, offset.index);
-          view->get_buffer()->insert(iter, std::get<1>(documentation_template));
-          iter=view->get_iter_at_line_pos(offset.line, offset.index);
-          iter.forward_chars(std::get<2>(documentation_template));
-          view->get_buffer()->place_cursor(iter);
-          view->scroll_to_cursor_delayed(view, true, false);
+        if (Notebook::get().current_cursor_location == static_cast<size_t>(-1))
+            Notebook::get().current_cursor_location = Notebook::get().cursor_locations.size() - 1;
+
+        auto cursor_location = &Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
+        // Move to current position if current position's view is not current view
+        // (in case one is looking at a new file but has not yet placed the cursor within the file)
+        if (cursor_location->view != Notebook::get().get_current_view())
+            Notebook::get().open(cursor_location->view->file_path);
+        else {
+            if (Notebook::get().cursor_locations.size() <= 1)
+                return;
+            if (Notebook::get().current_cursor_location == 0)
+                return;
+
+            --Notebook::get().current_cursor_location;
+            cursor_location = &Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
+            if (Notebook::get().get_current_view() != cursor_location->view)
+                Notebook::get().open(cursor_location->view->file_path);
         }
-      }
-    }
-  });
-  menu.add_action("source_find_documentation", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_token_data) {
-        auto data=view->get_token_data();
-        std::string url;
-        if(data.size()==1)
-          url=data[0];
-        else if(data.size()>1) {
-          auto documentation_search=Config::get().source.documentation_searches.find(data[0]);
-          if(documentation_search!=Config::get().source.documentation_searches.end()) {
-            std::string token_query;
-            for(size_t c=1;c<data.size();c++) {
-              if(data[c].size()>0) {
-                if(token_query.size()>0)
-                  token_query+=documentation_search->second.separator;
-                token_query+=data[c];
-              }
+        Notebook::get().disable_next_update_cursor_locations = true;
+        cursor_location->view->get_buffer()->place_cursor(cursor_location->mark->get_iter());
+        cursor_location->view->scroll_to_cursor_delayed(cursor_location->view, true, false);
+    });
+    menu.add_action("source_cursor_history_forward", []() {
+        if (Notebook::get().cursor_locations.size() <= 1)
+            return;
+        if (Notebook::get().current_cursor_location == static_cast<size_t>(-1))
+            Notebook::get().current_cursor_location = Notebook::get().cursor_locations.size() - 1;
+        if (Notebook::get().current_cursor_location == Notebook::get().cursor_locations.size() - 1)
+            return;
+
+        ++Notebook::get().current_cursor_location;
+        auto &cursor_location = Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
+        if (Notebook::get().get_current_view() != cursor_location.view)
+            Notebook::get().open(cursor_location.view->file_path);
+        Notebook::get().disable_next_update_cursor_locations = true;
+        cursor_location.view->get_buffer()->place_cursor(cursor_location.mark->get_iter());
+        cursor_location.view->scroll_to_cursor_delayed(cursor_location.view, true, false);
+    });
+
+    menu.add_action("source_show_completion", [] {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->non_interactive_completion)
+                view->non_interactive_completion();
+            else
+                g_signal_emit_by_name(view->gobj(), "show-completion");
+        }
+    });
+
+    menu.add_action("source_find_symbol", []() {
+        auto project = Project::create();
+        project->show_symbols();
+    });
+
+    menu.add_action("source_find_file", []() {
+        auto view = Notebook::get().get_current_view();
+
+        boost::filesystem::path search_path;
+        if (view)
+            search_path = view->file_path.parent_path();
+        else if (!Directories::get().path.empty())
+            search_path = Directories::get().path;
+        else {
+            boost::system::error_code ec;
+            search_path = boost::filesystem::current_path(ec);
+            if (ec) {
+                Terminal::get().print("Error: could not find current path\n", true);
+                return;
             }
-            if(token_query.size()>0) {
-              std::unordered_map<std::string, std::string>::iterator query;
-              if(data[1].size()>0)
-                query=documentation_search->second.queries.find(data[1]);
-              else
-                query=documentation_search->second.queries.find("@empty");
-              if(query==documentation_search->second.queries.end())
-                query=documentation_search->second.queries.find("@any");
-              
-              if(query!=documentation_search->second.queries.end())
-                url=query->second+token_query;
+        }
+        auto build = Project::Build::create(search_path);
+        auto project_path = build->project_path;
+        boost::filesystem::path default_path, debug_path;
+        if (!project_path.empty()) {
+            search_path = project_path;
+            default_path = build->get_default_path();
+            debug_path = build->get_debug_path();
+        }
+
+        if (view) {
+            auto dialog_iter = view->get_iter_for_dialog();
+            SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+        } else
+            SelectionDialog::create(true, true);
+
+        std::unordered_set<std::string> buffer_paths;
+        for (auto view: Notebook::get().get_views())
+            buffer_paths.emplace(view->file_path.string());
+
+        std::vector<boost::filesystem::path> paths;
+        // populate with all files in search_path
+        for (boost::filesystem::recursive_directory_iterator iter(search_path), end; iter != end; iter++) {
+            auto path = iter->path();
+            // ignore folders
+            if (!boost::filesystem::is_regular_file(path)) {
+                if (path == default_path || path == debug_path || path.filename() == ".git")
+                    iter.no_push();
+                continue;
+            }
+
+            // remove project base path
+            auto row_str = filesystem::get_relative_path(path, search_path).string();
+            if (buffer_paths.count(path.string()))
+                row_str = "<b>" + row_str + "</b>";
+            paths.emplace_back(path);
+            SelectionDialog::get()->add_row(row_str);
+        }
+
+        if (paths.empty()) {
+            Info::get().print("No files found in current project");
+            return;
+        }
+
+        SelectionDialog::get()->on_select = [paths = std::move(paths)](unsigned int index, const std::string &text,
+                                                                       bool hide_window) {
+            if (index >= paths.size())
+                return;
+            Notebook::get().open(paths[index]);
+            if (auto view = Notebook::get().get_current_view())
+                view->hide_tooltips();
+        };
+
+        if (view)
+            view->hide_tooltips();
+        SelectionDialog::get()->show();
+
+    });
+
+    menu.add_action("source_comments_toggle", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->toggle_comments) {
+                view->toggle_comments();
             }
-          }
         }
-        if(!url.empty()) {
+    });
+    menu.add_action("source_comments_add_documentation", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_documentation_template) {
+                auto documentation_template = view->get_documentation_template();
+                auto offset = std::get<0>(documentation_template);
+                if (offset) {
+                    if (!boost::filesystem::is_regular_file(offset.file_path))
+                        return;
+                    Notebook::get().open(offset.file_path);
+                    auto view = Notebook::get().get_current_view();
+                    auto iter = view->get_iter_at_line_pos(offset.line, offset.index);
+                    view->get_buffer()->insert(iter, std::get<1>(documentation_template));
+                    iter = view->get_iter_at_line_pos(offset.line, offset.index);
+                    iter.forward_chars(std::get<2>(documentation_template));
+                    view->get_buffer()->place_cursor(iter);
+                    view->scroll_to_cursor_delayed(view, true, false);
+                }
+            }
+        }
+    });
+    menu.add_action("source_find_documentation", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_token_data) {
+                auto data = view->get_token_data();
+                std::string url;
+                if (data.size() == 1)
+                    url = data[0];
+                else if (data.size() > 1) {
+                    auto documentation_search = Config::get().source.documentation_searches.find(data[0]);
+                    if (documentation_search != Config::get().source.documentation_searches.end()) {
+                        std::string token_query;
+                        for (size_t c = 1; c < data.size(); c++) {
+                            if (data[c].size() > 0) {
+                                if (token_query.size() > 0)
+                                    token_query += documentation_search->second.separator;
+                                token_query += data[c];
+                            }
+                        }
+                        if (token_query.size() > 0) {
+                            std::unordered_map<std::string, std::string>::iterator query;
+                            if (data[1].size() > 0)
+                                query = documentation_search->second.queries.find(data[1]);
+                            else
+                                query = documentation_search->second.queries.find("@empty");
+                            if (query == documentation_search->second.queries.end())
+                                query = documentation_search->second.queries.find("@any");
+
+                            if (query != documentation_search->second.queries.end())
+                                url = query->second + token_query;
+                        }
+                    }
+                }
+                if (!url.empty()) {
 #ifdef __APPLE__
-          Terminal::get().process("open \""+url+"\"");
+                    Terminal::get().process("open \""+url+"\"");
 #else
-          GError* error=nullptr;
+                    GError *error = nullptr;
 #if GTK_VERSION_GE(3, 22)
-          gtk_show_uri_on_window(nullptr, url.c_str(), GDK_CURRENT_TIME, &error);
+                    gtk_show_uri_on_window(nullptr, url.c_str(), GDK_CURRENT_TIME, &error);
 #else
-          gtk_show_uri(nullptr, url.c_str(), GDK_CURRENT_TIME, &error);
+                    gtk_show_uri(nullptr, url.c_str(), GDK_CURRENT_TIME, &error);
 #endif
-          g_clear_error(&error);
+                    g_clear_error(&error);
 #endif
+                }
+            }
         }
-      }
-    }
-  });
-  
-  menu.add_action("source_goto_declaration", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_declaration_location) {
-        auto location=view->get_declaration_location();
-        if(location) {
-          if(!boost::filesystem::is_regular_file(location.file_path))
-            return;
-          Notebook::get().open(location.file_path);
-          auto view=Notebook::get().get_current_view();
-          auto line=static_cast<int>(location.line);
-          auto index=static_cast<int>(location.index);
-          view->place_cursor_at_line_pos(line, index);
-          view->scroll_to_cursor_delayed(view, true, false);
+    });
+
+    menu.add_action("source_goto_declaration", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_declaration_location) {
+                auto location = view->get_declaration_location();
+                if (location) {
+                    if (!boost::filesystem::is_regular_file(location.file_path))
+                        return;
+                    Notebook::get().open(location.file_path);
+                    auto view = Notebook::get().get_current_view();
+                    auto line = static_cast<int>(location.line);
+                    auto index = static_cast<int>(location.index);
+                    view->place_cursor_at_line_pos(line, index);
+                    view->scroll_to_cursor_delayed(view, true, false);
+                }
+            }
         }
-      }
-    }
-  });
-  menu.add_action("source_goto_type_declaration", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_type_declaration_location) {
-        auto location=view->get_type_declaration_location();
-        if(location) {
-          if(!boost::filesystem::is_regular_file(location.file_path))
-            return;
-          Notebook::get().open(location.file_path);
-          auto view=Notebook::get().get_current_view();
-          auto line=static_cast<int>(location.line);
-          auto index=static_cast<int>(location.index);
-          view->place_cursor_at_line_pos(line, index);
-          view->scroll_to_cursor_delayed(view, true, false);
+    });
+    menu.add_action("source_goto_type_declaration", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_type_declaration_location) {
+                auto location = view->get_type_declaration_location();
+                if (location) {
+                    if (!boost::filesystem::is_regular_file(location.file_path))
+                        return;
+                    Notebook::get().open(location.file_path);
+                    auto view = Notebook::get().get_current_view();
+                    auto line = static_cast<int>(location.line);
+                    auto index = static_cast<int>(location.index);
+                    view->place_cursor_at_line_pos(line, index);
+                    view->scroll_to_cursor_delayed(view, true, false);
+                }
+            }
         }
-      }
-    }
-  });
-  auto goto_selected_location=[](Source::View *view, const std::vector<Source::Offset> &locations) {
-    if(!locations.empty()) {
-      auto dialog_iter=view->get_iter_for_dialog();
-      SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-      std::vector<Source::Offset> rows;
-      auto project_path=Project::Build::create(view->file_path)->project_path;
-      if(project_path.empty()) {
-        if(!Directories::get().path.empty())
-          project_path=Directories::get().path;
-        else
-          project_path=view->file_path.parent_path();
-      }
-      for(auto &location: locations) {
-        auto path=filesystem::get_relative_path(filesystem::get_normal_path(location.file_path), project_path);
-        if(path.empty())
-          path=location.file_path.filename();
-        auto row=path.string()+":"+std::to_string(location.line+1);
-        rows.emplace_back(location);
-        SelectionDialog::get()->add_row(row);
-      }
-      
-      if(rows.size()==0)
-        return;
-      else if(rows.size()==1) {
-        auto location=*rows.begin();
-        if(!boost::filesystem::is_regular_file(location.file_path))
-          return;
-        Notebook::get().open(location.file_path);
-        auto view=Notebook::get().get_current_view();
-        auto line=static_cast<int>(location.line);
-        auto index=static_cast<int>(location.index);
-        view->place_cursor_at_line_pos(line, index);
-        view->scroll_to_cursor_delayed(view, true, false);
-        return;
-      }
-      SelectionDialog::get()->on_select=[rows=std::move(rows)](unsigned int index, const std::string &text, bool hide_window) {
-        if(index>=rows.size())
-          return;
-        auto location=rows[index];
-        if(!boost::filesystem::is_regular_file(location.file_path))
-          return;
-        Notebook::get().open(location.file_path);
-        auto view=Notebook::get().get_current_view();
-        view->place_cursor_at_line_pos(location.line, location.index);
-        view->scroll_to_cursor_delayed(view, true, false);
-        view->hide_tooltips();
-      };
-      view->hide_tooltips();
-      SelectionDialog::get()->show();
-    }
-  };
-  menu.add_action("source_goto_implementation", [goto_selected_location]() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_implementation_locations)
-        goto_selected_location(view, view->get_implementation_locations());
-    }
-  });
-  menu.add_action("source_goto_declaration_or_implementation", [goto_selected_location]() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_declaration_or_implementation_locations)
-        goto_selected_location(view, view->get_declaration_or_implementation_locations());
-    }
-  });
-
-  menu.add_action("source_goto_usage", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_usages) {
-        auto usages=view->get_usages();
-        if(!usages.empty()) {
-          auto dialog_iter=view->get_iter_for_dialog();
-          SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-          std::vector<Source::Offset> rows;
-          
-          auto iter=view->get_buffer()->get_insert()->get_iter();
-          for(auto &usage: usages) {
-            std::string row;
-            bool current_page=true;
-            //add file name if usage is not in current page
-            if(view->file_path!=usage.first.file_path) {
-              row=usage.first.file_path.filename().string()+":";
-              current_page=false;
+    });
+    auto goto_selected_location = [](Source::View *view, const std::vector<Source::Offset> &locations) {
+        if (!locations.empty()) {
+            auto dialog_iter = view->get_iter_for_dialog();
+            SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+            std::vector<Source::Offset> rows;
+            auto project_path = Project::Build::create(view->file_path)->project_path;
+            if (project_path.empty()) {
+                if (!Directories::get().path.empty())
+                    project_path = Directories::get().path;
+                else
+                    project_path = view->file_path.parent_path();
             }
-            row+=std::to_string(usage.first.line+1)+": "+usage.second;
-            rows.emplace_back(usage.first);
-            SelectionDialog::get()->add_row(row);
-            
-            //Set dialog cursor to the last row if the textview cursor is at the same line
-            if(current_page &&
-               iter.get_line()==static_cast<int>(usage.first.line) && iter.get_line_index()>=static_cast<int>(usage.first.index)) {
-              SelectionDialog::get()->set_cursor_at_last_row();
+            for (auto &location: locations) {
+                auto path = filesystem::get_relative_path(filesystem::get_normal_path(location.file_path),
+                                                          project_path);
+                if (path.empty())
+                    path = location.file_path.filename();
+                auto row = path.string() + ":" + std::to_string(location.line + 1);
+                rows.emplace_back(location);
+                SelectionDialog::get()->add_row(row);
             }
-          }
-          
-          if(rows.size()==0)
-            return;
-          SelectionDialog::get()->on_select=[rows=std::move(rows)](unsigned int index, const std::string &text, bool hide_window) {
-            if(index>=rows.size())
-              return;
-            auto offset=rows[index];
-            if(!boost::filesystem::is_regular_file(offset.file_path))
-              return;
-            Notebook::get().open(offset.file_path);
-            auto view=Notebook::get().get_current_view();
-            view->place_cursor_at_line_pos(offset.line, offset.index);
-            view->scroll_to_cursor_delayed(view, true, false);
+
+            if (rows.size() == 0)
+                return;
+            else if (rows.size() == 1) {
+                auto location = *rows.begin();
+                if (!boost::filesystem::is_regular_file(location.file_path))
+                    return;
+                Notebook::get().open(location.file_path);
+                auto view = Notebook::get().get_current_view();
+                auto line = static_cast<int>(location.line);
+                auto index = static_cast<int>(location.index);
+                view->place_cursor_at_line_pos(line, index);
+                view->scroll_to_cursor_delayed(view, true, false);
+                return;
+            }
+            SelectionDialog::get()->on_select = [rows = std::move(rows)](unsigned int index, const std::string &text,
+                                                                         bool hide_window) {
+                if (index >= rows.size())
+                    return;
+                auto location = rows[index];
+                if (!boost::filesystem::is_regular_file(location.file_path))
+                    return;
+                Notebook::get().open(location.file_path);
+                auto view = Notebook::get().get_current_view();
+                view->place_cursor_at_line_pos(location.line, location.index);
+                view->scroll_to_cursor_delayed(view, true, false);
+                view->hide_tooltips();
+            };
             view->hide_tooltips();
-          };
-          view->hide_tooltips();
-          SelectionDialog::get()->show();
+            SelectionDialog::get()->show();
+        }
+    };
+    menu.add_action("source_goto_implementation", [goto_selected_location]() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_implementation_locations)
+                goto_selected_location(view, view->get_implementation_locations());
+        }
+    });
+    menu.add_action("source_goto_declaration_or_implementation", [goto_selected_location]() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_declaration_or_implementation_locations)
+                goto_selected_location(view, view->get_declaration_or_implementation_locations());
+        }
+    });
+
+    menu.add_action("source_goto_usage", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_usages) {
+                auto usages = view->get_usages();
+                if (!usages.empty()) {
+                    auto dialog_iter = view->get_iter_for_dialog();
+                    SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+                    std::vector<Source::Offset> rows;
+
+                    auto iter = view->get_buffer()->get_insert()->get_iter();
+                    for (auto &usage: usages) {
+                        std::string row;
+                        bool current_page = true;
+                        //add file name if usage is not in current page
+                        if (view->file_path != usage.first.file_path) {
+                            row = usage.first.file_path.filename().string() + ":";
+                            current_page = false;
+                        }
+                        row += std::to_string(usage.first.line + 1) + ": " + usage.second;
+                        rows.emplace_back(usage.first);
+                        SelectionDialog::get()->add_row(row);
+
+                        //Set dialog cursor to the last row if the textview cursor is at the same line
+                        if (current_page &&
+                            iter.get_line() == static_cast<int>(usage.first.line) &&
+                            iter.get_line_index() >= static_cast<int>(usage.first.index)) {
+                            SelectionDialog::get()->set_cursor_at_last_row();
+                        }
+                    }
+
+                    if (rows.size() == 0)
+                        return;
+                    SelectionDialog::get()->on_select = [rows = std::move(rows)](unsigned int index,
+                                                                                 const std::string &text,
+                                                                                 bool hide_window) {
+                        if (index >= rows.size())
+                            return;
+                        auto offset = rows[index];
+                        if (!boost::filesystem::is_regular_file(offset.file_path))
+                            return;
+                        Notebook::get().open(offset.file_path);
+                        auto view = Notebook::get().get_current_view();
+                        view->place_cursor_at_line_pos(offset.line, offset.index);
+                        view->scroll_to_cursor_delayed(view, true, false);
+                        view->hide_tooltips();
+                    };
+                    view->hide_tooltips();
+                    SelectionDialog::get()->show();
+                }
+            }
+        }
+    });
+    menu.add_action("source_goto_method", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_methods) {
+                auto methods = Notebook::get().get_current_view()->get_methods();
+                if (!methods.empty()) {
+                    auto dialog_iter = view->get_iter_for_dialog();
+                    SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+                    std::vector<Source::Offset> rows;
+                    auto iter = view->get_buffer()->get_insert()->get_iter();
+                    for (auto &method: methods) {
+                        rows.emplace_back(method.first);
+                        SelectionDialog::get()->add_row(method.second);
+                        if (iter.get_line() >= static_cast<int>(method.first.line))
+                            SelectionDialog::get()->set_cursor_at_last_row();
+                    }
+                    SelectionDialog::get()->on_select = [view, rows = std::move(rows)](unsigned int index,
+                                                                                       const std::string &text,
+                                                                                       bool hide_window) {
+                        if (index >= rows.size())
+                            return;
+                        auto offset = rows[index];
+                        view->get_buffer()->place_cursor(view->get_iter_at_line_pos(offset.line, offset.index));
+                        view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+                        view->hide_tooltips();
+                    };
+                    view->hide_tooltips();
+                    SelectionDialog::get()->show();
+                }
+            }
+        }
+    });
+    menu.add_action("source_rename", [this]() {
+        rename_token_entry();
+    });
+    menu.add_action("source_implement_method", []() {
+        const static std::string button_text = "Insert Method Implementation";
+
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_method) {
+                auto iter = view->get_buffer()->get_insert()->get_iter();
+                if (!EntryBox::get().buttons.empty() && EntryBox::get().buttons.back().get_label() == button_text &&
+                    iter.ends_line() && iter.starts_line()) {
+                    EntryBox::get().buttons.back().activate();
+                    return;
+                }
+                auto method = view->get_method();
+                if (method.empty())
+                    return;
+
+                EntryBox::get().clear();
+                EntryBox::get().labels.emplace_back();
+                EntryBox::get().labels.back().set_text(method);
+                EntryBox::get().buttons.emplace_back(button_text, [method = std::move(method)]() {
+                    if (auto view = Notebook::get().get_current_view()) {
+                        view->get_buffer()->insert_at_cursor(method);
+                        EntryBox::get().clear();
+                    }
+                });
+                EntryBox::get().show();
+            }
         }
-      }
-    }
-  });
-  menu.add_action("source_goto_method", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_methods) {
-        auto methods=Notebook::get().get_current_view()->get_methods();
-        if(!methods.empty()) {
-          auto dialog_iter=view->get_iter_for_dialog();
-          SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-          std::vector<Source::Offset> rows;
-          auto iter=view->get_buffer()->get_insert()->get_iter();
-          for(auto &method: methods) {
-            rows.emplace_back(method.first);
-            SelectionDialog::get()->add_row(method.second);
-            if(iter.get_line()>=static_cast<int>(method.first.line))
-              SelectionDialog::get()->set_cursor_at_last_row();
-          }
-          SelectionDialog::get()->on_select=[view, rows=std::move(rows)](unsigned int index, const std::string &text, bool hide_window) {
-            if(index>=rows.size())
-              return;
-            auto offset=rows[index];
-            view->get_buffer()->place_cursor(view->get_iter_at_line_pos(offset.line, offset.index));
-            view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-            view->hide_tooltips();
-          };
-          view->hide_tooltips();
-          SelectionDialog::get()->show();
+    });
+
+    menu.add_action("source_goto_next_diagnostic", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->goto_next_diagnostic) {
+                view->goto_next_diagnostic();
+            }
         }
-      }
-    }
-  });
-  menu.add_action("source_rename", [this]() {
-    rename_token_entry();
-  });
-  menu.add_action("source_implement_method", []() {
-    const static std::string button_text="Insert Method Implementation";
-    
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_method) {
-        auto iter=view->get_buffer()->get_insert()->get_iter();
-        if(!EntryBox::get().buttons.empty() && EntryBox::get().buttons.back().get_label()==button_text &&
-           iter.ends_line() && iter.starts_line()) {
-          EntryBox::get().buttons.back().activate();
-          return;
+    });
+    menu.add_action("source_apply_fix_its", []() {
+        if (auto view = Notebook::get().get_current_view()) {
+            if (view->get_fix_its) {
+                auto buffer = view->get_buffer();
+                auto fix_its = view->get_fix_its();
+                std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > fix_it_marks;
+                for (auto &fix_it: fix_its) {
+                    auto start_iter = view->get_iter_at_line_pos(fix_it.offsets.first.line, fix_it.offsets.first.index);
+                    auto end_iter = view->get_iter_at_line_pos(fix_it.offsets.second.line, fix_it.offsets.second.index);
+                    fix_it_marks.emplace_back(buffer->create_mark(start_iter), buffer->create_mark(end_iter));
+                }
+                size_t c = 0;
+                buffer->begin_user_action();
+                for (auto &fix_it: fix_its) {
+                    if (fix_it.type == Source::FixIt::Type::INSERT) {
+                        buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source);
+                    }
+                    if (fix_it.type == Source::FixIt::Type::REPLACE) {
+                        buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter());
+                        buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source);
+                    }
+                    if (fix_it.type == Source::FixIt::Type::ERASE) {
+                        buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter());
+                    }
+                    c++;
+                }
+                for (auto &mark_pair: fix_it_marks) {
+                    buffer->delete_mark(mark_pair.first);
+                    buffer->delete_mark(mark_pair.second);
+                }
+                buffer->end_user_action();
+            }
         }
-        auto method=view->get_method();
-        if(method.empty())
-          return;
-        
+    });
+
+    menu.add_action("project_set_run_arguments", []() {
+        auto project = Project::create();
+        auto run_arguments = project->get_run_arguments();
+        if (run_arguments.second.empty())
+            return;
+
         EntryBox::get().clear();
         EntryBox::get().labels.emplace_back();
-        EntryBox::get().labels.back().set_text(method);
-        EntryBox::get().buttons.emplace_back(button_text, [method=std::move(method)](){
-          if(auto view=Notebook::get().get_current_view()) {
-            view->get_buffer()->insert_at_cursor(method);
-            EntryBox::get().clear();
-          }
+        auto label_it = EntryBox::get().labels.begin();
+        label_it->update = [label_it](int state, const std::string &message) {
+            label_it->set_text(
+                    "Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
+        };
+        label_it->update(0, "");
+        EntryBox::get().entries.emplace_back(run_arguments.second,
+                                             [run_arguments_first = std::move(run_arguments.first)](
+                                                     const std::string &content) {
+                                                 Project::run_arguments[run_arguments_first] = content;
+                                                 EntryBox::get().hide();
+                                             }, 50);
+        auto entry_it = EntryBox::get().entries.begin();
+        entry_it->set_placeholder_text("Project: Set Run Arguments");
+        EntryBox::get().buttons.emplace_back("Project: set run arguments", [entry_it]() {
+            entry_it->activate();
         });
         EntryBox::get().show();
-      }
-    }
-  });
-  
-  menu.add_action("source_goto_next_diagnostic", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->goto_next_diagnostic) {
-        view->goto_next_diagnostic();
-      }
-    }
-  });
-  menu.add_action("source_apply_fix_its", []() {
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->get_fix_its) {
-        auto buffer=view->get_buffer();
-        auto fix_its=view->get_fix_its();
-        std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > fix_it_marks;
-        for(auto &fix_it: fix_its) {
-          auto start_iter=view->get_iter_at_line_pos(fix_it.offsets.first.line, fix_it.offsets.first.index);
-          auto end_iter=view->get_iter_at_line_pos(fix_it.offsets.second.line, fix_it.offsets.second.index);
-          fix_it_marks.emplace_back(buffer->create_mark(start_iter), buffer->create_mark(end_iter));
+    });
+    menu.add_action("project_compile_and_run", []() {
+        if (Project::compiling || Project::debugging) {
+            Info::get().print("Compile or debug in progress");
+            return;
         }
-        size_t c=0;
-        buffer->begin_user_action();
-        for(auto &fix_it: fix_its) {
-          if(fix_it.type==Source::FixIt::Type::INSERT) {
-            buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source);
-          }
-          if(fix_it.type==Source::FixIt::Type::REPLACE) {
-            buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter());
-            buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source);
-          }
-          if(fix_it.type==Source::FixIt::Type::ERASE) {
-            buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter());
-          }
-          c++;
+
+        Project::current = Project::create();
+
+        if (Config::get().project.save_on_compile_or_run)
+            Project::save_files(Project::current->build->project_path);
+
+        Project::current->compile_and_run();
+    });
+    menu.add_action("project_compile", []() {
+        if (Project::compiling || Project::debugging) {
+            Info::get().print("Compile or debug in progress");
+            return;
         }
-        for(auto &mark_pair: fix_it_marks) {
-          buffer->delete_mark(mark_pair.first);
-          buffer->delete_mark(mark_pair.second);
+
+        Project::current = Project::create();
+
+        if (Config::get().project.save_on_compile_or_run)
+            Project::save_files(Project::current->build->project_path);
+
+        Project::current->compile();
+    });
+    menu.add_action("project_recreate_build", []() {
+        if (Project::compiling || Project::debugging) {
+            Info::get().print("Compile or debug in progress");
+            return;
         }
-        buffer->end_user_action();
-      }
-    }
-  });
-  
-  menu.add_action("project_set_run_arguments", []() {
-    auto project=Project::create();
-    auto run_arguments=project->get_run_arguments();
-    if(run_arguments.second.empty())
-      return;
-    
-    EntryBox::get().clear();
-    EntryBox::get().labels.emplace_back();
-    auto label_it=EntryBox::get().labels.begin();
-    label_it->update=[label_it](int state, const std::string& message){
-      label_it->set_text("Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
-    };
-    label_it->update(0, "");
-    EntryBox::get().entries.emplace_back(run_arguments.second, [run_arguments_first=std::move(run_arguments.first)](const std::string &content){
-      Project::run_arguments[run_arguments_first]=content;
-      EntryBox::get().hide();
-    }, 50);
-    auto entry_it=EntryBox::get().entries.begin();
-    entry_it->set_placeholder_text("Project: Set Run Arguments");
-    EntryBox::get().buttons.emplace_back("Project: set run arguments", [entry_it](){
-      entry_it->activate();
+
+        Project::current = Project::create();
+
+        Project::current->recreate_build();
     });
-    EntryBox::get().show();
-  });
-  menu.add_action("project_compile_and_run", []() {
-    if(Project::compiling || Project::debugging) {
-      Info::get().print("Compile or debug in progress");
-      return;
-    }
-    
-    Project::current=Project::create();
-    
-    if(Config::get().project.save_on_compile_or_run)
-      Project::save_files(Project::current->build->project_path);
-    
-    Project::current->compile_and_run();
-  });
-  menu.add_action("project_compile", []() {
-    if(Project::compiling || Project::debugging) {
-      Info::get().print("Compile or debug in progress");
-      return;
-    }
-            
-    Project::current=Project::create();
-    
-    if(Config::get().project.save_on_compile_or_run)
-      Project::save_files(Project::current->build->project_path);
-    
-    Project::current->compile();
-  });
-  menu.add_action("project_recreate_build", []() {
-    if(Project::compiling || Project::debugging) {
-      Info::get().print("Compile or debug in progress");
-      return;
-    }
-    
-    Project::current=Project::create();
 
-    Project::current->recreate_build();
-  });
-  
-  menu.add_action("project_run_command", [this]() {
-    EntryBox::get().clear();
-    EntryBox::get().labels.emplace_back();
-    auto label_it=EntryBox::get().labels.begin();
-    label_it->update=[label_it](int state, const std::string& message){
-      label_it->set_text("Run Command directory order: opened directory, file path, current directory");
-    };
-    label_it->update(0, "");
-    EntryBox::get().entries.emplace_back(last_run_command, [this](const std::string& content){
-      if(content!="") {
-        last_run_command=content;
-        auto run_path=Notebook::get().get_current_folder();
-        Terminal::get().async_print("Running: "+content+'\n');
-  
-        Terminal::get().async_process(content, run_path, [content](int exit_status){
-          Terminal::get().async_print(content+" returned: "+std::to_string(exit_status)+'\n');
+    menu.add_action("project_run_command", [this]() {
+        EntryBox::get().clear();
+        EntryBox::get().labels.emplace_back();
+        auto label_it = EntryBox::get().labels.begin();
+        label_it->update = [label_it](int state, const std::string &message) {
+            label_it->set_text("Run Command directory order: opened directory, file path, current directory");
+        };
+        label_it->update(0, "");
+        EntryBox::get().entries.emplace_back(last_run_command, [this](const std::string &content) {
+            if (content != "") {
+                last_run_command = content;
+                auto run_path = Notebook::get().get_current_folder();
+                Terminal::get().async_print("Running: " + content + '\n');
+
+                Terminal::get().async_process(content, run_path, [content](int exit_status) {
+                    Terminal::get().async_print(content + " returned: " + std::to_string(exit_status) + '\n');
+                });
+            }
+            EntryBox::get().hide();
+        }, 30);
+        auto entry_it = EntryBox::get().entries.begin();
+        entry_it->set_placeholder_text("Command");
+        EntryBox::get().buttons.emplace_back("Run command", [entry_it]() {
+            entry_it->activate();
         });
-      }
-      EntryBox::get().hide();
-    }, 30);
-    auto entry_it=EntryBox::get().entries.begin();
-    entry_it->set_placeholder_text("Command");
-    EntryBox::get().buttons.emplace_back("Run command", [entry_it](){
-      entry_it->activate();
+        EntryBox::get().show();
     });
-    EntryBox::get().show();
-  });
-  
-  menu.add_action("project_kill_last_running", []() {
-    Terminal::get().kill_last_async_process();
-  });
-  menu.add_action("project_force_kill_last_running", []() {
-    Terminal::get().kill_last_async_process(true);
-  });
-  
+
+    menu.add_action("project_kill_last_running", []() {
+        Terminal::get().kill_last_async_process();
+    });
+    menu.add_action("project_force_kill_last_running", []() {
+        Terminal::get().kill_last_async_process(true);
+    });
+
 #ifdef JUCI_ENABLE_DEBUG
-  menu.add_action("debug_set_run_arguments", []() {
-    auto project=Project::create();
-    auto run_arguments=project->debug_get_run_arguments();
-    if(run_arguments.second.empty())
-      return;
-    
-    EntryBox::get().clear();
-    EntryBox::get().labels.emplace_back();
-    auto label_it=EntryBox::get().labels.begin();
-    label_it->update=[label_it](int state, const std::string& message){
-      label_it->set_text("Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
-    };
-    label_it->update(0, "");
-    EntryBox::get().entries.emplace_back(run_arguments.second, [run_arguments_first=std::move(run_arguments.first)](const std::string& content){
-      Project::debug_run_arguments[run_arguments_first].arguments=content;
-      EntryBox::get().hide();
-    }, 50);
-    auto entry_it=EntryBox::get().entries.begin();
-    entry_it->set_placeholder_text("Debug: Set Run Arguments");
-    
-    if(auto options=project->debug_get_options()) {
-      EntryBox::get().buttons.emplace_back("", [options]() {
-        options->show_all();
+    menu.add_action("debug_set_run_arguments", []() {
+      auto project=Project::create();
+      auto run_arguments=project->debug_get_run_arguments();
+      if(run_arguments.second.empty())
+        return;
+
+      EntryBox::get().clear();
+      EntryBox::get().labels.emplace_back();
+      auto label_it=EntryBox::get().labels.begin();
+      label_it->update=[label_it](int state, const std::string& message){
+        label_it->set_text("Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
+      };
+      label_it->update(0, "");
+      EntryBox::get().entries.emplace_back(run_arguments.second, [run_arguments_first=std::move(run_arguments.first)](const std::string& content){
+        Project::debug_run_arguments[run_arguments_first].arguments=content;
+        EntryBox::get().hide();
+      }, 50);
+      auto entry_it=EntryBox::get().entries.begin();
+      entry_it->set_placeholder_text("Debug: Set Run Arguments");
+
+      if(auto options=project->debug_get_options()) {
+        EntryBox::get().buttons.emplace_back("", [options]() {
+          options->show_all();
+        });
+        EntryBox::get().buttons.back().set_image_from_icon_name("preferences-system");
+        EntryBox::get().buttons.back().set_always_show_image(true);
+        EntryBox::get().buttons.back().set_tooltip_text("Additional Options");
+        options->set_relative_to(EntryBox::get().buttons.back());
+      }
+
+      EntryBox::get().buttons.emplace_back("Debug: set run arguments", [entry_it](){
+        entry_it->activate();
       });
-      EntryBox::get().buttons.back().set_image_from_icon_name("preferences-system");
-      EntryBox::get().buttons.back().set_always_show_image(true);
-      EntryBox::get().buttons.back().set_tooltip_text("Additional Options");
-      options->set_relative_to(EntryBox::get().buttons.back());
-    }
-    
-    EntryBox::get().buttons.emplace_back("Debug: set run arguments", [entry_it](){
-      entry_it->activate();
+      EntryBox::get().show();
     });
-    EntryBox::get().show();
-  });
-  menu.add_action("debug_start_continue", [](){
-    if(Project::compiling) {
-      Info::get().print("Compile in progress");
-      return;
-    }
-    else if(Project::debugging) {
-      Project::current->debug_continue();
-      return;
-    }
-        
-    Project::current=Project::create();
-    
-    if(Config::get().project.save_on_compile_or_run)
-      Project::save_files(Project::current->build->project_path);
-    
-    Project::current->debug_start();
-  });
-  menu.add_action("debug_stop", []() {
-    if(Project::current)
-      Project::current->debug_stop();
-  });
-  menu.add_action("debug_kill", []() {
-    if(Project::current)
-      Project::current->debug_kill();
-  });
-  menu.add_action("debug_step_over", []() {
-    if(Project::current)
-      Project::current->debug_step_over();
-  });
-  menu.add_action("debug_step_into", []() {
-    if(Project::current)
-      Project::current->debug_step_into();
-  });
-  menu.add_action("debug_step_out", []() {
-    if(Project::current)
-      Project::current->debug_step_out();
-  });
-  menu.add_action("debug_backtrace", []() {
-    if(Project::current)
-      Project::current->debug_backtrace();
-  });
-  menu.add_action("debug_show_variables", []() {
-    if(Project::current)
-      Project::current->debug_show_variables();
-  });
-  menu.add_action("debug_run_command", [this]() {
-    EntryBox::get().clear();
-    EntryBox::get().entries.emplace_back(last_run_debug_command, [this](const std::string& content){
-      if(content!="") {
-        if(Project::current)
-          Project::current->debug_run_command(content);
-        last_run_debug_command=content;
+    menu.add_action("debug_start_continue", [](){
+      if(Project::compiling) {
+        Info::get().print("Compile in progress");
+        return;
+      }
+      else if(Project::debugging) {
+        Project::current->debug_continue();
+        return;
       }
-      EntryBox::get().hide();
-    }, 30);
-    auto entry_it=EntryBox::get().entries.begin();
-    entry_it->set_placeholder_text("Debug Command");
-    EntryBox::get().buttons.emplace_back("Run debug command", [entry_it](){
-      entry_it->activate();
+
+      Project::current=Project::create();
+
+      if(Config::get().project.save_on_compile_or_run)
+        Project::save_files(Project::current->build->project_path);
+
+      Project::current->debug_start();
     });
-    EntryBox::get().show();
-  });
-  menu.add_action("debug_toggle_breakpoint", [](){
-    if(auto view=Notebook::get().get_current_view()) {
-      if(view->toggle_breakpoint)
-        view->toggle_breakpoint(view->get_buffer()->get_insert()->get_iter().get_line());
-    }
-  });
-  menu.add_action("debug_goto_stop", [](){
-    if(Project::debugging) {
-      if(!Project::debug_stop.first.empty()) {
-        Notebook::get().open(Project::debug_stop.first);
-        if(auto view=Notebook::get().get_current_view()) {
-          int line=Project::debug_stop.second.first;
-          int index=Project::debug_stop.second.second;
-          view->place_cursor_at_line_index(line, index);
-          view->scroll_to_cursor_delayed(view, true, true);
+    menu.add_action("debug_stop", []() {
+      if(Project::current)
+        Project::current->debug_stop();
+    });
+    menu.add_action("debug_kill", []() {
+      if(Project::current)
+        Project::current->debug_kill();
+    });
+    menu.add_action("debug_step_over", []() {
+      if(Project::current)
+        Project::current->debug_step_over();
+    });
+    menu.add_action("debug_step_into", []() {
+      if(Project::current)
+        Project::current->debug_step_into();
+    });
+    menu.add_action("debug_step_out", []() {
+      if(Project::current)
+        Project::current->debug_step_out();
+    });
+    menu.add_action("debug_backtrace", []() {
+      if(Project::current)
+        Project::current->debug_backtrace();
+    });
+    menu.add_action("debug_show_variables", []() {
+      if(Project::current)
+        Project::current->debug_show_variables();
+    });
+    menu.add_action("debug_run_command", [this]() {
+      EntryBox::get().clear();
+      EntryBox::get().entries.emplace_back(last_run_debug_command, [this](const std::string& content){
+        if(content!="") {
+          if(Project::current)
+            Project::current->debug_run_command(content);
+          last_run_debug_command=content;
+        }
+        EntryBox::get().hide();
+      }, 30);
+      auto entry_it=EntryBox::get().entries.begin();
+      entry_it->set_placeholder_text("Debug Command");
+      EntryBox::get().buttons.emplace_back("Run debug command", [entry_it](){
+        entry_it->activate();
+      });
+      EntryBox::get().show();
+    });
+    menu.add_action("debug_toggle_breakpoint", [](){
+      if(auto view=Notebook::get().get_current_view()) {
+        if(view->toggle_breakpoint)
+          view->toggle_breakpoint(view->get_buffer()->get_insert()->get_iter().get_line());
+      }
+    });
+    menu.add_action("debug_goto_stop", [](){
+      if(Project::debugging) {
+        if(!Project::debug_stop.first.empty()) {
+          Notebook::get().open(Project::debug_stop.first);
+          if(auto view=Notebook::get().get_current_view()) {
+            int line=Project::debug_stop.second.first;
+            int index=Project::debug_stop.second.second;
+            view->place_cursor_at_line_index(line, index);
+            view->scroll_to_cursor_delayed(view, true, true);
+          }
         }
       }
-    }
-  });
-  
-  Project::debug_update_status("");
+    });
+
+    Project::debug_update_status("");
 #endif
-  
-  menu.add_action("window_next_tab", []() {
-    Notebook::get().next();
-  });
-  menu.add_action("window_previous_tab", []() {
-    Notebook::get().previous();
-  });
-  menu.add_action("window_close_tab", []() {
-    if(Notebook::get().get_current_view())
-      Notebook::get().close_current();
-  });
-  menu.add_action("window_toggle_split", [] {
-    Notebook::get().toggle_split();
-  });
-  menu.add_action("window_toggle_full_screen", [this] {
-    if(this->get_window()->get_state() & Gdk::WindowState::WINDOW_STATE_FULLSCREEN)
-      unfullscreen();
-    else
-      fullscreen();
-  });
-  menu.add_action("window_toggle_tabs", [] {
-    Notebook::get().toggle_tabs();
-  });
-  menu.add_action("window_clear_terminal", [] {
-    Terminal::get().clear();
-  });
-  
-  menu.toggle_menu_items=[] {
-    auto &menu = Menu::get();
-    auto view=Notebook::get().get_current_view();
-    
-    menu.actions["file_reload_file"]->set_enabled(view);
-    menu.actions["source_spellcheck"]->set_enabled(view);
-    menu.actions["source_spellcheck_clear"]->set_enabled(view);
-    menu.actions["source_spellcheck_next_error"]->set_enabled(view);
-    menu.actions["source_git_next_diff"]->set_enabled(view);
-    menu.actions["source_git_show_diff"]->set_enabled(view);
-    menu.actions["source_indentation_set_buffer_tab"]->set_enabled(view);
-    menu.actions["source_goto_line"]->set_enabled(view);
-    menu.actions["source_center_cursor"]->set_enabled(view);
-    
-    menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && view->format_style);
-    menu.actions["source_comments_toggle"]->set_enabled(view && view->toggle_comments);
-    menu.actions["source_comments_add_documentation"]->set_enabled(view && view->get_documentation_template);
-    menu.actions["source_find_documentation"]->set_enabled(view && view->get_token_data);
-    menu.actions["source_goto_declaration"]->set_enabled(view && view->get_declaration_location);
-    menu.actions["source_goto_type_declaration"]->set_enabled(view && view->get_type_declaration_location);
-    menu.actions["source_goto_implementation"]->set_enabled(view && view->get_implementation_locations);
-    menu.actions["source_goto_declaration_or_implementation"]->set_enabled(view && view->get_declaration_or_implementation_locations);
-    menu.actions["source_goto_usage"]->set_enabled(view && view->get_usages);
-    menu.actions["source_goto_method"]->set_enabled(view && view->get_methods);
-    menu.actions["source_rename"]->set_enabled(view && view->rename_similar_tokens);
-    menu.actions["source_implement_method"]->set_enabled(view && view->get_method);
-    menu.actions["source_goto_next_diagnostic"]->set_enabled(view && view->goto_next_diagnostic);
-    menu.actions["source_apply_fix_its"]->set_enabled(view && view->get_fix_its);
+
+    menu.add_action("window_next_tab", []() {
+        Notebook::get().next();
+    });
+    menu.add_action("window_previous_tab", []() {
+        Notebook::get().previous();
+    });
+    menu.add_action("window_close_tab", []() {
+        if (Notebook::get().get_current_view())
+            Notebook::get().close_current();
+    });
+    menu.add_action("window_toggle_split", [] {
+        Notebook::get().toggle_split();
+    });
+    menu.add_action("window_toggle_full_screen", [this] {
+        if (this->get_window()->get_state() & Gdk::WindowState::WINDOW_STATE_FULLSCREEN)
+            unfullscreen();
+        else
+            fullscreen();
+    });
+    menu.add_action("window_toggle_tabs", [] {
+        Notebook::get().toggle_tabs();
+    });
+    menu.add_action("window_clear_terminal", [] {
+        Terminal::get().clear();
+    });
+
+    menu.toggle_menu_items = [] {
+        auto &menu = Menu::get();
+        auto view = Notebook::get().get_current_view();
+
+        menu.actions["file_reload_file"]->set_enabled(view);
+        menu.actions["source_spellcheck"]->set_enabled(view);
+        menu.actions["source_spellcheck_clear"]->set_enabled(view);
+        menu.actions["source_spellcheck_next_error"]->set_enabled(view);
+        menu.actions["source_git_next_diff"]->set_enabled(view);
+        menu.actions["source_git_show_diff"]->set_enabled(view);
+        menu.actions["source_indentation_set_buffer_tab"]->set_enabled(view);
+        menu.actions["source_goto_line"]->set_enabled(view);
+        menu.actions["source_center_cursor"]->set_enabled(view);
+
+        menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && view->format_style);
+        menu.actions["source_comments_toggle"]->set_enabled(view && view->toggle_comments);
+        menu.actions["source_comments_add_documentation"]->set_enabled(view && view->get_documentation_template);
+        menu.actions["source_find_documentation"]->set_enabled(view && view->get_token_data);
+        menu.actions["source_goto_declaration"]->set_enabled(view && view->get_declaration_location);
+        menu.actions["source_goto_type_declaration"]->set_enabled(view && view->get_type_declaration_location);
+        menu.actions["source_goto_implementation"]->set_enabled(view && view->get_implementation_locations);
+        menu.actions["source_goto_declaration_or_implementation"]->set_enabled(
+                view && view->get_declaration_or_implementation_locations);
+        menu.actions["source_goto_usage"]->set_enabled(view && view->get_usages);
+        menu.actions["source_goto_method"]->set_enabled(view && view->get_methods);
+        menu.actions["source_rename"]->set_enabled(view && view->rename_similar_tokens);
+        menu.actions["source_implement_method"]->set_enabled(view && view->get_method);
+        menu.actions["source_goto_next_diagnostic"]->set_enabled(view && view->goto_next_diagnostic);
+        menu.actions["source_apply_fix_its"]->set_enabled(view && view->get_fix_its);
 #ifdef JUCI_ENABLE_DEBUG
-    Project::debug_activate_menu_items();
+        Project::debug_activate_menu_items();
 #endif
-  };
+    };
 }
 
 void Window::add_widgets() {
-  auto directories_scrolled_window=Gtk::manage(new Gtk::ScrolledWindow());
-  directories_scrolled_window->add(Directories::get());
-  
-  auto notebook_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-  notebook_vbox->pack_start(Notebook::get());
-  notebook_vbox->pack_end(EntryBox::get(), Gtk::PACK_SHRINK);
-  
-  auto terminal_scrolled_window=Gtk::manage(new Gtk::ScrolledWindow());
-  terminal_scrolled_window->add(Terminal::get());
-  
-  int width, height;
-  get_default_size(width, height);
-  
-  auto notebook_and_terminal_vpaned=Gtk::manage(new Gtk::Paned(Gtk::Orientation::ORIENTATION_VERTICAL));
-  notebook_and_terminal_vpaned->set_position(static_cast<int>(0.75*height));
-  notebook_and_terminal_vpaned->pack1(*notebook_vbox, Gtk::SHRINK);
-  notebook_and_terminal_vpaned->pack2(*terminal_scrolled_window, Gtk::SHRINK);
-  
-  auto hpaned=Gtk::manage(new Gtk::Paned());
-  hpaned->set_position(static_cast<int>(0.2*width));
-  hpaned->pack1(*directories_scrolled_window, Gtk::SHRINK);
-  hpaned->pack2(*notebook_and_terminal_vpaned, Gtk::SHRINK);
-  
-  auto status_hbox=Gtk::manage(new Gtk::Box());
-  status_hbox->set_homogeneous(true);
-  status_hbox->pack_start(*Gtk::manage(new Gtk::Box()));
-  auto status_right_hbox=Gtk::manage(new Gtk::Box());
-  status_right_hbox->pack_end(Notebook::get().status_state, Gtk::PACK_SHRINK);
-  auto status_right_overlay=Gtk::manage(new Gtk::Overlay());
-  status_right_overlay->add(*status_right_hbox);
-  status_right_overlay->add_overlay(Notebook::get().status_diagnostics);
-  status_hbox->pack_end(*status_right_overlay);
-  
-  auto status_overlay=Gtk::manage(new Gtk::Overlay());
-  status_overlay->add(*status_hbox);
-  auto status_file_info_hbox=Gtk::manage(new Gtk::Box);
-  status_file_info_hbox->pack_start(Notebook::get().status_file_path, Gtk::PACK_SHRINK);
-  status_file_info_hbox->pack_start(Notebook::get().status_branch, Gtk::PACK_SHRINK);
-  status_file_info_hbox->pack_start(Notebook::get().status_location, Gtk::PACK_SHRINK);
-  status_overlay->add_overlay(*status_file_info_hbox);
-  status_overlay->add_overlay(Project::debug_status_label());
-  
-  auto vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-  vbox->pack_start(*hpaned);
-  vbox->pack_start(*status_overlay, Gtk::PACK_SHRINK);
-  
-  auto overlay_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-  auto overlay_hbox=Gtk::manage(new Gtk::Box());
-  overlay_vbox->set_hexpand(false);
-  overlay_vbox->set_halign(Gtk::Align::ALIGN_START);
-  overlay_vbox->pack_start(Info::get(), Gtk::PACK_SHRINK, 20);
-  overlay_hbox->set_hexpand(false);
-  overlay_hbox->set_halign(Gtk::Align::ALIGN_END);
-  overlay_hbox->pack_end(*overlay_vbox, Gtk::PACK_SHRINK, 20);
-  
-  auto overlay=Gtk::manage(new Gtk::Overlay());
-  overlay->add(*vbox);
-  overlay->add_overlay(*overlay_hbox);
-  overlay->set_overlay_pass_through(*overlay_hbox, true);
-  add(*overlay);
-  
-  show_all_children();
-  Info::get().hide();
-  
-  //Scroll to end of terminal whenever info is printed
-  Terminal::get().signal_size_allocate().connect([terminal_scrolled_window](Gtk::Allocation& allocation){
-    auto adjustment=terminal_scrolled_window->get_vadjustment();
-    adjustment->set_value(adjustment->get_upper()-adjustment->get_page_size());
-    Terminal::get().queue_draw();
-  });
-  
-  EntryBox::get().signal_show().connect([hpaned, notebook_and_terminal_vpaned, notebook_vbox](){
-    hpaned->set_focus_chain({notebook_and_terminal_vpaned});
-    notebook_and_terminal_vpaned->set_focus_chain({notebook_vbox});
-    notebook_vbox->set_focus_chain({&EntryBox::get()});
-  });
-  EntryBox::get().signal_hide().connect([hpaned, notebook_and_terminal_vpaned, notebook_vbox](){
-    hpaned->unset_focus_chain();
-    notebook_and_terminal_vpaned->unset_focus_chain();
-    notebook_vbox->unset_focus_chain();
-  });
+    auto directories_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());
+    directories_scrolled_window->add(Directories::get());
+
+    auto notebook_vbox = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+    notebook_vbox->pack_start(Notebook::get());
+    notebook_vbox->pack_end(EntryBox::get(), Gtk::PACK_SHRINK);
+
+    auto terminal_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());
+    terminal_scrolled_window->add(Terminal::get());
+
+    int width, height;
+    get_default_size(width, height);
+
+    auto notebook_and_terminal_vpaned = Gtk::manage(new Gtk::Paned(Gtk::Orientation::ORIENTATION_VERTICAL));
+    notebook_and_terminal_vpaned->set_position(static_cast<int>(0.75 * height));
+    notebook_and_terminal_vpaned->pack1(*notebook_vbox, Gtk::SHRINK);
+    notebook_and_terminal_vpaned->pack2(*terminal_scrolled_window, Gtk::SHRINK);
+
+    auto hpaned = Gtk::manage(new Gtk::Paned());
+    hpaned->set_position(static_cast<int>(0.2 * width));
+    hpaned->pack1(*directories_scrolled_window, Gtk::SHRINK);
+    hpaned->pack2(*notebook_and_terminal_vpaned, Gtk::SHRINK);
+
+    auto status_hbox = Gtk::manage(new Gtk::Box());
+    status_hbox->set_homogeneous(true);
+    status_hbox->pack_start(*Gtk::manage(new Gtk::Box()));
+    auto status_right_hbox = Gtk::manage(new Gtk::Box());
+    status_right_hbox->pack_end(Notebook::get().status_state, Gtk::PACK_SHRINK);
+    auto status_right_overlay = Gtk::manage(new Gtk::Overlay());
+    status_right_overlay->add(*status_right_hbox);
+    status_right_overlay->add_overlay(Notebook::get().status_diagnostics);
+    status_hbox->pack_end(*status_right_overlay);
+
+    auto status_overlay = Gtk::manage(new Gtk::Overlay());
+    status_overlay->add(*status_hbox);
+    auto status_file_info_hbox = Gtk::manage(new Gtk::Box);
+    status_file_info_hbox->pack_start(Notebook::get().status_file_path, Gtk::PACK_SHRINK);
+    status_file_info_hbox->pack_start(Notebook::get().status_branch, Gtk::PACK_SHRINK);
+    status_file_info_hbox->pack_start(Notebook::get().status_location, Gtk::PACK_SHRINK);
+    status_overlay->add_overlay(*status_file_info_hbox);
+    status_overlay->add_overlay(Project::debug_status_label());
+
+    auto vbox = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+    vbox->pack_start(*hpaned);
+    vbox->pack_start(*status_overlay, Gtk::PACK_SHRINK);
+
+    auto overlay_vbox = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+    auto overlay_hbox = Gtk::manage(new Gtk::Box());
+    overlay_vbox->set_hexpand(false);
+    overlay_vbox->set_halign(Gtk::Align::ALIGN_START);
+    overlay_vbox->pack_start(Info::get(), Gtk::PACK_SHRINK, 20);
+    overlay_hbox->set_hexpand(false);
+    overlay_hbox->set_halign(Gtk::Align::ALIGN_END);
+    overlay_hbox->pack_end(*overlay_vbox, Gtk::PACK_SHRINK, 20);
+
+    auto overlay = Gtk::manage(new Gtk::Overlay());
+    overlay->add(*vbox);
+    overlay->add_overlay(*overlay_hbox);
+    overlay->set_overlay_pass_through(*overlay_hbox, true);
+    add(*overlay);
+
+    show_all_children();
+    Info::get().hide();
+
+    //Scroll to end of terminal whenever info is printed
+    Terminal::get().signal_size_allocate().connect([terminal_scrolled_window](Gtk::Allocation &allocation) {
+        auto adjustment = terminal_scrolled_window->get_vadjustment();
+        adjustment->set_value(adjustment->get_upper() - adjustment->get_page_size());
+        Terminal::get().queue_draw();
+    });
+
+    EntryBox::get().signal_show().connect([hpaned, notebook_and_terminal_vpaned, notebook_vbox]() {
+        hpaned->set_focus_chain({notebook_and_terminal_vpaned});
+        notebook_and_terminal_vpaned->set_focus_chain({notebook_vbox});
+        notebook_vbox->set_focus_chain({&EntryBox::get()});
+    });
+    EntryBox::get().signal_hide().connect([hpaned, notebook_and_terminal_vpaned, notebook_vbox]() {
+        hpaned->unset_focus_chain();
+        notebook_and_terminal_vpaned->unset_focus_chain();
+        notebook_vbox->unset_focus_chain();
+    });
 }
 
 bool Window::on_key_press_event(GdkEventKey *event) {
-  if(event->keyval==GDK_KEY_Escape) {
-    EntryBox::get().hide();
-  }
-#ifdef __APPLE__ //For Apple's Command-left, right, up, down keys
-  else if((event->state & GDK_META_MASK)>0 && (event->state & GDK_MOD1_MASK)==0) {
-    if(event->keyval==GDK_KEY_Left || event->keyval==GDK_KEY_KP_Left) {
-      event->keyval=GDK_KEY_Home;
-      event->state=event->state & GDK_SHIFT_MASK;
-      event->hardware_keycode=115;
-    }
-    else if(event->keyval==GDK_KEY_Right || event->keyval==GDK_KEY_KP_Right) {
-      event->keyval=GDK_KEY_End;
-      event->state=event->state & GDK_SHIFT_MASK;
-      event->hardware_keycode=119;
-    }
-    else if(event->keyval==GDK_KEY_Up || event->keyval==GDK_KEY_KP_Up) {
-      event->keyval=GDK_KEY_Home;
-      event->state=event->state & GDK_SHIFT_MASK;
-      event->state+=GDK_CONTROL_MASK;
-      event->hardware_keycode=115;
+    if (event->keyval == GDK_KEY_Escape) {
+        EntryBox::get().hide();
     }
-    else if(event->keyval==GDK_KEY_Down || event->keyval==GDK_KEY_KP_Down) {
-      event->keyval=GDK_KEY_End;
-      event->state=event->state & GDK_SHIFT_MASK;
-      event->state+=GDK_CONTROL_MASK;
-      event->hardware_keycode=119;
+#ifdef __APPLE__ //For Apple's Command-left, right, up, down keys
+    else if((event->state & GDK_META_MASK)>0 && (event->state & GDK_MOD1_MASK)==0) {
+      if(event->keyval==GDK_KEY_Left || event->keyval==GDK_KEY_KP_Left) {
+        event->keyval=GDK_KEY_Home;
+        event->state=event->state & GDK_SHIFT_MASK;
+        event->hardware_keycode=115;
+      }
+      else if(event->keyval==GDK_KEY_Right || event->keyval==GDK_KEY_KP_Right) {
+        event->keyval=GDK_KEY_End;
+        event->state=event->state & GDK_SHIFT_MASK;
+        event->hardware_keycode=119;
+      }
+      else if(event->keyval==GDK_KEY_Up || event->keyval==GDK_KEY_KP_Up) {
+        event->keyval=GDK_KEY_Home;
+        event->state=event->state & GDK_SHIFT_MASK;
+        event->state+=GDK_CONTROL_MASK;
+        event->hardware_keycode=115;
+      }
+      else if(event->keyval==GDK_KEY_Down || event->keyval==GDK_KEY_KP_Down) {
+        event->keyval=GDK_KEY_End;
+        event->state=event->state & GDK_SHIFT_MASK;
+        event->state+=GDK_CONTROL_MASK;
+        event->hardware_keycode=119;
+      }
     }
-  }
 #endif
 
-  if(SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
-    if(SelectionDialog::get()->on_key_press(event))
-      return true;
-  }
+    if (SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
+        if (SelectionDialog::get()->on_key_press(event))
+            return true;
+    }
 
-  return Gtk::ApplicationWindow::on_key_press_event(event);
+    return Gtk::ApplicationWindow::on_key_press_event(event);
 }
 
 bool Window::on_delete_event(GdkEventAny *event) {
-  save_session();
-  
-  for(size_t c=Notebook::get().size()-1;c!=static_cast<size_t>(-1);--c) {
-    if(!Notebook::get().close(c))
-      return true;
-  }
-  Terminal::get().kill_async_processes();
+    save_session();
+
+    for (size_t c = Notebook::get().size() - 1; c != static_cast<size_t>(-1); --c) {
+        if (!Notebook::get().close(c))
+            return true;
+    }
+    Terminal::get().kill_async_processes();
 #ifdef JUCI_ENABLE_DEBUG
-  if(Project::current)
-    Project::current->debug_cancel();
+    if(Project::current)
+      Project::current->debug_cancel();
 #endif
 
-  return false;
-}
-
-void Window::search_and_replace_entry() {
-  EntryBox::get().clear();
-  EntryBox::get().labels.emplace_back();
-  auto label_it=EntryBox::get().labels.begin();
-  label_it->update=[label_it](int state, const std::string& message){
-    if(state==0) {
-      try {
-        auto number = stoi(message);
-        if(number==0)
-          label_it->set_text("");
-        else if(number==1)
-          label_it->set_text("1 result found");
-        else if(number>1)
-          label_it->set_text(message+" results found");
-      }
-      catch(const std::exception &e) {}
-    }
-  };
-  EntryBox::get().entries.emplace_back(last_search, [](const std::string& content){
-    if(auto view=Notebook::get().get_current_view())
-      view->search_forward();
-  });
-  auto search_entry_it=EntryBox::get().entries.begin();
-  search_entry_it->set_placeholder_text("Find");
-  if(auto view=Notebook::get().get_current_view()) {
-    view->update_search_occurrences=[label_it](int number){
-      label_it->update(0, std::to_string(number));
-    };
-    view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
-  }
-  search_entry_it->signal_key_press_event().connect([](GdkEventKey* event){
-    if((event->keyval==GDK_KEY_Return || event->keyval==GDK_KEY_KP_Enter) && (event->state&GDK_SHIFT_MASK)>0) {
-      if(auto view=Notebook::get().get_current_view())
-        view->search_backward();
-    }
     return false;
-  });
-  search_entry_it->signal_changed().connect([this, search_entry_it](){
-    last_search=search_entry_it->get_text();
-    if(auto view=Notebook::get().get_current_view())
-      view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
-  });
-
-  EntryBox::get().entries.emplace_back(last_replace, [](const std::string &content){
-    if(auto view=Notebook::get().get_current_view())
-      view->replace_forward(content);
-  });
-  auto replace_entry_it=EntryBox::get().entries.begin();
-  replace_entry_it++;
-  replace_entry_it->set_placeholder_text("Replace");
-  replace_entry_it->signal_key_press_event().connect([replace_entry_it](GdkEventKey* event){
-    if((event->keyval==GDK_KEY_Return || event->keyval==GDK_KEY_KP_Enter) && (event->state&GDK_SHIFT_MASK)>0) {
-      if(auto view=Notebook::get().get_current_view())
-        view->replace_backward(replace_entry_it->get_text());
-    }
-    return false;
-  });
-  replace_entry_it->signal_changed().connect([this, replace_entry_it](){
-    last_replace=replace_entry_it->get_text();
-  });
-  
-  EntryBox::get().buttons.emplace_back("↑", [](){
-    if(auto view=Notebook::get().get_current_view())
-        view->search_backward();
-  });
-  EntryBox::get().buttons.back().set_tooltip_text("Find Previous\n\nShortcut: Shift+Enter in the Find entry field");
-  EntryBox::get().buttons.emplace_back("⇄", [replace_entry_it](){
-    if(auto view=Notebook::get().get_current_view()) {
-      view->replace_forward(replace_entry_it->get_text());
-    }
-  });
-  EntryBox::get().buttons.back().set_tooltip_text("Replace Next\n\nShortcut: Enter in the Replace entry field");
-  EntryBox::get().buttons.emplace_back("↓", [](){
-    if(auto view=Notebook::get().get_current_view())
-      view->search_forward();
-  });
-  EntryBox::get().buttons.back().set_tooltip_text("Find Next\n\nShortcut: Enter in the Find entry field");
-  EntryBox::get().buttons.emplace_back("Replace All", [replace_entry_it](){
-    if(auto view=Notebook::get().get_current_view())
-      view->replace_all(replace_entry_it->get_text());
-  });
-  EntryBox::get().buttons.back().set_tooltip_text("Replace All");
-  
-  EntryBox::get().toggle_buttons.emplace_back("Aa");
-  EntryBox::get().toggle_buttons.back().set_tooltip_text("Match Case");
-  EntryBox::get().toggle_buttons.back().set_active(case_sensitive_search);
-  EntryBox::get().toggle_buttons.back().on_activate=[this, search_entry_it](){
-    case_sensitive_search=!case_sensitive_search;
-    if(auto view=Notebook::get().get_current_view())
-      view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
-  };
-  EntryBox::get().toggle_buttons.emplace_back(".*");
-  EntryBox::get().toggle_buttons.back().set_tooltip_text("Use Regex");
-  EntryBox::get().toggle_buttons.back().set_active(regex_search);
-  EntryBox::get().toggle_buttons.back().on_activate=[this, search_entry_it](){
-    regex_search=!regex_search;
-    if(auto view=Notebook::get().get_current_view())
-      view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
-  };
-  EntryBox::get().signal_hide().connect([this]() {
-    for(size_t c=0;c<Notebook::get().size();c++) {
-      Notebook::get().get_view(c)->update_search_occurrences=nullptr;
-      Notebook::get().get_view(c)->search_highlight("", case_sensitive_search, regex_search);
-    }
-    search_entry_shown=false;
-  });
-  search_entry_shown=true;
-  EntryBox::get().show();
 }
 
-void Window::set_tab_entry() {
-  EntryBox::get().clear();
-  if(auto view=Notebook::get().get_current_view()) {
-    auto tab_char_and_size=view->get_tab_char_and_size();
-    
+void Window::search_and_replace_entry() {
+    EntryBox::get().clear();
     EntryBox::get().labels.emplace_back();
-    auto label_it=EntryBox::get().labels.begin();
-    
-    EntryBox::get().entries.emplace_back(std::to_string(tab_char_and_size.second));
-    auto entry_tab_size_it=EntryBox::get().entries.begin();
-    entry_tab_size_it->set_placeholder_text("Tab size");
-    
-    char tab_char=tab_char_and_size.first;
-    std::string tab_char_string;
-    if(tab_char==' ')
-      tab_char_string="space";
-    else if(tab_char=='\t')
-      tab_char_string="tab";
-      
-    EntryBox::get().entries.emplace_back(tab_char_string);
-    auto entry_tab_char_it=EntryBox::get().entries.rbegin();
-    entry_tab_char_it->set_placeholder_text("Tab char");
-    
-    const auto activate_function=[entry_tab_char_it, entry_tab_size_it, label_it](const std::string& content){
-      if(auto view=Notebook::get().get_current_view()) {
-        char tab_char=0;
-        unsigned tab_size=0;
-        try {
-          tab_size = static_cast<unsigned>(std::stoul(entry_tab_size_it->get_text()));
-          std::string tab_char_string=entry_tab_char_it->get_text();
-          std::transform(tab_char_string.begin(), tab_char_string.end(), tab_char_string.begin(), ::tolower);
-          if(tab_char_string=="space")
-            tab_char=' ';
-          else if(tab_char_string=="tab")
-            tab_char='\t';
+    auto label_it = EntryBox::get().labels.begin();
+    label_it->update = [label_it](int state, const std::string &message) {
+        if (state == 0) {
+            try {
+                auto number = stoi(message);
+                if (number == 0)
+                    label_it->set_text("");
+                else if (number == 1)
+                    label_it->set_text("1 result found");
+                else if (number > 1)
+                    label_it->set_text(message + " results found");
+            }
+            catch (const std::exception &e) {}
         }
-        catch(const std::exception &e) {}
-
-        if(tab_char!=0 && tab_size>0) {
-          view->set_tab_char_and_size(tab_char, tab_size);
-          EntryBox::get().hide();
+    };
+    EntryBox::get().entries.emplace_back(last_search, [](const std::string &content) {
+        if (auto view = Notebook::get().get_current_view())
+            view->search_forward();
+    });
+    auto search_entry_it = EntryBox::get().entries.begin();
+    search_entry_it->set_placeholder_text("Find");
+    if (auto view = Notebook::get().get_current_view()) {
+        view->update_search_occurrences = [label_it](int number) {
+            label_it->update(0, std::to_string(number));
+        };
+        view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
+    }
+    search_entry_it->signal_key_press_event().connect([](GdkEventKey *event) {
+        if ((event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) &&
+            (event->state & GDK_SHIFT_MASK) > 0) {
+            if (auto view = Notebook::get().get_current_view())
+                view->search_backward();
         }
-        else {
-          label_it->set_text("Tab size must be >0 and tab char set to either 'space' or 'tab'");
+        return false;
+    });
+    search_entry_it->signal_changed().connect([this, search_entry_it]() {
+        last_search = search_entry_it->get_text();
+        if (auto view = Notebook::get().get_current_view())
+            view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
+    });
+
+    EntryBox::get().entries.emplace_back(last_replace, [](const std::string &content) {
+        if (auto view = Notebook::get().get_current_view())
+            view->replace_forward(content);
+    });
+    auto replace_entry_it = EntryBox::get().entries.begin();
+    replace_entry_it++;
+    replace_entry_it->set_placeholder_text("Replace");
+    replace_entry_it->signal_key_press_event().connect([replace_entry_it](GdkEventKey *event) {
+        if ((event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) &&
+            (event->state & GDK_SHIFT_MASK) > 0) {
+            if (auto view = Notebook::get().get_current_view())
+                view->replace_backward(replace_entry_it->get_text());
         }
-      }
-    };
-    
-    entry_tab_char_it->on_activate=activate_function;
-    entry_tab_size_it->on_activate=activate_function;
-    
-    EntryBox::get().buttons.emplace_back("Set tab in current buffer", [entry_tab_char_it](){
-      entry_tab_char_it->activate();
-    });
-    
-    EntryBox::get().show();
-  }
-}
+        return false;
+    });
+    replace_entry_it->signal_changed().connect([this, replace_entry_it]() {
+        last_replace = replace_entry_it->get_text();
+    });
 
-void Window::goto_line_entry() {
-  EntryBox::get().clear();
-  if(Notebook::get().get_current_view()) {
-    EntryBox::get().entries.emplace_back("", [](const std::string& content){
-      if(auto view=Notebook::get().get_current_view()) {
-        try {
-          view->place_cursor_at_line_index(stoi(content)-1, 0);
-          view->scroll_to_cursor_delayed(view, true, false);
+    EntryBox::get().buttons.emplace_back("↑", []() {
+        if (auto view = Notebook::get().get_current_view())
+            view->search_backward();
+    });
+    EntryBox::get().buttons.back().set_tooltip_text("Find Previous\n\nShortcut: Shift+Enter in the Find entry field");
+    EntryBox::get().buttons.emplace_back("⇄", [replace_entry_it]() {
+        if (auto view = Notebook::get().get_current_view()) {
+            view->replace_forward(replace_entry_it->get_text());
         }
-        catch(const std::exception &e) {}  
-        EntryBox::get().hide();
-      }
     });
-    auto entry_it=EntryBox::get().entries.begin();
-    entry_it->set_placeholder_text("Line number");
-    EntryBox::get().buttons.emplace_back("Go to line", [entry_it](){
-      entry_it->activate();
+    EntryBox::get().buttons.back().set_tooltip_text("Replace Next\n\nShortcut: Enter in the Replace entry field");
+    EntryBox::get().buttons.emplace_back("↓", []() {
+        if (auto view = Notebook::get().get_current_view())
+            view->search_forward();
     });
+    EntryBox::get().buttons.back().set_tooltip_text("Find Next\n\nShortcut: Enter in the Find entry field");
+    EntryBox::get().buttons.emplace_back("Replace All", [replace_entry_it]() {
+        if (auto view = Notebook::get().get_current_view())
+            view->replace_all(replace_entry_it->get_text());
+    });
+    EntryBox::get().buttons.back().set_tooltip_text("Replace All");
+
+    EntryBox::get().toggle_buttons.emplace_back("Aa");
+    EntryBox::get().toggle_buttons.back().set_tooltip_text("Match Case");
+    EntryBox::get().toggle_buttons.back().set_active(case_sensitive_search);
+    EntryBox::get().toggle_buttons.back().on_activate = [this, search_entry_it]() {
+        case_sensitive_search = !case_sensitive_search;
+        if (auto view = Notebook::get().get_current_view())
+            view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
+    };
+    EntryBox::get().toggle_buttons.emplace_back(".*");
+    EntryBox::get().toggle_buttons.back().set_tooltip_text("Use Regex");
+    EntryBox::get().toggle_buttons.back().set_active(regex_search);
+    EntryBox::get().toggle_buttons.back().on_activate = [this, search_entry_it]() {
+        regex_search = !regex_search;
+        if (auto view = Notebook::get().get_current_view())
+            view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
+    };
+    EntryBox::get().signal_hide().connect([this]() {
+        for (size_t c = 0; c < Notebook::get().size(); c++) {
+            Notebook::get().get_view(c)->update_search_occurrences = nullptr;
+            Notebook::get().get_view(c)->search_highlight("", case_sensitive_search, regex_search);
+        }
+        search_entry_shown = false;
+    });
+    search_entry_shown = true;
     EntryBox::get().show();
-  }
 }
 
-void Window::rename_token_entry() {
-  EntryBox::get().clear();
-  if(auto view=Notebook::get().get_current_view()) {
-    if(view->get_token_spelling && view->rename_similar_tokens) {
-      auto spelling=std::make_shared<std::string>(view->get_token_spelling());
-      if(!spelling->empty()) {
-        EntryBox::get().entries.emplace_back(*spelling, [view, spelling, iter=view->get_buffer()->get_insert()->get_iter()](const std::string& content){
-          //TODO: gtk needs a way to check if iter is valid without dumping g_error message
-          //iter->get_buffer() will print such a message, but no segfault will occur
-          if(Notebook::get().get_current_view()==view && content!=*spelling && iter.get_buffer() && view->get_buffer()->get_insert()->get_iter()==iter)
-            view->rename_similar_tokens(content);
-          else
-            Info::get().print("Operation canceled");
-          EntryBox::get().hide();
-        });
-        auto entry_it=EntryBox::get().entries.begin();
-        entry_it->set_placeholder_text("New name");
-        EntryBox::get().buttons.emplace_back("Rename", [entry_it](){
-          entry_it->activate();
+void Window::set_tab_entry() {
+    EntryBox::get().clear();
+    if (auto view = Notebook::get().get_current_view()) {
+        auto tab_char_and_size = view->get_tab_char_and_size();
+
+        EntryBox::get().labels.emplace_back();
+        auto label_it = EntryBox::get().labels.begin();
+
+        EntryBox::get().entries.emplace_back(std::to_string(tab_char_and_size.second));
+        auto entry_tab_size_it = EntryBox::get().entries.begin();
+        entry_tab_size_it->set_placeholder_text("Tab size");
+
+        char tab_char = tab_char_and_size.first;
+        std::string tab_char_string;
+        if (tab_char == ' ')
+            tab_char_string = "space";
+        else if (tab_char == '\t')
+            tab_char_string = "tab";
+
+        EntryBox::get().entries.emplace_back(tab_char_string);
+        auto entry_tab_char_it = EntryBox::get().entries.rbegin();
+        entry_tab_char_it->set_placeholder_text("Tab char");
+
+        const auto activate_function = [entry_tab_char_it, entry_tab_size_it, label_it](const std::string &content) {
+            if (auto view = Notebook::get().get_current_view()) {
+                char tab_char = 0;
+                unsigned tab_size = 0;
+                try {
+                    tab_size = static_cast<unsigned>(std::stoul(entry_tab_size_it->get_text()));
+                    std::string tab_char_string = entry_tab_char_it->get_text();
+                    std::transform(tab_char_string.begin(), tab_char_string.end(), tab_char_string.begin(), ::tolower);
+                    if (tab_char_string == "space")
+                        tab_char = ' ';
+                    else if (tab_char_string == "tab")
+                        tab_char = '\t';
+                }
+                catch (const std::exception &e) {}
+
+                if (tab_char != 0 && tab_size > 0) {
+                    view->set_tab_char_and_size(tab_char, tab_size);
+                    EntryBox::get().hide();
+                } else {
+                    label_it->set_text("Tab size must be >0 and tab char set to either 'space' or 'tab'");
+                }
+            }
+        };
+
+        entry_tab_char_it->on_activate = activate_function;
+        entry_tab_size_it->on_activate = activate_function;
+
+        EntryBox::get().buttons.emplace_back("Set tab in current buffer", [entry_tab_char_it]() {
+            entry_tab_char_it->activate();
         });
+
         EntryBox::get().show();
-      }
     }
-  }
 }
 
-void Window::save_session() {
-  try {
-    boost::property_tree::ptree root_pt;
-    root_pt.put("folder", Directories::get().path.string());
-    
-    boost::property_tree::ptree files_pt;
-    for(auto &notebook_view: Notebook::get().get_notebook_views()) {
-      boost::property_tree::ptree file_pt;
-      file_pt.put("path", notebook_view.second->file_path.string());
-      file_pt.put("notebook", notebook_view.first);
-      auto iter=notebook_view.second->get_buffer()->get_insert()->get_iter();
-      file_pt.put("line", iter.get_line());
-      file_pt.put("line_offset", iter.get_line_offset());
-      files_pt.push_back(std::make_pair("", file_pt));
-    }
-    root_pt.add_child("files", files_pt);
-    
-    boost::property_tree::ptree current_file_pt;
-    if(auto view=Notebook::get().get_current_view()) {
-      current_file_pt.put("path", view->file_path.string());
-      auto iter=view->get_buffer()->get_insert()->get_iter();
-      current_file_pt.put("line", iter.get_line());
-      current_file_pt.put("line_offset", iter.get_line_offset());
-    }
-    std::string current_path;
-    if(auto view=Notebook::get().get_current_view())
-      current_path=view->file_path.string();
-    root_pt.put("current_file", current_path);
-    
-    boost::property_tree::ptree run_arguments_pt;
-    for(auto &run_argument: Project::run_arguments) {
-      if(run_argument.second.empty())
-        continue;
-      boost::system::error_code ec;
-      if(boost::filesystem::exists(run_argument.first, ec) && boost::filesystem::is_directory(run_argument.first, ec)) {
-        boost::property_tree::ptree run_argument_pt;
-        run_argument_pt.put("path", run_argument.first);
-        run_argument_pt.put("arguments", run_argument.second);
-        run_arguments_pt.push_back(std::make_pair("", run_argument_pt));
-      }
+void Window::goto_line_entry() {
+    EntryBox::get().clear();
+    if (Notebook::get().get_current_view()) {
+        EntryBox::get().entries.emplace_back("", [](const std::string &content) {
+            if (auto view = Notebook::get().get_current_view()) {
+                try {
+                    view->place_cursor_at_line_index(stoi(content) - 1, 0);
+                    view->scroll_to_cursor_delayed(view, true, false);
+                }
+                catch (const std::exception &e) {}
+                EntryBox::get().hide();
+            }
+        });
+        auto entry_it = EntryBox::get().entries.begin();
+        entry_it->set_placeholder_text("Line number");
+        EntryBox::get().buttons.emplace_back("Go to line", [entry_it]() {
+            entry_it->activate();
+        });
+        EntryBox::get().show();
     }
-    root_pt.add_child("run_arguments", run_arguments_pt);
-    
-    boost::property_tree::ptree debug_run_arguments_pt;
-    for(auto &debug_run_argument: Project::debug_run_arguments) {
-      if(debug_run_argument.second.arguments.empty() && !debug_run_argument.second.remote_enabled && debug_run_argument.second.remote_host_port.empty())
-        continue;
-      boost::system::error_code ec;
-      if(boost::filesystem::exists(debug_run_argument.first, ec) && boost::filesystem::is_directory(debug_run_argument.first, ec)) {
-        boost::property_tree::ptree debug_run_argument_pt;
-        debug_run_argument_pt.put("path", debug_run_argument.first);
-        debug_run_argument_pt.put("arguments", debug_run_argument.second.arguments);
-        debug_run_argument_pt.put("remote_enabled", debug_run_argument.second.remote_enabled);
-        debug_run_argument_pt.put("remote_host_port", debug_run_argument.second.remote_host_port);
-        debug_run_arguments_pt.push_back(std::make_pair("", debug_run_argument_pt));
-      }
+}
+
+void Window::rename_token_entry() {
+    EntryBox::get().clear();
+    if (auto view = Notebook::get().get_current_view()) {
+        if (view->get_token_spelling && view->rename_similar_tokens) {
+            auto spelling = std::make_shared<std::string>(view->get_token_spelling());
+            if (!spelling->empty()) {
+                EntryBox::get().entries.emplace_back(*spelling,
+                                                     [view, spelling, iter = view->get_buffer()->get_insert()->get_iter()](
+                                                             const std::string &content) {
+                                                         //TODO: gtk needs a way to check if iter is valid without dumping g_error message
+                                                         //iter->get_buffer() will print such a message, but no segfault will occur
+                                                         if (Notebook::get().get_current_view() == view &&
+                                                             content != *spelling && iter.get_buffer() &&
+                                                             view->get_buffer()->get_insert()->get_iter() == iter)
+                                                             view->rename_similar_tokens(content);
+                                                         else
+                                                             Info::get().print("Operation canceled");
+                                                         EntryBox::get().hide();
+                                                     });
+                auto entry_it = EntryBox::get().entries.begin();
+                entry_it->set_placeholder_text("New name");
+                EntryBox::get().buttons.emplace_back("Rename", [entry_it]() {
+                    entry_it->activate();
+                });
+                EntryBox::get().show();
+            }
+        }
     }
-    root_pt.add_child("debug_run_arguments", debug_run_arguments_pt);
-    
-    int width, height;
-    get_size(width, height);
-    boost::property_tree::ptree window_pt;
-    window_pt.put("width", width);
-    window_pt.put("height", height);
-    root_pt.add_child("window", window_pt);
-    
-    boost::property_tree::write_json((Config::get().home_juci_path/"last_session.json").string(), root_pt);
-  }
-  catch(...) {}
 }
 
-void Window::load_session(std::vector<boost::filesystem::path> &directories, std::vector<std::pair<boost::filesystem::path, size_t> > &files, std::vector<std::pair<int, int> > &file_offsets, std::string &current_file, bool read_directories_and_files) {
-  try {
-    boost::property_tree::ptree root_pt;
-    boost::property_tree::read_json((Config::get().home_juci_path/"last_session.json").string(), root_pt);
-    if(read_directories_and_files) {
-      auto folder=root_pt.get<std::string>("folder");
-      if(!folder.empty() && boost::filesystem::exists(folder) && boost::filesystem::is_directory(folder))
-        directories.emplace_back(folder);
-      
-      for(auto &file_pt: root_pt.get_child("files")) {
-        auto file=file_pt.second.get<std::string>("path");
-        auto notebook=file_pt.second.get<size_t>("notebook");
-        auto line=file_pt.second.get<int>("line");
-        auto line_offset=file_pt.second.get<int>("line_offset");
-        if(!file.empty() && boost::filesystem::exists(file) && !boost::filesystem::is_directory(file)) {
-          files.emplace_back(file, notebook);
-          file_offsets.emplace_back(line, line_offset);
+void Window::save_session() {
+    try {
+        boost::property_tree::ptree root_pt;
+        root_pt.put("folder", Directories::get().path.string());
+
+        boost::property_tree::ptree files_pt;
+        for (auto &notebook_view: Notebook::get().get_notebook_views()) {
+            boost::property_tree::ptree file_pt;
+            file_pt.put("path", notebook_view.second->file_path.string());
+            file_pt.put("notebook", notebook_view.first);
+            auto iter = notebook_view.second->get_buffer()->get_insert()->get_iter();
+            file_pt.put("line", iter.get_line());
+            file_pt.put("line_offset", iter.get_line_offset());
+            files_pt.push_back(std::make_pair("", file_pt));
         }
-      }
-     
-      current_file=root_pt.get<std::string>("current_file");
+        root_pt.add_child("files", files_pt);
+
+        boost::property_tree::ptree current_file_pt;
+        if (auto view = Notebook::get().get_current_view()) {
+            current_file_pt.put("path", view->file_path.string());
+            auto iter = view->get_buffer()->get_insert()->get_iter();
+            current_file_pt.put("line", iter.get_line());
+            current_file_pt.put("line_offset", iter.get_line_offset());
+        }
+        std::string current_path;
+        if (auto view = Notebook::get().get_current_view())
+            current_path = view->file_path.string();
+        root_pt.put("current_file", current_path);
+
+        boost::property_tree::ptree run_arguments_pt;
+        for (auto &run_argument: Project::run_arguments) {
+            if (run_argument.second.empty())
+                continue;
+            boost::system::error_code ec;
+            if (boost::filesystem::exists(run_argument.first, ec) &&
+                boost::filesystem::is_directory(run_argument.first, ec)) {
+                boost::property_tree::ptree run_argument_pt;
+                run_argument_pt.put("path", run_argument.first);
+                run_argument_pt.put("arguments", run_argument.second);
+                run_arguments_pt.push_back(std::make_pair("", run_argument_pt));
+            }
+        }
+        root_pt.add_child("run_arguments", run_arguments_pt);
+
+        boost::property_tree::ptree debug_run_arguments_pt;
+        for (auto &debug_run_argument: Project::debug_run_arguments) {
+            if (debug_run_argument.second.arguments.empty() && !debug_run_argument.second.remote_enabled &&
+                debug_run_argument.second.remote_host_port.empty())
+                continue;
+            boost::system::error_code ec;
+            if (boost::filesystem::exists(debug_run_argument.first, ec) &&
+                boost::filesystem::is_directory(debug_run_argument.first, ec)) {
+                boost::property_tree::ptree debug_run_argument_pt;
+                debug_run_argument_pt.put("path", debug_run_argument.first);
+                debug_run_argument_pt.put("arguments", debug_run_argument.second.arguments);
+                debug_run_argument_pt.put("remote_enabled", debug_run_argument.second.remote_enabled);
+                debug_run_argument_pt.put("remote_host_port", debug_run_argument.second.remote_host_port);
+                debug_run_arguments_pt.push_back(std::make_pair("", debug_run_argument_pt));
+            }
+        }
+        root_pt.add_child("debug_run_arguments", debug_run_arguments_pt);
+
+        int width, height;
+        get_size(width, height);
+        boost::property_tree::ptree window_pt;
+        window_pt.put("width", width);
+        window_pt.put("height", height);
+        root_pt.add_child("window", window_pt);
+
+        boost::property_tree::write_json((Config::get().home_juci_path / "last_session.json").string(), root_pt);
     }
-    
-    for(auto &run_argument: root_pt.get_child(("run_arguments"))) {
-      auto path=run_argument.second.get<std::string>("path");
-      boost::system::error_code ec;
-      if(boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec))
-        Project::run_arguments.emplace(path, run_argument.second.get<std::string>("arguments"));
+    catch (...) {}
+}
+
+void Window::load_session(std::vector<boost::filesystem::path> &directories,
+                          std::vector<std::pair<boost::filesystem::path, size_t> > &files,
+                          std::vector<std::pair<int, int> > &file_offsets, std::string &current_file,
+                          bool read_directories_and_files) {
+    try {
+        boost::property_tree::ptree root_pt;
+        boost::property_tree::read_json((Config::get().home_juci_path / "last_session.json").string(), root_pt);
+        if (read_directories_and_files) {
+            auto folder = root_pt.get<std::string>("folder");
+            if (!folder.empty() && boost::filesystem::exists(folder) && boost::filesystem::is_directory(folder))
+                directories.emplace_back(folder);
+
+            for (auto &file_pt: root_pt.get_child("files")) {
+                auto file = file_pt.second.get<std::string>("path");
+                auto notebook = file_pt.second.get<size_t>("notebook");
+                auto line = file_pt.second.get<int>("line");
+                auto line_offset = file_pt.second.get<int>("line_offset");
+                if (!file.empty() && boost::filesystem::exists(file) && !boost::filesystem::is_directory(file)) {
+                    files.emplace_back(file, notebook);
+                    file_offsets.emplace_back(line, line_offset);
+                }
+            }
+
+            current_file = root_pt.get<std::string>("current_file");
+        }
+
+        for (auto &run_argument: root_pt.get_child(("run_arguments"))) {
+            auto path = run_argument.second.get<std::string>("path");
+            boost::system::error_code ec;
+            if (boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec))
+                Project::run_arguments.emplace(path, run_argument.second.get<std::string>("arguments"));
+        }
+
+        for (auto &debug_run_argument: root_pt.get_child(("debug_run_arguments"))) {
+            auto path = debug_run_argument.second.get<std::string>("path");
+            boost::system::error_code ec;
+            if (boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec))
+                Project::debug_run_arguments.emplace(path, Project::DebugRunArguments{
+                        debug_run_argument.second.get<std::string>("arguments"),
+                        debug_run_argument.second.get<bool>("remote_enabled"),
+                        debug_run_argument.second.get<std::string>("remote_host_port")});
+        }
+
+        auto window_pt = root_pt.get_child("window");
+        set_default_size(window_pt.get<int>("width"), window_pt.get<int>("height"));
     }
-    
-    for(auto &debug_run_argument: root_pt.get_child(("debug_run_arguments"))) {
-      auto path=debug_run_argument.second.get<std::string>("path");
-      boost::system::error_code ec;
-      if(boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec))
-        Project::debug_run_arguments.emplace(path, Project::DebugRunArguments{debug_run_argument.second.get<std::string>("arguments"),
-                                                                              debug_run_argument.second.get<bool>("remote_enabled"),
-                                                                              debug_run_argument.second.get<std::string>("remote_host_port")});
+    catch (...) {
+        set_default_size(800, 600);
     }
-    
-    auto window_pt=root_pt.get_child("window");
-    set_default_size(window_pt.get<int>("width"), window_pt.get<int>("height"));
-  }
-  catch(...) {
-    set_default_size(800, 600);
-  }
 }
diff --git a/src/window.h b/src/window.h
index fa9b32d8..7f9b062e 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1,40 +1,55 @@
 #pragma once
+
 #include <gtkmm.h>
 #include <atomic>
 #include <boost/filesystem.hpp>
 
 class Window : public Gtk::ApplicationWindow {
-  Window();
+    Window();
+
 public:
-  static Window &get() {
-    static Window singleton;
-    return singleton;
-  }
-  void add_widgets();
-  void save_session();
-  void load_session(std::vector<boost::filesystem::path> &directories, std::vector<std::pair<boost::filesystem::path, size_t>> &files, std::vector<std::pair<int, int>> &file_offsets, std::string &current_file, bool read_directories_and_files);
+    static Window &get() {
+        static Window singleton;
+        return singleton;
+    }
+
+    void add_widgets();
+
+    void save_session();
+
+    void load_session(std::vector<boost::filesystem::path> &directories,
+                      std::vector<std::pair<boost::filesystem::path, size_t>> &files,
+                      std::vector<std::pair<int, int>> &file_offsets, std::string &current_file,
+                      bool read_directories_and_files);
 
 protected:
-  bool on_key_press_event(GdkEventKey *event) override;
-  bool on_delete_event(GdkEventAny *event) override;
+    bool on_key_press_event(GdkEventKey *event) override;
+
+    bool on_delete_event(GdkEventAny *event) override;
 
 private:
-  Gtk::AboutDialog about;
-  
-  Glib::RefPtr<Gtk::CssProvider> css_provider_theme;
-  Glib::RefPtr<Gtk::CssProvider> css_provider_tooltips;
-
-  void configure();
-  void set_menu_actions();
-  void search_and_replace_entry();
-  void set_tab_entry();
-  void goto_line_entry();
-  void rename_token_entry();
-  std::string last_search;
-  std::string last_replace;
-  std::string last_run_command;
-  std::string last_run_debug_command;
-  bool case_sensitive_search=true;
-  bool regex_search=false;
-  bool search_entry_shown=false;
+    Gtk::AboutDialog about;
+
+    Glib::RefPtr<Gtk::CssProvider> css_provider_theme;
+    Glib::RefPtr<Gtk::CssProvider> css_provider_tooltips;
+
+    void configure();
+
+    void set_menu_actions();
+
+    void search_and_replace_entry();
+
+    void set_tab_entry();
+
+    void goto_line_entry();
+
+    void rename_token_entry();
+
+    std::string last_search;
+    std::string last_replace;
+    std::string last_run_command;
+    std::string last_run_debug_command;
+    bool case_sensitive_search = true;
+    bool regex_search = false;
+    bool search_entry_shown = false;
 };

From 0892e40f74dead347589209403bef8bff4b18a3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BA=88=E9=A1=BA=20=E5=88=98?= <yshliu0321@icloud.com>
Date: Fri, 18 May 2018 18:26:33 +0800
Subject: [PATCH 02/12] Make Things Compile

---
 src/buildsystem/buildsystem.h     | 9 ++++++---
 src/documentation_cppreference.cc | 6 ++----
 src/project_build.cc              | 2 +-
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/buildsystem/buildsystem.h b/src/buildsystem/buildsystem.h
index d384bec2..764e5928 100644
--- a/src/buildsystem/buildsystem.h
+++ b/src/buildsystem/buildsystem.h
@@ -5,15 +5,18 @@
 
 class BuildSystemBase {
 public:
+    virtual ~BuildSystemBase() = default;
+
     auto get_project_path() const { return project_path; }
+
     void set_project_path(const boost::filesystem::path& rhs) { project_path = rhs; }
 
-    virtual bool update_default_build(const boost::filesystem::path &default_build_path, bool force = false);
+    virtual bool update_default_build(const boost::filesystem::path &default_build_path, bool force = false) = 0;
 
-    virtual bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force = false);
+    virtual bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force = false) = 0;
 
     virtual boost::filesystem::path
-    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
+    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) = 0;
 
 private:
     boost::filesystem::path project_path;
diff --git a/src/documentation_cppreference.cc b/src/documentation_cppreference.cc
index ef7365bd..7dc5fbe0 100644
--- a/src/documentation_cppreference.cc
+++ b/src/documentation_cppreference.cc
@@ -1,7 +1,5 @@
-#include
-"documentation_cppreference.h"
-#include
-<unordered_map>
+#include "documentation_cppreference.h"
+#include <unordered_map>
 
 std::string Documentation::CppReference::get_url(const std::string symbol) noexcept {
 // Copied from http://upload.cppreference.com/mwiki/images/d/df/html_book_20170409.zip/reference/cppreference-export-ns0,4,8,10.xml
diff --git a/src/project_build.cc b/src/project_build.cc
index b756f592..ca050a2c 100644
--- a/src/project_build.cc
+++ b/src/project_build.cc
@@ -98,7 +98,7 @@ boost::filesystem::path Project::Build::get_debug_path() {
 }
 
 Project::CMakeBuild::CMakeBuild(const boost::filesystem::path &path) : Project::Build(), cmake(path) {
-    project_path = cmake.project_path;
+    project_path = cmake.get_project_path();
 }
 
 bool Project::CMakeBuild::update_default(bool force) {

From d8ffec5e8cdd1331677ad281b547a0f7f272db10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BA=88=E9=A1=BA=20=E5=88=98?= <yshliu0321@icloud.com>
Date: Fri, 18 May 2018 21:50:15 +0800
Subject: [PATCH 03/12] refactor

---
 src/buildsystem/buildsystem.cc | 49 ++++++++++++++++++++++++++++++
 src/buildsystem/buildsystem.h  | 14 +++++----
 src/buildsystem/cmake.cc       | 47 ++---------------------------
 src/buildsystem/cmake.h        |  4 +--
 src/buildsystem/meson.cc       | 55 +++++-----------------------------
 src/buildsystem/meson.h        | 15 ++++------
 src/project_build.cc           |  2 +-
 7 files changed, 76 insertions(+), 110 deletions(-)
 create mode 100644 src/buildsystem/buildsystem.cc

diff --git a/src/buildsystem/buildsystem.cc b/src/buildsystem/buildsystem.cc
new file mode 100644
index 00000000..0d528364
--- /dev/null
+++ b/src/buildsystem/buildsystem.cc
@@ -0,0 +1,49 @@
+#include <regex>
+#include "meson.h"
+#include "buildsystem.h"
+#include "../terminal.h"
+#include "../filesystem.h"
+
+bool BuildSystemBase::create_build_directory(const boost::filesystem::path &build_path) {
+    if (!boost::filesystem::exists(build_path)) {
+        boost::system::error_code ec;
+        boost::filesystem::create_directories(build_path, ec);
+        if (ec) {
+            Terminal::get().print("Error: could not create " + build_path.string() + ": " + ec.message() + "\n",
+                                  true);
+            return false;
+        }
+    }
+    return true;
+}
+
+namespace {
+    bool find_project_impl(const boost::filesystem::path &file_path) {
+        for (auto &line: filesystem::read_lines(file_path)) {
+            const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
+            std::smatch sm;
+            if (std::regex_match(line, sm, project_regex))
+                return true;
+        }
+        return false;
+    }
+
+    boost::filesystem::path find_project(const boost::filesystem::path &path, const std::string &filename) {
+        auto search_path = is_directory(path) ? path : path.parent_path();
+        while (true) {
+            auto search_file = search_path / filename;
+            if (exists(search_file)) {
+                if (find_project_impl(search_file)) {
+                    return search_path;
+                }
+            }
+            if (search_path == search_path.root_directory())
+                break;
+            search_path = search_path.parent_path();
+        }
+        return "";
+    }
+}
+
+BuildSystemBase::BuildSystemBase(const boost::filesystem::path &path, const std::string &filename) : project_path(
+        find_project(path, filename)) {}
diff --git a/src/buildsystem/buildsystem.h b/src/buildsystem/buildsystem.h
index 764e5928..962748ab 100644
--- a/src/buildsystem/buildsystem.h
+++ b/src/buildsystem/buildsystem.h
@@ -5,19 +5,21 @@
 
 class BuildSystemBase {
 public:
-    virtual ~BuildSystemBase() = default;
+    BuildSystemBase(const boost::filesystem::path &path, const std::string &filename);
 
-    auto get_project_path() const { return project_path; }
+    virtual ~BuildSystemBase() = default;
 
-    void set_project_path(const boost::filesystem::path& rhs) { project_path = rhs; }
+    auto& get_project_path() const { return project_path; }
 
-    virtual bool update_default_build(const boost::filesystem::path &default_build_path, bool force = false) = 0;
+    virtual bool update_default_build(const boost::filesystem::path &default_build_path, bool force) = 0;
 
-    virtual bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force = false) = 0;
+    virtual bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) = 0;
 
     virtual boost::filesystem::path
     get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) = 0;
 
+protected:
+    static bool create_build_directory(const boost::filesystem::path &build_path);
 private:
-    boost::filesystem::path project_path;
+    const boost::filesystem::path project_path;
 };
diff --git a/src/buildsystem/cmake.cc b/src/buildsystem/cmake.cc
index c656c536..c2a5d39b 100644
--- a/src/buildsystem/cmake.cc
+++ b/src/buildsystem/cmake.cc
@@ -6,47 +6,14 @@
 #include <regex>
 #include "../compile_commands.h"
 
-CMake::CMake(const boost::filesystem::path &path) {
-    const auto find_cmake_project = [](const boost::filesystem::path &cmake_path) {
-        for (auto &line: filesystem::read_lines(cmake_path)) {
-            const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
-            std::smatch sm;
-            if (std::regex_match(line, sm, project_regex))
-                return true;
-        }
-        return false;
-    };
-
-    auto search_path = boost::filesystem::is_directory(path) ? path : path.parent_path();
-    while (true) {
-        auto search_cmake_path = search_path / "CMakeLists.txt";
-        if (boost::filesystem::exists(search_cmake_path)) {
-            paths.emplace(paths.begin(), search_cmake_path);
-            if (find_cmake_project(search_cmake_path)) {
-                set_project_path(search_path);
-                break;
-            }
-        }
-        if (search_path == search_path.root_directory())
-            break;
-        search_path = search_path.parent_path();
-    }
-}
+CMake::CMake(const boost::filesystem::path &path): BuildSystemBase(path, "CMakeLists.txt") {}
 
 bool CMake::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
     if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "CMakeLists.txt") ||
         default_build_path.empty())
         return false;
 
-    if (!boost::filesystem::exists(default_build_path)) {
-        boost::system::error_code ec;
-        boost::filesystem::create_directories(default_build_path, ec);
-        if (ec) {
-            Terminal::get().print("Error: could not create " + default_build_path.string() + ": " + ec.message() + "\n",
-                                  true);
-            return false;
-        }
-    }
+    if (!create_build_directory(default_build_path)) return false;
 
     if (!force && boost::filesystem::exists(default_build_path / "compile_commands.json"))
         return true;
@@ -84,15 +51,7 @@ bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path,
     if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "CMakeLists.txt") || debug_build_path.empty())
         return false;
 
-    if (!boost::filesystem::exists(debug_build_path)) {
-        boost::system::error_code ec;
-        boost::filesystem::create_directories(debug_build_path, ec);
-        if (ec) {
-            Terminal::get().print("Error: could not create " + debug_build_path.string() + ": " + ec.message() + "\n",
-                                  true);
-            return false;
-        }
-    }
+    if (!create_build_directory(debug_build_path)) return false;
 
     if (!force && boost::filesystem::exists(debug_build_path / "CMakeCache.txt"))
         return true;
diff --git a/src/buildsystem/cmake.h b/src/buildsystem/cmake.h
index 9ea4c41b..0f44b7a0 100644
--- a/src/buildsystem/cmake.h
+++ b/src/buildsystem/cmake.h
@@ -8,9 +8,9 @@ class CMake : public BuildSystemBase {
 public:
     CMake(const boost::filesystem::path &path);
 
-    bool update_default_build(const boost::filesystem::path &default_build_path, bool force = false) override;
+    bool update_default_build(const boost::filesystem::path &default_build_path, bool force) override;
 
-    bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force = false) override;
+    bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) override;
 
     boost::filesystem::path
     get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
diff --git a/src/buildsystem/meson.cc b/src/buildsystem/meson.cc
index 9b2b994c..a81584a3 100644
--- a/src/buildsystem/meson.cc
+++ b/src/buildsystem/meson.cc
@@ -1,50 +1,17 @@
 #include "meson.h"
 #include "../filesystem.h"
 #include "../compile_commands.h"
-#include <regex>
 #include "../terminal.h"
 #include "../dialogs.h"
 #include "../config.h"
 
-Meson::Meson(const boost::filesystem::path &path) {
-    const auto find_project = [](const boost::filesystem::path &file_path) {
-        for (auto &line: filesystem::read_lines(file_path)) {
-            const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
-            std::smatch sm;
-            if (std::regex_match(line, sm, project_regex))
-                return true;
-        }
-        return false;
-    };
-
-    auto search_path = boost::filesystem::is_directory(path) ? path : path.parent_path();
-    while (true) {
-        auto search_file = search_path / "meson.build";
-        if (boost::filesystem::exists(search_file)) {
-            if (find_project(search_file)) {
-                project_path = search_path;
-                break;
-            }
-        }
-        if (search_path == search_path.root_directory())
-            break;
-        search_path = search_path.parent_path();
-    }
-}
+Meson::Meson(const boost::filesystem::path &path): BuildSystemBase(path, "meson.build") {}
 
 bool Meson::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
-    if (project_path.empty() || !boost::filesystem::exists(project_path / "meson.build") || default_build_path.empty())
+    if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") || default_build_path.empty())
         return false;
 
-    if (!boost::filesystem::exists(default_build_path)) {
-        boost::system::error_code ec;
-        boost::filesystem::create_directories(default_build_path, ec);
-        if (ec) {
-            Terminal::get().print("Error: could not create " + default_build_path.string() + ": " + ec.message() + "\n",
-                                  true);
-            return false;
-        }
-    }
+    if (!create_build_directory(default_build_path)) return false;
 
     auto compile_commands_path = default_build_path / "compile_commands.json";
     bool compile_commands_exists = boost::filesystem::exists(compile_commands_path);
@@ -54,7 +21,7 @@ bool Meson::update_default_build(const boost::filesystem::path &default_build_pa
     Dialog::Message message("Creating/updating default build");
     auto exit_status = Terminal::get().process(
             Config::get().project.meson.command + ' ' + (compile_commands_exists ? "--internal regenerate " : "") +
-            filesystem::escape_argument(project_path.string()), default_build_path);
+            filesystem::escape_argument(get_project_path().string()), default_build_path);
     message.hide();
     if (exit_status == EXIT_SUCCESS)
         return true;
@@ -62,18 +29,10 @@ bool Meson::update_default_build(const boost::filesystem::path &default_build_pa
 }
 
 bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-    if (project_path.empty() || !boost::filesystem::exists(project_path / "meson.build") || debug_build_path.empty())
+    if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") || debug_build_path.empty())
         return false;
 
-    if (!boost::filesystem::exists(debug_build_path)) {
-        boost::system::error_code ec;
-        boost::filesystem::create_directories(debug_build_path, ec);
-        if (ec) {
-            Terminal::get().print("Error: could not create " + debug_build_path.string() + ": " + ec.message() + "\n",
-                                  true);
-            return false;
-        }
-    }
+    if (!create_build_directory(debug_build_path)) return false;
 
     bool compile_commands_exists = boost::filesystem::exists(debug_build_path / "compile_commands.json");
     if (!force && compile_commands_exists)
@@ -82,7 +41,7 @@ bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path,
     Dialog::Message message("Creating/updating debug build");
     auto exit_status = Terminal::get().process(
             Config::get().project.meson.command + ' ' + (compile_commands_exists ? "--internal regenerate " : "") +
-            "--buildtype debug " + filesystem::escape_argument(project_path.string()), debug_build_path);
+            "--buildtype debug " + filesystem::escape_argument(get_project_path().string()), debug_build_path);
     message.hide();
     if (exit_status == EXIT_SUCCESS)
         return true;
diff --git a/src/buildsystem/meson.h b/src/buildsystem/meson.h
index 17b9a540..d22625d3 100644
--- a/src/buildsystem/meson.h
+++ b/src/buildsystem/meson.h
@@ -1,18 +1,15 @@
 #pragma once
 
-#include <boost/filesystem.hpp>
-#include <vector>
-
-class Meson {
+#include "buildsystem.h"
+class Meson : public BuildSystemBase {
 public:
     Meson(const boost::filesystem::path &path);
 
-    boost::filesystem::path project_path;
-
-    bool update_default_build(const boost::filesystem::path &default_build_path, bool force = false);
+    bool update_default_build(const boost::filesystem::path &default_build_path, bool force) override;
 
-    bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force = false);
+    bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) override;
 
     boost::filesystem::path
-    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
+    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
+
 };
diff --git a/src/project_build.cc b/src/project_build.cc
index ca050a2c..d3294916 100644
--- a/src/project_build.cc
+++ b/src/project_build.cc
@@ -118,7 +118,7 @@ boost::filesystem::path Project::CMakeBuild::get_executable(const boost::filesys
 }
 
 Project::MesonBuild::MesonBuild(const boost::filesystem::path &path) : Project::Build(), meson(path) {
-    project_path = meson.project_path;
+    project_path = meson.get_project_path();
 }
 
 bool Project::MesonBuild::update_default(bool force) {

From c09cf8ba8c8550d2d227bc0af6e0067de9564e83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E4=BA=88=E9=A1=BA?= <ys_37677@126.com>
Date: Mon, 21 May 2018 17:05:54 +0800
Subject: [PATCH 04/12] Move Files

---
 src/{buildsystem => }/buildsystem.cc |  4 ++--
 src/{buildsystem => }/buildsystem.h  |  0
 src/{buildsystem => }/cmake.cc       | 10 +++++-----
 src/{buildsystem => }/cmake.h        |  0
 src/{buildsystem => }/meson.cc       | 10 +++++-----
 src/{buildsystem => }/meson.h        |  0
 src/project_build.h                  |  4 ++--
 7 files changed, 14 insertions(+), 14 deletions(-)
 rename src/{buildsystem => }/buildsystem.cc (97%)
 rename src/{buildsystem => }/buildsystem.h (100%)
 rename src/{buildsystem => }/cmake.cc (99%)
 rename src/{buildsystem => }/cmake.h (100%)
 rename src/{buildsystem => }/meson.cc (96%)
 rename src/{buildsystem => }/meson.h (100%)

diff --git a/src/buildsystem/buildsystem.cc b/src/buildsystem.cc
similarity index 97%
rename from src/buildsystem/buildsystem.cc
rename to src/buildsystem.cc
index 0d528364..cd0f075a 100644
--- a/src/buildsystem/buildsystem.cc
+++ b/src/buildsystem.cc
@@ -1,8 +1,8 @@
 #include <regex>
 #include "meson.h"
 #include "buildsystem.h"
-#include "../terminal.h"
-#include "../filesystem.h"
+#include "terminal.h"
+#include "filesystem.h"
 
 bool BuildSystemBase::create_build_directory(const boost::filesystem::path &build_path) {
     if (!boost::filesystem::exists(build_path)) {
diff --git a/src/buildsystem/buildsystem.h b/src/buildsystem.h
similarity index 100%
rename from src/buildsystem/buildsystem.h
rename to src/buildsystem.h
diff --git a/src/buildsystem/cmake.cc b/src/cmake.cc
similarity index 99%
rename from src/buildsystem/cmake.cc
rename to src/cmake.cc
index c2a5d39b..d61f05b8 100644
--- a/src/buildsystem/cmake.cc
+++ b/src/cmake.cc
@@ -1,10 +1,10 @@
 #include "cmake.h"
-#include "../filesystem.h"
-#include "../dialogs.h"
-#include "../config.h"
-#include "../terminal.h"
+#include "filesystem.h"
+#include "dialogs.h"
+#include "config.h"
+#include "terminal.h"
 #include <regex>
-#include "../compile_commands.h"
+#include "compile_commands.h"
 
 CMake::CMake(const boost::filesystem::path &path): BuildSystemBase(path, "CMakeLists.txt") {}
 
diff --git a/src/buildsystem/cmake.h b/src/cmake.h
similarity index 100%
rename from src/buildsystem/cmake.h
rename to src/cmake.h
diff --git a/src/buildsystem/meson.cc b/src/meson.cc
similarity index 96%
rename from src/buildsystem/meson.cc
rename to src/meson.cc
index a81584a3..3bc43006 100644
--- a/src/buildsystem/meson.cc
+++ b/src/meson.cc
@@ -1,9 +1,9 @@
 #include "meson.h"
-#include "../filesystem.h"
-#include "../compile_commands.h"
-#include "../terminal.h"
-#include "../dialogs.h"
-#include "../config.h"
+#include "filesystem.h"
+#include "compile_commands.h"
+#include "terminal.h"
+#include "dialogs.h"
+#include "config.h"
 
 Meson::Meson(const boost::filesystem::path &path): BuildSystemBase(path, "meson.build") {}
 
diff --git a/src/buildsystem/meson.h b/src/meson.h
similarity index 100%
rename from src/buildsystem/meson.h
rename to src/meson.h
diff --git a/src/project_build.h b/src/project_build.h
index 0900a851..8720ea30 100644
--- a/src/project_build.h
+++ b/src/project_build.h
@@ -1,8 +1,8 @@
 #pragma once
 
 #include <boost/filesystem.hpp>
-#include "buildsystem/cmake.h"
-#include "buildsystem/meson.h"
+#include "cmake.h"
+#include "meson.h"
 
 namespace Project {
     class Build {

From 76319bbf0c7ad2b4768059a3d8c978da95b7b326 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E4=BA=88=E9=A1=BA?= <ys_37677@126.com>
Date: Mon, 21 May 2018 17:13:03 +0800
Subject: [PATCH 05/12] Reintendent

---
 src/autocomplete.cc               |  320 +-
 src/autocomplete.h                |   78 +-
 src/buildsystem.cc                |   62 +-
 src/buildsystem.h                 |   19 +-
 src/cmake.cc                      |  533 +--
 src/cmake.h                       |   36 +-
 src/compile_commands.cc           |  282 +-
 src/compile_commands.h            |   24 +-
 src/config.cc                     |  340 +-
 src/config.h                      |  200 +-
 src/ctags.cc                      |  338 +-
 src/ctags.h                       |   32 +-
 src/debug_lldb.cc                 |  846 ++---
 src/debug_lldb.h                  |  140 +-
 src/dialogs.cc                    |  112 +-
 src/dialogs.h                     |   28 +-
 src/dialogs_unix.cc               |   30 +-
 src/dialogs_win.cc                |  248 +-
 src/directories.cc                | 1272 +++----
 src/directories.h                 |  130 +-
 src/dispatcher.cc                 |   40 +-
 src/dispatcher.h                  |   28 +-
 src/documentation_cppreference.cc |   59 +-
 src/documentation_cppreference.h  |    8 +-
 src/entrybox.cc                   |  150 +-
 src/entrybox.h                    |   76 +-
 src/filesystem.cc                 |  354 +-
 src/filesystem.h                  |   56 +-
 src/git.cc                        |  473 ++-
 src/git.h                         |  162 +-
 src/info.cc                       |   50 +-
 src/info.h                        |   16 +-
 src/juci.cc                       |  201 +-
 src/juci.h                        |   14 +-
 src/menu.cc                       |   54 +-
 src/menu.h                        |   30 +-
 src/meson.cc                      |  110 +-
 src/meson.h                       |   11 +-
 src/notebook.cc                   | 1124 +++---
 src/notebook.h                    |  126 +-
 src/project.cc                    |  932 ++---
 src/project.h                     |  254 +-
 src/project_build.cc              |  186 +-
 src/project_build.h               |   90 +-
 src/selection_dialog.cc           |  778 ++---
 src/selection_dialog.h            |  158 +-
 src/source.cc                     | 5278 ++++++++++++++---------------
 src/source.h                      |  278 +-
 src/source_base.cc                |  582 ++--
 src/source_base.h                 |  138 +-
 src/source_clang.cc               | 3438 +++++++++----------
 src/source_clang.h                |  184 +-
 src/source_diff.cc                |  616 ++--
 src/source_diff.h                 |   98 +-
 src/source_language_protocol.cc   | 2766 +++++++--------
 src/source_language_protocol.h    |  188 +-
 src/source_spellcheck.cc          |  858 ++---
 src/source_spellcheck.h           |   62 +-
 src/terminal.cc                   |  692 ++--
 src/terminal.h                    |   62 +-
 src/tooltips.cc                   |  410 +--
 src/tooltips.h                    |   68 +-
 src/usages_clang.cc               | 1204 +++----
 src/usages_clang.h                |  282 +-
 src/window.cc                     | 3200 ++++++++---------
 src/window.h                      |   58 +-
 66 files changed, 15538 insertions(+), 15534 deletions(-)

diff --git a/src/autocomplete.cc b/src/autocomplete.cc
index 374e25c7..03c0dcf9 100644
--- a/src/autocomplete.cc
+++ b/src/autocomplete.cc
@@ -2,178 +2,178 @@
 #include "selection_dialog.h"
 
 Autocomplete::Autocomplete(Gtk::TextView *view, bool &interactive_completion, guint &last_keyval, bool strip_word)
-        : view(view), interactive_completion(interactive_completion), strip_word(strip_word), state(State::IDLE) {
-    view->get_buffer()->signal_changed().connect([this, &last_keyval] {
-        if (CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
-            cancel_reparse();
-            return;
-        }
-        if (!this->view->has_focus())
-            return;
-        if (is_continue_key(last_keyval) && (this->interactive_completion || state != State::IDLE))
-            run();
-        else {
-            stop();
-
-            if (is_restart_key(last_keyval) && this->interactive_completion)
-                run();
-        }
-    });
+    : view(view), interactive_completion(interactive_completion), strip_word(strip_word), state(State::IDLE) {
+  view->get_buffer()->signal_changed().connect([this, &last_keyval] {
+    if (CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
+      cancel_reparse();
+      return;
+    }
+    if (!this->view->has_focus())
+      return;
+    if (is_continue_key(last_keyval) && (this->interactive_completion || state != State::IDLE))
+      run();
+    else {
+      stop();
+
+      if (is_restart_key(last_keyval) && this->interactive_completion)
+        run();
+    }
+  });
+
+  view->get_buffer()->signal_mark_set().connect(
+      [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+        if (mark->get_name() == "insert")
+          stop();
+      });
+
+  view->signal_key_release_event().connect([](GdkEventKey *key) {
+    if (CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
+      if (CompletionDialog::get()->on_key_release(key))
+        return true;
+    }
+    return false;
+  }, false);
 
-    view->get_buffer()->signal_mark_set().connect(
-            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-                if (mark->get_name() == "insert")
-                    stop();
-            });
-
-    view->signal_key_release_event().connect([](GdkEventKey *key) {
-        if (CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
-            if (CompletionDialog::get()->on_key_release(key))
-                return true;
-        }
-        return false;
-    }, false);
-
-    view->signal_focus_out_event().connect([this](GdkEventFocus *event) {
-        stop();
-        return false;
-    });
+  view->signal_focus_out_event().connect([this](GdkEventFocus *event) {
+    stop();
+    return false;
+  });
 }
 
 void Autocomplete::run() {
-    if (run_check()) {
-        if (!is_processing())
-            return;
-
-        if (state == State::CANCELED)
-            state = State::RESTARTING;
-
-        if (state != State::IDLE)
-            return;
-
-        state = State::STARTING;
-
-        before_add_rows();
-
-        if (thread.joinable())
-            thread.join();
-        auto buffer = view->get_buffer()->get_text();
-        auto iter = view->get_buffer()->get_insert()->get_iter();
-        auto line_nr = iter.get_line() + 1;
-        auto column_nr = iter.get_line_index() + 1;
-        if (strip_word) {
-            auto pos = iter.get_offset() - 1;
-            while (pos >= 0 &&
-                   ((buffer[pos] >= 'a' && buffer[pos] <= 'z') || (buffer[pos] >= 'A' && buffer[pos] <= 'Z') ||
-                    (buffer[pos] >= '0' && buffer[pos] <= '9') || buffer[pos] == '_')) {
-                buffer.replace(pos, 1, " ");
-                column_nr--;
-                pos--;
+  if (run_check()) {
+    if (!is_processing())
+      return;
+
+    if (state == State::CANCELED)
+      state = State::RESTARTING;
+
+    if (state != State::IDLE)
+      return;
+
+    state = State::STARTING;
+
+    before_add_rows();
+
+    if (thread.joinable())
+      thread.join();
+    auto buffer = view->get_buffer()->get_text();
+    auto iter = view->get_buffer()->get_insert()->get_iter();
+    auto line_nr = iter.get_line() + 1;
+    auto column_nr = iter.get_line_index() + 1;
+    if (strip_word) {
+      auto pos = iter.get_offset() - 1;
+      while (pos >= 0 &&
+             ((buffer[pos] >= 'a' && buffer[pos] <= 'z') || (buffer[pos] >= 'A' && buffer[pos] <= 'Z') ||
+              (buffer[pos] >= '0' && buffer[pos] <= '9') || buffer[pos] == '_')) {
+        buffer.replace(pos, 1, " ");
+        column_nr--;
+        pos--;
+      }
+    }
+    thread = std::thread([this, line_nr, column_nr, buffer = std::move(buffer)] {
+      auto lock = get_parse_lock();
+      if (!is_processing())
+        return;
+      stop_parse();
+
+      auto &buffer_raw = const_cast<std::string &>(buffer.raw());
+      rows.clear();
+      add_rows(buffer_raw, line_nr, column_nr);
+
+      if (is_processing()) {
+        dispatcher.post([this]() {
+          after_add_rows();
+          if (state == State::RESTARTING) {
+            state = State::IDLE;
+            reparse();
+            run();
+          } else if (state == State::CANCELED || rows.empty()) {
+            state = State::IDLE;
+            reparse();
+          } else {
+            auto start_iter = view->get_buffer()->get_insert()->get_iter();
+            if (prefix.size() > 0 && !start_iter.backward_chars(prefix.size())) {
+              state = State::IDLE;
+              reparse();
+              return;
             }
-        }
-        thread = std::thread([this, line_nr, column_nr, buffer = std::move(buffer)] {
-            auto lock = get_parse_lock();
-            if (!is_processing())
-                return;
-            stop_parse();
-
-            auto &buffer_raw = const_cast<std::string &>(buffer.raw());
-            rows.clear();
-            add_rows(buffer_raw, line_nr, column_nr);
-
-            if (is_processing()) {
-                dispatcher.post([this]() {
-                    after_add_rows();
-                    if (state == State::RESTARTING) {
-                        state = State::IDLE;
-                        reparse();
-                        run();
-                    } else if (state == State::CANCELED || rows.empty()) {
-                        state = State::IDLE;
-                        reparse();
-                    } else {
-                        auto start_iter = view->get_buffer()->get_insert()->get_iter();
-                        if (prefix.size() > 0 && !start_iter.backward_chars(prefix.size())) {
-                            state = State::IDLE;
-                            reparse();
-                            return;
-                        }
-                        CompletionDialog::create(view, view->get_buffer()->create_mark(start_iter));
-                        setup_dialog();
-                        for (auto &row : rows) {
-                            CompletionDialog::get()->add_row(row);
-                            row.clear();
-                        }
-                        state = State::IDLE;
-
-                        view->get_buffer()->begin_user_action();
-                        CompletionDialog::get()->show();
-                    }
-                });
-            } else {
-                dispatcher.post([this] {
-                    state = State::CANCELED;
-                    on_add_rows_error();
-                });
+            CompletionDialog::create(view, view->get_buffer()->create_mark(start_iter));
+            setup_dialog();
+            for (auto &row : rows) {
+              CompletionDialog::get()->add_row(row);
+              row.clear();
             }
+            state = State::IDLE;
+
+            view->get_buffer()->begin_user_action();
+            CompletionDialog::get()->show();
+          }
         });
-    }
+      } else {
+        dispatcher.post([this] {
+          state = State::CANCELED;
+          on_add_rows_error();
+        });
+      }
+    });
+  }
 
-    if (state != State::IDLE)
-        cancel_reparse();
+  if (state != State::IDLE)
+    cancel_reparse();
 }
 
 void Autocomplete::stop() {
-    if (state == State::STARTING || state == State::RESTARTING)
-        state = State::CANCELED;
+  if (state == State::STARTING || state == State::RESTARTING)
+    state = State::CANCELED;
 }
 
 void Autocomplete::setup_dialog() {
-    CompletionDialog::get()->on_show = [this] {
-        on_show();
-    };
-
-    CompletionDialog::get()->on_hide = [this]() {
-        view->get_buffer()->end_user_action();
-        tooltips.hide();
-        tooltips.clear();
-        on_hide();
-        reparse();
-    };
-
-    CompletionDialog::get()->on_changed = [this](unsigned int index, const std::string &text) {
-        if (index >= rows.size()) {
-            tooltips.hide();
-            return;
-        }
-
-        on_changed(index, text);
-
-        auto tooltip = get_tooltip(index);
-        if (tooltip.empty())
-            tooltips.hide();
-        else {
-            tooltips.clear();
-            auto create_tooltip_buffer = [this, tooltip = std::move(tooltip)]() {
-                auto tooltip_buffer = Gtk::TextBuffer::create(view->get_buffer()->get_tag_table());
-
-                tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), tooltip);
-
-                return tooltip_buffer;
-            };
-
-            auto iter = CompletionDialog::get()->start_mark->get_iter();
-            tooltips.emplace_back(create_tooltip_buffer, view, view->get_buffer()->create_mark(iter),
-                                  view->get_buffer()->create_mark(iter));
-
-            tooltips.show(true);
-        }
-    };
-
-    CompletionDialog::get()->on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
-        if (index >= rows.size())
-            return;
-
-        on_select(index, text, hide_window);
-    };
+  CompletionDialog::get()->on_show = [this] {
+    on_show();
+  };
+
+  CompletionDialog::get()->on_hide = [this]() {
+    view->get_buffer()->end_user_action();
+    tooltips.hide();
+    tooltips.clear();
+    on_hide();
+    reparse();
+  };
+
+  CompletionDialog::get()->on_changed = [this](unsigned int index, const std::string &text) {
+    if (index >= rows.size()) {
+      tooltips.hide();
+      return;
+    }
+
+    on_changed(index, text);
+
+    auto tooltip = get_tooltip(index);
+    if (tooltip.empty())
+      tooltips.hide();
+    else {
+      tooltips.clear();
+      auto create_tooltip_buffer = [this, tooltip = std::move(tooltip)]() {
+        auto tooltip_buffer = Gtk::TextBuffer::create(view->get_buffer()->get_tag_table());
+
+        tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), tooltip);
+
+        return tooltip_buffer;
+      };
+
+      auto iter = CompletionDialog::get()->start_mark->get_iter();
+      tooltips.emplace_back(create_tooltip_buffer, view, view->get_buffer()->create_mark(iter),
+                            view->get_buffer()->create_mark(iter));
+
+      tooltips.show(true);
+    }
+  };
+
+  CompletionDialog::get()->on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
+    if (index >= rows.size())
+      return;
+
+    on_select(index, text, hide_window);
+  };
 }
diff --git a/src/autocomplete.h b/src/autocomplete.h
index b808ca04..13a2500d 100644
--- a/src/autocomplete.h
+++ b/src/autocomplete.h
@@ -6,60 +6,60 @@
 #include <thread>
 
 class Autocomplete {
-    Gtk::TextView *view;
-    bool &interactive_completion;
-    /// Some libraries/utilities, like libclang, require that autocomplete is started at the beginning of a word
-    bool strip_word;
+  Gtk::TextView *view;
+  bool &interactive_completion;
+  /// Some libraries/utilities, like libclang, require that autocomplete is started at the beginning of a word
+  bool strip_word;
 
-    Dispatcher dispatcher;
+  Dispatcher dispatcher;
 
 public:
-    enum class State {
-        IDLE, STARTING, RESTARTING, CANCELED
-    };
+  enum class State {
+    IDLE, STARTING, RESTARTING, CANCELED
+  };
 
-    std::string prefix;
-    std::mutex prefix_mutex;
-    std::vector<std::string> rows;
-    Tooltips tooltips;
+  std::string prefix;
+  std::mutex prefix_mutex;
+  std::vector<std::string> rows;
+  Tooltips tooltips;
 
-    std::atomic<State> state;
+  std::atomic<State> state;
 
-    std::thread thread;
+  std::thread thread;
 
-    std::function<bool()> is_processing = [] { return true; };
-    std::function<void()> reparse = [] {};
-    std::function<void()> cancel_reparse = [] {};
-    std::function<std::unique_ptr<std::lock_guard<std::mutex>>()> get_parse_lock = [] { return nullptr; };
-    std::function<void()> stop_parse = [] {};
+  std::function<bool()> is_processing = [] { return true; };
+  std::function<void()> reparse = [] {};
+  std::function<void()> cancel_reparse = [] {};
+  std::function<std::unique_ptr<std::lock_guard<std::mutex>>()> get_parse_lock = [] { return nullptr; };
+  std::function<void()> stop_parse = [] {};
 
-    std::function<bool(guint last_keyval)> is_continue_key = [](guint) { return false; };
-    std::function<bool(guint last_keyval)> is_restart_key = [](guint) { return false; };
-    std::function<bool()> run_check = [] { return false; };
+  std::function<bool(guint last_keyval)> is_continue_key = [](guint) { return false; };
+  std::function<bool(guint last_keyval)> is_restart_key = [](guint) { return false; };
+  std::function<bool()> run_check = [] { return false; };
 
-    std::function<void()> before_add_rows = [] {};
-    std::function<void()> after_add_rows = [] {};
-    std::function<void()> on_add_rows_error = [] {};
+  std::function<void()> before_add_rows = [] {};
+  std::function<void()> after_add_rows = [] {};
+  std::function<void()> on_add_rows_error = [] {};
 
-    /// The handler is not run in the main loop.
-    std::function<void(std::string &buffer, int line_number, int column)> add_rows = [](std::string &, int, int) {};
+  /// The handler is not run in the main loop.
+  std::function<void(std::string &buffer, int line_number, int column)> add_rows = [](std::string &, int, int) {};
 
-    std::function<void()> on_show = [] {};
-    std::function<void()> on_hide = [] {};
-    std::function<void(unsigned int, const std::string &)> on_changed = [](unsigned int index,
-                                                                           const std::string &text) {};
-    std::function<void(unsigned int, const std::string &, bool)> on_select = [](unsigned int index,
-                                                                                const std::string &text,
-                                                                                bool hide_window) {};
+  std::function<void()> on_show = [] {};
+  std::function<void()> on_hide = [] {};
+  std::function<void(unsigned int, const std::string &)> on_changed = [](unsigned int index,
+                                                                         const std::string &text) {};
+  std::function<void(unsigned int, const std::string &, bool)> on_select = [](unsigned int index,
+                                                                              const std::string &text,
+                                                                              bool hide_window) {};
 
-    std::function<std::string(unsigned int)> get_tooltip = [](unsigned int index) { return std::string(); };
+  std::function<std::string(unsigned int)> get_tooltip = [](unsigned int index) { return std::string(); };
 
-    Autocomplete(Gtk::TextView *view, bool &interactive_completion, guint &last_keyval, bool strip_word);
+  Autocomplete(Gtk::TextView *view, bool &interactive_completion, guint &last_keyval, bool strip_word);
 
-    void run();
+  void run();
 
-    void stop();
+  void stop();
 
 private:
-    void setup_dialog();
+  void setup_dialog();
 };
diff --git a/src/buildsystem.cc b/src/buildsystem.cc
index cd0f075a..e6ddefae 100644
--- a/src/buildsystem.cc
+++ b/src/buildsystem.cc
@@ -5,45 +5,45 @@
 #include "filesystem.h"
 
 bool BuildSystemBase::create_build_directory(const boost::filesystem::path &build_path) {
-    if (!boost::filesystem::exists(build_path)) {
-        boost::system::error_code ec;
-        boost::filesystem::create_directories(build_path, ec);
-        if (ec) {
-            Terminal::get().print("Error: could not create " + build_path.string() + ": " + ec.message() + "\n",
-                                  true);
-            return false;
-        }
+  if (!boost::filesystem::exists(build_path)) {
+    boost::system::error_code ec;
+    boost::filesystem::create_directories(build_path, ec);
+    if (ec) {
+      Terminal::get().print("Error: could not create " + build_path.string() + ": " + ec.message() + "\n",
+                            true);
+      return false;
     }
-    return true;
+  }
+  return true;
 }
 
 namespace {
-    bool find_project_impl(const boost::filesystem::path &file_path) {
-        for (auto &line: filesystem::read_lines(file_path)) {
-            const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
-            std::smatch sm;
-            if (std::regex_match(line, sm, project_regex))
-                return true;
-        }
-        return false;
+  bool find_project_impl(const boost::filesystem::path &file_path) {
+    for (auto &line: filesystem::read_lines(file_path)) {
+      const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
+      std::smatch sm;
+      if (std::regex_match(line, sm, project_regex))
+        return true;
     }
+    return false;
+  }
 
-    boost::filesystem::path find_project(const boost::filesystem::path &path, const std::string &filename) {
-        auto search_path = is_directory(path) ? path : path.parent_path();
-        while (true) {
-            auto search_file = search_path / filename;
-            if (exists(search_file)) {
-                if (find_project_impl(search_file)) {
-                    return search_path;
-                }
-            }
-            if (search_path == search_path.root_directory())
-                break;
-            search_path = search_path.parent_path();
+  boost::filesystem::path find_project(const boost::filesystem::path &path, const std::string &filename) {
+    auto search_path = is_directory(path) ? path : path.parent_path();
+    while (true) {
+      auto search_file = search_path / filename;
+      if (exists(search_file)) {
+        if (find_project_impl(search_file)) {
+          return search_path;
         }
-        return "";
+      }
+      if (search_path == search_path.root_directory())
+        break;
+      search_path = search_path.parent_path();
     }
+    return "";
+  }
 }
 
 BuildSystemBase::BuildSystemBase(const boost::filesystem::path &path, const std::string &filename) : project_path(
-        find_project(path, filename)) {}
+    find_project(path, filename)) {}
diff --git a/src/buildsystem.h b/src/buildsystem.h
index 962748ab..202a5674 100644
--- a/src/buildsystem.h
+++ b/src/buildsystem.h
@@ -5,21 +5,22 @@
 
 class BuildSystemBase {
 public:
-    BuildSystemBase(const boost::filesystem::path &path, const std::string &filename);
+  BuildSystemBase(const boost::filesystem::path &path, const std::string &filename);
 
-    virtual ~BuildSystemBase() = default;
+  virtual ~BuildSystemBase() = default;
 
-    auto& get_project_path() const { return project_path; }
+  auto &get_project_path() const { return project_path; }
 
-    virtual bool update_default_build(const boost::filesystem::path &default_build_path, bool force) = 0;
+  virtual bool update_default_build(const boost::filesystem::path &default_build_path, bool force) = 0;
 
-    virtual bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) = 0;
+  virtual bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) = 0;
 
-    virtual boost::filesystem::path
-    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) = 0;
+  virtual boost::filesystem::path
+  get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) = 0;
 
 protected:
-    static bool create_build_directory(const boost::filesystem::path &build_path);
+  static bool create_build_directory(const boost::filesystem::path &build_path);
+
 private:
-    const boost::filesystem::path project_path;
+  const boost::filesystem::path project_path;
 };
diff --git a/src/cmake.cc b/src/cmake.cc
index d61f05b8..b67573c9 100644
--- a/src/cmake.cc
+++ b/src/cmake.cc
@@ -6,340 +6,341 @@
 #include <regex>
 #include "compile_commands.h"
 
-CMake::CMake(const boost::filesystem::path &path): BuildSystemBase(path, "CMakeLists.txt") {}
+CMake::CMake(const boost::filesystem::path &path) : BuildSystemBase(path, "CMakeLists.txt") {}
 
 bool CMake::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
-    if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "CMakeLists.txt") ||
-        default_build_path.empty())
-        return false;
+  if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "CMakeLists.txt") ||
+      default_build_path.empty())
+    return false;
 
-    if (!create_build_directory(default_build_path)) return false;
+  if (!create_build_directory(default_build_path)) return false;
 
-    if (!force && boost::filesystem::exists(default_build_path / "compile_commands.json"))
-        return true;
+  if (!force && boost::filesystem::exists(default_build_path / "compile_commands.json"))
+    return true;
 
-    auto compile_commands_path = default_build_path / "compile_commands.json";
-    Dialog::Message message("Creating/updating default build");
-    auto exit_status = Terminal::get().process(Config::get().project.cmake.command + ' ' +
-                                               filesystem::escape_argument(get_project_path().string()) +
-                                               " -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path);
-    message.hide();
-    if (exit_status == EXIT_SUCCESS) {
+  auto compile_commands_path = default_build_path / "compile_commands.json";
+  Dialog::Message message("Creating/updating default build");
+  auto exit_status = Terminal::get().process(Config::get().project.cmake.command + ' ' +
+                                             filesystem::escape_argument(get_project_path().string()) +
+                                             " -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path);
+  message.hide();
+  if (exit_status == EXIT_SUCCESS) {
 #ifdef _WIN32 //Temporary fix to MSYS2's libclang
-        auto compile_commands_file = filesystem::read(compile_commands_path);
-        auto replace_drive = [&compile_commands_file](const std::string &param) {
-            size_t pos = 0;
-            auto param_size = param.length();
-            while ((pos = compile_commands_file.find(param + "/", pos)) != std::string::npos) {
-                if (pos + param_size + 1 < compile_commands_file.size())
-                    compile_commands_file.replace(pos, param_size + 2,
-                                                  param + compile_commands_file[pos + param_size + 1] + ":");
-                else
-                    break;
-            }
-        };
-        replace_drive("-I");
-        replace_drive("-isystem ");
-        filesystem::write(compile_commands_path, compile_commands_file);
+    auto compile_commands_file = filesystem::read(compile_commands_path);
+    auto replace_drive = [&compile_commands_file](const std::string &param) {
+      size_t pos = 0;
+      auto param_size = param.length();
+      while ((pos = compile_commands_file.find(param + "/", pos)) != std::string::npos) {
+        if (pos + param_size + 1 < compile_commands_file.size())
+          compile_commands_file.replace(pos, param_size + 2,
+                                        param + compile_commands_file[pos + param_size + 1] + ":");
+        else
+          break;
+      }
+    };
+    replace_drive("-I");
+    replace_drive("-isystem ");
+    filesystem::write(compile_commands_path, compile_commands_file);
 #endif
-        return true;
-    }
-    return false;
+    return true;
+  }
+  return false;
 }
 
 bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-    if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "CMakeLists.txt") || debug_build_path.empty())
-        return false;
+  if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "CMakeLists.txt") ||
+      debug_build_path.empty())
+    return false;
 
-    if (!create_build_directory(debug_build_path)) return false;
+  if (!create_build_directory(debug_build_path)) return false;
 
-    if (!force && boost::filesystem::exists(debug_build_path / "CMakeCache.txt"))
-        return true;
+  if (!force && boost::filesystem::exists(debug_build_path / "CMakeCache.txt"))
+    return true;
 
-    Dialog::Message message("Creating/updating debug build");
-    auto exit_status = Terminal::get().process(Config::get().project.cmake.command + ' ' +
-                                               filesystem::escape_argument(get_project_path().string()) +
-                                               " -DCMAKE_BUILD_TYPE=Debug", debug_build_path);
-    message.hide();
-    if (exit_status == EXIT_SUCCESS)
-        return true;
-    return false;
+  Dialog::Message message("Creating/updating debug build");
+  auto exit_status = Terminal::get().process(Config::get().project.cmake.command + ' ' +
+                                             filesystem::escape_argument(get_project_path().string()) +
+                                             " -DCMAKE_BUILD_TYPE=Debug", debug_build_path);
+  message.hide();
+  if (exit_status == EXIT_SUCCESS)
+    return true;
+  return false;
 }
 
 boost::filesystem::path
 CMake::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
-    // CMake does not store in compile_commands.json if an object is part of an executable or not.
-    // Therefore, executables are first attempted found in the cmake files. These executables
-    // are then used to identify if a file in compile_commands.json is part of an executable or not
+  // CMake does not store in compile_commands.json if an object is part of an executable or not.
+  // Therefore, executables are first attempted found in the cmake files. These executables
+  // are then used to identify if a file in compile_commands.json is part of an executable or not
 
-    auto parameters = get_functions_parameters("add_executable");
+  auto parameters = get_functions_parameters("add_executable");
 
-    std::vector<boost::filesystem::path> cmake_executables;
-    for (auto &parameter: parameters) {
-        if (parameter.second.size() > 1 && parameter.second[0].size() > 0 &&
-            parameter.second[0].compare(0, 2, "${") != 0) {
-            auto executable = (parameter.first.parent_path() / parameter.second[0]).string();
-            auto project_path_str = get_project_path().string();
-            size_t pos = executable.find(project_path_str);
-            if (pos != std::string::npos)
-                executable.replace(pos, project_path_str.size(), build_path.string());
-            cmake_executables.emplace_back(executable);
-        }
+  std::vector<boost::filesystem::path> cmake_executables;
+  for (auto &parameter: parameters) {
+    if (parameter.second.size() > 1 && parameter.second[0].size() > 0 &&
+        parameter.second[0].compare(0, 2, "${") != 0) {
+      auto executable = (parameter.first.parent_path() / parameter.second[0]).string();
+      auto project_path_str = get_project_path().string();
+      size_t pos = executable.find(project_path_str);
+      if (pos != std::string::npos)
+        executable.replace(pos, project_path_str.size(), build_path.string());
+      cmake_executables.emplace_back(executable);
     }
+  }
 
 
-    CompileCommands compile_commands(build_path);
-    std::vector<std::pair<boost::filesystem::path, boost::filesystem::path>> command_files_and_maybe_executables;
-    for (auto &command: compile_commands.commands) {
-        auto command_file = filesystem::get_normal_path(command.file);
-        auto values = command.parameter_values("-o");
-        if (!values.empty()) {
-            size_t pos;
-            values[0].erase(0, 11);
-            if ((pos = values[0].find(".dir")) != std::string::npos) {
-                auto executable = command.directory / values[0].substr(0, pos);
-                command_files_and_maybe_executables.emplace_back(command_file, executable);
-            }
-        }
+  CompileCommands compile_commands(build_path);
+  std::vector<std::pair<boost::filesystem::path, boost::filesystem::path>> command_files_and_maybe_executables;
+  for (auto &command: compile_commands.commands) {
+    auto command_file = filesystem::get_normal_path(command.file);
+    auto values = command.parameter_values("-o");
+    if (!values.empty()) {
+      size_t pos;
+      values[0].erase(0, 11);
+      if ((pos = values[0].find(".dir")) != std::string::npos) {
+        auto executable = command.directory / values[0].substr(0, pos);
+        command_files_and_maybe_executables.emplace_back(command_file, executable);
+      }
     }
+  }
 
-    size_t best_match_size = -1;
-    boost::filesystem::path best_match_executable;
-
-    for (auto &cmake_executable: cmake_executables) {
-        for (auto &command_file_and_maybe_executable: command_files_and_maybe_executables) {
-            auto &command_file = command_file_and_maybe_executable.first;
-            auto &maybe_executable = command_file_and_maybe_executable.second;
-            if (cmake_executable == maybe_executable) {
-                if (command_file == file_path)
-                    return maybe_executable;
-                auto command_file_directory = command_file.parent_path();
-                if (filesystem::file_in_path(file_path, command_file_directory)) {
-                    auto size = static_cast<size_t>(std::distance(command_file_directory.begin(),
-                                                                  command_file_directory.end()));
-                    if (best_match_size == static_cast<size_t>(-1) || best_match_size < size) {
-                        best_match_size = size;
-                        best_match_executable = maybe_executable;
-                    }
-                }
-            }
-        }
-    }
-    if (!best_match_executable.empty())
-        return best_match_executable;
+  size_t best_match_size = -1;
+  boost::filesystem::path best_match_executable;
 
+  for (auto &cmake_executable: cmake_executables) {
     for (auto &command_file_and_maybe_executable: command_files_and_maybe_executables) {
-        auto &command_file = command_file_and_maybe_executable.first;
-        auto &maybe_executable = command_file_and_maybe_executable.second;
+      auto &command_file = command_file_and_maybe_executable.first;
+      auto &maybe_executable = command_file_and_maybe_executable.second;
+      if (cmake_executable == maybe_executable) {
         if (command_file == file_path)
-            return maybe_executable;
+          return maybe_executable;
         auto command_file_directory = command_file.parent_path();
         if (filesystem::file_in_path(file_path, command_file_directory)) {
-            auto size = static_cast<size_t>(std::distance(command_file_directory.begin(),
-                                                          command_file_directory.end()));
-            if (best_match_size == static_cast<size_t>(-1) || best_match_size < size) {
-                best_match_size = size;
-                best_match_executable = maybe_executable;
-            }
+          auto size = static_cast<size_t>(std::distance(command_file_directory.begin(),
+                                                        command_file_directory.end()));
+          if (best_match_size == static_cast<size_t>(-1) || best_match_size < size) {
+            best_match_size = size;
+            best_match_executable = maybe_executable;
+          }
         }
+      }
     }
+  }
+  if (!best_match_executable.empty())
     return best_match_executable;
+
+  for (auto &command_file_and_maybe_executable: command_files_and_maybe_executables) {
+    auto &command_file = command_file_and_maybe_executable.first;
+    auto &maybe_executable = command_file_and_maybe_executable.second;
+    if (command_file == file_path)
+      return maybe_executable;
+    auto command_file_directory = command_file.parent_path();
+    if (filesystem::file_in_path(file_path, command_file_directory)) {
+      auto size = static_cast<size_t>(std::distance(command_file_directory.begin(),
+                                                    command_file_directory.end()));
+      if (best_match_size == static_cast<size_t>(-1) || best_match_size < size) {
+        best_match_size = size;
+        best_match_executable = maybe_executable;
+      }
+    }
+  }
+  return best_match_executable;
 }
 
 void CMake::read_files() {
-    for (auto &path: paths)
-        files.emplace_back(filesystem::read(path));
+  for (auto &path: paths)
+    files.emplace_back(filesystem::read(path));
 }
 
 void CMake::remove_tabs() {
-    for (auto &file: files) {
-        for (auto &chr: file) {
-            if (chr == '\t')
-                chr = ' ';
-        }
+  for (auto &file: files) {
+    for (auto &chr: file) {
+      if (chr == '\t')
+        chr = ' ';
     }
+  }
 }
 
 void CMake::remove_comments() {
-    for (auto &file: files) {
-        size_t pos = 0;
-        size_t comment_start;
-        bool inside_comment = false;
-        while (pos < file.size()) {
-            if (!inside_comment && file[pos] == '#') {
-                comment_start = pos;
-                inside_comment = true;
-            }
-            if (inside_comment && file[pos] == '\n') {
-                file.erase(comment_start, pos - comment_start);
-                pos -= pos - comment_start;
-                inside_comment = false;
-            }
-            pos++;
-        }
-        if (inside_comment)
-            file.erase(comment_start);
+  for (auto &file: files) {
+    size_t pos = 0;
+    size_t comment_start;
+    bool inside_comment = false;
+    while (pos < file.size()) {
+      if (!inside_comment && file[pos] == '#') {
+        comment_start = pos;
+        inside_comment = true;
+      }
+      if (inside_comment && file[pos] == '\n') {
+        file.erase(comment_start, pos - comment_start);
+        pos -= pos - comment_start;
+        inside_comment = false;
+      }
+      pos++;
     }
+    if (inside_comment)
+      file.erase(comment_start);
+  }
 }
 
 void CMake::remove_newlines_inside_parentheses() {
-    for (auto &file: files) {
-        size_t pos = 0;
-        bool inside_para = false;
-        bool inside_quote = false;
-        char last_char = 0;
-        while (pos < file.size()) {
-            if (!inside_quote && file[pos] == '"' && last_char != '\\')
-                inside_quote = true;
-            else if (inside_quote && file[pos] == '"' && last_char != '\\')
-                inside_quote = false;
+  for (auto &file: files) {
+    size_t pos = 0;
+    bool inside_para = false;
+    bool inside_quote = false;
+    char last_char = 0;
+    while (pos < file.size()) {
+      if (!inside_quote && file[pos] == '"' && last_char != '\\')
+        inside_quote = true;
+      else if (inside_quote && file[pos] == '"' && last_char != '\\')
+        inside_quote = false;
 
-            else if (!inside_quote && file[pos] == '(')
-                inside_para = true;
-            else if (!inside_quote && file[pos] == ')')
-                inside_para = false;
+      else if (!inside_quote && file[pos] == '(')
+        inside_para = true;
+      else if (!inside_quote && file[pos] == ')')
+        inside_para = false;
 
-            else if (inside_para && file[pos] == '\n')
-                file.replace(pos, 1, 1, ' ');
-            last_char = file[pos];
-            pos++;
-        }
+      else if (inside_para && file[pos] == '\n')
+        file.replace(pos, 1, 1, ' ');
+      last_char = file[pos];
+      pos++;
     }
+  }
 }
 
 void CMake::parse_variable_parameters(std::string &data) {
-    size_t pos = 0;
-    bool inside_quote = false;
-    char last_char = 0;
-    while (pos < data.size()) {
-        if (!inside_quote && data[pos] == '"' && last_char != '\\') {
-            inside_quote = true;
-            data.erase(pos,
-                       1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
-            pos--;
-        } else if (inside_quote && data[pos] == '"' && last_char != '\\') {
-            inside_quote = false;
-            data.erase(pos,
-                       1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
-            pos--;
-        } else if (!inside_quote && data[pos] == ' ' && pos + 1 < data.size() && data[pos + 1] == ' ') {
-            data.erase(pos, 1);
-            pos--;
-        }
-
-        if (pos != static_cast<size_t>(-1))
-            last_char = data[pos];
-        pos++;
+  size_t pos = 0;
+  bool inside_quote = false;
+  char last_char = 0;
+  while (pos < data.size()) {
+    if (!inside_quote && data[pos] == '"' && last_char != '\\') {
+      inside_quote = true;
+      data.erase(pos,
+                 1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
+      pos--;
+    } else if (inside_quote && data[pos] == '"' && last_char != '\\') {
+      inside_quote = false;
+      data.erase(pos,
+                 1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
+      pos--;
+    } else if (!inside_quote && data[pos] == ' ' && pos + 1 < data.size() && data[pos + 1] == ' ') {
+      data.erase(pos, 1);
+      pos--;
     }
-    for (auto &var: variables) {
-        auto pos = data.find("${" + var.first + '}');
-        while (pos != std::string::npos) {
-            data.replace(pos, var.first.size() + 3, var.second);
-            pos = data.find("${" + var.first + '}');
-        }
+
+    if (pos != static_cast<size_t>(-1))
+      last_char = data[pos];
+    pos++;
+  }
+  for (auto &var: variables) {
+    auto pos = data.find("${" + var.first + '}');
+    while (pos != std::string::npos) {
+      data.replace(pos, var.first.size() + 3, var.second);
+      pos = data.find("${" + var.first + '}');
     }
+  }
 
-    //Remove variables we do not know:
+  //Remove variables we do not know:
+  pos = data.find("${");
+  auto pos_end = data.find("}", pos + 2);
+  while (pos != std::string::npos && pos_end != std::string::npos) {
+    data.erase(pos, pos_end - pos + 1);
     pos = data.find("${");
-    auto pos_end = data.find("}", pos + 2);
-    while (pos != std::string::npos && pos_end != std::string::npos) {
-        data.erase(pos, pos_end - pos + 1);
-        pos = data.find("${");
-        pos_end = data.find("}", pos + 2);
-    }
+    pos_end = data.find("}", pos + 2);
+  }
 }
 
 void CMake::parse() {
-    read_files();
-    remove_tabs();
-    remove_comments();
-    remove_newlines_inside_parentheses();
-    parsed = true;
+  read_files();
+  remove_tabs();
+  remove_comments();
+  remove_newlines_inside_parentheses();
+  parsed = true;
 }
 
 std::vector<std::string> CMake::get_function_parameters(std::string &data) {
-    std::vector<std::string> parameters;
-    size_t pos = 0;
-    size_t parameter_pos = 0;
-    bool inside_quote = false;
-    char last_char = 0;
-    while (pos < data.size()) {
-        if (!inside_quote && data[pos] == '"' && last_char != '\\') {
-            inside_quote = true;
-            data.erase(pos, 1);
-            pos--;
-        } else if (inside_quote && data[pos] == '"' && last_char != '\\') {
-            inside_quote = false;
-            data.erase(pos, 1);
-            pos--;
-        } else if (!inside_quote && pos + 1 < data.size() && data[pos] == ' ' && data[pos + 1] == ' ') {
-            data.erase(pos, 1);
-            pos--;
-        } else if (!inside_quote && data[pos] == ' ') {
-            parameters.emplace_back(data.substr(parameter_pos, pos - parameter_pos));
-            if (pos + 1 < data.size())
-                parameter_pos = pos + 1;
-        }
-
-        if (pos != static_cast<size_t>(-1))
-            last_char = data[pos];
-        pos++;
+  std::vector<std::string> parameters;
+  size_t pos = 0;
+  size_t parameter_pos = 0;
+  bool inside_quote = false;
+  char last_char = 0;
+  while (pos < data.size()) {
+    if (!inside_quote && data[pos] == '"' && last_char != '\\') {
+      inside_quote = true;
+      data.erase(pos, 1);
+      pos--;
+    } else if (inside_quote && data[pos] == '"' && last_char != '\\') {
+      inside_quote = false;
+      data.erase(pos, 1);
+      pos--;
+    } else if (!inside_quote && pos + 1 < data.size() && data[pos] == ' ' && data[pos + 1] == ' ') {
+      data.erase(pos, 1);
+      pos--;
+    } else if (!inside_quote && data[pos] == ' ') {
+      parameters.emplace_back(data.substr(parameter_pos, pos - parameter_pos));
+      if (pos + 1 < data.size())
+        parameter_pos = pos + 1;
     }
-    parameters.emplace_back(data.substr(parameter_pos));
-    for (auto &var: variables) {
-        for (auto &parameter: parameters) {
-            auto pos = parameter.find("${" + var.first + '}');
-            while (pos != std::string::npos) {
-                parameter.replace(pos, var.first.size() + 3, var.second);
-                pos = parameter.find("${" + var.first + '}');
-            }
-        }
+
+    if (pos != static_cast<size_t>(-1))
+      last_char = data[pos];
+    pos++;
+  }
+  parameters.emplace_back(data.substr(parameter_pos));
+  for (auto &var: variables) {
+    for (auto &parameter: parameters) {
+      auto pos = parameter.find("${" + var.first + '}');
+      while (pos != std::string::npos) {
+        parameter.replace(pos, var.first.size() + 3, var.second);
+        pos = parameter.find("${" + var.first + '}');
+      }
     }
-    return parameters;
+  }
+  return parameters;
 }
 
 std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > >
 CMake::get_functions_parameters(const std::string &name) {
-    const std::regex function_regex("^ *" + name + " *\\( *(.*)\\) *\\r?$", std::regex::icase);
-    variables.clear();
-    if (!parsed)
-        parse();
-    std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > > functions;
-    for (size_t c = 0; c < files.size(); ++c) {
-        size_t pos = 0;
-        while (pos < files[c].size()) {
-            auto start_line = pos;
-            auto end_line = files[c].find('\n', start_line);
-            if (end_line == std::string::npos)
-                end_line = files[c].size();
-            if (end_line > start_line) {
-                auto line = files[c].substr(start_line, end_line - start_line);
-                std::smatch sm;
-                const static std::regex set_regex("^ *set *\\( *([A-Za-z_][A-Za-z_0-9]*) +(.*)\\) *\\r?$",
-                                                  std::regex::icase);
-                const static std::regex project_regex("^ *project *\\( *([^ ]+).*\\) *\\r?$", std::regex::icase);
-                if (std::regex_match(line, sm, set_regex)) {
-                    auto data = sm[2].str();
-                    while (data.size() > 0 && data.back() == ' ')
-                        data.pop_back();
-                    parse_variable_parameters(data);
-                    variables[sm[1].str()] = data;
-                } else if (std::regex_match(line, sm, project_regex)) {
-                    auto data = sm[1].str();
-                    parse_variable_parameters(data);
-                    variables["CMAKE_PROJECT_NAME"] = data; //TODO: is this variable deprecated/non-standard?
-                    variables["PROJECT_NAME"] = data;
-                }
-                if (std::regex_match(line, sm, function_regex)) {
-                    auto data = sm[1].str();
-                    while (data.size() > 0 && data.back() == ' ')
-                        data.pop_back();
-                    auto parameters = get_function_parameters(data);
-                    functions.emplace_back(paths[c], parameters);
-                }
-            }
-            pos = end_line + 1;
+  const std::regex function_regex("^ *" + name + " *\\( *(.*)\\) *\\r?$", std::regex::icase);
+  variables.clear();
+  if (!parsed)
+    parse();
+  std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > > functions;
+  for (size_t c = 0; c < files.size(); ++c) {
+    size_t pos = 0;
+    while (pos < files[c].size()) {
+      auto start_line = pos;
+      auto end_line = files[c].find('\n', start_line);
+      if (end_line == std::string::npos)
+        end_line = files[c].size();
+      if (end_line > start_line) {
+        auto line = files[c].substr(start_line, end_line - start_line);
+        std::smatch sm;
+        const static std::regex set_regex("^ *set *\\( *([A-Za-z_][A-Za-z_0-9]*) +(.*)\\) *\\r?$",
+                                          std::regex::icase);
+        const static std::regex project_regex("^ *project *\\( *([^ ]+).*\\) *\\r?$", std::regex::icase);
+        if (std::regex_match(line, sm, set_regex)) {
+          auto data = sm[2].str();
+          while (data.size() > 0 && data.back() == ' ')
+            data.pop_back();
+          parse_variable_parameters(data);
+          variables[sm[1].str()] = data;
+        } else if (std::regex_match(line, sm, project_regex)) {
+          auto data = sm[1].str();
+          parse_variable_parameters(data);
+          variables["CMAKE_PROJECT_NAME"] = data; //TODO: is this variable deprecated/non-standard?
+          variables["PROJECT_NAME"] = data;
+        }
+        if (std::regex_match(line, sm, function_regex)) {
+          auto data = sm[1].str();
+          while (data.size() > 0 && data.back() == ' ')
+            data.pop_back();
+          auto parameters = get_function_parameters(data);
+          functions.emplace_back(paths[c], parameters);
         }
+      }
+      pos = end_line + 1;
     }
-    return functions;
+  }
+  return functions;
 }
diff --git a/src/cmake.h b/src/cmake.h
index 0f44b7a0..7783ae28 100644
--- a/src/cmake.h
+++ b/src/cmake.h
@@ -6,36 +6,36 @@
 
 class CMake : public BuildSystemBase {
 public:
-    CMake(const boost::filesystem::path &path);
+  CMake(const boost::filesystem::path &path);
 
-    bool update_default_build(const boost::filesystem::path &default_build_path, bool force) override;
+  bool update_default_build(const boost::filesystem::path &default_build_path, bool force) override;
 
-    bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) override;
+  bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) override;
 
-    boost::filesystem::path
-    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
+  boost::filesystem::path
+  get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
 
 private:
-    std::vector<boost::filesystem::path> paths;
-    std::vector<std::string> files;
-    std::unordered_map<std::string, std::string> variables;
+  std::vector<boost::filesystem::path> paths;
+  std::vector<std::string> files;
+  std::unordered_map<std::string, std::string> variables;
 
-    void read_files();
+  void read_files();
 
-    void remove_tabs();
+  void remove_tabs();
 
-    void remove_comments();
+  void remove_comments();
 
-    void remove_newlines_inside_parentheses();
+  void remove_newlines_inside_parentheses();
 
-    void parse_variable_parameters(std::string &data);
+  void parse_variable_parameters(std::string &data);
 
-    void parse();
+  void parse();
 
-    std::vector<std::string> get_function_parameters(std::string &data);
+  std::vector<std::string> get_function_parameters(std::string &data);
 
-    std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > >
-    get_functions_parameters(const std::string &name);
+  std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > >
+  get_functions_parameters(const std::string &name);
 
-    bool parsed = false;
+  bool parsed = false;
 };
diff --git a/src/compile_commands.cc b/src/compile_commands.cc
index 7f283d8d..a3e82b75 100644
--- a/src/compile_commands.cc
+++ b/src/compile_commands.cc
@@ -4,159 +4,159 @@
 #include <regex>
 
 std::vector<std::string> CompileCommands::Command::parameter_values(const std::string &parameter_name) const {
-    std::vector<std::string> parameter_values;
-
-    bool found_argument = false;
-    for (auto &parameter: parameters) {
-        if (found_argument) {
-            parameter_values.emplace_back(parameter);
-            found_argument = false;
-        } else if (parameter == parameter_name)
-            found_argument = true;
-    }
-
-    return parameter_values;
+  std::vector<std::string> parameter_values;
+
+  bool found_argument = false;
+  for (auto &parameter: parameters) {
+    if (found_argument) {
+      parameter_values.emplace_back(parameter);
+      found_argument = false;
+    } else if (parameter == parameter_name)
+      found_argument = true;
+  }
+
+  return parameter_values;
 }
 
 CompileCommands::CompileCommands(const boost::filesystem::path &build_path) {
-    try {
-        boost::property_tree::ptree root_pt;
-        boost::property_tree::json_parser::read_json((build_path / "compile_commands.json").string(), root_pt);
-
-        auto commands_pt = root_pt.get_child("");
-        for (auto &command: commands_pt) {
-            boost::filesystem::path directory = command.second.get<std::string>("directory");
-            auto parameters_str = command.second.get<std::string>("command");
-            boost::filesystem::path file = command.second.get<std::string>("file");
-
-            std::vector<std::string> parameters;
-            bool backslash = false;
-            bool single_quote = false;
-            bool double_quote = false;
-            size_t parameter_start_pos = std::string::npos;
-            size_t parameter_size = 0;
-            auto add_parameter = [&parameters, &parameters_str, &parameter_start_pos, &parameter_size] {
-                auto parameter = parameters_str.substr(parameter_start_pos, parameter_size);
-                // Remove escaping
-                for (size_t c = 0; c < parameter.size() - 1; ++c) {
-                    if (parameter[c] == '\\')
-                        parameter.replace(c, 2, std::string() + parameter[c + 1]);
-                }
-                parameters.emplace_back(parameter);
-            };
-            for (size_t c = 0; c < parameters_str.size(); ++c) {
-                if (backslash)
-                    backslash = false;
-                else if (parameters_str[c] == '\\')
-                    backslash = true;
-                else if ((parameters_str[c] == ' ' || parameters_str[c] == '\t') && !backslash && !single_quote &&
-                         !double_quote) {
-                    if (parameter_start_pos != std::string::npos) {
-                        add_parameter();
-                        parameter_start_pos = std::string::npos;
-                        parameter_size = 0;
-                    }
-                    continue;
-                } else if (parameters_str[c] == '\'' && !backslash && !double_quote) {
-                    single_quote = !single_quote;
-                    continue;
-                } else if (parameters_str[c] == '\"' && !backslash && !single_quote) {
-                    double_quote = !double_quote;
-                    continue;
-                }
-
-                if (parameter_start_pos == std::string::npos)
-                    parameter_start_pos = c;
-                ++parameter_size;
-            }
-            if (parameter_start_pos != std::string::npos)
-                add_parameter();
-
-            commands.emplace_back(Command{directory, parameters, boost::filesystem::absolute(file, build_path)});
+  try {
+    boost::property_tree::ptree root_pt;
+    boost::property_tree::json_parser::read_json((build_path / "compile_commands.json").string(), root_pt);
+
+    auto commands_pt = root_pt.get_child("");
+    for (auto &command: commands_pt) {
+      boost::filesystem::path directory = command.second.get<std::string>("directory");
+      auto parameters_str = command.second.get<std::string>("command");
+      boost::filesystem::path file = command.second.get<std::string>("file");
+
+      std::vector<std::string> parameters;
+      bool backslash = false;
+      bool single_quote = false;
+      bool double_quote = false;
+      size_t parameter_start_pos = std::string::npos;
+      size_t parameter_size = 0;
+      auto add_parameter = [&parameters, &parameters_str, &parameter_start_pos, &parameter_size] {
+        auto parameter = parameters_str.substr(parameter_start_pos, parameter_size);
+        // Remove escaping
+        for (size_t c = 0; c < parameter.size() - 1; ++c) {
+          if (parameter[c] == '\\')
+            parameter.replace(c, 2, std::string() + parameter[c + 1]);
         }
+        parameters.emplace_back(parameter);
+      };
+      for (size_t c = 0; c < parameters_str.size(); ++c) {
+        if (backslash)
+          backslash = false;
+        else if (parameters_str[c] == '\\')
+          backslash = true;
+        else if ((parameters_str[c] == ' ' || parameters_str[c] == '\t') && !backslash && !single_quote &&
+                 !double_quote) {
+          if (parameter_start_pos != std::string::npos) {
+            add_parameter();
+            parameter_start_pos = std::string::npos;
+            parameter_size = 0;
+          }
+          continue;
+        } else if (parameters_str[c] == '\'' && !backslash && !double_quote) {
+          single_quote = !single_quote;
+          continue;
+        } else if (parameters_str[c] == '\"' && !backslash && !single_quote) {
+          double_quote = !double_quote;
+          continue;
+        }
+
+        if (parameter_start_pos == std::string::npos)
+          parameter_start_pos = c;
+        ++parameter_size;
+      }
+      if (parameter_start_pos != std::string::npos)
+        add_parameter();
+
+      commands.emplace_back(Command{directory, parameters, boost::filesystem::absolute(file, build_path)});
     }
-    catch (...) {}
+  }
+  catch (...) {}
 }
 
 std::vector<std::string>
 CompileCommands::get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
-    std::string default_std_argument = "-std=c++1y";
-
-    std::vector<std::string> arguments;
-    if (!build_path.empty()) {
-        clangmm::CompilationDatabase db(build_path.string());
-        if (db) {
-            clangmm::CompileCommands commands(file_path.string(), db);
-            auto cmds = commands.get_commands();
-            for (auto &cmd : cmds) {
-                auto cmd_arguments = cmd.get_arguments();
-                bool ignore_next = false;
-                for (size_t c = 1; c < cmd_arguments.size(); c++) {
-                    if (ignore_next) {
-                        ignore_next = false;
-                        continue;
-                    } else if (cmd_arguments[c] == "-o" || cmd_arguments[c] == "-c") {
-                        ignore_next = true;
-                        continue;
-                    }
-                    arguments.emplace_back(cmd_arguments[c]);
-                }
-            }
-        } else
-            arguments.emplace_back(default_std_argument);
+  std::string default_std_argument = "-std=c++1y";
+
+  std::vector<std::string> arguments;
+  if (!build_path.empty()) {
+    clangmm::CompilationDatabase db(build_path.string());
+    if (db) {
+      clangmm::CompileCommands commands(file_path.string(), db);
+      auto cmds = commands.get_commands();
+      for (auto &cmd : cmds) {
+        auto cmd_arguments = cmd.get_arguments();
+        bool ignore_next = false;
+        for (size_t c = 1; c < cmd_arguments.size(); c++) {
+          if (ignore_next) {
+            ignore_next = false;
+            continue;
+          } else if (cmd_arguments[c] == "-o" || cmd_arguments[c] == "-c") {
+            ignore_next = true;
+            continue;
+          }
+          arguments.emplace_back(cmd_arguments[c]);
+        }
+      }
     } else
-        arguments.emplace_back(default_std_argument);
-
-    auto clang_version_string = clangmm::to_string(clang_getClangVersion());
-    const static std::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$");
-    std::smatch sm;
-    if (std::regex_match(clang_version_string, sm, clang_version_regex)) {
-        auto clang_version = sm[1].str();
-        arguments.emplace_back("-I/usr/lib/clang/" + clang_version + "/include");
-        arguments.emplace_back("-I/usr/lib64/clang/" + clang_version + "/include"); // For Fedora
+      arguments.emplace_back(default_std_argument);
+  } else
+    arguments.emplace_back(default_std_argument);
+
+  auto clang_version_string = clangmm::to_string(clang_getClangVersion());
+  const static std::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$");
+  std::smatch sm;
+  if (std::regex_match(clang_version_string, sm, clang_version_regex)) {
+    auto clang_version = sm[1].str();
+    arguments.emplace_back("-I/usr/lib/clang/" + clang_version + "/include");
+    arguments.emplace_back("-I/usr/lib64/clang/" + clang_version + "/include"); // For Fedora
 #if defined(__APPLE__) && CINDEX_VERSION_MAJOR == 0 && CINDEX_VERSION_MINOR < 32 // TODO: remove during 2018 if llvm3.7 is no longer in homebrew (CINDEX_VERSION_MINOR=32 equals clang-3.8 I think)
-        arguments.emplace_back("-I/usr/local/Cellar/llvm/"+clang_version+"/lib/clang/"+clang_version+"/include");
-        arguments.emplace_back("-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1");
-        arguments.emplace_back("-I/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1"); //Added for OS X 10.11
+    arguments.emplace_back("-I/usr/local/Cellar/llvm/"+clang_version+"/lib/clang/"+clang_version+"/include");
+    arguments.emplace_back("-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1");
+    arguments.emplace_back("-I/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1"); //Added for OS X 10.11
 #endif
 #ifdef _WIN32
-        auto env_msystem_prefix = std::getenv("MSYSTEM_PREFIX");
-        if (env_msystem_prefix != nullptr)
-            arguments.emplace_back("-I" + (boost::filesystem::path(env_msystem_prefix) / "lib/clang" / clang_version /
-                                           "include").string());
+    auto env_msystem_prefix = std::getenv("MSYSTEM_PREFIX");
+    if (env_msystem_prefix != nullptr)
+      arguments.emplace_back("-I" + (boost::filesystem::path(env_msystem_prefix) / "lib/clang" / clang_version /
+                                     "include").string());
 #endif
-    }
-    arguments.emplace_back("-fretain-comments-from-system-headers");
-
-    auto extension = file_path.extension().string();
-    if (extension == ".h" ||  //TODO: temporary fix for .h-files (parse as c++)
-        extension != ".c")
-        arguments.emplace_back("-xc++");
-
-    if (extension.empty() || (1 < extension.size() && extension[1] == 'h') || extension == ".tcc" ||
-        extension == ".cuh") {
-        arguments.emplace_back("-Wno-pragma-once-outside-header");
-        arguments.emplace_back("-Wno-pragma-system-header-outside-header");
-        arguments.emplace_back("-Wno-include-next-outside-header");
-    }
-
-    if (extension == ".cu" || extension == ".cuh") {
-        arguments.emplace_back("-include");
-        arguments.emplace_back("cuda_runtime.h");
-    }
-
-    if (extension == ".cl") {
-        arguments.emplace_back("-xcl");
-        arguments.emplace_back("-cl-std=CL2.0");
-        arguments.emplace_back("-Xclang");
-        arguments.emplace_back("-finclude-default-header");
-        arguments.emplace_back("-Wno-gcc-compat");
-    }
-
-    if (!build_path.empty()) {
-        arguments.emplace_back("-working-directory");
-        arguments.emplace_back(build_path.string());
-    }
-
-    return arguments;
+  }
+  arguments.emplace_back("-fretain-comments-from-system-headers");
+
+  auto extension = file_path.extension().string();
+  if (extension == ".h" ||  //TODO: temporary fix for .h-files (parse as c++)
+      extension != ".c")
+    arguments.emplace_back("-xc++");
+
+  if (extension.empty() || (1 < extension.size() && extension[1] == 'h') || extension == ".tcc" ||
+      extension == ".cuh") {
+    arguments.emplace_back("-Wno-pragma-once-outside-header");
+    arguments.emplace_back("-Wno-pragma-system-header-outside-header");
+    arguments.emplace_back("-Wno-include-next-outside-header");
+  }
+
+  if (extension == ".cu" || extension == ".cuh") {
+    arguments.emplace_back("-include");
+    arguments.emplace_back("cuda_runtime.h");
+  }
+
+  if (extension == ".cl") {
+    arguments.emplace_back("-xcl");
+    arguments.emplace_back("-cl-std=CL2.0");
+    arguments.emplace_back("-Xclang");
+    arguments.emplace_back("-finclude-default-header");
+    arguments.emplace_back("-Wno-gcc-compat");
+  }
+
+  if (!build_path.empty()) {
+    arguments.emplace_back("-working-directory");
+    arguments.emplace_back(build_path.string());
+  }
+
+  return arguments;
 }
diff --git a/src/compile_commands.h b/src/compile_commands.h
index 83c3d6dd..c7bb0f4a 100644
--- a/src/compile_commands.h
+++ b/src/compile_commands.h
@@ -6,20 +6,20 @@
 
 class CompileCommands {
 public:
-    class Command {
-    public:
-        boost::filesystem::path directory;
-        std::vector<std::string> parameters;
-        boost::filesystem::path file;
+  class Command {
+  public:
+    boost::filesystem::path directory;
+    std::vector<std::string> parameters;
+    boost::filesystem::path file;
 
-        std::vector<std::string> parameter_values(const std::string &parameter_name) const;
-    };
+    std::vector<std::string> parameter_values(const std::string &parameter_name) const;
+  };
 
-    CompileCommands(const boost::filesystem::path &build_path);
+  CompileCommands(const boost::filesystem::path &build_path);
 
-    std::vector<Command> commands;
+  std::vector<Command> commands;
 
-    /// Return arguments for the given file using libclangmm
-    static std::vector<std::string>
-    get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
+  /// Return arguments for the given file using libclangmm
+  static std::vector<std::string>
+  get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
 };
diff --git a/src/config.cc b/src/config.cc
index 625da547..bc8d2e8d 100644
--- a/src/config.cc
+++ b/src/config.cc
@@ -7,203 +7,203 @@
 #include <algorithm>
 
 Config::Config() {
-    home_path = filesystem::get_home_path();
-    if (home_path.empty())
-        throw std::runtime_error("Could not find home path");
-    home_juci_path = home_path / ".juci";
+  home_path = filesystem::get_home_path();
+  if (home_path.empty())
+    throw std::runtime_error("Could not find home path");
+  home_juci_path = home_path / ".juci";
 }
 
 void Config::load() {
-    auto config_json = (home_juci_path / "config" /
-                        "config.json").string(); // This causes some redundant copies, but assures windows support
-    boost::property_tree::ptree cfg;
-    try {
-        find_or_create_config_files();
-        boost::property_tree::json_parser::read_json(config_json, cfg);
-        update(cfg);
-        read(cfg);
-    }
-    catch (const std::exception &e) {
-        dispatcher.post([config_json, e_what = std::string(e.what())] {
-            ::Terminal::get().print("Error: could not parse " + config_json + ": " + e_what + "\n", true);
-        });
-        std::stringstream ss;
-        ss << default_config_file;
-        boost::property_tree::read_json(ss, cfg);
-        read(cfg);
-    }
+  auto config_json = (home_juci_path / "config" /
+                      "config.json").string(); // This causes some redundant copies, but assures windows support
+  boost::property_tree::ptree cfg;
+  try {
+    find_or_create_config_files();
+    boost::property_tree::json_parser::read_json(config_json, cfg);
+    update(cfg);
+    read(cfg);
+  }
+  catch (const std::exception &e) {
+    dispatcher.post([config_json, e_what = std::string(e.what())] {
+      ::Terminal::get().print("Error: could not parse " + config_json + ": " + e_what + "\n", true);
+    });
+    std::stringstream ss;
+    ss << default_config_file;
+    boost::property_tree::read_json(ss, cfg);
+    read(cfg);
+  }
 }
 
 void Config::find_or_create_config_files() {
-    auto config_dir = home_juci_path / "config";
-    auto config_json = config_dir / "config.json";
-
-    boost::filesystem::create_directories(config_dir); // io exp captured by calling method
-
-    if (!boost::filesystem::exists(config_json))
-        filesystem::write(config_json, default_config_file);
-
-    auto juci_style_path = home_juci_path / "styles";
-    boost::filesystem::create_directories(juci_style_path); // io exp captured by calling method
-
-    juci_style_path /= "juci-light.xml";
-    if (!boost::filesystem::exists(juci_style_path))
-        filesystem::write(juci_style_path, juci_light_style);
-    juci_style_path = juci_style_path.parent_path();
-    juci_style_path /= "juci-dark.xml";
-    if (!boost::filesystem::exists(juci_style_path))
-        filesystem::write(juci_style_path, juci_dark_style);
-    juci_style_path = juci_style_path.parent_path();
-    juci_style_path /= "juci-dark-blue.xml";
-    if (!boost::filesystem::exists(juci_style_path))
-        filesystem::write(juci_style_path, juci_dark_blue_style);
+  auto config_dir = home_juci_path / "config";
+  auto config_json = config_dir / "config.json";
+
+  boost::filesystem::create_directories(config_dir); // io exp captured by calling method
+
+  if (!boost::filesystem::exists(config_json))
+    filesystem::write(config_json, default_config_file);
+
+  auto juci_style_path = home_juci_path / "styles";
+  boost::filesystem::create_directories(juci_style_path); // io exp captured by calling method
+
+  juci_style_path /= "juci-light.xml";
+  if (!boost::filesystem::exists(juci_style_path))
+    filesystem::write(juci_style_path, juci_light_style);
+  juci_style_path = juci_style_path.parent_path();
+  juci_style_path /= "juci-dark.xml";
+  if (!boost::filesystem::exists(juci_style_path))
+    filesystem::write(juci_style_path, juci_dark_style);
+  juci_style_path = juci_style_path.parent_path();
+  juci_style_path /= "juci-dark-blue.xml";
+  if (!boost::filesystem::exists(juci_style_path))
+    filesystem::write(juci_style_path, juci_dark_blue_style);
 }
 
 void Config::update(boost::property_tree::ptree &cfg) {
-    boost::property_tree::ptree default_cfg;
-    bool cfg_ok = true;
-    if (cfg.get<std::string>("version") != JUCI_VERSION) {
-        std::stringstream ss;
-        ss << default_config_file;
-        boost::property_tree::read_json(ss, default_cfg);
-        cfg_ok = false;
-        auto it_version = cfg.find("version");
-        if (it_version != cfg.not_found()) {
-            make_version_dependent_corrections(cfg, default_cfg, it_version->second.data());
-            it_version->second.data() = JUCI_VERSION;
-        }
-
-        auto style_path = home_juci_path / "styles";
-        filesystem::write(style_path / "juci-light.xml", juci_light_style);
-        filesystem::write(style_path / "juci-dark.xml", juci_dark_style);
-        filesystem::write(style_path / "juci-dark-blue.xml", juci_dark_blue_style);
-    } else
-        return;
-    cfg_ok &= add_missing_nodes(cfg, default_cfg);
-    cfg_ok &= remove_deprecated_nodes(cfg, default_cfg);
-    if (!cfg_ok)
-        boost::property_tree::write_json((home_juci_path / "config" / "config.json").string(), cfg);
+  boost::property_tree::ptree default_cfg;
+  bool cfg_ok = true;
+  if (cfg.get<std::string>("version") != JUCI_VERSION) {
+    std::stringstream ss;
+    ss << default_config_file;
+    boost::property_tree::read_json(ss, default_cfg);
+    cfg_ok = false;
+    auto it_version = cfg.find("version");
+    if (it_version != cfg.not_found()) {
+      make_version_dependent_corrections(cfg, default_cfg, it_version->second.data());
+      it_version->second.data() = JUCI_VERSION;
+    }
+
+    auto style_path = home_juci_path / "styles";
+    filesystem::write(style_path / "juci-light.xml", juci_light_style);
+    filesystem::write(style_path / "juci-dark.xml", juci_dark_style);
+    filesystem::write(style_path / "juci-dark-blue.xml", juci_dark_blue_style);
+  } else
+    return;
+  cfg_ok &= add_missing_nodes(cfg, default_cfg);
+  cfg_ok &= remove_deprecated_nodes(cfg, default_cfg);
+  if (!cfg_ok)
+    boost::property_tree::write_json((home_juci_path / "config" / "config.json").string(), cfg);
 }
 
 void Config::make_version_dependent_corrections(boost::property_tree::ptree &cfg,
                                                 const boost::property_tree::ptree &default_cfg,
                                                 const std::string &version) {
-    auto &keybindings_cfg = cfg.get_child("keybindings");
-    try {
-        if (version <= "1.2.4") {
-            auto it_file_print = keybindings_cfg.find("print");
-            if (it_file_print != keybindings_cfg.not_found() && it_file_print->second.data() == "<primary>p") {
-                dispatcher.post([] {
-                    ::Terminal::get().print("Preference change: keybindings.print set to \"\"\n");
-                });
-                it_file_print->second.data() = "";
-            }
-        }
-    }
-    catch (const std::exception &e) {
-        std::cerr << "Error correcting preferences: " << e.what() << std::endl;
+  auto &keybindings_cfg = cfg.get_child("keybindings");
+  try {
+    if (version <= "1.2.4") {
+      auto it_file_print = keybindings_cfg.find("print");
+      if (it_file_print != keybindings_cfg.not_found() && it_file_print->second.data() == "<primary>p") {
+        dispatcher.post([] {
+          ::Terminal::get().print("Preference change: keybindings.print set to \"\"\n");
+        });
+        it_file_print->second.data() = "";
+      }
     }
+  }
+  catch (const std::exception &e) {
+    std::cerr << "Error correcting preferences: " << e.what() << std::endl;
+  }
 }
 
 bool Config::add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
                                std::string parent_path) {
-    if (parent_path.size() > 0)
-        parent_path += ".";
-    bool unchanged = true;
-    for (auto &node: default_cfg) {
-        auto path = parent_path + node.first;
-        try {
-            cfg.get<std::string>(path);
-        }
-        catch (const std::exception &e) {
-            cfg.add(path, node.second.data());
-            unchanged = false;
-        }
-        unchanged &= add_missing_nodes(cfg, node.second, path);
+  if (parent_path.size() > 0)
+    parent_path += ".";
+  bool unchanged = true;
+  for (auto &node: default_cfg) {
+    auto path = parent_path + node.first;
+    try {
+      cfg.get<std::string>(path);
     }
-    return unchanged;
+    catch (const std::exception &e) {
+      cfg.add(path, node.second.data());
+      unchanged = false;
+    }
+    unchanged &= add_missing_nodes(cfg, node.second, path);
+  }
+  return unchanged;
 }
 
 bool Config::remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
                                      std::string parent_path) {
-    if (parent_path.size() > 0)
-        parent_path += ".";
-    bool unchanged = true;
-    for (auto it = cfg.begin(); it != cfg.end();) {
-        auto path = parent_path + it->first;
-        try {
-            default_cfg.get<std::string>(path);
-            unchanged &= remove_deprecated_nodes(it->second, default_cfg, path);
-            ++it;
-        }
-        catch (const std::exception &e) {
-            it = cfg.erase(it);
-            unchanged = false;
-        }
+  if (parent_path.size() > 0)
+    parent_path += ".";
+  bool unchanged = true;
+  for (auto it = cfg.begin(); it != cfg.end();) {
+    auto path = parent_path + it->first;
+    try {
+      default_cfg.get<std::string>(path);
+      unchanged &= remove_deprecated_nodes(it->second, default_cfg, path);
+      ++it;
     }
-    return unchanged;
+    catch (const std::exception &e) {
+      it = cfg.erase(it);
+      unchanged = false;
+    }
+  }
+  return unchanged;
 }
 
 void Config::read(const boost::property_tree::ptree &cfg) {
-    auto keybindings_pt = cfg.get_child("keybindings");
-    for (auto &i : keybindings_pt) {
-        menu.keys[i.first] = i.second.get_value<std::string>();
+  auto keybindings_pt = cfg.get_child("keybindings");
+  for (auto &i : keybindings_pt) {
+    menu.keys[i.first] = i.second.get_value<std::string>();
+  }
+
+  auto source_json = cfg.get_child("source");
+  source.style = source_json.get<std::string>("style");
+  source.font = source_json.get<std::string>("font");
+  source.cleanup_whitespace_characters = source_json.get<bool>("cleanup_whitespace_characters");
+  source.show_whitespace_characters = source_json.get<std::string>("show_whitespace_characters");
+  source.format_style_on_save = source_json.get<bool>("format_style_on_save");
+  source.format_style_on_save_if_style_file_found = source_json.get<bool>("format_style_on_save_if_style_file_found");
+  source.smart_brackets = source_json.get<bool>("smart_brackets");
+  source.smart_inserts = source_json.get<bool>("smart_inserts");
+  if (source.smart_inserts)
+    source.smart_brackets = true;
+  source.show_map = source_json.get<bool>("show_map");
+  source.map_font_size = source_json.get<std::string>("map_font_size");
+  source.show_git_diff = source_json.get<bool>("show_git_diff");
+  source.show_background_pattern = source_json.get<bool>("show_background_pattern");
+  source.show_right_margin = source_json.get<bool>("show_right_margin");
+  source.right_margin_position = source_json.get<unsigned>("right_margin_position");
+  source.spellcheck_language = source_json.get<std::string>("spellcheck_language");
+  source.default_tab_char = source_json.get<char>("default_tab_char");
+  source.default_tab_size = source_json.get<unsigned>("default_tab_size");
+  source.auto_tab_char_and_size = source_json.get<bool>("auto_tab_char_and_size");
+  source.tab_indents_line = source_json.get<bool>("tab_indents_line");
+  source.wrap_lines = source_json.get<bool>("wrap_lines");
+  source.highlight_current_line = source_json.get<bool>("highlight_current_line");
+  source.show_line_numbers = source_json.get<bool>("show_line_numbers");
+  source.enable_multiple_cursors = source_json.get<bool>("enable_multiple_cursors");
+  source.auto_reload_changed_files = source_json.get<bool>("auto_reload_changed_files");
+  source.clang_format_style = source_json.get<std::string>("clang_format_style");
+  source.clang_usages_threads = static_cast<unsigned>(source_json.get<int>("clang_usages_threads"));
+  auto pt_doc_search = cfg.get_child("documentation_searches");
+  for (auto &pt_doc_search_lang: pt_doc_search) {
+    source.documentation_searches[pt_doc_search_lang.first].separator = pt_doc_search_lang.second.get<std::string>(
+        "separator");
+    auto &queries = source.documentation_searches.find(pt_doc_search_lang.first)->second.queries;
+    for (auto &i: pt_doc_search_lang.second.get_child("queries")) {
+      queries[i.first] = i.second.get_value<std::string>();
     }
-
-    auto source_json = cfg.get_child("source");
-    source.style = source_json.get<std::string>("style");
-    source.font = source_json.get<std::string>("font");
-    source.cleanup_whitespace_characters = source_json.get<bool>("cleanup_whitespace_characters");
-    source.show_whitespace_characters = source_json.get<std::string>("show_whitespace_characters");
-    source.format_style_on_save = source_json.get<bool>("format_style_on_save");
-    source.format_style_on_save_if_style_file_found = source_json.get<bool>("format_style_on_save_if_style_file_found");
-    source.smart_brackets = source_json.get<bool>("smart_brackets");
-    source.smart_inserts = source_json.get<bool>("smart_inserts");
-    if (source.smart_inserts)
-        source.smart_brackets = true;
-    source.show_map = source_json.get<bool>("show_map");
-    source.map_font_size = source_json.get<std::string>("map_font_size");
-    source.show_git_diff = source_json.get<bool>("show_git_diff");
-    source.show_background_pattern = source_json.get<bool>("show_background_pattern");
-    source.show_right_margin = source_json.get<bool>("show_right_margin");
-    source.right_margin_position = source_json.get<unsigned>("right_margin_position");
-    source.spellcheck_language = source_json.get<std::string>("spellcheck_language");
-    source.default_tab_char = source_json.get<char>("default_tab_char");
-    source.default_tab_size = source_json.get<unsigned>("default_tab_size");
-    source.auto_tab_char_and_size = source_json.get<bool>("auto_tab_char_and_size");
-    source.tab_indents_line = source_json.get<bool>("tab_indents_line");
-    source.wrap_lines = source_json.get<bool>("wrap_lines");
-    source.highlight_current_line = source_json.get<bool>("highlight_current_line");
-    source.show_line_numbers = source_json.get<bool>("show_line_numbers");
-    source.enable_multiple_cursors = source_json.get<bool>("enable_multiple_cursors");
-    source.auto_reload_changed_files = source_json.get<bool>("auto_reload_changed_files");
-    source.clang_format_style = source_json.get<std::string>("clang_format_style");
-    source.clang_usages_threads = static_cast<unsigned>(source_json.get<int>("clang_usages_threads"));
-    auto pt_doc_search = cfg.get_child("documentation_searches");
-    for (auto &pt_doc_search_lang: pt_doc_search) {
-        source.documentation_searches[pt_doc_search_lang.first].separator = pt_doc_search_lang.second.get<std::string>(
-                "separator");
-        auto &queries = source.documentation_searches.find(pt_doc_search_lang.first)->second.queries;
-        for (auto &i: pt_doc_search_lang.second.get_child("queries")) {
-            queries[i.first] = i.second.get_value<std::string>();
-        }
-    }
-
-    window.theme_name = cfg.get<std::string>("gtk_theme.name");
-    window.theme_variant = cfg.get<std::string>("gtk_theme.variant");
-    window.version = cfg.get<std::string>("version");
-
-    project.default_build_path = cfg.get<std::string>("project.default_build_path");
-    project.debug_build_path = cfg.get<std::string>("project.debug_build_path");
-    project.cmake.command = cfg.get<std::string>("project.cmake.command");
-    project.cmake.compile_command = cfg.get<std::string>("project.cmake.compile_command");
-    project.meson.command = cfg.get<std::string>("project.meson.command");
-    project.meson.compile_command = cfg.get<std::string>("project.meson.compile_command");
-    project.save_on_compile_or_run = cfg.get<bool>("project.save_on_compile_or_run");
-    project.clear_terminal_on_compile = cfg.get<bool>("project.clear_terminal_on_compile");
-    project.ctags_command = cfg.get<std::string>("project.ctags_command");
-    project.python_command = cfg.get<std::string>("project.python_command");
-
-    terminal.history_size = cfg.get<int>("terminal.history_size");
-    terminal.font = cfg.get<std::string>("terminal.font");
+  }
+
+  window.theme_name = cfg.get<std::string>("gtk_theme.name");
+  window.theme_variant = cfg.get<std::string>("gtk_theme.variant");
+  window.version = cfg.get<std::string>("version");
+
+  project.default_build_path = cfg.get<std::string>("project.default_build_path");
+  project.debug_build_path = cfg.get<std::string>("project.debug_build_path");
+  project.cmake.command = cfg.get<std::string>("project.cmake.command");
+  project.cmake.compile_command = cfg.get<std::string>("project.cmake.compile_command");
+  project.meson.command = cfg.get<std::string>("project.meson.command");
+  project.meson.compile_command = cfg.get<std::string>("project.meson.compile_command");
+  project.save_on_compile_or_run = cfg.get<bool>("project.save_on_compile_or_run");
+  project.clear_terminal_on_compile = cfg.get<bool>("project.clear_terminal_on_compile");
+  project.ctags_command = cfg.get<std::string>("project.ctags_command");
+  project.python_command = cfg.get<std::string>("project.python_command");
+
+  terminal.history_size = cfg.get<int>("terminal.history_size");
+  terminal.font = cfg.get<std::string>("terminal.font");
 }
diff --git a/src/config.h b/src/config.h
index 5ec14d86..096374b8 100644
--- a/src/config.h
+++ b/src/config.h
@@ -10,129 +10,129 @@
 
 class Config {
 public:
-    class Menu {
+  class Menu {
+  public:
+    std::unordered_map<std::string, std::string> keys;
+  };
+
+  class Window {
+  public:
+    std::string theme_name;
+    std::string theme_variant;
+    std::string version;
+  };
+
+  class Terminal {
+  public:
+    int history_size;
+    std::string font;
+  };
+
+  class Project {
+  public:
+    class CMake {
     public:
-        std::unordered_map<std::string, std::string> keys;
+      std::string command;
+      std::string compile_command;
     };
 
-    class Window {
+    class Meson {
     public:
-        std::string theme_name;
-        std::string theme_variant;
-        std::string version;
+      std::string command;
+      std::string compile_command;
     };
 
-    class Terminal {
+    std::string default_build_path;
+    std::string debug_build_path;
+    CMake cmake;
+    Meson meson;
+    bool save_on_compile_or_run;
+    bool clear_terminal_on_compile;
+    std::string ctags_command;
+    std::string python_command;
+  };
+
+  class Source {
+  public:
+    class DocumentationSearch {
     public:
-        int history_size;
-        std::string font;
+      std::string separator;
+      std::unordered_map<std::string, std::string> queries;
     };
 
-    class Project {
-    public:
-        class CMake {
-        public:
-            std::string command;
-            std::string compile_command;
-        };
-
-        class Meson {
-        public:
-            std::string command;
-            std::string compile_command;
-        };
-
-        std::string default_build_path;
-        std::string debug_build_path;
-        CMake cmake;
-        Meson meson;
-        bool save_on_compile_or_run;
-        bool clear_terminal_on_compile;
-        std::string ctags_command;
-        std::string python_command;
-    };
+    std::string style;
+    std::string font;
+    std::string spellcheck_language;
 
-    class Source {
-    public:
-        class DocumentationSearch {
-        public:
-            std::string separator;
-            std::unordered_map<std::string, std::string> queries;
-        };
-
-        std::string style;
-        std::string font;
-        std::string spellcheck_language;
-
-        bool cleanup_whitespace_characters;
-        std::string show_whitespace_characters;
-
-        bool format_style_on_save;
-        bool format_style_on_save_if_style_file_found;
-
-        bool smart_brackets;
-        bool smart_inserts;
-
-        bool show_map;
-        std::string map_font_size;
-        bool show_git_diff;
-        bool show_background_pattern;
-        bool show_right_margin;
-        unsigned right_margin_position;
-
-        bool auto_tab_char_and_size;
-        char default_tab_char;
-        unsigned default_tab_size;
-        bool tab_indents_line;
-        bool wrap_lines;
-        bool highlight_current_line;
-        bool show_line_numbers;
-        bool enable_multiple_cursors;
-        bool auto_reload_changed_files;
-
-        std::string clang_format_style;
-        unsigned clang_usages_threads;
-
-        std::unordered_map<std::string, DocumentationSearch> documentation_searches;
-    };
+    bool cleanup_whitespace_characters;
+    std::string show_whitespace_characters;
+
+    bool format_style_on_save;
+    bool format_style_on_save_if_style_file_found;
+
+    bool smart_brackets;
+    bool smart_inserts;
+
+    bool show_map;
+    std::string map_font_size;
+    bool show_git_diff;
+    bool show_background_pattern;
+    bool show_right_margin;
+    unsigned right_margin_position;
+
+    bool auto_tab_char_and_size;
+    char default_tab_char;
+    unsigned default_tab_size;
+    bool tab_indents_line;
+    bool wrap_lines;
+    bool highlight_current_line;
+    bool show_line_numbers;
+    bool enable_multiple_cursors;
+    bool auto_reload_changed_files;
+
+    std::string clang_format_style;
+    unsigned clang_usages_threads;
+
+    std::unordered_map<std::string, DocumentationSearch> documentation_searches;
+  };
 
 private:
-    Config();
+  Config();
 
 public:
-    static Config &get() {
-        static Config singleton;
-        return singleton;
-    }
+  static Config &get() {
+    static Config singleton;
+    return singleton;
+  }
 
-    void load();
+  void load();
 
-    Menu menu;
-    Window window;
-    Terminal terminal;
-    Project project;
-    Source source;
+  Menu menu;
+  Window window;
+  Terminal terminal;
+  Project project;
+  Source source;
 
-    boost::filesystem::path home_path;
-    boost::filesystem::path home_juci_path;
+  boost::filesystem::path home_path;
+  boost::filesystem::path home_juci_path;
 
 private:
-    /// Used to dispatch Terminal outputs after juCi++ GUI setup and configuration
-    Dispatcher dispatcher;
+  /// Used to dispatch Terminal outputs after juCi++ GUI setup and configuration
+  Dispatcher dispatcher;
 
-    void find_or_create_config_files();
+  void find_or_create_config_files();
 
-    void update(boost::property_tree::ptree &cfg);
+  void update(boost::property_tree::ptree &cfg);
 
-    void
-    make_version_dependent_corrections(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
-                                       const std::string &version);
+  void
+  make_version_dependent_corrections(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                                     const std::string &version);
 
-    bool add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
-                           std::string parent_path = "");
+  bool add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                         std::string parent_path = "");
 
-    bool remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
-                                 std::string parent_path = "");
+  bool remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                               std::string parent_path = "");
 
-    void read(const boost::property_tree::ptree &cfg);
+  void read(const boost::property_tree::ptree &cfg);
 };
diff --git a/src/ctags.cc b/src/ctags.cc
index e51213c1..08642d53 100644
--- a/src/ctags.cc
+++ b/src/ctags.cc
@@ -10,197 +10,197 @@
 
 std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> >
 Ctags::get_result(const boost::filesystem::path &path) {
-    auto build = Project::Build::create(path);
-    auto run_path = build->project_path;
-    std::string exclude;
-    if (!run_path.empty()) {
-        auto relative_default_path = filesystem::get_relative_path(build->get_default_path(), run_path);
-        if (!relative_default_path.empty())
-            exclude += " --exclude=" + relative_default_path.string();
-
-        auto relative_debug_path = filesystem::get_relative_path(build->get_debug_path(), run_path);
-        if (!relative_debug_path.empty())
-            exclude += " --exclude=" + relative_debug_path.string();
-    } else {
-        boost::system::error_code ec;
-        if (boost::filesystem::is_directory(path, ec) || ec)
-            run_path = path;
-        else
-            run_path = path.parent_path();
-    }
-
-    std::stringstream stdin_stream;
-    //TODO: when debian stable gets newer g++ version that supports move on streams, remove unique_ptr below
-    auto stdout_stream = std::make_unique<std::stringstream>();
-    auto command = Config::get().project.ctags_command + exclude +
-                   " --fields=ns --sort=foldcase -I \"override noexcept\" -f - -R *";
-    Terminal::get().process(stdin_stream, *stdout_stream, command, run_path);
-    return {run_path, std::move(stdout_stream)};
+  auto build = Project::Build::create(path);
+  auto run_path = build->project_path;
+  std::string exclude;
+  if (!run_path.empty()) {
+    auto relative_default_path = filesystem::get_relative_path(build->get_default_path(), run_path);
+    if (!relative_default_path.empty())
+      exclude += " --exclude=" + relative_default_path.string();
+
+    auto relative_debug_path = filesystem::get_relative_path(build->get_debug_path(), run_path);
+    if (!relative_debug_path.empty())
+      exclude += " --exclude=" + relative_debug_path.string();
+  } else {
+    boost::system::error_code ec;
+    if (boost::filesystem::is_directory(path, ec) || ec)
+      run_path = path;
+    else
+      run_path = path.parent_path();
+  }
+
+  std::stringstream stdin_stream;
+  //TODO: when debian stable gets newer g++ version that supports move on streams, remove unique_ptr below
+  auto stdout_stream = std::make_unique<std::stringstream>();
+  auto command = Config::get().project.ctags_command + exclude +
+                 " --fields=ns --sort=foldcase -I \"override noexcept\" -f - -R *";
+  Terminal::get().process(stdin_stream, *stdout_stream, command, run_path);
+  return {run_path, std::move(stdout_stream)};
 }
 
 Ctags::Location Ctags::get_location(const std::string &line, bool markup) {
-    Location location;
+  Location location;
 
 #ifdef _WIN32
-    auto line_fixed = line;
-    if (!line_fixed.empty() && line_fixed.back() == '\r')
-        line_fixed.pop_back();
+  auto line_fixed = line;
+  if (!line_fixed.empty() && line_fixed.back() == '\r')
+    line_fixed.pop_back();
 #else
-    auto &line_fixed=line;
+  auto &line_fixed=line;
 #endif
 
-    const static std::regex regex(
-            "^([^\t]+)\t([^\t]+)\t(?:/\\^)?([ \t]*)(.+?)(\\$/)?;\"\tline:([0-9]+)\t?[a-zA-Z]*:?(.*)$");
-    std::smatch sm;
-    if (std::regex_match(line_fixed, sm, regex)) {
-        location.symbol = sm[1].str();
-        //fix location.symbol for operators
-        if (9 < location.symbol.size() && location.symbol[8] == ' ' && location.symbol.compare(0, 8, "operator") == 0) {
-            auto &chr = location.symbol[9];
-            if (!((chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr == '_'))
-                location.symbol.erase(8, 1);
-        }
+  const static std::regex regex(
+      "^([^\t]+)\t([^\t]+)\t(?:/\\^)?([ \t]*)(.+?)(\\$/)?;\"\tline:([0-9]+)\t?[a-zA-Z]*:?(.*)$");
+  std::smatch sm;
+  if (std::regex_match(line_fixed, sm, regex)) {
+    location.symbol = sm[1].str();
+    //fix location.symbol for operators
+    if (9 < location.symbol.size() && location.symbol[8] == ' ' && location.symbol.compare(0, 8, "operator") == 0) {
+      auto &chr = location.symbol[9];
+      if (!((chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr == '_'))
+        location.symbol.erase(8, 1);
+    }
 
-        location.file_path = sm[2].str();
-        location.source = sm[4].str();
-        try {
-            location.line = std::stoul(sm[6]) - 1;
-        }
-        catch (const std::exception &) {
-            location.line = 0;
-        }
-        location.scope = sm[7].str();
-        if (!sm[5].str().empty()) {
-            location.index = sm[3].str().size();
-
-            size_t pos = location.source.find(location.symbol);
-            if (pos != std::string::npos)
-                location.index += pos;
-
-            if (markup) {
-                location.source = Glib::Markup::escape_text(location.source);
-                auto symbol = Glib::Markup::escape_text(location.symbol);
-                pos = -1;
-                while ((pos = location.source.find(symbol, pos + 1)) != std::string::npos) {
-                    location.source.insert(pos + symbol.size(), "</b>");
-                    location.source.insert(pos, "<b>");
-                    pos += 7 + symbol.size();
-                }
-            }
-        } else {
-            location.index = 0;
-            location.source = location.symbol;
-            if (markup)
-                location.source = "<b>" + Glib::Markup::escape_text(location.source) + "</b>";
+    location.file_path = sm[2].str();
+    location.source = sm[4].str();
+    try {
+      location.line = std::stoul(sm[6]) - 1;
+    }
+    catch (const std::exception &) {
+      location.line = 0;
+    }
+    location.scope = sm[7].str();
+    if (!sm[5].str().empty()) {
+      location.index = sm[3].str().size();
+
+      size_t pos = location.source.find(location.symbol);
+      if (pos != std::string::npos)
+        location.index += pos;
+
+      if (markup) {
+        location.source = Glib::Markup::escape_text(location.source);
+        auto symbol = Glib::Markup::escape_text(location.symbol);
+        pos = -1;
+        while ((pos = location.source.find(symbol, pos + 1)) != std::string::npos) {
+          location.source.insert(pos + symbol.size(), "</b>");
+          location.source.insert(pos, "<b>");
+          pos += 7 + symbol.size();
         }
-    } else
-        std::cerr << "Warning (ctags): please report to the juCi++ project that the following line was not parsed:\n"
-                  << line << std::endl;
+      }
+    } else {
+      location.index = 0;
+      location.source = location.symbol;
+      if (markup)
+        location.source = "<b>" + Glib::Markup::escape_text(location.source) + "</b>";
+    }
+  } else
+    std::cerr << "Warning (ctags): please report to the juCi++ project that the following line was not parsed:\n"
+              << line << std::endl;
 
-    return location;
+  return location;
 }
 
 ///Split up a type into its various significant parts
 std::vector<std::string> Ctags::get_type_parts(const std::string type) {
-    std::vector<std::string> parts;
-    size_t text_start = -1;
-    for (size_t c = 0; c < type.size(); ++c) {
-        auto &chr = type[c];
-        if ((chr >= '0' && chr <= '9') || (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || chr == '_' ||
-            chr == '~') {
-            if (text_start == static_cast<size_t>(-1))
-                text_start = c;
-        } else {
-            if (text_start != static_cast<size_t>(-1)) {
-                parts.emplace_back(type.substr(text_start, c - text_start));
-                text_start = -1;
-            }
-            if (chr == '*' || chr == '&')
-                parts.emplace_back(std::string() + chr);
-        }
+  std::vector<std::string> parts;
+  size_t text_start = -1;
+  for (size_t c = 0; c < type.size(); ++c) {
+    auto &chr = type[c];
+    if ((chr >= '0' && chr <= '9') || (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || chr == '_' ||
+        chr == '~') {
+      if (text_start == static_cast<size_t>(-1))
+        text_start = c;
+    } else {
+      if (text_start != static_cast<size_t>(-1)) {
+        parts.emplace_back(type.substr(text_start, c - text_start));
+        text_start = -1;
+      }
+      if (chr == '*' || chr == '&')
+        parts.emplace_back(std::string() + chr);
     }
-    return parts;
+  }
+  return parts;
 }
 
 std::vector<Ctags::Location>
 Ctags::get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type) {
-    auto result = get_result(path);
-    result.second->seekg(0, std::ios::end);
-    if (result.second->tellg() == 0)
-        return std::vector<Location>();
-    result.second->seekg(0, std::ios::beg);
-
-    //insert name into type
-    size_t c = 0;
-    size_t bracket_count = 0;
-    for (; c < type.size(); ++c) {
-        if (type[c] == '<')
-            ++bracket_count;
-        else if (type[c] == '>')
-            --bracket_count;
-        else if (bracket_count == 0 && type[c] == '(')
-            break;
-    }
-    auto full_type = type;
-    full_type.insert(c, name);
-
-    auto parts = get_type_parts(full_type);
-
-    std::string line;
-    long best_score = LONG_MIN;
-    std::vector<Location> best_locations;
-    while (std::getline(*result.second, line)) {
-        if (line.size() > 2048)
-            continue;
-        auto location = Ctags::get_location(line, false);
-        if (!location.scope.empty()) {
-            if (location.scope + "::" + location.symbol != name)
-                continue;
-        } else if (location.symbol != name)
-            continue;
-
-        location.file_path = result.first / location.file_path;
-
-        auto source_parts = get_type_parts(location.source);
-
-        //Find match score
-        long score = 0;
-        size_t source_index = 0;
-        for (auto &part: parts) {
-            bool found = false;
-            for (auto c = source_index; c < source_parts.size(); ++c) {
-                if (part == source_parts[c]) {
-                    source_index = c + 1;
-                    ++score;
-                    found = true;
-                    break;
-                }
-            }
-            if (!found)
-                --score;
+  auto result = get_result(path);
+  result.second->seekg(0, std::ios::end);
+  if (result.second->tellg() == 0)
+    return std::vector<Location>();
+  result.second->seekg(0, std::ios::beg);
+
+  //insert name into type
+  size_t c = 0;
+  size_t bracket_count = 0;
+  for (; c < type.size(); ++c) {
+    if (type[c] == '<')
+      ++bracket_count;
+    else if (type[c] == '>')
+      --bracket_count;
+    else if (bracket_count == 0 && type[c] == '(')
+      break;
+  }
+  auto full_type = type;
+  full_type.insert(c, name);
+
+  auto parts = get_type_parts(full_type);
+
+  std::string line;
+  long best_score = LONG_MIN;
+  std::vector<Location> best_locations;
+  while (std::getline(*result.second, line)) {
+    if (line.size() > 2048)
+      continue;
+    auto location = Ctags::get_location(line, false);
+    if (!location.scope.empty()) {
+      if (location.scope + "::" + location.symbol != name)
+        continue;
+    } else if (location.symbol != name)
+      continue;
+
+    location.file_path = result.first / location.file_path;
+
+    auto source_parts = get_type_parts(location.source);
+
+    //Find match score
+    long score = 0;
+    size_t source_index = 0;
+    for (auto &part: parts) {
+      bool found = false;
+      for (auto c = source_index; c < source_parts.size(); ++c) {
+        if (part == source_parts[c]) {
+          source_index = c + 1;
+          ++score;
+          found = true;
+          break;
         }
-        size_t index = 0;
-        for (auto &source_part: source_parts) {
-            bool found = false;
-            for (auto c = index; c < parts.size(); ++c) {
-                if (source_part == parts[c]) {
-                    index = c + 1;
-                    ++score;
-                    found = true;
-                    break;
-                }
-            }
-            if (!found)
-                --score;
+      }
+      if (!found)
+        --score;
+    }
+    size_t index = 0;
+    for (auto &source_part: source_parts) {
+      bool found = false;
+      for (auto c = index; c < parts.size(); ++c) {
+        if (source_part == parts[c]) {
+          index = c + 1;
+          ++score;
+          found = true;
+          break;
         }
-
-        if (score > best_score) {
-            best_score = score;
-            best_locations.clear();
-            best_locations.emplace_back(location);
-        } else if (score == best_score)
-            best_locations.emplace_back(location);
+      }
+      if (!found)
+        --score;
     }
 
-    return best_locations;
+    if (score > best_score) {
+      best_score = score;
+      best_locations.clear();
+      best_locations.emplace_back(location);
+    } else if (score == best_score)
+      best_locations.emplace_back(location);
+  }
+
+  return best_locations;
 }
diff --git a/src/ctags.h b/src/ctags.h
index 0d0aefad..8ff5452b 100644
--- a/src/ctags.h
+++ b/src/ctags.h
@@ -7,26 +7,26 @@
 
 class Ctags {
 public:
-    class Location {
-    public:
-        boost::filesystem::path file_path;
-        unsigned long line;
-        unsigned long index;
-        std::string symbol;
-        std::string scope;
-        std::string source;
+  class Location {
+  public:
+    boost::filesystem::path file_path;
+    unsigned long line;
+    unsigned long index;
+    std::string symbol;
+    std::string scope;
+    std::string source;
 
-        operator bool() const { return !file_path.empty(); }
-    };
+    operator bool() const { return !file_path.empty(); }
+  };
 
-    static std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> >
-    get_result(const boost::filesystem::path &path);
+  static std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> >
+  get_result(const boost::filesystem::path &path);
 
-    static Location get_location(const std::string &line, bool markup);
+  static Location get_location(const std::string &line, bool markup);
 
-    static std::vector<Location>
-    get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type);
+  static std::vector<Location>
+  get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type);
 
 private:
-    static std::vector<std::string> get_type_parts(const std::string type);
+  static std::vector<std::string> get_type_parts(const std::string type);
 };
diff --git a/src/debug_lldb.cc b/src/debug_lldb.cc
index 7bfa7172..a64fde3d 100644
--- a/src/debug_lldb.cc
+++ b/src/debug_lldb.cc
@@ -15,529 +15,529 @@
 extern char **environ;
 
 void log(const char *msg, void *) {
-    std::cout << "debugger log: " << msg << std::endl;
+  std::cout << "debugger log: " << msg << std::endl;
 }
 
 Debug::LLDB::LLDB() : state(lldb::StateType::eStateInvalid), buffer_size(131072) {
-    if (!getenv("LLDB_DEBUGSERVER_PATH")) {
+  if (!getenv("LLDB_DEBUGSERVER_PATH")) {
 #ifdef __APPLE__
-        std::string debug_server_path("/usr/local/opt/llvm/bin/debugserver");
-        if(boost::filesystem::exists(debug_server_path))
-          setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
+    std::string debug_server_path("/usr/local/opt/llvm/bin/debugserver");
+    if(boost::filesystem::exists(debug_server_path))
+      setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
 #else
-        auto debug_server_path = filesystem::get_executable("lldb-server").string();
-        if (debug_server_path != "lldb-server")
-            setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
+    auto debug_server_path = filesystem::get_executable("lldb-server").string();
+    if (debug_server_path != "lldb-server")
+      setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
 #endif
-    }
+  }
 }
 
 std::tuple<std::vector<std::string>, std::string, std::vector<std::string> >
 Debug::LLDB::parse_run_arguments(const std::string &command) {
-    std::vector<std::string> environment;
-    std::string executable;
-    std::vector<std::string> arguments;
-
-    size_t start_pos = std::string::npos;
-    bool quote = false;
-    bool double_quote = false;
-    size_t backslash_count = 0;
-    for (size_t c = 0; c <= command.size(); c++) {
-        if (c == command.size() || (!quote && !double_quote && backslash_count % 2 == 0 && command[c] == ' ')) {
-            if (c > 0 && start_pos != std::string::npos) {
-                auto argument = command.substr(start_pos, c - start_pos);
-                if (executable.empty()) {
-                    //Check for environment variable
-                    bool env_arg = false;
-                    for (size_t c = 0; c < argument.size(); ++c) {
-                        if ((argument[c] >= 'a' && argument[c] <= 'z') || (argument[c] >= 'A' && argument[c] <= 'Z') ||
-                            (argument[c] >= '0' && argument[c] <= '9') || argument[c] == '_')
-                            continue;
-                        else if (argument[c] == '=' && c + 1 < argument.size()) {
-                            environment.emplace_back(
-                                    argument.substr(0, c + 1) + filesystem::unescape_argument(argument.substr(c + 1)));
-                            env_arg = true;
-                            break;
-                        } else
-                            break;
-                    }
-
-                    if (!env_arg) {
-                        executable = filesystem::unescape_argument(argument);
+  std::vector<std::string> environment;
+  std::string executable;
+  std::vector<std::string> arguments;
+
+  size_t start_pos = std::string::npos;
+  bool quote = false;
+  bool double_quote = false;
+  size_t backslash_count = 0;
+  for (size_t c = 0; c <= command.size(); c++) {
+    if (c == command.size() || (!quote && !double_quote && backslash_count % 2 == 0 && command[c] == ' ')) {
+      if (c > 0 && start_pos != std::string::npos) {
+        auto argument = command.substr(start_pos, c - start_pos);
+        if (executable.empty()) {
+          //Check for environment variable
+          bool env_arg = false;
+          for (size_t c = 0; c < argument.size(); ++c) {
+            if ((argument[c] >= 'a' && argument[c] <= 'z') || (argument[c] >= 'A' && argument[c] <= 'Z') ||
+                (argument[c] >= '0' && argument[c] <= '9') || argument[c] == '_')
+              continue;
+            else if (argument[c] == '=' && c + 1 < argument.size()) {
+              environment.emplace_back(
+                  argument.substr(0, c + 1) + filesystem::unescape_argument(argument.substr(c + 1)));
+              env_arg = true;
+              break;
+            } else
+              break;
+          }
+
+          if (!env_arg) {
+            executable = filesystem::unescape_argument(argument);
 #ifdef _WIN32
-                        if (remote_host.empty())
-                            executable += ".exe";
+            if (remote_host.empty())
+              executable += ".exe";
 #endif
-                    }
-                } else
-                    arguments.emplace_back(filesystem::unescape_argument(argument));
-                start_pos = std::string::npos;
-            }
-        } else if (command[c] == '\'' && backslash_count % 2 == 0 && !double_quote)
-            quote = !quote;
-        else if (command[c] == '"' && backslash_count % 2 == 0 && !quote)
-            double_quote = !double_quote;
-        else if (command[c] == '\\' && !quote && !double_quote)
-            ++backslash_count;
-        else
-            backslash_count = 0;
-        if (c < command.size() && start_pos == std::string::npos && command[c] != ' ')
-            start_pos = c;
-    }
-
-    return std::make_tuple(environment, executable, arguments);
+          }
+        } else
+          arguments.emplace_back(filesystem::unescape_argument(argument));
+        start_pos = std::string::npos;
+      }
+    } else if (command[c] == '\'' && backslash_count % 2 == 0 && !double_quote)
+      quote = !quote;
+    else if (command[c] == '"' && backslash_count % 2 == 0 && !quote)
+      double_quote = !double_quote;
+    else if (command[c] == '\\' && !quote && !double_quote)
+      ++backslash_count;
+    else
+      backslash_count = 0;
+    if (c < command.size() && start_pos == std::string::npos && command[c] != ' ')
+      start_pos = c;
+  }
+
+  return std::make_tuple(environment, executable, arguments);
 }
 
 void Debug::LLDB::start(const std::string &command, const boost::filesystem::path &path,
                         const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints,
                         const std::vector<std::string> &startup_commands, const std::string &remote_host) {
-    if (!debugger) {
-        lldb::SBDebugger::Initialize();
-        debugger = std::make_unique<lldb::SBDebugger>(lldb::SBDebugger::Create(true, log, nullptr));
-        listener = std::make_unique<lldb::SBListener>("juCi++ lldb listener");
+  if (!debugger) {
+    lldb::SBDebugger::Initialize();
+    debugger = std::make_unique<lldb::SBDebugger>(lldb::SBDebugger::Create(true, log, nullptr));
+    listener = std::make_unique<lldb::SBListener>("juCi++ lldb listener");
+  }
+
+  //Create executable string and argument array
+  auto parsed_run_arguments = parse_run_arguments(command);
+  auto &environment_from_arguments = std::get<0>(parsed_run_arguments);
+  auto &executable = std::get<1>(parsed_run_arguments);
+  auto &arguments = std::get<2>(parsed_run_arguments);
+
+  std::vector<const char *> argv;
+  for (size_t c = 0; c < arguments.size(); c++)
+    argv.emplace_back(arguments[c].c_str());
+  argv.emplace_back(nullptr);
+
+  auto target = debugger->CreateTarget(executable.c_str());
+  if (!target.IsValid()) {
+    Terminal::get().async_print("Error (debug): Could not create debug target to: " + executable + '\n', true);
+    for (auto &handler: on_exit)
+      handler(-1);
+    return;
+  }
+
+  //Set breakpoints
+  for (auto &breakpoint: breakpoints) {
+    if (!(target.BreakpointCreateByLocation(breakpoint.first.string().c_str(), breakpoint.second)).IsValid()) {
+      Terminal::get().async_print(
+          "Error (debug): Could not create breakpoint at: " + breakpoint.first.string() + ":" +
+          std::to_string(breakpoint.second) + '\n', true);
+      for (auto &handler: on_exit)
+        handler(-1);
+      return;
     }
+  }
 
-    //Create executable string and argument array
-    auto parsed_run_arguments = parse_run_arguments(command);
-    auto &environment_from_arguments = std::get<0>(parsed_run_arguments);
-    auto &executable = std::get<1>(parsed_run_arguments);
-    auto &arguments = std::get<2>(parsed_run_arguments);
-
-    std::vector<const char *> argv;
-    for (size_t c = 0; c < arguments.size(); c++)
-        argv.emplace_back(arguments[c].c_str());
-    argv.emplace_back(nullptr);
-
-    auto target = debugger->CreateTarget(executable.c_str());
-    if (!target.IsValid()) {
-        Terminal::get().async_print("Error (debug): Could not create debug target to: " + executable + '\n', true);
-        for (auto &handler: on_exit)
-            handler(-1);
-        return;
+  lldb::SBError error;
+  if (!remote_host.empty()) {
+    auto connect_string = "connect://" + remote_host;
+    process = std::make_unique<lldb::SBProcess>(
+        target.ConnectRemote(*listener, connect_string.c_str(), "gdb-remote", error));
+    if (error.Fail()) {
+      Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
+      for (auto &handler: on_exit)
+        handler(-1);
+      return;
     }
-
-    //Set breakpoints
-    for (auto &breakpoint: breakpoints) {
-        if (!(target.BreakpointCreateByLocation(breakpoint.first.string().c_str(), breakpoint.second)).IsValid()) {
-            Terminal::get().async_print(
-                    "Error (debug): Could not create breakpoint at: " + breakpoint.first.string() + ":" +
-                    std::to_string(breakpoint.second) + '\n', true);
-            for (auto &handler: on_exit)
-                handler(-1);
-            return;
+    lldb::SBEvent event;
+    while (true) {
+      if (listener->GetNextEvent(event)) {
+        if ((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged) > 0) {
+          auto state = process->GetStateFromEvent(event);
+          this->state = state;
+          if (state == lldb::StateType::eStateConnected)
+            break;
         }
+      }
     }
 
-    lldb::SBError error;
-    if (!remote_host.empty()) {
-        auto connect_string = "connect://" + remote_host;
-        process = std::make_unique<lldb::SBProcess>(
-                target.ConnectRemote(*listener, connect_string.c_str(), "gdb-remote", error));
-        if (error.Fail()) {
-            Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
-            for (auto &handler: on_exit)
-                handler(-1);
-            return;
-        }
-        lldb::SBEvent event;
-        while (true) {
-            if (listener->GetNextEvent(event)) {
-                if ((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged) > 0) {
-                    auto state = process->GetStateFromEvent(event);
-                    this->state = state;
-                    if (state == lldb::StateType::eStateConnected)
-                        break;
-                }
+    // Create environment array
+    std::vector<const char *> environment;
+    for (auto &e: environment_from_arguments)
+      environment.emplace_back(e.c_str());
+    environment.emplace_back(nullptr);
+
+    process->RemoteLaunch(argv.data(), environment.data(), nullptr, nullptr, nullptr, nullptr,
+                          lldb::eLaunchFlagNone, false, error);
+    if (!error.Fail())
+      process->Continue();
+  } else {
+    // Create environment array
+    std::vector<const char *> environment;
+    for (auto &e: environment_from_arguments)
+      environment.emplace_back(e.c_str());
+    size_t environ_size = 0;
+    while (environ[environ_size] != nullptr)
+      ++environ_size;
+    for (size_t c = 0; c < environ_size; ++c)
+      environment.emplace_back(environ[c]);
+    environment.emplace_back(nullptr);
+
+    process = std::make_unique<lldb::SBProcess>(
+        target.Launch(*listener, argv.data(), environment.data(), nullptr, nullptr, nullptr,
+                      path.string().c_str(), lldb::eLaunchFlagNone, false, error));
+  }
+  if (error.Fail()) {
+    Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
+    for (auto &handler: on_exit)
+      handler(-1);
+    return;
+  }
+  if (debug_thread.joinable())
+    debug_thread.join();
+  for (auto &handler: on_start)
+    handler(*process);
+
+  for (auto &command: startup_commands) {
+    lldb::SBCommandReturnObject command_return_object;
+    debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, false);
+  }
+
+  debug_thread = std::thread([this]() {
+    lldb::SBEvent event;
+    while (true) {
+      std::unique_lock<std::mutex> lock(mutex);
+      if (listener->GetNextEvent(event)) {
+        if ((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged) > 0) {
+          auto state = process->GetStateFromEvent(event);
+          this->state = state;
+
+          if (state == lldb::StateType::eStateStopped) {
+            for (uint32_t c = 0; c < process->GetNumThreads(); c++) {
+              auto thread = process->GetThreadAtIndex(c);
+              if (thread.GetStopReason() >= 2) {
+                process->SetSelectedThreadByIndexID(thread.GetIndexID());
+                break;
+              }
             }
-        }
+          }
 
-        // Create environment array
-        std::vector<const char *> environment;
-        for (auto &e: environment_from_arguments)
-            environment.emplace_back(e.c_str());
-        environment.emplace_back(nullptr);
-
-        process->RemoteLaunch(argv.data(), environment.data(), nullptr, nullptr, nullptr, nullptr,
-                              lldb::eLaunchFlagNone, false, error);
-        if (!error.Fail())
-            process->Continue();
-    } else {
-        // Create environment array
-        std::vector<const char *> environment;
-        for (auto &e: environment_from_arguments)
-            environment.emplace_back(e.c_str());
-        size_t environ_size = 0;
-        while (environ[environ_size] != nullptr)
-            ++environ_size;
-        for (size_t c = 0; c < environ_size; ++c)
-            environment.emplace_back(environ[c]);
-        environment.emplace_back(nullptr);
-
-        process = std::make_unique<lldb::SBProcess>(
-                target.Launch(*listener, argv.data(), environment.data(), nullptr, nullptr, nullptr,
-                              path.string().c_str(), lldb::eLaunchFlagNone, false, error));
-    }
-    if (error.Fail()) {
-        Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
-        for (auto &handler: on_exit)
-            handler(-1);
-        return;
-    }
-    if (debug_thread.joinable())
-        debug_thread.join();
-    for (auto &handler: on_start)
-        handler(*process);
-
-    for (auto &command: startup_commands) {
-        lldb::SBCommandReturnObject command_return_object;
-        debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, false);
-    }
+          lock.unlock();
+          for (auto &handler: on_event)
+            handler(event);
+          lock.lock();
 
-    debug_thread = std::thread([this]() {
-        lldb::SBEvent event;
-        while (true) {
-            std::unique_lock<std::mutex> lock(mutex);
-            if (listener->GetNextEvent(event)) {
-                if ((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged) > 0) {
-                    auto state = process->GetStateFromEvent(event);
-                    this->state = state;
-
-                    if (state == lldb::StateType::eStateStopped) {
-                        for (uint32_t c = 0; c < process->GetNumThreads(); c++) {
-                            auto thread = process->GetThreadAtIndex(c);
-                            if (thread.GetStopReason() >= 2) {
-                                process->SetSelectedThreadByIndexID(thread.GetIndexID());
-                                break;
-                            }
-                        }
-                    }
-
-                    lock.unlock();
-                    for (auto &handler: on_event)
-                        handler(event);
-                    lock.lock();
-
-                    if (state == lldb::StateType::eStateExited || state == lldb::StateType::eStateCrashed) {
-                        auto exit_status = state == lldb::StateType::eStateCrashed ? -1 : process->GetExitStatus();
-                        lock.unlock();
-                        for (auto &handler: on_exit)
-                            handler(exit_status);
-                        lock.lock();
-                        process.reset();
-                        this->state = lldb::StateType::eStateInvalid;
-                        return;
-                    }
-                }
-                if ((event.GetType() & lldb::SBProcess::eBroadcastBitSTDOUT) > 0) {
-                    char buffer[buffer_size];
-                    size_t n;
-                    while ((n = process->GetSTDOUT(buffer, buffer_size)) != 0)
-                        Terminal::get().async_print(std::string(buffer, n));
-                }
-                //TODO: for some reason stderr is redirected to stdout
-                if ((event.GetType() & lldb::SBProcess::eBroadcastBitSTDERR) > 0) {
-                    char buffer[buffer_size];
-                    size_t n;
-                    while ((n = process->GetSTDERR(buffer, buffer_size)) != 0)
-                        Terminal::get().async_print(std::string(buffer, n), true);
-                }
-            }
+          if (state == lldb::StateType::eStateExited || state == lldb::StateType::eStateCrashed) {
+            auto exit_status = state == lldb::StateType::eStateCrashed ? -1 : process->GetExitStatus();
             lock.unlock();
-            std::this_thread::sleep_for(std::chrono::milliseconds(200));
+            for (auto &handler: on_exit)
+              handler(exit_status);
+            lock.lock();
+            process.reset();
+            this->state = lldb::StateType::eStateInvalid;
+            return;
+          }
+        }
+        if ((event.GetType() & lldb::SBProcess::eBroadcastBitSTDOUT) > 0) {
+          char buffer[buffer_size];
+          size_t n;
+          while ((n = process->GetSTDOUT(buffer, buffer_size)) != 0)
+            Terminal::get().async_print(std::string(buffer, n));
+        }
+        //TODO: for some reason stderr is redirected to stdout
+        if ((event.GetType() & lldb::SBProcess::eBroadcastBitSTDERR) > 0) {
+          char buffer[buffer_size];
+          size_t n;
+          while ((n = process->GetSTDERR(buffer, buffer_size)) != 0)
+            Terminal::get().async_print(std::string(buffer, n), true);
         }
-    });
+      }
+      lock.unlock();
+      std::this_thread::sleep_for(std::chrono::milliseconds(200));
+    }
+  });
 }
 
 void Debug::LLDB::continue_debug() {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped)
-        process->Continue();
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped)
+    process->Continue();
 }
 
 void Debug::LLDB::stop() {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateRunning) {
-        auto error = process->Stop();
-        if (error.Fail())
-            Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
-    }
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateRunning) {
+    auto error = process->Stop();
+    if (error.Fail())
+      Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
+  }
 }
 
 void Debug::LLDB::kill() {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (process) {
-        auto error = process->Kill();
-        if (error.Fail())
-            Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
-    }
+  std::unique_lock<std::mutex> lock(mutex);
+  if (process) {
+    auto error = process->Kill();
+    if (error.Fail())
+      Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true);
+  }
 }
 
 void Debug::LLDB::step_over() {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped) {
-        process->GetSelectedThread().StepOver();
-    }
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped) {
+    process->GetSelectedThread().StepOver();
+  }
 }
 
 void Debug::LLDB::step_into() {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped) {
-        process->GetSelectedThread().StepInto();
-    }
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped) {
+    process->GetSelectedThread().StepInto();
+  }
 }
 
 void Debug::LLDB::step_out() {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped) {
-        process->GetSelectedThread().StepOut();
-    }
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped) {
+    process->GetSelectedThread().StepOut();
+  }
 }
 
 std::pair<std::string, std::string> Debug::LLDB::run_command(const std::string &command) {
-    std::pair<std::string, std::string> command_return;
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped || state == lldb::StateType::eStateRunning) {
-        lldb::SBCommandReturnObject command_return_object;
-        debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, true);
-        auto output = command_return_object.GetOutput();
-        if (output)
-            command_return.first = output;
-        auto error = command_return_object.GetError();
-        if (error)
-            command_return.second = error;
-    }
-    return command_return;
+  std::pair<std::string, std::string> command_return;
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped || state == lldb::StateType::eStateRunning) {
+    lldb::SBCommandReturnObject command_return_object;
+    debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, true);
+    auto output = command_return_object.GetOutput();
+    if (output)
+      command_return.first = output;
+    auto error = command_return_object.GetError();
+    if (error)
+      command_return.second = error;
+  }
+  return command_return;
 }
 
 std::vector<Debug::LLDB::Frame> Debug::LLDB::get_backtrace() {
-    std::vector<Frame> backtrace;
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped) {
-        auto thread = process->GetSelectedThread();
-        for (uint32_t c_f = 0; c_f < thread.GetNumFrames(); c_f++) {
-            Frame backtrace_frame;
-            auto frame = thread.GetFrameAtIndex(c_f);
-
-            backtrace_frame.index = c_f;
-
-            if (frame.GetFunctionName() != nullptr)
-                backtrace_frame.function_name = frame.GetFunctionName();
-
-            auto module_filename = frame.GetModule().GetFileSpec().GetFilename();
-            if (module_filename != nullptr) {
-                backtrace_frame.module_filename = module_filename;
-            }
-
-            auto line_entry = frame.GetLineEntry();
-            if (line_entry.IsValid()) {
-                lldb::SBStream stream;
-                line_entry.GetFileSpec().GetDescription(stream);
-                auto column = line_entry.GetColumn();
-                if (column == 0)
-                    column = 1;
-                backtrace_frame.file_path = filesystem::get_normal_path(stream.GetData());
-                backtrace_frame.line_nr = line_entry.GetLine();
-                backtrace_frame.line_index = column;
-            }
-            backtrace.emplace_back(backtrace_frame);
-        }
+  std::vector<Frame> backtrace;
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped) {
+    auto thread = process->GetSelectedThread();
+    for (uint32_t c_f = 0; c_f < thread.GetNumFrames(); c_f++) {
+      Frame backtrace_frame;
+      auto frame = thread.GetFrameAtIndex(c_f);
+
+      backtrace_frame.index = c_f;
+
+      if (frame.GetFunctionName() != nullptr)
+        backtrace_frame.function_name = frame.GetFunctionName();
+
+      auto module_filename = frame.GetModule().GetFileSpec().GetFilename();
+      if (module_filename != nullptr) {
+        backtrace_frame.module_filename = module_filename;
+      }
+
+      auto line_entry = frame.GetLineEntry();
+      if (line_entry.IsValid()) {
+        lldb::SBStream stream;
+        line_entry.GetFileSpec().GetDescription(stream);
+        auto column = line_entry.GetColumn();
+        if (column == 0)
+          column = 1;
+        backtrace_frame.file_path = filesystem::get_normal_path(stream.GetData());
+        backtrace_frame.line_nr = line_entry.GetLine();
+        backtrace_frame.line_index = column;
+      }
+      backtrace.emplace_back(backtrace_frame);
     }
-    return backtrace;
+  }
+  return backtrace;
 }
 
 std::vector<Debug::LLDB::Variable> Debug::LLDB::get_variables() {
-    std::vector<Debug::LLDB::Variable> variables;
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped) {
-        for (uint32_t c_t = 0; c_t < process->GetNumThreads(); c_t++) {
-            auto thread = process->GetThreadAtIndex(c_t);
-            for (uint32_t c_f = 0; c_f < thread.GetNumFrames(); c_f++) {
-                auto frame = thread.GetFrameAtIndex(c_f);
-                auto values = frame.GetVariables(true, true, true, false);
-                for (uint32_t value_index = 0; value_index < values.GetSize(); value_index++) {
-                    lldb::SBStream stream;
-                    auto value = values.GetValueAtIndex(value_index);
-
-                    Debug::LLDB::Variable variable;
-                    variable.thread_index_id = thread.GetIndexID();
-                    variable.frame_index = c_f;
-                    if (value.GetName() != nullptr)
-                        variable.name = value.GetName();
-                    value.GetDescription(stream);
-                    variable.value = stream.GetData();
-
-                    auto declaration = value.GetDeclaration();
-                    if (declaration.IsValid()) {
-                        variable.declaration_found = true;
-                        variable.line_nr = declaration.GetLine();
-                        variable.line_index = declaration.GetColumn();
-                        if (variable.line_index == 0)
-                            variable.line_index = 1;
-
-                        auto file_spec = declaration.GetFileSpec();
-                        variable.file_path = filesystem::get_normal_path(file_spec.GetDirectory());
-                        variable.file_path /= file_spec.GetFilename();
-                    } else {
-                        variable.declaration_found = false;
-                        auto line_entry = frame.GetLineEntry();
-                        if (line_entry.IsValid()) {
-                            variable.line_nr = line_entry.GetLine();
-                            variable.line_index = line_entry.GetColumn();
-                            if (variable.line_index == 0)
-                                variable.line_index = 1;
-
-                            auto file_spec = line_entry.GetFileSpec();
-                            variable.file_path = filesystem::get_normal_path(file_spec.GetDirectory());
-                            variable.file_path /= file_spec.GetFilename();
-                        }
-                    }
-                    variables.emplace_back(variable);
-                }
+  std::vector<Debug::LLDB::Variable> variables;
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped) {
+    for (uint32_t c_t = 0; c_t < process->GetNumThreads(); c_t++) {
+      auto thread = process->GetThreadAtIndex(c_t);
+      for (uint32_t c_f = 0; c_f < thread.GetNumFrames(); c_f++) {
+        auto frame = thread.GetFrameAtIndex(c_f);
+        auto values = frame.GetVariables(true, true, true, false);
+        for (uint32_t value_index = 0; value_index < values.GetSize(); value_index++) {
+          lldb::SBStream stream;
+          auto value = values.GetValueAtIndex(value_index);
+
+          Debug::LLDB::Variable variable;
+          variable.thread_index_id = thread.GetIndexID();
+          variable.frame_index = c_f;
+          if (value.GetName() != nullptr)
+            variable.name = value.GetName();
+          value.GetDescription(stream);
+          variable.value = stream.GetData();
+
+          auto declaration = value.GetDeclaration();
+          if (declaration.IsValid()) {
+            variable.declaration_found = true;
+            variable.line_nr = declaration.GetLine();
+            variable.line_index = declaration.GetColumn();
+            if (variable.line_index == 0)
+              variable.line_index = 1;
+
+            auto file_spec = declaration.GetFileSpec();
+            variable.file_path = filesystem::get_normal_path(file_spec.GetDirectory());
+            variable.file_path /= file_spec.GetFilename();
+          } else {
+            variable.declaration_found = false;
+            auto line_entry = frame.GetLineEntry();
+            if (line_entry.IsValid()) {
+              variable.line_nr = line_entry.GetLine();
+              variable.line_index = line_entry.GetColumn();
+              if (variable.line_index == 0)
+                variable.line_index = 1;
+
+              auto file_spec = line_entry.GetFileSpec();
+              variable.file_path = filesystem::get_normal_path(file_spec.GetDirectory());
+              variable.file_path /= file_spec.GetFilename();
             }
+          }
+          variables.emplace_back(variable);
         }
+      }
     }
-    return variables;
+  }
+  return variables;
 }
 
 void Debug::LLDB::select_frame(uint32_t frame_index, uint32_t thread_index_id) {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped) {
-        if (thread_index_id != 0)
-            process->SetSelectedThreadByIndexID(thread_index_id);
-        process->GetSelectedThread().SetSelectedFrame(frame_index);;
-    }
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped) {
+    if (thread_index_id != 0)
+      process->SetSelectedThreadByIndexID(thread_index_id);
+    process->GetSelectedThread().SetSelectedFrame(frame_index);;
+  }
 }
 
 void Debug::LLDB::cancel() {
-    kill();
-    if (debug_thread.joinable())
-        debug_thread.join();
+  kill();
+  if (debug_thread.joinable())
+    debug_thread.join();
 }
 
 std::string
 Debug::LLDB::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr,
                        unsigned int line_index) {
-    std::string variable_value;
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped) {
-        auto frame = process->GetSelectedThread().GetSelectedFrame();
-
-        auto values = frame.GetVariables(true, true, true, false);
-        //First try to find variable based on name, file and line number
-        if (!file_path.empty()) {
-            for (uint32_t value_index = 0; value_index < values.GetSize(); value_index++) {
-                lldb::SBStream stream;
-                auto value = values.GetValueAtIndex(value_index);
-
-                if (value.GetName() != nullptr && value.GetName() == variable) {
-                    auto declaration = value.GetDeclaration();
-                    if (declaration.IsValid()) {
-                        if (declaration.GetLine() == line_nr &&
-                            (declaration.GetColumn() == 0 || declaration.GetColumn() == line_index)) {
-                            auto file_spec = declaration.GetFileSpec();
-                            auto value_decl_path = filesystem::get_normal_path(file_spec.GetDirectory());
-                            value_decl_path /= file_spec.GetFilename();
-                            if (value_decl_path == file_path) {
-                                value.GetDescription(stream);
-                                variable_value = stream.GetData();
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        if (variable_value.empty()) {
-            //In case a variable is missing file and line number, only do check on name
-            auto value = frame.GetValueForVariablePath(variable.c_str());
-            if (value.IsValid()) {
-                lldb::SBStream stream;
+  std::string variable_value;
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped) {
+    auto frame = process->GetSelectedThread().GetSelectedFrame();
+
+    auto values = frame.GetVariables(true, true, true, false);
+    //First try to find variable based on name, file and line number
+    if (!file_path.empty()) {
+      for (uint32_t value_index = 0; value_index < values.GetSize(); value_index++) {
+        lldb::SBStream stream;
+        auto value = values.GetValueAtIndex(value_index);
+
+        if (value.GetName() != nullptr && value.GetName() == variable) {
+          auto declaration = value.GetDeclaration();
+          if (declaration.IsValid()) {
+            if (declaration.GetLine() == line_nr &&
+                (declaration.GetColumn() == 0 || declaration.GetColumn() == line_index)) {
+              auto file_spec = declaration.GetFileSpec();
+              auto value_decl_path = filesystem::get_normal_path(file_spec.GetDirectory());
+              value_decl_path /= file_spec.GetFilename();
+              if (value_decl_path == file_path) {
                 value.GetDescription(stream);
                 variable_value = stream.GetData();
+                break;
+              }
             }
+          }
         }
+      }
     }
-    return variable_value;
+    if (variable_value.empty()) {
+      //In case a variable is missing file and line number, only do check on name
+      auto value = frame.GetValueForVariablePath(variable.c_str());
+      if (value.IsValid()) {
+        lldb::SBStream stream;
+        value.GetDescription(stream);
+        variable_value = stream.GetData();
+      }
+    }
+  }
+  return variable_value;
 }
 
 std::string
 Debug::LLDB::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) {
-    std::string return_value;
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateStopped) {
-        auto thread = process->GetSelectedThread();
-        auto thread_return_value = thread.GetStopReturnValue();
-        if (thread_return_value.IsValid()) {
-            auto line_entry = thread.GetSelectedFrame().GetLineEntry();
-            if (line_entry.IsValid()) {
-                lldb::SBStream stream;
-                line_entry.GetFileSpec().GetDescription(stream);
-                if (filesystem::get_normal_path(stream.GetData()) == file_path && line_entry.GetLine() == line_nr &&
-                    (line_entry.GetColumn() == 0 || line_entry.GetColumn() == line_index)) {
-                    lldb::SBStream stream;
-                    thread_return_value.GetDescription(stream);
-                    return_value = stream.GetData();
-                }
-            }
+  std::string return_value;
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateStopped) {
+    auto thread = process->GetSelectedThread();
+    auto thread_return_value = thread.GetStopReturnValue();
+    if (thread_return_value.IsValid()) {
+      auto line_entry = thread.GetSelectedFrame().GetLineEntry();
+      if (line_entry.IsValid()) {
+        lldb::SBStream stream;
+        line_entry.GetFileSpec().GetDescription(stream);
+        if (filesystem::get_normal_path(stream.GetData()) == file_path && line_entry.GetLine() == line_nr &&
+            (line_entry.GetColumn() == 0 || line_entry.GetColumn() == line_index)) {
+          lldb::SBStream stream;
+          thread_return_value.GetDescription(stream);
+          return_value = stream.GetData();
         }
+      }
     }
-    return return_value;
+  }
+  return return_value;
 }
 
 bool Debug::LLDB::is_invalid() {
-    std::unique_lock<std::mutex> lock(mutex);
-    return state == lldb::StateType::eStateInvalid;
+  std::unique_lock<std::mutex> lock(mutex);
+  return state == lldb::StateType::eStateInvalid;
 }
 
 bool Debug::LLDB::is_stopped() {
-    std::unique_lock<std::mutex> lock(mutex);
-    return state == lldb::StateType::eStateStopped;
+  std::unique_lock<std::mutex> lock(mutex);
+  return state == lldb::StateType::eStateStopped;
 }
 
 bool Debug::LLDB::is_running() {
-    std::unique_lock<std::mutex> lock(mutex);
-    return state == lldb::StateType::eStateRunning;
+  std::unique_lock<std::mutex> lock(mutex);
+  return state == lldb::StateType::eStateRunning;
 }
 
 void Debug::LLDB::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::eStateStopped || state == lldb::eStateRunning) {
-        if (!(process->GetTarget().BreakpointCreateByLocation(file_path.string().c_str(), line_nr)).IsValid())
-            Terminal::get().async_print("Error (debug): Could not create breakpoint at: " + file_path.string() + ":" +
-                                        std::to_string(line_nr) + '\n', true);
-    }
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::eStateStopped || state == lldb::eStateRunning) {
+    if (!(process->GetTarget().BreakpointCreateByLocation(file_path.string().c_str(), line_nr)).IsValid())
+      Terminal::get().async_print("Error (debug): Could not create breakpoint at: " + file_path.string() + ":" +
+                                  std::to_string(line_nr) + '\n', true);
+  }
 }
 
 void Debug::LLDB::remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::eStateStopped || state == lldb::eStateRunning) {
-        auto target = process->GetTarget();
-        for (int line_nr_try = line_nr; line_nr_try < line_count; line_nr_try++) {
-            for (uint32_t b_index = 0; b_index < target.GetNumBreakpoints(); b_index++) {
-                auto breakpoint = target.GetBreakpointAtIndex(b_index);
-                for (uint32_t l_index = 0; l_index < breakpoint.GetNumLocations(); l_index++) {
-                    auto line_entry = breakpoint.GetLocationAtIndex(l_index).GetAddress().GetLineEntry();
-                    if (line_entry.GetLine() == static_cast<uint32_t>(line_nr_try)) {
-                        auto file_spec = line_entry.GetFileSpec();
-                        auto breakpoint_path = filesystem::get_normal_path(file_spec.GetDirectory());
-                        breakpoint_path /= file_spec.GetFilename();
-                        if (breakpoint_path == file_path) {
-                            if (!target.BreakpointDelete(breakpoint.GetID()))
-                                Terminal::get().async_print(
-                                        "Error (debug): Could not delete breakpoint at: " + file_path.string() + ":" +
-                                        std::to_string(line_nr) + '\n', true);
-                            return;
-                        }
-                    }
-                }
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::eStateStopped || state == lldb::eStateRunning) {
+    auto target = process->GetTarget();
+    for (int line_nr_try = line_nr; line_nr_try < line_count; line_nr_try++) {
+      for (uint32_t b_index = 0; b_index < target.GetNumBreakpoints(); b_index++) {
+        auto breakpoint = target.GetBreakpointAtIndex(b_index);
+        for (uint32_t l_index = 0; l_index < breakpoint.GetNumLocations(); l_index++) {
+          auto line_entry = breakpoint.GetLocationAtIndex(l_index).GetAddress().GetLineEntry();
+          if (line_entry.GetLine() == static_cast<uint32_t>(line_nr_try)) {
+            auto file_spec = line_entry.GetFileSpec();
+            auto breakpoint_path = filesystem::get_normal_path(file_spec.GetDirectory());
+            breakpoint_path /= file_spec.GetFilename();
+            if (breakpoint_path == file_path) {
+              if (!target.BreakpointDelete(breakpoint.GetID()))
+                Terminal::get().async_print(
+                    "Error (debug): Could not delete breakpoint at: " + file_path.string() + ":" +
+                    std::to_string(line_nr) + '\n', true);
+              return;
             }
+          }
         }
+      }
     }
+  }
 }
 
 void Debug::LLDB::write(const std::string &buffer) {
-    std::unique_lock<std::mutex> lock(mutex);
-    if (state == lldb::StateType::eStateRunning) {
-        process->PutSTDIN(buffer.c_str(), buffer.size());
-    }
+  std::unique_lock<std::mutex> lock(mutex);
+  if (state == lldb::StateType::eStateRunning) {
+    process->PutSTDIN(buffer.c_str(), buffer.size());
+  }
 }
diff --git a/src/debug_lldb.h b/src/debug_lldb.h
index 1b948a7b..b7215d1c 100644
--- a/src/debug_lldb.h
+++ b/src/debug_lldb.h
@@ -8,102 +8,102 @@
 #include <tuple>
 
 namespace Debug {
-    class LLDB {
+  class LLDB {
+  public:
+    class Frame {
     public:
-        class Frame {
-        public:
-            uint32_t index;
-            std::string module_filename;
-            boost::filesystem::path file_path;
-            std::string function_name;
-            int line_nr;
-            int line_index;
-        };
-
-        class Variable {
-        public:
-            uint32_t thread_index_id;
-            uint32_t frame_index;
-            std::string name;
-            std::string value;
-            bool declaration_found;
-            boost::filesystem::path file_path;
-            int line_nr;
-            int line_index;
-        };
-
-    private:
-        LLDB();
+      uint32_t index;
+      std::string module_filename;
+      boost::filesystem::path file_path;
+      std::string function_name;
+      int line_nr;
+      int line_index;
+    };
 
+    class Variable {
     public:
-        static LLDB &get() {
-            static LLDB singleton;
-            return singleton;
-        }
+      uint32_t thread_index_id;
+      uint32_t frame_index;
+      std::string name;
+      std::string value;
+      bool declaration_found;
+      boost::filesystem::path file_path;
+      int line_nr;
+      int line_index;
+    };
 
-        std::list<std::function<void(const lldb::SBProcess &)>> on_start;
-        /// The handlers are not run in the main loop.
-        std::list<std::function<void(int exit_status)>> on_exit;
-        /// The handlers are not run in the main loop.
-        std::list<std::function<void(const lldb::SBEvent &)>> on_event;
+  private:
+    LLDB();
 
-        std::mutex mutex;
+  public:
+    static LLDB &get() {
+      static LLDB singleton;
+      return singleton;
+    }
 
-        void start(const std::string &command, const boost::filesystem::path &path = "",
-                   const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints = {},
-                   const std::vector<std::string> &startup_commands = {}, const std::string &remote_host = "");
+    std::list<std::function<void(const lldb::SBProcess &)>> on_start;
+    /// The handlers are not run in the main loop.
+    std::list<std::function<void(int exit_status)>> on_exit;
+    /// The handlers are not run in the main loop.
+    std::list<std::function<void(const lldb::SBEvent &)>> on_event;
 
-        void continue_debug(); //can't use continue as function name
-        void stop();
+    std::mutex mutex;
 
-        void kill();
+    void start(const std::string &command, const boost::filesystem::path &path = "",
+               const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints = {},
+               const std::vector<std::string> &startup_commands = {}, const std::string &remote_host = "");
 
-        void step_over();
+    void continue_debug(); //can't use continue as function name
+    void stop();
 
-        void step_into();
+    void kill();
 
-        void step_out();
+    void step_over();
 
-        std::pair<std::string, std::string> run_command(const std::string &command);
+    void step_into();
 
-        std::vector<Frame> get_backtrace();
+    void step_out();
 
-        std::vector<Variable> get_variables();
+    std::pair<std::string, std::string> run_command(const std::string &command);
 
-        void select_frame(uint32_t frame_index, uint32_t thread_index_id = 0);
+    std::vector<Frame> get_backtrace();
 
-        void cancel();
+    std::vector<Variable> get_variables();
 
-        std::string
-        get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr,
-                  unsigned int line_index);
+    void select_frame(uint32_t frame_index, uint32_t thread_index_id = 0);
 
-        std::string
-        get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index);
+    void cancel();
 
-        bool is_invalid();
+    std::string
+    get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr,
+              unsigned int line_index);
 
-        bool is_stopped();
+    std::string
+    get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index);
 
-        bool is_running();
+    bool is_invalid();
 
-        void add_breakpoint(const boost::filesystem::path &file_path, int line_nr);
+    bool is_stopped();
 
-        void remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count);
+    bool is_running();
 
-        void write(const std::string &buffer);
+    void add_breakpoint(const boost::filesystem::path &file_path, int line_nr);
 
-    private:
-        std::tuple<std::vector<std::string>, std::string, std::vector<std::string>>
-        parse_run_arguments(const std::string &command);
+    void remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count);
 
-        std::unique_ptr<lldb::SBDebugger> debugger;
-        std::unique_ptr<lldb::SBListener> listener;
-        std::unique_ptr<lldb::SBProcess> process;
-        std::thread debug_thread;
+    void write(const std::string &buffer);
 
-        lldb::StateType state;
+  private:
+    std::tuple<std::vector<std::string>, std::string, std::vector<std::string>>
+    parse_run_arguments(const std::string &command);
 
-        size_t buffer_size;
-    };
+    std::unique_ptr<lldb::SBDebugger> debugger;
+    std::unique_ptr<lldb::SBListener> listener;
+    std::unique_ptr<lldb::SBProcess> process;
+    std::thread debug_thread;
+
+    lldb::StateType state;
+
+    size_t buffer_size;
+  };
 }
diff --git a/src/dialogs.cc b/src/dialogs.cc
index f4194848..efd95a9e 100644
--- a/src/dialogs.cc
+++ b/src/dialogs.cc
@@ -2,79 +2,79 @@
 #include <cmath>
 
 Dialog::Message::Message(const std::string &text) : Gtk::Window(Gtk::WindowType::WINDOW_POPUP) {
-    auto g_application = g_application_get_default();
-    auto gio_application = Glib::wrap(g_application, true);
-    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-    set_transient_for(*application->get_active_window());
+  auto g_application = g_application_get_default();
+  auto gio_application = Glib::wrap(g_application, true);
+  auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+  set_transient_for(*application->get_active_window());
 
-    set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);
-    set_modal(true);
-    set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_NOTIFICATION);
-    property_decorated() = false;
-    set_skip_taskbar_hint(true);
+  set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);
+  set_modal(true);
+  set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_NOTIFICATION);
+  property_decorated() = false;
+  set_skip_taskbar_hint(true);
 
-    auto box = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-    auto label = Gtk::manage(new Gtk::Label(text));
-    label->set_padding(10, 10);
-    box->pack_start(*label);
-    add(*box);
+  auto box = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+  auto label = Gtk::manage(new Gtk::Label(text));
+  label->set_padding(10, 10);
+  box->pack_start(*label);
+  add(*box);
 
-    show_all_children();
-    show_now();
+  show_all_children();
+  show_now();
 
-    while (Gtk::Main::events_pending())
-        Gtk::Main::iteration(false);
+  while (Gtk::Main::events_pending())
+    Gtk::Main::iteration(false);
 }
 
 bool Dialog::Message::on_delete_event(GdkEventAny *event) {
-    return true;
+  return true;
 }
 
 std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::string &title,
                                const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
                                Gtk::FileChooserAction action) {
-    // Workaround for crash on MacOS when filtering files in file/folder dialogs.
-    // See also https://github.com/cppit/jucipp/issues/259.
-    // TODO 2018: check if this bug has been fixed
+  // Workaround for crash on MacOS when filtering files in file/folder dialogs.
+  // See also https://github.com/cppit/jucipp/issues/259.
+  // TODO 2018: check if this bug has been fixed
 #ifdef __APPLE__
-    class FileChooserDialog : public Gtk::FileChooserDialog {
-      Gtk::FileChooserAction action;
-    public:
-      FileChooserDialog(const Glib::ustring& title, Gtk::FileChooserAction action) : Gtk::FileChooserDialog(title, action), action(action) {}
-    protected:
-      bool on_key_press_event(GdkEventKey *key_event) override {
-        if(action==Gtk::FileChooserAction::FILE_CHOOSER_ACTION_OPEN || action==Gtk::FileChooserAction::FILE_CHOOSER_ACTION_SELECT_FOLDER) {
-          auto unicode=gdk_keyval_to_unicode(key_event->keyval);
-          if(unicode>31 && unicode!=127)
-            return true;
-        }
-        return Gtk::FileChooserDialog::on_key_press_event(key_event);
+  class FileChooserDialog : public Gtk::FileChooserDialog {
+    Gtk::FileChooserAction action;
+  public:
+    FileChooserDialog(const Glib::ustring& title, Gtk::FileChooserAction action) : Gtk::FileChooserDialog(title, action), action(action) {}
+  protected:
+    bool on_key_press_event(GdkEventKey *key_event) override {
+      if(action==Gtk::FileChooserAction::FILE_CHOOSER_ACTION_OPEN || action==Gtk::FileChooserAction::FILE_CHOOSER_ACTION_SELECT_FOLDER) {
+        auto unicode=gdk_keyval_to_unicode(key_event->keyval);
+        if(unicode>31 && unicode!=127)
+          return true;
       }
-    };
-    FileChooserDialog dialog(title, action);
+      return Gtk::FileChooserDialog::on_key_press_event(key_event);
+    }
+  };
+  FileChooserDialog dialog(title, action);
 #else
-    Gtk::FileChooserDialog dialog(title, action);
+  Gtk::FileChooserDialog dialog(title, action);
 #endif
 
-    auto g_application = g_application_get_default();
-    auto gio_application = Glib::wrap(g_application, true);
-    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-    dialog.set_transient_for(*application->get_active_window());
-    dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);
+  auto g_application = g_application_get_default();
+  auto gio_application = Glib::wrap(g_application, true);
+  auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+  dialog.set_transient_for(*application->get_active_window());
+  dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);
 
-    if (title == "Save File As")
-        gtk_file_chooser_set_filename(reinterpret_cast<GtkFileChooser *>(dialog.gobj()), path.string().c_str());
-    else if (!path.empty())
-        gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser *>(dialog.gobj()), path.string().c_str());
-    else {
-        boost::system::error_code ec;
-        auto current_path = boost::filesystem::current_path(ec);
-        if (!ec)
-            gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser *>(dialog.gobj()),
-                                                current_path.string().c_str());
-    }
+  if (title == "Save File As")
+    gtk_file_chooser_set_filename(reinterpret_cast<GtkFileChooser *>(dialog.gobj()), path.string().c_str());
+  else if (!path.empty())
+    gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser *>(dialog.gobj()), path.string().c_str());
+  else {
+    boost::system::error_code ec;
+    auto current_path = boost::filesystem::current_path(ec);
+    if (!ec)
+      gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser *>(dialog.gobj()),
+                                          current_path.string().c_str());
+  }
 
-    for (auto &button : buttons)
-        dialog.add_button(button.first, button.second);
-    return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : "";
+  for (auto &button : buttons)
+    dialog.add_button(button.first, button.second);
+  return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : "";
 }
diff --git a/src/dialogs.h b/src/dialogs.h
index b3e57730..ad46d450 100644
--- a/src/dialogs.h
+++ b/src/dialogs.h
@@ -7,26 +7,26 @@
 
 class Dialog {
 public:
-    static std::string open_folder(const boost::filesystem::path &path);
+  static std::string open_folder(const boost::filesystem::path &path);
 
-    static std::string open_file(const boost::filesystem::path &path);
+  static std::string open_file(const boost::filesystem::path &path);
 
-    static std::string new_file(const boost::filesystem::path &path);
+  static std::string new_file(const boost::filesystem::path &path);
 
-    static std::string new_folder(const boost::filesystem::path &path);
+  static std::string new_folder(const boost::filesystem::path &path);
 
-    static std::string save_file_as(const boost::filesystem::path &path);
+  static std::string save_file_as(const boost::filesystem::path &path);
 
-    class Message : public Gtk::Window {
-    public:
-        Message(const std::string &text);
+  class Message : public Gtk::Window {
+  public:
+    Message(const std::string &text);
 
-    protected:
-        bool on_delete_event(GdkEventAny *event) override;
-    };
+  protected:
+    bool on_delete_event(GdkEventAny *event) override;
+  };
 
 private:
-    static std::string gtk_dialog(const boost::filesystem::path &path, const std::string &title,
-                                  const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
-                                  Gtk::FileChooserAction gtk_options);
+  static std::string gtk_dialog(const boost::filesystem::path &path, const std::string &title,
+                                const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
+                                Gtk::FileChooserAction gtk_options);
 };
diff --git a/src/dialogs_unix.cc b/src/dialogs_unix.cc
index 865bf3d9..cbd1f052 100644
--- a/src/dialogs_unix.cc
+++ b/src/dialogs_unix.cc
@@ -1,32 +1,32 @@
 #include "dialogs.h"
 
 std::string Dialog::open_folder(const boost::filesystem::path &path) {
-    return gtk_dialog(path, "Open Folder",
-                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Open", Gtk::RESPONSE_OK)},
-                      Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
+  return gtk_dialog(path, "Open Folder",
+                    {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Open", Gtk::RESPONSE_OK)},
+                    Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
 }
 
 std::string Dialog::new_file(const boost::filesystem::path &path) {
-    return gtk_dialog(path, "New File",
-                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
-                      Gtk::FILE_CHOOSER_ACTION_SAVE);
+  return gtk_dialog(path, "New File",
+                    {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
+                    Gtk::FILE_CHOOSER_ACTION_SAVE);
 }
 
 std::string Dialog::new_folder(const boost::filesystem::path &path) {
-    return gtk_dialog(path, "New Folder",
-                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Create", Gtk::RESPONSE_OK)},
-                      Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
+  return gtk_dialog(path, "New Folder",
+                    {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Create", Gtk::RESPONSE_OK)},
+                    Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
 }
 
 std::string Dialog::open_file(const boost::filesystem::path &path) {
-    return gtk_dialog(path, "Open File",
-                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Select", Gtk::RESPONSE_OK)},
-                      Gtk::FILE_CHOOSER_ACTION_OPEN);
+  return gtk_dialog(path, "Open File",
+                    {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Select", Gtk::RESPONSE_OK)},
+                    Gtk::FILE_CHOOSER_ACTION_OPEN);
 }
 
 std::string Dialog::save_file_as(const boost::filesystem::path &path) {
-    return gtk_dialog(path, "Save File As",
-                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
-                      Gtk::FILE_CHOOSER_ACTION_SAVE);
+  return gtk_dialog(path, "Save File As",
+                    {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
+                    Gtk::FILE_CHOOSER_ACTION_SAVE);
 }
 
diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc
index 6322a9ae..cb0f27f4 100644
--- a/src/dialogs_win.cc
+++ b/src/dialogs_win.cc
@@ -17,149 +17,149 @@ using namespace std; //TODO: remove
 
 class Win32Dialog {
 public:
-    Win32Dialog() {};
-
-    ~Win32Dialog() {
-        if (dialog != nullptr)
-            dialog->Release();
-    }
-
-    /** Returns the selected item's path as a string */
-    std::string open(const std::wstring &title, unsigned option = 0) {
-        if (!init(CLSID_FileOpenDialog))
-            return "";
-
-        if (!set_title(title) || !add_option(option))
-            return "";
-        if (!set_folder())
-            return "";
-
-        return show();
+  Win32Dialog() {};
+
+  ~Win32Dialog() {
+    if (dialog != nullptr)
+      dialog->Release();
+  }
+
+  /** Returns the selected item's path as a string */
+  std::string open(const std::wstring &title, unsigned option = 0) {
+    if (!init(CLSID_FileOpenDialog))
+      return "";
+
+    if (!set_title(title) || !add_option(option))
+      return "";
+    if (!set_folder())
+      return "";
+
+    return show();
+  }
+
+  std::string save(const std::wstring &title, const boost::filesystem::path &file_path = "", unsigned option = 0) {
+    if (!init(CLSID_FileSaveDialog))
+      return "";
+
+    if (!set_title(title) || !add_option(option))
+      return "";
+    if (!set_folder())
+      return "";
+    std::vector<COMDLG_FILTERSPEC> extensions;
+    if (!file_path.empty()) {
+      if (file_path.has_extension() && file_path.filename() != file_path.extension()) {
+        auto extension = (L"*" + file_path.extension().native()).c_str();
+        extensions.emplace_back(COMDLG_FILTERSPEC{extension, extension});
+        if (!set_default_file_extension(extension))
+          return "";
+      }
     }
+    extensions.emplace_back(COMDLG_FILTERSPEC{L"All files", L"*.*"});
+    if (dialog->SetFileTypes(extensions.size(), extensions.data()) != S_OK)
+      return "";
 
-    std::string save(const std::wstring &title, const boost::filesystem::path &file_path = "", unsigned option = 0) {
-        if (!init(CLSID_FileSaveDialog))
-            return "";
-
-        if (!set_title(title) || !add_option(option))
-            return "";
-        if (!set_folder())
-            return "";
-        std::vector<COMDLG_FILTERSPEC> extensions;
-        if (!file_path.empty()) {
-            if (file_path.has_extension() && file_path.filename() != file_path.extension()) {
-                auto extension = (L"*" + file_path.extension().native()).c_str();
-                extensions.emplace_back(COMDLG_FILTERSPEC{extension, extension});
-                if (!set_default_file_extension(extension))
-                    return "";
-            }
-        }
-        extensions.emplace_back(COMDLG_FILTERSPEC{L"All files", L"*.*"});
-        if (dialog->SetFileTypes(extensions.size(), extensions.data()) != S_OK)
-            return "";
-
-        return show();
-    }
+    return show();
+  }
 
 private:
-    IFileDialog *dialog = nullptr;
-    DWORD options;
-
-    bool init(CLSID type) {
-        if (CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog)) != S_OK)
-            return false;
-        if (dialog->GetOptions(&options) != S_OK)
-            return false;
-        return true;
-    }
-
-    /** available options are listed at https://msdn.microsoft.com/en-gb/library/windows/desktop/dn457282(v=vs.85).aspx */
-    bool add_option(unsigned option) {
-        if (dialog->SetOptions(options | option) != S_OK)
-            return false;
-        return true;
+  IFileDialog *dialog = nullptr;
+  DWORD options;
+
+  bool init(CLSID type) {
+    if (CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog)) != S_OK)
+      return false;
+    if (dialog->GetOptions(&options) != S_OK)
+      return false;
+    return true;
+  }
+
+  /** available options are listed at https://msdn.microsoft.com/en-gb/library/windows/desktop/dn457282(v=vs.85).aspx */
+  bool add_option(unsigned option) {
+    if (dialog->SetOptions(options | option) != S_OK)
+      return false;
+    return true;
+  }
+
+  bool set_title(const std::wstring &title) {
+    if (dialog->SetTitle(title.c_str()) != S_OK)
+      return false;
+    return true;
+  }
+
+  /** Sets the extensions the browser can find */
+  bool set_default_file_extension(const std::wstring &file_extension) {
+    if (dialog->SetDefaultExtension(file_extension.c_str()) != S_OK)
+      return false;
+    return true;
+  }
+
+  /** Sets the directory to start browsing */
+  bool set_folder() {
+    auto g_application = g_application_get_default(); //TODO: Post issue that Gio::Application::get_default should return pointer and not Glib::RefPtr
+    auto gio_application = Glib::wrap(g_application, true);
+    auto application = Glib::RefPtr<Application>::cast_static(gio_application);
+
+    auto current_path = application->window->notebook.get_current_folder();
+    boost::system::error_code ec;
+    if (current_path.empty())
+      current_path = boost::filesystem::current_path(ec);
+    if (ec)
+      return false;
+
+    std::wstring path = current_path.native();
+    size_t pos = 0;
+    while ((pos = path.find(L'/', pos)) !=
+           std::wstring::npos) {//TODO: issue bug report on boost::filesystem::path::native on MSYS2
+      path.replace(pos, 1, L"\\");
+      pos++;
     }
 
-    bool set_title(const std::wstring &title) {
-        if (dialog->SetTitle(title.c_str()) != S_OK)
-            return false;
-        return true;
-    }
-
-    /** Sets the extensions the browser can find */
-    bool set_default_file_extension(const std::wstring &file_extension) {
-        if (dialog->SetDefaultExtension(file_extension.c_str()) != S_OK)
-            return false;
-        return true;
-    }
-
-    /** Sets the directory to start browsing */
-    bool set_folder() {
-        auto g_application = g_application_get_default(); //TODO: Post issue that Gio::Application::get_default should return pointer and not Glib::RefPtr
-        auto gio_application = Glib::wrap(g_application, true);
-        auto application = Glib::RefPtr<Application>::cast_static(gio_application);
-
-        auto current_path = application->window->notebook.get_current_folder();
-        boost::system::error_code ec;
-        if (current_path.empty())
-            current_path = boost::filesystem::current_path(ec);
-        if (ec)
-            return false;
-
-        std::wstring path = current_path.native();
-        size_t pos = 0;
-        while ((pos = path.find(L'/', pos)) !=
-               std::wstring::npos) {//TODO: issue bug report on boost::filesystem::path::native on MSYS2
-            path.replace(pos, 1, L"\\");
-            pos++;
-        }
-
-        IShellItem *folder = nullptr;
-        if (SHCreateItemFromParsingName(path.c_str(), nullptr, IID_PPV_ARGS(&folder)) != S_OK)
-            return false;
-        if (dialog->SetFolder(folder) != S_OK)
-            return false;
-        folder->Release();
-        return true;
-    }
-
-    std::string show() {
-        if (dialog->Show(nullptr) != S_OK)
-            return "";
-        IShellItem *result = nullptr;
-        if (dialog->GetResult(&result) != S_OK)
-            return "";
-        LPWSTR file_path = nullptr;
-        auto hresult = result->GetDisplayName(SIGDN_FILESYSPATH, &file_path);
-        result->Release();
-        if (hresult != S_OK)
-            return "";
-        std::wstring file_path_wstring(file_path);
-        std::string file_path_string(file_path_wstring.begin(), file_path_wstring.end());
-        CoTaskMemFree(file_path);
-        return file_path_string;
-    }
+    IShellItem *folder = nullptr;
+    if (SHCreateItemFromParsingName(path.c_str(), nullptr, IID_PPV_ARGS(&folder)) != S_OK)
+      return false;
+    if (dialog->SetFolder(folder) != S_OK)
+      return false;
+    folder->Release();
+    return true;
+  }
+
+  std::string show() {
+    if (dialog->Show(nullptr) != S_OK)
+      return "";
+    IShellItem *result = nullptr;
+    if (dialog->GetResult(&result) != S_OK)
+      return "";
+    LPWSTR file_path = nullptr;
+    auto hresult = result->GetDisplayName(SIGDN_FILESYSPATH, &file_path);
+    result->Release();
+    if (hresult != S_OK)
+      return "";
+    std::wstring file_path_wstring(file_path);
+    std::string file_path_string(file_path_wstring.begin(), file_path_wstring.end());
+    CoTaskMemFree(file_path);
+    return file_path_string;
+  }
 };
 
 std::string Dialog::open_folder() {
-    return Win32Dialog().open(L"Open Folder", FOS_PICKFOLDERS);
+  return Win32Dialog().open(L"Open Folder", FOS_PICKFOLDERS);
 }
 
 std::string Dialog::new_file() {
-    return Win32Dialog().save(L"New File");
+  return Win32Dialog().save(L"New File");
 }
 
 std::string Dialog::new_folder() {
-    //Win32 (IFileDialog) does not support create folder...
-    return gtk_dialog("New Folder",
-                      {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Create", Gtk::RESPONSE_OK)},
-                      Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
+  //Win32 (IFileDialog) does not support create folder...
+  return gtk_dialog("New Folder",
+                    {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Create", Gtk::RESPONSE_OK)},
+                    Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
 }
 
 std::string Dialog::open_file() {
-    return Win32Dialog().open(L"Open File");
+  return Win32Dialog().open(L"Open File");
 }
 
 std::string Dialog::save_file_as(const boost::filesystem::path &file_path) {
-    return Win32Dialog().save(L"Save File As", file_path);
+  return Win32Dialog().save(L"Save File As", file_path);
 }
diff --git a/src/directories.cc b/src/directories.cc
index 299f379c..eff783e7 100644
--- a/src/directories.cc
+++ b/src/directories.cc
@@ -8,724 +8,724 @@
 
 bool Directories::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path &path,
                                                      const Gtk::SelectionData &selection_data) const {
-    return true;
+  return true;
 }
 
 bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &path,
                                                       const Gtk::SelectionData &selection_data) {
-    auto &directories = Directories::get();
-
-    auto get_target_folder = [this, &directories](const TreeModel::Path &path) {
-        if (path.size() == 1)
-            return directories.path;
+  auto &directories = Directories::get();
+
+  auto get_target_folder = [this, &directories](const TreeModel::Path &path) {
+    if (path.size() == 1)
+      return directories.path;
+    else {
+      auto it = get_iter(path);
+      if (it) {
+        auto prev_path = path;
+        prev_path.up();
+        it = get_iter(prev_path);
+        if (it)
+          return it->get_value(directories.column_record.path);
+      } else {
+        auto prev_path = path;
+        prev_path.up();
+        if (prev_path.size() == 1)
+          return directories.path;
         else {
-            auto it = get_iter(path);
-            if (it) {
-                auto prev_path = path;
-                prev_path.up();
-                it = get_iter(prev_path);
-                if (it)
-                    return it->get_value(directories.column_record.path);
-            } else {
-                auto prev_path = path;
-                prev_path.up();
-                if (prev_path.size() == 1)
-                    return directories.path;
-                else {
-                    prev_path.up();
-                    it = get_iter(prev_path);
-                    if (it)
-                        return it->get_value(directories.column_record.path);
-                }
-            }
+          prev_path.up();
+          it = get_iter(prev_path);
+          if (it)
+            return it->get_value(directories.column_record.path);
         }
-        return boost::filesystem::path();
-    };
+      }
+    }
+    return boost::filesystem::path();
+  };
 
-    auto it = directories.get_selection()->get_selected();
-    if (it) {
-        auto source_path = it->get_value(directories.column_record.path);
-        if (source_path.empty())
-            return false;
+  auto it = directories.get_selection()->get_selected();
+  if (it) {
+    auto source_path = it->get_value(directories.column_record.path);
+    if (source_path.empty())
+      return false;
 
-        auto target_path = get_target_folder(path);
-        target_path /= source_path.filename();
+    auto target_path = get_target_folder(path);
+    target_path /= source_path.filename();
 
-        if (source_path == target_path)
-            return false;
+    if (source_path == target_path)
+      return false;
 
-        if (boost::filesystem::exists(target_path)) {
-            Terminal::get().print("Error: could not move file: " + target_path.string() + " already exists\n", true);
-            return false;
-        }
+    if (boost::filesystem::exists(target_path)) {
+      Terminal::get().print("Error: could not move file: " + target_path.string() + " already exists\n", true);
+      return false;
+    }
 
-        bool is_directory = boost::filesystem::is_directory(source_path);
+    bool is_directory = boost::filesystem::is_directory(source_path);
 
-        if (is_directory)
-            Directories::get().remove_path(source_path);
+    if (is_directory)
+      Directories::get().remove_path(source_path);
 
-        boost::system::error_code ec;
-        boost::filesystem::rename(source_path, target_path, ec);
-        if (ec) {
-            Terminal::get().print("Error: could not move file: " + ec.message() + '\n', true);
-            return false;
-        }
+    boost::system::error_code ec;
+    boost::filesystem::rename(source_path, target_path, ec);
+    if (ec) {
+      Terminal::get().print("Error: could not move file: " + ec.message() + '\n', true);
+      return false;
+    }
 
-        for (size_t c = 0; c < Notebook::get().size(); c++) {
-            auto view = Notebook::get().get_view(c);
-            if (is_directory) {
-                if (filesystem::file_in_path(view->file_path, source_path)) {
-                    auto file_it = view->file_path.begin();
-                    for (auto source_it = source_path.begin(); source_it != source_path.end(); source_it++)
-                        file_it++;
-                    auto new_file_path = target_path;
-                    for (; file_it != view->file_path.end(); file_it++)
-                        new_file_path /= *file_it;
-                    view->rename(new_file_path);
-                }
-            } else if (view->file_path == source_path) {
-                view->rename(target_path);
-                break;
-            }
+    for (size_t c = 0; c < Notebook::get().size(); c++) {
+      auto view = Notebook::get().get_view(c);
+      if (is_directory) {
+        if (filesystem::file_in_path(view->file_path, source_path)) {
+          auto file_it = view->file_path.begin();
+          for (auto source_it = source_path.begin(); source_it != source_path.end(); source_it++)
+            file_it++;
+          auto new_file_path = target_path;
+          for (; file_it != view->file_path.end(); file_it++)
+            new_file_path /= *file_it;
+          view->rename(new_file_path);
         }
-
-        Directories::get().update();
-        Directories::get().on_save_file(target_path);
-        directories.select(target_path);
+      } else if (view->file_path == source_path) {
+        view->rename(target_path);
+        break;
+      }
     }
 
-    EntryBox::get().hide();
-    return false;
+    Directories::get().update();
+    Directories::get().on_save_file(target_path);
+    directories.select(target_path);
+  }
+
+  EntryBox::get().hide();
+  return false;
 }
 
 bool Directories::TreeStore::drag_data_delete_vfunc(const Gtk::TreeModel::Path &path) {
-    return false;
+  return false;
 }
 
 Directories::Directories() : Gtk::ListViewText(1) {
-    set_enable_tree_lines(true);
-
-    tree_store = TreeStore::create();
-    tree_store->set_column_types(column_record);
-    set_model(tree_store);
-
-    get_column(0)->set_title("");
-
-    auto renderer = dynamic_cast<Gtk::CellRendererText *>(get_column(0)->get_first_cell());
-    get_column(0)->set_cell_data_func(*renderer,
-                                      [this](Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &iter) {
-                                          if (auto renderer_text = dynamic_cast<Gtk::CellRendererText *>(renderer))
-                                              renderer_text->property_markup() = iter->get_value(column_record.markup);
-                                      });
-
-    get_style_context()->add_class("juci_directories");
-
-    tree_store->set_sort_column(column_record.id, Gtk::SortType::SORT_ASCENDING);
-    set_enable_search(true); //TODO: why does this not work in OS X?
-    set_search_column(column_record.name);
-
-    signal_row_activated().connect([this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column) {
-        auto iter = tree_store->get_iter(path);
-        if (iter) {
-            auto filesystem_path = iter->get_value(column_record.path);
-            if (filesystem_path != "") {
-                if (boost::filesystem::is_directory(boost::filesystem::path(filesystem_path)))
-                    row_expanded(path) ? collapse_row(path) : expand_row(path, false);
-                else
-                    Notebook::get().open(filesystem_path);
-            }
-        }
-    });
+  set_enable_tree_lines(true);
 
-    signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) {
-        if (iter->children().begin()->get_value(column_record.path) == "")
-            add_or_update_path(iter->get_value(column_record.path), *iter, true);
-        return false;
-    });
-    signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) {
-        this->remove_path(iter->get_value(column_record.path));
-    });
+  tree_store = TreeStore::create();
+  tree_store->set_column_types(column_record);
+  set_model(tree_store);
 
-    enable_model_drag_source();
-    enable_model_drag_dest();
+  get_column(0)->set_title("");
 
-    auto new_file_label = "New File";
-    auto new_file_function = [this] {
-        if (menu_popup_row_path.empty())
-            return;
-        EntryBox::get().clear();
-        EntryBox::get().entries.emplace_back("", [this, source_path = menu_popup_row_path](const std::string &content) {
-            bool is_directory = boost::filesystem::is_directory(source_path);
-            auto target_path = (is_directory ? source_path : source_path.parent_path()) / content;
-            if (!boost::filesystem::exists(target_path)) {
-                if (filesystem::write(target_path, "")) {
-                    update();
-                    Notebook::get().open(target_path);
-                    on_save_file(target_path);
-                } else {
-                    Terminal::get().print("Error: could not create " + target_path.string() + '\n', true);
-                    return;
-                }
-            } else {
-                Terminal::get().print("Error: could not create " + target_path.string() + ": already exists\n", true);
-                return;
-            }
+  auto renderer = dynamic_cast<Gtk::CellRendererText *>(get_column(0)->get_first_cell());
+  get_column(0)->set_cell_data_func(*renderer,
+                                    [this](Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &iter) {
+                                      if (auto renderer_text = dynamic_cast<Gtk::CellRendererText *>(renderer))
+                                        renderer_text->property_markup() = iter->get_value(column_record.markup);
+                                    });
 
-            EntryBox::get().hide();
-        });
-        auto entry_it = EntryBox::get().entries.begin();
-        entry_it->set_placeholder_text("Filename");
-        EntryBox::get().buttons.emplace_back("Create New File", [entry_it]() {
-            entry_it->activate();
-        });
-        EntryBox::get().show();
-    };
-
-    menu_item_new_file.set_label(new_file_label);
-    menu_item_new_file.signal_activate().connect(new_file_function);
-    menu.append(menu_item_new_file);
+  get_style_context()->add_class("juci_directories");
 
-    menu_root_item_new_file.set_label(new_file_label);
-    menu_root_item_new_file.signal_activate().connect(new_file_function);
-    menu_root.append(menu_root_item_new_file);
+  tree_store->set_sort_column(column_record.id, Gtk::SortType::SORT_ASCENDING);
+  set_enable_search(true); //TODO: why does this not work in OS X?
+  set_search_column(column_record.name);
 
-    auto new_folder_label = "New Folder";
-    auto new_folder_function = [this] {
-        if (menu_popup_row_path.empty())
-            return;
-        EntryBox::get().clear();
-        EntryBox::get().entries.emplace_back("", [this, source_path = menu_popup_row_path](const std::string &content) {
-            bool is_directory = boost::filesystem::is_directory(source_path);
-            auto target_path = (is_directory ? source_path : source_path.parent_path()) / content;
-            if (!boost::filesystem::exists(target_path)) {
-                boost::system::error_code ec;
-                boost::filesystem::create_directory(target_path, ec);
-                if (!ec) {
-                    update();
-                    select(target_path);
-                } else {
-                    Terminal::get().print("Error: could not create " + target_path.string() + ": " + ec.message(),
-                                          true);
-                    return;
-                }
-            } else {
-                Terminal::get().print("Error: could not create " + target_path.string() + ": already exists\n", true);
-                return;
-            }
-
-            EntryBox::get().hide();
-        });
-        auto entry_it = EntryBox::get().entries.begin();
-        entry_it->set_placeholder_text("Folder name");
-        EntryBox::get().buttons.emplace_back("Create New Folder", [entry_it]() {
-            entry_it->activate();
-        });
-        EntryBox::get().show();
-    };
-
-    menu_item_new_folder.set_label(new_folder_label);
-    menu_item_new_folder.signal_activate().connect(new_folder_function);
-    menu.append(menu_item_new_folder);
+  signal_row_activated().connect([this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column) {
+    auto iter = tree_store->get_iter(path);
+    if (iter) {
+      auto filesystem_path = iter->get_value(column_record.path);
+      if (filesystem_path != "") {
+        if (boost::filesystem::is_directory(boost::filesystem::path(filesystem_path)))
+          row_expanded(path) ? collapse_row(path) : expand_row(path, false);
+        else
+          Notebook::get().open(filesystem_path);
+      }
+    }
+  });
 
-    menu_root_item_new_folder.set_label(new_folder_label);
-    menu_root_item_new_folder.signal_activate().connect(new_folder_function);
-    menu_root.append(menu_root_item_new_folder);
+  signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) {
+    if (iter->children().begin()->get_value(column_record.path) == "")
+      add_or_update_path(iter->get_value(column_record.path), *iter, true);
+    return false;
+  });
+  signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) {
+    this->remove_path(iter->get_value(column_record.path));
+  });
+
+  enable_model_drag_source();
+  enable_model_drag_dest();
+
+  auto new_file_label = "New File";
+  auto new_file_function = [this] {
+    if (menu_popup_row_path.empty())
+      return;
+    EntryBox::get().clear();
+    EntryBox::get().entries.emplace_back("", [this, source_path = menu_popup_row_path](const std::string &content) {
+      bool is_directory = boost::filesystem::is_directory(source_path);
+      auto target_path = (is_directory ? source_path : source_path.parent_path()) / content;
+      if (!boost::filesystem::exists(target_path)) {
+        if (filesystem::write(target_path, "")) {
+          update();
+          Notebook::get().open(target_path);
+          on_save_file(target_path);
+        } else {
+          Terminal::get().print("Error: could not create " + target_path.string() + '\n', true);
+          return;
+        }
+      } else {
+        Terminal::get().print("Error: could not create " + target_path.string() + ": already exists\n", true);
+        return;
+      }
 
-    menu.append(menu_item_separator);
+      EntryBox::get().hide();
+    });
+    auto entry_it = EntryBox::get().entries.begin();
+    entry_it->set_placeholder_text("Filename");
+    EntryBox::get().buttons.emplace_back("Create New File", [entry_it]() {
+      entry_it->activate();
+    });
+    EntryBox::get().show();
+  };
+
+  menu_item_new_file.set_label(new_file_label);
+  menu_item_new_file.signal_activate().connect(new_file_function);
+  menu.append(menu_item_new_file);
+
+  menu_root_item_new_file.set_label(new_file_label);
+  menu_root_item_new_file.signal_activate().connect(new_file_function);
+  menu_root.append(menu_root_item_new_file);
+
+  auto new_folder_label = "New Folder";
+  auto new_folder_function = [this] {
+    if (menu_popup_row_path.empty())
+      return;
+    EntryBox::get().clear();
+    EntryBox::get().entries.emplace_back("", [this, source_path = menu_popup_row_path](const std::string &content) {
+      bool is_directory = boost::filesystem::is_directory(source_path);
+      auto target_path = (is_directory ? source_path : source_path.parent_path()) / content;
+      if (!boost::filesystem::exists(target_path)) {
+        boost::system::error_code ec;
+        boost::filesystem::create_directory(target_path, ec);
+        if (!ec) {
+          update();
+          select(target_path);
+        } else {
+          Terminal::get().print("Error: could not create " + target_path.string() + ": " + ec.message(),
+                                true);
+          return;
+        }
+      } else {
+        Terminal::get().print("Error: could not create " + target_path.string() + ": already exists\n", true);
+        return;
+      }
 
-    menu_item_rename.set_label("Rename");
-    menu_item_rename.signal_activate().connect([this] {
-        if (menu_popup_row_path.empty())
-            return;
-        EntryBox::get().clear();
-        EntryBox::get().entries.emplace_back(menu_popup_row_path.filename().string(),
-                                             [this, source_path = menu_popup_row_path](const std::string &content) {
-                                                 bool is_directory = boost::filesystem::is_directory(source_path);
-
-                                                 auto target_path = source_path.parent_path() / content;
-
-                                                 if (boost::filesystem::exists(target_path)) {
-                                                     Terminal::get().print(
-                                                             "Error: could not rename to " + target_path.string() +
-                                                             ": already exists\n", true);
-                                                     return;
-                                                 }
-
-                                                 if (is_directory)
-                                                     this->remove_path(source_path);
-
-                                                 boost::system::error_code ec;
-                                                 boost::filesystem::rename(source_path, target_path, ec);
-                                                 if (ec) {
-                                                     Terminal::get().print(
-                                                             "Error: could not rename " + source_path.string() + ": " +
-                                                             ec.message() + '\n', true);
-                                                     return;
-                                                 }
-                                                 update();
-                                                 on_save_file(target_path);
-                                                 select(target_path);
-
-                                                 for (size_t c = 0; c < Notebook::get().size(); c++) {
-                                                     auto view = Notebook::get().get_view(c);
-                                                     if (is_directory) {
-                                                         if (filesystem::file_in_path(view->file_path, source_path)) {
-                                                             auto file_it = view->file_path.begin();
-                                                             for (auto source_it = source_path.begin();
-                                                                  source_it != source_path.end(); source_it++)
-                                                                 file_it++;
-                                                             auto new_file_path = target_path;
-                                                             for (; file_it != view->file_path.end(); file_it++)
-                                                                 new_file_path /= *file_it;
-                                                             view->rename(new_file_path);
-                                                         }
-                                                     } else if (view->file_path == source_path) {
-                                                         view->rename(target_path);
-
-                                                         std::string old_language_id;
-                                                         if (view->language)
-                                                             old_language_id = view->language->get_id();
-                                                         view->language = Source::guess_language(target_path);
-                                                         std::string new_language_id;
-                                                         if (view->language)
-                                                             new_language_id = view->language->get_id();
-                                                         if (new_language_id != old_language_id)
-                                                             Terminal::get().print(
-                                                                     "Warning: language for " + target_path.string() +
-                                                                     " has changed. Please reopen the file\n");
-                                                     }
-                                                 }
-
-                                                 EntryBox::get().hide();
-                                             });
-        auto entry_it = EntryBox::get().entries.begin();
-        entry_it->set_placeholder_text("Filename");
-        EntryBox::get().buttons.emplace_back("Rename file", [entry_it]() {
-            entry_it->activate();
-        });
-        EntryBox::get().show();
+      EntryBox::get().hide();
+    });
+    auto entry_it = EntryBox::get().entries.begin();
+    entry_it->set_placeholder_text("Folder name");
+    EntryBox::get().buttons.emplace_back("Create New Folder", [entry_it]() {
+      entry_it->activate();
     });
-    menu.append(menu_item_rename);
+    EntryBox::get().show();
+  };
+
+  menu_item_new_folder.set_label(new_folder_label);
+  menu_item_new_folder.signal_activate().connect(new_folder_function);
+  menu.append(menu_item_new_folder);
+
+  menu_root_item_new_folder.set_label(new_folder_label);
+  menu_root_item_new_folder.signal_activate().connect(new_folder_function);
+  menu_root.append(menu_root_item_new_folder);
+
+  menu.append(menu_item_separator);
+
+  menu_item_rename.set_label("Rename");
+  menu_item_rename.signal_activate().connect([this] {
+    if (menu_popup_row_path.empty())
+      return;
+    EntryBox::get().clear();
+    EntryBox::get().entries.emplace_back(menu_popup_row_path.filename().string(),
+                                         [this, source_path = menu_popup_row_path](const std::string &content) {
+                                           bool is_directory = boost::filesystem::is_directory(source_path);
+
+                                           auto target_path = source_path.parent_path() / content;
+
+                                           if (boost::filesystem::exists(target_path)) {
+                                             Terminal::get().print(
+                                                 "Error: could not rename to " + target_path.string() +
+                                                 ": already exists\n", true);
+                                             return;
+                                           }
+
+                                           if (is_directory)
+                                             this->remove_path(source_path);
+
+                                           boost::system::error_code ec;
+                                           boost::filesystem::rename(source_path, target_path, ec);
+                                           if (ec) {
+                                             Terminal::get().print(
+                                                 "Error: could not rename " + source_path.string() + ": " +
+                                                 ec.message() + '\n', true);
+                                             return;
+                                           }
+                                           update();
+                                           on_save_file(target_path);
+                                           select(target_path);
+
+                                           for (size_t c = 0; c < Notebook::get().size(); c++) {
+                                             auto view = Notebook::get().get_view(c);
+                                             if (is_directory) {
+                                               if (filesystem::file_in_path(view->file_path, source_path)) {
+                                                 auto file_it = view->file_path.begin();
+                                                 for (auto source_it = source_path.begin();
+                                                      source_it != source_path.end(); source_it++)
+                                                   file_it++;
+                                                 auto new_file_path = target_path;
+                                                 for (; file_it != view->file_path.end(); file_it++)
+                                                   new_file_path /= *file_it;
+                                                 view->rename(new_file_path);
+                                               }
+                                             } else if (view->file_path == source_path) {
+                                               view->rename(target_path);
+
+                                               std::string old_language_id;
+                                               if (view->language)
+                                                 old_language_id = view->language->get_id();
+                                               view->language = Source::guess_language(target_path);
+                                               std::string new_language_id;
+                                               if (view->language)
+                                                 new_language_id = view->language->get_id();
+                                               if (new_language_id != old_language_id)
+                                                 Terminal::get().print(
+                                                     "Warning: language for " + target_path.string() +
+                                                     " has changed. Please reopen the file\n");
+                                             }
+                                           }
+
+                                           EntryBox::get().hide();
+                                         });
+    auto entry_it = EntryBox::get().entries.begin();
+    entry_it->set_placeholder_text("Filename");
+    EntryBox::get().buttons.emplace_back("Rename file", [entry_it]() {
+      entry_it->activate();
+    });
+    EntryBox::get().show();
+  });
+  menu.append(menu_item_rename);
+
+  menu_item_delete.set_label("Delete");
+  menu_item_delete.signal_activate().connect([this] {
+    if (menu_popup_row_path.empty())
+      return;
+    Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(get_toplevel()), "Delete!", false, Gtk::MESSAGE_QUESTION,
+                              Gtk::BUTTONS_YES_NO);
+    dialog.set_default_response(Gtk::RESPONSE_NO);
+    dialog.set_secondary_text("Are you sure you want to delete " + menu_popup_row_path.string() + "?");
+    int result = dialog.run();
+    if (result == Gtk::RESPONSE_YES) {
+      bool is_directory = boost::filesystem::is_directory(menu_popup_row_path);
+
+      boost::system::error_code ec;
+      boost::filesystem::remove_all(menu_popup_row_path, ec);
+      if (ec)
+        Terminal::get().print(
+            "Error: could not delete " + menu_popup_row_path.string() + ": " + ec.message() + "\n", true);
+      else {
+        update();
 
-    menu_item_delete.set_label("Delete");
-    menu_item_delete.signal_activate().connect([this] {
-        if (menu_popup_row_path.empty())
-            return;
-        Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(get_toplevel()), "Delete!", false, Gtk::MESSAGE_QUESTION,
-                                  Gtk::BUTTONS_YES_NO);
-        dialog.set_default_response(Gtk::RESPONSE_NO);
-        dialog.set_secondary_text("Are you sure you want to delete " + menu_popup_row_path.string() + "?");
-        int result = dialog.run();
-        if (result == Gtk::RESPONSE_YES) {
-            bool is_directory = boost::filesystem::is_directory(menu_popup_row_path);
-
-            boost::system::error_code ec;
-            boost::filesystem::remove_all(menu_popup_row_path, ec);
-            if (ec)
-                Terminal::get().print(
-                        "Error: could not delete " + menu_popup_row_path.string() + ": " + ec.message() + "\n", true);
-            else {
-                update();
-
-                for (size_t c = 0; c < Notebook::get().size(); c++) {
-                    auto view = Notebook::get().get_view(c);
-
-                    if (is_directory) {
-                        if (filesystem::file_in_path(view->file_path, menu_popup_row_path))
-                            view->get_buffer()->set_modified();
-                    } else if (view->file_path == menu_popup_row_path)
-                        view->get_buffer()->set_modified();
-                }
-            }
+        for (size_t c = 0; c < Notebook::get().size(); c++) {
+          auto view = Notebook::get().get_view(c);
+
+          if (is_directory) {
+            if (filesystem::file_in_path(view->file_path, menu_popup_row_path))
+              view->get_buffer()->set_modified();
+          } else if (view->file_path == menu_popup_row_path)
+            view->get_buffer()->set_modified();
         }
-    });
-    menu.append(menu_item_delete);
-
-    menu.show_all();
-    menu.accelerate(*this);
-
-    menu_root.show_all();
-    menu_root.accelerate(*this);
-
-    set_headers_clickable();
-    forall([this](Gtk::Widget &widget) {
-        if (widget.get_name() == "GtkButton") {
-            widget.signal_button_press_event().connect([this](GdkEventButton *event) {
-                if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY && !path.empty()) {
-                    menu_popup_row_path = this->path;
-                    menu_root.popup(event->button, event->time);
-                }
-                return true;
-            });
+      }
+    }
+  });
+  menu.append(menu_item_delete);
+
+  menu.show_all();
+  menu.accelerate(*this);
+
+  menu_root.show_all();
+  menu_root.accelerate(*this);
+
+  set_headers_clickable();
+  forall([this](Gtk::Widget &widget) {
+    if (widget.get_name() == "GtkButton") {
+      widget.signal_button_press_event().connect([this](GdkEventButton *event) {
+        if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY && !path.empty()) {
+          menu_popup_row_path = this->path;
+          menu_root.popup(event->button, event->time);
         }
-    });
+        return true;
+      });
+    }
+  });
 }
 
 Directories::~Directories() {
-    dispatcher.disconnect();
+  dispatcher.disconnect();
 }
 
 void Directories::open(const boost::filesystem::path &dir_path) {
-    boost::system::error_code ec;
-    if (dir_path.empty() || !boost::filesystem::exists(dir_path, ec) || ec)
-        return;
-
-    tree_store->clear();
-
-    path = filesystem::get_normal_path(dir_path);
-
-    //TODO: report that set_title does not handle '_' correctly?
-    auto title = path.filename().string();
-    size_t pos = 0;
-    while ((pos = title.find('_', pos)) != std::string::npos) {
-        title.replace(pos, 1, "__");
-        pos += 2;
-    }
-    get_column(0)->set_title(title);
-
-    for (auto &directory: directories) {
-        if (directory.second.repository)
-            directory.second.repository->clear_saved_status();
-    }
-    directories.clear();
-
-    add_or_update_path(path, Gtk::TreeModel::Row(), true);
+  boost::system::error_code ec;
+  if (dir_path.empty() || !boost::filesystem::exists(dir_path, ec) || ec)
+    return;
+
+  tree_store->clear();
+
+  path = filesystem::get_normal_path(dir_path);
+
+  //TODO: report that set_title does not handle '_' correctly?
+  auto title = path.filename().string();
+  size_t pos = 0;
+  while ((pos = title.find('_', pos)) != std::string::npos) {
+    title.replace(pos, 1, "__");
+    pos += 2;
+  }
+  get_column(0)->set_title(title);
+
+  for (auto &directory: directories) {
+    if (directory.second.repository)
+      directory.second.repository->clear_saved_status();
+  }
+  directories.clear();
+
+  add_or_update_path(path, Gtk::TreeModel::Row(), true);
 }
 
 void Directories::update() {
-    std::vector<std::pair<std::string, Gtk::TreeModel::Row> > saved_directories;
-    for (auto &directory: directories)
-        saved_directories.emplace_back(directory.first, directory.second.row);
-    for (auto &directory: saved_directories)
-        add_or_update_path(directory.first, directory.second, false);
+  std::vector<std::pair<std::string, Gtk::TreeModel::Row> > saved_directories;
+  for (auto &directory: directories)
+    saved_directories.emplace_back(directory.first, directory.second.row);
+  for (auto &directory: saved_directories)
+    add_or_update_path(directory.first, directory.second, false);
 }
 
 void Directories::on_save_file(boost::filesystem::path file_path) {
-    auto it = directories.find(file_path.parent_path().string());
-    if (it != directories.end()) {
-        if (it->second.repository)
-            it->second.repository->clear_saved_status();
-        colorize_path(it->first, true);
-    }
+  auto it = directories.find(file_path.parent_path().string());
+  if (it != directories.end()) {
+    if (it->second.repository)
+      it->second.repository->clear_saved_status();
+    colorize_path(it->first, true);
+  }
 }
 
 void Directories::select(const boost::filesystem::path &select_path) {
-    if (path == "")
-        return;
-
-    if (!filesystem::file_in_path(select_path, path))
-        return;
-
-    //return if the select_path is already selected
-    auto iter = get_selection()->get_selected();
-    if (iter) {
-        if (iter->get_value(column_record.path) == select_path)
-            return;
-    }
-
-    std::list<boost::filesystem::path> paths;
-    boost::filesystem::path parent_path;
-    if (boost::filesystem::is_directory(select_path))
-        parent_path = select_path;
-    else
-        parent_path = select_path.parent_path();
-
-    //check if select_path is already expanded
-    if (directories.find(parent_path.string()) != directories.end()) {
-        //set cursor at select_path and return
-        tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter) {
-            if (iter->get_value(column_record.path) == select_path) {
-                auto tree_path = Gtk::TreePath(iter);
-                expand_to_path(tree_path);
-                set_cursor(tree_path);
-                return true;
-            }
-            return false;
-        });
-        return;
-    }
+  if (path == "")
+    return;
+
+  if (!filesystem::file_in_path(select_path, path))
+    return;
+
+  //return if the select_path is already selected
+  auto iter = get_selection()->get_selected();
+  if (iter) {
+    if (iter->get_value(column_record.path) == select_path)
+      return;
+  }
+
+  std::list<boost::filesystem::path> paths;
+  boost::filesystem::path parent_path;
+  if (boost::filesystem::is_directory(select_path))
+    parent_path = select_path;
+  else
+    parent_path = select_path.parent_path();
+
+  //check if select_path is already expanded
+  if (directories.find(parent_path.string()) != directories.end()) {
+    //set cursor at select_path and return
+    tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter) {
+      if (iter->get_value(column_record.path) == select_path) {
+        auto tree_path = Gtk::TreePath(iter);
+        expand_to_path(tree_path);
+        set_cursor(tree_path);
+        return true;
+      }
+      return false;
+    });
+    return;
+  }
 
+  paths.emplace_front(parent_path);
+  while (parent_path != path) {
+    parent_path = parent_path.parent_path();
     paths.emplace_front(parent_path);
-    while (parent_path != path) {
-        parent_path = parent_path.parent_path();
-        paths.emplace_front(parent_path);
-    }
-
-    //expand to select_path
-    for (auto &a_path: paths) {
-        tree_store->foreach_iter([this, &a_path](const Gtk::TreeModel::iterator &iter) {
-            if (iter->get_value(column_record.path) == a_path) {
-                add_or_update_path(a_path, *iter, true);
-                return true;
-            }
-            return false;
-        });
-    }
-
-    //set cursor at select_path
-    tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter) {
-        if (iter->get_value(column_record.path) == select_path) {
-            auto tree_path = Gtk::TreePath(iter);
-            expand_to_path(tree_path);
-            set_cursor(tree_path);
-            return true;
-        }
-        return false;
+  }
+
+  //expand to select_path
+  for (auto &a_path: paths) {
+    tree_store->foreach_iter([this, &a_path](const Gtk::TreeModel::iterator &iter) {
+      if (iter->get_value(column_record.path) == a_path) {
+        add_or_update_path(a_path, *iter, true);
+        return true;
+      }
+      return false;
     });
+  }
+
+  //set cursor at select_path
+  tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter) {
+    if (iter->get_value(column_record.path) == select_path) {
+      auto tree_path = Gtk::TreePath(iter);
+      expand_to_path(tree_path);
+      set_cursor(tree_path);
+      return true;
+    }
+    return false;
+  });
 }
 
 bool Directories::on_button_press_event(GdkEventButton *event) {
-    if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY) {
-        EntryBox::get().hide();
-        Gtk::TreeModel::Path path;
-        if (get_path_at_pos(static_cast<int>(event->x), static_cast<int>(event->y), path)) {
-            menu_popup_row_path = get_model()->get_iter(path)->get_value(column_record.path);
-            if (menu_popup_row_path.empty()) {
-                auto parent = get_model()->get_iter(path)->parent();
-                if (parent)
-                    menu_popup_row_path = parent->get_value(column_record.path);
-                else {
-                    menu_popup_row_path = this->path;
-                    menu_root.popup(event->button, event->time);
-                    return true;
-                }
-            }
-            menu.popup(event->button, event->time);
-            return true;
-        } else if (!this->path.empty()) {
-            menu_popup_row_path = this->path;
-            menu_root.popup(event->button, event->time);
-            return true;
+  if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY) {
+    EntryBox::get().hide();
+    Gtk::TreeModel::Path path;
+    if (get_path_at_pos(static_cast<int>(event->x), static_cast<int>(event->y), path)) {
+      menu_popup_row_path = get_model()->get_iter(path)->get_value(column_record.path);
+      if (menu_popup_row_path.empty()) {
+        auto parent = get_model()->get_iter(path)->parent();
+        if (parent)
+          menu_popup_row_path = parent->get_value(column_record.path);
+        else {
+          menu_popup_row_path = this->path;
+          menu_root.popup(event->button, event->time);
+          return true;
         }
+      }
+      menu.popup(event->button, event->time);
+      return true;
+    } else if (!this->path.empty()) {
+      menu_popup_row_path = this->path;
+      menu_root.popup(event->button, event->time);
+      return true;
     }
+  }
 
-    return Gtk::TreeView::on_button_press_event(event);
+  return Gtk::TreeView::on_button_press_event(event);
 }
 
 void Directories::add_or_update_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row,
                                      bool include_parent_paths) {
-    auto path_it = directories.find(dir_path.string());
-    if (!boost::filesystem::exists(dir_path)) {
-        if (path_it != directories.end())
-            directories.erase(path_it);
-        return;
+  auto path_it = directories.find(dir_path.string());
+  if (!boost::filesystem::exists(dir_path)) {
+    if (path_it != directories.end())
+      directories.erase(path_it);
+    return;
+  }
+
+  if (path_it == directories.end()) {
+    auto g_file = Gio::File::create_for_path(dir_path.string());
+    auto monitor = g_file->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
+    auto path_and_row = std::make_shared<std::pair<boost::filesystem::path, Gtk::TreeModel::Row> >(dir_path, row);
+    auto connection = std::make_shared<sigc::connection>();
+
+    std::shared_ptr<Git::Repository> repository;
+    try {
+      repository = Git::get_repository(dir_path);
     }
+    catch (const std::exception &) {}
 
-    if (path_it == directories.end()) {
-        auto g_file = Gio::File::create_for_path(dir_path.string());
-        auto monitor = g_file->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
-        auto path_and_row = std::make_shared<std::pair<boost::filesystem::path, Gtk::TreeModel::Row> >(dir_path, row);
-        auto connection = std::make_shared<sigc::connection>();
-
-        std::shared_ptr<Git::Repository> repository;
-        try {
-            repository = Git::get_repository(dir_path);
-        }
-        catch (const std::exception &) {}
-
-        monitor->signal_changed().connect(
-                [this, connection, path_and_row, repository](const Glib::RefPtr<Gio::File> &file,
-                                                             const Glib::RefPtr<Gio::File> &,
-                                                             Gio::FileMonitorEvent monitor_event) {
-                    if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-                        if (repository)
-                            repository->clear_saved_status();
-                        connection->disconnect();
-                        *connection = Glib::signal_timeout().connect([path_and_row, this]() {
-                            if (directories.find(path_and_row->first.string()) != directories.end())
-                                add_or_update_path(path_and_row->first, path_and_row->second, true);
-                            return false;
-                        }, 500);
-                    }
-                });
-
-        std::shared_ptr<sigc::connection> repository_connection(new sigc::connection(),
-                                                                [](sigc::connection *connection) {
-                                                                    connection->disconnect();
-                                                                    delete connection;
-                                                                });
-
-        if (repository) {
-            auto connection = std::make_shared<sigc::connection>();
-            *repository_connection = repository->monitor->signal_changed().connect(
-                    [this, connection, path_and_row](const Glib::RefPtr<Gio::File> &file,
+    monitor->signal_changed().connect(
+        [this, connection, path_and_row, repository](const Glib::RefPtr<Gio::File> &file,
                                                      const Glib::RefPtr<Gio::File> &,
                                                      Gio::FileMonitorEvent monitor_event) {
-                        if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-                            connection->disconnect();
-                            *connection = Glib::signal_timeout().connect([this, path_and_row] {
-                                if (directories.find(path_and_row->first.string()) != directories.end())
-                                    colorize_path(path_and_row->first, false);
-                                return false;
-                            }, 500);
-                        }
-                    });
-        }
-        directories[dir_path.string()] = {row, monitor, repository, repository_connection};
-    }
+          if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+            if (repository)
+              repository->clear_saved_status();
+            connection->disconnect();
+            *connection = Glib::signal_timeout().connect([path_and_row, this]() {
+              if (directories.find(path_and_row->first.string()) != directories.end())
+                add_or_update_path(path_and_row->first, path_and_row->second, true);
+              return false;
+            }, 500);
+          }
+        });
 
-    Gtk::TreeNodeChildren children(row ? row.children() : tree_store->children());
-    if (children) {
-        if (children.begin()->get_value(column_record.path) == "")
-            tree_store->erase(children.begin());
-    }
-    std::unordered_set<std::string> not_deleted;
-    boost::filesystem::directory_iterator end_it;
-    for (boost::filesystem::directory_iterator it(dir_path); it != end_it; it++) {
-        auto filename = it->path().filename().string();
-        bool already_added = false;
-        if (children) {
-            for (auto &child: children) {
-                if (child->get_value(column_record.name) == filename) {
-                    not_deleted.emplace(filename);
-                    already_added = true;
-                    break;
-                }
-            }
-        }
-        if (!already_added) {
-            auto child = tree_store->append(children);
-            not_deleted.emplace(filename);
-            child->set_value(column_record.name, filename);
-            child->set_value(column_record.markup, Glib::Markup::escape_text(filename));
-            child->set_value(column_record.path, it->path());
-            if (boost::filesystem::is_directory(it->path())) {
-                child->set_value(column_record.id, '1' + filename);
-                auto grandchild = tree_store->append(child->children());
-                grandchild->set_value(column_record.name, std::string("(empty)"));
-                grandchild->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
-                grandchild->set_value(column_record.type, PathType::UNKNOWN);
-            } else {
-                child->set_value(column_record.id, '2' + filename);
-
-                auto language = Source::guess_language(it->path().filename());
-                if (!language)
-                    child->set_value(column_record.type, PathType::UNKNOWN);
+    std::shared_ptr<sigc::connection> repository_connection(new sigc::connection(),
+                                                            [](sigc::connection *connection) {
+                                                              connection->disconnect();
+                                                              delete connection;
+                                                            });
+
+    if (repository) {
+      auto connection = std::make_shared<sigc::connection>();
+      *repository_connection = repository->monitor->signal_changed().connect(
+          [this, connection, path_and_row](const Glib::RefPtr<Gio::File> &file,
+                                           const Glib::RefPtr<Gio::File> &,
+                                           Gio::FileMonitorEvent monitor_event) {
+            if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+              connection->disconnect();
+              *connection = Glib::signal_timeout().connect([this, path_and_row] {
+                if (directories.find(path_and_row->first.string()) != directories.end())
+                  colorize_path(path_and_row->first, false);
+                return false;
+              }, 500);
             }
-        }
+          });
     }
+    directories[dir_path.string()] = {row, monitor, repository, repository_connection};
+  }
+
+  Gtk::TreeNodeChildren children(row ? row.children() : tree_store->children());
+  if (children) {
+    if (children.begin()->get_value(column_record.path) == "")
+      tree_store->erase(children.begin());
+  }
+  std::unordered_set<std::string> not_deleted;
+  boost::filesystem::directory_iterator end_it;
+  for (boost::filesystem::directory_iterator it(dir_path); it != end_it; it++) {
+    auto filename = it->path().filename().string();
+    bool already_added = false;
     if (children) {
-        for (auto it = children.begin(); it != children.end();) {
-            if (not_deleted.count(it->get_value(column_record.name)) == 0) {
-                it = tree_store->erase(it);
-            } else
-                it++;
+      for (auto &child: children) {
+        if (child->get_value(column_record.name) == filename) {
+          not_deleted.emplace(filename);
+          already_added = true;
+          break;
         }
+      }
     }
-    if (!children) {
-        auto child = tree_store->append(children);
-        child->set_value(column_record.name, std::string("(empty)"));
-        child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
-        child->set_value(column_record.type, PathType::UNKNOWN);
+    if (!already_added) {
+      auto child = tree_store->append(children);
+      not_deleted.emplace(filename);
+      child->set_value(column_record.name, filename);
+      child->set_value(column_record.markup, Glib::Markup::escape_text(filename));
+      child->set_value(column_record.path, it->path());
+      if (boost::filesystem::is_directory(it->path())) {
+        child->set_value(column_record.id, '1' + filename);
+        auto grandchild = tree_store->append(child->children());
+        grandchild->set_value(column_record.name, std::string("(empty)"));
+        grandchild->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
+        grandchild->set_value(column_record.type, PathType::UNKNOWN);
+      } else {
+        child->set_value(column_record.id, '2' + filename);
+
+        auto language = Source::guess_language(it->path().filename());
+        if (!language)
+          child->set_value(column_record.type, PathType::UNKNOWN);
+      }
     }
-
-    colorize_path(dir_path, include_parent_paths);
+  }
+  if (children) {
+    for (auto it = children.begin(); it != children.end();) {
+      if (not_deleted.count(it->get_value(column_record.name)) == 0) {
+        it = tree_store->erase(it);
+      } else
+        it++;
+    }
+  }
+  if (!children) {
+    auto child = tree_store->append(children);
+    child->set_value(column_record.name, std::string("(empty)"));
+    child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
+    child->set_value(column_record.type, PathType::UNKNOWN);
+  }
+
+  colorize_path(dir_path, include_parent_paths);
 }
 
 void Directories::remove_path(const boost::filesystem::path &dir_path) {
-    auto it = directories.find(dir_path.string());
-    if (it == directories.end())
-        return;
-    auto children = it->second.row->children();
-
-    for (auto it = directories.begin(); it != directories.end();) {
-        if (filesystem::file_in_path(it->first, dir_path))
-            it = directories.erase(it);
-        else
-            it++;
-    }
+  auto it = directories.find(dir_path.string());
+  if (it == directories.end())
+    return;
+  auto children = it->second.row->children();
+
+  for (auto it = directories.begin(); it != directories.end();) {
+    if (filesystem::file_in_path(it->first, dir_path))
+      it = directories.erase(it);
+    else
+      it++;
+  }
 
-    if (children) {
-        while (children) {
-            tree_store->erase(children.begin());
-        }
-        auto child = tree_store->append(children);
-        child->set_value(column_record.name, std::string("(empty)"));
-        child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
-        child->set_value(column_record.type, PathType::UNKNOWN);
+  if (children) {
+    while (children) {
+      tree_store->erase(children.begin());
     }
+    auto child = tree_store->append(children);
+    child->set_value(column_record.name, std::string("(empty)"));
+    child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
+    child->set_value(column_record.type, PathType::UNKNOWN);
+  }
 }
 
 void Directories::colorize_path(const boost::filesystem::path &dir_path, bool include_parent_paths) {
-    auto it = directories.find(dir_path.string());
-    if (it == directories.end())
-        return;
-
-    if (it != directories.end() && it->second.repository) {
-        auto repository = it->second.repository;
-        std::thread git_status_thread([this, dir_path, repository, include_parent_paths] {
-            Git::Repository::Status status;
-            try {
-                status = repository->get_status();
-            }
-            catch (const std::exception &e) {
-                Terminal::get().async_print(std::string("Error (git): ") + e.what() + '\n', true);
-            }
+  auto it = directories.find(dir_path.string());
+  if (it == directories.end())
+    return;
+
+  if (it != directories.end() && it->second.repository) {
+    auto repository = it->second.repository;
+    std::thread git_status_thread([this, dir_path, repository, include_parent_paths] {
+      Git::Repository::Status status;
+      try {
+        status = repository->get_status();
+      }
+      catch (const std::exception &e) {
+        Terminal::get().async_print(std::string("Error (git): ") + e.what() + '\n', true);
+      }
+
+      dispatcher.post([this, dir_path = std::move(dir_path), include_parent_paths, status = std::move(status)] {
+        auto it = directories.find(dir_path.string());
+        if (it == directories.end())
+          return;
+
+        auto normal_color = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
+        Gdk::RGBA gray;
+        gray.set_rgba(0.5, 0.5, 0.5);
+        Gdk::RGBA yellow;
+        yellow.set_rgba(1.0, 1.0, 0.2);
+        double factor = 0.5;
+        yellow.set_red(normal_color.get_red() + factor * (yellow.get_red() - normal_color.get_red()));
+        yellow.set_green(normal_color.get_green() + factor * (yellow.get_green() - normal_color.get_green()));
+        yellow.set_blue(normal_color.get_blue() + factor * (yellow.get_blue() - normal_color.get_blue()));
+        Gdk::RGBA green;
+        green.set_rgba(0.0, 1.0, 0.0);
+        factor = 0.4;
+        green.set_red(normal_color.get_red() + factor * (green.get_red() - normal_color.get_red()));
+        green.set_green(normal_color.get_green() + factor * (green.get_green() - normal_color.get_green()));
+        green.set_blue(normal_color.get_blue() + factor * (green.get_blue() - normal_color.get_blue()));
+
+        do {
+          Gtk::TreeNodeChildren children(it->second.row ? it->second.row.children() : tree_store->children());
+          if (!children)
+            return;
 
-            dispatcher.post([this, dir_path = std::move(dir_path), include_parent_paths, status = std::move(status)] {
-                auto it = directories.find(dir_path.string());
-                if (it == directories.end())
-                    return;
-
-                auto normal_color = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
-                Gdk::RGBA gray;
-                gray.set_rgba(0.5, 0.5, 0.5);
-                Gdk::RGBA yellow;
-                yellow.set_rgba(1.0, 1.0, 0.2);
-                double factor = 0.5;
-                yellow.set_red(normal_color.get_red() + factor * (yellow.get_red() - normal_color.get_red()));
-                yellow.set_green(normal_color.get_green() + factor * (yellow.get_green() - normal_color.get_green()));
-                yellow.set_blue(normal_color.get_blue() + factor * (yellow.get_blue() - normal_color.get_blue()));
-                Gdk::RGBA green;
-                green.set_rgba(0.0, 1.0, 0.0);
-                factor = 0.4;
-                green.set_red(normal_color.get_red() + factor * (green.get_red() - normal_color.get_red()));
-                green.set_green(normal_color.get_green() + factor * (green.get_green() - normal_color.get_green()));
-                green.set_blue(normal_color.get_blue() + factor * (green.get_blue() - normal_color.get_blue()));
-
-                do {
-                    Gtk::TreeNodeChildren children(it->second.row ? it->second.row.children() : tree_store->children());
-                    if (!children)
-                        return;
-
-                    for (auto &child: children) {
-                        auto name = Glib::Markup::escape_text(child.get_value(column_record.name));
-                        auto path = child.get_value(column_record.path);
-                        Gdk::RGBA *color;
-                        if (status.modified.find(path.generic_string()) != status.modified.end())
-                            color = &yellow;
-                        else if (status.added.find(path.generic_string()) != status.added.end())
-                            color = &green;
-                        else
-                            color = &normal_color;
-
-                        std::stringstream ss;
-                        ss << '#' << std::setfill('0') << std::hex;
-                        ss << std::setw(2) << std::hex << (color->get_red_u() >> 8);
-                        ss << std::setw(2) << std::hex << (color->get_green_u() >> 8);
-                        ss << std::setw(2) << std::hex << (color->get_blue_u() >> 8);
-                        child.set_value(column_record.markup,
-                                        "<span foreground=\"" + ss.str() + "\">" + name + "</span>");
-
-                        auto type = child.get_value(column_record.type);
-                        if (type == PathType::UNKNOWN)
-                            child.set_value(column_record.markup,
-                                            "<i>" + child.get_value(column_record.markup) + "</i>");
-                    }
-
-                    if (!include_parent_paths)
-                        break;
-
-                    auto path = boost::filesystem::path(it->first);
-                    if (boost::filesystem::exists(path / ".git"))
-                        break;
-                    if (path == path.root_directory())
-                        break;
-                    auto parent_path = boost::filesystem::path(it->first).parent_path();
-                    it = directories.find(parent_path.string());
-                } while (it != directories.end());
-            });
-        });
-        git_status_thread.detach();
-    }
+          for (auto &child: children) {
+            auto name = Glib::Markup::escape_text(child.get_value(column_record.name));
+            auto path = child.get_value(column_record.path);
+            Gdk::RGBA *color;
+            if (status.modified.find(path.generic_string()) != status.modified.end())
+              color = &yellow;
+            else if (status.added.find(path.generic_string()) != status.added.end())
+              color = &green;
+            else
+              color = &normal_color;
+
+            std::stringstream ss;
+            ss << '#' << std::setfill('0') << std::hex;
+            ss << std::setw(2) << std::hex << (color->get_red_u() >> 8);
+            ss << std::setw(2) << std::hex << (color->get_green_u() >> 8);
+            ss << std::setw(2) << std::hex << (color->get_blue_u() >> 8);
+            child.set_value(column_record.markup,
+                            "<span foreground=\"" + ss.str() + "\">" + name + "</span>");
+
+            auto type = child.get_value(column_record.type);
+            if (type == PathType::UNKNOWN)
+              child.set_value(column_record.markup,
+                              "<i>" + child.get_value(column_record.markup) + "</i>");
+          }
+
+          if (!include_parent_paths)
+            break;
+
+          auto path = boost::filesystem::path(it->first);
+          if (boost::filesystem::exists(path / ".git"))
+            break;
+          if (path == path.root_directory())
+            break;
+          auto parent_path = boost::filesystem::path(it->first).parent_path();
+          it = directories.find(parent_path.string());
+        } while (it != directories.end());
+      });
+    });
+    git_status_thread.detach();
+  }
 }
diff --git a/src/directories.h b/src/directories.h
index 6caaea48..1d5fb428 100644
--- a/src/directories.h
+++ b/src/directories.h
@@ -13,96 +13,96 @@
 #include "dispatcher.h"
 
 class Directories : public Gtk::ListViewText {
-    class DirectoryData {
-    public:
-        Gtk::TreeModel::Row row;
-        Glib::RefPtr<Gio::FileMonitor> monitor;
-        std::shared_ptr<Git::Repository> repository;
-        std::shared_ptr<sigc::connection> connection;
-    };
+  class DirectoryData {
+  public:
+    Gtk::TreeModel::Row row;
+    Glib::RefPtr<Gio::FileMonitor> monitor;
+    std::shared_ptr<Git::Repository> repository;
+    std::shared_ptr<sigc::connection> connection;
+  };
 
-    enum class PathType {
-        KNOWN, UNKNOWN
-    };
+  enum class PathType {
+    KNOWN, UNKNOWN
+  };
 
-    class TreeStore : public Gtk::TreeStore {
-    protected:
-        TreeStore() {}
+  class TreeStore : public Gtk::TreeStore {
+  protected:
+    TreeStore() {}
 
-        bool row_drop_possible_vfunc(const Gtk::TreeModel::Path &path,
-                                     const Gtk::SelectionData &selection_data) const override;
+    bool row_drop_possible_vfunc(const Gtk::TreeModel::Path &path,
+                                 const Gtk::SelectionData &selection_data) const override;
 
-        bool drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) override;
+    bool drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) override;
 
-        bool drag_data_delete_vfunc(const Gtk::TreeModel::Path &path) override;
+    bool drag_data_delete_vfunc(const Gtk::TreeModel::Path &path) override;
 
+  public:
+    class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
     public:
-        class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
-        public:
-            ColumnRecord() {
-                add(id);
-                add(name);
-                add(markup);
-                add(path);
-                add(type);
-            }
-
-            Gtk::TreeModelColumn<std::string> id;
-            Gtk::TreeModelColumn<std::string> name;
-            Gtk::TreeModelColumn<Glib::ustring> markup;
-            Gtk::TreeModelColumn<boost::filesystem::path> path;
-            Gtk::TreeModelColumn<PathType> type;
-        };
-
-        static Glib::RefPtr<TreeStore> create() { return Glib::RefPtr<TreeStore>(new TreeStore()); }
+      ColumnRecord() {
+        add(id);
+        add(name);
+        add(markup);
+        add(path);
+        add(type);
+      }
+
+      Gtk::TreeModelColumn<std::string> id;
+      Gtk::TreeModelColumn<std::string> name;
+      Gtk::TreeModelColumn<Glib::ustring> markup;
+      Gtk::TreeModelColumn<boost::filesystem::path> path;
+      Gtk::TreeModelColumn<PathType> type;
     };
 
-    Directories();
+    static Glib::RefPtr<TreeStore> create() { return Glib::RefPtr<TreeStore>(new TreeStore()); }
+  };
+
+  Directories();
 
 public:
-    static Directories &get() {
-        static Directories singleton;
-        return singleton;
-    }
+  static Directories &get() {
+    static Directories singleton;
+    return singleton;
+  }
 
-    ~Directories();
+  ~Directories();
 
-    void open(const boost::filesystem::path &dir_path = "");
+  void open(const boost::filesystem::path &dir_path = "");
 
-    void update();
+  void update();
 
-    void on_save_file(boost::filesystem::path file_path);
+  void on_save_file(boost::filesystem::path file_path);
 
-    void select(const boost::filesystem::path &path);
+  void select(const boost::filesystem::path &path);
 
-    boost::filesystem::path path;
+  boost::filesystem::path path;
 
 protected:
-    bool on_button_press_event(GdkEventButton *event) override;
+  bool on_button_press_event(GdkEventButton *event) override;
 
 private:
-    void add_or_update_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row,
-                            bool include_parent_paths);
+  void add_or_update_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row,
+                          bool include_parent_paths);
 
-    void remove_path(const boost::filesystem::path &dir_path);
+  void remove_path(const boost::filesystem::path &dir_path);
 
-    void colorize_path(const boost::filesystem::path &dir_path, bool include_parent_paths);
+  void colorize_path(const boost::filesystem::path &dir_path, bool include_parent_paths);
 
-    Glib::RefPtr<Gtk::TreeStore> tree_store;
-    TreeStore::ColumnRecord column_record;
+  Glib::RefPtr<Gtk::TreeStore> tree_store;
+  TreeStore::ColumnRecord column_record;
 
-    std::unordered_map<std::string, DirectoryData> directories;
+  std::unordered_map<std::string, DirectoryData> directories;
 
-    Dispatcher dispatcher;
+  Dispatcher dispatcher;
 
-    Gtk::Menu menu;
-    Gtk::MenuItem menu_item_new_file;
-    Gtk::MenuItem menu_item_new_folder;
-    Gtk::SeparatorMenuItem menu_item_separator;
-    Gtk::MenuItem menu_item_rename;
-    Gtk::MenuItem menu_item_delete;
-    Gtk::Menu menu_root;
-    Gtk::MenuItem menu_root_item_new_file;
-    Gtk::MenuItem menu_root_item_new_folder;
-    boost::filesystem::path menu_popup_row_path;
+  Gtk::Menu menu;
+  Gtk::MenuItem menu_item_new_file;
+  Gtk::MenuItem menu_item_new_folder;
+  Gtk::SeparatorMenuItem menu_item_separator;
+  Gtk::MenuItem menu_item_rename;
+  Gtk::MenuItem menu_item_delete;
+  Gtk::Menu menu_root;
+  Gtk::MenuItem menu_root_item_new_file;
+  Gtk::MenuItem menu_root_item_new_folder;
+  boost::filesystem::path menu_popup_row_path;
 };
diff --git a/src/dispatcher.cc b/src/dispatcher.cc
index 1a0651de..e4e7f1f4 100644
--- a/src/dispatcher.cc
+++ b/src/dispatcher.cc
@@ -2,30 +2,30 @@
 #include <vector>
 
 Dispatcher::Dispatcher() {
-    connection = dispatcher.connect([this] {
-        std::vector<std::list<std::function<void()>>::iterator> its;
-        {
-            std::unique_lock<std::mutex> lock(functions_mutex);
-            if (functions.empty())
-                return;
-            its.reserve(functions.size());
-            for (auto it = functions.begin(); it != functions.end(); ++it)
-                its.emplace_back(it);
-        }
-        for (auto &it: its)
-            (*it)();
-        {
-            std::unique_lock<std::mutex> lock(functions_mutex);
-            for (auto &it: its)
-                functions.erase(it);
-        }
-    });
+  connection = dispatcher.connect([this] {
+    std::vector<std::list<std::function<void()>>::iterator> its;
+    {
+      std::unique_lock<std::mutex> lock(functions_mutex);
+      if (functions.empty())
+        return;
+      its.reserve(functions.size());
+      for (auto it = functions.begin(); it != functions.end(); ++it)
+        its.emplace_back(it);
+    }
+    for (auto &it: its)
+      (*it)();
+    {
+      std::unique_lock<std::mutex> lock(functions_mutex);
+      for (auto &it: its)
+        functions.erase(it);
+    }
+  });
 }
 
 Dispatcher::~Dispatcher() {
-    disconnect();
+  disconnect();
 }
 
 void Dispatcher::disconnect() {
-    connection.disconnect();
+  connection.disconnect();
 }
diff --git a/src/dispatcher.h b/src/dispatcher.h
index 6fbab177..99302cf4 100644
--- a/src/dispatcher.h
+++ b/src/dispatcher.h
@@ -7,23 +7,23 @@
 
 class Dispatcher {
 private:
-    std::list<std::function<void()>> functions;
-    std::mutex functions_mutex;
-    Glib::Dispatcher dispatcher;
-    sigc::connection connection;
+  std::list<std::function<void()>> functions;
+  std::mutex functions_mutex;
+  Glib::Dispatcher dispatcher;
+  sigc::connection connection;
 public:
-    Dispatcher();
+  Dispatcher();
 
-    ~Dispatcher();
+  ~Dispatcher();
 
-    template<typename T>
-    void post(T &&function) {
-        {
-            std::unique_lock<std::mutex> lock(functions_mutex);
-            functions.emplace_back(std::forward<T>(function));
-        }
-        dispatcher();
+  template<typename T>
+  void post(T &&function) {
+    {
+      std::unique_lock<std::mutex> lock(functions_mutex);
+      functions.emplace_back(std::forward<T>(function));
     }
+    dispatcher();
+  }
 
-    void disconnect();
+  void disconnect();
 };
diff --git a/src/documentation_cppreference.cc b/src/documentation_cppreference.cc
index 7dc5fbe0..74019264 100644
--- a/src/documentation_cppreference.cc
+++ b/src/documentation_cppreference.cc
@@ -4,7 +4,7 @@
 std::string Documentation::CppReference::get_url(const std::string symbol) noexcept {
 // Copied from http://upload.cppreference.com/mwiki/images/d/df/html_book_20170409.zip/reference/cppreference-export-ns0,4,8,10.xml
 // Using raw string instead of map to reduce compile time
-const static std::string symbol_urls = R"(size_t	c/types/size_t
+  const static std::string symbol_urls = R"(size_t	c/types/size_t
 ptrdiff_t	c/types/ptrdiff_t
 nullptr_t	c/types/nullptr_t
 NULL	c/types/NULL
@@ -12174,33 +12174,34 @@ std::experimental::filesystem::is_symlink	cpp/experimental/fs/is_symlink
 std::experimental::filesystem::status_known	cpp/experimental/fs/status_known"}
 )";
 
-class SymbolToUrl {
-public:
-SymbolToUrl(const std::string &symbol_urls) {
-size_t symbol_start=0;
-size_t symbol_end=std::string::npos;
-size_t url_start=std::string::npos;
-for (size_t c=0;c<symbol_urls.size();++c) {
-auto &chr=symbol_urls[c];
-if (chr=='\t') {
-symbol_end=c;
-url_start=c+1;
-}
-else if (chr=='\n') {
-if (symbol_end!=std::string::npos && url_start!=std::string::npos)
-map.emplace(symbol_urls.substr(symbol_start, symbol_end-symbol_start), symbol_urls.substr(url_start, c-url_start));
-symbol_start=c+1;
-symbol_end=std::string::npos;
-url_start=std::string::npos;
-}
-}
-}
-std::unordered_map<std::string, std::string> map;
-};
+  class SymbolToUrl {
+  public:
+    SymbolToUrl(const std::string &symbol_urls) {
+      size_t symbol_start = 0;
+      size_t symbol_end = std::string::npos;
+      size_t url_start = std::string::npos;
+      for (size_t c = 0; c < symbol_urls.size(); ++c) {
+        auto &chr = symbol_urls[c];
+        if (chr == '\t') {
+          symbol_end = c;
+          url_start = c + 1;
+        } else if (chr == '\n') {
+          if (symbol_end != std::string::npos && url_start != std::string::npos)
+            map.emplace(symbol_urls.substr(symbol_start, symbol_end - symbol_start),
+                        symbol_urls.substr(url_start, c - url_start));
+          symbol_start = c + 1;
+          symbol_end = std::string::npos;
+          url_start = std::string::npos;
+        }
+      }
+    }
+
+    std::unordered_map<std::string, std::string> map;
+  };
 
-static SymbolToUrl symbol_to_url(symbol_urls);
-auto it=symbol_to_url.map.find(symbol);
-if (it==symbol_to_url.map.end())
-return std::string();
-return "http://en.cppreference.com/w/"+it->second;
+  static SymbolToUrl symbol_to_url(symbol_urls);
+  auto it = symbol_to_url.map.find(symbol);
+  if (it == symbol_to_url.map.end())
+    return std::string();
+  return "http://en.cppreference.com/w/" + it->second;
 }
diff --git a/src/documentation_cppreference.h b/src/documentation_cppreference.h
index db9bf26e..b8bfad34 100644
--- a/src/documentation_cppreference.h
+++ b/src/documentation_cppreference.h
@@ -3,8 +3,8 @@
 #include <string>
 
 namespace Documentation {
-    class CppReference {
-    public:
-        static std::string get_url(const std::string symbol) noexcept;
-    };
+  class CppReference {
+  public:
+    static std::string get_url(const std::string symbol) noexcept;
+  };
 }
diff --git a/src/entrybox.cc b/src/entrybox.cc
index 5a81ef1e..635537a5 100644
--- a/src/entrybox.cc
+++ b/src/entrybox.cc
@@ -4,99 +4,99 @@ std::unordered_map<std::string, std::vector<std::string> > EntryBox::entry_histo
 
 EntryBox::Entry::Entry(const std::string &content, std::function<void(const std::string &content)> on_activate,
                        unsigned width_chars) : Gtk::Entry(), on_activate(on_activate) {
-    set_max_length(0);
-    set_width_chars(width_chars);
-    set_text(content);
-    selected_history = 0;
-    signal_activate().connect([this]() {
-        if (this->on_activate) {
-            auto &history = EntryBox::entry_histories[get_placeholder_text()];
-            auto text = get_text();
-            if (history.size() == 0 || (history.size() > 0 && *history.begin() != text))
-                history.emplace(history.begin(), text);
-            selected_history = 0;
-            this->on_activate(text);
-        }
-    });
-    signal_key_press_event().connect([this](GdkEventKey *key) {
-        if (key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) {
-            auto &history = entry_histories[get_placeholder_text()];
-            if (history.size() > 0) {
-                selected_history++;
-                if (selected_history >= history.size())
-                    selected_history = history.size() - 1;
-                set_text(history[selected_history]);
-                set_position(-1);
-            }
-        }
-        if (key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) {
-            auto &history = entry_histories[get_placeholder_text()];
-            if (history.size() > 0) {
-                if (selected_history != 0)
-                    selected_history--;
-                set_text(history[selected_history]);
-                set_position(-1);
-            }
-        }
-        return false;
-    });
+  set_max_length(0);
+  set_width_chars(width_chars);
+  set_text(content);
+  selected_history = 0;
+  signal_activate().connect([this]() {
+    if (this->on_activate) {
+      auto &history = EntryBox::entry_histories[get_placeholder_text()];
+      auto text = get_text();
+      if (history.size() == 0 || (history.size() > 0 && *history.begin() != text))
+        history.emplace(history.begin(), text);
+      selected_history = 0;
+      this->on_activate(text);
+    }
+  });
+  signal_key_press_event().connect([this](GdkEventKey *key) {
+    if (key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) {
+      auto &history = entry_histories[get_placeholder_text()];
+      if (history.size() > 0) {
+        selected_history++;
+        if (selected_history >= history.size())
+          selected_history = history.size() - 1;
+        set_text(history[selected_history]);
+        set_position(-1);
+      }
+    }
+    if (key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) {
+      auto &history = entry_histories[get_placeholder_text()];
+      if (history.size() > 0) {
+        if (selected_history != 0)
+          selected_history--;
+        set_text(history[selected_history]);
+        set_position(-1);
+      }
+    }
+    return false;
+  });
 }
 
 EntryBox::Button::Button(const std::string &label, std::function<void()> on_activate) : Gtk::Button(label),
                                                                                         on_activate(on_activate) {
-    set_focus_on_click(false);
-    signal_clicked().connect([this]() {
-        if (this->on_activate)
-            this->on_activate();
-    });
+  set_focus_on_click(false);
+  signal_clicked().connect([this]() {
+    if (this->on_activate)
+      this->on_activate();
+  });
 }
 
 EntryBox::ToggleButton::ToggleButton(const std::string &label, std::function<void()> on_activate) : Gtk::ToggleButton(
-        label), on_activate(on_activate) {
-    set_focus_on_click(false);
-    signal_clicked().connect([this]() {
-        if (this->on_activate)
-            this->on_activate();
-    });
+    label), on_activate(on_activate) {
+  set_focus_on_click(false);
+  signal_clicked().connect([this]() {
+    if (this->on_activate)
+      this->on_activate();
+  });
 }
 
 EntryBox::Label::Label(std::function<void(int state, const std::string &message)> update)
-        : Gtk::Label(), update(update) {
-    if (this->update)
-        this->update(-1, "");
+    : Gtk::Label(), update(update) {
+  if (this->update)
+    this->update(-1, "");
 }
 
 EntryBox::EntryBox() : Gtk::Box(Gtk::ORIENTATION_VERTICAL), upper_box(Gtk::ORIENTATION_HORIZONTAL),
                        lower_box(Gtk::ORIENTATION_HORIZONTAL) {
-    pack_start(upper_box, Gtk::PACK_SHRINK);
-    pack_start(lower_box, Gtk::PACK_SHRINK);
-    this->set_focus_chain({&lower_box});
+  pack_start(upper_box, Gtk::PACK_SHRINK);
+  pack_start(lower_box, Gtk::PACK_SHRINK);
+  this->set_focus_chain({&lower_box});
 }
 
 void EntryBox::clear() {
-    Gtk::Box::hide();
-    entries.clear();
-    buttons.clear();
-    toggle_buttons.clear();
-    labels.clear();
+  Gtk::Box::hide();
+  entries.clear();
+  buttons.clear();
+  toggle_buttons.clear();
+  labels.clear();
 }
 
 void EntryBox::show() {
-    std::vector<Gtk::Widget *> focus_chain;
-    for (auto &entry: entries) {
-        lower_box.pack_start(entry, Gtk::PACK_SHRINK);
-        focus_chain.emplace_back(&entry);
-    }
-    for (auto &button: buttons)
-        lower_box.pack_start(button, Gtk::PACK_SHRINK);
-    for (auto &toggle_button: toggle_buttons)
-        lower_box.pack_start(toggle_button, Gtk::PACK_SHRINK);
-    for (auto &label: labels)
-        upper_box.pack_start(label, Gtk::PACK_SHRINK);
-    lower_box.set_focus_chain(focus_chain);
-    show_all();
-    if (entries.size() > 0) {
-        entries.begin()->grab_focus();
-        entries.begin()->select_region(0, entries.begin()->get_text_length());
-    }
+  std::vector<Gtk::Widget *> focus_chain;
+  for (auto &entry: entries) {
+    lower_box.pack_start(entry, Gtk::PACK_SHRINK);
+    focus_chain.emplace_back(&entry);
+  }
+  for (auto &button: buttons)
+    lower_box.pack_start(button, Gtk::PACK_SHRINK);
+  for (auto &toggle_button: toggle_buttons)
+    lower_box.pack_start(toggle_button, Gtk::PACK_SHRINK);
+  for (auto &label: labels)
+    upper_box.pack_start(label, Gtk::PACK_SHRINK);
+  lower_box.set_focus_chain(focus_chain);
+  show_all();
+  if (entries.size() > 0) {
+    entries.begin()->grab_focus();
+    entries.begin()->select_region(0, entries.begin()->get_text_length());
+  }
 }
diff --git a/src/entrybox.h b/src/entrybox.h
index 107ba085..54d8e59f 100644
--- a/src/entrybox.h
+++ b/src/entrybox.h
@@ -9,60 +9,60 @@
 
 class EntryBox : public Gtk::Box {
 public:
-    class Entry : public Gtk::Entry {
-    public:
-        Entry(const std::string &content = "", std::function<void(const std::string &content)> on_activate = nullptr,
-              unsigned width_chars = -1);
+  class Entry : public Gtk::Entry {
+  public:
+    Entry(const std::string &content = "", std::function<void(const std::string &content)> on_activate = nullptr,
+          unsigned width_chars = -1);
 
-        std::function<void(const std::string &content)> on_activate;
-    private:
-        size_t selected_history;
-    };
+    std::function<void(const std::string &content)> on_activate;
+  private:
+    size_t selected_history;
+  };
 
-    class Button : public Gtk::Button {
-    public:
-        Button(const std::string &label, std::function<void()> on_activate = nullptr);
+  class Button : public Gtk::Button {
+  public:
+    Button(const std::string &label, std::function<void()> on_activate = nullptr);
 
-        std::function<void()> on_activate;
-    };
+    std::function<void()> on_activate;
+  };
 
-    class ToggleButton : public Gtk::ToggleButton {
-    public:
-        ToggleButton(const std::string &label, std::function<void()> on_activate = nullptr);
+  class ToggleButton : public Gtk::ToggleButton {
+  public:
+    ToggleButton(const std::string &label, std::function<void()> on_activate = nullptr);
 
-        std::function<void()> on_activate;
-    };
+    std::function<void()> on_activate;
+  };
 
-    class Label : public Gtk::Label {
-    public:
-        Label(std::function<void(int state, const std::string &message)> update = nullptr);
+  class Label : public Gtk::Label {
+  public:
+    Label(std::function<void(int state, const std::string &message)> update = nullptr);
 
-        std::function<void(int state, const std::string &message)> update;
-    };
+    std::function<void(int state, const std::string &message)> update;
+  };
 
 private:
-    EntryBox();
+  EntryBox();
 
 public:
-    static EntryBox &get() {
-        static EntryBox singleton;
-        return singleton;
-    }
+  static EntryBox &get() {
+    static EntryBox singleton;
+    return singleton;
+  }
 
-    Gtk::Box upper_box;
-    Gtk::Box lower_box;
+  Gtk::Box upper_box;
+  Gtk::Box lower_box;
 
-    void clear();
+  void clear();
 
-    void hide() { clear(); }
+  void hide() { clear(); }
 
-    void show();
+  void show();
 
-    std::list<Entry> entries;
-    std::list<Button> buttons;
-    std::list<ToggleButton> toggle_buttons;
-    std::list<Label> labels;
+  std::list<Entry> entries;
+  std::list<Button> buttons;
+  std::list<ToggleButton> toggle_buttons;
+  std::list<Label> labels;
 
 private:
-    static std::unordered_map<std::string, std::vector<std::string> > entry_histories;
+  static std::unordered_map<std::string, std::vector<std::string> > entry_histories;
 };
diff --git a/src/filesystem.cc b/src/filesystem.cc
index a7289137..475423c5 100644
--- a/src/filesystem.cc
+++ b/src/filesystem.cc
@@ -7,243 +7,243 @@
 
 //Only use on small files
 std::string filesystem::read(const std::string &path) {
-    std::stringstream ss;
-    std::ifstream input(path, std::ofstream::binary);
-    if (input) {
-        ss << input.rdbuf();
-        input.close();
-    }
-    return ss.str();
+  std::stringstream ss;
+  std::ifstream input(path, std::ofstream::binary);
+  if (input) {
+    ss << input.rdbuf();
+    input.close();
+  }
+  return ss.str();
 }
 
 //Only use on small files
 std::vector<std::string> filesystem::read_lines(const std::string &path) {
-    std::vector<std::string> res;
-    std::ifstream input(path, std::ofstream::binary);
-    if (input) {
-        do { res.emplace_back(); } while (getline(input, res.back()));
-    }
-    input.close();
-    return res;
+  std::vector<std::string> res;
+  std::ifstream input(path, std::ofstream::binary);
+  if (input) {
+    do { res.emplace_back(); } while (getline(input, res.back()));
+  }
+  input.close();
+  return res;
 }
 
 //Only use on small files
 bool filesystem::write(const std::string &path, const std::string &new_content) {
-    std::ofstream output(path, std::ofstream::binary);
-    if (output)
-        output << new_content;
-    else
-        return false;
-    output.close();
-    return true;
+  std::ofstream output(path, std::ofstream::binary);
+  if (output)
+    output << new_content;
+  else
+    return false;
+  output.close();
+  return true;
 }
 
 std::string filesystem::escape_argument(const std::string &argument) {
-    auto escaped = argument;
-    for (size_t pos = 0; pos < escaped.size(); ++pos) {
-        if (escaped[pos] == ' ' || escaped[pos] == '(' || escaped[pos] == ')' || escaped[pos] == '\'' ||
-            escaped[pos] == '"') {
-            escaped.insert(pos, "\\");
-            ++pos;
-        }
+  auto escaped = argument;
+  for (size_t pos = 0; pos < escaped.size(); ++pos) {
+    if (escaped[pos] == ' ' || escaped[pos] == '(' || escaped[pos] == ')' || escaped[pos] == '\'' ||
+        escaped[pos] == '"') {
+      escaped.insert(pos, "\\");
+      ++pos;
     }
-    return escaped;
+  }
+  return escaped;
 }
 
 std::string filesystem::unescape_argument(const std::string &argument) {
-    auto unescaped = argument;
-
-    if (unescaped.size() >= 2) {
-        if ((unescaped[0] == '\'' && unescaped[unescaped.size() - 1] == '\'') ||
-            (unescaped[0] == '"' && unescaped[unescaped.size() - 1] == '"')) {
-            char quotation_mark = unescaped[0];
-            unescaped = unescaped.substr(1, unescaped.size() - 2);
-            size_t backslash_count = 0;
-            for (size_t pos = 0; pos < unescaped.size(); ++pos) {
-                if (backslash_count % 2 == 1 && (unescaped[pos] == '\\' || unescaped[pos] == quotation_mark)) {
-                    unescaped.erase(pos - 1, 1);
-                    --pos;
-                    backslash_count = 0;
-                } else if (unescaped[pos] == '\\')
-                    ++backslash_count;
-                else
-                    backslash_count = 0;
-            }
-            return unescaped;
-        }
-    }
-
-    size_t backslash_count = 0;
-    for (size_t pos = 0; pos < unescaped.size(); ++pos) {
-        if (backslash_count % 2 == 1 &&
-            (unescaped[pos] == '\\' || unescaped[pos] == ' ' || unescaped[pos] == '(' || unescaped[pos] == ')' ||
-             unescaped[pos] == '\'' || unescaped[pos] == '"')) {
-            unescaped.erase(pos - 1, 1);
-            --pos;
-            backslash_count = 0;
+  auto unescaped = argument;
+
+  if (unescaped.size() >= 2) {
+    if ((unescaped[0] == '\'' && unescaped[unescaped.size() - 1] == '\'') ||
+        (unescaped[0] == '"' && unescaped[unescaped.size() - 1] == '"')) {
+      char quotation_mark = unescaped[0];
+      unescaped = unescaped.substr(1, unescaped.size() - 2);
+      size_t backslash_count = 0;
+      for (size_t pos = 0; pos < unescaped.size(); ++pos) {
+        if (backslash_count % 2 == 1 && (unescaped[pos] == '\\' || unescaped[pos] == quotation_mark)) {
+          unescaped.erase(pos - 1, 1);
+          --pos;
+          backslash_count = 0;
         } else if (unescaped[pos] == '\\')
-            ++backslash_count;
+          ++backslash_count;
         else
-            backslash_count = 0;
+          backslash_count = 0;
+      }
+      return unescaped;
     }
-    return unescaped;
+  }
+
+  size_t backslash_count = 0;
+  for (size_t pos = 0; pos < unescaped.size(); ++pos) {
+    if (backslash_count % 2 == 1 &&
+        (unescaped[pos] == '\\' || unescaped[pos] == ' ' || unescaped[pos] == '(' || unescaped[pos] == ')' ||
+         unescaped[pos] == '\'' || unescaped[pos] == '"')) {
+      unescaped.erase(pos - 1, 1);
+      --pos;
+      backslash_count = 0;
+    } else if (unescaped[pos] == '\\')
+      ++backslash_count;
+    else
+      backslash_count = 0;
+  }
+  return unescaped;
 }
 
 boost::filesystem::path filesystem::get_home_path() noexcept {
-    std::vector<std::string> environment_variables = {"HOME", "AppData"};
-    char *ptr = nullptr;
-    for (auto &variable : environment_variables) {
-        ptr = std::getenv(variable.c_str());
-        boost::system::error_code ec;
-        if (ptr != nullptr && boost::filesystem::exists(ptr, ec))
-            return ptr;
-    }
-    return boost::filesystem::path();
+  std::vector<std::string> environment_variables = {"HOME", "AppData"};
+  char *ptr = nullptr;
+  for (auto &variable : environment_variables) {
+    ptr = std::getenv(variable.c_str());
+    boost::system::error_code ec;
+    if (ptr != nullptr && boost::filesystem::exists(ptr, ec))
+      return ptr;
+  }
+  return boost::filesystem::path();
 }
 
 boost::filesystem::path filesystem::get_short_path(const boost::filesystem::path &path) noexcept {
 #ifdef _WIN32
-    return path;
+  return path;
 #else
-    static auto home_path=get_home_path();
-    if(!home_path.empty()) {
-      auto relative_path=filesystem::get_relative_path(path, home_path);
-      if(!relative_path.empty())
-        return "~"/relative_path;
-    }
-    return path;
+  static auto home_path=get_home_path();
+  if(!home_path.empty()) {
+    auto relative_path=filesystem::get_relative_path(path, home_path);
+    if(!relative_path.empty())
+      return "~"/relative_path;
+  }
+  return path;
 #endif
 }
 
 bool filesystem::file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path) {
-    if (std::distance(file_path.begin(), file_path.end()) < std::distance(path.begin(), path.end()))
-        return false;
-    return std::equal(path.begin(), path.end(), file_path.begin());
+  if (std::distance(file_path.begin(), file_path.end()) < std::distance(path.begin(), path.end()))
+    return false;
+  return std::equal(path.begin(), path.end(), file_path.begin());
 }
 
 boost::filesystem::path
 filesystem::find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path) {
-    auto current_path = path;
-    while (true) {
-        auto test_path = current_path / file_name;
-        if (boost::filesystem::exists(test_path))
-            return test_path;
-        if (current_path == current_path.root_directory())
-            return boost::filesystem::path();
-        current_path = current_path.parent_path();
-    }
+  auto current_path = path;
+  while (true) {
+    auto test_path = current_path / file_name;
+    if (boost::filesystem::exists(test_path))
+      return test_path;
+    if (current_path == current_path.root_directory())
+      return boost::filesystem::path();
+    current_path = current_path.parent_path();
+  }
 }
 
 boost::filesystem::path filesystem::get_normal_path(const boost::filesystem::path &path) noexcept {
-    boost::filesystem::path normal_path;
-
-    for (auto &e: path) {
-        if (e == ".")
-            continue;
-        else if (e == "..") {
-            auto parent_path = normal_path.parent_path();
-            if (!parent_path.empty())
-                normal_path = parent_path;
-            else
-                normal_path /= e;
-        } else if (e.empty())
-            continue;
-        else
-            normal_path /= e;
-    }
+  boost::filesystem::path normal_path;
+
+  for (auto &e: path) {
+    if (e == ".")
+      continue;
+    else if (e == "..") {
+      auto parent_path = normal_path.parent_path();
+      if (!parent_path.empty())
+        normal_path = parent_path;
+      else
+        normal_path /= e;
+    } else if (e.empty())
+      continue;
+    else
+      normal_path /= e;
+  }
 
-    return normal_path;
+  return normal_path;
 }
 
 boost::filesystem::path
 filesystem::get_relative_path(const boost::filesystem::path &path, const boost::filesystem::path &base) noexcept {
-    boost::filesystem::path relative_path;
-
-    if (std::distance(path.begin(), path.end()) < std::distance(base.begin(), base.end()))
-        return boost::filesystem::path();
-
-    auto base_it = base.begin();
-    auto path_it = path.begin();
-    while (path_it != path.end() && base_it != base.end()) {
-        if (*path_it != *base_it)
-            return boost::filesystem::path();
-        ++path_it;
-        ++base_it;
-    }
-    for (; path_it != path.end(); ++path_it)
-        relative_path /= *path_it;
+  boost::filesystem::path relative_path;
 
-    return relative_path;
+  if (std::distance(path.begin(), path.end()) < std::distance(base.begin(), base.end()))
+    return boost::filesystem::path();
+
+  auto base_it = base.begin();
+  auto path_it = path.begin();
+  while (path_it != path.end() && base_it != base.end()) {
+    if (*path_it != *base_it)
+      return boost::filesystem::path();
+    ++path_it;
+    ++base_it;
+  }
+  for (; path_it != path.end(); ++path_it)
+    relative_path /= *path_it;
+
+  return relative_path;
 }
 
 boost::filesystem::path filesystem::get_executable(const boost::filesystem::path &executable_name) noexcept {
 #if defined(__APPLE__) || defined(_WIN32)
-    return executable_name;
+  return executable_name;
 #endif
 
-    static std::vector<boost::filesystem::path> bin_paths = {"/usr/bin", "/usr/local/bin"};
+  static std::vector<boost::filesystem::path> bin_paths = {"/usr/bin", "/usr/local/bin"};
 
-    try {
-        for (auto &path: bin_paths) {
-            if (boost::filesystem::exists(path / executable_name))
-                return executable_name;
-        }
+  try {
+    for (auto &path: bin_paths) {
+      if (boost::filesystem::exists(path / executable_name))
+        return executable_name;
+    }
 
-        auto executable_name_str = executable_name.string();
-        for (auto &path: bin_paths) {
-            boost::filesystem::path executable;
-            for (boost::filesystem::directory_iterator it(path), end; it != end; ++it) {
-                auto it_path = it->path();
-                auto it_path_filename_str = it_path.filename().string();
-                if (!it_path_filename_str.empty() &&
-                    it_path_filename_str.compare(0, executable_name_str.size(), executable_name_str) == 0) {
-                    if (it_path > executable &&
-                        ((it_path_filename_str.size() > executable_name_str.size() &&
-                          it_path_filename_str[executable_name_str.size()] >= '0' &&
-                          it_path_filename_str[executable_name_str.size()] <= '9') ||
-                         (it_path_filename_str.size() > executable_name_str.size() + 1 &&
-                          it_path_filename_str[executable_name_str.size()] == '-' &&
-                          it_path_filename_str[executable_name_str.size() + 1] >= '0' &&
-                          it_path_filename_str[executable_name_str.size() + 1] <= '9')) &&
-                        !boost::filesystem::is_directory(it_path))
-                        executable = it_path;
-                }
-            }
-            if (!executable.empty())
-                return executable;
+    auto executable_name_str = executable_name.string();
+    for (auto &path: bin_paths) {
+      boost::filesystem::path executable;
+      for (boost::filesystem::directory_iterator it(path), end; it != end; ++it) {
+        auto it_path = it->path();
+        auto it_path_filename_str = it_path.filename().string();
+        if (!it_path_filename_str.empty() &&
+            it_path_filename_str.compare(0, executable_name_str.size(), executable_name_str) == 0) {
+          if (it_path > executable &&
+              ((it_path_filename_str.size() > executable_name_str.size() &&
+                it_path_filename_str[executable_name_str.size()] >= '0' &&
+                it_path_filename_str[executable_name_str.size()] <= '9') ||
+               (it_path_filename_str.size() > executable_name_str.size() + 1 &&
+                it_path_filename_str[executable_name_str.size()] == '-' &&
+                it_path_filename_str[executable_name_str.size() + 1] >= '0' &&
+                it_path_filename_str[executable_name_str.size() + 1] <= '9')) &&
+              !boost::filesystem::is_directory(it_path))
+            executable = it_path;
         }
+      }
+      if (!executable.empty())
+        return executable;
     }
-    catch (...) {}
+  }
+  catch (...) {}
 
-    return executable_name;
+  return executable_name;
 }
 
 // Based on https://stackoverflow.com/a/11295568
 const std::vector<boost::filesystem::path> &filesystem::get_executable_search_paths() {
-    static std::vector<boost::filesystem::path> result;
-    if (!result.empty())
-        return result;
-
-    const std::string env = getenv("PATH");
-    const char delimiter = ':';
-
-    size_t previous = 0;
-    size_t pos;
-    while ((pos = env.find(delimiter, previous)) != std::string::npos) {
-        result.emplace_back(env.substr(previous, pos - previous));
-        previous = pos + 1;
-    }
-    result.emplace_back(env.substr(previous));
-
+  static std::vector<boost::filesystem::path> result;
+  if (!result.empty())
     return result;
+
+  const std::string env = getenv("PATH");
+  const char delimiter = ':';
+
+  size_t previous = 0;
+  size_t pos;
+  while ((pos = env.find(delimiter, previous)) != std::string::npos) {
+    result.emplace_back(env.substr(previous, pos - previous));
+    previous = pos + 1;
+  }
+  result.emplace_back(env.substr(previous));
+
+  return result;
 }
 
 boost::filesystem::path filesystem::find_executable(const std::string &executable_name) {
-    for (auto &path: get_executable_search_paths()) {
-        boost::system::error_code ec;
-        auto executable_path = path / executable_name;
-        if (boost::filesystem::exists(executable_path, ec))
-            return executable_path;
-    }
-    return boost::filesystem::path();
+  for (auto &path: get_executable_search_paths()) {
+    boost::system::error_code ec;
+    auto executable_path = path / executable_name;
+    if (boost::filesystem::exists(executable_path, ec))
+      return executable_path;
+  }
+  return boost::filesystem::path();
 }
diff --git a/src/filesystem.h b/src/filesystem.h
index e32a18a0..14cec226 100644
--- a/src/filesystem.h
+++ b/src/filesystem.h
@@ -6,50 +6,50 @@
 
 class filesystem {
 public:
-    static std::string read(const std::string &path);
+  static std::string read(const std::string &path);
 
-    static std::string read(const boost::filesystem::path &path) { return read(path.string()); }
+  static std::string read(const boost::filesystem::path &path) { return read(path.string()); }
 
-    static std::vector<std::string> read_lines(const std::string &path);
+  static std::vector<std::string> read_lines(const std::string &path);
 
-    static std::vector<std::string> read_lines(const boost::filesystem::path &path) {
-        return read_lines(path.string());
-    };
+  static std::vector<std::string> read_lines(const boost::filesystem::path &path) {
+    return read_lines(path.string());
+  };
 
-    static bool write(const std::string &path, const std::string &new_content);
+  static bool write(const std::string &path, const std::string &new_content);
 
-    static bool write(const boost::filesystem::path &path, const std::string &new_content) {
-        return write(path.string(), new_content);
-    }
+  static bool write(const boost::filesystem::path &path, const std::string &new_content) {
+    return write(path.string(), new_content);
+  }
 
-    static bool write(const std::string &path) { return write(path, ""); };
+  static bool write(const std::string &path) { return write(path, ""); };
 
-    static bool write(const boost::filesystem::path &path) { return write(path, ""); };
+  static bool write(const boost::filesystem::path &path) { return write(path, ""); };
 
-    static std::string escape_argument(const std::string &argument);
+  static std::string escape_argument(const std::string &argument);
 
-    static std::string unescape_argument(const std::string &argument);
+  static std::string unescape_argument(const std::string &argument);
 
-    static boost::filesystem::path get_home_path() noexcept;
+  static boost::filesystem::path get_home_path() noexcept;
 
-    static boost::filesystem::path get_short_path(const boost::filesystem::path &path) noexcept;
+  static boost::filesystem::path get_short_path(const boost::filesystem::path &path) noexcept;
 
-    static bool file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path);
+  static bool file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path);
 
-    static boost::filesystem::path
-    find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path);
+  static boost::filesystem::path
+  find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path);
 
-    /// Return path with dot, dot-dot and directory separator elements removed
-    static boost::filesystem::path get_normal_path(const boost::filesystem::path &path) noexcept;
+  /// Return path with dot, dot-dot and directory separator elements removed
+  static boost::filesystem::path get_normal_path(const boost::filesystem::path &path) noexcept;
 
-    /// Returns empty path on failure
-    static boost::filesystem::path
-    get_relative_path(const boost::filesystem::path &path, const boost::filesystem::path &base) noexcept;
+  /// Returns empty path on failure
+  static boost::filesystem::path
+  get_relative_path(const boost::filesystem::path &path, const boost::filesystem::path &base) noexcept;
 
-    /// Return executable with latest version in filename on systems that is lacking executable_name symbolic link
-    static boost::filesystem::path get_executable(const boost::filesystem::path &executable_name) noexcept;
+  /// Return executable with latest version in filename on systems that is lacking executable_name symbolic link
+  static boost::filesystem::path get_executable(const boost::filesystem::path &executable_name) noexcept;
 
-    static const std::vector<boost::filesystem::path> &get_executable_search_paths();
+  static const std::vector<boost::filesystem::path> &get_executable_search_paths();
 
-    static boost::filesystem::path find_executable(const std::string &executable_name);
+  static boost::filesystem::path find_executable(const std::string &executable_name);
 };
diff --git a/src/git.cc b/src/git.cc
index 100ad9a1..ad4321f4 100644
--- a/src/git.cc
+++ b/src/git.cc
@@ -1,317 +1,316 @@
 #include "git.h"
-#include <cstring>
 
 bool Git::initialized = false;
 std::mutex Git::mutex;
 
 std::string Git::Error::message() noexcept {
-    const git_error *last_error = giterr_last();
-    if (last_error == nullptr)
-        return std::string();
-    else
-        return last_error->message;
+  const git_error *last_error = giterr_last();
+  if (last_error == nullptr)
+    return std::string();
+  else
+    return last_error->message;
 }
 
 Git::Repository::Diff::Diff(const boost::filesystem::path &path, git_repository *repository) : repository(repository) {
-    blob = std::shared_ptr<git_blob>(nullptr, [](git_blob *blob) {
-        if (blob) git_blob_free(blob);
-    });
-    Error error;
-    std::lock_guard<std::mutex> lock(mutex);
-    auto spec = "HEAD:" + path.generic_string();
-    error.code = git_revparse_single(reinterpret_cast<git_object **>(&blob), repository, spec.c_str());
-    if (error)
-        throw std::runtime_error(error.message());
+  blob = std::shared_ptr<git_blob>(nullptr, [](git_blob *blob) {
+    if (blob) git_blob_free(blob);
+  });
+  Error error;
+  std::lock_guard<std::mutex> lock(mutex);
+  auto spec = "HEAD:" + path.generic_string();
+  error.code = git_revparse_single(reinterpret_cast<git_object **>(&blob), repository, spec.c_str());
+  if (error)
+    throw std::runtime_error(error.message());
 
-    git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
-    options.context_lines = 0;
+  git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
+  options.context_lines = 0;
 }
 
 //Based on https://github.com/atom/git-diff/blob/master/lib/git-diff-view.coffee
 int Git::Repository::Diff::hunk_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) noexcept {
-    auto lines = static_cast<Lines *>(payload);
-    auto start = hunk->new_start - 1;
-    auto end = hunk->new_start + hunk->new_lines - 1;
-    if (hunk->old_lines == 0 && hunk->new_lines > 0)
-        lines->added.emplace_back(start, end);
-    else if (hunk->new_lines == 0 && hunk->old_lines > 0)
-        lines->removed.emplace_back(start);
-    else
-        lines->modified.emplace_back(start, end);
+  auto lines = static_cast<Lines *>(payload);
+  auto start = hunk->new_start - 1;
+  auto end = hunk->new_start + hunk->new_lines - 1;
+  if (hunk->old_lines == 0 && hunk->new_lines > 0)
+    lines->added.emplace_back(start, end);
+  else if (hunk->new_lines == 0 && hunk->old_lines > 0)
+    lines->removed.emplace_back(start);
+  else
+    lines->modified.emplace_back(start, end);
 
-    return 0;
+  return 0;
 }
 
 Git::Repository::Diff::Lines Git::Repository::Diff::get_lines(const std::string &buffer) {
-    Lines lines;
-    Error error;
-    std::lock_guard<std::mutex> lock(mutex);
-    error.code = git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr,
-                                         nullptr, hunk_cb, nullptr, &lines);
-    if (error)
-        throw std::runtime_error(error.message());
-    return lines;
+  Lines lines;
+  Error error;
+  std::lock_guard<std::mutex> lock(mutex);
+  error.code = git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr,
+                                       nullptr, hunk_cb, nullptr, &lines);
+  if (error)
+    throw std::runtime_error(error.message());
+  return lines;
 }
 
 std::vector<Git::Repository::Diff::Hunk>
 Git::Repository::Diff::get_hunks(const std::string &old_buffer, const std::string &new_buffer) {
-    std::vector<Git::Repository::Diff::Hunk> hunks;
-    Error error;
-    git_diff_options options;
-    git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
-    options.context_lines = 0;
-    error.code = git_diff_buffers(old_buffer.c_str(), old_buffer.size(), nullptr, new_buffer.c_str(), new_buffer.size(),
-                                  nullptr, &options, nullptr, nullptr,
-                                  [](const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) {
-                                      auto hunks = static_cast<std::vector<Git::Repository::Diff::Hunk> *>(payload);
-                                      hunks->emplace_back(hunk->old_start, hunk->old_lines, hunk->new_start,
-                                                          hunk->new_lines);
-                                      return 0;
-                                  }, nullptr, &hunks);
-    if (error)
-        throw std::runtime_error(error.message());
-    return hunks;
+  std::vector<Git::Repository::Diff::Hunk> hunks;
+  Error error;
+  git_diff_options options;
+  git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
+  options.context_lines = 0;
+  error.code = git_diff_buffers(old_buffer.c_str(), old_buffer.size(), nullptr, new_buffer.c_str(), new_buffer.size(),
+                                nullptr, &options, nullptr, nullptr,
+                                [](const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) {
+                                  auto hunks = static_cast<std::vector<Git::Repository::Diff::Hunk> *>(payload);
+                                  hunks->emplace_back(hunk->old_start, hunk->old_lines, hunk->new_start,
+                                                      hunk->new_lines);
+                                  return 0;
+                                }, nullptr, &hunks);
+  if (error)
+    throw std::runtime_error(error.message());
+  return hunks;
 }
 
 int Git::Repository::Diff::line_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line,
                                    void *payload) noexcept {
-    auto details = static_cast<std::pair<std::string, int> *>(payload);
-    auto line_nr = details->second;
-    auto start = hunk->new_start - 1;
-    auto end = hunk->new_start + hunk->new_lines - 1;
-    if (line_nr == start || (line_nr >= start && line_nr < end)) {
-        if (details->first.empty())
-            details->first += std::string(hunk->header, hunk->header_len);
-        details->first += line->origin + std::string(line->content, line->content_len);
-    }
-    return 0;
+  auto details = static_cast<std::pair<std::string, int> *>(payload);
+  auto line_nr = details->second;
+  auto start = hunk->new_start - 1;
+  auto end = hunk->new_start + hunk->new_lines - 1;
+  if (line_nr == start || (line_nr >= start && line_nr < end)) {
+    if (details->first.empty())
+      details->first += std::string(hunk->header, hunk->header_len);
+    details->first += line->origin + std::string(line->content, line->content_len);
+  }
+  return 0;
 }
 
 std::string Git::Repository::Diff::get_details(const std::string &buffer, int line_nr) {
-    std::pair<std::string, int> details;
-    details.second = line_nr;
-    Error error;
-    std::lock_guard<std::mutex> lock(mutex);
-    error.code = git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr,
-                                         nullptr, nullptr, line_cb, &details);
-    if (error)
-        throw std::runtime_error(error.message());
-    return details.first;
+  std::pair<std::string, int> details;
+  details.second = line_nr;
+  Error error;
+  std::lock_guard<std::mutex> lock(mutex);
+  error.code = git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr,
+                                       nullptr, nullptr, line_cb, &details);
+  if (error)
+    throw std::runtime_error(error.message());
+  return details.first;
 }
 
 Git::Repository::Repository(const boost::filesystem::path &path) {
-    git_repository *repository_ptr;
-    {
-        Error error;
-        std::lock_guard<std::mutex> lock(mutex);
-        auto path_str = path.generic_string();
-        error.code = git_repository_open_ext(&repository_ptr, path_str.c_str(), 0, nullptr);
-        if (error)
-            throw std::runtime_error(error.message());
-    }
-    repository = std::unique_ptr<git_repository, std::function<void(git_repository *)> >(repository_ptr,
-                                                                                         [](git_repository *ptr) {
-                                                                                             git_repository_free(ptr);
-                                                                                         });
+  git_repository *repository_ptr;
+  {
+    Error error;
+    std::lock_guard<std::mutex> lock(mutex);
+    auto path_str = path.generic_string();
+    error.code = git_repository_open_ext(&repository_ptr, path_str.c_str(), 0, nullptr);
+    if (error)
+      throw std::runtime_error(error.message());
+  }
+  repository = std::unique_ptr<git_repository, std::function<void(git_repository *)> >(repository_ptr,
+                                                                                       [](git_repository *ptr) {
+                                                                                         git_repository_free(ptr);
+                                                                                       });
 
-    work_path = get_work_path();
-    if (work_path.empty())
-        throw std::runtime_error("Could not find work path");
+  work_path = get_work_path();
+  if (work_path.empty())
+    throw std::runtime_error("Could not find work path");
 
-    auto git_directory = Gio::File::create_for_path(get_path().string());
-    monitor = git_directory->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
-    monitor_changed_connection = monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
-                                                                          const Glib::RefPtr<Gio::File> &,
-                                                                          Gio::FileMonitorEvent monitor_event) {
-        if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-            this->clear_saved_status();
-        }
-    }, false);
+  auto git_directory = Gio::File::create_for_path(get_path().string());
+  monitor = git_directory->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
+  monitor_changed_connection = monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
+                                                                        const Glib::RefPtr<Gio::File> &,
+                                                                        Gio::FileMonitorEvent monitor_event) {
+    if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+      this->clear_saved_status();
+    }
+  }, false);
 }
 
 Git::Repository::~Repository() {
-    monitor_changed_connection.disconnect();
+  monitor_changed_connection.disconnect();
 }
 
 std::string Git::Repository::status_string(STATUS status) noexcept {
-    switch (status) {
-        case STATUS::CURRENT:
-            return "current";
-        case STATUS::NEW:
-            return "new";
-        case STATUS::MODIFIED:
-            return "modified";
-        case STATUS::DELETED:
-            return "deleted";
-        case STATUS::RENAMED:
-            return "renamed";
-        case STATUS::TYPECHANGE:
-            return "typechange";
-        case STATUS::UNREADABLE:
-            return "unreadable";
-        case STATUS::IGNORED:
-            return "ignored";
-        case STATUS::CONFLICTED:
-            return "conflicted";
-        default:
-            return "";
-    }
+  switch (status) {
+    case STATUS::CURRENT:
+      return "current";
+    case STATUS::NEW:
+      return "new";
+    case STATUS::MODIFIED:
+      return "modified";
+    case STATUS::DELETED:
+      return "deleted";
+    case STATUS::RENAMED:
+      return "renamed";
+    case STATUS::TYPECHANGE:
+      return "typechange";
+    case STATUS::UNREADABLE:
+      return "unreadable";
+    case STATUS::IGNORED:
+      return "ignored";
+    case STATUS::CONFLICTED:
+      return "conflicted";
+    default:
+      return "";
+  }
 }
 
 int Git::Repository::status_callback(const char *path, unsigned int status_flags, void *data) noexcept {
-    auto callback = static_cast<std::function<void(const char *path, STATUS status)> *>(data);
+  auto callback = static_cast<std::function<void(const char *path, STATUS status)> *>(data);
 
-    STATUS status;
-    if ((status_flags & (GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_NEW)) > 0)
-        status = STATUS::NEW;
-    else if ((status_flags & (GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED)) > 0)
-        status = STATUS::MODIFIED;
-    else if ((status_flags & (GIT_STATUS_INDEX_DELETED | GIT_STATUS_WT_DELETED)) > 0)
-        status = STATUS::DELETED;
-    else if ((status_flags & (GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED)) > 0)
-        status = STATUS::RENAMED;
-    else if ((status_flags & (GIT_STATUS_INDEX_TYPECHANGE | GIT_STATUS_WT_TYPECHANGE)) > 0)
-        status = STATUS::TYPECHANGE;
-    else if ((status_flags & (GIT_STATUS_WT_UNREADABLE)) > 0)
-        status = STATUS::UNREADABLE;
-    else if ((status_flags & (GIT_STATUS_IGNORED)) > 0)
-        status = STATUS::IGNORED;
-    else if ((status_flags & (GIT_STATUS_CONFLICTED)) > 0)
-        status = STATUS::CONFLICTED;
-    else
-        status = STATUS::CURRENT;
+  STATUS status;
+  if ((status_flags & (GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_NEW)) > 0)
+    status = STATUS::NEW;
+  else if ((status_flags & (GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED)) > 0)
+    status = STATUS::MODIFIED;
+  else if ((status_flags & (GIT_STATUS_INDEX_DELETED | GIT_STATUS_WT_DELETED)) > 0)
+    status = STATUS::DELETED;
+  else if ((status_flags & (GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED)) > 0)
+    status = STATUS::RENAMED;
+  else if ((status_flags & (GIT_STATUS_INDEX_TYPECHANGE | GIT_STATUS_WT_TYPECHANGE)) > 0)
+    status = STATUS::TYPECHANGE;
+  else if ((status_flags & (GIT_STATUS_WT_UNREADABLE)) > 0)
+    status = STATUS::UNREADABLE;
+  else if ((status_flags & (GIT_STATUS_IGNORED)) > 0)
+    status = STATUS::IGNORED;
+  else if ((status_flags & (GIT_STATUS_CONFLICTED)) > 0)
+    status = STATUS::CONFLICTED;
+  else
+    status = STATUS::CURRENT;
 
-    if (*callback)
-        (*callback)(path, status);
+  if (*callback)
+    (*callback)(path, status);
 
-    return 0;
+  return 0;
 }
 
 Git::Repository::Status Git::Repository::get_status() {
-    {
-        std::unique_lock<std::mutex> lock(saved_status_mutex);
-        if (has_saved_status)
-            return saved_status;
-    }
+  {
+    std::unique_lock<std::mutex> lock(saved_status_mutex);
+    if (has_saved_status)
+      return saved_status;
+  }
 
-    Status status;
-    bool first = true;
-    std::unique_lock<std::mutex> status_saved_lock(saved_status_mutex, std::defer_lock);
-    std::function<void(const char *path, STATUS status)> callback = [this, &status, &first, &status_saved_lock](
-            const char *path_cstr, STATUS status_enum) {
-        if (first) {
-            status_saved_lock.lock();
-            first = false;
-        }
-        boost::filesystem::path rel_path(path_cstr);
-        do {
-            if (status_enum == STATUS::MODIFIED)
-                status.modified.emplace((work_path / rel_path).generic_string());
-            if (status_enum == STATUS::NEW)
-                status.added.emplace((work_path / rel_path).generic_string());
-            rel_path = rel_path.parent_path();
-        } while (!rel_path.empty());
-    };
-    Error error;
-    std::lock_guard<std::mutex> lock(mutex);
-    error.code = git_status_foreach(repository.get(), status_callback, &callback);
-    if (error)
-        throw std::runtime_error(error.message());
-    saved_status = status;
-    has_saved_status = true;
-    if (status_saved_lock)
-        status_saved_lock.unlock();
-    return status;
+  Status status;
+  bool first = true;
+  std::unique_lock<std::mutex> status_saved_lock(saved_status_mutex, std::defer_lock);
+  std::function<void(const char *path, STATUS status)> callback = [this, &status, &first, &status_saved_lock](
+      const char *path_cstr, STATUS status_enum) {
+    if (first) {
+      status_saved_lock.lock();
+      first = false;
+    }
+    boost::filesystem::path rel_path(path_cstr);
+    do {
+      if (status_enum == STATUS::MODIFIED)
+        status.modified.emplace((work_path / rel_path).generic_string());
+      if (status_enum == STATUS::NEW)
+        status.added.emplace((work_path / rel_path).generic_string());
+      rel_path = rel_path.parent_path();
+    } while (!rel_path.empty());
+  };
+  Error error;
+  std::lock_guard<std::mutex> lock(mutex);
+  error.code = git_status_foreach(repository.get(), status_callback, &callback);
+  if (error)
+    throw std::runtime_error(error.message());
+  saved_status = status;
+  has_saved_status = true;
+  if (status_saved_lock)
+    status_saved_lock.unlock();
+  return status;
 }
 
 void Git::Repository::clear_saved_status() {
-    std::unique_lock<std::mutex> lock(saved_status_mutex);
-    saved_status.added.clear();
-    saved_status.modified.clear();
-    has_saved_status = false;
+  std::unique_lock<std::mutex> lock(saved_status_mutex);
+  saved_status.added.clear();
+  saved_status.modified.clear();
+  has_saved_status = false;
 }
 
 boost::filesystem::path Git::Repository::get_work_path() noexcept {
-    std::lock_guard<std::mutex> lock(mutex);
-    return Git::path(git_repository_workdir(repository.get()));
+  std::lock_guard<std::mutex> lock(mutex);
+  return Git::path(git_repository_workdir(repository.get()));
 }
 
 boost::filesystem::path Git::Repository::get_path() noexcept {
-    std::lock_guard<std::mutex> lock(mutex);
-    return Git::path(git_repository_path(repository.get()));
+  std::lock_guard<std::mutex> lock(mutex);
+  return Git::path(git_repository_path(repository.get()));
 }
 
 boost::filesystem::path Git::Repository::get_root_path(const boost::filesystem::path &path) {
-    initialize();
-    git_buf root = {0, 0, 0};
-    {
-        Error error;
-        std::lock_guard<std::mutex> lock(mutex);
-        auto path_str = path.generic_string();
-        error.code = git_repository_discover(&root, path_str.c_str(), 0, nullptr);
-        if (error)
-            throw std::runtime_error(error.message());
-    }
-    auto root_path = Git::path(root.ptr, root.size);
-    git_buf_free(&root);
-    return root_path;
+  initialize();
+  git_buf root = {0, 0, 0};
+  {
+    Error error;
+    std::lock_guard<std::mutex> lock(mutex);
+    auto path_str = path.generic_string();
+    error.code = git_repository_discover(&root, path_str.c_str(), 0, nullptr);
+    if (error)
+      throw std::runtime_error(error.message());
+  }
+  auto root_path = Git::path(root.ptr, root.size);
+  git_buf_free(&root);
+  return root_path;
 }
 
 Git::Repository::Diff Git::Repository::get_diff(const boost::filesystem::path &path) {
-    return Diff(path, repository.get());
+  return Diff(path, repository.get());
 }
 
 std::string Git::Repository::get_branch() noexcept {
-    std::string branch;
-    git_reference *reference;
-    if (git_repository_head(&reference, repository.get()) == 0) {
-        if (auto reference_name_cstr = git_reference_name(reference)) {
-            std::string reference_name(reference_name_cstr);
-            size_t pos;
-            if ((pos = reference_name.rfind('/')) != std::string::npos) {
-                if (pos + 1 < reference_name.size())
-                    branch = reference_name.substr(pos + 1);
-            } else if ((pos = reference_name.rfind('\\')) != std::string::npos) {
-                if (pos + 1 < reference_name.size())
-                    branch = reference_name.substr(pos + 1);
-            }
-        }
-        git_reference_free(reference);
+  std::string branch;
+  git_reference *reference;
+  if (git_repository_head(&reference, repository.get()) == 0) {
+    if (auto reference_name_cstr = git_reference_name(reference)) {
+      std::string reference_name(reference_name_cstr);
+      size_t pos;
+      if ((pos = reference_name.rfind('/')) != std::string::npos) {
+        if (pos + 1 < reference_name.size())
+          branch = reference_name.substr(pos + 1);
+      } else if ((pos = reference_name.rfind('\\')) != std::string::npos) {
+        if (pos + 1 < reference_name.size())
+          branch = reference_name.substr(pos + 1);
+      }
     }
-    return branch;
+    git_reference_free(reference);
+  }
+  return branch;
 }
 
 void Git::initialize() noexcept {
-    std::lock_guard<std::mutex> lock(mutex);
-    if (!initialized) {
-        git_libgit2_init();
-        initialized = true;
-    }
+  std::lock_guard<std::mutex> lock(mutex);
+  if (!initialized) {
+    git_libgit2_init();
+    initialized = true;
+  }
 }
 
 std::shared_ptr<Git::Repository> Git::get_repository(const boost::filesystem::path &path) {
-    initialize();
-    static std::unordered_map<std::string, std::weak_ptr<Git::Repository> > cache;
-    static std::mutex mutex;
+  initialize();
+  static std::unordered_map<std::string, std::weak_ptr<Git::Repository> > cache;
+  static std::mutex mutex;
 
-    std::lock_guard<std::mutex> lock(mutex);
-    auto root_path = Repository::get_root_path(path).generic_string();
-    auto it = cache.find(root_path);
-    if (it == cache.end())
-        it = cache.emplace(root_path, std::weak_ptr<Git::Repository>()).first;
-    auto instance = it->second.lock();
-    if (!instance)
-        it->second = instance = std::shared_ptr<Repository>(new Repository(root_path));
-    return instance;
+  std::lock_guard<std::mutex> lock(mutex);
+  auto root_path = Repository::get_root_path(path).generic_string();
+  auto it = cache.find(root_path);
+  if (it == cache.end())
+    it = cache.emplace(root_path, std::weak_ptr<Git::Repository>()).first;
+  auto instance = it->second.lock();
+  if (!instance)
+    it->second = instance = std::shared_ptr<Repository>(new Repository(root_path));
+  return instance;
 }
 
 boost::filesystem::path Git::path(const char *cpath, size_t cpath_length) noexcept {
-    if (cpath == nullptr)
-        return boost::filesystem::path();
-    if (cpath_length == static_cast<size_t>(-1))
-        cpath_length = strlen(cpath);
-    if (cpath_length > 0 && (cpath[cpath_length - 1] == '/' || cpath[cpath_length - 1] == '\\'))
-        return std::string(cpath, cpath_length - 1);
-    else
-        return std::string(cpath, cpath_length);
+  if (cpath == nullptr)
+    return boost::filesystem::path();
+  if (cpath_length == static_cast<size_t>(-1))
+    cpath_length = strlen(cpath);
+  if (cpath_length > 0 && (cpath[cpath_length - 1] == '/' || cpath[cpath_length - 1] == '\\'))
+    return std::string(cpath, cpath_length - 1);
+  else
+    return std::string(cpath, cpath_length);
 }
diff --git a/src/git.h b/src/git.h
index 38545c92..0fa937a1 100644
--- a/src/git.h
+++ b/src/git.h
@@ -11,125 +11,125 @@
 #include <boost/filesystem.hpp>
 
 class Git {
-    friend class Repository;
+  friend class Repository;
 
 public:
-    class Error {
-        friend class Git;
+  class Error {
+    friend class Git;
 
-        std::string message() noexcept;
+    std::string message() noexcept;
 
-    public:
-        int code = 0;
+  public:
+    int code = 0;
 
-        Error() {}
+    Error() {}
 
-        operator bool() noexcept { return code < 0; }
-    };
+    operator bool() noexcept { return code < 0; }
+  };
 
-    class Repository {
+  class Repository {
+  public:
+    class Diff {
     public:
-        class Diff {
-        public:
-            class Lines {
-            public:
-                std::vector<std::pair<int, int> > added;
-                std::vector<std::pair<int, int> > modified;
-                std::vector<int> removed;
-            };
-
-            class Hunk {
-            public:
-                Hunk(int old_start, int old_size, int new_start, int new_size) : old_lines(old_start, old_size),
-                                                                                 new_lines(new_start, new_size) {}
-
-                /// Start and size
-                std::pair<int, int> old_lines;
-                /// Start and size
-                std::pair<int, int> new_lines;
-            };
+      class Lines {
+      public:
+        std::vector<std::pair<int, int> > added;
+        std::vector<std::pair<int, int> > modified;
+        std::vector<int> removed;
+      };
+
+      class Hunk {
+      public:
+        Hunk(int old_start, int old_size, int new_start, int new_size) : old_lines(old_start, old_size),
+                                                                         new_lines(new_start, new_size) {}
+
+        /// Start and size
+        std::pair<int, int> old_lines;
+        /// Start and size
+        std::pair<int, int> new_lines;
+      };
 
-        private:
-            friend class Repository;
+    private:
+      friend class Repository;
 
-            Diff(const boost::filesystem::path &path, git_repository *repository);
+      Diff(const boost::filesystem::path &path, git_repository *repository);
 
-            git_repository *repository;
-            std::shared_ptr<git_blob> blob;
-            git_diff_options options;
+      git_repository *repository;
+      std::shared_ptr<git_blob> blob;
+      git_diff_options options;
 
-            static int hunk_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) noexcept;
+      static int hunk_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) noexcept;
 
-            static int line_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line,
-                               void *payload) noexcept;
+      static int line_cb(const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line,
+                         void *payload) noexcept;
 
-        public:
-            Diff() : repository(nullptr), blob(nullptr) {}
+    public:
+      Diff() : repository(nullptr), blob(nullptr) {}
 
-            Lines get_lines(const std::string &buffer);
+      Lines get_lines(const std::string &buffer);
 
-            static std::vector<Hunk> get_hunks(const std::string &old_buffer, const std::string &new_buffer);
+      static std::vector<Hunk> get_hunks(const std::string &old_buffer, const std::string &new_buffer);
 
-            std::string get_details(const std::string &buffer, int line_nr);
-        };
+      std::string get_details(const std::string &buffer, int line_nr);
+    };
 
-        enum class STATUS {
-            CURRENT, NEW, MODIFIED, DELETED, RENAMED, TYPECHANGE, UNREADABLE, IGNORED, CONFLICTED
-        };
+    enum class STATUS {
+      CURRENT, NEW, MODIFIED, DELETED, RENAMED, TYPECHANGE, UNREADABLE, IGNORED, CONFLICTED
+    };
 
-        class Status {
-        public:
-            std::unordered_set<std::string> added;
-            std::unordered_set<std::string> modified;
-        };
+    class Status {
+    public:
+      std::unordered_set<std::string> added;
+      std::unordered_set<std::string> modified;
+    };
 
-    private:
-        friend class Git;
+  private:
+    friend class Git;
 
-        Repository(const boost::filesystem::path &path);
+    Repository(const boost::filesystem::path &path);
 
-        static int status_callback(const char *path, unsigned int status_flags, void *data) noexcept;
+    static int status_callback(const char *path, unsigned int status_flags, void *data) noexcept;
 
-        std::unique_ptr<git_repository, std::function<void(git_repository *)> > repository;
+    std::unique_ptr<git_repository, std::function<void(git_repository *)> > repository;
 
-        boost::filesystem::path work_path;
-        sigc::connection monitor_changed_connection;
-        Status saved_status;
-        bool has_saved_status = false;
-        std::mutex saved_status_mutex;
-    public:
-        ~Repository();
+    boost::filesystem::path work_path;
+    sigc::connection monitor_changed_connection;
+    Status saved_status;
+    bool has_saved_status = false;
+    std::mutex saved_status_mutex;
+  public:
+    ~Repository();
 
-        static std::string status_string(STATUS status) noexcept;
+    static std::string status_string(STATUS status) noexcept;
 
-        Status get_status();
+    Status get_status();
 
-        void clear_saved_status();
+    void clear_saved_status();
 
-        boost::filesystem::path get_work_path() noexcept;
+    boost::filesystem::path get_work_path() noexcept;
 
-        boost::filesystem::path get_path() noexcept;
+    boost::filesystem::path get_path() noexcept;
 
-        static boost::filesystem::path get_root_path(const boost::filesystem::path &path);
+    static boost::filesystem::path get_root_path(const boost::filesystem::path &path);
 
-        Diff get_diff(const boost::filesystem::path &path);
+    Diff get_diff(const boost::filesystem::path &path);
 
-        std::string get_branch() noexcept;
+    std::string get_branch() noexcept;
 
-        Glib::RefPtr<Gio::FileMonitor> monitor;
-    };
+    Glib::RefPtr<Gio::FileMonitor> monitor;
+  };
 
 private:
-    static bool initialized;
+  static bool initialized;
 
-    ///Mutex for thread safe operations
-    static std::mutex mutex;
+  ///Mutex for thread safe operations
+  static std::mutex mutex;
 
-    ///Call initialize in public static methods
-    static void initialize() noexcept;
+  ///Call initialize in public static methods
+  static void initialize() noexcept;
 
-    static boost::filesystem::path path(const char *cpath, size_t cpath_length = static_cast<size_t>(-1)) noexcept;
+  static boost::filesystem::path path(const char *cpath, size_t cpath_length = static_cast<size_t>(-1)) noexcept;
 
 public:
-    static std::shared_ptr<Repository> get_repository(const boost::filesystem::path &path);
+  static std::shared_ptr<Repository> get_repository(const boost::filesystem::path &path);
 };
diff --git a/src/info.cc b/src/info.cc
index a4723a4c..95246334 100644
--- a/src/info.cc
+++ b/src/info.cc
@@ -1,36 +1,36 @@
 #include "info.h"
 
 Info::Info() {
-    set_hexpand(false);
-    set_halign(Gtk::Align::ALIGN_END);
+  set_hexpand(false);
+  set_halign(Gtk::Align::ALIGN_END);
 
-    auto content_area = dynamic_cast<Gtk::Container *>(get_content_area());
-    label.set_max_width_chars(40);
-    label.set_line_wrap(true);
-    content_area->add(label);
+  auto content_area = dynamic_cast<Gtk::Container *>(get_content_area());
+  label.set_max_width_chars(40);
+  label.set_line_wrap(true);
+  content_area->add(label);
 
-    get_style_context()->add_class("juci_info");
+  get_style_context()->add_class("juci_info");
 
-    //Workaround from https://bugzilla.gnome.org/show_bug.cgi?id=710888
-    //Issue described at the same issue report
-    //TODO: remove later
-    auto revealer = gtk_widget_get_template_child(GTK_WIDGET (gobj()), GTK_TYPE_INFO_BAR, "revealer");
-    if (revealer) {
-        gtk_revealer_set_transition_type(GTK_REVEALER (revealer), GTK_REVEALER_TRANSITION_TYPE_NONE);
-        gtk_revealer_set_transition_duration(GTK_REVEALER (revealer), 0);
-    }
+  //Workaround from https://bugzilla.gnome.org/show_bug.cgi?id=710888
+  //Issue described at the same issue report
+  //TODO: remove later
+  auto revealer = gtk_widget_get_template_child(GTK_WIDGET (gobj()), GTK_TYPE_INFO_BAR, "revealer");
+  if (revealer) {
+    gtk_revealer_set_transition_type(GTK_REVEALER (revealer), GTK_REVEALER_TRANSITION_TYPE_NONE);
+    gtk_revealer_set_transition_duration(GTK_REVEALER (revealer), 0);
+  }
 }
 
 void Info::print(const std::string &text) {
-    timeout_connection.disconnect();
-    //Timeout based on https://en.wikipedia.org/wiki/Words_per_minute
-    //(average_words_per_minute*average_letters_per_word)/60 => (228*4.5)/60 = 17.1
-    double timeout = 1000.0 * std::max(3.0, 1.0 + text.size() / 17.1);
-    timeout_connection = Glib::signal_timeout().connect([this]() {
-        hide();
-        return false;
-    }, timeout);
+  timeout_connection.disconnect();
+  //Timeout based on https://en.wikipedia.org/wiki/Words_per_minute
+  //(average_words_per_minute*average_letters_per_word)/60 => (228*4.5)/60 = 17.1
+  double timeout = 1000.0 * std::max(3.0, 1.0 + text.size() / 17.1);
+  timeout_connection = Glib::signal_timeout().connect([this]() {
+    hide();
+    return false;
+  }, timeout);
 
-    label.set_text(text);
-    show();
+  label.set_text(text);
+  show();
 }
diff --git a/src/info.h b/src/info.h
index d1ad78ab..8ddae006 100644
--- a/src/info.h
+++ b/src/info.h
@@ -3,17 +3,17 @@
 #include <gtkmm.h>
 
 class Info : public Gtk::InfoBar {
-    Info();
+  Info();
 
 public:
-    static Info &get() {
-        static Info instance;
-        return instance;
-    }
+  static Info &get() {
+    static Info instance;
+    return instance;
+  }
 
-    void print(const std::string &text);
+  void print(const std::string &text);
 
 private:
-    Gtk::Label label;
-    sigc::connection timeout_connection;
+  Gtk::Label label;
+  sigc::connection timeout_connection;
 };
diff --git a/src/juci.cc b/src/juci.cc
index 29881803..a57babd7 100644
--- a/src/juci.cc
+++ b/src/juci.cc
@@ -3,7 +3,6 @@
 #include "notebook.h"
 #include "directories.h"
 #include "menu.h"
-#include "config.h"
 #include "terminal.h"
 
 #ifndef _WIN32
@@ -11,127 +10,127 @@
 #endif
 
 int Application::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) {
-    Glib::set_prgname("juci");
-    Glib::OptionContext ctx("[PATH ...]");
-    Glib::OptionGroup gtk_group(gtk_get_option_group(true));
-    ctx.add_group(gtk_group);
-    int argc;
-    char **argv = cmd->get_arguments(argc);
-    ctx.parse(argc, argv);
-    if (argc >= 2) {
-        boost::system::error_code current_path_ec;
-        auto current_path = boost::filesystem::current_path(current_path_ec);
-        if (current_path_ec)
-            errors.emplace_back("Error: could not find current path\n");
-        for (int c = 1; c < argc; c++) {
-            boost::filesystem::path path(argv[c]);
-            if (path.is_relative() && !current_path_ec)
-                path = current_path / path;
-            if (boost::filesystem::exists(path)) {
-                if (boost::filesystem::is_regular_file(path))
-                    files.emplace_back(path, 0);
-                else if (boost::filesystem::is_directory(path))
-                    directories.emplace_back(path);
-            }
-                //Open new file if parent path exists
-            else {
-                if (path.is_absolute() && boost::filesystem::is_directory(path.parent_path()))
-                    files.emplace_back(path, 0);
-                else
-                    errors.emplace_back("Error: could not create " + path.string() + ".\n");
-            }
-        }
+  Glib::set_prgname("juci");
+  Glib::OptionContext ctx("[PATH ...]");
+  Glib::OptionGroup gtk_group(gtk_get_option_group(true));
+  ctx.add_group(gtk_group);
+  int argc;
+  char **argv = cmd->get_arguments(argc);
+  ctx.parse(argc, argv);
+  if (argc >= 2) {
+    boost::system::error_code current_path_ec;
+    auto current_path = boost::filesystem::current_path(current_path_ec);
+    if (current_path_ec)
+      errors.emplace_back("Error: could not find current path\n");
+    for (int c = 1; c < argc; c++) {
+      boost::filesystem::path path(argv[c]);
+      if (path.is_relative() && !current_path_ec)
+        path = current_path / path;
+      if (boost::filesystem::exists(path)) {
+        if (boost::filesystem::is_regular_file(path))
+          files.emplace_back(path, 0);
+        else if (boost::filesystem::is_directory(path))
+          directories.emplace_back(path);
+      }
+        //Open new file if parent path exists
+      else {
+        if (path.is_absolute() && boost::filesystem::is_directory(path.parent_path()))
+          files.emplace_back(path, 0);
+        else
+          errors.emplace_back("Error: could not create " + path.string() + ".\n");
+      }
     }
-    activate();
-    return 0;
+  }
+  activate();
+  return 0;
 }
 
 void Application::on_activate() {
-    std::vector<std::pair<int, int>> file_offsets;
-    std::string current_file;
-    Window::get().load_session(directories, files, file_offsets, current_file, directories.empty() && files.empty());
-
-    Window::get().add_widgets();
-
-    add_window(Window::get());
-    Window::get().show();
-
-    bool first_directory = true;
-    for (auto &directory: directories) {
-        if (first_directory) {
-            Directories::get().open(directory);
-            first_directory = false;
-        } else {
-            std::string files_in_directory;
-            for (auto it = files.begin(); it != files.end();) {
-                if (it->first.generic_string().compare(0, directory.generic_string().size() + 1,
-                                                       directory.generic_string() + '/') == 0) {
-                    files_in_directory += " " + it->first.string();
-                    it = files.erase(it);
-                } else
-                    it++;
-            }
-            std::thread another_juci_app([directory, files_in_directory]() {
-                Terminal::get().async_print("Executing: juci " + directory.string() + files_in_directory + "\n");
-                Terminal::get().process("juci " + directory.string() + files_in_directory, "", false);
-            });
-            another_juci_app.detach();
-        }
-    }
+  std::vector<std::pair<int, int>> file_offsets;
+  std::string current_file;
+  Window::get().load_session(directories, files, file_offsets, current_file, directories.empty() && files.empty());
 
-    for (size_t i = 0; i < files.size(); ++i) {
-        Notebook::get().open(files[i].first, files[i].second);
-        if (i < file_offsets.size()) {
-            if (auto view = Notebook::get().get_current_view()) {
-                view->place_cursor_at_line_offset(file_offsets[i].first, file_offsets[i].second);
-                view->hide_tooltips();
-            }
-        }
-    }
+  Window::get().add_widgets();
 
-    for (auto &error: errors)
-        Terminal::get().print(error, true);
-
-    if (!current_file.empty()) {
-        Notebook::get().open(current_file);
-        if (auto view = Notebook::get().get_current_view()) {
-            auto iter = view->get_buffer()->get_insert()->get_iter();
-            // To update cursor history
-            view->place_cursor_at_line_offset(iter.get_line(), iter.get_line_offset());
-            view->hide_tooltips();
-        }
+  add_window(Window::get());
+  Window::get().show();
+
+  bool first_directory = true;
+  for (auto &directory: directories) {
+    if (first_directory) {
+      Directories::get().open(directory);
+      first_directory = false;
+    } else {
+      std::string files_in_directory;
+      for (auto it = files.begin(); it != files.end();) {
+        if (it->first.generic_string().compare(0, directory.generic_string().size() + 1,
+                                               directory.generic_string() + '/') == 0) {
+          files_in_directory += " " + it->first.string();
+          it = files.erase(it);
+        } else
+          it++;
+      }
+      std::thread another_juci_app([directory, files_in_directory]() {
+        Terminal::get().async_print("Executing: juci " + directory.string() + files_in_directory + "\n");
+        Terminal::get().process("juci " + directory.string() + files_in_directory, "", false);
+      });
+      another_juci_app.detach();
     }
+  }
+
+  for (size_t i = 0; i < files.size(); ++i) {
+    Notebook::get().open(files[i].first, files[i].second);
+    if (i < file_offsets.size()) {
+      if (auto view = Notebook::get().get_current_view()) {
+        view->place_cursor_at_line_offset(file_offsets[i].first, file_offsets[i].second);
+        view->hide_tooltips();
+      }
+    }
+  }
+
+  for (auto &error: errors)
+    Terminal::get().print(error, true);
+
+  if (!current_file.empty()) {
+    Notebook::get().open(current_file);
+    if (auto view = Notebook::get().get_current_view()) {
+      auto iter = view->get_buffer()->get_insert()->get_iter();
+      // To update cursor history
+      view->place_cursor_at_line_offset(iter.get_line(), iter.get_line_offset());
+      view->hide_tooltips();
+    }
+  }
 
-    while (Gtk::Main::events_pending())
-        Gtk::Main::iteration(false);
-    for (auto view: Notebook::get().get_views())
-        view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+  while (Gtk::Main::events_pending())
+    Gtk::Main::iteration(false);
+  for (auto view: Notebook::get().get_views())
+    view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
 }
 
 void Application::on_startup() {
-    Gtk::Application::on_startup();
+  Gtk::Application::on_startup();
 
-    Menu::get().build();
+  Menu::get().build();
 
-    if (!Menu::get().juci_menu || !Menu::get().window_menu) {
-        std::cerr << "Menu not found." << std::endl;
-    } else {
-        set_app_menu(Menu::get().juci_menu);
-        set_menubar(Menu::get().window_menu);
-    }
+  if (!Menu::get().juci_menu || !Menu::get().window_menu) {
+    std::cerr << "Menu not found." << std::endl;
+  } else {
+    set_app_menu(Menu::get().juci_menu);
+    set_menubar(Menu::get().window_menu);
+  }
 }
 
 Application::Application() : Gtk::Application("no.sout.juci",
                                               Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) {
-    Glib::set_application_name("juCi++");
+  Glib::set_application_name("juCi++");
 
-    //Gtk::MessageDialog without buttons caused text to be selected, this prevents that
-    Gtk::Settings::get_default()->property_gtk_label_select_on_focus() = false;
+  //Gtk::MessageDialog without buttons caused text to be selected, this prevents that
+  Gtk::Settings::get_default()->property_gtk_label_select_on_focus() = false;
 }
 
 int main(int argc, char *argv[]) {
 #ifndef _WIN32
-    signal(SIGPIPE, SIG_IGN); // Do not terminate application when writing to a process fails
+  signal(SIGPIPE, SIG_IGN); // Do not terminate application when writing to a process fails
 #endif
-    return Application().run(argc, argv);
+  return Application().run(argc, argv);
 }
diff --git a/src/juci.h b/src/juci.h
index 0d267496..fe68b971 100644
--- a/src/juci.h
+++ b/src/juci.h
@@ -30,16 +30,16 @@
 
 class Application : public Gtk::Application {
 public:
-    Application();
+  Application();
 
-    int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) override;
+  int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) override;
 
-    void on_activate() override;
+  void on_activate() override;
 
-    void on_startup() override;
+  void on_startup() override;
 
 private:
-    std::vector<boost::filesystem::path> directories;
-    std::vector<std::pair<boost::filesystem::path, size_t>> files;
-    std::vector<std::string> errors;
+  std::vector<boost::filesystem::path> directories;
+  std::vector<std::pair<boost::filesystem::path, size_t>> files;
+  std::vector<std::string> errors;
 };
diff --git a/src/menu.cc b/src/menu.cc
index 3a0e16dd..6634d4a3 100644
--- a/src/menu.cc
+++ b/src/menu.cc
@@ -478,39 +478,39 @@ const Glib::ustring menu_xml = R"RAW(<interface>
 )RAW";
 
 void Menu::add_action(const std::string &name, std::function<void()> action) {
-    auto g_application = g_application_get_default();
-    auto gio_application = Glib::wrap(g_application, true);
-    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+  auto g_application = g_application_get_default();
+  auto gio_application = Glib::wrap(g_application, true);
+  auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
 
-    actions[name] = application->add_action(name, action);
+  actions[name] = application->add_action(name, action);
 }
 
 void Menu::set_keys() {
-    auto g_application = g_application_get_default();
-    auto gio_application = Glib::wrap(g_application, true);
-    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+  auto g_application = g_application_get_default();
+  auto gio_application = Glib::wrap(g_application, true);
+  auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
 
-    for (auto &key: Config::get().menu.keys) {
-        if (key.second.size() > 0 && actions.find(key.first) != actions.end())
-            application->set_accel_for_action("app." + key.first, key.second);
-    }
+  for (auto &key: Config::get().menu.keys) {
+    if (key.second.size() > 0 && actions.find(key.first) != actions.end())
+      application->set_accel_for_action("app." + key.first, key.second);
+  }
 }
 
 void Menu::build() {
-    try {
-        builder = Gtk::Builder::create_from_string(menu_xml);
-        auto object = builder->get_object("juci-menu");
-        juci_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
-        object = builder->get_object("window-menu");
-        window_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
-        object = builder->get_object("right-click-line-menu");
-        auto ptr = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
-        right_click_line_menu = std::make_unique<Gtk::Menu>(ptr);
-        object = builder->get_object("right-click-selected-menu");
-        ptr = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
-        right_click_selected_menu = std::make_unique<Gtk::Menu>(ptr);
-    }
-    catch (const Glib::Error &ex) {
-        std::cerr << "building menu failed: " << ex.what();
-    }
+  try {
+    builder = Gtk::Builder::create_from_string(menu_xml);
+    auto object = builder->get_object("juci-menu");
+    juci_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
+    object = builder->get_object("window-menu");
+    window_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
+    object = builder->get_object("right-click-line-menu");
+    auto ptr = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
+    right_click_line_menu = std::make_unique<Gtk::Menu>(ptr);
+    object = builder->get_object("right-click-selected-menu");
+    ptr = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
+    right_click_selected_menu = std::make_unique<Gtk::Menu>(ptr);
+  }
+  catch (const Glib::Error &ex) {
+    std::cerr << "building menu failed: " << ex.what();
+  }
 }
diff --git a/src/menu.h b/src/menu.h
index 9951b373..324575f4 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -6,27 +6,27 @@
 #include <gtkmm.h>
 
 class Menu {
-    Menu() {}
+  Menu() {}
 
 public:
-    static Menu &get() {
-        static Menu singleton;
-        return singleton;
-    }
+  static Menu &get() {
+    static Menu singleton;
+    return singleton;
+  }
 
-    void add_action(const std::string &name, std::function<void()> action);
+  void add_action(const std::string &name, std::function<void()> action);
 
-    std::unordered_map<std::string, Glib::RefPtr<Gio::SimpleAction> > actions;
+  std::unordered_map<std::string, Glib::RefPtr<Gio::SimpleAction> > actions;
 
-    void set_keys();
+  void set_keys();
 
-    void build();
+  void build();
 
-    Glib::RefPtr<Gio::Menu> juci_menu;
-    Glib::RefPtr<Gio::Menu> window_menu;
-    std::unique_ptr<Gtk::Menu> right_click_line_menu;
-    std::unique_ptr<Gtk::Menu> right_click_selected_menu;
-    std::function<void()> toggle_menu_items = [] {};
+  Glib::RefPtr<Gio::Menu> juci_menu;
+  Glib::RefPtr<Gio::Menu> window_menu;
+  std::unique_ptr<Gtk::Menu> right_click_line_menu;
+  std::unique_ptr<Gtk::Menu> right_click_selected_menu;
+  std::function<void()> toggle_menu_items = [] {};
 private:
-    Glib::RefPtr<Gtk::Builder> builder;
+  Glib::RefPtr<Gtk::Builder> builder;
 };
diff --git a/src/meson.cc b/src/meson.cc
index 3bc43006..7ea854fa 100644
--- a/src/meson.cc
+++ b/src/meson.cc
@@ -5,78 +5,80 @@
 #include "dialogs.h"
 #include "config.h"
 
-Meson::Meson(const boost::filesystem::path &path): BuildSystemBase(path, "meson.build") {}
+Meson::Meson(const boost::filesystem::path &path) : BuildSystemBase(path, "meson.build") {}
 
 bool Meson::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
-    if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") || default_build_path.empty())
-        return false;
+  if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") ||
+      default_build_path.empty())
+    return false;
 
-    if (!create_build_directory(default_build_path)) return false;
+  if (!create_build_directory(default_build_path)) return false;
 
-    auto compile_commands_path = default_build_path / "compile_commands.json";
-    bool compile_commands_exists = boost::filesystem::exists(compile_commands_path);
-    if (!force && compile_commands_exists)
-        return true;
+  auto compile_commands_path = default_build_path / "compile_commands.json";
+  bool compile_commands_exists = boost::filesystem::exists(compile_commands_path);
+  if (!force && compile_commands_exists)
+    return true;
 
-    Dialog::Message message("Creating/updating default build");
-    auto exit_status = Terminal::get().process(
-            Config::get().project.meson.command + ' ' + (compile_commands_exists ? "--internal regenerate " : "") +
-            filesystem::escape_argument(get_project_path().string()), default_build_path);
-    message.hide();
-    if (exit_status == EXIT_SUCCESS)
-        return true;
-    return false;
+  Dialog::Message message("Creating/updating default build");
+  auto exit_status = Terminal::get().process(
+      Config::get().project.meson.command + ' ' + (compile_commands_exists ? "--internal regenerate " : "") +
+      filesystem::escape_argument(get_project_path().string()), default_build_path);
+  message.hide();
+  if (exit_status == EXIT_SUCCESS)
+    return true;
+  return false;
 }
 
 bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-    if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") || debug_build_path.empty())
-        return false;
+  if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") ||
+      debug_build_path.empty())
+    return false;
 
-    if (!create_build_directory(debug_build_path)) return false;
+  if (!create_build_directory(debug_build_path)) return false;
 
-    bool compile_commands_exists = boost::filesystem::exists(debug_build_path / "compile_commands.json");
-    if (!force && compile_commands_exists)
-        return true;
+  bool compile_commands_exists = boost::filesystem::exists(debug_build_path / "compile_commands.json");
+  if (!force && compile_commands_exists)
+    return true;
 
-    Dialog::Message message("Creating/updating debug build");
-    auto exit_status = Terminal::get().process(
-            Config::get().project.meson.command + ' ' + (compile_commands_exists ? "--internal regenerate " : "") +
-            "--buildtype debug " + filesystem::escape_argument(get_project_path().string()), debug_build_path);
-    message.hide();
-    if (exit_status == EXIT_SUCCESS)
-        return true;
-    return false;
+  Dialog::Message message("Creating/updating debug build");
+  auto exit_status = Terminal::get().process(
+      Config::get().project.meson.command + ' ' + (compile_commands_exists ? "--internal regenerate " : "") +
+      "--buildtype debug " + filesystem::escape_argument(get_project_path().string()), debug_build_path);
+  message.hide();
+  if (exit_status == EXIT_SUCCESS)
+    return true;
+  return false;
 }
 
 boost::filesystem::path
 Meson::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
-    CompileCommands compile_commands(build_path);
+  CompileCommands compile_commands(build_path);
 
-    size_t best_match_size = -1;
-    boost::filesystem::path best_match_executable;
-    for (auto &command: compile_commands.commands) {
-        auto command_file = filesystem::get_normal_path(command.file);
-        auto values = command.parameter_values("-o");
-        if (!values.empty()) {
-            size_t pos;
-            if ((pos = values[0].find("@")) != std::string::npos) {
-                if (pos + 1 < values[0].size() && values[0].compare(pos + 1, 3, "exe") == 0) {
-                    auto executable = build_path / values[0].substr(0, pos);
-                    if (command_file == file_path)
-                        return executable;
-                    auto command_file_directory = command_file.parent_path();
-                    if (filesystem::file_in_path(file_path, command_file_directory)) {
-                        auto size = static_cast<size_t>(std::distance(command_file_directory.begin(),
-                                                                      command_file_directory.end()));
-                        if (best_match_size == static_cast<size_t>(-1) || best_match_size < size) {
-                            best_match_size = size;
-                            best_match_executable = executable;
-                        }
-                    }
-                }
+  size_t best_match_size = -1;
+  boost::filesystem::path best_match_executable;
+  for (auto &command: compile_commands.commands) {
+    auto command_file = filesystem::get_normal_path(command.file);
+    auto values = command.parameter_values("-o");
+    if (!values.empty()) {
+      size_t pos;
+      if ((pos = values[0].find("@")) != std::string::npos) {
+        if (pos + 1 < values[0].size() && values[0].compare(pos + 1, 3, "exe") == 0) {
+          auto executable = build_path / values[0].substr(0, pos);
+          if (command_file == file_path)
+            return executable;
+          auto command_file_directory = command_file.parent_path();
+          if (filesystem::file_in_path(file_path, command_file_directory)) {
+            auto size = static_cast<size_t>(std::distance(command_file_directory.begin(),
+                                                          command_file_directory.end()));
+            if (best_match_size == static_cast<size_t>(-1) || best_match_size < size) {
+              best_match_size = size;
+              best_match_executable = executable;
             }
+          }
         }
+      }
     }
+  }
 
-    return best_match_executable;
+  return best_match_executable;
 }
diff --git a/src/meson.h b/src/meson.h
index d22625d3..cd31dbfa 100644
--- a/src/meson.h
+++ b/src/meson.h
@@ -1,15 +1,16 @@
 #pragma once
 
 #include "buildsystem.h"
+
 class Meson : public BuildSystemBase {
 public:
-    Meson(const boost::filesystem::path &path);
+  Meson(const boost::filesystem::path &path);
 
-    bool update_default_build(const boost::filesystem::path &default_build_path, bool force) override;
+  bool update_default_build(const boost::filesystem::path &default_build_path, bool force) override;
 
-    bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) override;
+  bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) override;
 
-    boost::filesystem::path
-    get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
+  boost::filesystem::path
+  get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
 
 };
diff --git a/src/notebook.cc b/src/notebook.cc
index a177968a..43473d1e 100644
--- a/src/notebook.cc
+++ b/src/notebook.cc
@@ -11,673 +11,673 @@
 #include "gtksourceview-3.0/gtksourceview/gtksourcemap.h"
 
 Notebook::TabLabel::TabLabel(std::function<void()> on_close) {
-    set_can_focus(false);
-
-    auto button = Gtk::manage(new Gtk::Button());
-    auto hbox = Gtk::manage(new Gtk::Box());
-
-    hbox->set_can_focus(false);
-    label.set_can_focus(false);
-    button->set_image_from_icon_name("window-close-symbolic", Gtk::ICON_SIZE_MENU);
-    button->set_can_focus(false);
-    button->set_relief(Gtk::ReliefStyle::RELIEF_NONE);
-
-    hbox->pack_start(label, Gtk::PACK_SHRINK);
-    hbox->pack_end(*button, Gtk::PACK_SHRINK);
-    add(*hbox);
-
-    button->signal_clicked().connect(on_close);
-    signal_button_press_event().connect([on_close](GdkEventButton *event) {
-        if (event->button == GDK_BUTTON_MIDDLE) {
-            on_close();
-            return true;
-        }
-        return false;
-    });
+  set_can_focus(false);
+
+  auto button = Gtk::manage(new Gtk::Button());
+  auto hbox = Gtk::manage(new Gtk::Box());
+
+  hbox->set_can_focus(false);
+  label.set_can_focus(false);
+  button->set_image_from_icon_name("window-close-symbolic", Gtk::ICON_SIZE_MENU);
+  button->set_can_focus(false);
+  button->set_relief(Gtk::ReliefStyle::RELIEF_NONE);
+
+  hbox->pack_start(label, Gtk::PACK_SHRINK);
+  hbox->pack_end(*button, Gtk::PACK_SHRINK);
+  add(*hbox);
+
+  button->signal_clicked().connect(on_close);
+  signal_button_press_event().connect([on_close](GdkEventButton *event) {
+    if (event->button == GDK_BUTTON_MIDDLE) {
+      on_close();
+      return true;
+    }
+    return false;
+  });
 
-    show_all();
+  show_all();
 }
 
 Notebook::Notebook() : Gtk::Paned(), notebooks(2) {
-    for (auto &notebook: notebooks) {
-        notebook.get_style_context()->add_class("juci_notebook");
-        notebook.set_scrollable();
-        notebook.set_group_name("source_notebooks");
-        notebook.signal_switch_page().connect([this](Gtk::Widget *widget, guint) {
-            auto hbox = dynamic_cast<Gtk::Box *>(widget);
-            for (size_t c = 0; c < hboxes.size(); ++c) {
-                if (hboxes[c].get() == hbox) {
-                    focus_view(source_views[c]);
-                    set_current_view(source_views[c]);
-                    break;
-                }
-            }
-            last_index = -1;
-        });
-        notebook.signal_page_added().connect([this](Gtk::Widget *widget, guint) {
-            auto hbox = dynamic_cast<Gtk::Box *>(widget);
-            for (size_t c = 0; c < hboxes.size(); ++c) {
-                if (hboxes[c].get() == hbox) {
-                    focus_view(source_views[c]);
-                    set_current_view(source_views[c]);
-                    break;
-                }
-            }
-        });
-    }
-    pack1(notebooks[0], true, true);
+  for (auto &notebook: notebooks) {
+    notebook.get_style_context()->add_class("juci_notebook");
+    notebook.set_scrollable();
+    notebook.set_group_name("source_notebooks");
+    notebook.signal_switch_page().connect([this](Gtk::Widget *widget, guint) {
+      auto hbox = dynamic_cast<Gtk::Box *>(widget);
+      for (size_t c = 0; c < hboxes.size(); ++c) {
+        if (hboxes[c].get() == hbox) {
+          focus_view(source_views[c]);
+          set_current_view(source_views[c]);
+          break;
+        }
+      }
+      last_index = -1;
+    });
+    notebook.signal_page_added().connect([this](Gtk::Widget *widget, guint) {
+      auto hbox = dynamic_cast<Gtk::Box *>(widget);
+      for (size_t c = 0; c < hboxes.size(); ++c) {
+        if (hboxes[c].get() == hbox) {
+          focus_view(source_views[c]);
+          set_current_view(source_views[c]);
+          break;
+        }
+      }
+    });
+  }
+  pack1(notebooks[0], true, true);
 }
 
 size_t Notebook::size() {
-    return source_views.size();
+  return source_views.size();
 }
 
 Source::View *Notebook::get_view(size_t index) {
-    if (index >= size())
-        return nullptr;
-    return source_views[index];
+  if (index >= size())
+    return nullptr;
+  return source_views[index];
 }
 
 Source::View *Notebook::get_current_view() {
-    if (intermediate_view) {
-        for (auto view: source_views) {
-            if (view == intermediate_view)
-                return view;
-        }
-    }
+  if (intermediate_view) {
     for (auto view: source_views) {
-        if (view == current_view)
-            return view;
-    }
-    //In case there exist a tab that has not yet received focus again in a different notebook
-    for (int notebook_index = 0; notebook_index < 2; ++notebook_index) {
-        auto page = notebooks[notebook_index].get_current_page();
-        if (page >= 0)
-            return get_view(notebook_index, page);
+      if (view == intermediate_view)
+        return view;
     }
-    return nullptr;
+  }
+  for (auto view: source_views) {
+    if (view == current_view)
+      return view;
+  }
+  //In case there exist a tab that has not yet received focus again in a different notebook
+  for (int notebook_index = 0; notebook_index < 2; ++notebook_index) {
+    auto page = notebooks[notebook_index].get_current_page();
+    if (page >= 0)
+      return get_view(notebook_index, page);
+  }
+  return nullptr;
 }
 
 std::vector<Source::View *> &Notebook::get_views() {
-    return source_views;
+  return source_views;
 }
 
 void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_index) {
-    auto file_path = filesystem::get_normal_path(file_path_);
-
-    if (notebook_index == 1 && !split)
-        toggle_split();
-
-    // Use canonical path to follow symbolic links
-    boost::system::error_code ec;
-    auto canonical_file_path = boost::filesystem::canonical(file_path, ec);
-    if (ec)
-        canonical_file_path = file_path;
-    for (size_t c = 0; c < size(); c++) {
-        if (canonical_file_path == source_views[c]->canonical_file_path) {
-            auto notebook_page = get_notebook_page(c);
-            notebooks[notebook_page.first].set_current_page(notebook_page.second);
-            focus_view(source_views[c]);
-            return;
-        }
+  auto file_path = filesystem::get_normal_path(file_path_);
+
+  if (notebook_index == 1 && !split)
+    toggle_split();
+
+  // Use canonical path to follow symbolic links
+  boost::system::error_code ec;
+  auto canonical_file_path = boost::filesystem::canonical(file_path, ec);
+  if (ec)
+    canonical_file_path = file_path;
+  for (size_t c = 0; c < size(); c++) {
+    if (canonical_file_path == source_views[c]->canonical_file_path) {
+      auto notebook_page = get_notebook_page(c);
+      notebooks[notebook_page.first].set_current_page(notebook_page.second);
+      focus_view(source_views[c]);
+      return;
     }
+  }
 
-    if (boost::filesystem::exists(file_path)) {
-        std::ifstream can_read(file_path.string());
-        if (!can_read) {
-            Terminal::get().print("Error: could not open " + file_path.string() + "\n", true);
-            return;
-        }
-        can_read.close();
+  if (boost::filesystem::exists(file_path)) {
+    std::ifstream can_read(file_path.string());
+    if (!can_read) {
+      Terminal::get().print("Error: could not open " + file_path.string() + "\n", true);
+      return;
     }
+    can_read.close();
+  }
 
-    auto last_view = get_current_view();
+  auto last_view = get_current_view();
 
-    auto language = Source::guess_language(file_path);
+  auto language = Source::guess_language(file_path);
 
-    std::string language_protocol_language_id;
-    if (language) {
-        language_protocol_language_id = language->get_id();
-        if (language_protocol_language_id == "js") {
-            if (file_path.extension() == ".ts")
-                language_protocol_language_id = "typescript";
-            else
-                language_protocol_language_id = "javascript";
-        }
+  std::string language_protocol_language_id;
+  if (language) {
+    language_protocol_language_id = language->get_id();
+    if (language_protocol_language_id == "js") {
+      if (file_path.extension() == ".ts")
+        language_protocol_language_id = "typescript";
+      else
+        language_protocol_language_id = "javascript";
     }
-
-    if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr" || language->get_id() == "c" ||
-                     language->get_id() == "cpp" || language->get_id() == "objc"))
-        source_views.emplace_back(new Source::ClangView(file_path, language));
-    else if (language && !language_protocol_language_id.empty() &&
-             !filesystem::find_executable(language_protocol_language_id + "-language-server").empty())
-        source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id));
-    else
-        source_views.emplace_back(new Source::GenericView(file_path, language));
-
-    auto source_view = source_views.back();
-
-    source_view->scroll_to_cursor_delayed = [this](Source::BaseView *view, bool center, bool show_tooltips) {
-        while (Gtk::Main::events_pending())
-            Gtk::Main::iteration(false);
-        if (get_current_view() == view) {
-            if (center)
-                view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-            else
-                view->scroll_to(view->get_buffer()->get_insert());
-            if (!show_tooltips)
-                view->hide_tooltips();
+  }
+
+  if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr" || language->get_id() == "c" ||
+                   language->get_id() == "cpp" || language->get_id() == "objc"))
+    source_views.emplace_back(new Source::ClangView(file_path, language));
+  else if (language && !language_protocol_language_id.empty() &&
+           !filesystem::find_executable(language_protocol_language_id + "-language-server").empty())
+    source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id));
+  else
+    source_views.emplace_back(new Source::GenericView(file_path, language));
+
+  auto source_view = source_views.back();
+
+  source_view->scroll_to_cursor_delayed = [this](Source::BaseView *view, bool center, bool show_tooltips) {
+    while (Gtk::Main::events_pending())
+      Gtk::Main::iteration(false);
+    if (get_current_view() == view) {
+      if (center)
+        view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+      else
+        view->scroll_to(view->get_buffer()->get_insert());
+      if (!show_tooltips)
+        view->hide_tooltips();
+    }
+  };
+  source_view->update_status_location = [this](Source::BaseView *view) {
+    if (get_current_view() == view) {
+      auto iter = view->get_buffer()->get_insert()->get_iter();
+      status_location.set_text(
+          " " + std::to_string(iter.get_line() + 1) + ":" + std::to_string(iter.get_line_offset() + 1));
+    }
+  };
+  source_view->update_status_file_path = [this](Source::BaseView *view) {
+    if (get_current_view() == view)
+      status_file_path.set_text(' ' + filesystem::get_short_path(view->file_path).string());
+  };
+  source_view->update_status_branch = [this](Source::BaseView *view) {
+    if (get_current_view() == view) {
+      if (!view->status_branch.empty())
+        status_branch.set_text(" (" + view->status_branch + ")");
+      else
+        status_branch.set_text("");
+    }
+  };
+  source_view->update_status_diagnostics = [this](Source::BaseView *view) {
+    if (get_current_view() == view) {
+      std::string diagnostic_info;
+
+      auto num_warnings = std::get<0>(view->status_diagnostics);
+      auto num_errors = std::get<1>(view->status_diagnostics);
+      auto num_fix_its = std::get<2>(view->status_diagnostics);
+      if (num_warnings > 0 || num_errors > 0 || num_fix_its > 0) {
+        auto normal_color = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
+        Gdk::RGBA yellow;
+        yellow.set_rgba(1.0, 1.0, 0.2);
+        double factor = 0.5;
+        yellow.set_red(normal_color.get_red() + factor * (yellow.get_red() - normal_color.get_red()));
+        yellow.set_green(normal_color.get_green() + factor * (yellow.get_green() - normal_color.get_green()));
+        yellow.set_blue(normal_color.get_blue() + factor * (yellow.get_blue() - normal_color.get_blue()));
+        Gdk::RGBA red;
+        red.set_rgba(1.0, 0.0, 0.0);
+        factor = 0.5;
+        red.set_red(normal_color.get_red() + factor * (red.get_red() - normal_color.get_red()));
+        red.set_green(normal_color.get_green() + factor * (red.get_green() - normal_color.get_green()));
+        red.set_blue(normal_color.get_blue() + factor * (red.get_blue() - normal_color.get_blue()));
+        Gdk::RGBA green;
+        green.set_rgba(0.0, 1.0, 0.0);
+        factor = 0.4;
+        green.set_red(normal_color.get_red() + factor * (green.get_red() - normal_color.get_red()));
+        green.set_green(normal_color.get_green() + factor * (green.get_green() - normal_color.get_green()));
+        green.set_blue(normal_color.get_blue() + factor * (green.get_blue() - normal_color.get_blue()));
+
+        std::stringstream yellow_ss, red_ss, green_ss;
+        yellow_ss << std::hex << std::setfill('0') << std::setw(2) << (int) (yellow.get_red_u() >> 8)
+                  << std::setw(2) << (int) (yellow.get_green_u() >> 8) << std::setw(2)
+                  << (int) (yellow.get_blue_u() >> 8);
+        red_ss << std::hex << std::setfill('0') << std::setw(2) << (int) (red.get_red_u() >> 8) << std::setw(2)
+               << (int) (red.get_green_u() >> 8) << std::setw(2) << (int) (red.get_blue_u() >> 8);
+        green_ss << std::hex << std::setfill('0') << std::setw(2) << (int) (green.get_red_u() >> 8)
+                 << std::setw(2) << (int) (green.get_green_u() >> 8) << std::setw(2)
+                 << (int) (green.get_blue_u() >> 8);
+        if (num_warnings > 0) {
+          diagnostic_info += "<span color='#" + yellow_ss.str() + "'>";
+          diagnostic_info += std::to_string(num_warnings) + " warning";
+          if (num_warnings > 1)
+            diagnostic_info += 's';
+          diagnostic_info += "</span>";
         }
-    };
-    source_view->update_status_location = [this](Source::BaseView *view) {
-        if (get_current_view() == view) {
-            auto iter = view->get_buffer()->get_insert()->get_iter();
-            status_location.set_text(
-                    " " + std::to_string(iter.get_line() + 1) + ":" + std::to_string(iter.get_line_offset() + 1));
+        if (num_errors > 0) {
+          if (num_warnings > 0)
+            diagnostic_info += ", ";
+          diagnostic_info += "<span color='#" + red_ss.str() + "'>";
+          diagnostic_info += std::to_string(num_errors) + " error";
+          if (num_errors > 1)
+            diagnostic_info += 's';
+          diagnostic_info += "</span>";
         }
-    };
-    source_view->update_status_file_path = [this](Source::BaseView *view) {
-        if (get_current_view() == view)
-            status_file_path.set_text(' ' + filesystem::get_short_path(view->file_path).string());
-    };
-    source_view->update_status_branch = [this](Source::BaseView *view) {
-        if (get_current_view() == view) {
-            if (!view->status_branch.empty())
-                status_branch.set_text(" (" + view->status_branch + ")");
-            else
-                status_branch.set_text("");
+        if (num_fix_its > 0) {
+          if (num_warnings > 0 || num_errors > 0)
+            diagnostic_info += ", ";
+          diagnostic_info += "<span color='#" + green_ss.str() + "'>";
+          diagnostic_info += std::to_string(num_fix_its) + " fix it";
+          if (num_fix_its > 1)
+            diagnostic_info += 's';
+          diagnostic_info += "</span>";
         }
-    };
-    source_view->update_status_diagnostics = [this](Source::BaseView *view) {
-        if (get_current_view() == view) {
-            std::string diagnostic_info;
-
-            auto num_warnings = std::get<0>(view->status_diagnostics);
-            auto num_errors = std::get<1>(view->status_diagnostics);
-            auto num_fix_its = std::get<2>(view->status_diagnostics);
-            if (num_warnings > 0 || num_errors > 0 || num_fix_its > 0) {
-                auto normal_color = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
-                Gdk::RGBA yellow;
-                yellow.set_rgba(1.0, 1.0, 0.2);
-                double factor = 0.5;
-                yellow.set_red(normal_color.get_red() + factor * (yellow.get_red() - normal_color.get_red()));
-                yellow.set_green(normal_color.get_green() + factor * (yellow.get_green() - normal_color.get_green()));
-                yellow.set_blue(normal_color.get_blue() + factor * (yellow.get_blue() - normal_color.get_blue()));
-                Gdk::RGBA red;
-                red.set_rgba(1.0, 0.0, 0.0);
-                factor = 0.5;
-                red.set_red(normal_color.get_red() + factor * (red.get_red() - normal_color.get_red()));
-                red.set_green(normal_color.get_green() + factor * (red.get_green() - normal_color.get_green()));
-                red.set_blue(normal_color.get_blue() + factor * (red.get_blue() - normal_color.get_blue()));
-                Gdk::RGBA green;
-                green.set_rgba(0.0, 1.0, 0.0);
-                factor = 0.4;
-                green.set_red(normal_color.get_red() + factor * (green.get_red() - normal_color.get_red()));
-                green.set_green(normal_color.get_green() + factor * (green.get_green() - normal_color.get_green()));
-                green.set_blue(normal_color.get_blue() + factor * (green.get_blue() - normal_color.get_blue()));
-
-                std::stringstream yellow_ss, red_ss, green_ss;
-                yellow_ss << std::hex << std::setfill('0') << std::setw(2) << (int) (yellow.get_red_u() >> 8)
-                          << std::setw(2) << (int) (yellow.get_green_u() >> 8) << std::setw(2)
-                          << (int) (yellow.get_blue_u() >> 8);
-                red_ss << std::hex << std::setfill('0') << std::setw(2) << (int) (red.get_red_u() >> 8) << std::setw(2)
-                       << (int) (red.get_green_u() >> 8) << std::setw(2) << (int) (red.get_blue_u() >> 8);
-                green_ss << std::hex << std::setfill('0') << std::setw(2) << (int) (green.get_red_u() >> 8)
-                         << std::setw(2) << (int) (green.get_green_u() >> 8) << std::setw(2)
-                         << (int) (green.get_blue_u() >> 8);
-                if (num_warnings > 0) {
-                    diagnostic_info += "<span color='#" + yellow_ss.str() + "'>";
-                    diagnostic_info += std::to_string(num_warnings) + " warning";
-                    if (num_warnings > 1)
-                        diagnostic_info += 's';
-                    diagnostic_info += "</span>";
-                }
-                if (num_errors > 0) {
-                    if (num_warnings > 0)
-                        diagnostic_info += ", ";
-                    diagnostic_info += "<span color='#" + red_ss.str() + "'>";
-                    diagnostic_info += std::to_string(num_errors) + " error";
-                    if (num_errors > 1)
-                        diagnostic_info += 's';
-                    diagnostic_info += "</span>";
-                }
-                if (num_fix_its > 0) {
-                    if (num_warnings > 0 || num_errors > 0)
-                        diagnostic_info += ", ";
-                    diagnostic_info += "<span color='#" + green_ss.str() + "'>";
-                    diagnostic_info += std::to_string(num_fix_its) + " fix it";
-                    if (num_fix_its > 1)
-                        diagnostic_info += 's';
-                    diagnostic_info += "</span>";
-                }
-            }
-            status_diagnostics.set_markup(diagnostic_info);
-        }
-    };
-    source_view->update_status_state = [this](Source::BaseView *view) {
-        if (get_current_view() == view)
-            status_state.set_text(view->status_state + " ");
-    };
-
-    scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
-    hboxes.emplace_back(new Gtk::Box());
-    scrolled_windows.back()->add(*source_view);
-    hboxes.back()->pack_start(*scrolled_windows.back());
-
-    source_maps.emplace_back(Glib::wrap(gtk_source_map_new()));
-    gtk_source_map_set_view(GTK_SOURCE_MAP(source_maps.back()->gobj()), source_view->gobj());
-
-    configure(source_views.size() - 1);
-
-    //Set up tab label
-    tab_labels.emplace_back(new TabLabel([this, source_view]() {
-        auto index = get_index(source_view);
-        if (index != static_cast<size_t>(-1))
-            close(index);
-    }));
-    source_view->update_tab_label = [this](Source::BaseView *view) {
-        std::string title = view->file_path.filename().string();
-        if (view->get_buffer()->get_modified())
-            title += '*';
-        else
-            title += ' ';
-        for (size_t c = 0; c < size(); ++c) {
-            if (source_views[c] == view) {
-                auto &tab_label = tab_labels.at(c);
-                tab_label->label.set_text(title);
-                tab_label->set_tooltip_text(filesystem::get_short_path(view->file_path).string());
-                return;
-            }
+      }
+      status_diagnostics.set_markup(diagnostic_info);
+    }
+  };
+  source_view->update_status_state = [this](Source::BaseView *view) {
+    if (get_current_view() == view)
+      status_state.set_text(view->status_state + " ");
+  };
+
+  scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
+  hboxes.emplace_back(new Gtk::Box());
+  scrolled_windows.back()->add(*source_view);
+  hboxes.back()->pack_start(*scrolled_windows.back());
+
+  source_maps.emplace_back(Glib::wrap(gtk_source_map_new()));
+  gtk_source_map_set_view(GTK_SOURCE_MAP(source_maps.back()->gobj()), source_view->gobj());
+
+  configure(source_views.size() - 1);
+
+  //Set up tab label
+  tab_labels.emplace_back(new TabLabel([this, source_view]() {
+    auto index = get_index(source_view);
+    if (index != static_cast<size_t>(-1))
+      close(index);
+  }));
+  source_view->update_tab_label = [this](Source::BaseView *view) {
+    std::string title = view->file_path.filename().string();
+    if (view->get_buffer()->get_modified())
+      title += '*';
+    else
+      title += ' ';
+    for (size_t c = 0; c < size(); ++c) {
+      if (source_views[c] == view) {
+        auto &tab_label = tab_labels.at(c);
+        tab_label->label.set_text(title);
+        tab_label->set_tooltip_text(filesystem::get_short_path(view->file_path).string());
+        return;
+      }
+    }
+  };
+  source_view->update_tab_label(source_view);
+
+  //Add star on tab label when the page is not saved:
+  source_view->get_buffer()->signal_modified_changed().connect([source_view]() {
+    if (source_view->update_tab_label)
+      source_view->update_tab_label(source_view);
+  });
+
+  //Cursor history
+  auto update_cursor_locations = [this, source_view](const Gtk::TextBuffer::iterator &iter) {
+    bool mark_moved = false;
+    if (current_cursor_location != static_cast<size_t>(-1)) {
+      auto &cursor_location = cursor_locations.at(current_cursor_location);
+      if (cursor_location.view == source_view &&
+          abs(cursor_location.mark->get_iter().get_line() - iter.get_line()) <= 2) {
+        source_view->get_buffer()->move_mark(cursor_location.mark, iter);
+        mark_moved = true;
+      }
+    }
+    if (!mark_moved) {
+      if (current_cursor_location != static_cast<size_t>(-1)) {
+        for (auto it = cursor_locations.begin() + current_cursor_location + 1; it != cursor_locations.end();) {
+          it->view->get_buffer()->delete_mark(it->mark);
+          it = cursor_locations.erase(it);
         }
-    };
-    source_view->update_tab_label(source_view);
-
-    //Add star on tab label when the page is not saved:
-    source_view->get_buffer()->signal_modified_changed().connect([source_view]() {
-        if (source_view->update_tab_label)
-            source_view->update_tab_label(source_view);
-    });
+      }
+      cursor_locations.emplace_back(source_view, source_view->get_buffer()->create_mark(iter));
+      current_cursor_location = cursor_locations.size() - 1;
+    }
 
-    //Cursor history
-    auto update_cursor_locations = [this, source_view](const Gtk::TextBuffer::iterator &iter) {
-        bool mark_moved = false;
-        if (current_cursor_location != static_cast<size_t>(-1)) {
-            auto &cursor_location = cursor_locations.at(current_cursor_location);
-            if (cursor_location.view == source_view &&
-                abs(cursor_location.mark->get_iter().get_line() - iter.get_line()) <= 2) {
-                source_view->get_buffer()->move_mark(cursor_location.mark, iter);
-                mark_moved = true;
-            }
-        }
-        if (!mark_moved) {
-            if (current_cursor_location != static_cast<size_t>(-1)) {
-                for (auto it = cursor_locations.begin() + current_cursor_location + 1; it != cursor_locations.end();) {
-                    it->view->get_buffer()->delete_mark(it->mark);
-                    it = cursor_locations.erase(it);
-                }
-            }
-            cursor_locations.emplace_back(source_view, source_view->get_buffer()->create_mark(iter));
-            current_cursor_location = cursor_locations.size() - 1;
+    // Combine adjacent cursor histories that are similar
+    if (!cursor_locations.empty()) {
+      size_t cursor_locations_index = 1;
+      auto last_it = cursor_locations.begin();
+      for (auto it = cursor_locations.begin() + 1; it != cursor_locations.end();) {
+        if (last_it->view == it->view &&
+            abs(last_it->mark->get_iter().get_line() - it->mark->get_iter().get_line()) <= 2) {
+          last_it->view->get_buffer()->delete_mark(last_it->mark);
+          last_it->mark = it->mark;
+          it = cursor_locations.erase(it);
+          if (current_cursor_location != static_cast<size_t>(-1) &&
+              current_cursor_location > cursor_locations_index)
+            --current_cursor_location;
+        } else {
+          ++it;
+          ++last_it;
+          ++cursor_locations_index;
         }
+      }
+    }
 
-        // Combine adjacent cursor histories that are similar
-        if (!cursor_locations.empty()) {
-            size_t cursor_locations_index = 1;
-            auto last_it = cursor_locations.begin();
-            for (auto it = cursor_locations.begin() + 1; it != cursor_locations.end();) {
-                if (last_it->view == it->view &&
-                    abs(last_it->mark->get_iter().get_line() - it->mark->get_iter().get_line()) <= 2) {
-                    last_it->view->get_buffer()->delete_mark(last_it->mark);
-                    last_it->mark = it->mark;
-                    it = cursor_locations.erase(it);
-                    if (current_cursor_location != static_cast<size_t>(-1) &&
-                        current_cursor_location > cursor_locations_index)
-                        --current_cursor_location;
-                } else {
-                    ++it;
-                    ++last_it;
-                    ++cursor_locations_index;
-                }
-            }
-        }
+    // Remove start of cache if cache limit is exceeded
+    while (cursor_locations.size() > 10) {
+      cursor_locations.begin()->view->get_buffer()->delete_mark(cursor_locations.begin()->mark);
+      cursor_locations.erase(cursor_locations.begin());
+      if (current_cursor_location != static_cast<size_t>(-1))
+        --current_cursor_location;
+    }
 
-        // Remove start of cache if cache limit is exceeded
-        while (cursor_locations.size() > 10) {
-            cursor_locations.begin()->view->get_buffer()->delete_mark(cursor_locations.begin()->mark);
-            cursor_locations.erase(cursor_locations.begin());
-            if (current_cursor_location != static_cast<size_t>(-1))
-                --current_cursor_location;
+    if (current_cursor_location >= cursor_locations.size())
+      current_cursor_location = cursor_locations.size() - 1;
+  };
+  source_view->get_buffer()->signal_mark_set().connect(
+      [this, update_cursor_locations](const Gtk::TextBuffer::iterator &iter,
+                                      const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+        if (mark->get_name() == "insert") {
+          if (disable_next_update_cursor_locations) {
+            disable_next_update_cursor_locations = false;
+            return;
+          }
+          update_cursor_locations(iter);
         }
-
-        if (current_cursor_location >= cursor_locations.size())
-            current_cursor_location = cursor_locations.size() - 1;
-    };
-    source_view->get_buffer()->signal_mark_set().connect(
-            [this, update_cursor_locations](const Gtk::TextBuffer::iterator &iter,
-                                            const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-                if (mark->get_name() == "insert") {
-                    if (disable_next_update_cursor_locations) {
-                        disable_next_update_cursor_locations = false;
-                        return;
-                    }
-                    update_cursor_locations(iter);
-                }
-            });
-    source_view->get_buffer()->signal_changed().connect([source_view, update_cursor_locations] {
-        update_cursor_locations(source_view->get_buffer()->get_insert()->get_iter());
-    });
+      });
+  source_view->get_buffer()->signal_changed().connect([source_view, update_cursor_locations] {
+    update_cursor_locations(source_view->get_buffer()->get_insert()->get_iter());
+  });
 
 #ifdef JUCI_ENABLE_DEBUG
-    if(dynamic_cast<Source::ClangView*>(source_view) || (source_view->language && source_view->language->get_id()=="rust")) {
-      source_view->toggle_breakpoint=[source_view](int line_nr) {
-        if(source_view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_breakpoint").size()>0) {
-          auto start_iter=source_view->get_buffer()->get_iter_at_line(line_nr);
-          auto end_iter=source_view->get_iter_at_line_end(line_nr);
-          source_view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint");
-          source_view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint_and_stop");
-          if(Project::current && Project::debugging)
-            Project::current->debug_remove_breakpoint(source_view->file_path, line_nr+1, source_view->get_buffer()->get_line_count()+1);
-        }
-        else {
-          auto iter=source_view->get_buffer()->get_iter_at_line(line_nr);
-          source_view->get_source_buffer()->create_source_mark("debug_breakpoint", iter);
-          if(source_view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_stop").size()>0)
-            source_view->get_source_buffer()->create_source_mark("debug_breakpoint_and_stop", iter);
-          if(Project::current && Project::debugging)
-            Project::current->debug_add_breakpoint(source_view->file_path, line_nr+1);
-        }
-      };
-    }
+  if(dynamic_cast<Source::ClangView*>(source_view) || (source_view->language && source_view->language->get_id()=="rust")) {
+    source_view->toggle_breakpoint=[source_view](int line_nr) {
+      if(source_view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_breakpoint").size()>0) {
+        auto start_iter=source_view->get_buffer()->get_iter_at_line(line_nr);
+        auto end_iter=source_view->get_iter_at_line_end(line_nr);
+        source_view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint");
+        source_view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint_and_stop");
+        if(Project::current && Project::debugging)
+          Project::current->debug_remove_breakpoint(source_view->file_path, line_nr+1, source_view->get_buffer()->get_line_count()+1);
+      }
+      else {
+        auto iter=source_view->get_buffer()->get_iter_at_line(line_nr);
+        source_view->get_source_buffer()->create_source_mark("debug_breakpoint", iter);
+        if(source_view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_stop").size()>0)
+          source_view->get_source_buffer()->create_source_mark("debug_breakpoint_and_stop", iter);
+        if(Project::current && Project::debugging)
+          Project::current->debug_add_breakpoint(source_view->file_path, line_nr+1);
+      }
+    };
+  }
 #endif
 
-    source_view->signal_focus_in_event().connect([this, source_view](GdkEventFocus *) {
-        set_current_view(source_view);
-        return false;
-    });
-
-    if (notebook_index == static_cast<size_t>(-1)) {
-        if (!split)
-            notebook_index = 0;
-        else if (notebooks[0].get_n_pages() == 0)
-            notebook_index = 0;
-        else if (notebooks[1].get_n_pages() == 0)
-            notebook_index = 1;
-        else if (last_view)
-            notebook_index = get_notebook_page(get_index(last_view)).first;
-    }
-    auto &notebook = notebooks[notebook_index];
-
-    notebook.append_page(*hboxes.back(), *tab_labels.back());
-
-    notebook.set_tab_reorderable(*hboxes.back(), true);
-    notebook.set_tab_detachable(*hboxes.back(), true);
-    show_all_children();
-
-    notebook.set_current_page(notebook.get_n_pages() - 1);
-    last_index = -1;
-    if (last_view) {
-        auto index = get_index(last_view);
-        auto notebook_page = get_notebook_page(index);
-        if (notebook_page.first == notebook_index)
-            last_index = index;
-    }
-
-    set_focus_child(*source_views.back());
-    focus_view(source_view);
+  source_view->signal_focus_in_event().connect([this, source_view](GdkEventFocus *) {
+    set_current_view(source_view);
+    return false;
+  });
+
+  if (notebook_index == static_cast<size_t>(-1)) {
+    if (!split)
+      notebook_index = 0;
+    else if (notebooks[0].get_n_pages() == 0)
+      notebook_index = 0;
+    else if (notebooks[1].get_n_pages() == 0)
+      notebook_index = 1;
+    else if (last_view)
+      notebook_index = get_notebook_page(get_index(last_view)).first;
+  }
+  auto &notebook = notebooks[notebook_index];
+
+  notebook.append_page(*hboxes.back(), *tab_labels.back());
+
+  notebook.set_tab_reorderable(*hboxes.back(), true);
+  notebook.set_tab_detachable(*hboxes.back(), true);
+  show_all_children();
+
+  notebook.set_current_page(notebook.get_n_pages() - 1);
+  last_index = -1;
+  if (last_view) {
+    auto index = get_index(last_view);
+    auto notebook_page = get_notebook_page(index);
+    if (notebook_page.first == notebook_index)
+      last_index = index;
+  }
+
+  set_focus_child(*source_views.back());
+  focus_view(source_view);
 }
 
 void Notebook::configure(size_t index) {
-    auto source_font_description = Pango::FontDescription(Config::get().source.font);
-    auto source_map_font_desc = Pango::FontDescription(
-            static_cast<std::string>(source_font_description.get_family()) + " " + Config::get().source.map_font_size);
-    source_maps.at(index)->override_font(source_map_font_desc);
-    if (Config::get().source.show_map) {
-        if (hboxes.at(index)->get_children().size() == 1)
-            hboxes.at(index)->pack_end(*source_maps.at(index), Gtk::PACK_SHRINK);
-    } else if (hboxes.at(index)->get_children().size() == 2)
-        hboxes.at(index)->remove(*source_maps.at(index));
+  auto source_font_description = Pango::FontDescription(Config::get().source.font);
+  auto source_map_font_desc = Pango::FontDescription(
+      static_cast<std::string>(source_font_description.get_family()) + " " + Config::get().source.map_font_size);
+  source_maps.at(index)->override_font(source_map_font_desc);
+  if (Config::get().source.show_map) {
+    if (hboxes.at(index)->get_children().size() == 1)
+      hboxes.at(index)->pack_end(*source_maps.at(index), Gtk::PACK_SHRINK);
+  } else if (hboxes.at(index)->get_children().size() == 2)
+    hboxes.at(index)->remove(*source_maps.at(index));
 }
 
 bool Notebook::save(size_t index) {
-    if (!source_views[index]->save())
-        return false;
-    Project::on_save(index);
-    return true;
+  if (!source_views[index]->save())
+    return false;
+  Project::on_save(index);
+  return true;
 }
 
 bool Notebook::save_current() {
-    if (auto view = get_current_view())
-        return save(get_index(view));
-    return false;
+  if (auto view = get_current_view())
+    return save(get_index(view));
+  return false;
 }
 
 bool Notebook::close(size_t index) {
-    if (auto view = get_view(index)) {
-        if (view->get_buffer()->get_modified()) {
-            if (!save_modified_dialog(index))
-                return false;
-        }
-        if (view == get_current_view()) {
-            bool focused = false;
-            if (last_index != static_cast<size_t>(-1)) {
-                auto notebook_page = get_notebook_page(last_index);
-                if (notebook_page.first == get_notebook_page(get_index(view)).first) {
-                    focus_view(source_views[last_index]);
-                    notebooks[notebook_page.first].set_current_page(notebook_page.second);
-                    last_index = -1;
-                    focused = true;
-                }
-            }
-            if (!focused) {
-                auto notebook_page = get_notebook_page(get_index(view));
-                if (notebook_page.second > 0)
-                    focus_view(get_view(notebook_page.first, notebook_page.second - 1));
-                else {
-                    size_t notebook_index = notebook_page.first == 0 ? 1 : 0;
-                    if (notebooks[notebook_index].get_n_pages() > 0)
-                        focus_view(get_view(notebook_index, notebooks[notebook_index].get_current_page()));
-                    else
-                        set_current_view(nullptr);
-                }
-            }
-        } else if (index == last_index)
-            last_index = -1;
-        else if (index < last_index && last_index != static_cast<size_t>(-1))
-            last_index--;
-
-        auto notebook_page = get_notebook_page(index);
-        notebooks[notebook_page.first].remove_page(notebook_page.second);
-        source_maps.erase(source_maps.begin() + index);
-
-        if (on_close_page)
-            on_close_page(view);
-
-        delete_cursor_locations(view);
-
-        SelectionDialog::get() = nullptr;
-        CompletionDialog::get() = nullptr;
-
-        if (auto clang_view = dynamic_cast<Source::ClangView *>(view))
-            clang_view->async_delete();
-        else
-            delete view;
-        source_views.erase(source_views.begin() + index);
-        scrolled_windows.erase(scrolled_windows.begin() + index);
-        hboxes.erase(hboxes.begin() + index);
-        tab_labels.erase(tab_labels.begin() + index);
+  if (auto view = get_view(index)) {
+    if (view->get_buffer()->get_modified()) {
+      if (!save_modified_dialog(index))
+        return false;
     }
-    return true;
+    if (view == get_current_view()) {
+      bool focused = false;
+      if (last_index != static_cast<size_t>(-1)) {
+        auto notebook_page = get_notebook_page(last_index);
+        if (notebook_page.first == get_notebook_page(get_index(view)).first) {
+          focus_view(source_views[last_index]);
+          notebooks[notebook_page.first].set_current_page(notebook_page.second);
+          last_index = -1;
+          focused = true;
+        }
+      }
+      if (!focused) {
+        auto notebook_page = get_notebook_page(get_index(view));
+        if (notebook_page.second > 0)
+          focus_view(get_view(notebook_page.first, notebook_page.second - 1));
+        else {
+          size_t notebook_index = notebook_page.first == 0 ? 1 : 0;
+          if (notebooks[notebook_index].get_n_pages() > 0)
+            focus_view(get_view(notebook_index, notebooks[notebook_index].get_current_page()));
+          else
+            set_current_view(nullptr);
+        }
+      }
+    } else if (index == last_index)
+      last_index = -1;
+    else if (index < last_index && last_index != static_cast<size_t>(-1))
+      last_index--;
+
+    auto notebook_page = get_notebook_page(index);
+    notebooks[notebook_page.first].remove_page(notebook_page.second);
+    source_maps.erase(source_maps.begin() + index);
+
+    if (on_close_page)
+      on_close_page(view);
+
+    delete_cursor_locations(view);
+
+    SelectionDialog::get() = nullptr;
+    CompletionDialog::get() = nullptr;
+
+    if (auto clang_view = dynamic_cast<Source::ClangView *>(view))
+      clang_view->async_delete();
+    else
+      delete view;
+    source_views.erase(source_views.begin() + index);
+    scrolled_windows.erase(scrolled_windows.begin() + index);
+    hboxes.erase(hboxes.begin() + index);
+    tab_labels.erase(tab_labels.begin() + index);
+  }
+  return true;
 }
 
 void Notebook::delete_cursor_locations(Source::View *view) {
-    size_t cursor_locations_index = 0;
-    for (auto it = cursor_locations.begin(); it != cursor_locations.end();) {
-        if (it->view == view) {
-            view->get_buffer()->delete_mark(it->mark);
-            it = cursor_locations.erase(it);
-            if (current_cursor_location != static_cast<size_t>(-1) && current_cursor_location > cursor_locations_index)
-                --current_cursor_location;
-        } else {
-            ++it;
-            ++cursor_locations_index;
-        }
+  size_t cursor_locations_index = 0;
+  for (auto it = cursor_locations.begin(); it != cursor_locations.end();) {
+    if (it->view == view) {
+      view->get_buffer()->delete_mark(it->mark);
+      it = cursor_locations.erase(it);
+      if (current_cursor_location != static_cast<size_t>(-1) && current_cursor_location > cursor_locations_index)
+        --current_cursor_location;
+    } else {
+      ++it;
+      ++cursor_locations_index;
     }
-    if (current_cursor_location >= cursor_locations.size())
-        current_cursor_location = cursor_locations.size() - 1;
+  }
+  if (current_cursor_location >= cursor_locations.size())
+    current_cursor_location = cursor_locations.size() - 1;
 }
 
 bool Notebook::close_current() {
-    return close(get_index(get_current_view()));
+  return close(get_index(get_current_view()));
 }
 
 void Notebook::next() {
-    if (auto view = get_current_view()) {
-        auto notebook_page = get_notebook_page(get_index(view));
-        int page = notebook_page.second + 1;
-        if (page >= notebooks[notebook_page.first].get_n_pages())
-            notebooks[notebook_page.first].set_current_page(0);
-        else
-            notebooks[notebook_page.first].set_current_page(page);
-    }
+  if (auto view = get_current_view()) {
+    auto notebook_page = get_notebook_page(get_index(view));
+    int page = notebook_page.second + 1;
+    if (page >= notebooks[notebook_page.first].get_n_pages())
+      notebooks[notebook_page.first].set_current_page(0);
+    else
+      notebooks[notebook_page.first].set_current_page(page);
+  }
 }
 
 void Notebook::previous() {
-    if (auto view = get_current_view()) {
-        auto notebook_page = get_notebook_page(get_index(view));
-        int page = notebook_page.second - 1;
-        if (page < 0)
-            notebooks[notebook_page.first].set_current_page(notebooks[notebook_page.first].get_n_pages() - 1);
-        else
-            notebooks[notebook_page.first].set_current_page(page);
-    }
+  if (auto view = get_current_view()) {
+    auto notebook_page = get_notebook_page(get_index(view));
+    int page = notebook_page.second - 1;
+    if (page < 0)
+      notebooks[notebook_page.first].set_current_page(notebooks[notebook_page.first].get_n_pages() - 1);
+    else
+      notebooks[notebook_page.first].set_current_page(page);
+  }
 }
 
 void Notebook::toggle_split() {
-    if (!split) {
-        pack2(notebooks[1], true, true);
-        set_position(get_width() / 2);
-        show_all();
-        //Make sure the position is correct
-        //TODO: report bug to gtk if it is not fixed in gtk3.22
-        Glib::signal_timeout().connect([this] {
-            set_position(get_width() / 2);
-            return false;
-        }, 200);
-    } else {
-        for (size_t c = size() - 1; c != static_cast<size_t>(-1); --c) {
-            auto notebook_index = get_notebook_page(c).first;
-            if (notebook_index == 1 && !close(c))
-                return;
-        }
-        remove(notebooks[1]);
+  if (!split) {
+    pack2(notebooks[1], true, true);
+    set_position(get_width() / 2);
+    show_all();
+    //Make sure the position is correct
+    //TODO: report bug to gtk if it is not fixed in gtk3.22
+    Glib::signal_timeout().connect([this] {
+      set_position(get_width() / 2);
+      return false;
+    }, 200);
+  } else {
+    for (size_t c = size() - 1; c != static_cast<size_t>(-1); --c) {
+      auto notebook_index = get_notebook_page(c).first;
+      if (notebook_index == 1 && !close(c))
+        return;
     }
-    split = !split;
+    remove(notebooks[1]);
+  }
+  split = !split;
 }
 
 void Notebook::toggle_tabs() {
-    //Show / Hide tabs for each notebook.
-    for (auto &notebook : Notebook::notebooks)
-        notebook.set_show_tabs(!notebook.get_show_tabs());
+  //Show / Hide tabs for each notebook.
+  for (auto &notebook : Notebook::notebooks)
+    notebook.set_show_tabs(!notebook.get_show_tabs());
 }
 
 boost::filesystem::path Notebook::get_current_folder() {
-    if (!Directories::get().path.empty())
-        return Directories::get().path;
-    else if (auto view = get_current_view())
-        return view->file_path.parent_path();
-    else
-        return boost::filesystem::path();
+  if (!Directories::get().path.empty())
+    return Directories::get().path;
+  else if (auto view = get_current_view())
+    return view->file_path.parent_path();
+  else
+    return boost::filesystem::path();
 }
 
 std::vector<std::pair<size_t, Source::View *>> Notebook::get_notebook_views() {
-    std::vector<std::pair<size_t, Source::View *>> notebook_views;
-    for (size_t notebook_index = 0; notebook_index < notebooks.size(); ++notebook_index) {
-        for (int page = 0; page < notebooks[notebook_index].get_n_pages(); ++page) {
-            if (auto view = get_view(notebook_index, page))
-                notebook_views.emplace_back(notebook_index, view);
-        }
+  std::vector<std::pair<size_t, Source::View *>> notebook_views;
+  for (size_t notebook_index = 0; notebook_index < notebooks.size(); ++notebook_index) {
+    for (int page = 0; page < notebooks[notebook_index].get_n_pages(); ++page) {
+      if (auto view = get_view(notebook_index, page))
+        notebook_views.emplace_back(notebook_index, view);
     }
-    return notebook_views;
+  }
+  return notebook_views;
 }
 
 void Notebook::update_status(Source::BaseView *view) {
-    if (view->update_status_location)
-        view->update_status_location(view);
-    if (view->update_status_file_path)
-        view->update_status_file_path(view);
-    if (view->update_status_branch)
-        view->update_status_branch(view);
-    if (view->update_status_diagnostics)
-        view->update_status_diagnostics(view);
-    if (view->update_status_state)
-        view->update_status_state(view);
+  if (view->update_status_location)
+    view->update_status_location(view);
+  if (view->update_status_file_path)
+    view->update_status_file_path(view);
+  if (view->update_status_branch)
+    view->update_status_branch(view);
+  if (view->update_status_diagnostics)
+    view->update_status_diagnostics(view);
+  if (view->update_status_state)
+    view->update_status_state(view);
 }
 
 void Notebook::clear_status() {
-    status_location.set_text("");
-    status_file_path.set_text("");
-    status_branch.set_text("");
-    status_diagnostics.set_text("");
-    status_state.set_text("");
+  status_location.set_text("");
+  status_file_path.set_text("");
+  status_branch.set_text("");
+  status_diagnostics.set_text("");
+  status_state.set_text("");
 }
 
 size_t Notebook::get_index(Source::View *view) {
-    for (size_t c = 0; c < size(); ++c) {
-        if (source_views[c] == view)
-            return c;
-    }
-    return -1;
+  for (size_t c = 0; c < size(); ++c) {
+    if (source_views[c] == view)
+      return c;
+  }
+  return -1;
 }
 
 Source::View *Notebook::get_view(size_t notebook_index, int page) {
-    if (notebook_index == static_cast<size_t>(-1) || notebook_index >= notebooks.size() ||
-        page < 0 || page >= notebooks[notebook_index].get_n_pages())
-        return nullptr;
-    auto hbox = dynamic_cast<Gtk::Box *>(notebooks[notebook_index].get_nth_page(page));
-    auto scrolled_window = dynamic_cast<Gtk::ScrolledWindow *>(hbox->get_children()[0]);
-    return dynamic_cast<Source::View *>(scrolled_window->get_children()[0]);
+  if (notebook_index == static_cast<size_t>(-1) || notebook_index >= notebooks.size() ||
+      page < 0 || page >= notebooks[notebook_index].get_n_pages())
+    return nullptr;
+  auto hbox = dynamic_cast<Gtk::Box *>(notebooks[notebook_index].get_nth_page(page));
+  auto scrolled_window = dynamic_cast<Gtk::ScrolledWindow *>(hbox->get_children()[0]);
+  return dynamic_cast<Source::View *>(scrolled_window->get_children()[0]);
 }
 
 void Notebook::focus_view(Source::View *view) {
-    intermediate_view = view;
-    view->grab_focus();
+  intermediate_view = view;
+  view->grab_focus();
 }
 
 std::pair<size_t, int> Notebook::get_notebook_page(size_t index) {
-    if (index >= hboxes.size())
-        return {-1, -1};
-    for (size_t c = 0; c < notebooks.size(); ++c) {
-        auto page_num = notebooks[c].page_num(*hboxes[index]);
-        if (page_num >= 0)
-            return {c, page_num};
-    }
+  if (index >= hboxes.size())
     return {-1, -1};
+  for (size_t c = 0; c < notebooks.size(); ++c) {
+    auto page_num = notebooks[c].page_num(*hboxes[index]);
+    if (page_num >= 0)
+      return {c, page_num};
+  }
+  return {-1, -1};
 }
 
 void Notebook::set_current_view(Source::View *view) {
-    intermediate_view = nullptr;
-    if (current_view != view) {
-        if (auto view = get_current_view()) {
-            view->hide_tooltips();
-            view->hide_dialogs();
-        }
-        current_view = view;
-        if (view && on_change_page)
-            on_change_page(view);
+  intermediate_view = nullptr;
+  if (current_view != view) {
+    if (auto view = get_current_view()) {
+      view->hide_tooltips();
+      view->hide_dialogs();
     }
+    current_view = view;
+    if (view && on_change_page)
+      on_change_page(view);
+  }
 }
 
 bool Notebook::save_modified_dialog(size_t index) {
-    Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION,
-                              Gtk::BUTTONS_YES_NO);
-    dialog.set_default_response(Gtk::RESPONSE_YES);
-    dialog.set_secondary_text("Do you want to save: " + get_view(index)->file_path.string() + " ?");
-    int result = dialog.run();
-    if (result == Gtk::RESPONSE_YES) {
-        return save(index);
-    } else if (result == Gtk::RESPONSE_NO) {
-        return true;
-    } else {
-        return false;
-    }
+  Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION,
+                            Gtk::BUTTONS_YES_NO);
+  dialog.set_default_response(Gtk::RESPONSE_YES);
+  dialog.set_secondary_text("Do you want to save: " + get_view(index)->file_path.string() + " ?");
+  int result = dialog.run();
+  if (result == Gtk::RESPONSE_YES) {
+    return save(index);
+  } else if (result == Gtk::RESPONSE_NO) {
+    return true;
+  } else {
+    return false;
+  }
 }
diff --git a/src/notebook.h b/src/notebook.h
index 9bf1cdc4..47c89bfb 100644
--- a/src/notebook.h
+++ b/src/notebook.h
@@ -8,106 +8,106 @@
 #include <sigc++/sigc++.h>
 
 class Notebook : public Gtk::Paned {
-    class TabLabel : public Gtk::EventBox {
-    public:
-        TabLabel(std::function<void()> on_close);
+  class TabLabel : public Gtk::EventBox {
+  public:
+    TabLabel(std::function<void()> on_close);
 
-        Gtk::Label label;
-    };
+    Gtk::Label label;
+  };
 
-    class CursorLocation {
-    public:
-        CursorLocation(Source::View *view, Glib::RefPtr<Gtk::TextBuffer::Mark> mark) : view(view), mark(mark) {}
+  class CursorLocation {
+  public:
+    CursorLocation(Source::View *view, Glib::RefPtr<Gtk::TextBuffer::Mark> mark) : view(view), mark(mark) {}
 
-        Source::View *view;
-        Glib::RefPtr<Gtk::TextBuffer::Mark> mark;
-    };
+    Source::View *view;
+    Glib::RefPtr<Gtk::TextBuffer::Mark> mark;
+  };
 
 private:
-    Notebook();
+  Notebook();
 
 public:
-    static Notebook &get() {
-        static Notebook singleton;
-        return singleton;
-    }
+  static Notebook &get() {
+    static Notebook singleton;
+    return singleton;
+  }
 
-    size_t size();
+  size_t size();
 
-    Source::View *get_view(size_t index);
+  Source::View *get_view(size_t index);
 
-    Source::View *get_current_view();
+  Source::View *get_current_view();
 
-    std::vector<Source::View *> &get_views();
+  std::vector<Source::View *> &get_views();
 
-    void open(const boost::filesystem::path &file_path, size_t notebook_index = -1);
+  void open(const boost::filesystem::path &file_path, size_t notebook_index = -1);
 
-    void configure(size_t index);
+  void configure(size_t index);
 
-    bool save(size_t index);
+  bool save(size_t index);
 
-    bool save_current();
+  bool save_current();
 
-    bool close(size_t index);
+  bool close(size_t index);
 
-    bool close_current();
+  bool close_current();
 
-    void next();
+  void next();
 
-    void previous();
+  void previous();
 
-    void toggle_split();
+  void toggle_split();
 
-    /// Hide/Show tabs.
-    void toggle_tabs();
+  /// Hide/Show tabs.
+  void toggle_tabs();
 
-    boost::filesystem::path get_current_folder();
+  boost::filesystem::path get_current_folder();
 
-    std::vector<std::pair<size_t, Source::View *>> get_notebook_views();
+  std::vector<std::pair<size_t, Source::View *>> get_notebook_views();
 
-    Gtk::Label status_location;
-    Gtk::Label status_file_path;
-    Gtk::Label status_branch;
-    Gtk::Label status_diagnostics;
-    Gtk::Label status_state;
+  Gtk::Label status_location;
+  Gtk::Label status_file_path;
+  Gtk::Label status_branch;
+  Gtk::Label status_diagnostics;
+  Gtk::Label status_state;
 
-    void update_status(Source::BaseView *view);
+  void update_status(Source::BaseView *view);
 
-    void clear_status();
+  void clear_status();
 
-    std::function<void(Source::View *)> on_change_page;
-    std::function<void(Source::View *)> on_close_page;
+  std::function<void(Source::View *)> on_change_page;
+  std::function<void(Source::View *)> on_close_page;
 
-    /// Cursor history
-    std::vector<CursorLocation> cursor_locations;
-    size_t current_cursor_location = -1;
-    bool disable_next_update_cursor_locations = false;
+  /// Cursor history
+  std::vector<CursorLocation> cursor_locations;
+  size_t current_cursor_location = -1;
+  bool disable_next_update_cursor_locations = false;
 
-    void delete_cursor_locations(Source::View *view);
+  void delete_cursor_locations(Source::View *view);
 
 private:
-    size_t get_index(Source::View *view);
+  size_t get_index(Source::View *view);
 
-    Source::View *get_view(size_t notebook_index, int page);
+  Source::View *get_view(size_t notebook_index, int page);
 
-    void focus_view(Source::View *view);
+  void focus_view(Source::View *view);
 
-    std::pair<size_t, int> get_notebook_page(size_t index);
+  std::pair<size_t, int> get_notebook_page(size_t index);
 
-    std::vector<Gtk::Notebook> notebooks;
-    std::vector<Source::View *> source_views; //Is NOT freed in destructor, this is intended for quick program exit.
-    std::vector<std::unique_ptr<Gtk::Widget> > source_maps;
-    std::vector<std::unique_ptr<Gtk::ScrolledWindow> > scrolled_windows;
-    std::vector<std::unique_ptr<Gtk::Box> > hboxes;
-    std::vector<std::unique_ptr<TabLabel> > tab_labels;
+  std::vector<Gtk::Notebook> notebooks;
+  std::vector<Source::View *> source_views; //Is NOT freed in destructor, this is intended for quick program exit.
+  std::vector<std::unique_ptr<Gtk::Widget> > source_maps;
+  std::vector<std::unique_ptr<Gtk::ScrolledWindow> > scrolled_windows;
+  std::vector<std::unique_ptr<Gtk::Box> > hboxes;
+  std::vector<std::unique_ptr<TabLabel> > tab_labels;
 
-    bool split = false;
-    size_t last_index = -1;
+  bool split = false;
+  size_t last_index = -1;
 
-    void set_current_view(Source::View *view);
+  void set_current_view(Source::View *view);
 
-    Source::View *current_view = nullptr;
-    Source::View *intermediate_view = nullptr;
+  Source::View *current_view = nullptr;
+  Source::View *intermediate_view = nullptr;
 
-    bool save_modified_dialog(size_t index);
+  bool save_modified_dialog(size_t index);
 };
diff --git a/src/project.cc b/src/project.cc
index 61976041..e1bb2e61 100644
--- a/src/project.cc
+++ b/src/project.cc
@@ -30,231 +30,231 @@ std::shared_ptr<Project::Base> Project::current;
 std::unique_ptr<Project::DebugOptions> Project::Base::debug_options;
 
 Gtk::Label &Project::debug_status_label() {
-    static Gtk::Label label;
-    return label;
+  static Gtk::Label label;
+  return label;
 }
 
 void Project::save_files(const boost::filesystem::path &path) {
-    for (size_t c = 0; c < Notebook::get().size(); c++) {
-        auto view = Notebook::get().get_view(c);
-        if (view->get_buffer()->get_modified()) {
-            if (filesystem::file_in_path(view->file_path, path))
-                Notebook::get().save(c);
-        }
+  for (size_t c = 0; c < Notebook::get().size(); c++) {
+    auto view = Notebook::get().get_view(c);
+    if (view->get_buffer()->get_modified()) {
+      if (filesystem::file_in_path(view->file_path, path))
+        Notebook::get().save(c);
     }
+  }
 }
 
 void Project::on_save(size_t index) {
-    auto view = Notebook::get().get_view(index);
-    if (!view)
-        return;
-    boost::filesystem::path build_path;
-    if (view->language && view->language->get_id() == "cmake") {
-        if (view->file_path.filename() == "CMakeLists.txt")
-            build_path = view->file_path;
-        else
-            build_path = filesystem::find_file_in_path_parents("CMakeLists.txt", view->file_path.parent_path());
-    } else if (view->language && view->language->get_id() == "meson") {
-        if (view->file_path.filename() == "meson.build")
-            build_path = view->file_path;
-        else
-            build_path = filesystem::find_file_in_path_parents("meson.build", view->file_path.parent_path());
-    }
+  auto view = Notebook::get().get_view(index);
+  if (!view)
+    return;
+  boost::filesystem::path build_path;
+  if (view->language && view->language->get_id() == "cmake") {
+    if (view->file_path.filename() == "CMakeLists.txt")
+      build_path = view->file_path;
+    else
+      build_path = filesystem::find_file_in_path_parents("CMakeLists.txt", view->file_path.parent_path());
+  } else if (view->language && view->language->get_id() == "meson") {
+    if (view->file_path.filename() == "meson.build")
+      build_path = view->file_path;
+    else
+      build_path = filesystem::find_file_in_path_parents("meson.build", view->file_path.parent_path());
+  }
 
-    if (!build_path.empty()) {
-        auto build = Build::create(build_path);
-        if (dynamic_cast<CMakeBuild *>(build.get()) || dynamic_cast<MesonBuild *>(build.get())) {
-            build->update_default(true);
-            Usages::Clang::erase_all_caches_for_project(build->project_path, build->get_default_path());
-            boost::system::error_code ec;
-            if (boost::filesystem::exists(build->get_debug_path()), ec)
-                build->update_debug(true);
-
-            for (size_t c = 0; c < Notebook::get().size(); c++) {
-                auto source_view = Notebook::get().get_view(c);
-                if (auto source_clang_view = dynamic_cast<Source::ClangView *>(source_view)) {
-                    if (filesystem::file_in_path(source_clang_view->file_path, build->project_path))
-                        source_clang_view->full_reparse_needed = true;
-                }
-            }
+  if (!build_path.empty()) {
+    auto build = Build::create(build_path);
+    if (dynamic_cast<CMakeBuild *>(build.get()) || dynamic_cast<MesonBuild *>(build.get())) {
+      build->update_default(true);
+      Usages::Clang::erase_all_caches_for_project(build->project_path, build->get_default_path());
+      boost::system::error_code ec;
+      if (boost::filesystem::exists(build->get_debug_path()), ec)
+        build->update_debug(true);
+
+      for (size_t c = 0; c < Notebook::get().size(); c++) {
+        auto source_view = Notebook::get().get_view(c);
+        if (auto source_clang_view = dynamic_cast<Source::ClangView *>(source_view)) {
+          if (filesystem::file_in_path(source_clang_view->file_path, build->project_path))
+            source_clang_view->full_reparse_needed = true;
         }
+      }
     }
+  }
 }
 
 void Project::debug_update_status(const std::string &new_debug_status) {
-    debug_status = new_debug_status;
-    if (debug_status.empty())
-        debug_status_label().set_text("");
-    else
-        debug_status_label().set_text(debug_status);
-    debug_activate_menu_items();
+  debug_status = new_debug_status;
+  if (debug_status.empty())
+    debug_status_label().set_text("");
+  else
+    debug_status_label().set_text(debug_status);
+  debug_activate_menu_items();
 }
 
 void Project::debug_activate_menu_items() {
-    auto &menu = Menu::get();
-    auto view = Notebook::get().get_current_view();
-    menu.actions["debug_stop"]->set_enabled(!debug_status.empty());
-    menu.actions["debug_kill"]->set_enabled(!debug_status.empty());
-    menu.actions["debug_step_over"]->set_enabled(!debug_status.empty());
-    menu.actions["debug_step_into"]->set_enabled(!debug_status.empty());
-    menu.actions["debug_step_out"]->set_enabled(!debug_status.empty());
-    menu.actions["debug_backtrace"]->set_enabled(!debug_status.empty());
-    menu.actions["debug_show_variables"]->set_enabled(!debug_status.empty());
-    menu.actions["debug_run_command"]->set_enabled(!debug_status.empty());
-    menu.actions["debug_toggle_breakpoint"]->set_enabled(view && view->toggle_breakpoint);
-    menu.actions["debug_goto_stop"]->set_enabled(!debug_status.empty());
+  auto &menu = Menu::get();
+  auto view = Notebook::get().get_current_view();
+  menu.actions["debug_stop"]->set_enabled(!debug_status.empty());
+  menu.actions["debug_kill"]->set_enabled(!debug_status.empty());
+  menu.actions["debug_step_over"]->set_enabled(!debug_status.empty());
+  menu.actions["debug_step_into"]->set_enabled(!debug_status.empty());
+  menu.actions["debug_step_out"]->set_enabled(!debug_status.empty());
+  menu.actions["debug_backtrace"]->set_enabled(!debug_status.empty());
+  menu.actions["debug_show_variables"]->set_enabled(!debug_status.empty());
+  menu.actions["debug_run_command"]->set_enabled(!debug_status.empty());
+  menu.actions["debug_toggle_breakpoint"]->set_enabled(view && view->toggle_breakpoint);
+  menu.actions["debug_goto_stop"]->set_enabled(!debug_status.empty());
 }
 
 void Project::debug_update_stop() {
-    if (!debug_last_stop_file_path.empty()) {
-        for (size_t c = 0; c < Notebook::get().size(); c++) {
-            auto view = Notebook::get().get_view(c);
-            if (view->file_path == debug_last_stop_file_path) {
-                view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(),
-                                                               "debug_stop");
-                view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(),
-                                                               "debug_breakpoint_and_stop");
-                break;
-            }
-        }
-    }
-    //Add debug stop source mark
-    debug_last_stop_file_path.clear();
+  if (!debug_last_stop_file_path.empty()) {
     for (size_t c = 0; c < Notebook::get().size(); c++) {
-        auto view = Notebook::get().get_view(c);
-        if (view->file_path == debug_stop.first) {
-            if (debug_stop.second.first < view->get_buffer()->get_line_count()) {
-                auto iter = view->get_buffer()->get_iter_at_line(debug_stop.second.first);
-                view->get_source_buffer()->create_source_mark("debug_stop", iter);
-                if (view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size() > 0)
-                    view->get_source_buffer()->create_source_mark("debug_breakpoint_and_stop", iter);
-                debug_last_stop_file_path = debug_stop.first;
-            }
-            break;
-        }
+      auto view = Notebook::get().get_view(c);
+      if (view->file_path == debug_last_stop_file_path) {
+        view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(),
+                                                       "debug_stop");
+        view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(),
+                                                       "debug_breakpoint_and_stop");
+        break;
+      }
     }
+  }
+  //Add debug stop source mark
+  debug_last_stop_file_path.clear();
+  for (size_t c = 0; c < Notebook::get().size(); c++) {
+    auto view = Notebook::get().get_view(c);
+    if (view->file_path == debug_stop.first) {
+      if (debug_stop.second.first < view->get_buffer()->get_line_count()) {
+        auto iter = view->get_buffer()->get_iter_at_line(debug_stop.second.first);
+        view->get_source_buffer()->create_source_mark("debug_stop", iter);
+        if (view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size() > 0)
+          view->get_source_buffer()->create_source_mark("debug_breakpoint_and_stop", iter);
+        debug_last_stop_file_path = debug_stop.first;
+      }
+      break;
+    }
+  }
 }
 
 std::shared_ptr<Project::Base> Project::create() {
-    std::unique_ptr<Project::Build> build;
-
-    if (auto view = Notebook::get().get_current_view()) {
-        build = Build::create(view->file_path);
-        if (view->language) {
-            auto language_id = view->language->get_id();
-            if (language_id == "markdown")
-                return std::shared_ptr<Project::Base>(new Project::Markdown(std::move(build)));
-            if (language_id == "python")
-                return std::shared_ptr<Project::Base>(new Project::Python(std::move(build)));
-            if (language_id == "js")
-                return std::shared_ptr<Project::Base>(new Project::JavaScript(std::move(build)));
-            if (language_id == "html")
-                return std::shared_ptr<Project::Base>(new Project::HTML(std::move(build)));
-        }
-    } else
-        build = Build::create(Directories::get().path);
-
-    if (dynamic_cast<CMakeBuild *>(build.get()) || dynamic_cast<MesonBuild *>(build.get()))
-        return std::shared_ptr<Project::Base>(new Project::Clang(std::move(build)));
-    else if (dynamic_cast<CargoBuild *>(build.get()))
-        return std::shared_ptr<Project::Base>(new Project::Rust(std::move(build)));
-    else if (dynamic_cast<NpmBuild *>(build.get()))
+  std::unique_ptr<Project::Build> build;
+
+  if (auto view = Notebook::get().get_current_view()) {
+    build = Build::create(view->file_path);
+    if (view->language) {
+      auto language_id = view->language->get_id();
+      if (language_id == "markdown")
+        return std::shared_ptr<Project::Base>(new Project::Markdown(std::move(build)));
+      if (language_id == "python")
+        return std::shared_ptr<Project::Base>(new Project::Python(std::move(build)));
+      if (language_id == "js")
         return std::shared_ptr<Project::Base>(new Project::JavaScript(std::move(build)));
-    else
-        return std::shared_ptr<Project::Base>(new Project::Base(std::move(build)));
+      if (language_id == "html")
+        return std::shared_ptr<Project::Base>(new Project::HTML(std::move(build)));
+    }
+  } else
+    build = Build::create(Directories::get().path);
+
+  if (dynamic_cast<CMakeBuild *>(build.get()) || dynamic_cast<MesonBuild *>(build.get()))
+    return std::shared_ptr<Project::Base>(new Project::Clang(std::move(build)));
+  else if (dynamic_cast<CargoBuild *>(build.get()))
+    return std::shared_ptr<Project::Base>(new Project::Rust(std::move(build)));
+  else if (dynamic_cast<NpmBuild *>(build.get()))
+    return std::shared_ptr<Project::Base>(new Project::JavaScript(std::move(build)));
+  else
+    return std::shared_ptr<Project::Base>(new Project::Base(std::move(build)));
 }
 
 std::pair<std::string, std::string> Project::Base::get_run_arguments() {
-    Info::get().print("Could not find a supported project");
-    return {"", ""};
+  Info::get().print("Could not find a supported project");
+  return {"", ""};
 }
 
 void Project::Base::compile() {
-    Info::get().print("Could not find a supported project");
+  Info::get().print("Could not find a supported project");
 }
 
 void Project::Base::compile_and_run() {
-    Info::get().print("Could not find a supported project");
+  Info::get().print("Could not find a supported project");
 }
 
 void Project::Base::recreate_build() {
-    Info::get().print("Could not find a supported project");
+  Info::get().print("Could not find a supported project");
 }
 
 void Project::Base::show_symbols() {
-    auto view = Notebook::get().get_current_view();
-
-    boost::filesystem::path search_path;
-    if (view)
-        search_path = view->file_path.parent_path();
-    else if (!Directories::get().path.empty())
-        search_path = Directories::get().path;
-    else {
-        boost::system::error_code ec;
-        search_path = boost::filesystem::current_path(ec);
-        if (ec) {
-            Terminal::get().print("Error: could not find current path\n", true);
-            return;
-        }
+  auto view = Notebook::get().get_current_view();
+
+  boost::filesystem::path search_path;
+  if (view)
+    search_path = view->file_path.parent_path();
+  else if (!Directories::get().path.empty())
+    search_path = Directories::get().path;
+  else {
+    boost::system::error_code ec;
+    search_path = boost::filesystem::current_path(ec);
+    if (ec) {
+      Terminal::get().print("Error: could not find current path\n", true);
+      return;
     }
-    auto pair = Ctags::get_result(search_path);
+  }
+  auto pair = Ctags::get_result(search_path);
 
-    auto path = std::move(pair.first);
-    auto stream = std::move(pair.second);
-    stream->seekg(0, std::ios::end);
-    if (stream->tellg() == 0) {
-        Info::get().print("No symbols found in current project");
-        return;
-    }
-    stream->seekg(0, std::ios::beg);
+  auto path = std::move(pair.first);
+  auto stream = std::move(pair.second);
+  stream->seekg(0, std::ios::end);
+  if (stream->tellg() == 0) {
+    Info::get().print("No symbols found in current project");
+    return;
+  }
+  stream->seekg(0, std::ios::beg);
 
-    if (view) {
-        auto dialog_iter = view->get_iter_for_dialog();
-        SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-    } else
-        SelectionDialog::create(true, true);
+  if (view) {
+    auto dialog_iter = view->get_iter_for_dialog();
+    SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+  } else
+    SelectionDialog::create(true, true);
 
-    std::vector<Source::Offset> rows;
+  std::vector<Source::Offset> rows;
 
-    std::string line;
-    while (std::getline(*stream, line)) {
-        auto location = Ctags::get_location(line, true);
+  std::string line;
+  while (std::getline(*stream, line)) {
+    auto location = Ctags::get_location(line, true);
 
-        std::string row =
-                location.file_path.string() + ":" + std::to_string(location.line + 1) + ": " + location.source;
-        rows.emplace_back(Source::Offset(location.line, location.index, location.file_path));
-        SelectionDialog::get()->add_row(row);
-    }
+    std::string row =
+        location.file_path.string() + ":" + std::to_string(location.line + 1) + ": " + location.source;
+    rows.emplace_back(Source::Offset(location.line, location.index, location.file_path));
+    SelectionDialog::get()->add_row(row);
+  }
 
-    if (rows.size() == 0)
-        return;
-    SelectionDialog::get()->on_select = [rows = std::move(rows), path = std::move(path)](unsigned int index,
-                                                                                         const std::string &text,
-                                                                                         bool hide_window) {
-        if (index >= rows.size())
-            return;
-        auto offset = rows[index];
-        auto full_path = path / offset.file_path;
-        if (!boost::filesystem::is_regular_file(full_path))
-            return;
-        Notebook::get().open(full_path);
-        auto view = Notebook::get().get_current_view();
-        view->place_cursor_at_line_index(offset.line, offset.index);
-        view->scroll_to_cursor_delayed(view, true, false);
-        view->hide_tooltips();
-    };
-    if (view)
-        view->hide_tooltips();
-    SelectionDialog::get()->show();
+  if (rows.size() == 0)
+    return;
+  SelectionDialog::get()->on_select = [rows = std::move(rows), path = std::move(path)](unsigned int index,
+                                                                                       const std::string &text,
+                                                                                       bool hide_window) {
+    if (index >= rows.size())
+      return;
+    auto offset = rows[index];
+    auto full_path = path / offset.file_path;
+    if (!boost::filesystem::is_regular_file(full_path))
+      return;
+    Notebook::get().open(full_path);
+    auto view = Notebook::get().get_current_view();
+    view->place_cursor_at_line_index(offset.line, offset.index);
+    view->scroll_to_cursor_delayed(view, true, false);
+    view->hide_tooltips();
+  };
+  if (view)
+    view->hide_tooltips();
+  SelectionDialog::get()->show();
 }
 
 std::pair<std::string, std::string> Project::Base::debug_get_run_arguments() {
-    Info::get().print("Could not find a supported project");
-    return {"", ""};
+  Info::get().print("Could not find a supported project");
+  return {"", ""};
 }
 
 void Project::Base::debug_start() {
-    Info::get().print("Could not find a supported project");
+  Info::get().print("Could not find a supported project");
 }
 
 #ifdef JUCI_ENABLE_DEBUG
@@ -671,371 +671,371 @@ void Project::LLDB::debug_cancel() {
 #endif
 
 void Project::LanguageProtocol::show_symbols() {
-    if (build->project_path.empty()) {
-        Info::get().print("Could not find project folder");
-        return;
-    }
+  if (build->project_path.empty()) {
+    Info::get().print("Could not find project folder");
+    return;
+  }
 
-    auto language_id = get_language_id();
-    auto executable_name = language_id + "-language-server";
-    if (filesystem::find_executable(executable_name).empty()) {
-        Info::get().print("Executable " + executable_name + " not found");
-        return;
-    }
+  auto language_id = get_language_id();
+  auto executable_name = language_id + "-language-server";
+  if (filesystem::find_executable(executable_name).empty()) {
+    Info::get().print("Executable " + executable_name + " not found");
+    return;
+  }
 
-    auto project_path = std::make_shared<boost::filesystem::path>(build->project_path);
+  auto project_path = std::make_shared<boost::filesystem::path>(build->project_path);
 
-    auto client = ::LanguageProtocol::Client::get(*project_path, language_id);
-    auto capabilities = client->initialize(nullptr);
+  auto client = ::LanguageProtocol::Client::get(*project_path, language_id);
+  auto capabilities = client->initialize(nullptr);
 
-    if (!capabilities.workspace_symbol) {
-        Info::get().print("Language server does not support workspace/symbol");
-        return;
-    }
+  if (!capabilities.workspace_symbol) {
+    Info::get().print("Language server does not support workspace/symbol");
+    return;
+  }
 
-    auto view = Notebook::get().get_current_view();
-    if (view) {
-        auto dialog_iter = view->get_iter_for_dialog();
-        SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-    } else
-        SelectionDialog::create(true, true);
-
-    SelectionDialog::get()->on_hide = [] {
-        SelectionDialog::get()->on_search_entry_changed = nullptr; // To delete client object
-    };
+  auto view = Notebook::get().get_current_view();
+  if (view) {
+    auto dialog_iter = view->get_iter_for_dialog();
+    SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+  } else
+    SelectionDialog::create(true, true);
 
-    auto offsets = std::make_shared<std::vector<Source::Offset>>();
-    SelectionDialog::get()->on_search_entry_changed = [client, project_path, offsets](const std::string &text) {
-        if (text.size() > 1)
-            return;
-        else {
-            offsets->clear();
-            SelectionDialog::get()->erase_rows();
-            if (text.empty())
-                return;
-        }
-        std::vector<std::string> names;
-        std::promise<void> result_processed;
-        client->write_request(nullptr, "workspace/symbol", "\"query\":\"" + text + "\"",
-                              [&result_processed, &names, offsets, project_path](
-                                      const boost::property_tree::ptree &result, bool error) {
-                                  if (!error) {
-                                      for (auto it = result.begin(); it != result.end(); ++it) {
-                                          auto name = it->second.get<std::string>("name", "");
-                                          if (!name.empty()) {
-                                              auto location_it = it->second.find("location");
-                                              if (location_it != it->second.not_found()) {
-                                                  auto file = location_it->second.get<std::string>("uri", "");
-                                                  if (file.size() > 7) {
-                                                      file.erase(0, 7);
-                                                      auto range_it = location_it->second.find("range");
-                                                      if (range_it != location_it->second.not_found()) {
-                                                          auto start_it = range_it->second.find("start");
-                                                          if (start_it != range_it->second.not_found()) {
-                                                              try {
-                                                                  offsets->emplace_back(Source::Offset(
-                                                                          start_it->second.get<unsigned>("line"),
-                                                                          start_it->second.get<unsigned>("character"),
-                                                                          file));
-                                                                  names.emplace_back(name);
-                                                              }
-                                                              catch (...) {}
-                                                          }
-                                                      }
-                                                  }
-                                              }
+  SelectionDialog::get()->on_hide = [] {
+    SelectionDialog::get()->on_search_entry_changed = nullptr; // To delete client object
+  };
+
+  auto offsets = std::make_shared<std::vector<Source::Offset>>();
+  SelectionDialog::get()->on_search_entry_changed = [client, project_path, offsets](const std::string &text) {
+    if (text.size() > 1)
+      return;
+    else {
+      offsets->clear();
+      SelectionDialog::get()->erase_rows();
+      if (text.empty())
+        return;
+    }
+    std::vector<std::string> names;
+    std::promise<void> result_processed;
+    client->write_request(nullptr, "workspace/symbol", "\"query\":\"" + text + "\"",
+                          [&result_processed, &names, offsets, project_path](
+                              const boost::property_tree::ptree &result, bool error) {
+                            if (!error) {
+                              for (auto it = result.begin(); it != result.end(); ++it) {
+                                auto name = it->second.get<std::string>("name", "");
+                                if (!name.empty()) {
+                                  auto location_it = it->second.find("location");
+                                  if (location_it != it->second.not_found()) {
+                                    auto file = location_it->second.get<std::string>("uri", "");
+                                    if (file.size() > 7) {
+                                      file.erase(0, 7);
+                                      auto range_it = location_it->second.find("range");
+                                      if (range_it != location_it->second.not_found()) {
+                                        auto start_it = range_it->second.find("start");
+                                        if (start_it != range_it->second.not_found()) {
+                                          try {
+                                            offsets->emplace_back(Source::Offset(
+                                                start_it->second.get<unsigned>("line"),
+                                                start_it->second.get<unsigned>("character"),
+                                                file));
+                                            names.emplace_back(name);
                                           }
+                                          catch (...) {}
+                                        }
                                       }
+                                    }
                                   }
-                                  result_processed.set_value();
-                              });
-        result_processed.get_future().get();
-        for (size_t c = 0; c < offsets->size() && c < names.size(); ++c)
-            SelectionDialog::get()->add_row(
-                    filesystem::get_relative_path((*offsets)[c].file_path, *project_path).string() + ':' +
-                    std::to_string((*offsets)[c].line + 1) + ':' + std::to_string((*offsets)[c].index + 1) + ": " +
-                    names[c]);
-    };
-
-    SelectionDialog::get()->on_select = [offsets](unsigned int index, const std::string &text, bool hide_window) {
-        auto &offset = (*offsets)[index];
-        if (!boost::filesystem::is_regular_file(offset.file_path))
-            return;
-        Notebook::get().open(offset.file_path);
-        auto view = Notebook::get().get_current_view();
-        view->place_cursor_at_line_offset(offset.line, offset.index);
-        view->scroll_to_cursor_delayed(view, true, false);
-        view->hide_tooltips();
-    };
-
-    if (view)
-        view->hide_tooltips();
-    SelectionDialog::get()->show();
+                                }
+                              }
+                            }
+                            result_processed.set_value();
+                          });
+    result_processed.get_future().get();
+    for (size_t c = 0; c < offsets->size() && c < names.size(); ++c)
+      SelectionDialog::get()->add_row(
+          filesystem::get_relative_path((*offsets)[c].file_path, *project_path).string() + ':' +
+          std::to_string((*offsets)[c].line + 1) + ':' + std::to_string((*offsets)[c].index + 1) + ": " +
+          names[c]);
+  };
+
+  SelectionDialog::get()->on_select = [offsets](unsigned int index, const std::string &text, bool hide_window) {
+    auto &offset = (*offsets)[index];
+    if (!boost::filesystem::is_regular_file(offset.file_path))
+      return;
+    Notebook::get().open(offset.file_path);
+    auto view = Notebook::get().get_current_view();
+    view->place_cursor_at_line_offset(offset.line, offset.index);
+    view->scroll_to_cursor_delayed(view, true, false);
+    view->hide_tooltips();
+  };
+
+  if (view)
+    view->hide_tooltips();
+  SelectionDialog::get()->show();
 }
 
 std::pair<std::string, std::string> Project::Clang::get_run_arguments() {
-    auto build_path = build->get_default_path();
-    if (build_path.empty())
-        return {"", ""};
-
-    auto project_path = build->project_path.string();
-    auto run_arguments_it = run_arguments.find(project_path);
-    std::string arguments;
-    if (run_arguments_it != run_arguments.end())
-        arguments = run_arguments_it->second;
-
-    if (arguments.empty()) {
-        auto view = Notebook::get().get_current_view();
-        auto executable = build->get_executable(view ? view->file_path : Directories::get().path);
-
-        if (!executable.empty())
-            arguments = filesystem::escape_argument(filesystem::get_short_path(executable).string());
-        else
-            arguments = filesystem::escape_argument(filesystem::get_short_path(build->get_default_path()).string());
-    }
+  auto build_path = build->get_default_path();
+  if (build_path.empty())
+    return {"", ""};
+
+  auto project_path = build->project_path.string();
+  auto run_arguments_it = run_arguments.find(project_path);
+  std::string arguments;
+  if (run_arguments_it != run_arguments.end())
+    arguments = run_arguments_it->second;
 
-    return {project_path, arguments};
+  if (arguments.empty()) {
+    auto view = Notebook::get().get_current_view();
+    auto executable = build->get_executable(view ? view->file_path : Directories::get().path);
+
+    if (!executable.empty())
+      arguments = filesystem::escape_argument(filesystem::get_short_path(executable).string());
+    else
+      arguments = filesystem::escape_argument(filesystem::get_short_path(build->get_default_path()).string());
+  }
+
+  return {project_path, arguments};
 }
 
 void Project::Clang::compile() {
-    auto default_build_path = build->get_default_path();
-    if (default_build_path.empty() || !build->update_default())
-        return;
+  auto default_build_path = build->get_default_path();
+  if (default_build_path.empty() || !build->update_default())
+    return;
 
-    compiling = true;
+  compiling = true;
 
-    if (Config::get().project.clear_terminal_on_compile)
-        Terminal::get().clear();
+  if (Config::get().project.clear_terminal_on_compile)
+    Terminal::get().clear();
 
-    Terminal::get().print("Compiling project " + filesystem::get_short_path(build->project_path).string() + "\n");
-    Terminal::get().async_process(build->get_compile_command(), default_build_path, [](int exit_status) {
-        compiling = false;
-    });
+  Terminal::get().print("Compiling project " + filesystem::get_short_path(build->project_path).string() + "\n");
+  Terminal::get().async_process(build->get_compile_command(), default_build_path, [](int exit_status) {
+    compiling = false;
+  });
 }
 
 void Project::Clang::compile_and_run() {
-    auto default_build_path = build->get_default_path();
-    if (default_build_path.empty() || !build->update_default())
-        return;
+  auto default_build_path = build->get_default_path();
+  if (default_build_path.empty() || !build->update_default())
+    return;
 
-    auto project_path = build->project_path;
-
-    auto run_arguments_it = run_arguments.find(project_path.string());
-    std::string arguments;
-    if (run_arguments_it != run_arguments.end())
-        arguments = run_arguments_it->second;
-
-    if (arguments.empty()) {
-        auto view = Notebook::get().get_current_view();
-        auto executable = build->get_executable(view ? view->file_path : Directories::get().path);
-        if (executable.empty()) {
-            Terminal::get().print("Warning: could not find executable.\n");
-            Terminal::get().print(
-                    "Solution: either use Project Set Run Arguments, or open a source file within a directory where an executable is defined.\n",
-                    true);
-            return;
-        }
-        arguments = filesystem::escape_argument(filesystem::get_short_path(executable).string());
+  auto project_path = build->project_path;
+
+  auto run_arguments_it = run_arguments.find(project_path.string());
+  std::string arguments;
+  if (run_arguments_it != run_arguments.end())
+    arguments = run_arguments_it->second;
+
+  if (arguments.empty()) {
+    auto view = Notebook::get().get_current_view();
+    auto executable = build->get_executable(view ? view->file_path : Directories::get().path);
+    if (executable.empty()) {
+      Terminal::get().print("Warning: could not find executable.\n");
+      Terminal::get().print(
+          "Solution: either use Project Set Run Arguments, or open a source file within a directory where an executable is defined.\n",
+          true);
+      return;
     }
+    arguments = filesystem::escape_argument(filesystem::get_short_path(executable).string());
+  }
 
-    compiling = true;
-
-    if (Config::get().project.clear_terminal_on_compile)
-        Terminal::get().clear();
-
-    Terminal::get().print("Compiling and running " + arguments + "\n");
-    Terminal::get().async_process(build->get_compile_command(), default_build_path,
-                                  [arguments, project_path](int exit_status) {
-                                      compiling = false;
-                                      if (exit_status == EXIT_SUCCESS) {
-                                          Terminal::get().async_process(arguments, project_path,
-                                                                        [arguments](int exit_status) {
-                                                                            Terminal::get().async_print(
-                                                                                    arguments + " returned: " +
-                                                                                    std::to_string(exit_status) + '\n');
-                                                                        });
-                                      }
-                                  });
+  compiling = true;
+
+  if (Config::get().project.clear_terminal_on_compile)
+    Terminal::get().clear();
+
+  Terminal::get().print("Compiling and running " + arguments + "\n");
+  Terminal::get().async_process(build->get_compile_command(), default_build_path,
+                                [arguments, project_path](int exit_status) {
+                                  compiling = false;
+                                  if (exit_status == EXIT_SUCCESS) {
+                                    Terminal::get().async_process(arguments, project_path,
+                                                                  [arguments](int exit_status) {
+                                                                    Terminal::get().async_print(
+                                                                        arguments + " returned: " +
+                                                                        std::to_string(exit_status) + '\n');
+                                                                  });
+                                  }
+                                });
 }
 
 void Project::Clang::recreate_build() {
-    if (build->project_path.empty())
-        return;
-    auto default_build_path = build->get_default_path();
-    if (default_build_path.empty())
-        return;
+  if (build->project_path.empty())
+    return;
+  auto default_build_path = build->get_default_path();
+  if (default_build_path.empty())
+    return;
 
-    auto debug_build_path = build->get_debug_path();
-    bool has_default_build = boost::filesystem::exists(default_build_path);
-    bool has_debug_build = !debug_build_path.empty() && boost::filesystem::exists(debug_build_path);
-
-    if (has_default_build || has_debug_build) {
-        Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(Notebook::get().get_toplevel()), "Recreate Build", false,
-                                  Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
-        dialog.set_default_response(Gtk::RESPONSE_NO);
-        std::string message = "Are you sure you want to recreate ";
-        if (has_default_build)
-            message += default_build_path.string();
-        if (has_debug_build) {
-            if (has_default_build)
-                message += " and ";
-            message += debug_build_path.string();
-        }
-        dialog.set_secondary_text(message + "?");
-        if (dialog.run() != Gtk::RESPONSE_YES)
-            return;
-        Usages::Clang::erase_all_caches_for_project(build->project_path, default_build_path);
-        try {
-            if (has_default_build)
-                boost::filesystem::remove_all(default_build_path);
-            if (has_debug_build)
-                boost::filesystem::remove_all(debug_build_path);
-        }
-        catch (const std::exception &e) {
-            Terminal::get().print(std::string("Error: could not remove build: ") + e.what() + "\n", true);
-            return;
-        }
+  auto debug_build_path = build->get_debug_path();
+  bool has_default_build = boost::filesystem::exists(default_build_path);
+  bool has_debug_build = !debug_build_path.empty() && boost::filesystem::exists(debug_build_path);
+
+  if (has_default_build || has_debug_build) {
+    Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(Notebook::get().get_toplevel()), "Recreate Build", false,
+                              Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
+    dialog.set_default_response(Gtk::RESPONSE_NO);
+    std::string message = "Are you sure you want to recreate ";
+    if (has_default_build)
+      message += default_build_path.string();
+    if (has_debug_build) {
+      if (has_default_build)
+        message += " and ";
+      message += debug_build_path.string();
+    }
+    dialog.set_secondary_text(message + "?");
+    if (dialog.run() != Gtk::RESPONSE_YES)
+      return;
+    Usages::Clang::erase_all_caches_for_project(build->project_path, default_build_path);
+    try {
+      if (has_default_build)
+        boost::filesystem::remove_all(default_build_path);
+      if (has_debug_build)
+        boost::filesystem::remove_all(debug_build_path);
+    }
+    catch (const std::exception &e) {
+      Terminal::get().print(std::string("Error: could not remove build: ") + e.what() + "\n", true);
+      return;
     }
+  }
 
-    build->update_default(true);
-    if (has_debug_build)
-        build->update_debug(true);
+  build->update_default(true);
+  if (has_debug_build)
+    build->update_debug(true);
 
-    for (size_t c = 0; c < Notebook::get().size(); c++) {
-        auto source_view = Notebook::get().get_view(c);
-        if (auto source_clang_view = dynamic_cast<Source::ClangView *>(source_view)) {
-            if (filesystem::file_in_path(source_clang_view->file_path, build->project_path))
-                source_clang_view->full_reparse_needed = true;
-        }
+  for (size_t c = 0; c < Notebook::get().size(); c++) {
+    auto source_view = Notebook::get().get_view(c);
+    if (auto source_clang_view = dynamic_cast<Source::ClangView *>(source_view)) {
+      if (filesystem::file_in_path(source_clang_view->file_path, build->project_path))
+        source_clang_view->full_reparse_needed = true;
     }
+  }
 
-    if (auto view = Notebook::get().get_current_view()) {
-        if (view->full_reparse_needed)
-            view->full_reparse();
-    }
+  if (auto view = Notebook::get().get_current_view()) {
+    if (view->full_reparse_needed)
+      view->full_reparse();
+  }
 }
 
 Project::Markdown::~Markdown() {
-    if (!last_temp_path.empty()) {
-        boost::filesystem::remove(last_temp_path);
-        last_temp_path = boost::filesystem::path();
-    }
+  if (!last_temp_path.empty()) {
+    boost::filesystem::remove(last_temp_path);
+    last_temp_path = boost::filesystem::path();
+  }
 }
 
 void Project::Markdown::compile_and_run() {
-    if (!last_temp_path.empty()) {
-        boost::filesystem::remove(last_temp_path);
-        last_temp_path = boost::filesystem::path();
-    }
+  if (!last_temp_path.empty()) {
+    boost::filesystem::remove(last_temp_path);
+    last_temp_path = boost::filesystem::path();
+  }
 
-    std::stringstream stdin_stream, stdout_stream;
-    auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, "command -v grip");
-    if (exit_status == 0) {
-        auto command = "grip -b " + filesystem::escape_argument(
-                filesystem::get_short_path(Notebook::get().get_current_view()->file_path).string());
-        Terminal::get().print("Running: " + command + " in a quiet background process\n");
-        Terminal::get().async_process(command, "", nullptr, true);
-    } else
-        Terminal::get().print("Warning: install grip to preview Markdown files\n");
+  std::stringstream stdin_stream, stdout_stream;
+  auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, "command -v grip");
+  if (exit_status == 0) {
+    auto command = "grip -b " + filesystem::escape_argument(
+        filesystem::get_short_path(Notebook::get().get_current_view()->file_path).string());
+    Terminal::get().print("Running: " + command + " in a quiet background process\n");
+    Terminal::get().async_process(command, "", nullptr, true);
+  } else
+    Terminal::get().print("Warning: install grip to preview Markdown files\n");
 }
 
 void Project::Python::compile_and_run() {
-    auto command = Config::get().project.python_command + ' ' + filesystem::escape_argument(
-            filesystem::get_short_path(Notebook::get().get_current_view()->file_path).string());
-    Terminal::get().print("Running " + command + "\n");
-    Terminal::get().async_process(command, Notebook::get().get_current_view()->file_path.parent_path(),
-                                  [command](int exit_status) {
-                                      Terminal::get().async_print(
-                                              command + " returned: " + std::to_string(exit_status) + '\n');
-                                  });
+  auto command = Config::get().project.python_command + ' ' + filesystem::escape_argument(
+      filesystem::get_short_path(Notebook::get().get_current_view()->file_path).string());
+  Terminal::get().print("Running " + command + "\n");
+  Terminal::get().async_process(command, Notebook::get().get_current_view()->file_path.parent_path(),
+                                [command](int exit_status) {
+                                  Terminal::get().async_print(
+                                      command + " returned: " + std::to_string(exit_status) + '\n');
+                                });
 }
 
 void Project::JavaScript::compile_and_run() {
-    std::string command;
-    boost::filesystem::path path;
-    if (!build->project_path.empty()) {
-        command = "npm start";
-        path = build->project_path;
-    } else {
-        auto view = Notebook::get().get_current_view();
-        if (!view) {
-            Info::get().print("No executable found");
-            return;
-        }
-        command = "node --harmony " + filesystem::escape_argument(filesystem::get_short_path(view->file_path).string());
-        path = view->file_path.parent_path();
+  std::string command;
+  boost::filesystem::path path;
+  if (!build->project_path.empty()) {
+    command = "npm start";
+    path = build->project_path;
+  } else {
+    auto view = Notebook::get().get_current_view();
+    if (!view) {
+      Info::get().print("No executable found");
+      return;
     }
-    Terminal::get().print("Running " + command + "\n");
-    Terminal::get().async_process(command, path, [command](int exit_status) {
-        Terminal::get().async_print(command + " returned: " + std::to_string(exit_status) + '\n');
-    });
+    command = "node --harmony " + filesystem::escape_argument(filesystem::get_short_path(view->file_path).string());
+    path = view->file_path.parent_path();
+  }
+  Terminal::get().print("Running " + command + "\n");
+  Terminal::get().async_process(command, path, [command](int exit_status) {
+    Terminal::get().async_print(command + " returned: " + std::to_string(exit_status) + '\n');
+  });
 }
 
 void Project::HTML::compile_and_run() {
-    auto uri = Notebook::get().get_current_view()->file_path.string();
+  auto uri = Notebook::get().get_current_view()->file_path.string();
 #ifdef __APPLE__
-    Terminal::get().process("open "+filesystem::escape_argument(uri));
+  Terminal::get().process("open "+filesystem::escape_argument(uri));
 #else
 #ifdef __linux
-    uri="file://"+uri;
+  uri="file://"+uri;
 #endif
-    GError *error = nullptr;
+  GError *error = nullptr;
 #if GTK_VERSION_GE(3, 22)
-    gtk_show_uri_on_window(nullptr, uri.c_str(), GDK_CURRENT_TIME, &error);
+  gtk_show_uri_on_window(nullptr, uri.c_str(), GDK_CURRENT_TIME, &error);
 #else
-    gtk_show_uri(nullptr, uri.c_str(), GDK_CURRENT_TIME, &error);
+  gtk_show_uri(nullptr, uri.c_str(), GDK_CURRENT_TIME, &error);
 #endif
-    g_clear_error(&error);
+  g_clear_error(&error);
 #endif
 }
 
 std::pair<std::string, std::string> Project::Rust::get_run_arguments() {
-    auto project_path = build->project_path.string();
-    auto run_arguments_it = run_arguments.find(project_path);
-    std::string arguments;
-    if (run_arguments_it != run_arguments.end())
-        arguments = run_arguments_it->second;
+  auto project_path = build->project_path.string();
+  auto run_arguments_it = run_arguments.find(project_path);
+  std::string arguments;
+  if (run_arguments_it != run_arguments.end())
+    arguments = run_arguments_it->second;
 
-    if (arguments.empty())
-        arguments = filesystem::get_short_path(build->get_executable(project_path)).string();
+  if (arguments.empty())
+    arguments = filesystem::get_short_path(build->get_executable(project_path)).string();
 
-    return {project_path, arguments};
+  return {project_path, arguments};
 }
 
 void Project::Rust::compile() {
-    compiling = true;
+  compiling = true;
 
-    if (Config::get().project.clear_terminal_on_compile)
-        Terminal::get().clear();
+  if (Config::get().project.clear_terminal_on_compile)
+    Terminal::get().clear();
 
-    Terminal::get().print("Compiling project " + filesystem::get_short_path(build->project_path).string() + "\n");
+  Terminal::get().print("Compiling project " + filesystem::get_short_path(build->project_path).string() + "\n");
 
-    auto command = build->get_compile_command();
-    Terminal::get().async_process(command, build->project_path, [](int exit_status) {
-        compiling = false;
-    });
+  auto command = build->get_compile_command();
+  Terminal::get().async_process(command, build->project_path, [](int exit_status) {
+    compiling = false;
+  });
 }
 
 void Project::Rust::compile_and_run() {
-    compiling = true;
-
-    if (Config::get().project.clear_terminal_on_compile)
-        Terminal::get().clear();
-
-    auto arguments = get_run_arguments().second;
-    Terminal::get().print("Compiling and running " + arguments + "\n");
-
-    auto self = this->shared_from_this();
-    Terminal::get().async_process(build->get_compile_command(), build->project_path,
-                                  [self, arguments = std::move(arguments)](int exit_status) {
-                                      compiling = false;
-                                      if (exit_status == EXIT_SUCCESS) {
-                                          Terminal::get().async_process(arguments, self->build->project_path,
-                                                                        [arguments](int exit_status) {
-                                                                            Terminal::get().async_print(
-                                                                                    arguments + " returned: " +
-                                                                                    std::to_string(exit_status) + '\n');
-                                                                        });
-                                      }
-                                  });
+  compiling = true;
+
+  if (Config::get().project.clear_terminal_on_compile)
+    Terminal::get().clear();
+
+  auto arguments = get_run_arguments().second;
+  Terminal::get().print("Compiling and running " + arguments + "\n");
+
+  auto self = this->shared_from_this();
+  Terminal::get().async_process(build->get_compile_command(), build->project_path,
+                                [self, arguments = std::move(arguments)](int exit_status) {
+                                  compiling = false;
+                                  if (exit_status == EXIT_SUCCESS) {
+                                    Terminal::get().async_process(arguments, self->build->project_path,
+                                                                  [arguments](int exit_status) {
+                                                                    Terminal::get().async_print(
+                                                                        arguments + " returned: " +
+                                                                        std::to_string(exit_status) + '\n');
+                                                                  });
+                                  }
+                                });
 }
diff --git a/src/project.h b/src/project.h
index 82c100ce..5a8c020f 100644
--- a/src/project.h
+++ b/src/project.h
@@ -10,200 +10,200 @@
 #include "project_build.h"
 
 namespace Project {
-    class DebugRunArguments {
-    public:
-        std::string arguments;
-        bool remote_enabled;
-        std::string remote_host_port;
-    };
+  class DebugRunArguments {
+  public:
+    std::string arguments;
+    bool remote_enabled;
+    std::string remote_host_port;
+  };
 
-    class DebugOptions : public Gtk::Popover {
-    public:
-        DebugOptions() : Gtk::Popover(), vbox(Gtk::Orientation::ORIENTATION_VERTICAL) { add(vbox); }
+  class DebugOptions : public Gtk::Popover {
+  public:
+    DebugOptions() : Gtk::Popover(), vbox(Gtk::Orientation::ORIENTATION_VERTICAL) { add(vbox); }
 
-        Gtk::Box vbox;
-    };
+    Gtk::Box vbox;
+  };
 
-    Gtk::Label &debug_status_label();
+  Gtk::Label &debug_status_label();
 
-    void save_files(const boost::filesystem::path &path);
+  void save_files(const boost::filesystem::path &path);
 
-    void on_save(size_t index);
+  void on_save(size_t index);
 
-    extern boost::filesystem::path debug_last_stop_file_path;
-    extern std::unordered_map<std::string, std::string> run_arguments;
-    extern std::unordered_map<std::string, DebugRunArguments> debug_run_arguments;
-    extern std::atomic<bool> compiling;
-    extern std::atomic<bool> debugging;
-    extern std::pair<boost::filesystem::path, std::pair<int, int> > debug_stop;
-    extern std::string debug_status;
+  extern boost::filesystem::path debug_last_stop_file_path;
+  extern std::unordered_map<std::string, std::string> run_arguments;
+  extern std::unordered_map<std::string, DebugRunArguments> debug_run_arguments;
+  extern std::atomic<bool> compiling;
+  extern std::atomic<bool> debugging;
+  extern std::pair<boost::filesystem::path, std::pair<int, int> > debug_stop;
+  extern std::string debug_status;
 
-    void debug_update_status(const std::string &new_debug_status);
+  void debug_update_status(const std::string &new_debug_status);
 
-    void debug_activate_menu_items();
+  void debug_activate_menu_items();
 
-    void debug_update_stop();
+  void debug_update_stop();
 
-    class Base : public std::enable_shared_from_this<Base> {
-    protected:
-        static std::unique_ptr<DebugOptions> debug_options;
-    public:
-        Base() {}
+  class Base : public std::enable_shared_from_this<Base> {
+  protected:
+    static std::unique_ptr<DebugOptions> debug_options;
+  public:
+    Base() {}
 
-        Base(std::unique_ptr<Build> &&build) : build(std::move(build)) {}
+    Base(std::unique_ptr<Build> &&build) : build(std::move(build)) {}
 
-        virtual ~Base() {}
+    virtual ~Base() {}
 
-        std::unique_ptr<Build> build;
+    std::unique_ptr<Build> build;
 
-        Dispatcher dispatcher;
+    Dispatcher dispatcher;
 
-        virtual std::pair<std::string, std::string> get_run_arguments();
+    virtual std::pair<std::string, std::string> get_run_arguments();
 
-        virtual void compile();
+    virtual void compile();
 
-        virtual void compile_and_run();
+    virtual void compile_and_run();
 
-        virtual void recreate_build();
+    virtual void recreate_build();
 
-        virtual void show_symbols();
+    virtual void show_symbols();
 
-        virtual std::pair<std::string, std::string> debug_get_run_arguments();
+    virtual std::pair<std::string, std::string> debug_get_run_arguments();
 
-        virtual Project::DebugOptions *debug_get_options() { return nullptr; }
+    virtual Project::DebugOptions *debug_get_options() { return nullptr; }
 
-        Tooltips debug_variable_tooltips;
+    Tooltips debug_variable_tooltips;
 
-        virtual void debug_start();
+    virtual void debug_start();
 
-        virtual void debug_continue() {}
+    virtual void debug_continue() {}
 
-        virtual void debug_stop() {}
+    virtual void debug_stop() {}
 
-        virtual void debug_kill() {}
+    virtual void debug_kill() {}
 
-        virtual void debug_step_over() {}
+    virtual void debug_step_over() {}
 
-        virtual void debug_step_into() {}
+    virtual void debug_step_into() {}
 
-        virtual void debug_step_out() {}
+    virtual void debug_step_out() {}
 
-        virtual void debug_backtrace() {}
+    virtual void debug_backtrace() {}
 
-        virtual void debug_show_variables() {}
+    virtual void debug_show_variables() {}
 
-        virtual void debug_run_command(const std::string &command) {}
+    virtual void debug_run_command(const std::string &command) {}
 
-        virtual void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {}
+    virtual void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {}
 
-        virtual void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {}
+    virtual void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {}
 
-        virtual bool debug_is_running() { return false; }
+    virtual bool debug_is_running() { return false; }
 
-        virtual void debug_write(const std::string &buffer) {}
+    virtual void debug_write(const std::string &buffer) {}
 
-        virtual void debug_cancel() {}
-    };
+    virtual void debug_cancel() {}
+  };
 
-    class LLDB : public virtual Base {
-    public:
-        LLDB() {}
+  class LLDB : public virtual Base {
+  public:
+    LLDB() {}
 
-        ~LLDB() { dispatcher.disconnect(); }
+    ~LLDB() { dispatcher.disconnect(); }
 
 #ifdef JUCI_ENABLE_DEBUG
-        std::pair<std::string, std::string> debug_get_run_arguments() override;
-        Project::DebugOptions *debug_get_options() override;
-        void debug_start() override;
-        void debug_continue() override;
-        void debug_stop() override;
-        void debug_kill() override;
-        void debug_step_over() override;
-        void debug_step_into() override;
-        void debug_step_out() override;
-        void debug_backtrace() override;
-        void debug_show_variables() override;
-        void debug_run_command(const std::string &command) override;
-        void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) override;
-        void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) override;
-        bool debug_is_running() override;
-        void debug_write(const std::string &buffer) override;
-        void debug_cancel() override;
+    std::pair<std::string, std::string> debug_get_run_arguments() override;
+    Project::DebugOptions *debug_get_options() override;
+    void debug_start() override;
+    void debug_continue() override;
+    void debug_stop() override;
+    void debug_kill() override;
+    void debug_step_over() override;
+    void debug_step_into() override;
+    void debug_step_out() override;
+    void debug_backtrace() override;
+    void debug_show_variables() override;
+    void debug_run_command(const std::string &command) override;
+    void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) override;
+    void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) override;
+    bool debug_is_running() override;
+    void debug_write(const std::string &buffer) override;
+    void debug_cancel() override;
 #endif
-    };
+  };
 
-    class LanguageProtocol : public virtual Base {
-    public:
-        LanguageProtocol() {}
+  class LanguageProtocol : public virtual Base {
+  public:
+    LanguageProtocol() {}
 
-        virtual std::string get_language_id()=0;
+    virtual std::string get_language_id()=0;
 
-        void show_symbols() override;
-    };
+    void show_symbols() override;
+  };
 
-    class Clang : public LLDB {
-    public:
-        Clang(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+  class Clang : public LLDB {
+  public:
+    Clang(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
 
-        std::pair<std::string, std::string> get_run_arguments() override;
+    std::pair<std::string, std::string> get_run_arguments() override;
 
-        void compile() override;
+    void compile() override;
 
-        void compile_and_run() override;
+    void compile_and_run() override;
 
-        void recreate_build() override;
-    };
+    void recreate_build() override;
+  };
 
-    class Markdown : public Base {
-    public:
-        Markdown(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+  class Markdown : public Base {
+  public:
+    Markdown(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
 
-        ~Markdown();
+    ~Markdown();
 
-        boost::filesystem::path last_temp_path;
+    boost::filesystem::path last_temp_path;
 
-        void compile_and_run() override;
-    };
+    void compile_and_run() override;
+  };
 
-    class Python : public LanguageProtocol {
-    public:
-        Python(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+  class Python : public LanguageProtocol {
+  public:
+    Python(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
 
-        void compile_and_run() override;
+    void compile_and_run() override;
 
-        std::string get_language_id() override { return "python"; }
-    };
+    std::string get_language_id() override { return "python"; }
+  };
 
-    class JavaScript : public LanguageProtocol {
-    public:
-        JavaScript(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+  class JavaScript : public LanguageProtocol {
+  public:
+    JavaScript(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
 
-        void compile_and_run() override;
+    void compile_and_run() override;
 
-        std::string get_language_id() override { return "javascript"; }
-    };
+    std::string get_language_id() override { return "javascript"; }
+  };
 
-    class HTML : public Base {
-    public:
-        HTML(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+  class HTML : public Base {
+  public:
+    HTML(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
 
-        void compile_and_run() override;
-    };
+    void compile_and_run() override;
+  };
 
-    class Rust : public LLDB, public LanguageProtocol {
-    public:
-        Rust(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
+  class Rust : public LLDB, public LanguageProtocol {
+  public:
+    Rust(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
 
-        std::pair<std::string, std::string> get_run_arguments() override;
+    std::pair<std::string, std::string> get_run_arguments() override;
 
-        void compile() override;
+    void compile() override;
 
-        void compile_and_run() override;
+    void compile_and_run() override;
 
-        std::string get_language_id() override { return "rust"; }
-    };
+    std::string get_language_id() override { return "rust"; }
+  };
 
-    std::shared_ptr<Base> create();
+  std::shared_ptr<Base> create();
 
-    extern std::shared_ptr<Base> current;
+  extern std::shared_ptr<Base> current;
 };
diff --git a/src/project_build.cc b/src/project_build.cc
index d3294916..a1f6f003 100644
--- a/src/project_build.cc
+++ b/src/project_build.cc
@@ -3,136 +3,136 @@
 #include "filesystem.h"
 
 std::unique_ptr<Project::Build> Project::Build::create(const boost::filesystem::path &path) {
-    auto search_path = boost::filesystem::is_directory(path) ? path : path.parent_path();
-
-    while (true) {
-        if (boost::filesystem::exists(search_path / "CMakeLists.txt")) {
-            std::unique_ptr<Project::Build> build(new CMakeBuild(path));
-            if (!build->project_path.empty())
-                return build;
-            else
-                return std::make_unique<Project::Build>();
-        }
-
-        if (boost::filesystem::exists(search_path / "meson.build")) {
-            std::unique_ptr<Project::Build> build(new MesonBuild(path));
-            if (!build->project_path.empty())
-                return build;
-        }
-
-        if (boost::filesystem::exists(search_path / "Cargo.toml")) {
-            std::unique_ptr<Project::Build> build(new CargoBuild());
-            build->project_path = search_path;
-            return build;
-        }
-
-        if (boost::filesystem::exists(search_path / "package.json")) {
-            std::unique_ptr<Project::Build> build(new NpmBuild());
-            build->project_path = search_path;
-            return build;
-        }
-
-        if (search_path == search_path.root_directory())
-            break;
-        search_path = search_path.parent_path();
+  auto search_path = boost::filesystem::is_directory(path) ? path : path.parent_path();
+
+  while (true) {
+    if (boost::filesystem::exists(search_path / "CMakeLists.txt")) {
+      std::unique_ptr<Project::Build> build(new CMakeBuild(path));
+      if (!build->project_path.empty())
+        return build;
+      else
+        return std::make_unique<Project::Build>();
     }
 
-    return std::make_unique<Project::Build>();
-}
+    if (boost::filesystem::exists(search_path / "meson.build")) {
+      std::unique_ptr<Project::Build> build(new MesonBuild(path));
+      if (!build->project_path.empty())
+        return build;
+    }
 
-boost::filesystem::path Project::Build::get_default_path() {
-    if (project_path.empty())
-        return boost::filesystem::path();
-
-    boost::filesystem::path default_build_path = Config::get().project.default_build_path;
-
-    const std::string path_variable_project_directory_name = "<project_directory_name>";
-    size_t pos = 0;
-    auto default_build_path_string = default_build_path.string();
-    auto path_filename_string = project_path.filename().string();
-    while ((pos = default_build_path_string.find(path_variable_project_directory_name, pos)) != std::string::npos) {
-        default_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
-        pos += path_filename_string.size();
+    if (boost::filesystem::exists(search_path / "Cargo.toml")) {
+      std::unique_ptr<Project::Build> build(new CargoBuild());
+      build->project_path = search_path;
+      return build;
     }
-    if (pos != 0)
-        default_build_path = default_build_path_string;
 
-    if (default_build_path.is_relative())
-        default_build_path = project_path / default_build_path;
+    if (boost::filesystem::exists(search_path / "package.json")) {
+      std::unique_ptr<Project::Build> build(new NpmBuild());
+      build->project_path = search_path;
+      return build;
+    }
 
-    return filesystem::get_normal_path(default_build_path);
-}
+    if (search_path == search_path.root_directory())
+      break;
+    search_path = search_path.parent_path();
+  }
 
-boost::filesystem::path Project::Build::get_debug_path() {
-    if (project_path.empty())
-        return boost::filesystem::path();
-
-    boost::filesystem::path debug_build_path = Config::get().project.debug_build_path;
-
-    const std::string path_variable_project_directory_name = "<project_directory_name>";
-    size_t pos = 0;
-    auto debug_build_path_string = debug_build_path.string();
-    auto path_filename_string = project_path.filename().string();
-    while ((pos = debug_build_path_string.find(path_variable_project_directory_name, pos)) != std::string::npos) {
-        debug_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
-        pos += path_filename_string.size();
-    }
-    if (pos != 0)
-        debug_build_path = debug_build_path_string;
-
-    const std::string path_variable_default_build_path = "<default_build_path>";
-    pos = 0;
-    debug_build_path_string = debug_build_path.string();
-    auto default_build_path = Config::get().project.default_build_path;
-    while ((pos = debug_build_path_string.find(path_variable_default_build_path, pos)) != std::string::npos) {
-        debug_build_path_string.replace(pos, path_variable_default_build_path.size(), default_build_path);
-        pos += default_build_path.size();
-    }
-    if (pos != 0)
-        debug_build_path = debug_build_path_string;
+  return std::make_unique<Project::Build>();
+}
 
-    if (debug_build_path.is_relative())
-        debug_build_path = project_path / debug_build_path;
+boost::filesystem::path Project::Build::get_default_path() {
+  if (project_path.empty())
+    return boost::filesystem::path();
+
+  boost::filesystem::path default_build_path = Config::get().project.default_build_path;
+
+  const std::string path_variable_project_directory_name = "<project_directory_name>";
+  size_t pos = 0;
+  auto default_build_path_string = default_build_path.string();
+  auto path_filename_string = project_path.filename().string();
+  while ((pos = default_build_path_string.find(path_variable_project_directory_name, pos)) != std::string::npos) {
+    default_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
+    pos += path_filename_string.size();
+  }
+  if (pos != 0)
+    default_build_path = default_build_path_string;
+
+  if (default_build_path.is_relative())
+    default_build_path = project_path / default_build_path;
+
+  return filesystem::get_normal_path(default_build_path);
+}
 
-    return filesystem::get_normal_path(debug_build_path);
+boost::filesystem::path Project::Build::get_debug_path() {
+  if (project_path.empty())
+    return boost::filesystem::path();
+
+  boost::filesystem::path debug_build_path = Config::get().project.debug_build_path;
+
+  const std::string path_variable_project_directory_name = "<project_directory_name>";
+  size_t pos = 0;
+  auto debug_build_path_string = debug_build_path.string();
+  auto path_filename_string = project_path.filename().string();
+  while ((pos = debug_build_path_string.find(path_variable_project_directory_name, pos)) != std::string::npos) {
+    debug_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
+    pos += path_filename_string.size();
+  }
+  if (pos != 0)
+    debug_build_path = debug_build_path_string;
+
+  const std::string path_variable_default_build_path = "<default_build_path>";
+  pos = 0;
+  debug_build_path_string = debug_build_path.string();
+  auto default_build_path = Config::get().project.default_build_path;
+  while ((pos = debug_build_path_string.find(path_variable_default_build_path, pos)) != std::string::npos) {
+    debug_build_path_string.replace(pos, path_variable_default_build_path.size(), default_build_path);
+    pos += default_build_path.size();
+  }
+  if (pos != 0)
+    debug_build_path = debug_build_path_string;
+
+  if (debug_build_path.is_relative())
+    debug_build_path = project_path / debug_build_path;
+
+  return filesystem::get_normal_path(debug_build_path);
 }
 
 Project::CMakeBuild::CMakeBuild(const boost::filesystem::path &path) : Project::Build(), cmake(path) {
-    project_path = cmake.get_project_path();
+  project_path = cmake.get_project_path();
 }
 
 bool Project::CMakeBuild::update_default(bool force) {
-    return cmake.update_default_build(get_default_path(), force);
+  return cmake.update_default_build(get_default_path(), force);
 }
 
 bool Project::CMakeBuild::update_debug(bool force) {
-    return cmake.update_debug_build(get_debug_path(), force);
+  return cmake.update_debug_build(get_debug_path(), force);
 }
 
 std::string Project::CMakeBuild::get_compile_command() {
-    return Config::get().project.cmake.compile_command;
+  return Config::get().project.cmake.compile_command;
 }
 
 boost::filesystem::path Project::CMakeBuild::get_executable(const boost::filesystem::path &path) {
-    return cmake.get_executable(get_default_path(), path).string();
+  return cmake.get_executable(get_default_path(), path).string();
 }
 
 Project::MesonBuild::MesonBuild(const boost::filesystem::path &path) : Project::Build(), meson(path) {
-    project_path = meson.get_project_path();
+  project_path = meson.get_project_path();
 }
 
 bool Project::MesonBuild::update_default(bool force) {
-    return meson.update_default_build(get_default_path(), force);
+  return meson.update_default_build(get_default_path(), force);
 }
 
 bool Project::MesonBuild::update_debug(bool force) {
-    return meson.update_debug_build(get_debug_path(), force);
+  return meson.update_debug_build(get_debug_path(), force);
 }
 
 std::string Project::MesonBuild::get_compile_command() {
-    return Config::get().project.meson.compile_command;
+  return Config::get().project.meson.compile_command;
 }
 
 boost::filesystem::path Project::MesonBuild::get_executable(const boost::filesystem::path &path) {
-    return meson.get_executable(get_default_path(), path);
+  return meson.get_executable(get_default_path(), path);
 }
diff --git a/src/project_build.h b/src/project_build.h
index 8720ea30..2709de6e 100644
--- a/src/project_build.h
+++ b/src/project_build.h
@@ -5,75 +5,75 @@
 #include "meson.h"
 
 namespace Project {
-    class Build {
-    public:
-        Build() {}
+  class Build {
+  public:
+    Build() {}
 
-        virtual ~Build() {}
+    virtual ~Build() {}
 
-        boost::filesystem::path project_path;
+    boost::filesystem::path project_path;
 
-        virtual boost::filesystem::path get_default_path();
+    virtual boost::filesystem::path get_default_path();
 
-        virtual bool update_default(bool force = false) { return false; }
+    virtual bool update_default(bool force = false) { return false; }
 
-        virtual boost::filesystem::path get_debug_path();
+    virtual boost::filesystem::path get_debug_path();
 
-        virtual bool update_debug(bool force = false) { return false; }
+    virtual bool update_debug(bool force = false) { return false; }
 
-        virtual std::string get_compile_command() { return std::string(); }
+    virtual std::string get_compile_command() { return std::string(); }
 
-        virtual boost::filesystem::path
-        get_executable(const boost::filesystem::path &path) { return boost::filesystem::path(); }
+    virtual boost::filesystem::path
+    get_executable(const boost::filesystem::path &path) { return boost::filesystem::path(); }
 
-        static std::unique_ptr<Build> create(const boost::filesystem::path &path);
-    };
+    static std::unique_ptr<Build> create(const boost::filesystem::path &path);
+  };
 
-    class CMakeBuild : public Build {
-        ::CMake cmake;
-    public:
-        CMakeBuild(const boost::filesystem::path &path);
+  class CMakeBuild : public Build {
+    ::CMake cmake;
+  public:
+    CMakeBuild(const boost::filesystem::path &path);
 
-        bool update_default(bool force = false) override;
+    bool update_default(bool force = false) override;
 
-        bool update_debug(bool force = false) override;
+    bool update_debug(bool force = false) override;
 
-        std::string get_compile_command() override;
+    std::string get_compile_command() override;
 
-        boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
-    };
+    boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
+  };
 
-    class MesonBuild : public Build {
-        Meson meson;
-    public:
-        MesonBuild(const boost::filesystem::path &path);
+  class MesonBuild : public Build {
+    Meson meson;
+  public:
+    MesonBuild(const boost::filesystem::path &path);
 
-        bool update_default(bool force = false) override;
+    bool update_default(bool force = false) override;
 
-        bool update_debug(bool force = false) override;
+    bool update_debug(bool force = false) override;
 
-        std::string get_compile_command() override;
+    std::string get_compile_command() override;
 
-        boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
-    };
+    boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
+  };
 
-    class CargoBuild : public Build {
-    public:
-        boost::filesystem::path get_default_path() override { return project_path / "target" / "debug"; }
+  class CargoBuild : public Build {
+  public:
+    boost::filesystem::path get_default_path() override { return project_path / "target" / "debug"; }
 
-        bool update_default(bool force = false) override { return true; }
+    bool update_default(bool force = false) override { return true; }
 
-        boost::filesystem::path get_debug_path() override { return get_default_path(); }
+    boost::filesystem::path get_debug_path() override { return get_default_path(); }
 
-        bool update_debug(bool force = false) override { return true; }
+    bool update_debug(bool force = false) override { return true; }
 
-        std::string get_compile_command() override { return "cargo build"; }
+    std::string get_compile_command() override { return "cargo build"; }
 
-        boost::filesystem::path get_executable(const boost::filesystem::path &path) override {
-            return get_debug_path() / project_path.filename();
-        }
-    };
+    boost::filesystem::path get_executable(const boost::filesystem::path &path) override {
+      return get_debug_path() / project_path.filename();
+    }
+  };
 
-    class NpmBuild : public Build {
-    };
+  class NpmBuild : public Build {
+  };
 }
diff --git a/src/selection_dialog.cc b/src/selection_dialog.cc
index 5b0461c3..3fc05217 100644
--- a/src/selection_dialog.cc
+++ b/src/selection_dialog.cc
@@ -2,198 +2,198 @@
 #include <algorithm>
 
 SelectionDialogBase::ListViewText::ListViewText(bool use_markup) : Gtk::TreeView(), use_markup(use_markup) {
-    list_store = Gtk::ListStore::create(column_record);
-    set_model(list_store);
-    append_column("", cell_renderer);
-    if (use_markup)
-        get_column(0)->add_attribute(cell_renderer.property_markup(), column_record.text);
-    else
-        get_column(0)->add_attribute(cell_renderer.property_text(), column_record.text);
-
-    get_selection()->set_mode(Gtk::SelectionMode::SELECTION_BROWSE);
-    set_enable_search(true);
-    set_headers_visible(false);
-    set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL);
-    set_activate_on_single_click(true);
-    set_hover_selection(false);
-    set_rules_hint(true);
+  list_store = Gtk::ListStore::create(column_record);
+  set_model(list_store);
+  append_column("", cell_renderer);
+  if (use_markup)
+    get_column(0)->add_attribute(cell_renderer.property_markup(), column_record.text);
+  else
+    get_column(0)->add_attribute(cell_renderer.property_text(), column_record.text);
+
+  get_selection()->set_mode(Gtk::SelectionMode::SELECTION_BROWSE);
+  set_enable_search(true);
+  set_headers_visible(false);
+  set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL);
+  set_activate_on_single_click(true);
+  set_hover_selection(false);
+  set_rules_hint(true);
 }
 
 void SelectionDialogBase::ListViewText::append(const std::string &value) {
-    auto new_row = list_store->append();
-    new_row->set_value(column_record.text, value);
-    new_row->set_value(column_record.index, size++);
+  auto new_row = list_store->append();
+  new_row->set_value(column_record.text, value);
+  new_row->set_value(column_record.index, size++);
 }
 
 void SelectionDialogBase::ListViewText::erase_rows() {
-    list_store->clear();
-    size = 0;
+  list_store->clear();
+  size = 0;
 }
 
 void SelectionDialogBase::ListViewText::clear() {
-    unset_model();
-    list_store.reset();
-    size = 0;
+  unset_model();
+  list_store.reset();
+  size = 0;
 }
 
 SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark,
                                          bool show_search_entry, bool use_markup) :
-        start_mark(start_mark), text_view(text_view), window(Gtk::WindowType::WINDOW_POPUP),
-        vbox(Gtk::Orientation::ORIENTATION_VERTICAL), list_view_text(use_markup), show_search_entry(show_search_entry) {
-    auto g_application = g_application_get_default();
-    auto gio_application = Glib::wrap(g_application, true);
-    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-    window.set_transient_for(*application->get_active_window());
+    start_mark(start_mark), text_view(text_view), window(Gtk::WindowType::WINDOW_POPUP),
+    vbox(Gtk::Orientation::ORIENTATION_VERTICAL), list_view_text(use_markup), show_search_entry(show_search_entry) {
+  auto g_application = g_application_get_default();
+  auto gio_application = Glib::wrap(g_application, true);
+  auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+  window.set_transient_for(*application->get_active_window());
 
-    window.set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_COMBO);
+  window.set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_COMBO);
 
-    search_entry.signal_changed().connect([this] {
-        if (on_search_entry_changed)
-            on_search_entry_changed(search_entry.get_text());
-    }, false);
+  search_entry.signal_changed().connect([this] {
+    if (on_search_entry_changed)
+      on_search_entry_changed(search_entry.get_text());
+  }, false);
 
-    list_view_text.set_search_entry(search_entry);
+  list_view_text.set_search_entry(search_entry);
 
-    window.set_default_size(0, 0);
-    window.property_decorated() = false;
-    window.set_skip_taskbar_hint(true);
-
-    scrolled_window.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC);
-
-    scrolled_window.add(list_view_text);
-    if (show_search_entry)
-        vbox.pack_start(search_entry, false, false);
-    vbox.pack_start(scrolled_window, true, true);
-    window.add(vbox);
-
-    list_view_text.signal_realize().connect([this]() {
-        auto g_application = g_application_get_default();
-        auto gio_application = Glib::wrap(g_application, true);
-        auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-        auto application_window = application->get_active_window();
-
-        int row_width = 0, row_height;
-        Gdk::Rectangle rect;
-        list_view_text.get_cell_area(
-                list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()),
-                *(list_view_text.get_column(0)), rect);
-        row_width = rect.get_width();
-        row_height = rect.get_height();
-
-        row_width += rect.get_x() * 2; //TODO: Add correct margin x and y
-        row_height += rect.get_y() * 2;
-
-        if (this->text_view && row_width > this->text_view->get_width() * 2 / 3)
-            row_width = this->text_view->get_width() * 2 / 3;
-        else if (row_width > application_window->get_width() / 2)
-            row_width = application_window->get_width() / 2;
-        else
-            scrolled_window.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC);
-
-        int window_height = std::min(row_height * static_cast<int>(list_view_text.get_model()->children().size()),
-                                     row_height * 10);
-        if (this->show_search_entry)
-            window_height += search_entry.get_height();
-        int window_width = row_width + 1;
-        window.resize(window_width, window_height);
-
-        if (this->text_view) {
-            Gdk::Rectangle iter_rect;
-            this->text_view->get_iter_location(this->start_mark->get_iter(), iter_rect);
-            Gdk::Rectangle visible_rect;
-            this->text_view->get_visible_rect(visible_rect);
-            int buffer_x = std::max(iter_rect.get_x(), visible_rect.get_x());
-            int buffer_y = iter_rect.get_y() + iter_rect.get_height();
-            int window_x, window_y;
-            this->text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, buffer_x, buffer_y,
-                                                     window_x, window_y);
-            int root_x, root_y;
-            this->text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y,
-                                                                                                root_x, root_y);
-            window.move(root_x, root_y + 1); //TODO: replace 1 with some margin
-        } else {
-            int root_x, root_y;
-            application_window->get_position(root_x, root_y);
-            root_x += application_window->get_width() / 2 - window_width / 2;
-            root_y += application_window->get_height() / 2 - window_height / 2;
-            window.move(root_x, root_y);
-        }
-    });
+  window.set_default_size(0, 0);
+  window.property_decorated() = false;
+  window.set_skip_taskbar_hint(true);
 
-    list_view_text.signal_cursor_changed().connect([this] {
-        cursor_changed();
-    });
+  scrolled_window.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC);
+
+  scrolled_window.add(list_view_text);
+  if (show_search_entry)
+    vbox.pack_start(search_entry, false, false);
+  vbox.pack_start(scrolled_window, true, true);
+  window.add(vbox);
+
+  list_view_text.signal_realize().connect([this]() {
+    auto g_application = g_application_get_default();
+    auto gio_application = Glib::wrap(g_application, true);
+    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+    auto application_window = application->get_active_window();
+
+    int row_width = 0, row_height;
+    Gdk::Rectangle rect;
+    list_view_text.get_cell_area(
+        list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()),
+        *(list_view_text.get_column(0)), rect);
+    row_width = rect.get_width();
+    row_height = rect.get_height();
+
+    row_width += rect.get_x() * 2; //TODO: Add correct margin x and y
+    row_height += rect.get_y() * 2;
+
+    if (this->text_view && row_width > this->text_view->get_width() * 2 / 3)
+      row_width = this->text_view->get_width() * 2 / 3;
+    else if (row_width > application_window->get_width() / 2)
+      row_width = application_window->get_width() / 2;
+    else
+      scrolled_window.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC);
+
+    int window_height = std::min(row_height * static_cast<int>(list_view_text.get_model()->children().size()),
+                                 row_height * 10);
+    if (this->show_search_entry)
+      window_height += search_entry.get_height();
+    int window_width = row_width + 1;
+    window.resize(window_width, window_height);
+
+    if (this->text_view) {
+      Gdk::Rectangle iter_rect;
+      this->text_view->get_iter_location(this->start_mark->get_iter(), iter_rect);
+      Gdk::Rectangle visible_rect;
+      this->text_view->get_visible_rect(visible_rect);
+      int buffer_x = std::max(iter_rect.get_x(), visible_rect.get_x());
+      int buffer_y = iter_rect.get_y() + iter_rect.get_height();
+      int window_x, window_y;
+      this->text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, buffer_x, buffer_y,
+                                               window_x, window_y);
+      int root_x, root_y;
+      this->text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y,
+                                                                                          root_x, root_y);
+      window.move(root_x, root_y + 1); //TODO: replace 1 with some margin
+    } else {
+      int root_x, root_y;
+      application_window->get_position(root_x, root_y);
+      root_x += application_window->get_width() / 2 - window_width / 2;
+      root_y += application_window->get_height() / 2 - window_height / 2;
+      window.move(root_x, root_y);
+    }
+  });
+
+  list_view_text.signal_cursor_changed().connect([this] {
+    cursor_changed();
+  });
 }
 
 SelectionDialogBase::~SelectionDialogBase() {
-    if (text_view)
-        text_view->get_buffer()->delete_mark(start_mark);
+  if (text_view)
+    text_view->get_buffer()->delete_mark(start_mark);
 }
 
 void SelectionDialogBase::cursor_changed() {
-    if (!is_visible())
-        return;
-    auto it = list_view_text.get_selection()->get_selected();
-    unsigned int index = static_cast<unsigned int>(-1);
+  if (!is_visible())
+    return;
+  auto it = list_view_text.get_selection()->get_selected();
+  unsigned int index = static_cast<unsigned int>(-1);
+  if (it)
+    index = it->get_value(list_view_text.column_record.index);
+  if (last_index == index)
+    return;
+  if (on_changed) {
+    std::string text;
     if (it)
-        index = it->get_value(list_view_text.column_record.index);
-    if (last_index == index)
-        return;
-    if (on_changed) {
-        std::string text;
-        if (it)
-            text = it->get_value(list_view_text.column_record.text);
-        on_changed(index, text);
-    }
-    last_index = index;
+      text = it->get_value(list_view_text.column_record.text);
+    on_changed(index, text);
+  }
+  last_index = index;
 }
 
 void SelectionDialogBase::add_row(const std::string &row) {
-    list_view_text.append(row);
+  list_view_text.append(row);
 }
 
 void SelectionDialogBase::erase_rows() {
-    list_view_text.erase_rows();
+  list_view_text.erase_rows();
 }
 
 void SelectionDialogBase::show() {
-    window.show_all();
-    if (text_view)
-        text_view->grab_focus();
-
-    if (list_view_text.get_model()->children().size() > 0) {
-        if (!list_view_text.get_selection()->get_selected()) {
-            list_view_text.set_cursor(
-                    list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
-            cursor_changed();
-        } else if (list_view_text.get_model()->children().begin() != list_view_text.get_selection()->get_selected()) {
-            while (Gtk::Main::events_pending())
-                Gtk::Main::iteration(false);
-            if (is_visible())
-                list_view_text.scroll_to_row(
-                        list_view_text.get_model()->get_path(list_view_text.get_selection()->get_selected()), 0.5);
-        }
+  window.show_all();
+  if (text_view)
+    text_view->grab_focus();
+
+  if (list_view_text.get_model()->children().size() > 0) {
+    if (!list_view_text.get_selection()->get_selected()) {
+      list_view_text.set_cursor(
+          list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
+      cursor_changed();
+    } else if (list_view_text.get_model()->children().begin() != list_view_text.get_selection()->get_selected()) {
+      while (Gtk::Main::events_pending())
+        Gtk::Main::iteration(false);
+      if (is_visible())
+        list_view_text.scroll_to_row(
+            list_view_text.get_model()->get_path(list_view_text.get_selection()->get_selected()), 0.5);
     }
-    if (on_show)
-        on_show();
+  }
+  if (on_show)
+    on_show();
 }
 
 void SelectionDialogBase::set_cursor_at_last_row() {
-    auto children = list_view_text.get_model()->children();
-    if (children.size() > 0) {
-        list_view_text.set_cursor(list_view_text.get_model()->get_path(children[children.size() - 1]));
-        cursor_changed();
-    }
+  auto children = list_view_text.get_model()->children();
+  if (children.size() > 0) {
+    list_view_text.set_cursor(list_view_text.get_model()->get_path(children[children.size() - 1]));
+    cursor_changed();
+  }
 }
 
 void SelectionDialogBase::hide() {
-    if (!is_visible())
-        return;
-    window.hide();
-    if (on_hide)
-        on_hide();
-    list_view_text.clear();
-    last_index = static_cast<unsigned int>(-1);
+  if (!is_visible())
+    return;
+  window.hide();
+  if (on_hide)
+    on_hide();
+  list_view_text.clear();
+  last_index = static_cast<unsigned int>(-1);
 }
 
 std::unique_ptr<SelectionDialog> SelectionDialog::instance;
@@ -202,271 +202,271 @@ SelectionDialog::SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::Tex
                                  bool show_search_entry, bool use_markup) : SelectionDialogBase(text_view, start_mark,
                                                                                                 show_search_entry,
                                                                                                 use_markup) {
-    auto search_key = std::make_shared<std::string>();
-    auto filter_model = Gtk::TreeModelFilter::create(list_view_text.get_model());
-
-    filter_model->set_visible_func([this, search_key](const Gtk::TreeModel::const_iterator &iter) {
-        std::string row_lc;
-        iter->get_value(0, row_lc);
-        auto search_key_lc = *search_key;
-        std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower);
-        std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower);
-        if (list_view_text.use_markup) {
-            size_t pos = 0;
-            while ((pos = row_lc.find('<', pos)) != std::string::npos) {
-                auto pos2 = row_lc.find('>', pos + 1);
-                row_lc.erase(pos, pos2 - pos + 1);
-            }
-            search_key_lc = Glib::Markup::escape_text(search_key_lc);
-        }
-        if (row_lc.find(search_key_lc) != std::string::npos)
-            return true;
-        return false;
-    });
+  auto search_key = std::make_shared<std::string>();
+  auto filter_model = Gtk::TreeModelFilter::create(list_view_text.get_model());
+
+  filter_model->set_visible_func([this, search_key](const Gtk::TreeModel::const_iterator &iter) {
+    std::string row_lc;
+    iter->get_value(0, row_lc);
+    auto search_key_lc = *search_key;
+    std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower);
+    std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower);
+    if (list_view_text.use_markup) {
+      size_t pos = 0;
+      while ((pos = row_lc.find('<', pos)) != std::string::npos) {
+        auto pos2 = row_lc.find('>', pos + 1);
+        row_lc.erase(pos, pos2 - pos + 1);
+      }
+      search_key_lc = Glib::Markup::escape_text(search_key_lc);
+    }
+    if (row_lc.find(search_key_lc) != std::string::npos)
+      return true;
+    return false;
+  });
 
-    list_view_text.set_model(filter_model);
-
-    list_view_text.set_search_equal_func(
-            [](const Glib::RefPtr<Gtk::TreeModel> &model, int column, const Glib::ustring &key,
-               const Gtk::TreeModel::iterator &iter) {
-                return false;
-            });
-
-    search_entry.signal_changed().connect([this, search_key, filter_model]() {
-        *search_key = search_entry.get_text();
-        filter_model->refilter();
-        list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug)
-        if (search_key->empty()) {
-            if (list_view_text.get_model()->children().size() > 0)
-                list_view_text.set_cursor(
-                        list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
-        }
-    });
+  list_view_text.set_model(filter_model);
 
-    auto activate = [this]() {
-        auto it = list_view_text.get_selection()->get_selected();
-        if (on_select && it) {
-            auto index = it->get_value(list_view_text.column_record.index);
-            auto text = it->get_value(list_view_text.column_record.text);
-            on_select(index, text, true);
-        }
-        hide();
-    };
-    search_entry.signal_activate().connect([activate]() {
-        activate();
-    });
-    list_view_text.signal_row_activated().connect([activate](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *) {
-        activate();
-    });
+  list_view_text.set_search_equal_func(
+      [](const Glib::RefPtr<Gtk::TreeModel> &model, int column, const Glib::ustring &key,
+         const Gtk::TreeModel::iterator &iter) {
+        return false;
+      });
+
+  search_entry.signal_changed().connect([this, search_key, filter_model]() {
+    *search_key = search_entry.get_text();
+    filter_model->refilter();
+    list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug)
+    if (search_key->empty()) {
+      if (list_view_text.get_model()->children().size() > 0)
+        list_view_text.set_cursor(
+            list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
+    }
+  });
+
+  auto activate = [this]() {
+    auto it = list_view_text.get_selection()->get_selected();
+    if (on_select && it) {
+      auto index = it->get_value(list_view_text.column_record.index);
+      auto text = it->get_value(list_view_text.column_record.text);
+      on_select(index, text, true);
+    }
+    hide();
+  };
+  search_entry.signal_activate().connect([activate]() {
+    activate();
+  });
+  list_view_text.signal_row_activated().connect([activate](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *) {
+    activate();
+  });
 }
 
 bool SelectionDialog::on_key_press(GdkEventKey *key) {
-    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
-        list_view_text.get_model()->children().size() > 0) {
-        auto it = list_view_text.get_selection()->get_selected();
-        if (it) {
-            it++;
-            if (it)
-                list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
-        }
-        return true;
-    } else if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
-               list_view_text.get_model()->children().size() > 0) {
-        auto it = list_view_text.get_selection()->get_selected();
-        if (it) {
-            it--;
-            if (it)
-                list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
-        }
-        return true;
-    } else if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter ||
-               key->keyval == GDK_KEY_ISO_Left_Tab || key->keyval == GDK_KEY_Tab) {
-        auto it = list_view_text.get_selection()->get_selected();
-        auto column = list_view_text.get_column(0);
-        list_view_text.row_activated(list_view_text.get_model()->get_path(it), *column);
-        return true;
-    } else if (key->keyval == GDK_KEY_Escape) {
-        hide();
-        return true;
-    } else if (key->keyval == GDK_KEY_Left || key->keyval == GDK_KEY_KP_Left || key->keyval == GDK_KEY_Right ||
-               key->keyval == GDK_KEY_KP_Right) {
-        hide();
-        return false;
-    } else if (show_search_entry) {
-#ifdef __APPLE__ //OS X bug most likely: Gtk::Entry will not work if window is of type POPUP
-        int search_entry_length=search_entry.get_text_length();
-        if(key->keyval==GDK_KEY_dead_tilde) {
-          search_entry.insert_text("~", 1, search_entry_length);
-          return true;
-        }
-        else if(key->keyval==GDK_KEY_dead_circumflex) {
-          search_entry.insert_text("^", 1, search_entry_length);
-          return true;
-        }
-        else if(key->is_modifier)
-          return true;
-        else if(key->keyval==GDK_KEY_BackSpace) {
-          auto length=search_entry.get_text_length();
-          if(length>0)
-            search_entry.delete_text(length-1, length);
-          return true;
-        }
-        else {
-          gunichar unicode=gdk_keyval_to_unicode(key->keyval);
-          if(unicode>=32 && unicode!=126) {
-            auto ustr=Glib::ustring(1, unicode);
-            search_entry.insert_text(ustr, ustr.bytes(), search_entry_length);
-            return true;
-          }
-        }
-#else
-        search_entry.on_key_press_event(key);
-        return true;
-#endif
+  if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
+      list_view_text.get_model()->children().size() > 0) {
+    auto it = list_view_text.get_selection()->get_selected();
+    if (it) {
+      it++;
+      if (it)
+        list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
+    }
+    return true;
+  } else if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
+             list_view_text.get_model()->children().size() > 0) {
+    auto it = list_view_text.get_selection()->get_selected();
+    if (it) {
+      it--;
+      if (it)
+        list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
     }
+    return true;
+  } else if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter ||
+             key->keyval == GDK_KEY_ISO_Left_Tab || key->keyval == GDK_KEY_Tab) {
+    auto it = list_view_text.get_selection()->get_selected();
+    auto column = list_view_text.get_column(0);
+    list_view_text.row_activated(list_view_text.get_model()->get_path(it), *column);
+    return true;
+  } else if (key->keyval == GDK_KEY_Escape) {
+    hide();
+    return true;
+  } else if (key->keyval == GDK_KEY_Left || key->keyval == GDK_KEY_KP_Left || key->keyval == GDK_KEY_Right ||
+             key->keyval == GDK_KEY_KP_Right) {
     hide();
     return false;
+  } else if (show_search_entry) {
+#ifdef __APPLE__ //OS X bug most likely: Gtk::Entry will not work if window is of type POPUP
+    int search_entry_length=search_entry.get_text_length();
+    if(key->keyval==GDK_KEY_dead_tilde) {
+      search_entry.insert_text("~", 1, search_entry_length);
+      return true;
+    }
+    else if(key->keyval==GDK_KEY_dead_circumflex) {
+      search_entry.insert_text("^", 1, search_entry_length);
+      return true;
+    }
+    else if(key->is_modifier)
+      return true;
+    else if(key->keyval==GDK_KEY_BackSpace) {
+      auto length=search_entry.get_text_length();
+      if(length>0)
+        search_entry.delete_text(length-1, length);
+      return true;
+    }
+    else {
+      gunichar unicode=gdk_keyval_to_unicode(key->keyval);
+      if(unicode>=32 && unicode!=126) {
+        auto ustr=Glib::ustring(1, unicode);
+        search_entry.insert_text(ustr, ustr.bytes(), search_entry_length);
+        return true;
+      }
+    }
+#else
+    search_entry.on_key_press_event(key);
+    return true;
+#endif
+  }
+  hide();
+  return false;
 }
 
 std::unique_ptr<CompletionDialog> CompletionDialog::instance;
 
 CompletionDialog::CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark)
-        : SelectionDialogBase(text_view, start_mark, false, false) {
-    show_offset = text_view->get_buffer()->get_insert()->get_iter().get_offset();
-
-    auto search_key = std::make_shared<std::string>();
-    auto filter_model = Gtk::TreeModelFilter::create(list_view_text.get_model());
-    if (show_offset == start_mark->get_iter().get_offset()) {
-        filter_model->set_visible_func([search_key](const Gtk::TreeModel::const_iterator &iter) {
-            std::string row_lc;
-            iter->get_value(0, row_lc);
-            auto search_key_lc = *search_key;
-            std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower);
-            std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower);
-            if (row_lc.find(search_key_lc) != std::string::npos)
-                return true;
-            return false;
-        });
-    } else {
-        filter_model->set_visible_func([search_key](const Gtk::TreeModel::const_iterator &iter) {
-            std::string row;
-            iter->get_value(0, row);
-            if (row.find(*search_key) == 0)
-                return true;
-            return false;
-        });
-    }
-    list_view_text.set_model(filter_model);
-    search_entry.signal_changed().connect([this, search_key, filter_model]() {
-        *search_key = search_entry.get_text();
-        filter_model->refilter();
-        list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug)
+    : SelectionDialogBase(text_view, start_mark, false, false) {
+  show_offset = text_view->get_buffer()->get_insert()->get_iter().get_offset();
+
+  auto search_key = std::make_shared<std::string>();
+  auto filter_model = Gtk::TreeModelFilter::create(list_view_text.get_model());
+  if (show_offset == start_mark->get_iter().get_offset()) {
+    filter_model->set_visible_func([search_key](const Gtk::TreeModel::const_iterator &iter) {
+      std::string row_lc;
+      iter->get_value(0, row_lc);
+      auto search_key_lc = *search_key;
+      std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower);
+      std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower);
+      if (row_lc.find(search_key_lc) != std::string::npos)
+        return true;
+      return false;
     });
-
-    list_view_text.signal_row_activated().connect([this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *) {
-        select();
+  } else {
+    filter_model->set_visible_func([search_key](const Gtk::TreeModel::const_iterator &iter) {
+      std::string row;
+      iter->get_value(0, row);
+      if (row.find(*search_key) == 0)
+        return true;
+      return false;
     });
-
-    auto text = text_view->get_buffer()->get_text(start_mark->get_iter(),
-                                                  text_view->get_buffer()->get_insert()->get_iter());
-    if (text.size() > 0) {
-        search_entry.set_text(text);
-        list_view_text.set_search_entry(search_entry);
-    }
+  }
+  list_view_text.set_model(filter_model);
+  search_entry.signal_changed().connect([this, search_key, filter_model]() {
+    *search_key = search_entry.get_text();
+    filter_model->refilter();
+    list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug)
+  });
+
+  list_view_text.signal_row_activated().connect([this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *) {
+    select();
+  });
+
+  auto text = text_view->get_buffer()->get_text(start_mark->get_iter(),
+                                                text_view->get_buffer()->get_insert()->get_iter());
+  if (text.size() > 0) {
+    search_entry.set_text(text);
+    list_view_text.set_search_entry(search_entry);
+  }
 }
 
 void CompletionDialog::select(bool hide_window) {
-    row_in_entry = true;
-
-    auto it = list_view_text.get_selection()->get_selected();
-    if (on_select && it) {
-        auto index = it->get_value(list_view_text.column_record.index);
-        auto text = it->get_value(list_view_text.column_record.text);
-        on_select(index, text, hide_window);
-    }
-    if (hide_window)
-        hide();
+  row_in_entry = true;
+
+  auto it = list_view_text.get_selection()->get_selected();
+  if (on_select && it) {
+    auto index = it->get_value(list_view_text.column_record.index);
+    auto text = it->get_value(list_view_text.column_record.text);
+    on_select(index, text, hide_window);
+  }
+  if (hide_window)
+    hide();
 }
 
 bool CompletionDialog::on_key_release(GdkEventKey *key) {
-    if (key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down || key->keyval == GDK_KEY_Up ||
-        key->keyval == GDK_KEY_KP_Up)
-        return false;
+  if (key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down || key->keyval == GDK_KEY_Up ||
+      key->keyval == GDK_KEY_KP_Up)
+    return false;
 
-    if (show_offset > text_view->get_buffer()->get_insert()->get_iter().get_offset()) {
-        hide();
-    } else {
-        auto text = text_view->get_buffer()->get_text(start_mark->get_iter(),
-                                                      text_view->get_buffer()->get_insert()->get_iter());
-        search_entry.set_text(text);
-        list_view_text.set_search_entry(search_entry);
-        if (text == "") {
-            if (list_view_text.get_model()->children().size() > 0)
-                list_view_text.set_cursor(
-                        list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
-        }
-        cursor_changed();
+  if (show_offset > text_view->get_buffer()->get_insert()->get_iter().get_offset()) {
+    hide();
+  } else {
+    auto text = text_view->get_buffer()->get_text(start_mark->get_iter(),
+                                                  text_view->get_buffer()->get_insert()->get_iter());
+    search_entry.set_text(text);
+    list_view_text.set_search_entry(search_entry);
+    if (text == "") {
+      if (list_view_text.get_model()->children().size() > 0)
+        list_view_text.set_cursor(
+            list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
     }
-    return false;
+    cursor_changed();
+  }
+  return false;
 }
 
 bool CompletionDialog::on_key_press(GdkEventKey *key) {
-    if ((key->keyval >= GDK_KEY_0 && key->keyval <= GDK_KEY_9) ||
-        (key->keyval >= GDK_KEY_A && key->keyval <= GDK_KEY_Z) ||
-        (key->keyval >= GDK_KEY_a && key->keyval <= GDK_KEY_z) ||
-        key->keyval == GDK_KEY_underscore || key->keyval == GDK_KEY_BackSpace) {
-        if (row_in_entry) {
-            text_view->get_buffer()->erase(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter());
-            row_in_entry = false;
-            if (key->keyval == GDK_KEY_BackSpace)
-                return true;
-        }
-        return false;
-    }
-    if (key->keyval == GDK_KEY_Shift_L || key->keyval == GDK_KEY_Shift_R || key->keyval == GDK_KEY_Alt_L ||
-        key->keyval == GDK_KEY_Alt_R || key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R ||
-        key->keyval == GDK_KEY_Meta_L || key->keyval == GDK_KEY_Meta_R)
-        return false;
-    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
-        list_view_text.get_model()->children().size() > 0) {
-        auto it = list_view_text.get_selection()->get_selected();
-        if (it) {
-            it++;
-            if (it) {
-                list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
-                cursor_changed();
-            }
-        } else
-            list_view_text.set_cursor(
-                    list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
-        select(false);
-        return true;
-    }
-    if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
-        list_view_text.get_model()->children().size() > 0) {
-        auto it = list_view_text.get_selection()->get_selected();
-        if (it) {
-            it--;
-            if (it) {
-                list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
-                cursor_changed();
-            }
-        } else {
-            auto last_it = list_view_text.get_model()->children().end();
-            last_it--;
-            if (last_it)
-                list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it));
-        }
-        select(false);
-        return true;
-    }
-    if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter || key->keyval == GDK_KEY_ISO_Left_Tab ||
-        key->keyval == GDK_KEY_Tab) {
-        select();
+  if ((key->keyval >= GDK_KEY_0 && key->keyval <= GDK_KEY_9) ||
+      (key->keyval >= GDK_KEY_A && key->keyval <= GDK_KEY_Z) ||
+      (key->keyval >= GDK_KEY_a && key->keyval <= GDK_KEY_z) ||
+      key->keyval == GDK_KEY_underscore || key->keyval == GDK_KEY_BackSpace) {
+    if (row_in_entry) {
+      text_view->get_buffer()->erase(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter());
+      row_in_entry = false;
+      if (key->keyval == GDK_KEY_BackSpace)
         return true;
     }
-    hide();
-    if (key->keyval == GDK_KEY_Escape)
-        return true;
     return false;
+  }
+  if (key->keyval == GDK_KEY_Shift_L || key->keyval == GDK_KEY_Shift_R || key->keyval == GDK_KEY_Alt_L ||
+      key->keyval == GDK_KEY_Alt_R || key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R ||
+      key->keyval == GDK_KEY_Meta_L || key->keyval == GDK_KEY_Meta_R)
+    return false;
+  if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
+      list_view_text.get_model()->children().size() > 0) {
+    auto it = list_view_text.get_selection()->get_selected();
+    if (it) {
+      it++;
+      if (it) {
+        list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
+        cursor_changed();
+      }
+    } else
+      list_view_text.set_cursor(
+          list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
+    select(false);
+    return true;
+  }
+  if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
+      list_view_text.get_model()->children().size() > 0) {
+    auto it = list_view_text.get_selection()->get_selected();
+    if (it) {
+      it--;
+      if (it) {
+        list_view_text.set_cursor(list_view_text.get_model()->get_path(it));
+        cursor_changed();
+      }
+    } else {
+      auto last_it = list_view_text.get_model()->children().end();
+      last_it--;
+      if (last_it)
+        list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it));
+    }
+    select(false);
+    return true;
+  }
+  if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter || key->keyval == GDK_KEY_ISO_Left_Tab ||
+      key->keyval == GDK_KEY_Tab) {
+    select();
+    return true;
+  }
+  hide();
+  if (key->keyval == GDK_KEY_Escape)
+    return true;
+  return false;
 }
diff --git a/src/selection_dialog.h b/src/selection_dialog.h
index 05d33d48..224636d0 100644
--- a/src/selection_dialog.h
+++ b/src/selection_dialog.h
@@ -5,125 +5,125 @@
 #include <functional>
 
 class SelectionDialogBase {
-    class ListViewText : public Gtk::TreeView {
-        class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
-        public:
-            ColumnRecord() {
-                add(text);
-                add(index);
-            }
-
-            Gtk::TreeModelColumn<std::string> text;
-            Gtk::TreeModelColumn<unsigned int> index;
-        };
-
+  class ListViewText : public Gtk::TreeView {
+    class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
     public:
-        bool use_markup;
-        ColumnRecord column_record;
+      ColumnRecord() {
+        add(text);
+        add(index);
+      }
 
-        ListViewText(bool use_markup);
+      Gtk::TreeModelColumn<std::string> text;
+      Gtk::TreeModelColumn<unsigned int> index;
+    };
 
-        void append(const std::string &value);
+  public:
+    bool use_markup;
+    ColumnRecord column_record;
 
-        void erase_rows();
+    ListViewText(bool use_markup);
 
-        void clear();
+    void append(const std::string &value);
 
-    private:
-        Glib::RefPtr<Gtk::ListStore> list_store;
-        Gtk::CellRendererText cell_renderer;
-        unsigned int size = 0;
-    };
+    void erase_rows();
 
-    class SearchEntry : public Gtk::Entry {
-    public:
-        SearchEntry() : Gtk::Entry() {}
+    void clear();
 
-        bool on_key_press_event(GdkEventKey *event) override { return Gtk::Entry::on_key_press_event(event); };
-    };
+  private:
+    Glib::RefPtr<Gtk::ListStore> list_store;
+    Gtk::CellRendererText cell_renderer;
+    unsigned int size = 0;
+  };
+
+  class SearchEntry : public Gtk::Entry {
+  public:
+    SearchEntry() : Gtk::Entry() {}
+
+    bool on_key_press_event(GdkEventKey *event) override { return Gtk::Entry::on_key_press_event(event); };
+  };
 
 public:
-    SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark,
-                        bool show_search_entry, bool use_markup);
+  SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark,
+                      bool show_search_entry, bool use_markup);
 
-    virtual ~SelectionDialogBase();
+  virtual ~SelectionDialogBase();
 
-    void add_row(const std::string &row);
+  void add_row(const std::string &row);
 
-    void erase_rows();
+  void erase_rows();
 
-    void set_cursor_at_last_row();
+  void set_cursor_at_last_row();
 
-    void show();
+  void show();
 
-    void hide();
+  void hide();
 
-    bool is_visible() { return window.is_visible(); }
+  bool is_visible() { return window.is_visible(); }
 
-    void get_position(int &root_x, int &root_y) { window.get_position(root_x, root_y); }
+  void get_position(int &root_x, int &root_y) { window.get_position(root_x, root_y); }
 
-    std::function<void()> on_show;
-    std::function<void()> on_hide;
-    std::function<void(unsigned int index, const std::string &text, bool hide_window)> on_select;
-    std::function<void(unsigned int index, const std::string &text)> on_changed;
-    std::function<void(const std::string &text)> on_search_entry_changed;
-    Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
+  std::function<void()> on_show;
+  std::function<void()> on_hide;
+  std::function<void(unsigned int index, const std::string &text, bool hide_window)> on_select;
+  std::function<void(unsigned int index, const std::string &text)> on_changed;
+  std::function<void(const std::string &text)> on_search_entry_changed;
+  Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
 
 protected:
-    void cursor_changed();
+  void cursor_changed();
 
-    Gtk::TextView *text_view;
-    Gtk::Window window;
-    Gtk::Box vbox;
-    Gtk::ScrolledWindow scrolled_window;
-    ListViewText list_view_text;
-    SearchEntry search_entry;
-    bool show_search_entry;
+  Gtk::TextView *text_view;
+  Gtk::Window window;
+  Gtk::Box vbox;
+  Gtk::ScrolledWindow scrolled_window;
+  ListViewText list_view_text;
+  SearchEntry search_entry;
+  bool show_search_entry;
 
-    unsigned int last_index = static_cast<unsigned int>(-1);
+  unsigned int last_index = static_cast<unsigned int>(-1);
 };
 
 class SelectionDialog : public SelectionDialogBase {
-    SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry,
-                    bool use_markup);
+  SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry,
+                  bool use_markup);
 
-    static std::unique_ptr<SelectionDialog> instance;
+  static std::unique_ptr<SelectionDialog> instance;
 public:
-    bool on_key_press(GdkEventKey *key);
+  bool on_key_press(GdkEventKey *key);
 
-    static void
-    create(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry = true,
-           bool use_markup = false) {
-        instance = std::unique_ptr<SelectionDialog>(
-                new SelectionDialog(text_view, start_mark, show_search_entry, use_markup));
-    }
+  static void
+  create(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry = true,
+         bool use_markup = false) {
+    instance = std::unique_ptr<SelectionDialog>(
+        new SelectionDialog(text_view, start_mark, show_search_entry, use_markup));
+  }
 
-    static void create(bool show_search_entry = true, bool use_markup = false) {
-        instance = std::unique_ptr<SelectionDialog>(
-                new SelectionDialog(nullptr, Glib::RefPtr<Gtk::TextBuffer::Mark>(), show_search_entry, use_markup));
-    }
+  static void create(bool show_search_entry = true, bool use_markup = false) {
+    instance = std::unique_ptr<SelectionDialog>(
+        new SelectionDialog(nullptr, Glib::RefPtr<Gtk::TextBuffer::Mark>(), show_search_entry, use_markup));
+  }
 
-    static std::unique_ptr<SelectionDialog> &get() { return instance; }
+  static std::unique_ptr<SelectionDialog> &get() { return instance; }
 };
 
 class CompletionDialog : public SelectionDialogBase {
-    CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark);
+  CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark);
 
-    static std::unique_ptr<CompletionDialog> instance;
+  static std::unique_ptr<CompletionDialog> instance;
 public:
-    bool on_key_release(GdkEventKey *key);
+  bool on_key_release(GdkEventKey *key);
 
-    bool on_key_press(GdkEventKey *key);
+  bool on_key_press(GdkEventKey *key);
 
-    static void create(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark) {
-        instance = std::unique_ptr<CompletionDialog>(new CompletionDialog(text_view, start_mark));
-    }
+  static void create(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark) {
+    instance = std::unique_ptr<CompletionDialog>(new CompletionDialog(text_view, start_mark));
+  }
 
-    static std::unique_ptr<CompletionDialog> &get() { return instance; }
+  static std::unique_ptr<CompletionDialog> &get() { return instance; }
 
 private:
-    void select(bool hide_window = true);
+  void select(bool hide_window = true);
 
-    int show_offset;
-    bool row_in_entry = false;
+  int show_offset;
+  bool row_in_entry = false;
 };
diff --git a/src/source.cc b/src/source.cc
index 01f7bd06..63e5bccb 100644
--- a/src/source.cc
+++ b/src/source.cc
@@ -19,91 +19,91 @@
 #include <limits>
 
 Glib::RefPtr<Gsv::LanguageManager> Source::LanguageManager::get_default() {
-    static auto instance = Gsv::LanguageManager::create();
-    return instance;
+  static auto instance = Gsv::LanguageManager::create();
+  return instance;
 }
 
 Glib::RefPtr<Gsv::StyleSchemeManager> Source::StyleSchemeManager::get_default() {
-    static auto instance = Gsv::StyleSchemeManager::create();
-    static bool first = true;
-    if (first) {
-        instance->prepend_search_path((Config::get().home_juci_path / "styles").string());
-        first = false;
-    }
-    return instance;
+  static auto instance = Gsv::StyleSchemeManager::create();
+  static bool first = true;
+  if (first) {
+    instance->prepend_search_path((Config::get().home_juci_path / "styles").string());
+    first = false;
+  }
+  return instance;
 }
 
 Glib::RefPtr<Gsv::Language> Source::guess_language(const boost::filesystem::path &file_path) {
-    auto language_manager = LanguageManager::get_default();
-    bool result_uncertain = false;
-    auto content_type = Gio::content_type_guess(file_path.string(), nullptr, 0, result_uncertain);
-    if (result_uncertain) {
-        content_type.clear();
-    }
-    auto language = language_manager->guess_language(file_path.string(), content_type);
-    if (!language) {
-        auto filename = file_path.filename().string();
-        if (filename == "CMakeLists.txt")
-            language = language_manager->get_language("cmake");
-        else if (filename == "Makefile")
-            language = language_manager->get_language("makefile");
-        else if (file_path.extension() == ".tcc")
-            language = language_manager->get_language("cpphdr");
-        else if (file_path.extension() == ".ts" || file_path.extension() == ".jsx")
-            language = language_manager->get_language("js");
-        else if (!file_path.has_extension()) {
-            for (auto &part: file_path) {
-                if (part == "include") {
-                    language = language_manager->get_language("cpphdr");
-                    break;
-                }
-            }
-        }
-    } else if (language->get_id() == "cuda") {
-        if (file_path.extension() == ".cuh")
-            language = language_manager->get_language("cpphdr");
-        else
-            language = language_manager->get_language("cpp");
-    } else if (language->get_id() == "opencl") {
-        language = language_manager->get_language("cpp");
-    }
-    return language;
+  auto language_manager = LanguageManager::get_default();
+  bool result_uncertain = false;
+  auto content_type = Gio::content_type_guess(file_path.string(), nullptr, 0, result_uncertain);
+  if (result_uncertain) {
+    content_type.clear();
+  }
+  auto language = language_manager->guess_language(file_path.string(), content_type);
+  if (!language) {
+    auto filename = file_path.filename().string();
+    if (filename == "CMakeLists.txt")
+      language = language_manager->get_language("cmake");
+    else if (filename == "Makefile")
+      language = language_manager->get_language("makefile");
+    else if (file_path.extension() == ".tcc")
+      language = language_manager->get_language("cpphdr");
+    else if (file_path.extension() == ".ts" || file_path.extension() == ".jsx")
+      language = language_manager->get_language("js");
+    else if (!file_path.has_extension()) {
+      for (auto &part: file_path) {
+        if (part == "include") {
+          language = language_manager->get_language("cpphdr");
+          break;
+        }
+      }
+    }
+  } else if (language->get_id() == "cuda") {
+    if (file_path.extension() == ".cuh")
+      language = language_manager->get_language("cpphdr");
+    else
+      language = language_manager->get_language("cpp");
+  } else if (language->get_id() == "opencl") {
+    language = language_manager->get_language("cpp");
+  }
+  return language;
 }
 
 Source::FixIt::FixIt(const std::string &source, const std::pair<Offset, Offset> &offsets) : source(source),
                                                                                             offsets(offsets) {
-    if (source.size() == 0)
-        type = Type::ERASE;
-    else {
-        if (this->offsets.first == this->offsets.second)
-            type = Type::INSERT;
-        else
-            type = Type::REPLACE;
-    }
+  if (source.size() == 0)
+    type = Type::ERASE;
+  else {
+    if (this->offsets.first == this->offsets.second)
+      type = Type::INSERT;
+    else
+      type = Type::REPLACE;
+  }
 }
 
 std::string Source::FixIt::string(Glib::RefPtr<Gtk::TextBuffer> buffer) {
-    auto iter = buffer->get_iter_at_line_index(offsets.first.line, offsets.first.index);
-    unsigned first_line_offset = iter.get_line_offset() + 1;
-    iter = buffer->get_iter_at_line_index(offsets.second.line, offsets.second.index);
-    unsigned second_line_offset = iter.get_line_offset() + 1;
-
-    std::string text;
-    if (type == Type::INSERT) {
-        text += "Insert " + source + " at ";
-        text += std::to_string(offsets.first.line + 1) + ":" + std::to_string(first_line_offset);
-    } else if (type == Type::REPLACE) {
-        text += "Replace ";
-        text += std::to_string(offsets.first.line + 1) + ":" + std::to_string(first_line_offset) + " - ";
-        text += std::to_string(offsets.second.line + 1) + ":" + std::to_string(second_line_offset);
-        text += " with " + source;
-    } else {
-        text += "Erase ";
-        text += std::to_string(offsets.first.line + 1) + ":" + std::to_string(first_line_offset) + " - ";
-        text += std::to_string(offsets.second.line + 1) + ":" + std::to_string(second_line_offset);
-    }
+  auto iter = buffer->get_iter_at_line_index(offsets.first.line, offsets.first.index);
+  unsigned first_line_offset = iter.get_line_offset() + 1;
+  iter = buffer->get_iter_at_line_index(offsets.second.line, offsets.second.index);
+  unsigned second_line_offset = iter.get_line_offset() + 1;
+
+  std::string text;
+  if (type == Type::INSERT) {
+    text += "Insert " + source + " at ";
+    text += std::to_string(offsets.first.line + 1) + ":" + std::to_string(first_line_offset);
+  } else if (type == Type::REPLACE) {
+    text += "Replace ";
+    text += std::to_string(offsets.first.line + 1) + ":" + std::to_string(first_line_offset) + " - ";
+    text += std::to_string(offsets.second.line + 1) + ":" + std::to_string(second_line_offset);
+    text += " with " + source;
+  } else {
+    text += "Erase ";
+    text += std::to_string(offsets.first.line + 1) + ":" + std::to_string(first_line_offset) + " - ";
+    text += std::to_string(offsets.second.line + 1) + ":" + std::to_string(second_line_offset);
+  }
 
-    return text;
+  return text;
 }
 
 //////////////
@@ -113,2789 +113,2789 @@ std::unordered_set<Source::View *> Source::View::non_deleted_views;
 std::unordered_set<Source::View *> Source::View::views;
 
 Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language, bool is_generic_view)
-        : BaseView(file_path, language), SpellCheckView(file_path, language), DiffView(file_path, language) {
-    non_deleted_views.emplace(this);
-    views.emplace(this);
-
-    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);
-    gtk_source_search_context_set_highlight(search_context, true);
-    //TODO: why does this not work?: Might be best to use the styles from sourceview. These has to be read from file, search-matches got style "search-match"
-    //TODO: in header if trying again: GtkSourceStyle* search_match_style;
-    //TODO: We can drop this, only work on newer versions of gtksourceview.
-    //search_match_style=(GtkSourceStyle*)g_object_new(GTK_SOURCE_TYPE_STYLE, "background-set", 1, "background", "#00FF00", nullptr);
-    //gtk_source_search_context_set_match_style(search_context, search_match_style);
-
-    //TODO: either use lambda if possible or create a gtkmm wrapper around search_context (including search_settings):
-    //TODO: (gtkmm's Gtk::Object has connect_property_changed, so subclassing this might be an idea)
-    g_signal_connect(search_context, "notify::occurrences-count", G_CALLBACK(search_occurrences_updated), this);
-
-    get_buffer()->create_tag("def:warning");
-    get_buffer()->create_tag("def:warning_underline");
-    get_buffer()->create_tag("def:error");
-    get_buffer()->create_tag("def:error_underline");
-
-    auto mark_attr_debug_breakpoint = Gsv::MarkAttributes::create();
-    Gdk::RGBA rgba;
-    rgba.set_red(1.0);
-    rgba.set_green(0.5);
-    rgba.set_blue(0.5);
-    rgba.set_alpha(0.3);
-    mark_attr_debug_breakpoint->set_background(rgba);
-    set_mark_attributes("debug_breakpoint", mark_attr_debug_breakpoint, 100);
-    auto mark_attr_debug_stop = Gsv::MarkAttributes::create();
-    rgba.set_red(0.5);
-    rgba.set_green(0.5);
-    rgba.set_blue(1.0);
-    mark_attr_debug_stop->set_background(rgba);
-    set_mark_attributes("debug_stop", mark_attr_debug_stop, 101);
-    auto mark_attr_debug_breakpoint_and_stop = Gsv::MarkAttributes::create();
-    rgba.set_red(0.75);
-    rgba.set_green(0.5);
-    rgba.set_blue(0.75);
-    mark_attr_debug_breakpoint_and_stop->set_background(rgba);
-    set_mark_attributes("debug_breakpoint_and_stop", mark_attr_debug_breakpoint_and_stop, 102);
-
-    get_buffer()->signal_changed().connect([this]() {
-        if (update_status_location)
-            update_status_location(this);
-    });
-
-    signal_realize().connect([this] {
-        auto gutter = get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT);
-        auto renderer = gutter->get_renderer_at_pos(15, 0);
-        if (renderer) {
-            renderer_activate_connection.disconnect();
-            renderer_activate_connection = renderer->signal_activate().connect(
-                    [this](const Gtk::TextIter &iter, const Gdk::Rectangle &, GdkEvent *) {
-                        if (toggle_breakpoint)
-                            toggle_breakpoint(iter.get_line());
-                    });
-        }
-    });
-
-    if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr" || language->get_id() == "c" ||
-                     language->get_id() == "cpp" || language->get_id() == "objc" || language->get_id() == "java" ||
-                     language->get_id() == "js" || language->get_id() == "ts" || language->get_id() == "proto" ||
-                     language->get_id() == "c-sharp" || language->get_id() == "html" || language->get_id() == "cuda" ||
-                     language->get_id() == "php" || language->get_id() == "rust" || language->get_id() == "swift" ||
-                     language->get_id() == "go" || language->get_id() == "scala" || language->get_id() == "opencl" ||
-                     language->get_id() == "json" || language->get_id() == "css"))
-        is_bracket_language = true;
-
-    setup_tooltip_and_dialog_events();
-    setup_format_style(is_generic_view);
+    : BaseView(file_path, language), SpellCheckView(file_path, language), DiffView(file_path, language) {
+  non_deleted_views.emplace(this);
+  views.emplace(this);
+
+  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);
+  gtk_source_search_context_set_highlight(search_context, true);
+  //TODO: why does this not work?: Might be best to use the styles from sourceview. These has to be read from file, search-matches got style "search-match"
+  //TODO: in header if trying again: GtkSourceStyle* search_match_style;
+  //TODO: We can drop this, only work on newer versions of gtksourceview.
+  //search_match_style=(GtkSourceStyle*)g_object_new(GTK_SOURCE_TYPE_STYLE, "background-set", 1, "background", "#00FF00", nullptr);
+  //gtk_source_search_context_set_match_style(search_context, search_match_style);
+
+  //TODO: either use lambda if possible or create a gtkmm wrapper around search_context (including search_settings):
+  //TODO: (gtkmm's Gtk::Object has connect_property_changed, so subclassing this might be an idea)
+  g_signal_connect(search_context, "notify::occurrences-count", G_CALLBACK(search_occurrences_updated), this);
+
+  get_buffer()->create_tag("def:warning");
+  get_buffer()->create_tag("def:warning_underline");
+  get_buffer()->create_tag("def:error");
+  get_buffer()->create_tag("def:error_underline");
+
+  auto mark_attr_debug_breakpoint = Gsv::MarkAttributes::create();
+  Gdk::RGBA rgba;
+  rgba.set_red(1.0);
+  rgba.set_green(0.5);
+  rgba.set_blue(0.5);
+  rgba.set_alpha(0.3);
+  mark_attr_debug_breakpoint->set_background(rgba);
+  set_mark_attributes("debug_breakpoint", mark_attr_debug_breakpoint, 100);
+  auto mark_attr_debug_stop = Gsv::MarkAttributes::create();
+  rgba.set_red(0.5);
+  rgba.set_green(0.5);
+  rgba.set_blue(1.0);
+  mark_attr_debug_stop->set_background(rgba);
+  set_mark_attributes("debug_stop", mark_attr_debug_stop, 101);
+  auto mark_attr_debug_breakpoint_and_stop = Gsv::MarkAttributes::create();
+  rgba.set_red(0.75);
+  rgba.set_green(0.5);
+  rgba.set_blue(0.75);
+  mark_attr_debug_breakpoint_and_stop->set_background(rgba);
+  set_mark_attributes("debug_breakpoint_and_stop", mark_attr_debug_breakpoint_and_stop, 102);
+
+  get_buffer()->signal_changed().connect([this]() {
+    if (update_status_location)
+      update_status_location(this);
+  });
+
+  signal_realize().connect([this] {
+    auto gutter = get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT);
+    auto renderer = gutter->get_renderer_at_pos(15, 0);
+    if (renderer) {
+      renderer_activate_connection.disconnect();
+      renderer_activate_connection = renderer->signal_activate().connect(
+          [this](const Gtk::TextIter &iter, const Gdk::Rectangle &, GdkEvent *) {
+            if (toggle_breakpoint)
+              toggle_breakpoint(iter.get_line());
+          });
+    }
+  });
+
+  if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr" || language->get_id() == "c" ||
+                   language->get_id() == "cpp" || language->get_id() == "objc" || language->get_id() == "java" ||
+                   language->get_id() == "js" || language->get_id() == "ts" || language->get_id() == "proto" ||
+                   language->get_id() == "c-sharp" || language->get_id() == "html" || language->get_id() == "cuda" ||
+                   language->get_id() == "php" || language->get_id() == "rust" || language->get_id() == "swift" ||
+                   language->get_id() == "go" || language->get_id() == "scala" || language->get_id() == "opencl" ||
+                   language->get_id() == "json" || language->get_id() == "css"))
+    is_bracket_language = true;
+
+  setup_tooltip_and_dialog_events();
+  setup_format_style(is_generic_view);
 
 #ifndef __APPLE__
-    set_tab_width(4); //Visual size of a \t hardcoded to be equal to visual size of 4 spaces. Buggy on OS X
+  set_tab_width(4); //Visual size of a \t hardcoded to be equal to visual size of 4 spaces. Buggy on OS X
 #endif
-    tab_char = Config::get().source.default_tab_char;
-    tab_size = Config::get().source.default_tab_size;
-    if (Config::get().source.auto_tab_char_and_size) {
-        auto tab_char_and_size = find_tab_char_and_size();
-        if (tab_char_and_size.second != 0) {
-            if (tab_char != tab_char_and_size.first || tab_size != tab_char_and_size.second) {
-                std::string tab_str;
-                if (tab_char_and_size.first == ' ')
-                    tab_str = "<space>";
-                else
-                    tab_str = "<tab>";
-            }
+  tab_char = Config::get().source.default_tab_char;
+  tab_size = Config::get().source.default_tab_size;
+  if (Config::get().source.auto_tab_char_and_size) {
+    auto tab_char_and_size = find_tab_char_and_size();
+    if (tab_char_and_size.second != 0) {
+      if (tab_char != tab_char_and_size.first || tab_size != tab_char_and_size.second) {
+        std::string tab_str;
+        if (tab_char_and_size.first == ' ')
+          tab_str = "<space>";
+        else
+          tab_str = "<tab>";
+      }
 
-            tab_char = tab_char_and_size.first;
-            tab_size = tab_char_and_size.second;
-        }
+      tab_char = tab_char_and_size.first;
+      tab_size = tab_char_and_size.second;
     }
-    set_tab_char_and_size(tab_char, tab_size);
-
-    std::string comment_characters;
-    if (is_bracket_language)
-        comment_characters = "//";
-    else if (language) {
-        if (language->get_id() == "cmake" || language->get_id() == "makefile" || language->get_id() == "python" ||
-            language->get_id() == "python3" || language->get_id() == "sh" || language->get_id() == "perl" ||
-            language->get_id() == "ruby" || language->get_id() == "r" || language->get_id() == "asm" ||
-            language->get_id() == "automake")
-            comment_characters = "#";
-        else if (language->get_id() == "latex" || language->get_id() == "matlab" || language->get_id() == "octave" ||
-                 language->get_id() == "bibtex")
-            comment_characters = "%";
-        else if (language->get_id() == "fortran")
-            comment_characters = "!";
-        else if (language->get_id() == "pascal")
-            comment_characters = "//";
-        else if (language->get_id() == "lua")
-            comment_characters = "--";
-    }
-    if (!comment_characters.empty()) {
-        toggle_comments = [this, comment_characters = std::move(comment_characters)] {
-            std::vector<int> lines;
-            Gtk::TextIter selection_start, selection_end;
-            get_buffer()->get_selection_bounds(selection_start, selection_end);
-            auto line_start = selection_start.get_line();
-            auto line_end = selection_end.get_line();
-            if (line_start != line_end && selection_end.starts_line())
-                --line_end;
-            bool lines_commented = true;
-            bool extra_spaces = true;
-            int min_indentation = -1;
-            for (auto line = line_start; line <= line_end; ++line) {
-                auto iter = get_buffer()->get_iter_at_line(line);
-                bool line_added = false;
-                bool line_commented = false;
-                bool extra_space = false;
-                int indentation = 0;
-                for (;;) {
-                    if (iter.ends_line())
-                        break;
-                    else if (*iter == ' ' || *iter == '\t') {
-                        ++indentation;
-                        iter.forward_char();
-                        continue;
-                    } else {
-                        lines.emplace_back(line);
-                        line_added = true;
-                        for (size_t c = 0; c < comment_characters.size(); ++c) {
-                            if (iter.ends_line()) {
-                                break;
-                            } else if (*iter == static_cast<unsigned int>(comment_characters[c])) {
-                                if (c < comment_characters.size() - 1) {
-                                    iter.forward_char();
-                                    continue;
-                                } else {
-                                    line_commented = true;
-                                    if (!iter.ends_line()) {
-                                        iter.forward_char();
-                                        if (*iter == ' ')
-                                            extra_space = true;
-                                    }
-                                    break;
-                                }
-                            } else
-                                break;
-                        }
-                        break;
-                    }
-                }
-                if (line_added) {
-                    lines_commented &= line_commented;
-                    extra_spaces &= extra_space;
-                    if (min_indentation == -1 || indentation < min_indentation)
-                        min_indentation = indentation;
-                }
-            }
-            if (lines.size()) {
-                auto comment_characters_and_space = comment_characters + ' ';
-                get_buffer()->begin_user_action();
-                for (auto &line: lines) {
-                    auto iter = get_buffer()->get_iter_at_line(line);
-                    iter.forward_chars(min_indentation);
-                    if (lines_commented) {
-                        auto end_iter = iter;
-                        end_iter.forward_chars(comment_characters.size() + static_cast<int>(extra_spaces));
-                        while (*iter == ' ' || *iter == '\t') {
-                            iter.forward_char();
-                            end_iter.forward_char();
-                        }
-                        get_buffer()->erase(iter, end_iter);
-                    } else
-                        get_buffer()->insert(iter, comment_characters_and_space);
+  }
+  set_tab_char_and_size(tab_char, tab_size);
+
+  std::string comment_characters;
+  if (is_bracket_language)
+    comment_characters = "//";
+  else if (language) {
+    if (language->get_id() == "cmake" || language->get_id() == "makefile" || language->get_id() == "python" ||
+        language->get_id() == "python3" || language->get_id() == "sh" || language->get_id() == "perl" ||
+        language->get_id() == "ruby" || language->get_id() == "r" || language->get_id() == "asm" ||
+        language->get_id() == "automake")
+      comment_characters = "#";
+    else if (language->get_id() == "latex" || language->get_id() == "matlab" || language->get_id() == "octave" ||
+             language->get_id() == "bibtex")
+      comment_characters = "%";
+    else if (language->get_id() == "fortran")
+      comment_characters = "!";
+    else if (language->get_id() == "pascal")
+      comment_characters = "//";
+    else if (language->get_id() == "lua")
+      comment_characters = "--";
+  }
+  if (!comment_characters.empty()) {
+    toggle_comments = [this, comment_characters = std::move(comment_characters)] {
+      std::vector<int> lines;
+      Gtk::TextIter selection_start, selection_end;
+      get_buffer()->get_selection_bounds(selection_start, selection_end);
+      auto line_start = selection_start.get_line();
+      auto line_end = selection_end.get_line();
+      if (line_start != line_end && selection_end.starts_line())
+        --line_end;
+      bool lines_commented = true;
+      bool extra_spaces = true;
+      int min_indentation = -1;
+      for (auto line = line_start; line <= line_end; ++line) {
+        auto iter = get_buffer()->get_iter_at_line(line);
+        bool line_added = false;
+        bool line_commented = false;
+        bool extra_space = false;
+        int indentation = 0;
+        for (;;) {
+          if (iter.ends_line())
+            break;
+          else if (*iter == ' ' || *iter == '\t') {
+            ++indentation;
+            iter.forward_char();
+            continue;
+          } else {
+            lines.emplace_back(line);
+            line_added = true;
+            for (size_t c = 0; c < comment_characters.size(); ++c) {
+              if (iter.ends_line()) {
+                break;
+              } else if (*iter == static_cast<unsigned int>(comment_characters[c])) {
+                if (c < comment_characters.size() - 1) {
+                  iter.forward_char();
+                  continue;
+                } else {
+                  line_commented = true;
+                  if (!iter.ends_line()) {
+                    iter.forward_char();
+                    if (*iter == ' ')
+                      extra_space = true;
+                  }
+                  break;
                 }
-                get_buffer()->end_user_action();
+              } else
+                break;
             }
-        };
-    }
+            break;
+          }
+        }
+        if (line_added) {
+          lines_commented &= line_commented;
+          extra_spaces &= extra_space;
+          if (min_indentation == -1 || indentation < min_indentation)
+            min_indentation = indentation;
+        }
+      }
+      if (lines.size()) {
+        auto comment_characters_and_space = comment_characters + ' ';
+        get_buffer()->begin_user_action();
+        for (auto &line: lines) {
+          auto iter = get_buffer()->get_iter_at_line(line);
+          iter.forward_chars(min_indentation);
+          if (lines_commented) {
+            auto end_iter = iter;
+            end_iter.forward_chars(comment_characters.size() + static_cast<int>(extra_spaces));
+            while (*iter == ' ' || *iter == '\t') {
+              iter.forward_char();
+              end_iter.forward_char();
+            }
+            get_buffer()->erase(iter, end_iter);
+          } else
+            get_buffer()->insert(iter, comment_characters_and_space);
+        }
+        get_buffer()->end_user_action();
+      }
+    };
+  }
 }
 
 void Source::View::set_tab_char_and_size(char tab_char, unsigned tab_size) {
-    this->tab_char = tab_char;
-    this->tab_size = tab_size;
+  this->tab_char = tab_char;
+  this->tab_size = tab_size;
 
-    tab.clear();
-    for (unsigned c = 0; c < tab_size; c++)
-        tab += tab_char;
+  tab.clear();
+  for (unsigned c = 0; c < tab_size; c++)
+    tab += tab_char;
 }
 
 void Source::View::cleanup_whitespace_characters() {
-    auto buffer = get_buffer();
-    buffer->begin_user_action();
-    for (int line = 0; line < buffer->get_line_count(); line++) {
-        auto iter = buffer->get_iter_at_line(line);
-        auto end_iter = get_iter_at_line_end(line);
-        if (iter == end_iter)
-            continue;
-        iter = end_iter;
-        while (!iter.starts_line() && (*iter == ' ' || *iter == '\t' || iter.ends_line()))
-            iter.backward_char();
-        if (*iter != ' ' && *iter != '\t')
-            iter.forward_char();
-        if (iter == end_iter)
-            continue;
-        buffer->erase(iter, end_iter);
-    }
-    auto iter = buffer->end();
-    if (!iter.starts_line())
-        buffer->insert(buffer->end(), "\n");
-    buffer->end_user_action();
+  auto buffer = get_buffer();
+  buffer->begin_user_action();
+  for (int line = 0; line < buffer->get_line_count(); line++) {
+    auto iter = buffer->get_iter_at_line(line);
+    auto end_iter = get_iter_at_line_end(line);
+    if (iter == end_iter)
+      continue;
+    iter = end_iter;
+    while (!iter.starts_line() && (*iter == ' ' || *iter == '\t' || iter.ends_line()))
+      iter.backward_char();
+    if (*iter != ' ' && *iter != '\t')
+      iter.forward_char();
+    if (iter == end_iter)
+      continue;
+    buffer->erase(iter, end_iter);
+  }
+  auto iter = buffer->end();
+  if (!iter.starts_line())
+    buffer->insert(buffer->end(), "\n");
+  buffer->end_user_action();
 }
 
 Gsv::DrawSpacesFlags Source::View::parse_show_whitespace_characters(const std::string &text) {
-    namespace qi = boost::spirit::qi;
-
-    qi::symbols<char, Gsv::DrawSpacesFlags> options;
-    options.add
-            ("space", Gsv::DRAW_SPACES_SPACE)
-            ("tab", Gsv::DRAW_SPACES_TAB)
-            ("newline", Gsv::DRAW_SPACES_NEWLINE)
-            ("nbsp", Gsv::DRAW_SPACES_NBSP)
-            ("leading", Gsv::DRAW_SPACES_LEADING)
-            ("text", Gsv::DRAW_SPACES_TEXT)
-            ("trailing", Gsv::DRAW_SPACES_TRAILING)
-            ("all", Gsv::DRAW_SPACES_ALL);
-
-    std::set<Gsv::DrawSpacesFlags> out;
-
-    // parse comma-separated list of options
-    qi::phrase_parse(text.begin(), text.end(), options % ',', qi::space, out);
-
-    return out.count(Gsv::DRAW_SPACES_ALL) > 0 ?
-           Gsv::DRAW_SPACES_ALL :
-           static_cast<Gsv::DrawSpacesFlags>(std::accumulate(out.begin(), out.end(), 0));
+  namespace qi = boost::spirit::qi;
+
+  qi::symbols<char, Gsv::DrawSpacesFlags> options;
+  options.add
+      ("space", Gsv::DRAW_SPACES_SPACE)
+      ("tab", Gsv::DRAW_SPACES_TAB)
+      ("newline", Gsv::DRAW_SPACES_NEWLINE)
+      ("nbsp", Gsv::DRAW_SPACES_NBSP)
+      ("leading", Gsv::DRAW_SPACES_LEADING)
+      ("text", Gsv::DRAW_SPACES_TEXT)
+      ("trailing", Gsv::DRAW_SPACES_TRAILING)
+      ("all", Gsv::DRAW_SPACES_ALL);
+
+  std::set<Gsv::DrawSpacesFlags> out;
+
+  // parse comma-separated list of options
+  qi::phrase_parse(text.begin(), text.end(), options % ',', qi::space, out);
+
+  return out.count(Gsv::DRAW_SPACES_ALL) > 0 ?
+         Gsv::DRAW_SPACES_ALL :
+         static_cast<Gsv::DrawSpacesFlags>(std::accumulate(out.begin(), out.end(), 0));
 }
 
 bool Source::View::save() {
-    if (file_path.empty() || !get_buffer()->get_modified())
-        return false;
-    if (Config::get().source.cleanup_whitespace_characters)
-        cleanup_whitespace_characters();
-
-    if (format_style) {
-        if (Config::get().source.format_style_on_save)
-            format_style(true);
-        else if (Config::get().source.format_style_on_save_if_style_file_found)
-            format_style(false);
-    }
+  if (file_path.empty() || !get_buffer()->get_modified())
+    return false;
+  if (Config::get().source.cleanup_whitespace_characters)
+    cleanup_whitespace_characters();
+
+  if (format_style) {
+    if (Config::get().source.format_style_on_save)
+      format_style(true);
+    else if (Config::get().source.format_style_on_save_if_style_file_found)
+      format_style(false);
+  }
 
-    std::ofstream output(file_path.string(), std::ofstream::binary);
-    if (output) {
-        auto start_iter = get_buffer()->begin();
-        auto end_iter = start_iter;
-        bool end_reached = false;
-        while (!end_reached) {
-            for (size_t c = 0; c < 131072; c++) {
-                if (!end_iter.forward_char()) {
-                    end_reached = true;
-                    break;
-                }
-            }
-            output << get_buffer()->get_text(start_iter, end_iter).c_str();
-            start_iter = end_iter;
-        }
-        output.close();
-        boost::system::error_code ec;
-        last_write_time = boost::filesystem::last_write_time(file_path, ec);
-        if (ec)
-            last_write_time = static_cast<std::time_t>(-1);
-        // Remonitor file in case it did not exist before
-        monitor_file();
-        get_buffer()->set_modified(false);
-        Directories::get().on_save_file(file_path);
-        return true;
-    } else {
-        Terminal::get().print("Error: could not save file " + file_path.string() + "\n", true);
-        return false;
-    }
+  std::ofstream output(file_path.string(), std::ofstream::binary);
+  if (output) {
+    auto start_iter = get_buffer()->begin();
+    auto end_iter = start_iter;
+    bool end_reached = false;
+    while (!end_reached) {
+      for (size_t c = 0; c < 131072; c++) {
+        if (!end_iter.forward_char()) {
+          end_reached = true;
+          break;
+        }
+      }
+      output << get_buffer()->get_text(start_iter, end_iter).c_str();
+      start_iter = end_iter;
+    }
+    output.close();
+    boost::system::error_code ec;
+    last_write_time = boost::filesystem::last_write_time(file_path, ec);
+    if (ec)
+      last_write_time = static_cast<std::time_t>(-1);
+    // Remonitor file in case it did not exist before
+    monitor_file();
+    get_buffer()->set_modified(false);
+    Directories::get().on_save_file(file_path);
+    return true;
+  } else {
+    Terminal::get().print("Error: could not save file " + file_path.string() + "\n", true);
+    return false;
+  }
 }
 
 void Source::View::configure() {
-    SpellCheckView::configure();
-    DiffView::configure();
-
-    if (Config::get().source.style.size() > 0) {
-        auto scheme = StyleSchemeManager::get_default()->get_scheme(Config::get().source.style);
-        if (scheme)
-            get_source_buffer()->set_style_scheme(scheme);
-    }
+  SpellCheckView::configure();
+  DiffView::configure();
 
-    set_draw_spaces(parse_show_whitespace_characters(Config::get().source.show_whitespace_characters));
+  if (Config::get().source.style.size() > 0) {
+    auto scheme = StyleSchemeManager::get_default()->get_scheme(Config::get().source.style);
+    if (scheme)
+      get_source_buffer()->set_style_scheme(scheme);
+  }
 
-    if (Config::get().source.wrap_lines)
-        set_wrap_mode(Gtk::WrapMode::WRAP_CHAR);
-    else
-        set_wrap_mode(Gtk::WrapMode::WRAP_NONE);
-    property_highlight_current_line() = Config::get().source.highlight_current_line;
-    property_show_line_numbers() = Config::get().source.show_line_numbers;
-    if (Config::get().source.font.size() > 0)
-        override_font(Pango::FontDescription(Config::get().source.font));
-    if (Config::get().source.show_background_pattern)
-        gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID);
-    else
-        gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE);
-    property_show_right_margin() = Config::get().source.show_right_margin;
-    property_right_margin_position() = Config::get().source.right_margin_position;
-
-    //Create tags for diagnostic warnings and errors:
-    auto scheme = get_source_buffer()->get_style_scheme();
-    auto tag_table = get_buffer()->get_tag_table();
-    auto style = scheme->get_style("def:warning");
-    auto diagnostic_tag = get_buffer()->get_tag_table()->lookup("def:warning");
-    auto diagnostic_tag_underline = get_buffer()->get_tag_table()->lookup("def:warning_underline");
-    if (style && (style->property_foreground_set() || style->property_background_set())) {
-        Glib::ustring warning_property;
-        if (style->property_foreground_set()) {
-            warning_property = style->property_foreground().get_value();
-            diagnostic_tag->property_foreground() = warning_property;
-        } else if (style->property_background_set())
-            warning_property = style->property_background().get_value();
-
-        diagnostic_tag_underline->property_underline() = Pango::Underline::UNDERLINE_ERROR;
-        auto tag_class = G_OBJECT_GET_CLASS(diagnostic_tag_underline->gobj()); //For older GTK+ 3 versions:
-        auto param_spec = g_object_class_find_property(tag_class, "underline-rgba");
-        if (param_spec != nullptr) {
-            diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(warning_property));
-        }
-    }
-    style = scheme->get_style("def:error");
-    diagnostic_tag = get_buffer()->get_tag_table()->lookup("def:error");
-    diagnostic_tag_underline = get_buffer()->get_tag_table()->lookup("def:error_underline");
-    if (style && (style->property_foreground_set() || style->property_background_set())) {
-        Glib::ustring error_property;
-        if (style->property_foreground_set()) {
-            error_property = style->property_foreground().get_value();
-            diagnostic_tag->property_foreground() = error_property;
-        } else if (style->property_background_set())
-            error_property = style->property_background().get_value();
-
-        diagnostic_tag_underline->property_underline() = Pango::Underline::UNDERLINE_ERROR;
-        diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(error_property));
-    }
-    //TODO: clear tag_class and param_spec?
-
-    if (Config::get().menu.keys["source_show_completion"].empty()) {
-        get_completion()->unblock_interactive();
-        interactive_completion = true;
-    } else {
-        get_completion()->block_interactive();
-        interactive_completion = false;
+  set_draw_spaces(parse_show_whitespace_characters(Config::get().source.show_whitespace_characters));
+
+  if (Config::get().source.wrap_lines)
+    set_wrap_mode(Gtk::WrapMode::WRAP_CHAR);
+  else
+    set_wrap_mode(Gtk::WrapMode::WRAP_NONE);
+  property_highlight_current_line() = Config::get().source.highlight_current_line;
+  property_show_line_numbers() = Config::get().source.show_line_numbers;
+  if (Config::get().source.font.size() > 0)
+    override_font(Pango::FontDescription(Config::get().source.font));
+  if (Config::get().source.show_background_pattern)
+    gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID);
+  else
+    gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE);
+  property_show_right_margin() = Config::get().source.show_right_margin;
+  property_right_margin_position() = Config::get().source.right_margin_position;
+
+  //Create tags for diagnostic warnings and errors:
+  auto scheme = get_source_buffer()->get_style_scheme();
+  auto tag_table = get_buffer()->get_tag_table();
+  auto style = scheme->get_style("def:warning");
+  auto diagnostic_tag = get_buffer()->get_tag_table()->lookup("def:warning");
+  auto diagnostic_tag_underline = get_buffer()->get_tag_table()->lookup("def:warning_underline");
+  if (style && (style->property_foreground_set() || style->property_background_set())) {
+    Glib::ustring warning_property;
+    if (style->property_foreground_set()) {
+      warning_property = style->property_foreground().get_value();
+      diagnostic_tag->property_foreground() = warning_property;
+    } else if (style->property_background_set())
+      warning_property = style->property_background().get_value();
+
+    diagnostic_tag_underline->property_underline() = Pango::Underline::UNDERLINE_ERROR;
+    auto tag_class = G_OBJECT_GET_CLASS(diagnostic_tag_underline->gobj()); //For older GTK+ 3 versions:
+    auto param_spec = g_object_class_find_property(tag_class, "underline-rgba");
+    if (param_spec != nullptr) {
+      diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(warning_property));
     }
+  }
+  style = scheme->get_style("def:error");
+  diagnostic_tag = get_buffer()->get_tag_table()->lookup("def:error");
+  diagnostic_tag_underline = get_buffer()->get_tag_table()->lookup("def:error_underline");
+  if (style && (style->property_foreground_set() || style->property_background_set())) {
+    Glib::ustring error_property;
+    if (style->property_foreground_set()) {
+      error_property = style->property_foreground().get_value();
+      diagnostic_tag->property_foreground() = error_property;
+    } else if (style->property_background_set())
+      error_property = style->property_background().get_value();
+
+    diagnostic_tag_underline->property_underline() = Pango::Underline::UNDERLINE_ERROR;
+    diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(error_property));
+  }
+  //TODO: clear tag_class and param_spec?
+
+  if (Config::get().menu.keys["source_show_completion"].empty()) {
+    get_completion()->unblock_interactive();
+    interactive_completion = true;
+  } else {
+    get_completion()->block_interactive();
+    interactive_completion = false;
+  }
 }
 
 void Source::View::setup_tooltip_and_dialog_events() {
-    type_tooltips.on_motion = [this] {
-        delayed_tooltips_connection.disconnect();
-    };
-    diagnostic_tooltips.on_motion = [this] {
-        delayed_tooltips_connection.disconnect();
-    };
-
-    get_buffer()->signal_changed().connect([this] {
-        hide_tooltips();
-    });
-
-    signal_motion_notify_event().connect([this](GdkEventMotion *event) {
-        if (on_motion_last_x != event->x || on_motion_last_y != event->y) {
-            delayed_tooltips_connection.disconnect();
-            if ((event->state & GDK_BUTTON1_MASK) == 0) {
-                gdouble x = event->x;
-                gdouble y = event->y;
-                delayed_tooltips_connection = Glib::signal_timeout().connect([this, x, y]() {
-                    type_tooltips.hide();
-                    diagnostic_tooltips.hide();
-                    Tooltips::init();
-                    Gdk::Rectangle rectangle(x, y, 1, 1);
-                    if (parsed) {
-                        show_type_tooltips(rectangle);
-                        show_diagnostic_tooltips(rectangle);
-                    }
-                    return false;
-                }, 100);
+  type_tooltips.on_motion = [this] {
+    delayed_tooltips_connection.disconnect();
+  };
+  diagnostic_tooltips.on_motion = [this] {
+    delayed_tooltips_connection.disconnect();
+  };
+
+  get_buffer()->signal_changed().connect([this] {
+    hide_tooltips();
+  });
+
+  signal_motion_notify_event().connect([this](GdkEventMotion *event) {
+    if (on_motion_last_x != event->x || on_motion_last_y != event->y) {
+      delayed_tooltips_connection.disconnect();
+      if ((event->state & GDK_BUTTON1_MASK) == 0) {
+        gdouble x = event->x;
+        gdouble y = event->y;
+        delayed_tooltips_connection = Glib::signal_timeout().connect([this, x, y]() {
+          type_tooltips.hide();
+          diagnostic_tooltips.hide();
+          Tooltips::init();
+          Gdk::Rectangle rectangle(x, y, 1, 1);
+          if (parsed) {
+            show_type_tooltips(rectangle);
+            show_diagnostic_tooltips(rectangle);
+          }
+          return false;
+        }, 100);
+      }
+      auto last_mouse_pos = std::make_pair(on_motion_last_x, on_motion_last_y);
+      auto mouse_pos = std::make_pair(event->x, event->y);
+      type_tooltips.hide(last_mouse_pos, mouse_pos);
+      diagnostic_tooltips.hide(last_mouse_pos, mouse_pos);
+    }
+    on_motion_last_x = event->x;
+    on_motion_last_y = event->y;
+    return false;
+  });
+
+  get_buffer()->signal_mark_set().connect(
+      [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+        if (get_buffer()->get_has_selection() && mark->get_name() == "selection_bound")
+          delayed_tooltips_connection.disconnect();
+
+        if (mark->get_name() == "insert") {
+          hide_tooltips();
+          delayed_tooltips_connection = Glib::signal_timeout().connect([this]() {
+            Tooltips::init();
+            Gdk::Rectangle rectangle;
+            get_iter_location(get_buffer()->get_insert()->get_iter(), rectangle);
+            int location_window_x, location_window_y;
+            buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(),
+                                    rectangle.get_y(), location_window_x, location_window_y);
+            rectangle.set_x(location_window_x - 2);
+            rectangle.set_y(location_window_y);
+            rectangle.set_width(5);
+            if (parsed) {
+              show_type_tooltips(rectangle);
+              show_diagnostic_tooltips(rectangle);
             }
-            auto last_mouse_pos = std::make_pair(on_motion_last_x, on_motion_last_y);
-            auto mouse_pos = std::make_pair(event->x, event->y);
-            type_tooltips.hide(last_mouse_pos, mouse_pos);
-            diagnostic_tooltips.hide(last_mouse_pos, mouse_pos);
-        }
-        on_motion_last_x = event->x;
-        on_motion_last_y = event->y;
-        return false;
-    });
+            return false;
+          }, 500);
 
-    get_buffer()->signal_mark_set().connect(
-            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-                if (get_buffer()->get_has_selection() && mark->get_name() == "selection_bound")
-                    delayed_tooltips_connection.disconnect();
-
-                if (mark->get_name() == "insert") {
-                    hide_tooltips();
-                    delayed_tooltips_connection = Glib::signal_timeout().connect([this]() {
-                        Tooltips::init();
-                        Gdk::Rectangle rectangle;
-                        get_iter_location(get_buffer()->get_insert()->get_iter(), rectangle);
-                        int location_window_x, location_window_y;
-                        buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(),
-                                                rectangle.get_y(), location_window_x, location_window_y);
-                        rectangle.set_x(location_window_x - 2);
-                        rectangle.set_y(location_window_y);
-                        rectangle.set_width(5);
-                        if (parsed) {
-                            show_type_tooltips(rectangle);
-                            show_diagnostic_tooltips(rectangle);
-                        }
-                        return false;
-                    }, 500);
-
-                    if (SelectionDialog::get())
-                        SelectionDialog::get()->hide();
-                    if (CompletionDialog::get())
-                        CompletionDialog::get()->hide();
-
-                    if (update_status_location)
-                        update_status_location(this);
-                }
-            });
+          if (SelectionDialog::get())
+            SelectionDialog::get()->hide();
+          if (CompletionDialog::get())
+            CompletionDialog::get()->hide();
 
-    signal_scroll_event().connect([this](GdkEventScroll *event) {
-        hide_tooltips();
-        hide_dialogs();
-        return false;
-    });
+          if (update_status_location)
+            update_status_location(this);
+        }
+      });
 
-    signal_focus_out_event().connect([this](GdkEventFocus *event) {
-        hide_tooltips();
-        return false;
-    });
+  signal_scroll_event().connect([this](GdkEventScroll *event) {
+    hide_tooltips();
+    hide_dialogs();
+    return false;
+  });
 
-    signal_leave_notify_event().connect([this](GdkEventCrossing *) {
-        delayed_tooltips_connection.disconnect();
-        return false;
-    });
+  signal_focus_out_event().connect([this](GdkEventFocus *event) {
+    hide_tooltips();
+    return false;
+  });
+
+  signal_leave_notify_event().connect([this](GdkEventCrossing *) {
+    delayed_tooltips_connection.disconnect();
+    return false;
+  });
 }
 
 void Source::View::setup_format_style(bool is_generic_view) {
-    static auto prettier = filesystem::find_executable("prettier");
-    if (!prettier.empty() && language &&
-        (language->get_id() == "js" || language->get_id() == "json" || language->get_id() == "css")) {
-        if (is_generic_view) {
-            goto_next_diagnostic = [this] {
-                place_cursor_at_next_diagnostic();
-            };
-            get_buffer()->signal_changed().connect([this] {
-                clear_diagnostic_tooltips();
-                status_diagnostics = std::make_tuple<size_t, size_t, size_t>(0, 0, 0);
-                if (update_status_diagnostics)
-                    update_status_diagnostics(this);
-            });
-        }
-        format_style = [this, is_generic_view](bool continue_without_style_file) {
-            auto command = prettier.string();
-            if (!continue_without_style_file) {
-                std::stringstream stdin_stream, stdout_stream;
-                auto exit_status = Terminal::get().process(stdin_stream, stdout_stream,
-                                                           command + " --find-config-path " + this->file_path.string());
-                if (exit_status == 0) {
-                    if (stdout_stream.tellp() == 0)
-                        return;
-                } else
-                    return;
-            }
+  static auto prettier = filesystem::find_executable("prettier");
+  if (!prettier.empty() && language &&
+      (language->get_id() == "js" || language->get_id() == "json" || language->get_id() == "css")) {
+    if (is_generic_view) {
+      goto_next_diagnostic = [this] {
+        place_cursor_at_next_diagnostic();
+      };
+      get_buffer()->signal_changed().connect([this] {
+        clear_diagnostic_tooltips();
+        status_diagnostics = std::make_tuple<size_t, size_t, size_t>(0, 0, 0);
+        if (update_status_diagnostics)
+          update_status_diagnostics(this);
+      });
+    }
+    format_style = [this, is_generic_view](bool continue_without_style_file) {
+      auto command = prettier.string();
+      if (!continue_without_style_file) {
+        std::stringstream stdin_stream, stdout_stream;
+        auto exit_status = Terminal::get().process(stdin_stream, stdout_stream,
+                                                   command + " --find-config-path " + this->file_path.string());
+        if (exit_status == 0) {
+          if (stdout_stream.tellp() == 0)
+            return;
+        } else
+          return;
+      }
 
-            command += " --stdin-filepath " + this->file_path.string() +
-                       " --print-width 120 --config-precedence prefer-file";
-
-            if (get_buffer()->get_has_selection()) { // Cannot be used together with --cursor-offset
-                Gtk::TextIter start, end;
-                get_buffer()->get_selection_bounds(start, end);
-                command += " --range-start " + std::to_string(start.get_offset());
-                command += " --range-end " + std::to_string(end.get_offset());
-            } else
-                command += " --cursor-offset " + std::to_string(get_buffer()->get_insert()->get_iter().get_offset());
-
-            size_t num_warnings = 0, num_errors = 0, num_fix_its = 0;
-            if (is_generic_view)
-                clear_diagnostic_tooltips();
-
-            std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream, stderr_stream;
-            auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, command,
-                                                       this->file_path.parent_path(), &stderr_stream);
-            if (exit_status == 0) {
-                replace_text(stdout_stream.str());
-                std::string line;
-                std::getline(stderr_stream, line);
-                if (!line.empty() && line != "NaN") {
-                    try {
-                        auto offset = atoi(line.c_str());
-                        if (offset < get_buffer()->size()) {
-                            get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset));
-                            hide_tooltips();
-                        }
-                    }
-                    catch (...) {}
-                }
-            } else if (is_generic_view) {
-                static std::regex regex("^\\[error\\] stdin: (.*) \\(([0-9]*):([0-9]*)\\)$");
-                std::string line;
-                std::getline(stderr_stream, line);
-                std::smatch sm;
-                if (std::regex_match(line, sm, regex)) {
-                    try {
-                        auto start = get_iter_at_line_offset(atoi(sm[2].str().c_str()) - 1,
-                                                             atoi(sm[3].str().c_str()) - 1);
-                        ++num_errors;
-                        if (start.ends_line())
-                            start.backward_char();
-                        auto end = start;
-                        end.forward_char();
-                        if (start == end)
-                            start.forward_char();
-
-                        add_diagnostic_tooltip(start, end, sm[1].str(), true);
-                    }
-                    catch (...) {}
-                }
-            }
-            if (is_generic_view) {
-                status_diagnostics = std::make_tuple(num_warnings, num_errors, num_fix_its);
-                if (update_status_diagnostics)
-                    update_status_diagnostics(this);
-            }
-            hide_tooltips();
-        };
-    } else if (is_bracket_language) {
-        format_style = [this](bool continue_without_style_file) {
-            static auto clang_format_command = filesystem::get_executable("clang-format").string();
-
-            auto command = clang_format_command + " -output-replacements-xml -assume-filename=" +
-                           filesystem::escape_argument(this->file_path.string());
-
-            if (get_buffer()->get_has_selection()) {
-                Gtk::TextIter start, end;
-                get_buffer()->get_selection_bounds(start, end);
-                command += " -lines=" + std::to_string(start.get_line() + 1) + ':' + std::to_string(end.get_line() + 1);
-            }
+      command += " --stdin-filepath " + this->file_path.string() +
+                 " --print-width 120 --config-precedence prefer-file";
 
-            bool use_style_file = false;
-            auto style_file_search_path = this->file_path.parent_path();
-            while (true) {
-                if (boost::filesystem::exists(style_file_search_path / ".clang-format") ||
-                    boost::filesystem::exists(style_file_search_path / "_clang-format")) {
-                    use_style_file = true;
-                    break;
-                }
-                if (style_file_search_path == style_file_search_path.root_directory())
-                    break;
-                style_file_search_path = style_file_search_path.parent_path();
-            }
+      if (get_buffer()->get_has_selection()) { // Cannot be used together with --cursor-offset
+        Gtk::TextIter start, end;
+        get_buffer()->get_selection_bounds(start, end);
+        command += " --range-start " + std::to_string(start.get_offset());
+        command += " --range-end " + std::to_string(end.get_offset());
+      } else
+        command += " --cursor-offset " + std::to_string(get_buffer()->get_insert()->get_iter().get_offset());
+
+      size_t num_warnings = 0, num_errors = 0, num_fix_its = 0;
+      if (is_generic_view)
+        clear_diagnostic_tooltips();
+
+      std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream, stderr_stream;
+      auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, command,
+                                                 this->file_path.parent_path(), &stderr_stream);
+      if (exit_status == 0) {
+        replace_text(stdout_stream.str());
+        std::string line;
+        std::getline(stderr_stream, line);
+        if (!line.empty() && line != "NaN") {
+          try {
+            auto offset = atoi(line.c_str());
+            if (offset < get_buffer()->size()) {
+              get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset));
+              hide_tooltips();
+            }
+          }
+          catch (...) {}
+        }
+      } else if (is_generic_view) {
+        static std::regex regex("^\\[error\\] stdin: (.*) \\(([0-9]*):([0-9]*)\\)$");
+        std::string line;
+        std::getline(stderr_stream, line);
+        std::smatch sm;
+        if (std::regex_match(line, sm, regex)) {
+          try {
+            auto start = get_iter_at_line_offset(atoi(sm[2].str().c_str()) - 1,
+                                                 atoi(sm[3].str().c_str()) - 1);
+            ++num_errors;
+            if (start.ends_line())
+              start.backward_char();
+            auto end = start;
+            end.forward_char();
+            if (start == end)
+              start.forward_char();
+
+            add_diagnostic_tooltip(start, end, sm[1].str(), true);
+          }
+          catch (...) {}
+        }
+      }
+      if (is_generic_view) {
+        status_diagnostics = std::make_tuple(num_warnings, num_errors, num_fix_its);
+        if (update_status_diagnostics)
+          update_status_diagnostics(this);
+      }
+      hide_tooltips();
+    };
+  } else if (is_bracket_language) {
+    format_style = [this](bool continue_without_style_file) {
+      static auto clang_format_command = filesystem::get_executable("clang-format").string();
 
-            if (use_style_file)
-                command += " -style=file";
-            else {
-                if (!continue_without_style_file)
-                    return;
-                unsigned indent_width;
-                std::string tab_style;
-                if (tab_char == '\t') {
-                    indent_width = tab_size * 8;
-                    tab_style = "UseTab: Always";
-                } else {
-                    indent_width = tab_size;
-                    tab_style = "UseTab: Never";
-                }
-                command += " -style=\"{IndentWidth: " + std::to_string(indent_width);
-                command += ", " + tab_style;
-                command += ", " + std::string("AccessModifierOffset: -") + std::to_string(indent_width);
-                if (Config::get().source.clang_format_style != "")
-                    command += ", " + Config::get().source.clang_format_style;
-                command += "}\"";
-            }
+      auto command = clang_format_command + " -output-replacements-xml -assume-filename=" +
+                     filesystem::escape_argument(this->file_path.string());
+
+      if (get_buffer()->get_has_selection()) {
+        Gtk::TextIter start, end;
+        get_buffer()->get_selection_bounds(start, end);
+        command += " -lines=" + std::to_string(start.get_line() + 1) + ':' + std::to_string(end.get_line() + 1);
+      }
+
+      bool use_style_file = false;
+      auto style_file_search_path = this->file_path.parent_path();
+      while (true) {
+        if (boost::filesystem::exists(style_file_search_path / ".clang-format") ||
+            boost::filesystem::exists(style_file_search_path / "_clang-format")) {
+          use_style_file = true;
+          break;
+        }
+        if (style_file_search_path == style_file_search_path.root_directory())
+          break;
+        style_file_search_path = style_file_search_path.parent_path();
+      }
+
+      if (use_style_file)
+        command += " -style=file";
+      else {
+        if (!continue_without_style_file)
+          return;
+        unsigned indent_width;
+        std::string tab_style;
+        if (tab_char == '\t') {
+          indent_width = tab_size * 8;
+          tab_style = "UseTab: Always";
+        } else {
+          indent_width = tab_size;
+          tab_style = "UseTab: Never";
+        }
+        command += " -style=\"{IndentWidth: " + std::to_string(indent_width);
+        command += ", " + tab_style;
+        command += ", " + std::string("AccessModifierOffset: -") + std::to_string(indent_width);
+        if (Config::get().source.clang_format_style != "")
+          command += ", " + Config::get().source.clang_format_style;
+        command += "}\"";
+      }
 
-            std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream;
+      std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream;
 
-            auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, command,
-                                                       this->file_path.parent_path());
-            if (exit_status == 0) {
-                // The following code is complex due to clang-format returning offsets in byte offsets instead of char offsets
+      auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, command,
+                                                 this->file_path.parent_path());
+      if (exit_status == 0) {
+        // The following code is complex due to clang-format returning offsets in byte offsets instead of char offsets
 
-                // Create bytes_in_lines cache to significantly speed up the processing of finding iterators from byte offsets
-                std::vector<size_t> bytes_in_lines;
-                auto line_count = get_buffer()->get_line_count();
-                for (int line_nr = 0; line_nr < line_count; ++line_nr) {
-                    auto iter = get_buffer()->get_iter_at_line(line_nr);
-                    bytes_in_lines.emplace_back(iter.get_bytes_in_line());
-                }
+        // Create bytes_in_lines cache to significantly speed up the processing of finding iterators from byte offsets
+        std::vector<size_t> bytes_in_lines;
+        auto line_count = get_buffer()->get_line_count();
+        for (int line_nr = 0; line_nr < line_count; ++line_nr) {
+          auto iter = get_buffer()->get_iter_at_line(line_nr);
+          bytes_in_lines.emplace_back(iter.get_bytes_in_line());
+        }
 
-                get_buffer()->begin_user_action();
-                try {
-                    boost::property_tree::ptree pt;
-                    boost::property_tree::xml_parser::read_xml(stdout_stream, pt);
-                    auto replacements_pt = pt.get_child("replacements");
-                    for (auto it = replacements_pt.rbegin(); it != replacements_pt.rend(); ++it) {
-                        if (it->first == "replacement") {
-                            auto offset = it->second.get<size_t>("<xmlattr>.offset");
-                            auto length = it->second.get<size_t>("<xmlattr>.length");
-                            auto replacement_str = it->second.get<std::string>("");
-
-                            size_t bytes = 0;
-                            for (size_t c = 0; c < bytes_in_lines.size(); ++c) {
-                                auto previous_bytes = bytes;
-                                bytes += bytes_in_lines[c];
-                                if (offset < bytes || (c == bytes_in_lines.size() - 1 && offset == bytes)) {
-                                    std::pair<size_t, size_t> line_index(c, offset - previous_bytes);
-                                    auto start = get_buffer()->get_iter_at_line_index(line_index.first,
-                                                                                      line_index.second);
-
-                                    // Use left gravity insert to avoid moving cursor from end of line
-                                    bool left_gravity_insert = false;
-                                    if (get_buffer()->get_insert()->get_iter() == start) {
-                                        auto iter = start;
-                                        do {
-                                            if (*iter != ' ' && *iter != '\t') {
-                                                left_gravity_insert = iter.ends_line();
-                                                break;
-                                            }
-                                        } while (iter.forward_char());
-                                    }
-
-                                    if (length > 0) {
-                                        auto offset_end = offset + length;
-                                        size_t bytes = 0;
-                                        for (size_t c = 0; c < bytes_in_lines.size(); ++c) {
-                                            auto previous_bytes = bytes;
-                                            bytes += bytes_in_lines[c];
-                                            if (offset_end < bytes ||
-                                                (c == bytes_in_lines.size() - 1 && offset_end == bytes)) {
-                                                auto end = get_buffer()->get_iter_at_line_index(c, offset_end -
-                                                                                                   previous_bytes);
-                                                get_buffer()->erase(start, end);
-                                                start = get_buffer()->get_iter_at_line_index(line_index.first,
-                                                                                             line_index.second);
-                                                break;
-                                            }
-                                        }
-                                    }
-                                    if (left_gravity_insert) {
-                                        auto mark = get_buffer()->create_mark(start);
-                                        get_buffer()->insert(start, replacement_str);
-                                        get_buffer()->place_cursor(mark->get_iter());
-                                        get_buffer()->delete_mark(mark);
-                                    } else
-                                        get_buffer()->insert(start, replacement_str);
-                                    break;
-                                }
-                            }
-                        }
+        get_buffer()->begin_user_action();
+        try {
+          boost::property_tree::ptree pt;
+          boost::property_tree::xml_parser::read_xml(stdout_stream, pt);
+          auto replacements_pt = pt.get_child("replacements");
+          for (auto it = replacements_pt.rbegin(); it != replacements_pt.rend(); ++it) {
+            if (it->first == "replacement") {
+              auto offset = it->second.get<size_t>("<xmlattr>.offset");
+              auto length = it->second.get<size_t>("<xmlattr>.length");
+              auto replacement_str = it->second.get<std::string>("");
+
+              size_t bytes = 0;
+              for (size_t c = 0; c < bytes_in_lines.size(); ++c) {
+                auto previous_bytes = bytes;
+                bytes += bytes_in_lines[c];
+                if (offset < bytes || (c == bytes_in_lines.size() - 1 && offset == bytes)) {
+                  std::pair<size_t, size_t> line_index(c, offset - previous_bytes);
+                  auto start = get_buffer()->get_iter_at_line_index(line_index.first,
+                                                                    line_index.second);
+
+                  // Use left gravity insert to avoid moving cursor from end of line
+                  bool left_gravity_insert = false;
+                  if (get_buffer()->get_insert()->get_iter() == start) {
+                    auto iter = start;
+                    do {
+                      if (*iter != ' ' && *iter != '\t') {
+                        left_gravity_insert = iter.ends_line();
+                        break;
+                      }
+                    } while (iter.forward_char());
+                  }
+
+                  if (length > 0) {
+                    auto offset_end = offset + length;
+                    size_t bytes = 0;
+                    for (size_t c = 0; c < bytes_in_lines.size(); ++c) {
+                      auto previous_bytes = bytes;
+                      bytes += bytes_in_lines[c];
+                      if (offset_end < bytes ||
+                          (c == bytes_in_lines.size() - 1 && offset_end == bytes)) {
+                        auto end = get_buffer()->get_iter_at_line_index(c, offset_end -
+                                                                           previous_bytes);
+                        get_buffer()->erase(start, end);
+                        start = get_buffer()->get_iter_at_line_index(line_index.first,
+                                                                     line_index.second);
+                        break;
+                      }
                     }
+                  }
+                  if (left_gravity_insert) {
+                    auto mark = get_buffer()->create_mark(start);
+                    get_buffer()->insert(start, replacement_str);
+                    get_buffer()->place_cursor(mark->get_iter());
+                    get_buffer()->delete_mark(mark);
+                  } else
+                    get_buffer()->insert(start, replacement_str);
+                  break;
                 }
-                catch (const std::exception &e) {
-                    Terminal::get().print(std::string("Error: error parsing clang-format output: ") + e.what() + '\n',
-                                          true);
-                }
-                get_buffer()->end_user_action();
+              }
             }
-        };
-    } else if (language && language->get_id() == "markdown") {
-        // The style file currently has no options, but checking if it exists
-        format_style = [this](bool continue_without_style_file) {
-            bool has_style_file = false;
-            auto style_file_search_path = this->file_path.parent_path();
-            while (true) {
-                if (boost::filesystem::exists(style_file_search_path / ".markdown-format")) {
-                    has_style_file = true;
-                    break;
-                }
-                if (style_file_search_path == style_file_search_path.root_directory())
-                    break;
-                style_file_search_path = style_file_search_path.parent_path();
+          }
+        }
+        catch (const std::exception &e) {
+          Terminal::get().print(std::string("Error: error parsing clang-format output: ") + e.what() + '\n',
+                                true);
+        }
+        get_buffer()->end_user_action();
+      }
+    };
+  } else if (language && language->get_id() == "markdown") {
+    // The style file currently has no options, but checking if it exists
+    format_style = [this](bool continue_without_style_file) {
+      bool has_style_file = false;
+      auto style_file_search_path = this->file_path.parent_path();
+      while (true) {
+        if (boost::filesystem::exists(style_file_search_path / ".markdown-format")) {
+          has_style_file = true;
+          break;
+        }
+        if (style_file_search_path == style_file_search_path.root_directory())
+          break;
+        style_file_search_path = style_file_search_path.parent_path();
+      }
+      if (!has_style_file && !continue_without_style_file)
+        return;
+
+      auto special_character = [](Gtk::TextIter iter) {
+        if (*iter == '*' || *iter == '#' || *iter == '<' || *iter == '>' || *iter == ' ' || *iter == '=' ||
+            *iter == '`' || *iter == '-')
+          return true;
+        // Tests if a line starts with for instance: 2.
+        if (*iter >= '0' && *iter <= '9' && iter.forward_char() &&
+            *iter == '.' && iter.forward_char() &&
+            *iter == ' ')
+          return true;
+        return false;
+      };
+
+      get_buffer()->begin_user_action();
+      disable_spellcheck = true;
+      cleanup_whitespace_characters();
+
+      auto iter = get_buffer()->begin();
+      size_t last_space_offset = -1;
+      bool headline = false;
+      bool monospace = false;
+      bool script = false;
+      bool html_tag = false;
+      int square_brackets = 0;
+      do {
+        if (iter.starts_line()) {
+          last_space_offset = -1;
+          auto next_line_iter = iter;
+          if (*iter == '#' || (next_line_iter.forward_line() && *next_line_iter == '='))
+            headline = true;
+          else
+            headline = false;
+          auto test_iter = iter;
+          if (*test_iter == '`' && test_iter.forward_char() &&
+              *test_iter == '`' && test_iter.forward_char() &&
+              *test_iter == '`') {
+            script = !script;
+            iter.forward_chars(3);
+            continue;
+          }
+        }
+        if (!script && *iter == '`')
+          monospace = !monospace;
+        if (!script && !monospace) {
+          if (*iter == '<')
+            html_tag = true;
+          else if (*iter == '>')
+            html_tag = false;
+          else if (*iter == '[')
+            ++square_brackets;
+          else if (*iter == ']')
+            --square_brackets;
+        }
+        if (!headline && !script && !monospace && !html_tag && square_brackets == 0) {
+          if (*iter == ' ' && iter.get_line_offset() <= 80)
+            last_space_offset = iter.get_offset();
+            // Insert newline on long lines
+          else if ((*iter == ' ' || iter.ends_line()) && iter.get_line_offset() > 80 &&
+                   last_space_offset != static_cast<size_t>(-1)) {
+            auto stored_iter = iter;
+            iter = get_buffer()->get_iter_at_offset(last_space_offset);
+            auto next_iter = iter;
+            next_iter.forward_char();
+            // Do not add newline if the next iter is a special character
+            if (special_character(next_iter)) {
+              iter = stored_iter;
+              if (*iter == ' ')
+                last_space_offset = iter.get_offset();
+              continue;
+            }
+            iter = get_buffer()->erase(iter, next_iter);
+            iter = get_buffer()->insert(iter, "\n");
+            iter.backward_char();
+          }
+            // Remove newline on short lines
+          else if (iter.ends_line() && !iter.starts_line() && iter.get_line_offset() <= 80) {
+            auto next_line_iter = iter;
+            // Do not remove newline if the next line for instance is a header
+            if (next_line_iter.forward_char() && !next_line_iter.ends_line() &&
+                !special_character(next_line_iter)) {
+              auto end_word_iter = next_line_iter;
+              // Do not remove newline if the word on the next line is too long
+              size_t diff = 0;
+              while (*end_word_iter != ' ' && !end_word_iter.ends_line() && end_word_iter.forward_char())
+                ++diff;
+              if (iter.get_line_offset() + diff + 1 <= 80) {
+                iter = get_buffer()->erase(iter, next_line_iter);
+                iter = get_buffer()->insert(iter, " ");
+                iter.backward_char();
+                if (iter.get_line_offset() <= 80)
+                  last_space_offset = iter.get_offset();
+              }
             }
-            if (!has_style_file && !continue_without_style_file)
-                return;
-
-            auto special_character = [](Gtk::TextIter iter) {
-                if (*iter == '*' || *iter == '#' || *iter == '<' || *iter == '>' || *iter == ' ' || *iter == '=' ||
-                    *iter == '`' || *iter == '-')
-                    return true;
-                // Tests if a line starts with for instance: 2.
-                if (*iter >= '0' && *iter <= '9' && iter.forward_char() &&
-                    *iter == '.' && iter.forward_char() &&
-                    *iter == ' ')
-                    return true;
-                return false;
-            };
-
-            get_buffer()->begin_user_action();
-            disable_spellcheck = true;
-            cleanup_whitespace_characters();
-
-            auto iter = get_buffer()->begin();
-            size_t last_space_offset = -1;
-            bool headline = false;
-            bool monospace = false;
-            bool script = false;
-            bool html_tag = false;
-            int square_brackets = 0;
-            do {
-                if (iter.starts_line()) {
-                    last_space_offset = -1;
-                    auto next_line_iter = iter;
-                    if (*iter == '#' || (next_line_iter.forward_line() && *next_line_iter == '='))
-                        headline = true;
-                    else
-                        headline = false;
-                    auto test_iter = iter;
-                    if (*test_iter == '`' && test_iter.forward_char() &&
-                        *test_iter == '`' && test_iter.forward_char() &&
-                        *test_iter == '`') {
-                        script = !script;
-                        iter.forward_chars(3);
-                        continue;
-                    }
-                }
-                if (!script && *iter == '`')
-                    monospace = !monospace;
-                if (!script && !monospace) {
-                    if (*iter == '<')
-                        html_tag = true;
-                    else if (*iter == '>')
-                        html_tag = false;
-                    else if (*iter == '[')
-                        ++square_brackets;
-                    else if (*iter == ']')
-                        --square_brackets;
-                }
-                if (!headline && !script && !monospace && !html_tag && square_brackets == 0) {
-                    if (*iter == ' ' && iter.get_line_offset() <= 80)
-                        last_space_offset = iter.get_offset();
-                        // Insert newline on long lines
-                    else if ((*iter == ' ' || iter.ends_line()) && iter.get_line_offset() > 80 &&
-                             last_space_offset != static_cast<size_t>(-1)) {
-                        auto stored_iter = iter;
-                        iter = get_buffer()->get_iter_at_offset(last_space_offset);
-                        auto next_iter = iter;
-                        next_iter.forward_char();
-                        // Do not add newline if the next iter is a special character
-                        if (special_character(next_iter)) {
-                            iter = stored_iter;
-                            if (*iter == ' ')
-                                last_space_offset = iter.get_offset();
-                            continue;
-                        }
-                        iter = get_buffer()->erase(iter, next_iter);
-                        iter = get_buffer()->insert(iter, "\n");
-                        iter.backward_char();
-                    }
-                        // Remove newline on short lines
-                    else if (iter.ends_line() && !iter.starts_line() && iter.get_line_offset() <= 80) {
-                        auto next_line_iter = iter;
-                        // Do not remove newline if the next line for instance is a header
-                        if (next_line_iter.forward_char() && !next_line_iter.ends_line() &&
-                            !special_character(next_line_iter)) {
-                            auto end_word_iter = next_line_iter;
-                            // Do not remove newline if the word on the next line is too long
-                            size_t diff = 0;
-                            while (*end_word_iter != ' ' && !end_word_iter.ends_line() && end_word_iter.forward_char())
-                                ++diff;
-                            if (iter.get_line_offset() + diff + 1 <= 80) {
-                                iter = get_buffer()->erase(iter, next_line_iter);
-                                iter = get_buffer()->insert(iter, " ");
-                                iter.backward_char();
-                                if (iter.get_line_offset() <= 80)
-                                    last_space_offset = iter.get_offset();
-                            }
-                        }
-                    }
-                }
-            } while (iter.forward_char());
-            disable_spellcheck = false;
-            get_buffer()->end_user_action();
-        };
-    }
+          }
+        }
+      } while (iter.forward_char());
+      disable_spellcheck = false;
+      get_buffer()->end_user_action();
+    };
+  }
 }
 
 void Source::View::search_occurrences_updated(GtkWidget *widget, GParamSpec *property, gpointer data) {
-    auto view = static_cast<Source::View *>(data);
-    if (view->update_search_occurrences)
-        view->update_search_occurrences(gtk_source_search_context_get_occurrences_count(view->search_context));
+  auto view = static_cast<Source::View *>(data);
+  if (view->update_search_occurrences)
+    view->update_search_occurrences(gtk_source_search_context_get_occurrences_count(view->search_context));
 }
 
 Source::View::~View() {
-    g_clear_object(&search_context);
-    g_clear_object(&search_settings);
+  g_clear_object(&search_context);
+  g_clear_object(&search_settings);
 
-    delayed_tooltips_connection.disconnect();
-    renderer_activate_connection.disconnect();
+  delayed_tooltips_connection.disconnect();
+  renderer_activate_connection.disconnect();
 
-    non_deleted_views.erase(this);
-    views.erase(this);
+  non_deleted_views.erase(this);
+  views.erase(this);
 }
 
 void Source::View::search_highlight(const std::string &text, bool case_sensitive, bool regex) {
-    gtk_source_search_settings_set_case_sensitive(search_settings, case_sensitive);
-    gtk_source_search_settings_set_regex_enabled(search_settings, regex);
-    gtk_source_search_settings_set_search_text(search_settings, text.c_str());
-    search_occurrences_updated(nullptr, nullptr, this);
+  gtk_source_search_settings_set_case_sensitive(search_settings, case_sensitive);
+  gtk_source_search_settings_set_regex_enabled(search_settings, regex);
+  gtk_source_search_settings_set_search_text(search_settings, text.c_str());
+  search_occurrences_updated(nullptr, nullptr, this);
 }
 
 void Source::View::search_forward() {
-    Gtk::TextIter insert, selection_bound;
-    get_buffer()->get_selection_bounds(insert, selection_bound);
-    auto &start = selection_bound;
-    Gtk::TextIter match_start, match_end;
+  Gtk::TextIter insert, selection_bound;
+  get_buffer()->get_selection_bounds(insert, selection_bound);
+  auto &start = selection_bound;
+  Gtk::TextIter match_start, match_end;
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-    gboolean has_wrapped_around;
-    if (gtk_source_search_context_forward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
-                                           &has_wrapped_around)) {
+  gboolean has_wrapped_around;
+  if (gtk_source_search_context_forward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
+                                         &has_wrapped_around)) {
 #else
-        if(gtk_source_search_context_forward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
+    if(gtk_source_search_context_forward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
 #endif
-        get_buffer()->select_range(match_start, match_end);
-        scroll_to(get_buffer()->get_insert());
-    }
+    get_buffer()->select_range(match_start, match_end);
+    scroll_to(get_buffer()->get_insert());
+  }
 }
 
 void Source::View::search_backward() {
-    Gtk::TextIter insert, selection_bound;
-    get_buffer()->get_selection_bounds(insert, selection_bound);
-    auto &start = insert;
-    Gtk::TextIter match_start, match_end;
+  Gtk::TextIter insert, selection_bound;
+  get_buffer()->get_selection_bounds(insert, selection_bound);
+  auto &start = insert;
+  Gtk::TextIter match_start, match_end;
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-    gboolean has_wrapped_around;
-    if (gtk_source_search_context_backward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
-                                            &has_wrapped_around)) {
+  gboolean has_wrapped_around;
+  if (gtk_source_search_context_backward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
+                                          &has_wrapped_around)) {
 #else
-        if(gtk_source_search_context_backward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
+    if(gtk_source_search_context_backward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
 #endif
-        get_buffer()->select_range(match_start, match_end);
-        scroll_to(get_buffer()->get_insert());
-    }
+    get_buffer()->select_range(match_start, match_end);
+    scroll_to(get_buffer()->get_insert());
+  }
 }
 
 void Source::View::replace_forward(const std::string &replacement) {
-    Gtk::TextIter insert, selection_bound;
-    get_buffer()->get_selection_bounds(insert, selection_bound);
-    auto &start = insert;
-    Gtk::TextIter match_start, match_end;
+  Gtk::TextIter insert, selection_bound;
+  get_buffer()->get_selection_bounds(insert, selection_bound);
+  auto &start = insert;
+  Gtk::TextIter match_start, match_end;
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-    gboolean has_wrapped_around;
-    if (gtk_source_search_context_forward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
-                                           &has_wrapped_around)) {
+  gboolean has_wrapped_around;
+  if (gtk_source_search_context_forward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
+                                         &has_wrapped_around)) {
 #else
-        if(gtk_source_search_context_forward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
+    if(gtk_source_search_context_forward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
 #endif
-        auto offset = match_start.get_offset();
+    auto offset = match_start.get_offset();
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-        gtk_source_search_context_replace2(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(),
-                                           replacement.size(), nullptr);
+    gtk_source_search_context_replace2(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(),
+                                       replacement.size(), nullptr);
 #else
-        gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
+    gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
 #endif
 
-        Glib::ustring replacement_ustring = replacement;
-        get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset),
-                                   get_buffer()->get_iter_at_offset(offset + replacement_ustring.size()));
-        scroll_to(get_buffer()->get_insert());
-    }
+    Glib::ustring replacement_ustring = replacement;
+    get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset),
+                               get_buffer()->get_iter_at_offset(offset + replacement_ustring.size()));
+    scroll_to(get_buffer()->get_insert());
+  }
 }
 
 void Source::View::replace_backward(const std::string &replacement) {
-    Gtk::TextIter insert, selection_bound;
-    get_buffer()->get_selection_bounds(insert, selection_bound);
-    auto &start = selection_bound;
-    Gtk::TextIter match_start, match_end;
+  Gtk::TextIter insert, selection_bound;
+  get_buffer()->get_selection_bounds(insert, selection_bound);
+  auto &start = selection_bound;
+  Gtk::TextIter match_start, match_end;
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-    gboolean has_wrapped_around;
-    if (gtk_source_search_context_backward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
-                                            &has_wrapped_around)) {
+  gboolean has_wrapped_around;
+  if (gtk_source_search_context_backward2(search_context, start.gobj(), match_start.gobj(), match_end.gobj(),
+                                          &has_wrapped_around)) {
 #else
-        if(gtk_source_search_context_backward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
+    if(gtk_source_search_context_backward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) {
 #endif
-        auto offset = match_start.get_offset();
+    auto offset = match_start.get_offset();
 #if defined(GTK_SOURCE_MAJOR_VERSION) && (GTK_SOURCE_MAJOR_VERSION > 3 || (GTK_SOURCE_MAJOR_VERSION == 3 && GTK_SOURCE_MINOR_VERSION >= 22))
-        gtk_source_search_context_replace2(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(),
-                                           replacement.size(), nullptr);
+    gtk_source_search_context_replace2(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(),
+                                       replacement.size(), nullptr);
 #else
-        gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
+    gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
 #endif
 
-        get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset),
-                                   get_buffer()->get_iter_at_offset(offset + replacement.size()));
-        scroll_to(get_buffer()->get_insert());
-    }
+    get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset),
+                               get_buffer()->get_iter_at_offset(offset + replacement.size()));
+    scroll_to(get_buffer()->get_insert());
+  }
 }
 
 void Source::View::replace_all(const std::string &replacement) {
-    gtk_source_search_context_replace_all(search_context, replacement.c_str(), replacement.size(), nullptr);
+  gtk_source_search_context_replace_all(search_context, replacement.c_str(), replacement.size(), nullptr);
 }
 
 void Source::View::paste() {
-    class Guard {
-    public:
-        bool &value;
+  class Guard {
+  public:
+    bool &value;
 
-        Guard(bool &value_) : value(value_) { value = true; }
-
-        ~Guard() { value = false; }
-    };
-    Guard guard{multiple_cursors_use};
+    Guard(bool &value_) : value(value_) { value = true; }
 
-    std::string text = Gtk::Clipboard::get()->wait_for_text();
+    ~Guard() { value = false; }
+  };
+  Guard guard{multiple_cursors_use};
 
-    //Replace carriage returns (which leads to crash) with newlines
-    for (size_t c = 0; c < text.size(); c++) {
-        if (text[c] == '\r') {
-            if ((c + 1) < text.size() && text[c + 1] == '\n')
-                text.replace(c, 2, "\n");
-            else
-                text.replace(c, 1, "\n");
-        }
-    }
+  std::string text = Gtk::Clipboard::get()->wait_for_text();
 
-    //Exception for when pasted text is only whitespaces
-    bool only_whitespaces = true;
-    for (auto &chr: text) {
-        if (chr != '\n' && chr != '\r' && chr != ' ' && chr != '\t') {
-            only_whitespaces = false;
-            break;
-        }
-    }
-    if (only_whitespaces) {
-        Gtk::Clipboard::get()->set_text(text);
-        get_buffer()->paste_clipboard(Gtk::Clipboard::get());
-        scroll_to_cursor_delayed(this, false, false);
-        return;
+  //Replace carriage returns (which leads to crash) with newlines
+  for (size_t c = 0; c < text.size(); c++) {
+    if (text[c] == '\r') {
+      if ((c + 1) < text.size() && text[c + 1] == '\n')
+        text.replace(c, 2, "\n");
+      else
+        text.replace(c, 1, "\n");
     }
+  }
 
-    get_buffer()->begin_user_action();
-    if (get_buffer()->get_has_selection()) {
-        Gtk::TextIter start, end;
-        get_buffer()->get_selection_bounds(start, end);
-        get_buffer()->erase(start, end);
+  //Exception for when pasted text is only whitespaces
+  bool only_whitespaces = true;
+  for (auto &chr: text) {
+    if (chr != '\n' && chr != '\r' && chr != ' ' && chr != '\t') {
+      only_whitespaces = false;
+      break;
     }
-    auto iter = get_buffer()->get_insert()->get_iter();
-    auto tabs_end_iter = get_tabs_end_iter();
-    auto prefix_tabs = get_line_before(iter < tabs_end_iter ? iter : tabs_end_iter);
-
-    size_t start_line = 0;
-    size_t end_line = 0;
-    bool paste_line = false;
-    bool first_paste_line = true;
-    size_t paste_line_tabs = -1;
-    bool first_paste_line_has_tabs = false;
-    for (size_t c = 0; c < text.size(); c++) {
-        if (text[c] == '\n') {
-            end_line = c;
-            paste_line = true;
-        } else if (c == text.size() - 1) {
-            end_line = c + 1;
-            paste_line = true;
-        }
-        if (paste_line) {
-            bool empty_line = true;
-            std::string line = text.substr(start_line, end_line - start_line);
-            size_t tabs = 0;
-            for (auto chr: line) {
-                if (chr == tab_char)
-                    tabs++;
-                else {
-                    empty_line = false;
-                    break;
-                }
-            }
-            if (first_paste_line) {
-                if (tabs != 0) {
-                    first_paste_line_has_tabs = true;
-                    paste_line_tabs = tabs;
-                }
-                first_paste_line = false;
-            } else if (!empty_line)
-                paste_line_tabs = std::min(paste_line_tabs, tabs);
+  }
+  if (only_whitespaces) {
+    Gtk::Clipboard::get()->set_text(text);
+    get_buffer()->paste_clipboard(Gtk::Clipboard::get());
+    scroll_to_cursor_delayed(this, false, false);
+    return;
+  }
 
-            start_line = end_line + 1;
-            paste_line = false;
+  get_buffer()->begin_user_action();
+  if (get_buffer()->get_has_selection()) {
+    Gtk::TextIter start, end;
+    get_buffer()->get_selection_bounds(start, end);
+    get_buffer()->erase(start, end);
+  }
+  auto iter = get_buffer()->get_insert()->get_iter();
+  auto tabs_end_iter = get_tabs_end_iter();
+  auto prefix_tabs = get_line_before(iter < tabs_end_iter ? iter : tabs_end_iter);
+
+  size_t start_line = 0;
+  size_t end_line = 0;
+  bool paste_line = false;
+  bool first_paste_line = true;
+  size_t paste_line_tabs = -1;
+  bool first_paste_line_has_tabs = false;
+  for (size_t c = 0; c < text.size(); c++) {
+    if (text[c] == '\n') {
+      end_line = c;
+      paste_line = true;
+    } else if (c == text.size() - 1) {
+      end_line = c + 1;
+      paste_line = true;
+    }
+    if (paste_line) {
+      bool empty_line = true;
+      std::string line = text.substr(start_line, end_line - start_line);
+      size_t tabs = 0;
+      for (auto chr: line) {
+        if (chr == tab_char)
+          tabs++;
+        else {
+          empty_line = false;
+          break;
         }
-    }
-    if (paste_line_tabs == static_cast<size_t>(-1))
-        paste_line_tabs = 0;
-    start_line = 0;
-    end_line = 0;
-    paste_line = false;
-    first_paste_line = true;
-    for (size_t c = 0; c < text.size(); c++) {
-        if (text[c] == '\n') {
-            end_line = c;
-            paste_line = true;
-        } else if (c == text.size() - 1) {
-            end_line = c + 1;
-            paste_line = true;
+      }
+      if (first_paste_line) {
+        if (tabs != 0) {
+          first_paste_line_has_tabs = true;
+          paste_line_tabs = tabs;
         }
-        if (paste_line) {
-            std::string line = text.substr(start_line, end_line - start_line);
-            size_t line_tabs = 0;
-            for (auto chr: line) {
-                if (chr == tab_char)
-                    line_tabs++;
-                else
-                    break;
-            }
-            auto tabs = paste_line_tabs;
-            if (!(first_paste_line && !first_paste_line_has_tabs) && line_tabs < paste_line_tabs) {
-                tabs = line_tabs;
-            }
+        first_paste_line = false;
+      } else if (!empty_line)
+        paste_line_tabs = std::min(paste_line_tabs, tabs);
 
-            if (first_paste_line) {
-                if (first_paste_line_has_tabs)
-                    get_buffer()->insert_at_cursor(text.substr(start_line + tabs, end_line - start_line - tabs));
-                else
-                    get_buffer()->insert_at_cursor(text.substr(start_line, end_line - start_line));
-                first_paste_line = false;
-            } else
-                get_buffer()->insert_at_cursor(
-                        '\n' + prefix_tabs + text.substr(start_line + tabs, end_line - start_line - tabs));
-            start_line = end_line + 1;
-            paste_line = false;
-        }
+      start_line = end_line + 1;
+      paste_line = false;
     }
-    // add final newline if present in text
-    if (text.size() > 0 && text.back() == '\n')
-        get_buffer()->insert_at_cursor('\n' + prefix_tabs);
-    get_buffer()->place_cursor(get_buffer()->get_insert()->get_iter());
-    get_buffer()->end_user_action();
-    scroll_to_cursor_delayed(this, false, false);
+  }
+  if (paste_line_tabs == static_cast<size_t>(-1))
+    paste_line_tabs = 0;
+  start_line = 0;
+  end_line = 0;
+  paste_line = false;
+  first_paste_line = true;
+  for (size_t c = 0; c < text.size(); c++) {
+    if (text[c] == '\n') {
+      end_line = c;
+      paste_line = true;
+    } else if (c == text.size() - 1) {
+      end_line = c + 1;
+      paste_line = true;
+    }
+    if (paste_line) {
+      std::string line = text.substr(start_line, end_line - start_line);
+      size_t line_tabs = 0;
+      for (auto chr: line) {
+        if (chr == tab_char)
+          line_tabs++;
+        else
+          break;
+      }
+      auto tabs = paste_line_tabs;
+      if (!(first_paste_line && !first_paste_line_has_tabs) && line_tabs < paste_line_tabs) {
+        tabs = line_tabs;
+      }
+
+      if (first_paste_line) {
+        if (first_paste_line_has_tabs)
+          get_buffer()->insert_at_cursor(text.substr(start_line + tabs, end_line - start_line - tabs));
+        else
+          get_buffer()->insert_at_cursor(text.substr(start_line, end_line - start_line));
+        first_paste_line = false;
+      } else
+        get_buffer()->insert_at_cursor(
+            '\n' + prefix_tabs + text.substr(start_line + tabs, end_line - start_line - tabs));
+      start_line = end_line + 1;
+      paste_line = false;
+    }
+  }
+  // add final newline if present in text
+  if (text.size() > 0 && text.back() == '\n')
+    get_buffer()->insert_at_cursor('\n' + prefix_tabs);
+  get_buffer()->place_cursor(get_buffer()->get_insert()->get_iter());
+  get_buffer()->end_user_action();
+  scroll_to_cursor_delayed(this, false, false);
 }
 
 void Source::View::hide_tooltips() {
-    delayed_tooltips_connection.disconnect();
-    type_tooltips.hide();
-    diagnostic_tooltips.hide();
+  delayed_tooltips_connection.disconnect();
+  type_tooltips.hide();
+  diagnostic_tooltips.hide();
 }
 
 void Source::View::add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, std::string spelling,
                                           bool error) {
-    diagnostic_offsets.emplace(start.get_offset());
+  diagnostic_offsets.emplace(start.get_offset());
 
-    std::string severity_tag_name = error ? "def:error" : "def:warning";
+  std::string severity_tag_name = error ? "def:error" : "def:warning";
 
-    auto create_tooltip_buffer = [this, spelling = std::move(spelling), error, severity_tag_name]() {
-        auto tooltip_buffer = Gtk::TextBuffer::create(get_buffer()->get_tag_table());
-        tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), error ? "Error" : "Warning",
-                                        severity_tag_name);
-        tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), ":\n" + spelling);
-        return tooltip_buffer;
-    };
-    diagnostic_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start),
-                                     get_buffer()->create_mark(end));
+  auto create_tooltip_buffer = [this, spelling = std::move(spelling), error, severity_tag_name]() {
+    auto tooltip_buffer = Gtk::TextBuffer::create(get_buffer()->get_tag_table());
+    tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), error ? "Error" : "Warning",
+                                    severity_tag_name);
+    tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), ":\n" + spelling);
+    return tooltip_buffer;
+  };
+  diagnostic_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start),
+                                   get_buffer()->create_mark(end));
 
-    get_buffer()->apply_tag_by_name(severity_tag_name + "_underline", start, end);
+  get_buffer()->apply_tag_by_name(severity_tag_name + "_underline", start, end);
 
-    auto iter = get_buffer()->get_insert()->get_iter();
-    if (iter.ends_line()) {
-        auto next_iter = iter;
-        if (next_iter.forward_char())
-            get_buffer()->remove_tag_by_name(severity_tag_name + "_underline", iter, next_iter);
-    }
+  auto iter = get_buffer()->get_insert()->get_iter();
+  if (iter.ends_line()) {
+    auto next_iter = iter;
+    if (next_iter.forward_char())
+      get_buffer()->remove_tag_by_name(severity_tag_name + "_underline", iter, next_iter);
+  }
 }
 
 void Source::View::clear_diagnostic_tooltips() {
-    diagnostic_offsets.clear();
-    diagnostic_tooltips.clear();
-    get_buffer()->remove_tag_by_name("def:warning_underline", get_buffer()->begin(), get_buffer()->end());
-    get_buffer()->remove_tag_by_name("def:error_underline", get_buffer()->begin(), get_buffer()->end());
+  diagnostic_offsets.clear();
+  diagnostic_tooltips.clear();
+  get_buffer()->remove_tag_by_name("def:warning_underline", get_buffer()->begin(), get_buffer()->end());
+  get_buffer()->remove_tag_by_name("def:error_underline", get_buffer()->begin(), get_buffer()->end());
 }
 
 void Source::View::hide_dialogs() {
-    SpellCheckView::hide_dialogs();
-    if (SelectionDialog::get())
-        SelectionDialog::get()->hide();
-    if (CompletionDialog::get())
-        CompletionDialog::get()->hide();
+  SpellCheckView::hide_dialogs();
+  if (SelectionDialog::get())
+    SelectionDialog::get()->hide();
+  if (CompletionDialog::get())
+    CompletionDialog::get()->hide();
 }
 
 bool Source::View::find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
-    long para_count = 0;
-    long square_count = 0;
-    long curly_count = 0;
-
-    do {
-        if (*iter == '(' && is_code_iter(iter))
-            para_count++;
-        else if (*iter == ')' && is_code_iter(iter))
-            para_count--;
-        else if (*iter == '[' && is_code_iter(iter))
-            square_count++;
-        else if (*iter == ']' && is_code_iter(iter))
-            square_count--;
-        else if (*iter == '{' && is_code_iter(iter))
-            curly_count++;
-        else if (*iter == '}' && is_code_iter(iter))
-            curly_count--;
-
-        if (curly_count > 0)
-            break;
-
-        if (para_count > 0 || square_count > 0) {
-            found_iter = iter;
-            return true;
-        }
-    } while (iter.backward_char());
-    return false;
+  long para_count = 0;
+  long square_count = 0;
+  long curly_count = 0;
+
+  do {
+    if (*iter == '(' && is_code_iter(iter))
+      para_count++;
+    else if (*iter == ')' && is_code_iter(iter))
+      para_count--;
+    else if (*iter == '[' && is_code_iter(iter))
+      square_count++;
+    else if (*iter == ']' && is_code_iter(iter))
+      square_count--;
+    else if (*iter == '{' && is_code_iter(iter))
+      curly_count++;
+    else if (*iter == '}' && is_code_iter(iter))
+      curly_count--;
+
+    if (curly_count > 0)
+      break;
+
+    if (para_count > 0 || square_count > 0) {
+      found_iter = iter;
+      return true;
+    }
+  } while (iter.backward_char());
+  return false;
 }
 
 Gtk::TextIter Source::View::find_start_of_sentence(Gtk::TextIter iter) {
-    if (iter.starts_line())
-        return iter;
-
-    bool stream_operator_test = false;
-    bool colon_test = false;
-
-    if (*iter == ';')
-        stream_operator_test = true;
-    if (*iter == '{') {
-        iter.backward_char();
-        colon_test = true;
-    }
-
-    int para_count = 0;
-    int square_count = 0;
-    long curly_count = 0;
+  if (iter.starts_line())
+    return iter;
 
-    do {
-        if (*iter == '(' && is_code_iter(iter))
-            para_count++;
-        else if (*iter == ')' && is_code_iter(iter))
-            para_count--;
-        else if (*iter == '[' && is_code_iter(iter))
-            square_count++;
-        else if (*iter == ']' && is_code_iter(iter))
-            square_count--;
-        else if (*iter == '{' && is_code_iter(iter))
-            curly_count++;
-        else if (*iter == '}' && is_code_iter(iter))
-            curly_count--;
-
-        if (curly_count > 0)
-            break;
+  bool stream_operator_test = false;
+  bool colon_test = false;
 
-        if (iter.starts_line() && para_count == 0 && square_count == 0) {
-            bool stream_operator_found = false;
-            bool colon_found = false;
-            // Handle << at the beginning of the sentence if iter initially started with ;
-            if (stream_operator_test) {
-                auto test_iter = get_tabs_end_iter(iter);
-                if (!test_iter.starts_line() && *test_iter == '<' && is_code_iter(test_iter) &&
-                    test_iter.forward_char() && *test_iter == '<')
-                    stream_operator_found = true;
-            }
-                // Handle : at the beginning of the sentence if iter initially started with {
-            else if (colon_test) {
-                auto test_iter = get_tabs_end_iter(iter);
-                if (!test_iter.starts_line() && *test_iter == ':' && is_code_iter(test_iter))
-                    colon_found = true;
-            }
-            // Handle : and , on previous line
-            if (!stream_operator_found && !colon_found) {
-                auto previous_iter = iter;
-                previous_iter.backward_char();
-                while (!previous_iter.starts_line() && (*previous_iter == ' ' || previous_iter.ends_line()) &&
-                       previous_iter.backward_char()) {}
-                if (*previous_iter != ',' && *previous_iter != ':')
-                    return iter;
-                else if (*previous_iter == ':') {
-                    previous_iter.backward_char();
-                    while (!previous_iter.starts_line() && *previous_iter == ' ' && previous_iter.backward_char()) {}
-                    if (*previous_iter == ')') {
-                        auto token = get_token(
-                                get_tabs_end_iter(get_buffer()->get_iter_at_line(previous_iter.get_line())));
-                        if (token == "case")
-                            return iter;
-                    } else
-                        return iter;
-                }
-            }
-        }
-    } while (iter.backward_char());
+  if (*iter == ';')
+    stream_operator_test = true;
+  if (*iter == '{') {
+    iter.backward_char();
+    colon_test = true;
+  }
 
-    return iter;
+  int para_count = 0;
+  int square_count = 0;
+  long curly_count = 0;
+
+  do {
+    if (*iter == '(' && is_code_iter(iter))
+      para_count++;
+    else if (*iter == ')' && is_code_iter(iter))
+      para_count--;
+    else if (*iter == '[' && is_code_iter(iter))
+      square_count++;
+    else if (*iter == ']' && is_code_iter(iter))
+      square_count--;
+    else if (*iter == '{' && is_code_iter(iter))
+      curly_count++;
+    else if (*iter == '}' && is_code_iter(iter))
+      curly_count--;
+
+    if (curly_count > 0)
+      break;
+
+    if (iter.starts_line() && para_count == 0 && square_count == 0) {
+      bool stream_operator_found = false;
+      bool colon_found = false;
+      // Handle << at the beginning of the sentence if iter initially started with ;
+      if (stream_operator_test) {
+        auto test_iter = get_tabs_end_iter(iter);
+        if (!test_iter.starts_line() && *test_iter == '<' && is_code_iter(test_iter) &&
+            test_iter.forward_char() && *test_iter == '<')
+          stream_operator_found = true;
+      }
+        // Handle : at the beginning of the sentence if iter initially started with {
+      else if (colon_test) {
+        auto test_iter = get_tabs_end_iter(iter);
+        if (!test_iter.starts_line() && *test_iter == ':' && is_code_iter(test_iter))
+          colon_found = true;
+      }
+      // Handle : and , on previous line
+      if (!stream_operator_found && !colon_found) {
+        auto previous_iter = iter;
+        previous_iter.backward_char();
+        while (!previous_iter.starts_line() && (*previous_iter == ' ' || previous_iter.ends_line()) &&
+               previous_iter.backward_char()) {}
+        if (*previous_iter != ',' && *previous_iter != ':')
+          return iter;
+        else if (*previous_iter == ':') {
+          previous_iter.backward_char();
+          while (!previous_iter.starts_line() && *previous_iter == ' ' && previous_iter.backward_char()) {}
+          if (*previous_iter == ')') {
+            auto token = get_token(
+                get_tabs_end_iter(get_buffer()->get_iter_at_line(previous_iter.get_line())));
+            if (token == "case")
+              return iter;
+          } else
+            return iter;
+        }
+      }
+    }
+  } while (iter.backward_char());
+
+  return iter;
 }
 
 bool Source::View::find_open_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
-    long count = 0;
+  long count = 0;
 
-    do {
-        if (*iter == '{') {
-            if (count == 0 && is_code_iter(iter)) {
-                found_iter = iter;
-                return true;
-            }
-            count++;
-        } else if (*iter == '}' && is_code_iter(iter))
-            count--;
-    } while (iter.backward_char());
-    return false;
+  do {
+    if (*iter == '{') {
+      if (count == 0 && is_code_iter(iter)) {
+        found_iter = iter;
+        return true;
+      }
+      count++;
+    } else if (*iter == '}' && is_code_iter(iter))
+      count--;
+  } while (iter.backward_char());
+  return false;
 }
 
 bool Source::View::find_close_curly_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
-    long count = 0;
+  long count = 0;
 
-    do {
-        if (*iter == '}' && is_code_iter(iter)) {
-            if (count == 0) {
-                found_iter = iter;
-                return true;
-            }
-            count--;
-        } else if (*iter == '{' && is_code_iter(iter))
-            count++;
-    } while (iter.forward_char());
-    return false;
+  do {
+    if (*iter == '}' && is_code_iter(iter)) {
+      if (count == 0) {
+        found_iter = iter;
+        return true;
+      }
+      count--;
+    } else if (*iter == '{' && is_code_iter(iter))
+      count++;
+  } while (iter.forward_char());
+  return false;
 }
 
 long Source::View::symbol_count(Gtk::TextIter iter, unsigned int positive_char, unsigned int negative_char) {
-    auto iter_stored = iter;
-    long symbol_count = 0;
-    long curly_count = 0;
-    bool break_on_curly = true;
-    if (positive_char == '{' || negative_char == '}')
-        break_on_curly = false;
-    bool check_if_next_iter_is_code_iter = false;
-    if (positive_char == '\'' || negative_char == '\'' || positive_char == '"' || negative_char == '"')
-        check_if_next_iter_is_code_iter = true;
-
-    Gtk::TextIter previous_iter;
-    do {
-        if (*iter == positive_char && is_code_iter(iter))
-            symbol_count++;
-        else if (*iter == negative_char && is_code_iter(iter))
-            symbol_count--;
-        else if (*iter == '{' && is_code_iter(iter))
-            curly_count++;
-        else if (*iter == '}' && is_code_iter(iter))
-            curly_count--;
-        else if (check_if_next_iter_is_code_iter) {
-            auto next_iter = iter;
-            next_iter.forward_char();
-            if (*iter == positive_char && is_code_iter(next_iter))
-                symbol_count++;
-            else if (*iter == negative_char && is_code_iter(next_iter))
-                symbol_count--;
-        }
+  auto iter_stored = iter;
+  long symbol_count = 0;
+  long curly_count = 0;
+  bool break_on_curly = true;
+  if (positive_char == '{' || negative_char == '}')
+    break_on_curly = false;
+  bool check_if_next_iter_is_code_iter = false;
+  if (positive_char == '\'' || negative_char == '\'' || positive_char == '"' || negative_char == '"')
+    check_if_next_iter_is_code_iter = true;
+
+  Gtk::TextIter previous_iter;
+  do {
+    if (*iter == positive_char && is_code_iter(iter))
+      symbol_count++;
+    else if (*iter == negative_char && is_code_iter(iter))
+      symbol_count--;
+    else if (*iter == '{' && is_code_iter(iter))
+      curly_count++;
+    else if (*iter == '}' && is_code_iter(iter))
+      curly_count--;
+    else if (check_if_next_iter_is_code_iter) {
+      auto next_iter = iter;
+      next_iter.forward_char();
+      if (*iter == positive_char && is_code_iter(next_iter))
+        symbol_count++;
+      else if (*iter == negative_char && is_code_iter(next_iter))
+        symbol_count--;
+    }
+
+    if (break_on_curly && curly_count > 0)
+      break;
+  } while (iter.backward_char());
+
+  iter = iter_stored;
+  if (!iter.forward_char()) {
+    return symbol_count;
+  }
 
-        if (break_on_curly && curly_count > 0)
-            break;
-    } while (iter.backward_char());
-
-    iter = iter_stored;
-    if (!iter.forward_char()) {
-        return symbol_count;
-    }
-
-    curly_count = 0;
-    do {
-        if (*iter == positive_char && is_code_iter(iter))
-            symbol_count++;
-        else if (*iter == negative_char && is_code_iter(iter))
-            symbol_count--;
-        else if (*iter == '{' && is_code_iter(iter))
-            curly_count++;
-        else if (*iter == '}' && is_code_iter(iter))
-            curly_count--;
-        else if (check_if_next_iter_is_code_iter) {
-            auto next_iter = iter;
-            next_iter.forward_char();
-            if (*iter == positive_char && is_code_iter(next_iter))
-                symbol_count++;
-            else if (*iter == negative_char && is_code_iter(next_iter))
-                symbol_count--;
-        }
-
-        if (break_on_curly && curly_count < 0)
-            break;
-    } while (iter.forward_char());
-
-    return symbol_count;
+  curly_count = 0;
+  do {
+    if (*iter == positive_char && is_code_iter(iter))
+      symbol_count++;
+    else if (*iter == negative_char && is_code_iter(iter))
+      symbol_count--;
+    else if (*iter == '{' && is_code_iter(iter))
+      curly_count++;
+    else if (*iter == '}' && is_code_iter(iter))
+      curly_count--;
+    else if (check_if_next_iter_is_code_iter) {
+      auto next_iter = iter;
+      next_iter.forward_char();
+      if (*iter == positive_char && is_code_iter(next_iter))
+        symbol_count++;
+      else if (*iter == negative_char && is_code_iter(next_iter))
+        symbol_count--;
+    }
+
+    if (break_on_curly && curly_count < 0)
+      break;
+  } while (iter.forward_char());
+
+  return symbol_count;
 }
 
 bool Source::View::is_templated_function(Gtk::TextIter iter, Gtk::TextIter &parenthesis_end_iter) {
-    auto iter_stored = iter;
-    long bracket_count = 0;
-    long curly_count = 0;
+  auto iter_stored = iter;
+  long bracket_count = 0;
+  long curly_count = 0;
 
-    if (!(iter.backward_char() && *iter == '>' && *iter_stored == '('))
-        return false;
-
-    do {
-        if (*iter == '<' && is_code_iter(iter))
-            bracket_count++;
-        else if (*iter == '>' && is_code_iter(iter))
-            bracket_count--;
-        else if (*iter == '{' && is_code_iter(iter))
-            curly_count++;
-        else if (*iter == '}' && is_code_iter(iter))
-            curly_count--;
-
-        if (bracket_count == 0)
-            break;
+  if (!(iter.backward_char() && *iter == '>' && *iter_stored == '('))
+    return false;
 
-        if (curly_count > 0)
-            break;
-    } while (iter.backward_char());
+  do {
+    if (*iter == '<' && is_code_iter(iter))
+      bracket_count++;
+    else if (*iter == '>' && is_code_iter(iter))
+      bracket_count--;
+    else if (*iter == '{' && is_code_iter(iter))
+      curly_count++;
+    else if (*iter == '}' && is_code_iter(iter))
+      curly_count--;
 
-    if (bracket_count != 0)
-        return false;
+    if (bracket_count == 0)
+      break;
 
-    iter = iter_stored;
-    bracket_count = 0;
-    curly_count = 0;
-    do {
-        if (*iter == '(' && is_code_iter(iter))
-            bracket_count++;
-        else if (*iter == ')' && is_code_iter(iter))
-            bracket_count--;
-        else if (*iter == '{' && is_code_iter(iter))
-            curly_count++;
-        else if (*iter == '}' && is_code_iter(iter))
-            curly_count--;
-
-        if (bracket_count == 0) {
-            parenthesis_end_iter = iter;
-            return true;
-        }
-
-        if (curly_count < 0)
-            return false;
-    } while (iter.forward_char());
+    if (curly_count > 0)
+      break;
+  } while (iter.backward_char());
 
+  if (bracket_count != 0)
     return false;
+
+  iter = iter_stored;
+  bracket_count = 0;
+  curly_count = 0;
+  do {
+    if (*iter == '(' && is_code_iter(iter))
+      bracket_count++;
+    else if (*iter == ')' && is_code_iter(iter))
+      bracket_count--;
+    else if (*iter == '{' && is_code_iter(iter))
+      curly_count++;
+    else if (*iter == '}' && is_code_iter(iter))
+      curly_count--;
+
+    if (bracket_count == 0) {
+      parenthesis_end_iter = iter;
+      return true;
+    }
+
+    if (curly_count < 0)
+      return false;
+  } while (iter.forward_char());
+
+  return false;
 }
 
 std::string Source::View::get_token(Gtk::TextIter iter) {
-    auto start = iter;
-    auto end = iter;
-
-    while ((*iter >= 'A' && *iter <= 'Z') || (*iter >= 'a' && *iter <= 'z') || (*iter >= '0' && *iter <= '9') ||
-           *iter == '_') {
-        start = iter;
-        if (!iter.backward_char())
-            break;
-    }
-    while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') ||
-           *end == '_') {
-        if (!end.forward_char())
-            break;
-    }
+  auto start = iter;
+  auto end = iter;
+
+  while ((*iter >= 'A' && *iter <= 'Z') || (*iter >= 'a' && *iter <= 'z') || (*iter >= '0' && *iter <= '9') ||
+         *iter == '_') {
+    start = iter;
+    if (!iter.backward_char())
+      break;
+  }
+  while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') ||
+         *end == '_') {
+    if (!end.forward_char())
+      break;
+  }
 
-    return get_buffer()->get_text(start, end);
+  return get_buffer()->get_text(start, end);
 }
 
 void Source::View::cleanup_whitespace_characters_on_return(const Gtk::TextIter &iter) {
-    auto start_blank_iter = iter;
-    auto end_blank_iter = iter;
-    while ((*end_blank_iter == ' ' || *end_blank_iter == '\t') &&
-           !end_blank_iter.ends_line() && end_blank_iter.forward_char()) {}
-    if (!start_blank_iter.starts_line()) {
-        start_blank_iter.backward_char();
-        while ((*start_blank_iter == ' ' || *start_blank_iter == '\t') &&
-               !start_blank_iter.starts_line() && start_blank_iter.backward_char()) {}
-        if (*start_blank_iter != ' ' && *start_blank_iter != '\t')
-            start_blank_iter.forward_char();
-    }
-
-    if (start_blank_iter.starts_line())
-        get_buffer()->erase(iter, end_blank_iter);
-    else
-        get_buffer()->erase(start_blank_iter, end_blank_iter);
+  auto start_blank_iter = iter;
+  auto end_blank_iter = iter;
+  while ((*end_blank_iter == ' ' || *end_blank_iter == '\t') &&
+         !end_blank_iter.ends_line() && end_blank_iter.forward_char()) {}
+  if (!start_blank_iter.starts_line()) {
+    start_blank_iter.backward_char();
+    while ((*start_blank_iter == ' ' || *start_blank_iter == '\t') &&
+           !start_blank_iter.starts_line() && start_blank_iter.backward_char()) {}
+    if (*start_blank_iter != ' ' && *start_blank_iter != '\t')
+      start_blank_iter.forward_char();
+  }
+
+  if (start_blank_iter.starts_line())
+    get_buffer()->erase(iter, end_blank_iter);
+  else
+    get_buffer()->erase(start_blank_iter, end_blank_iter);
 }
 
 bool Source::View::on_key_press_event(GdkEventKey *key) {
-    class Guard {
-    public:
-        bool &value;
+  class Guard {
+  public:
+    bool &value;
 
-        Guard(bool &value_) : value(value_) { value = true; }
+    Guard(bool &value_) : value(value_) { value = true; }
 
-        ~Guard() { value = false; }
-    };
-    Guard guard{multiple_cursors_use};
+    ~Guard() { value = false; }
+  };
+  Guard guard{multiple_cursors_use};
 
-    if (SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
-        if (SelectionDialog::get()->on_key_press(key))
-            return true;
-    }
-    if (CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
-        if (CompletionDialog::get()->on_key_press(key))
-            return true;
-    }
+  if (SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
+    if (SelectionDialog::get()->on_key_press(key))
+      return true;
+  }
+  if (CompletionDialog::get() && CompletionDialog::get()->is_visible()) {
+    if (CompletionDialog::get()->on_key_press(key))
+      return true;
+  }
 
-    if (last_keyval < GDK_KEY_Shift_L || last_keyval > GDK_KEY_Hyper_R)
-        previous_non_modifier_keyval = last_keyval;
-    last_keyval = key->keyval;
+  if (last_keyval < GDK_KEY_Shift_L || last_keyval > GDK_KEY_Hyper_R)
+    previous_non_modifier_keyval = last_keyval;
+  last_keyval = key->keyval;
 
-    if (Config::get().source.enable_multiple_cursors && on_key_press_event_multiple_cursors(key))
-        return true;
+  if (Config::get().source.enable_multiple_cursors && on_key_press_event_multiple_cursors(key))
+    return true;
 
-    //Move cursor one paragraph down
-    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) && (key->state & GDK_CONTROL_MASK) > 0) {
-        auto selection_start_iter = get_buffer()->get_selection_bound()->get_iter();
-        auto iter = get_buffer()->get_iter_at_line(get_buffer()->get_insert()->get_iter().get_line());
-        bool empty_line = false;
-        bool text_found = false;
-        for (;;) {
-            if (!iter)
-                break;
-            if (iter.starts_line())
-                empty_line = true;
-            if (empty_line && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
-                empty_line = false;
-            if (!text_found && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
-                text_found = true;
-            if (empty_line && text_found && iter.ends_line())
-                break;
-            iter.forward_char();
-        }
-        iter = get_buffer()->get_iter_at_line(iter.get_line());
-        if ((key->state & GDK_SHIFT_MASK) > 0)
-            get_buffer()->select_range(iter, selection_start_iter);
-        else
-            get_buffer()->place_cursor(iter);
-        scroll_to(get_buffer()->get_insert());
-        return true;
-    }
-        //Move cursor one paragraph up
-    else if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) && (key->state & GDK_CONTROL_MASK) > 0) {
-        auto selection_start_iter = get_buffer()->get_selection_bound()->get_iter();
-        auto iter = get_buffer()->get_iter_at_line(get_buffer()->get_insert()->get_iter().get_line());
-        iter.backward_char();
-        bool empty_line = false;
-        bool text_found = false;
-        bool move_to_start = false;
-        for (;;) {
-            if (!iter)
-                break;
-            if (iter.ends_line())
-                empty_line = true;
-            if (empty_line && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
-                empty_line = false;
-            if (!text_found && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
-                text_found = true;
-            if (empty_line && text_found && iter.starts_line())
-                break;
-            if (iter.is_start()) {
-                move_to_start = true;
-                break;
-            }
-            iter.backward_char();
-        }
-        if (empty_line && !move_to_start) {
-            iter = get_iter_at_line_end(iter.get_line());
-            iter.forward_char();
-            if (!iter.starts_line()) // For CR+LF
-                iter.forward_char();
-        }
-        if ((key->state & GDK_SHIFT_MASK) > 0)
-            get_buffer()->select_range(iter, selection_start_iter);
-        else
-            get_buffer()->place_cursor(iter);
-        scroll_to(get_buffer()->get_insert());
-        return true;
+  //Move cursor one paragraph down
+  if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) && (key->state & GDK_CONTROL_MASK) > 0) {
+    auto selection_start_iter = get_buffer()->get_selection_bound()->get_iter();
+    auto iter = get_buffer()->get_iter_at_line(get_buffer()->get_insert()->get_iter().get_line());
+    bool empty_line = false;
+    bool text_found = false;
+    for (;;) {
+      if (!iter)
+        break;
+      if (iter.starts_line())
+        empty_line = true;
+      if (empty_line && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
+        empty_line = false;
+      if (!text_found && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
+        text_found = true;
+      if (empty_line && text_found && iter.ends_line())
+        break;
+      iter.forward_char();
+    }
+    iter = get_buffer()->get_iter_at_line(iter.get_line());
+    if ((key->state & GDK_SHIFT_MASK) > 0)
+      get_buffer()->select_range(iter, selection_start_iter);
+    else
+      get_buffer()->place_cursor(iter);
+    scroll_to(get_buffer()->get_insert());
+    return true;
+  }
+    //Move cursor one paragraph up
+  else if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) && (key->state & GDK_CONTROL_MASK) > 0) {
+    auto selection_start_iter = get_buffer()->get_selection_bound()->get_iter();
+    auto iter = get_buffer()->get_iter_at_line(get_buffer()->get_insert()->get_iter().get_line());
+    iter.backward_char();
+    bool empty_line = false;
+    bool text_found = false;
+    bool move_to_start = false;
+    for (;;) {
+      if (!iter)
+        break;
+      if (iter.ends_line())
+        empty_line = true;
+      if (empty_line && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
+        empty_line = false;
+      if (!text_found && !iter.ends_line() && *iter != '\n' && *iter != ' ' && *iter != '\t')
+        text_found = true;
+      if (empty_line && text_found && iter.starts_line())
+        break;
+      if (iter.is_start()) {
+        move_to_start = true;
+        break;
+      }
+      iter.backward_char();
+    }
+    if (empty_line && !move_to_start) {
+      iter = get_iter_at_line_end(iter.get_line());
+      iter.forward_char();
+      if (!iter.starts_line()) // For CR+LF
+        iter.forward_char();
     }
+    if ((key->state & GDK_SHIFT_MASK) > 0)
+      get_buffer()->select_range(iter, selection_start_iter);
+    else
+      get_buffer()->place_cursor(iter);
+    scroll_to(get_buffer()->get_insert());
+    return true;
+  }
 
-    get_buffer()->begin_user_action();
+  get_buffer()->begin_user_action();
 
-    // Shift+enter: go to end of line and enter
-    if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) && (key->state & GDK_SHIFT_MASK) > 0) {
-        auto iter = get_buffer()->get_insert()->get_iter();
-        if (!iter.ends_line()) {
-            iter.forward_to_line_end();
-            get_buffer()->place_cursor(iter);
-        }
+  // Shift+enter: go to end of line and enter
+  if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) && (key->state & GDK_SHIFT_MASK) > 0) {
+    auto iter = get_buffer()->get_insert()->get_iter();
+    if (!iter.ends_line()) {
+      iter.forward_to_line_end();
+      get_buffer()->place_cursor(iter);
     }
+  }
 
-    if (Config::get().source.smart_brackets && on_key_press_event_smart_brackets(key)) {
-        get_buffer()->end_user_action();
-        return true;
-    }
-    if (Config::get().source.smart_inserts && on_key_press_event_smart_inserts(key)) {
-        get_buffer()->end_user_action();
-        return true;
-    }
+  if (Config::get().source.smart_brackets && on_key_press_event_smart_brackets(key)) {
+    get_buffer()->end_user_action();
+    return true;
+  }
+  if (Config::get().source.smart_inserts && on_key_press_event_smart_inserts(key)) {
+    get_buffer()->end_user_action();
+    return true;
+  }
 
-    if (is_bracket_language && on_key_press_event_bracket_language(key)) {
-        get_buffer()->end_user_action();
-        return true;
-    } else if (on_key_press_event_basic(key)) {
-        get_buffer()->end_user_action();
-        return true;
-    } else {
-        get_buffer()->end_user_action();
-        return Gsv::View::on_key_press_event(key);
-    }
+  if (is_bracket_language && on_key_press_event_bracket_language(key)) {
+    get_buffer()->end_user_action();
+    return true;
+  } else if (on_key_press_event_basic(key)) {
+    get_buffer()->end_user_action();
+    return true;
+  } else {
+    get_buffer()->end_user_action();
+    return Gsv::View::on_key_press_event(key);
+  }
 }
 
 //Basic indentation
 bool Source::View::on_key_press_event_basic(GdkEventKey *key) {
-    auto iter = get_buffer()->get_insert()->get_iter();
+  auto iter = get_buffer()->get_insert()->get_iter();
 
-    //Indent as in next or previous line
-    if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) && !get_buffer()->get_has_selection() &&
-        !iter.starts_line()) {
-        cleanup_whitespace_characters_on_return(iter);
-
-        iter = get_buffer()->get_insert()->get_iter();
-        auto tabs = get_line_before(get_tabs_end_iter(iter));
-
-        int line_nr = iter.get_line();
-        if (iter.ends_line() && (line_nr + 1) < get_buffer()->get_line_count()) {
-            auto next_line_tabs = get_line_before(get_tabs_end_iter(line_nr + 1));
-            if (next_line_tabs.size() > tabs.size()) {
-                get_buffer()->insert_at_cursor("\n" + next_line_tabs);
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
-        }
-        get_buffer()->insert_at_cursor("\n" + tabs);
-        scroll_to(get_buffer()->get_insert());
-        return true;
-    } else if (key->keyval == GDK_KEY_Tab && (key->state & GDK_SHIFT_MASK) == 0) {
-        if (!Config::get().source.tab_indents_line && !get_buffer()->get_has_selection()) {
-            get_buffer()->insert_at_cursor(tab);
-            return true;
-        }
-        //Indent right when clicking tab, no matter where in the line the cursor is. Also works on selected text.
-        //Special case if insert is at beginning of empty line:
-        if (iter.starts_line() && iter.ends_line() && !get_buffer()->get_has_selection()) {
-            auto prev_line_iter = iter;
-            while (prev_line_iter.starts_line() && prev_line_iter.backward_char()) {}
-            auto prev_line_tabs_end_iter = get_tabs_end_iter(prev_line_iter);
-            auto previous_line_tabs = get_line_before(prev_line_tabs_end_iter);
+  //Indent as in next or previous line
+  if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) && !get_buffer()->get_has_selection() &&
+      !iter.starts_line()) {
+    cleanup_whitespace_characters_on_return(iter);
 
-            auto next_line_iter = iter;
-            while (next_line_iter.starts_line() && next_line_iter.forward_char()) {}
-            auto next_line_tabs_end_iter = get_tabs_end_iter(next_line_iter);
-            auto next_line_tabs = get_line_before(next_line_tabs_end_iter);
-
-            std::string tabs;
-            if (previous_line_tabs.size() < next_line_tabs.size())
-                tabs = previous_line_tabs;
-            else
-                tabs = next_line_tabs;
-            if (tabs.size() >= tab_size) {
-                get_buffer()->insert_at_cursor(tabs);
-                return true;
-            }
-        }
+    iter = get_buffer()->get_insert()->get_iter();
+    auto tabs = get_line_before(get_tabs_end_iter(iter));
 
-        Gtk::TextIter selection_start, selection_end;
-        get_buffer()->get_selection_bounds(selection_start, selection_end);
-        auto selection_end_mark = get_buffer()->create_mark(selection_end);
-        int line_start = selection_start.get_line();
-        int line_end = selection_end.get_line();
-        for (int line = line_start; line <= line_end; line++) {
-            Gtk::TextIter line_it = get_buffer()->get_iter_at_line(line);
-            if (!get_buffer()->get_has_selection() || line_it != selection_end_mark->get_iter())
-                get_buffer()->insert(line_it, tab);
-        }
-        get_buffer()->delete_mark(selection_end_mark);
+    int line_nr = iter.get_line();
+    if (iter.ends_line() && (line_nr + 1) < get_buffer()->get_line_count()) {
+      auto next_line_tabs = get_line_before(get_tabs_end_iter(line_nr + 1));
+      if (next_line_tabs.size() > tabs.size()) {
+        get_buffer()->insert_at_cursor("\n" + next_line_tabs);
+        scroll_to(get_buffer()->get_insert());
         return true;
+      }
     }
-        //Indent left when clicking shift-tab, no matter where in the line the cursor is. Also works on selected text.
-    else if ((key->keyval == GDK_KEY_ISO_Left_Tab || key->keyval == GDK_KEY_Tab) && (key->state & GDK_SHIFT_MASK) > 0) {
-        Gtk::TextIter selection_start, selection_end;
-        get_buffer()->get_selection_bounds(selection_start, selection_end);
-        int line_start = selection_start.get_line();
-        int line_end = selection_end.get_line();
-
-        unsigned indent_left_steps = tab_size;
-        std::vector<bool> ignore_line;
-        for (int line_nr = line_start; line_nr <= line_end; line_nr++) {
-            auto line_it = get_buffer()->get_iter_at_line(line_nr);
-            if (!get_buffer()->get_has_selection() || line_it != selection_end) {
-                auto tabs_end_iter = get_tabs_end_iter(line_nr);
-                if (tabs_end_iter.starts_line() && tabs_end_iter.ends_line())
-                    ignore_line.push_back(true);
-                else {
-                    auto line_tabs = get_line_before(tabs_end_iter);
-
-                    if (line_tabs.size() > 0) {
-                        indent_left_steps = std::min(indent_left_steps, static_cast<unsigned>(line_tabs.size()));
-                        ignore_line.push_back(false);
-                    } else
-                        return true;
-                }
-            }
-        }
-
-        for (int line_nr = line_start; line_nr <= line_end; line_nr++) {
-            Gtk::TextIter line_it = get_buffer()->get_iter_at_line(line_nr);
-            Gtk::TextIter line_plus_it = line_it;
-            if (!get_buffer()->get_has_selection() || line_it != selection_end) {
-                line_plus_it.forward_chars(indent_left_steps);
-                if (!ignore_line.at(line_nr - line_start))
-                    get_buffer()->erase(line_it, line_plus_it);
-            }
-        }
+    get_buffer()->insert_at_cursor("\n" + tabs);
+    scroll_to(get_buffer()->get_insert());
+    return true;
+  } else if (key->keyval == GDK_KEY_Tab && (key->state & GDK_SHIFT_MASK) == 0) {
+    if (!Config::get().source.tab_indents_line && !get_buffer()->get_has_selection()) {
+      get_buffer()->insert_at_cursor(tab);
+      return true;
+    }
+    //Indent right when clicking tab, no matter where in the line the cursor is. Also works on selected text.
+    //Special case if insert is at beginning of empty line:
+    if (iter.starts_line() && iter.ends_line() && !get_buffer()->get_has_selection()) {
+      auto prev_line_iter = iter;
+      while (prev_line_iter.starts_line() && prev_line_iter.backward_char()) {}
+      auto prev_line_tabs_end_iter = get_tabs_end_iter(prev_line_iter);
+      auto previous_line_tabs = get_line_before(prev_line_tabs_end_iter);
+
+      auto next_line_iter = iter;
+      while (next_line_iter.starts_line() && next_line_iter.forward_char()) {}
+      auto next_line_tabs_end_iter = get_tabs_end_iter(next_line_iter);
+      auto next_line_tabs = get_line_before(next_line_tabs_end_iter);
+
+      std::string tabs;
+      if (previous_line_tabs.size() < next_line_tabs.size())
+        tabs = previous_line_tabs;
+      else
+        tabs = next_line_tabs;
+      if (tabs.size() >= tab_size) {
+        get_buffer()->insert_at_cursor(tabs);
         return true;
+      }
     }
-        //"Smart" backspace key
-    else if (key->keyval == GDK_KEY_BackSpace && !get_buffer()->get_has_selection()) {
-        auto line = get_line_before();
-        bool do_smart_backspace = true;
-        for (auto &chr: line) {
-            if (chr != ' ' && chr != '\t') {
-                do_smart_backspace = false;
-                break;
-            }
-        }
-        if (iter.get_line() == 0) // Special case since there are no previous line
-            do_smart_backspace = false;
-        if (do_smart_backspace) {
-            auto previous_line_end_iter = iter;
-            if (previous_line_end_iter.backward_chars(line.size() + 1)) {
-                if (!previous_line_end_iter.ends_line()) // For CR+LF
-                    previous_line_end_iter.backward_char();
-                if (previous_line_end_iter.starts_line()) // When previous line is empty, keep tabs in current line
-                    get_buffer()->erase(previous_line_end_iter, get_buffer()->get_iter_at_line(iter.get_line()));
-                else
-                    get_buffer()->erase(previous_line_end_iter, iter);
-                return true;
-            }
-        }
+
+    Gtk::TextIter selection_start, selection_end;
+    get_buffer()->get_selection_bounds(selection_start, selection_end);
+    auto selection_end_mark = get_buffer()->create_mark(selection_end);
+    int line_start = selection_start.get_line();
+    int line_end = selection_end.get_line();
+    for (int line = line_start; line <= line_end; line++) {
+      Gtk::TextIter line_it = get_buffer()->get_iter_at_line(line);
+      if (!get_buffer()->get_has_selection() || line_it != selection_end_mark->get_iter())
+        get_buffer()->insert(line_it, tab);
     }
-        //"Smart" delete key
-    else if (key->keyval == GDK_KEY_Delete && !get_buffer()->get_has_selection()) {
-        auto insert_iter = iter;
-        bool do_smart_delete = true;
-        do {
-            if (*iter != ' ' && *iter != '\t' && !iter.ends_line()) {
-                do_smart_delete = false;
-                break;
-            }
-            if (iter.ends_line()) {
-                if (*iter == '\r') // For CR+LF
-                    iter.forward_char();
-                if (!iter.forward_char())
-                    do_smart_delete = false;
-                break;
-            }
-        } while (iter.forward_char());
-        if (do_smart_delete) {
-            if (!insert_iter.starts_line()) {
-                while ((*iter == ' ' || *iter == '\t') && iter.forward_char()) {}
-            }
-            get_buffer()->erase(insert_iter, iter);
+    get_buffer()->delete_mark(selection_end_mark);
+    return true;
+  }
+    //Indent left when clicking shift-tab, no matter where in the line the cursor is. Also works on selected text.
+  else if ((key->keyval == GDK_KEY_ISO_Left_Tab || key->keyval == GDK_KEY_Tab) && (key->state & GDK_SHIFT_MASK) > 0) {
+    Gtk::TextIter selection_start, selection_end;
+    get_buffer()->get_selection_bounds(selection_start, selection_end);
+    int line_start = selection_start.get_line();
+    int line_end = selection_end.get_line();
+
+    unsigned indent_left_steps = tab_size;
+    std::vector<bool> ignore_line;
+    for (int line_nr = line_start; line_nr <= line_end; line_nr++) {
+      auto line_it = get_buffer()->get_iter_at_line(line_nr);
+      if (!get_buffer()->get_has_selection() || line_it != selection_end) {
+        auto tabs_end_iter = get_tabs_end_iter(line_nr);
+        if (tabs_end_iter.starts_line() && tabs_end_iter.ends_line())
+          ignore_line.push_back(true);
+        else {
+          auto line_tabs = get_line_before(tabs_end_iter);
+
+          if (line_tabs.size() > 0) {
+            indent_left_steps = std::min(indent_left_steps, static_cast<unsigned>(line_tabs.size()));
+            ignore_line.push_back(false);
+          } else
             return true;
         }
+      }
     }
-        // Smart Home/End-keys
-    else if ((key->keyval == GDK_KEY_Home || key->keyval == GDK_KEY_KP_Home) && (key->state & GDK_CONTROL_MASK) == 0) {
-        if ((key->state & GDK_SHIFT_MASK) > 0)
-            get_buffer()->move_mark_by_name("insert", get_smart_home_iter(iter));
-        else
-            get_buffer()->place_cursor(get_smart_home_iter(iter));
-        scroll_to(get_buffer()->get_insert());
-        return true;
-    } else if ((key->keyval == GDK_KEY_End || key->keyval == GDK_KEY_KP_End) && (key->state & GDK_CONTROL_MASK) == 0) {
-        if ((key->state & GDK_SHIFT_MASK) > 0)
-            get_buffer()->move_mark_by_name("insert", get_smart_end_iter(iter));
+
+    for (int line_nr = line_start; line_nr <= line_end; line_nr++) {
+      Gtk::TextIter line_it = get_buffer()->get_iter_at_line(line_nr);
+      Gtk::TextIter line_plus_it = line_it;
+      if (!get_buffer()->get_has_selection() || line_it != selection_end) {
+        line_plus_it.forward_chars(indent_left_steps);
+        if (!ignore_line.at(line_nr - line_start))
+          get_buffer()->erase(line_it, line_plus_it);
+      }
+    }
+    return true;
+  }
+    //"Smart" backspace key
+  else if (key->keyval == GDK_KEY_BackSpace && !get_buffer()->get_has_selection()) {
+    auto line = get_line_before();
+    bool do_smart_backspace = true;
+    for (auto &chr: line) {
+      if (chr != ' ' && chr != '\t') {
+        do_smart_backspace = false;
+        break;
+      }
+    }
+    if (iter.get_line() == 0) // Special case since there are no previous line
+      do_smart_backspace = false;
+    if (do_smart_backspace) {
+      auto previous_line_end_iter = iter;
+      if (previous_line_end_iter.backward_chars(line.size() + 1)) {
+        if (!previous_line_end_iter.ends_line()) // For CR+LF
+          previous_line_end_iter.backward_char();
+        if (previous_line_end_iter.starts_line()) // When previous line is empty, keep tabs in current line
+          get_buffer()->erase(previous_line_end_iter, get_buffer()->get_iter_at_line(iter.get_line()));
         else
-            get_buffer()->place_cursor(get_smart_end_iter(iter));
-        scroll_to(get_buffer()->get_insert());
+          get_buffer()->erase(previous_line_end_iter, iter);
         return true;
+      }
     }
+  }
+    //"Smart" delete key
+  else if (key->keyval == GDK_KEY_Delete && !get_buffer()->get_has_selection()) {
+    auto insert_iter = iter;
+    bool do_smart_delete = true;
+    do {
+      if (*iter != ' ' && *iter != '\t' && !iter.ends_line()) {
+        do_smart_delete = false;
+        break;
+      }
+      if (iter.ends_line()) {
+        if (*iter == '\r') // For CR+LF
+          iter.forward_char();
+        if (!iter.forward_char())
+          do_smart_delete = false;
+        break;
+      }
+    } while (iter.forward_char());
+    if (do_smart_delete) {
+      if (!insert_iter.starts_line()) {
+        while ((*iter == ' ' || *iter == '\t') && iter.forward_char()) {}
+      }
+      get_buffer()->erase(insert_iter, iter);
+      return true;
+    }
+  }
+    // Smart Home/End-keys
+  else if ((key->keyval == GDK_KEY_Home || key->keyval == GDK_KEY_KP_Home) && (key->state & GDK_CONTROL_MASK) == 0) {
+    if ((key->state & GDK_SHIFT_MASK) > 0)
+      get_buffer()->move_mark_by_name("insert", get_smart_home_iter(iter));
+    else
+      get_buffer()->place_cursor(get_smart_home_iter(iter));
+    scroll_to(get_buffer()->get_insert());
+    return true;
+  } else if ((key->keyval == GDK_KEY_End || key->keyval == GDK_KEY_KP_End) && (key->state & GDK_CONTROL_MASK) == 0) {
+    if ((key->state & GDK_SHIFT_MASK) > 0)
+      get_buffer()->move_mark_by_name("insert", get_smart_end_iter(iter));
+    else
+      get_buffer()->place_cursor(get_smart_end_iter(iter));
+    scroll_to(get_buffer()->get_insert());
+    return true;
+  }
 
-    //Workaround for TextView::on_key_press_event bug sometimes causing segmentation faults
-    //TODO: figure out the bug and create pull request to gtk
-    //Have only experienced this on OS X
-    //Note: valgrind reports issues on TextView::on_key_press_event as well
-    auto unicode = gdk_keyval_to_unicode(key->keyval);
-    if ((key->state & (GDK_CONTROL_MASK | GDK_META_MASK)) == 0 && unicode >= 32 && unicode != 127 &&
-        (previous_non_modifier_keyval < GDK_KEY_dead_grave || previous_non_modifier_keyval > GDK_KEY_dead_greek)) {
-        if (get_buffer()->get_has_selection()) {
-            Gtk::TextIter selection_start, selection_end;
-            get_buffer()->get_selection_bounds(selection_start, selection_end);
-            get_buffer()->erase(selection_start, selection_end);
-        }
-        get_buffer()->insert_at_cursor(Glib::ustring(1, unicode));
-        scroll_to(get_buffer()->get_insert());
+  //Workaround for TextView::on_key_press_event bug sometimes causing segmentation faults
+  //TODO: figure out the bug and create pull request to gtk
+  //Have only experienced this on OS X
+  //Note: valgrind reports issues on TextView::on_key_press_event as well
+  auto unicode = gdk_keyval_to_unicode(key->keyval);
+  if ((key->state & (GDK_CONTROL_MASK | GDK_META_MASK)) == 0 && unicode >= 32 && unicode != 127 &&
+      (previous_non_modifier_keyval < GDK_KEY_dead_grave || previous_non_modifier_keyval > GDK_KEY_dead_greek)) {
+    if (get_buffer()->get_has_selection()) {
+      Gtk::TextIter selection_start, selection_end;
+      get_buffer()->get_selection_bounds(selection_start, selection_end);
+      get_buffer()->erase(selection_start, selection_end);
+    }
+    get_buffer()->insert_at_cursor(Glib::ustring(1, unicode));
+    scroll_to(get_buffer()->get_insert());
 
-        //Trick to make the cursor visible right after insertion:
-        set_cursor_visible(false);
-        set_cursor_visible();
+    //Trick to make the cursor visible right after insertion:
+    set_cursor_visible(false);
+    set_cursor_visible();
 
-        return true;
-    }
+    return true;
+  }
 
-    return false;
+  return false;
 }
 
 //Bracket language indentation
 bool Source::View::on_key_press_event_bracket_language(GdkEventKey *key) {
-    const static std::regex no_bracket_statement_regex("^ *(if|for|while) *\\(.*[^;}{] *$|"
-                                                       "^[}]? *else if *\\(.*[^;}{] *$|"
-                                                       "^[}]? *else *$", std::regex::extended);
-
-    auto iter = get_buffer()->get_insert()->get_iter();
+  const static std::regex no_bracket_statement_regex("^ *(if|for|while) *\\(.*[^;}{] *$|"
+                                                     "^[}]? *else if *\\(.*[^;}{] *$|"
+                                                     "^[}]? *else *$", std::regex::extended);
 
-    if (get_buffer()->get_has_selection())
-        return false;
+  auto iter = get_buffer()->get_insert()->get_iter();
 
-    if (!is_code_iter(iter)) {
-        // Add * at start of line in comment blocks
-        if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) {
-            if (!iter.starts_line() && (!string_tag || (!iter.has_tag(string_tag) && !iter.ends_tag(string_tag)))) {
-                cleanup_whitespace_characters_on_return(iter);
-                iter = get_buffer()->get_insert()->get_iter();
-
-                auto start_iter = get_tabs_end_iter(iter.get_line());
-                auto end_iter = start_iter;
-                end_iter.forward_chars(2);
-                auto start_of_sentence = get_buffer()->get_text(start_iter, end_iter);
-                if (!start_of_sentence.empty()) {
-                    if (start_of_sentence == "/*" || start_of_sentence[0] == '*') {
-                        auto tabs = get_line_before(start_iter);
-                        auto insert_str = "\n" + tabs;
-                        if (start_of_sentence[0] == '/')
-                            insert_str += ' ';
-                        insert_str += "* ";
-
-                        get_buffer()->insert_at_cursor(insert_str);
-                        return true;
-                    }
-                }
-            } else if (!comment_tag || !iter.ends_tag(comment_tag))
-                return false;
-        } else
-            return false;
-    }
-
-    // get iter for if expressions below, which is moved backwards past any comment
-    auto get_condition_iter = [this](const Gtk::TextIter &iter) {
-        auto condition_iter = iter;
-        condition_iter.backward_char();
-        if (!comment_tag)
-            return condition_iter;
-        while (!condition_iter.starts_line() && (condition_iter.has_tag(comment_tag) ||
-                                                 #if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION >= 20)
-                                                 condition_iter.starts_tag(comment_tag) ||
-                                                 #else
-                                                 *condition_iter=='/' ||
-                                                 #endif
-                                                 *condition_iter == ' ' || *condition_iter == '\t') &&
-               condition_iter.backward_char()) {}
-        return condition_iter;
-    };
+  if (get_buffer()->get_has_selection())
+    return false;
 
-    //Indent depending on if/else/etc and brackets
-    if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) && !iter.starts_line()) {
+  if (!is_code_iter(iter)) {
+    // Add * at start of line in comment blocks
+    if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) {
+      if (!iter.starts_line() && (!string_tag || (!iter.has_tag(string_tag) && !iter.ends_tag(string_tag)))) {
         cleanup_whitespace_characters_on_return(iter);
         iter = get_buffer()->get_insert()->get_iter();
 
-        auto condition_iter = get_condition_iter(iter);
-        auto start_iter = condition_iter;
-        if (*start_iter == '{')
-            start_iter.backward_char();
-        Gtk::TextIter open_non_curly_bracket_iter;
-        bool open_non_curly_bracket_iter_found = false;
-        if (find_open_non_curly_bracket_backward(start_iter, open_non_curly_bracket_iter)) {
-            open_non_curly_bracket_iter_found = true;
-            start_iter = get_tabs_end_iter(get_buffer()->get_iter_at_line(open_non_curly_bracket_iter.get_line()));
-        } else
-            start_iter = get_tabs_end_iter(
-                    get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
-        auto tabs = get_line_before(start_iter);
-
-        /*
-     * Change tabs after ending comment block with an extra space (as in this case)
-     */
-        if (tabs.size() % tab_size == 1 && !start_iter.ends_line() && !is_code_iter(start_iter)) {
-            auto end_of_line_iter = start_iter;
-            end_of_line_iter.forward_to_line_end();
-            auto line = get_buffer()->get_text(start_iter, end_of_line_iter);
-            if (!line.empty() && line.compare(0, 2, "*/") == 0) {
-                tabs.pop_back();
-                get_buffer()->insert_at_cursor("\n" + tabs);
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
-        }
-
-        if (*condition_iter == '{' && is_code_iter(condition_iter)) {
-            Gtk::TextIter found_iter;
-            // Check if an '}' is needed
-            bool has_right_curly_bracket = false;
-            bool found_right_bracket = find_close_curly_bracket_forward(iter, found_iter);
-            if (found_right_bracket) {
-                auto tabs_end_iter = get_tabs_end_iter(found_iter);
-                auto line_tabs = get_line_before(tabs_end_iter);
-                if (tabs.size() == line_tabs.size())
-                    has_right_curly_bracket = true;
-            }
-            // special case for functions and classes with no indentation after: namespace {
-            if (tabs.empty() && has_right_curly_bracket)
-                has_right_curly_bracket = symbol_count(iter, '{', '}') != 1;
-
-            if (*get_buffer()->get_insert()->get_iter() == '}') {
-                get_buffer()->insert_at_cursor("\n" + tabs + tab + "\n" + tabs);
-                auto insert_it = get_buffer()->get_insert()->get_iter();
-                if (insert_it.backward_chars(tabs.size() + 1)) {
-                    scroll_to(get_buffer()->get_insert());
-                    get_buffer()->place_cursor(insert_it);
-                }
-                return true;
-            } else if (!has_right_curly_bracket) {
-                //Insert new lines with bracket end
-                bool add_semicolon = false;
-                if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr" ||
-                                 language->get_id() == "c" || language->get_id() == "cpp")) {
-                    auto token = get_token(start_iter);
-                    if (token.empty()) {
-                        auto iter = start_iter;
-                        while (!iter.starts_line() && iter.backward_char()) {}
-                        if (iter.backward_char())
-                            token = get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(iter.get_line())));
-                    }
-                    //Add semicolon after class or struct
-                    if (token == "class" || token == "struct")
-                        add_semicolon = true;
-                        //Add semicolon after lambda unless it's a parameter
-                    else if (!open_non_curly_bracket_iter_found) {
-                        auto it = condition_iter;
-                        long para_count = 0;
-                        long square_count = 0;
-                        bool square_outside_para_found = false;
-                        while (it.backward_char()) {
-                            if (*it == ']' && is_code_iter(it)) {
-                                --square_count;
-                                if (para_count == 0)
-                                    square_outside_para_found = true;
-                            } else if (*it == '[' && is_code_iter(it))
-                                ++square_count;
-                            else if (*it == ')' && is_code_iter(it))
-                                --para_count;
-                            else if (*it == '(' && is_code_iter(it))
-                                ++para_count;
-
-                            if (square_outside_para_found && square_count == 0 && para_count == 0) {
-                                add_semicolon = true;
-                                break;
-                            }
-                            if (it == start_iter)
-                                break;
-                            if (!square_outside_para_found && square_count == 0 && para_count == 0) {
-                                if ((*it >= 'A' && *it <= 'Z') || (*it >= 'a' && *it <= 'z') ||
-                                    (*it >= '0' && *it <= '9') || *it == '_' ||
-                                    *it == '-' || *it == ' ' || *it == '\t' || *it == '<' || *it == '>' || *it == '(' ||
-                                    *it == ':' ||
-                                    *it == '*' || *it == '&' || *it == '/' || it.ends_line() || !is_code_iter(it)) {
-                                    continue;
-                                } else
-                                    break;
-                            }
-                        }
-                    }
-                }
-                get_buffer()->insert_at_cursor("\n" + tabs + tab + "\n" + tabs + (add_semicolon ? "};" : "}"));
-                auto insert_it = get_buffer()->get_insert()->get_iter();
-                if (insert_it.backward_chars(tabs.size() + (add_semicolon ? 3 : 2))) {
-                    scroll_to(get_buffer()->get_insert());
-                    get_buffer()->place_cursor(insert_it);
-                }
-                return true;
-            } else {
-                get_buffer()->insert_at_cursor("\n" + tabs + tab);
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
-        }
-
-        //Indent multiline expressions
-        if (open_non_curly_bracket_iter_found) {
-            auto tabs_end_iter = get_tabs_end_iter(open_non_curly_bracket_iter);
-            auto tabs = get_line_before(get_tabs_end_iter(open_non_curly_bracket_iter));
-            auto iter = tabs_end_iter;
-            while (iter <= open_non_curly_bracket_iter) {
-                tabs += ' ';
-                iter.forward_char();
-            }
-            get_buffer()->insert_at_cursor("\n" + tabs);
-            scroll_to(get_buffer()->get_insert());
+        auto start_iter = get_tabs_end_iter(iter.get_line());
+        auto end_iter = start_iter;
+        end_iter.forward_chars(2);
+        auto start_of_sentence = get_buffer()->get_text(start_iter, end_iter);
+        if (!start_of_sentence.empty()) {
+          if (start_of_sentence == "/*" || start_of_sentence[0] == '*') {
+            auto tabs = get_line_before(start_iter);
+            auto insert_str = "\n" + tabs;
+            if (start_of_sentence[0] == '/')
+              insert_str += ' ';
+            insert_str += "* ";
+
+            get_buffer()->insert_at_cursor(insert_str);
             return true;
+          }
         }
-        auto after_condition_iter = condition_iter;
-        after_condition_iter.forward_char();
-        std::string sentence = get_buffer()->get_text(start_iter, after_condition_iter);
-        std::smatch sm;
-        if (std::regex_match(sentence, sm, no_bracket_statement_regex)) {
-            get_buffer()->insert_at_cursor("\n" + tabs + tab);
-            scroll_to(get_buffer()->get_insert());
-            return true;
+      } else if (!comment_tag || !iter.ends_tag(comment_tag))
+        return false;
+    } else
+      return false;
+  }
+
+  // get iter for if expressions below, which is moved backwards past any comment
+  auto get_condition_iter = [this](const Gtk::TextIter &iter) {
+    auto condition_iter = iter;
+    condition_iter.backward_char();
+    if (!comment_tag)
+      return condition_iter;
+    while (!condition_iter.starts_line() && (condition_iter.has_tag(comment_tag) ||
+                                             #if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION >= 20)
+                                             condition_iter.starts_tag(comment_tag) ||
+                                             #else
+                                             *condition_iter=='/' ||
+                                             #endif
+                                             *condition_iter == ' ' || *condition_iter == '\t') &&
+           condition_iter.backward_char()) {}
+    return condition_iter;
+  };
+
+  //Indent depending on if/else/etc and brackets
+  if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter) && !iter.starts_line()) {
+    cleanup_whitespace_characters_on_return(iter);
+    iter = get_buffer()->get_insert()->get_iter();
+
+    auto condition_iter = get_condition_iter(iter);
+    auto start_iter = condition_iter;
+    if (*start_iter == '{')
+      start_iter.backward_char();
+    Gtk::TextIter open_non_curly_bracket_iter;
+    bool open_non_curly_bracket_iter_found = false;
+    if (find_open_non_curly_bracket_backward(start_iter, open_non_curly_bracket_iter)) {
+      open_non_curly_bracket_iter_found = true;
+      start_iter = get_tabs_end_iter(get_buffer()->get_iter_at_line(open_non_curly_bracket_iter.get_line()));
+    } else
+      start_iter = get_tabs_end_iter(
+          get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
+    auto tabs = get_line_before(start_iter);
+
+    /*
+ * Change tabs after ending comment block with an extra space (as in this case)
+ */
+    if (tabs.size() % tab_size == 1 && !start_iter.ends_line() && !is_code_iter(start_iter)) {
+      auto end_of_line_iter = start_iter;
+      end_of_line_iter.forward_to_line_end();
+      auto line = get_buffer()->get_text(start_iter, end_of_line_iter);
+      if (!line.empty() && line.compare(0, 2, "*/") == 0) {
+        tabs.pop_back();
+        get_buffer()->insert_at_cursor("\n" + tabs);
+        scroll_to(get_buffer()->get_insert());
+        return true;
+      }
+    }
+
+    if (*condition_iter == '{' && is_code_iter(condition_iter)) {
+      Gtk::TextIter found_iter;
+      // Check if an '}' is needed
+      bool has_right_curly_bracket = false;
+      bool found_right_bracket = find_close_curly_bracket_forward(iter, found_iter);
+      if (found_right_bracket) {
+        auto tabs_end_iter = get_tabs_end_iter(found_iter);
+        auto line_tabs = get_line_before(tabs_end_iter);
+        if (tabs.size() == line_tabs.size())
+          has_right_curly_bracket = true;
+      }
+      // special case for functions and classes with no indentation after: namespace {
+      if (tabs.empty() && has_right_curly_bracket)
+        has_right_curly_bracket = symbol_count(iter, '{', '}') != 1;
+
+      if (*get_buffer()->get_insert()->get_iter() == '}') {
+        get_buffer()->insert_at_cursor("\n" + tabs + tab + "\n" + tabs);
+        auto insert_it = get_buffer()->get_insert()->get_iter();
+        if (insert_it.backward_chars(tabs.size() + 1)) {
+          scroll_to(get_buffer()->get_insert());
+          get_buffer()->place_cursor(insert_it);
         }
-            //Indenting after for instance if(...)\n...;\n
-        else if (*condition_iter == ';' && condition_iter.get_line() > 0 && is_code_iter(condition_iter)) {
-            auto previous_end_iter = start_iter;
-            while (previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {}
-            auto condition_iter = get_condition_iter(previous_end_iter);
-            auto previous_start_iter = get_tabs_end_iter(
-                    get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
-            auto previous_tabs = get_line_before(previous_start_iter);
-            auto after_condition_iter = condition_iter;
-            after_condition_iter.forward_char();
-            std::string previous_sentence = get_buffer()->get_text(previous_start_iter, after_condition_iter);
-            std::smatch sm2;
-            if (std::regex_match(previous_sentence, sm2, no_bracket_statement_regex)) {
-                get_buffer()->insert_at_cursor("\n" + previous_tabs);
-                scroll_to(get_buffer()->get_insert());
-                return true;
+        return true;
+      } else if (!has_right_curly_bracket) {
+        //Insert new lines with bracket end
+        bool add_semicolon = false;
+        if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr" ||
+                         language->get_id() == "c" || language->get_id() == "cpp")) {
+          auto token = get_token(start_iter);
+          if (token.empty()) {
+            auto iter = start_iter;
+            while (!iter.starts_line() && iter.backward_char()) {}
+            if (iter.backward_char())
+              token = get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(iter.get_line())));
+          }
+          //Add semicolon after class or struct
+          if (token == "class" || token == "struct")
+            add_semicolon = true;
+            //Add semicolon after lambda unless it's a parameter
+          else if (!open_non_curly_bracket_iter_found) {
+            auto it = condition_iter;
+            long para_count = 0;
+            long square_count = 0;
+            bool square_outside_para_found = false;
+            while (it.backward_char()) {
+              if (*it == ']' && is_code_iter(it)) {
+                --square_count;
+                if (para_count == 0)
+                  square_outside_para_found = true;
+              } else if (*it == '[' && is_code_iter(it))
+                ++square_count;
+              else if (*it == ')' && is_code_iter(it))
+                --para_count;
+              else if (*it == '(' && is_code_iter(it))
+                ++para_count;
+
+              if (square_outside_para_found && square_count == 0 && para_count == 0) {
+                add_semicolon = true;
+                break;
+              }
+              if (it == start_iter)
+                break;
+              if (!square_outside_para_found && square_count == 0 && para_count == 0) {
+                if ((*it >= 'A' && *it <= 'Z') || (*it >= 'a' && *it <= 'z') ||
+                    (*it >= '0' && *it <= '9') || *it == '_' ||
+                    *it == '-' || *it == ' ' || *it == '\t' || *it == '<' || *it == '>' || *it == '(' ||
+                    *it == ':' ||
+                    *it == '*' || *it == '&' || *it == '/' || it.ends_line() || !is_code_iter(it)) {
+                  continue;
+                } else
+                  break;
+              }
             }
+          }
         }
-            //Indenting after ':'
-        else if (*condition_iter == ':' && is_code_iter(condition_iter)) {
-            bool perform_indent = true;
-            auto iter = condition_iter;
-            while (!iter.starts_line() && *iter == ' ' && iter.backward_char()) {}
-            if (*iter == ')') {
-                auto token = get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(iter.get_line())));
-                if (token != "case")
-                    perform_indent = false;
-            }
-            if (perform_indent) {
-                Gtk::TextIter found_curly_iter;
-                if (find_open_curly_bracket_backward(iter, found_curly_iter)) {
-                    auto tabs_end_iter = get_tabs_end_iter(get_buffer()->get_iter_at_line(found_curly_iter.get_line()));
-                    auto tabs_start_of_sentence = get_line_before(tabs_end_iter);
-                    if (tabs.size() == (tabs_start_of_sentence.size() + tab_size)) {
-                        auto start_line_iter = get_buffer()->get_iter_at_line(iter.get_line());
-                        auto start_line_plus_tab_size = start_line_iter;
-                        for (size_t c = 0; c < tab_size; c++)
-                            start_line_plus_tab_size.forward_char();
-                        get_buffer()->erase(start_line_iter, start_line_plus_tab_size);
-                    } else {
-                        get_buffer()->insert_at_cursor("\n" + tabs + tab);
-                        scroll_to(get_buffer()->get_insert());
-                        return true;
-                    }
-                }
-            }
+        get_buffer()->insert_at_cursor("\n" + tabs + tab + "\n" + tabs + (add_semicolon ? "};" : "}"));
+        auto insert_it = get_buffer()->get_insert()->get_iter();
+        if (insert_it.backward_chars(tabs.size() + (add_semicolon ? 3 : 2))) {
+          scroll_to(get_buffer()->get_insert());
+          get_buffer()->place_cursor(insert_it);
         }
-        get_buffer()->insert_at_cursor("\n" + tabs);
+        return true;
+      } else {
+        get_buffer()->insert_at_cursor("\n" + tabs + tab);
         scroll_to(get_buffer()->get_insert());
         return true;
+      }
     }
-        //Indent left when writing } on a new line
-    else if (key->keyval == GDK_KEY_braceright) {
-        std::string line = get_line_before();
-        if (line.size() >= tab_size && iter.ends_line()) {
-            bool indent_left = true;
-            for (auto c: line) {
-                if (c != tab_char) {
-                    indent_left = false;
-                    break;
-                }
-            }
-            if (indent_left) {
-                Gtk::TextIter insert_it = get_buffer()->get_insert()->get_iter();
-                Gtk::TextIter line_it = get_buffer()->get_iter_at_line(insert_it.get_line());
-                Gtk::TextIter line_plus_it = line_it;
-                line_plus_it.forward_chars(tab_size);
-                get_buffer()->erase(line_it, line_plus_it);
-                get_buffer()->insert_at_cursor("}");
-                return true;
-            }
+
+    //Indent multiline expressions
+    if (open_non_curly_bracket_iter_found) {
+      auto tabs_end_iter = get_tabs_end_iter(open_non_curly_bracket_iter);
+      auto tabs = get_line_before(get_tabs_end_iter(open_non_curly_bracket_iter));
+      auto iter = tabs_end_iter;
+      while (iter <= open_non_curly_bracket_iter) {
+        tabs += ' ';
+        iter.forward_char();
+      }
+      get_buffer()->insert_at_cursor("\n" + tabs);
+      scroll_to(get_buffer()->get_insert());
+      return true;
+    }
+    auto after_condition_iter = condition_iter;
+    after_condition_iter.forward_char();
+    std::string sentence = get_buffer()->get_text(start_iter, after_condition_iter);
+    std::smatch sm;
+    if (std::regex_match(sentence, sm, no_bracket_statement_regex)) {
+      get_buffer()->insert_at_cursor("\n" + tabs + tab);
+      scroll_to(get_buffer()->get_insert());
+      return true;
+    }
+      //Indenting after for instance if(...)\n...;\n
+    else if (*condition_iter == ';' && condition_iter.get_line() > 0 && is_code_iter(condition_iter)) {
+      auto previous_end_iter = start_iter;
+      while (previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {}
+      auto condition_iter = get_condition_iter(previous_end_iter);
+      auto previous_start_iter = get_tabs_end_iter(
+          get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
+      auto previous_tabs = get_line_before(previous_start_iter);
+      auto after_condition_iter = condition_iter;
+      after_condition_iter.forward_char();
+      std::string previous_sentence = get_buffer()->get_text(previous_start_iter, after_condition_iter);
+      std::smatch sm2;
+      if (std::regex_match(previous_sentence, sm2, no_bracket_statement_regex)) {
+        get_buffer()->insert_at_cursor("\n" + previous_tabs);
+        scroll_to(get_buffer()->get_insert());
+        return true;
+      }
+    }
+      //Indenting after ':'
+    else if (*condition_iter == ':' && is_code_iter(condition_iter)) {
+      bool perform_indent = true;
+      auto iter = condition_iter;
+      while (!iter.starts_line() && *iter == ' ' && iter.backward_char()) {}
+      if (*iter == ')') {
+        auto token = get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(iter.get_line())));
+        if (token != "case")
+          perform_indent = false;
+      }
+      if (perform_indent) {
+        Gtk::TextIter found_curly_iter;
+        if (find_open_curly_bracket_backward(iter, found_curly_iter)) {
+          auto tabs_end_iter = get_tabs_end_iter(get_buffer()->get_iter_at_line(found_curly_iter.get_line()));
+          auto tabs_start_of_sentence = get_line_before(tabs_end_iter);
+          if (tabs.size() == (tabs_start_of_sentence.size() + tab_size)) {
+            auto start_line_iter = get_buffer()->get_iter_at_line(iter.get_line());
+            auto start_line_plus_tab_size = start_line_iter;
+            for (size_t c = 0; c < tab_size; c++)
+              start_line_plus_tab_size.forward_char();
+            get_buffer()->erase(start_line_iter, start_line_plus_tab_size);
+          } else {
+            get_buffer()->insert_at_cursor("\n" + tabs + tab);
+            scroll_to(get_buffer()->get_insert());
+            return true;
+          }
         }
+      }
     }
-        //Indent left when writing { on a new line after for instance if(...)\n...
-    else if (key->keyval == GDK_KEY_braceleft) {
-        auto tabs_end_iter = get_tabs_end_iter();
-        auto tabs = get_line_before(tabs_end_iter);
-        size_t line_nr = iter.get_line();
-        if (line_nr > 0 && tabs.size() >= tab_size && iter == tabs_end_iter) {
-            auto previous_end_iter = iter;
-            while (previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {}
-            auto condition_iter = get_condition_iter(previous_end_iter);
-            auto previous_start_iter = get_tabs_end_iter(
-                    get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
-            auto previous_tabs = get_line_before(previous_start_iter);
-            auto after_condition_iter = condition_iter;
-            after_condition_iter.forward_char();
-            if ((tabs.size() - tab_size) == previous_tabs.size()) {
-                std::string previous_sentence = get_buffer()->get_text(previous_start_iter, after_condition_iter);
-                std::smatch sm;
-                if (std::regex_match(previous_sentence, sm, no_bracket_statement_regex)) {
-                    auto start_iter = iter;
-                    start_iter.backward_chars(tab_size);
-                    get_buffer()->erase(start_iter, iter);
-                    get_buffer()->insert_at_cursor("{");
-                    scroll_to(get_buffer()->get_insert());
-                    return true;
-                }
-            }
-        }
+    get_buffer()->insert_at_cursor("\n" + tabs);
+    scroll_to(get_buffer()->get_insert());
+    return true;
+  }
+    //Indent left when writing } on a new line
+  else if (key->keyval == GDK_KEY_braceright) {
+    std::string line = get_line_before();
+    if (line.size() >= tab_size && iter.ends_line()) {
+      bool indent_left = true;
+      for (auto c: line) {
+        if (c != tab_char) {
+          indent_left = false;
+          break;
+        }
+      }
+      if (indent_left) {
+        Gtk::TextIter insert_it = get_buffer()->get_insert()->get_iter();
+        Gtk::TextIter line_it = get_buffer()->get_iter_at_line(insert_it.get_line());
+        Gtk::TextIter line_plus_it = line_it;
+        line_plus_it.forward_chars(tab_size);
+        get_buffer()->erase(line_it, line_plus_it);
+        get_buffer()->insert_at_cursor("}");
+        return true;
+      }
     }
-        // Mark parameters of templated functions after pressing tab and after writing template argument
-    else if (key->keyval == GDK_KEY_Tab && (key->state & GDK_SHIFT_MASK) == 0) {
-        if (*iter == '>') {
-            iter.forward_char();
-            Gtk::TextIter parenthesis_end_iter;
-            if (*iter == '(' && is_templated_function(iter, parenthesis_end_iter)) {
-                iter.forward_char();
-                get_buffer()->select_range(iter, parenthesis_end_iter);
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
+  }
+    //Indent left when writing { on a new line after for instance if(...)\n...
+  else if (key->keyval == GDK_KEY_braceleft) {
+    auto tabs_end_iter = get_tabs_end_iter();
+    auto tabs = get_line_before(tabs_end_iter);
+    size_t line_nr = iter.get_line();
+    if (line_nr > 0 && tabs.size() >= tab_size && iter == tabs_end_iter) {
+      auto previous_end_iter = iter;
+      while (previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {}
+      auto condition_iter = get_condition_iter(previous_end_iter);
+      auto previous_start_iter = get_tabs_end_iter(
+          get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
+      auto previous_tabs = get_line_before(previous_start_iter);
+      auto after_condition_iter = condition_iter;
+      after_condition_iter.forward_char();
+      if ((tabs.size() - tab_size) == previous_tabs.size()) {
+        std::string previous_sentence = get_buffer()->get_text(previous_start_iter, after_condition_iter);
+        std::smatch sm;
+        if (std::regex_match(previous_sentence, sm, no_bracket_statement_regex)) {
+          auto start_iter = iter;
+          start_iter.backward_chars(tab_size);
+          get_buffer()->erase(start_iter, iter);
+          get_buffer()->insert_at_cursor("{");
+          scroll_to(get_buffer()->get_insert());
+          return true;
         }
+      }
     }
+  }
+    // Mark parameters of templated functions after pressing tab and after writing template argument
+  else if (key->keyval == GDK_KEY_Tab && (key->state & GDK_SHIFT_MASK) == 0) {
+    if (*iter == '>') {
+      iter.forward_char();
+      Gtk::TextIter parenthesis_end_iter;
+      if (*iter == '(' && is_templated_function(iter, parenthesis_end_iter)) {
+        iter.forward_char();
+        get_buffer()->select_range(iter, parenthesis_end_iter);
+        scroll_to(get_buffer()->get_insert());
+        return true;
+      }
+    }
+  }
 
-    return false;
+  return false;
 }
 
 bool Source::View::on_key_press_event_smart_brackets(GdkEventKey *key) {
-    if (get_buffer()->get_has_selection())
-        return false;
+  if (get_buffer()->get_has_selection())
+    return false;
 
-    auto iter = get_buffer()->get_insert()->get_iter();
-    auto previous_iter = iter;
-    previous_iter.backward_char();
-    if (is_code_iter(iter)) {
-        //Move after ')' if closed expression
-        if (key->keyval == GDK_KEY_parenright) {
-            if (*iter == ')' && symbol_count(iter, '(', ')') == 0) {
-                iter.forward_char();
-                get_buffer()->place_cursor(iter);
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
-        }
-            //Move after '>' if >( and closed expression
-        else if (key->keyval == GDK_KEY_greater) {
-            if (*iter == '>') {
-                iter.forward_char();
-                Gtk::TextIter parenthesis_end_iter;
-                if (*iter == '(' && is_templated_function(iter, parenthesis_end_iter)) {
-                    get_buffer()->place_cursor(iter);
-                    scroll_to(get_buffer()->get_insert());
-                    return true;
-                }
-            }
-        }
-            //Move after '(' if >( and select text inside parentheses
-        else if (key->keyval == GDK_KEY_parenleft) {
-            auto previous_iter = iter;
-            previous_iter.backward_char();
-            if (*previous_iter == '>') {
-                Gtk::TextIter parenthesis_end_iter;
-                if (*iter == '(' && is_templated_function(iter, parenthesis_end_iter)) {
-                    iter.forward_char();
-                    get_buffer()->select_range(iter, parenthesis_end_iter);
-                    scroll_to(iter);
-                    return true;
-                }
-            }
-        }
+  auto iter = get_buffer()->get_insert()->get_iter();
+  auto previous_iter = iter;
+  previous_iter.backward_char();
+  if (is_code_iter(iter)) {
+    //Move after ')' if closed expression
+    if (key->keyval == GDK_KEY_parenright) {
+      if (*iter == ')' && symbol_count(iter, '(', ')') == 0) {
+        iter.forward_char();
+        get_buffer()->place_cursor(iter);
+        scroll_to(get_buffer()->get_insert());
+        return true;
+      }
     }
+      //Move after '>' if >( and closed expression
+    else if (key->keyval == GDK_KEY_greater) {
+      if (*iter == '>') {
+        iter.forward_char();
+        Gtk::TextIter parenthesis_end_iter;
+        if (*iter == '(' && is_templated_function(iter, parenthesis_end_iter)) {
+          get_buffer()->place_cursor(iter);
+          scroll_to(get_buffer()->get_insert());
+          return true;
+        }
+      }
+    }
+      //Move after '(' if >( and select text inside parentheses
+    else if (key->keyval == GDK_KEY_parenleft) {
+      auto previous_iter = iter;
+      previous_iter.backward_char();
+      if (*previous_iter == '>') {
+        Gtk::TextIter parenthesis_end_iter;
+        if (*iter == '(' && is_templated_function(iter, parenthesis_end_iter)) {
+          iter.forward_char();
+          get_buffer()->select_range(iter, parenthesis_end_iter);
+          scroll_to(iter);
+          return true;
+        }
+      }
+    }
+  }
 
-    return false;
+  return false;
 }
 
 bool Source::View::on_key_press_event_smart_inserts(GdkEventKey *key) {
-    if (get_buffer()->get_has_selection()) {
-        bool perform_insertion = false;
-        char left_char, right_char;
-        // Insert () around selection
-        if (key->keyval == GDK_KEY_parenleft) {
-            perform_insertion = true;
-            left_char = '(';
-            right_char = ')';
-        }
-            // Insert [] around selection
-        else if (key->keyval == GDK_KEY_bracketleft) {
-            perform_insertion = true;
-            left_char = '[';
-            right_char = ']';
-        }
-            // Insert {} around selection
-        else if (key->keyval == GDK_KEY_braceleft) {
-            perform_insertion = true;
-            left_char = '{';
-            right_char = '}';
-        }
-            // Insert <> around selection
-        else if (key->keyval == GDK_KEY_less) {
-            perform_insertion = true;
-            left_char = '<';
-            right_char = '>';
-        }
-            // Insert '' around selection
-        else if (key->keyval == GDK_KEY_apostrophe) {
-            perform_insertion = true;
-            left_char = '\'';
-            right_char = '\'';
-        }
-            // Insert "" around selection
-        else if (key->keyval == GDK_KEY_quotedbl) {
-            perform_insertion = true;
-            left_char = '"';
-            right_char = '"';
-        } else if (language && language->get_id() == "markdown") {
-            if (key->keyval == GDK_KEY_dead_grave) {
-                perform_insertion = true;
-                left_char = '`';
-                right_char = '`';
-            }
-            if (key->keyval == GDK_KEY_asterisk) {
-                perform_insertion = true;
-                left_char = '*';
-                right_char = '*';
-            }
-            if (key->keyval == GDK_KEY_underscore) {
-                perform_insertion = true;
-                left_char = '_';
-                right_char = '_';
-            }
-            if (key->keyval == GDK_KEY_dead_tilde) {
-                perform_insertion = true;
-                left_char = '~';
-                right_char = '~';
-            }
-        }
-        if (perform_insertion) {
-            Gtk::TextIter start, end;
-            get_buffer()->get_selection_bounds(start, end);
-            auto start_mark = get_buffer()->create_mark(start);
-            auto end_mark = get_buffer()->create_mark(end);
-            get_buffer()->insert(start, Glib::ustring() + left_char);
-            get_buffer()->insert(end_mark->get_iter(), Glib::ustring() + right_char);
-            auto start_mark_next_iter = start_mark->get_iter();
-            start_mark_next_iter.forward_char();
-            get_buffer()->select_range(start_mark_next_iter, end_mark->get_iter());
-            get_buffer()->delete_mark(start_mark);
-            get_buffer()->delete_mark(end_mark);
-            return true;
-        }
-        return false;
-    }
-
-    auto iter = get_buffer()->get_insert()->get_iter();
-    auto previous_iter = iter;
-    previous_iter.backward_char();
-    auto next_iter = iter;
-    next_iter.forward_char();
-
-    auto allow_insertion = [](const Gtk::TextIter &iter) {
-        if (iter.ends_line() || *iter == ' ' || *iter == '\t' || *iter == ';' || *iter == ')' || *iter == ']' ||
-            *iter == '[' || *iter == '{' || *iter == '}')
-            return true;
-        return false;
-    };
-
-    // Move right when clicking ' before a ' or when clicking " before a "
-    if (((key->keyval == GDK_KEY_apostrophe && *iter == '\'') ||
-         (key->keyval == GDK_KEY_quotedbl && *iter == '\"')) && is_code_iter(next_iter)) {
-        bool perform_move = false;
-        if (*previous_iter != '\\')
-            perform_move = true;
-        else {
-            auto it = previous_iter;
-            long backslash_count = 1;
-            while (it.backward_char() && *it == '\\') {
-                ++backslash_count;
-            }
-            if (backslash_count % 2 == 0)
-                perform_move = true;
-        }
-        if (perform_move) {
-            get_buffer()->place_cursor(next_iter);
-            scroll_to(get_buffer()->get_insert());
-            return true;
-        }
-    }
-        // When to delete '' or ""
-    else if (key->keyval == GDK_KEY_BackSpace) {
-        if (((*previous_iter == '\'' && *iter == '\'') ||
-             (*previous_iter == '"' && *iter == '"')) && is_code_iter(previous_iter)) {
-            get_buffer()->erase(previous_iter, next_iter);
-            scroll_to(get_buffer()->get_insert());
-            return true;
-        }
-    }
-
-    if (is_code_iter(iter)) {
-        // Insert ()
-        if (key->keyval == GDK_KEY_parenleft && allow_insertion(iter)) {
-            if (symbol_count(iter, '(', ')') == 0) {
-                get_buffer()->insert_at_cursor(")");
-                iter = get_buffer()->get_insert()->get_iter();
-                iter.backward_char();
-                get_buffer()->place_cursor(iter);
-                get_buffer()->insert_at_cursor("(");
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
-        }
-            // Insert []
-        else if (key->keyval == GDK_KEY_bracketleft && allow_insertion(iter)) {
-            if (symbol_count(iter, '[', ']') == 0) {
-                get_buffer()->insert_at_cursor("[]");
-                auto iter = get_buffer()->get_insert()->get_iter();
-                iter.backward_char();
-                get_buffer()->place_cursor(iter);
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
-        }
-            // Move left on ] in []
-        else if (key->keyval == GDK_KEY_bracketright) {
-            if (*iter == ']' && symbol_count(iter, '[', ']') == 0) {
-                iter.forward_char();
-                get_buffer()->place_cursor(iter);
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
-        }
-            // Insert ''
-        else if (key->keyval == GDK_KEY_apostrophe && allow_insertion(iter) && symbol_count(iter, '\'', -1) % 2 == 0) {
-            get_buffer()->insert_at_cursor("''");
-            auto iter = get_buffer()->get_insert()->get_iter();
-            iter.backward_char();
-            get_buffer()->place_cursor(iter);
-            scroll_to(get_buffer()->get_insert());
-            return true;
-        }
-            // Insert ""
-        else if (key->keyval == GDK_KEY_quotedbl && allow_insertion(iter) && symbol_count(iter, '"', -1) % 2 == 0) {
-            get_buffer()->insert_at_cursor("\"\"");
-            auto iter = get_buffer()->get_insert()->get_iter();
-            iter.backward_char();
-            get_buffer()->place_cursor(iter);
-            scroll_to(get_buffer()->get_insert());
-            return true;
-        }
-            // Insert ; at the end of line, if iter is at the last )
-        else if (key->keyval == GDK_KEY_semicolon) {
-            if (*iter == ')' && symbol_count(iter, '(', ')') == 0) {
-                if (next_iter.ends_line()) {
-                    Gtk::TextIter open_non_curly_bracket_iter;
-                    if (find_open_non_curly_bracket_backward(previous_iter, open_non_curly_bracket_iter)) {
-                        open_non_curly_bracket_iter.backward_char();
-                        if (*open_non_curly_bracket_iter == ' ')
-                            open_non_curly_bracket_iter.backward_char();
-                        if (get_token(open_non_curly_bracket_iter) != "for") {
-                            iter.forward_char();
-                            get_buffer()->place_cursor(iter);
-                            get_buffer()->insert_at_cursor(";");
-                            scroll_to(get_buffer()->get_insert());
-                            return true;
-                        }
-                    }
-                }
-            }
-        }
-            // Delete ()
-        else if (key->keyval == GDK_KEY_BackSpace) {
-            if (*previous_iter == '(' && *iter == ')' && symbol_count(iter, '(', ')') == 0) {
-                auto next_iter = iter;
-                next_iter.forward_char();
-                get_buffer()->erase(previous_iter, next_iter);
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
-                // Delete []
-            else if (*previous_iter == '[' && *iter == ']' && symbol_count(iter, '[', ']') == 0) {
-                auto next_iter = iter;
-                next_iter.forward_char();
-                get_buffer()->erase(previous_iter, next_iter);
-                scroll_to(get_buffer()->get_insert());
-                return true;
-            }
-        }
+  if (get_buffer()->get_has_selection()) {
+    bool perform_insertion = false;
+    char left_char, right_char;
+    // Insert () around selection
+    if (key->keyval == GDK_KEY_parenleft) {
+      perform_insertion = true;
+      left_char = '(';
+      right_char = ')';
+    }
+      // Insert [] around selection
+    else if (key->keyval == GDK_KEY_bracketleft) {
+      perform_insertion = true;
+      left_char = '[';
+      right_char = ']';
+    }
+      // Insert {} around selection
+    else if (key->keyval == GDK_KEY_braceleft) {
+      perform_insertion = true;
+      left_char = '{';
+      right_char = '}';
+    }
+      // Insert <> around selection
+    else if (key->keyval == GDK_KEY_less) {
+      perform_insertion = true;
+      left_char = '<';
+      right_char = '>';
+    }
+      // Insert '' around selection
+    else if (key->keyval == GDK_KEY_apostrophe) {
+      perform_insertion = true;
+      left_char = '\'';
+      right_char = '\'';
+    }
+      // Insert "" around selection
+    else if (key->keyval == GDK_KEY_quotedbl) {
+      perform_insertion = true;
+      left_char = '"';
+      right_char = '"';
+    } else if (language && language->get_id() == "markdown") {
+      if (key->keyval == GDK_KEY_dead_grave) {
+        perform_insertion = true;
+        left_char = '`';
+        right_char = '`';
+      }
+      if (key->keyval == GDK_KEY_asterisk) {
+        perform_insertion = true;
+        left_char = '*';
+        right_char = '*';
+      }
+      if (key->keyval == GDK_KEY_underscore) {
+        perform_insertion = true;
+        left_char = '_';
+        right_char = '_';
+      }
+      if (key->keyval == GDK_KEY_dead_tilde) {
+        perform_insertion = true;
+        left_char = '~';
+        right_char = '~';
+      }
+    }
+    if (perform_insertion) {
+      Gtk::TextIter start, end;
+      get_buffer()->get_selection_bounds(start, end);
+      auto start_mark = get_buffer()->create_mark(start);
+      auto end_mark = get_buffer()->create_mark(end);
+      get_buffer()->insert(start, Glib::ustring() + left_char);
+      get_buffer()->insert(end_mark->get_iter(), Glib::ustring() + right_char);
+      auto start_mark_next_iter = start_mark->get_iter();
+      start_mark_next_iter.forward_char();
+      get_buffer()->select_range(start_mark_next_iter, end_mark->get_iter());
+      get_buffer()->delete_mark(start_mark);
+      get_buffer()->delete_mark(end_mark);
+      return true;
     }
-
     return false;
-}
+  }
 
-bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
-    if (!multiple_cursors_signals_set) {
-        multiple_cursors_signals_set = true;
-        multiple_cursors_last_insert = get_buffer()->create_mark(get_buffer()->get_insert()->get_iter(), false);
-        get_buffer()->signal_mark_set().connect(
-                [this](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-                    for (auto &extra_cursor: multiple_cursors_extra_cursors) {
-                        if (extra_cursor.first == mark &&
-                            (!iter.ends_line() || iter.get_line_offset() > extra_cursor.second)) {
-                            extra_cursor.second = iter.get_line_offset();
-                            break;
-                        }
-                    }
+  auto iter = get_buffer()->get_insert()->get_iter();
+  auto previous_iter = iter;
+  previous_iter.backward_char();
+  auto next_iter = iter;
+  next_iter.forward_char();
 
-                    if (mark->get_name() == "insert") {
-                        if (multiple_cursors_use) {
-                            multiple_cursors_use = false;
-                            auto offset_diff = mark->get_iter().get_offset() -
-                                               multiple_cursors_last_insert->get_iter().get_offset();
-                            if (offset_diff != 0) {
-                                for (auto &extra_cursor: multiple_cursors_extra_cursors) {
-                                    auto iter = extra_cursor.first->get_iter();
-                                    iter.forward_chars(offset_diff);
-                                    get_buffer()->move_mark(extra_cursor.first, iter);
-                                }
-                            }
-                            multiple_cursors_use = true;
-                        }
-                        get_buffer()->delete_mark(multiple_cursors_last_insert);
-                        multiple_cursors_last_insert = get_buffer()->create_mark(mark->get_iter(), false);
-                    }
-                });
-
-        // TODO: this handler should run after signal_insert
-        get_buffer()->signal_insert().connect(
-                [this](const Gtk::TextBuffer::iterator &iter, const Glib::ustring &text, int bytes) {
-                    if (multiple_cursors_use) {
-                        multiple_cursors_use = false;
-                        auto offset = iter.get_offset() - get_buffer()->get_insert()->get_iter().get_offset();
-                        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
-                            auto iter = extra_cursor.first->get_iter();
-                            iter.forward_chars(offset);
-                            get_buffer()->insert(iter, text);
-                        }
-                        multiple_cursors_use = true;
-                    }
-                });
-
-        get_buffer()->signal_erase().connect(
-                [this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
-                    if (multiple_cursors_use) {
-                        auto insert_offset = get_buffer()->get_insert()->get_iter().get_offset();
-                        multiple_cursors_erase_backward_length = insert_offset - iter_start.get_offset();
-                        multiple_cursors_erase_forward_length = iter_end.get_offset() - insert_offset;
-                    }
-                }, false);
-
-        get_buffer()->signal_erase().connect(
-                [this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
-                    if (multiple_cursors_use) {
-                        multiple_cursors_use = false;
-                        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
-                            auto start_iter = extra_cursor.first->get_iter();
-                            auto end_iter = start_iter;
-                            start_iter.backward_chars(multiple_cursors_erase_backward_length);
-                            end_iter.forward_chars(multiple_cursors_erase_forward_length);
-                            get_buffer()->erase(start_iter, end_iter);
-                        }
-                        multiple_cursors_use = true;
-                    }
-                });
+  auto allow_insertion = [](const Gtk::TextIter &iter) {
+    if (iter.ends_line() || *iter == ' ' || *iter == '\t' || *iter == ';' || *iter == ')' || *iter == ']' ||
+        *iter == '[' || *iter == '{' || *iter == '}')
+      return true;
+    return false;
+  };
+
+  // Move right when clicking ' before a ' or when clicking " before a "
+  if (((key->keyval == GDK_KEY_apostrophe && *iter == '\'') ||
+       (key->keyval == GDK_KEY_quotedbl && *iter == '\"')) && is_code_iter(next_iter)) {
+    bool perform_move = false;
+    if (*previous_iter != '\\')
+      perform_move = true;
+    else {
+      auto it = previous_iter;
+      long backslash_count = 1;
+      while (it.backward_char() && *it == '\\') {
+        ++backslash_count;
+      }
+      if (backslash_count % 2 == 0)
+        perform_move = true;
+    }
+    if (perform_move) {
+      get_buffer()->place_cursor(next_iter);
+      scroll_to(get_buffer()->get_insert());
+      return true;
     }
+  }
+    // When to delete '' or ""
+  else if (key->keyval == GDK_KEY_BackSpace) {
+    if (((*previous_iter == '\'' && *iter == '\'') ||
+         (*previous_iter == '"' && *iter == '"')) && is_code_iter(previous_iter)) {
+      get_buffer()->erase(previous_iter, next_iter);
+      scroll_to(get_buffer()->get_insert());
+      return true;
+    }
+  }
 
-
-    if (key->keyval == GDK_KEY_Escape && !multiple_cursors_extra_cursors.empty()) {
-        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
-            extra_cursor.first->set_visible(false);
-            get_buffer()->delete_mark(extra_cursor.first);
-        }
-        multiple_cursors_extra_cursors.clear();
+  if (is_code_iter(iter)) {
+    // Insert ()
+    if (key->keyval == GDK_KEY_parenleft && allow_insertion(iter)) {
+      if (symbol_count(iter, '(', ')') == 0) {
+        get_buffer()->insert_at_cursor(")");
+        iter = get_buffer()->get_insert()->get_iter();
+        iter.backward_char();
+        get_buffer()->place_cursor(iter);
+        get_buffer()->insert_at_cursor("(");
+        scroll_to(get_buffer()->get_insert());
         return true;
+      }
     }
-
-    unsigned create_cursor_mask = GDK_MOD1_MASK;
-    unsigned move_last_created_cursor_mask = GDK_SHIFT_MASK | GDK_MOD1_MASK;
-
-    // Move last created cursor
-    if ((key->keyval == GDK_KEY_Left || key->keyval == GDK_KEY_KP_Left) &&
-        (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
-        if (multiple_cursors_extra_cursors.empty())
-            return false;
-        auto &cursor = multiple_cursors_extra_cursors.back().first;
-        auto iter = cursor->get_iter();
+      // Insert []
+    else if (key->keyval == GDK_KEY_bracketleft && allow_insertion(iter)) {
+      if (symbol_count(iter, '[', ']') == 0) {
+        get_buffer()->insert_at_cursor("[]");
+        auto iter = get_buffer()->get_insert()->get_iter();
         iter.backward_char();
-        get_buffer()->move_mark(cursor, iter);
+        get_buffer()->place_cursor(iter);
+        scroll_to(get_buffer()->get_insert());
         return true;
+      }
     }
-    if ((key->keyval == GDK_KEY_Right || key->keyval == GDK_KEY_KP_Right) &&
-        (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
-        if (multiple_cursors_extra_cursors.empty())
-            return false;
-        auto &cursor = multiple_cursors_extra_cursors.back().first;
-        auto iter = cursor->get_iter();
+      // Move left on ] in []
+    else if (key->keyval == GDK_KEY_bracketright) {
+      if (*iter == ']' && symbol_count(iter, '[', ']') == 0) {
         iter.forward_char();
-        get_buffer()->move_mark(cursor, iter);
+        get_buffer()->place_cursor(iter);
+        scroll_to(get_buffer()->get_insert());
         return true;
-    }
-    if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
-        (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
-        if (multiple_cursors_extra_cursors.empty())
-            return false;
-        auto &extra_cursor = multiple_cursors_extra_cursors.back();
-        auto iter = extra_cursor.first->get_iter();
-        auto line_offset = extra_cursor.second;
-        if (iter.backward_line()) {
-            auto end_line_iter = iter;
-            if (!end_line_iter.ends_line())
-                end_line_iter.forward_to_line_end();
-            iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
-            get_buffer()->move_mark(extra_cursor.first, iter);
-        }
+      }
+    }
+      // Insert ''
+    else if (key->keyval == GDK_KEY_apostrophe && allow_insertion(iter) && symbol_count(iter, '\'', -1) % 2 == 0) {
+      get_buffer()->insert_at_cursor("''");
+      auto iter = get_buffer()->get_insert()->get_iter();
+      iter.backward_char();
+      get_buffer()->place_cursor(iter);
+      scroll_to(get_buffer()->get_insert());
+      return true;
+    }
+      // Insert ""
+    else if (key->keyval == GDK_KEY_quotedbl && allow_insertion(iter) && symbol_count(iter, '"', -1) % 2 == 0) {
+      get_buffer()->insert_at_cursor("\"\"");
+      auto iter = get_buffer()->get_insert()->get_iter();
+      iter.backward_char();
+      get_buffer()->place_cursor(iter);
+      scroll_to(get_buffer()->get_insert());
+      return true;
+    }
+      // Insert ; at the end of line, if iter is at the last )
+    else if (key->keyval == GDK_KEY_semicolon) {
+      if (*iter == ')' && symbol_count(iter, '(', ')') == 0) {
+        if (next_iter.ends_line()) {
+          Gtk::TextIter open_non_curly_bracket_iter;
+          if (find_open_non_curly_bracket_backward(previous_iter, open_non_curly_bracket_iter)) {
+            open_non_curly_bracket_iter.backward_char();
+            if (*open_non_curly_bracket_iter == ' ')
+              open_non_curly_bracket_iter.backward_char();
+            if (get_token(open_non_curly_bracket_iter) != "for") {
+              iter.forward_char();
+              get_buffer()->place_cursor(iter);
+              get_buffer()->insert_at_cursor(";");
+              scroll_to(get_buffer()->get_insert());
+              return true;
+            }
+          }
+        }
+      }
+    }
+      // Delete ()
+    else if (key->keyval == GDK_KEY_BackSpace) {
+      if (*previous_iter == '(' && *iter == ')' && symbol_count(iter, '(', ')') == 0) {
+        auto next_iter = iter;
+        next_iter.forward_char();
+        get_buffer()->erase(previous_iter, next_iter);
+        scroll_to(get_buffer()->get_insert());
         return true;
-    }
-    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
-        (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
-        if (multiple_cursors_extra_cursors.empty())
-            return false;
-        auto &extra_cursor = multiple_cursors_extra_cursors.back();
-        auto iter = extra_cursor.first->get_iter();
-        auto line_offset = extra_cursor.second;
-        if (iter.forward_line()) {
-            auto end_line_iter = iter;
-            if (!end_line_iter.ends_line())
-                end_line_iter.forward_to_line_end();
-            iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
-            get_buffer()->move_mark(extra_cursor.first, iter);
-        }
+      }
+        // Delete []
+      else if (*previous_iter == '[' && *iter == ']' && symbol_count(iter, '[', ']') == 0) {
+        auto next_iter = iter;
+        next_iter.forward_char();
+        get_buffer()->erase(previous_iter, next_iter);
+        scroll_to(get_buffer()->get_insert());
         return true;
+      }
     }
+  }
 
-    // Create extra cursor
-    if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
-        (key->state & create_cursor_mask) == create_cursor_mask) {
-        auto insert_iter = get_buffer()->get_insert()->get_iter();
-        auto insert_line_offset = insert_iter.get_line_offset();
-        auto offset = insert_iter.get_offset();
-        for (auto &extra_cursor: multiple_cursors_extra_cursors)
-            offset = std::min(offset, extra_cursor.first->get_iter().get_offset());
-        auto iter = get_buffer()->get_iter_at_offset(offset);
-        if (iter.backward_line()) {
-            auto end_line_iter = iter;
-            if (!end_line_iter.ends_line())
-                end_line_iter.forward_to_line_end();
-            iter.forward_chars(std::min(insert_line_offset, end_line_iter.get_line_offset()));
-            multiple_cursors_extra_cursors.emplace_back(get_buffer()->create_mark(iter, false), insert_line_offset);
-            multiple_cursors_extra_cursors.back().first->set_visible(true);
-        }
-        return true;
-    }
-    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
-        (key->state & create_cursor_mask) == create_cursor_mask) {
-        auto insert_iter = get_buffer()->get_insert()->get_iter();
-        auto insert_line_offset = insert_iter.get_line_offset();
-        auto offset = insert_iter.get_offset();
-        for (auto &extra_cursor: multiple_cursors_extra_cursors)
-            offset = std::max(offset, extra_cursor.first->get_iter().get_offset());
-        auto iter = get_buffer()->get_iter_at_offset(offset);
-        if (iter.forward_line()) {
-            auto end_line_iter = iter;
-            if (!end_line_iter.ends_line())
-                end_line_iter.forward_to_line_end();
-            iter.forward_chars(std::min(insert_line_offset, end_line_iter.get_line_offset()));
-            multiple_cursors_extra_cursors.emplace_back(get_buffer()->create_mark(iter, false), insert_line_offset);
-            multiple_cursors_extra_cursors.back().first->set_visible(true);
-        }
-        return true;
+  return false;
+}
+
+bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
+  if (!multiple_cursors_signals_set) {
+    multiple_cursors_signals_set = true;
+    multiple_cursors_last_insert = get_buffer()->create_mark(get_buffer()->get_insert()->get_iter(), false);
+    get_buffer()->signal_mark_set().connect(
+        [this](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+          for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+            if (extra_cursor.first == mark &&
+                (!iter.ends_line() || iter.get_line_offset() > extra_cursor.second)) {
+              extra_cursor.second = iter.get_line_offset();
+              break;
+            }
+          }
+
+          if (mark->get_name() == "insert") {
+            if (multiple_cursors_use) {
+              multiple_cursors_use = false;
+              auto offset_diff = mark->get_iter().get_offset() -
+                                 multiple_cursors_last_insert->get_iter().get_offset();
+              if (offset_diff != 0) {
+                for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+                  auto iter = extra_cursor.first->get_iter();
+                  iter.forward_chars(offset_diff);
+                  get_buffer()->move_mark(extra_cursor.first, iter);
+                }
+              }
+              multiple_cursors_use = true;
+            }
+            get_buffer()->delete_mark(multiple_cursors_last_insert);
+            multiple_cursors_last_insert = get_buffer()->create_mark(mark->get_iter(), false);
+          }
+        });
+
+    // TODO: this handler should run after signal_insert
+    get_buffer()->signal_insert().connect(
+        [this](const Gtk::TextBuffer::iterator &iter, const Glib::ustring &text, int bytes) {
+          if (multiple_cursors_use) {
+            multiple_cursors_use = false;
+            auto offset = iter.get_offset() - get_buffer()->get_insert()->get_iter().get_offset();
+            for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+              auto iter = extra_cursor.first->get_iter();
+              iter.forward_chars(offset);
+              get_buffer()->insert(iter, text);
+            }
+            multiple_cursors_use = true;
+          }
+        });
+
+    get_buffer()->signal_erase().connect(
+        [this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
+          if (multiple_cursors_use) {
+            auto insert_offset = get_buffer()->get_insert()->get_iter().get_offset();
+            multiple_cursors_erase_backward_length = insert_offset - iter_start.get_offset();
+            multiple_cursors_erase_forward_length = iter_end.get_offset() - insert_offset;
+          }
+        }, false);
+
+    get_buffer()->signal_erase().connect(
+        [this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
+          if (multiple_cursors_use) {
+            multiple_cursors_use = false;
+            for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+              auto start_iter = extra_cursor.first->get_iter();
+              auto end_iter = start_iter;
+              start_iter.backward_chars(multiple_cursors_erase_backward_length);
+              end_iter.forward_chars(multiple_cursors_erase_forward_length);
+              get_buffer()->erase(start_iter, end_iter);
+            }
+            multiple_cursors_use = true;
+          }
+        });
+  }
+
+
+  if (key->keyval == GDK_KEY_Escape && !multiple_cursors_extra_cursors.empty()) {
+    for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+      extra_cursor.first->set_visible(false);
+      get_buffer()->delete_mark(extra_cursor.first);
     }
+    multiple_cursors_extra_cursors.clear();
+    return true;
+  }
 
-    // Move cursors left/right
-    if ((key->keyval == GDK_KEY_Left || key->keyval == GDK_KEY_KP_Left) && (key->state & GDK_CONTROL_MASK) > 0) {
-        multiple_cursors_use = false;
-        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
-            auto iter = extra_cursor.first->get_iter();
-            iter.backward_word_start();
-            extra_cursor.second = iter.get_line_offset();
-            get_buffer()->move_mark(extra_cursor.first, iter);
-        }
-        auto insert = get_buffer()->get_insert();
-        auto iter = insert->get_iter();
-        iter.backward_word_start();
-        get_buffer()->move_mark(insert, iter);
-        if ((key->state & GDK_SHIFT_MASK) == 0)
-            get_buffer()->move_mark_by_name("selection_bound", iter);
-        return true;
+  unsigned create_cursor_mask = GDK_MOD1_MASK;
+  unsigned move_last_created_cursor_mask = GDK_SHIFT_MASK | GDK_MOD1_MASK;
+
+  // Move last created cursor
+  if ((key->keyval == GDK_KEY_Left || key->keyval == GDK_KEY_KP_Left) &&
+      (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
+    if (multiple_cursors_extra_cursors.empty())
+      return false;
+    auto &cursor = multiple_cursors_extra_cursors.back().first;
+    auto iter = cursor->get_iter();
+    iter.backward_char();
+    get_buffer()->move_mark(cursor, iter);
+    return true;
+  }
+  if ((key->keyval == GDK_KEY_Right || key->keyval == GDK_KEY_KP_Right) &&
+      (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
+    if (multiple_cursors_extra_cursors.empty())
+      return false;
+    auto &cursor = multiple_cursors_extra_cursors.back().first;
+    auto iter = cursor->get_iter();
+    iter.forward_char();
+    get_buffer()->move_mark(cursor, iter);
+    return true;
+  }
+  if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
+      (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
+    if (multiple_cursors_extra_cursors.empty())
+      return false;
+    auto &extra_cursor = multiple_cursors_extra_cursors.back();
+    auto iter = extra_cursor.first->get_iter();
+    auto line_offset = extra_cursor.second;
+    if (iter.backward_line()) {
+      auto end_line_iter = iter;
+      if (!end_line_iter.ends_line())
+        end_line_iter.forward_to_line_end();
+      iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
+      get_buffer()->move_mark(extra_cursor.first, iter);
     }
-    if ((key->keyval == GDK_KEY_Right || key->keyval == GDK_KEY_KP_Right) && (key->state & GDK_CONTROL_MASK) > 0) {
-        multiple_cursors_use = false;
-        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
-            auto iter = extra_cursor.first->get_iter();
-            iter.forward_visible_word_end();
-            extra_cursor.second = iter.get_line_offset();
-            get_buffer()->move_mark(extra_cursor.first, iter);
-        }
-        auto insert = get_buffer()->get_insert();
-        auto iter = insert->get_iter();
-        iter.forward_visible_word_end();
-        get_buffer()->move_mark(insert, iter);
-        if ((key->state & GDK_SHIFT_MASK) == 0)
-            get_buffer()->move_mark_by_name("selection_bound", iter);
-        return true;
+    return true;
+  }
+  if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
+      (key->state & move_last_created_cursor_mask) == move_last_created_cursor_mask) {
+    if (multiple_cursors_extra_cursors.empty())
+      return false;
+    auto &extra_cursor = multiple_cursors_extra_cursors.back();
+    auto iter = extra_cursor.first->get_iter();
+    auto line_offset = extra_cursor.second;
+    if (iter.forward_line()) {
+      auto end_line_iter = iter;
+      if (!end_line_iter.ends_line())
+        end_line_iter.forward_to_line_end();
+      iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
+      get_buffer()->move_mark(extra_cursor.first, iter);
     }
+    return true;
+  }
 
-    // Move cursors up/down
-    if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up)) {
-        multiple_cursors_use = false;
-        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
-            auto iter = extra_cursor.first->get_iter();
-            auto line_offset = extra_cursor.second;
-            if (iter.backward_line()) {
-                auto end_line_iter = iter;
-                if (!end_line_iter.ends_line())
-                    end_line_iter.forward_to_line_end();
-                iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
-                get_buffer()->move_mark(extra_cursor.first, iter);
-            }
-        }
-        return false;
+  // Create extra cursor
+  if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up) &&
+      (key->state & create_cursor_mask) == create_cursor_mask) {
+    auto insert_iter = get_buffer()->get_insert()->get_iter();
+    auto insert_line_offset = insert_iter.get_line_offset();
+    auto offset = insert_iter.get_offset();
+    for (auto &extra_cursor: multiple_cursors_extra_cursors)
+      offset = std::min(offset, extra_cursor.first->get_iter().get_offset());
+    auto iter = get_buffer()->get_iter_at_offset(offset);
+    if (iter.backward_line()) {
+      auto end_line_iter = iter;
+      if (!end_line_iter.ends_line())
+        end_line_iter.forward_to_line_end();
+      iter.forward_chars(std::min(insert_line_offset, end_line_iter.get_line_offset()));
+      multiple_cursors_extra_cursors.emplace_back(get_buffer()->create_mark(iter, false), insert_line_offset);
+      multiple_cursors_extra_cursors.back().first->set_visible(true);
     }
-    if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down)) {
-        multiple_cursors_use = false;
-        for (auto &extra_cursor: multiple_cursors_extra_cursors) {
-            auto iter = extra_cursor.first->get_iter();
-            auto line_offset = extra_cursor.second;
-            if (iter.forward_line()) {
-                auto end_line_iter = iter;
-                if (!end_line_iter.ends_line())
-                    end_line_iter.forward_to_line_end();
-                iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
-                get_buffer()->move_mark(extra_cursor.first, iter);
-            }
-        }
-        return false;
+    return true;
+  }
+  if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down) &&
+      (key->state & create_cursor_mask) == create_cursor_mask) {
+    auto insert_iter = get_buffer()->get_insert()->get_iter();
+    auto insert_line_offset = insert_iter.get_line_offset();
+    auto offset = insert_iter.get_offset();
+    for (auto &extra_cursor: multiple_cursors_extra_cursors)
+      offset = std::max(offset, extra_cursor.first->get_iter().get_offset());
+    auto iter = get_buffer()->get_iter_at_offset(offset);
+    if (iter.forward_line()) {
+      auto end_line_iter = iter;
+      if (!end_line_iter.ends_line())
+        end_line_iter.forward_to_line_end();
+      iter.forward_chars(std::min(insert_line_offset, end_line_iter.get_line_offset()));
+      multiple_cursors_extra_cursors.emplace_back(get_buffer()->create_mark(iter, false), insert_line_offset);
+      multiple_cursors_extra_cursors.back().first->set_visible(true);
     }
+    return true;
+  }
 
-    // Smart Home-key, start of line
-    if ((key->keyval == GDK_KEY_Home || key->keyval == GDK_KEY_KP_Home) && (key->state & GDK_CONTROL_MASK) == 0) {
-        for (auto &extra_cursor: multiple_cursors_extra_cursors)
-            get_buffer()->move_mark(extra_cursor.first, get_smart_home_iter(extra_cursor.first->get_iter()));
-        multiple_cursors_use = false;
-        return false;
+  // Move cursors left/right
+  if ((key->keyval == GDK_KEY_Left || key->keyval == GDK_KEY_KP_Left) && (key->state & GDK_CONTROL_MASK) > 0) {
+    multiple_cursors_use = false;
+    for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+      auto iter = extra_cursor.first->get_iter();
+      iter.backward_word_start();
+      extra_cursor.second = iter.get_line_offset();
+      get_buffer()->move_mark(extra_cursor.first, iter);
+    }
+    auto insert = get_buffer()->get_insert();
+    auto iter = insert->get_iter();
+    iter.backward_word_start();
+    get_buffer()->move_mark(insert, iter);
+    if ((key->state & GDK_SHIFT_MASK) == 0)
+      get_buffer()->move_mark_by_name("selection_bound", iter);
+    return true;
+  }
+  if ((key->keyval == GDK_KEY_Right || key->keyval == GDK_KEY_KP_Right) && (key->state & GDK_CONTROL_MASK) > 0) {
+    multiple_cursors_use = false;
+    for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+      auto iter = extra_cursor.first->get_iter();
+      iter.forward_visible_word_end();
+      extra_cursor.second = iter.get_line_offset();
+      get_buffer()->move_mark(extra_cursor.first, iter);
+    }
+    auto insert = get_buffer()->get_insert();
+    auto iter = insert->get_iter();
+    iter.forward_visible_word_end();
+    get_buffer()->move_mark(insert, iter);
+    if ((key->state & GDK_SHIFT_MASK) == 0)
+      get_buffer()->move_mark_by_name("selection_bound", iter);
+    return true;
+  }
+
+  // Move cursors up/down
+  if ((key->keyval == GDK_KEY_Up || key->keyval == GDK_KEY_KP_Up)) {
+    multiple_cursors_use = false;
+    for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+      auto iter = extra_cursor.first->get_iter();
+      auto line_offset = extra_cursor.second;
+      if (iter.backward_line()) {
+        auto end_line_iter = iter;
+        if (!end_line_iter.ends_line())
+          end_line_iter.forward_to_line_end();
+        iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
+        get_buffer()->move_mark(extra_cursor.first, iter);
+      }
     }
-    // Smart End-key, end of line
-    if ((key->keyval == GDK_KEY_End || key->keyval == GDK_KEY_KP_End) && (key->state & GDK_CONTROL_MASK) == 0) {
-        for (auto &extra_cursor: multiple_cursors_extra_cursors)
-            get_buffer()->move_mark(extra_cursor.first, get_smart_end_iter(extra_cursor.first->get_iter()));
-        multiple_cursors_use = false;
-        return false;
+    return false;
+  }
+  if ((key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_KP_Down)) {
+    multiple_cursors_use = false;
+    for (auto &extra_cursor: multiple_cursors_extra_cursors) {
+      auto iter = extra_cursor.first->get_iter();
+      auto line_offset = extra_cursor.second;
+      if (iter.forward_line()) {
+        auto end_line_iter = iter;
+        if (!end_line_iter.ends_line())
+          end_line_iter.forward_to_line_end();
+        iter.forward_chars(std::min(line_offset, end_line_iter.get_line_offset()));
+        get_buffer()->move_mark(extra_cursor.first, iter);
+      }
     }
+    return false;
+  }
 
+  // Smart Home-key, start of line
+  if ((key->keyval == GDK_KEY_Home || key->keyval == GDK_KEY_KP_Home) && (key->state & GDK_CONTROL_MASK) == 0) {
+    for (auto &extra_cursor: multiple_cursors_extra_cursors)
+      get_buffer()->move_mark(extra_cursor.first, get_smart_home_iter(extra_cursor.first->get_iter()));
+    multiple_cursors_use = false;
+    return false;
+  }
+  // Smart End-key, end of line
+  if ((key->keyval == GDK_KEY_End || key->keyval == GDK_KEY_KP_End) && (key->state & GDK_CONTROL_MASK) == 0) {
+    for (auto &extra_cursor: multiple_cursors_extra_cursors)
+      get_buffer()->move_mark(extra_cursor.first, get_smart_end_iter(extra_cursor.first->get_iter()));
+    multiple_cursors_use = false;
     return false;
+  }
+
+  return false;
 }
 
 bool Source::View::on_button_press_event(GdkEventButton *event) {
-    // Select range when double clicking
-    if (event->type == GDK_2BUTTON_PRESS) {
-        Gtk::TextIter start, end;
-        get_buffer()->get_selection_bounds(start, end);
-        auto iter = start;
-        while ((*iter >= 48 && *iter <= 57) || (*iter >= 65 && *iter <= 90) || (*iter >= 97 && *iter <= 122) ||
-               *iter == 95) {
-            start = iter;
-            if (!iter.backward_char())
-                break;
-        }
-        while ((*end >= 48 && *end <= 57) || (*end >= 65 && *end <= 90) || (*end >= 97 && *end <= 122) || *end == 95) {
-            if (!end.forward_char())
-                break;
-        }
-        get_buffer()->select_range(start, end);
-        return true;
-    }
+  // Select range when double clicking
+  if (event->type == GDK_2BUTTON_PRESS) {
+    Gtk::TextIter start, end;
+    get_buffer()->get_selection_bounds(start, end);
+    auto iter = start;
+    while ((*iter >= 48 && *iter <= 57) || (*iter >= 65 && *iter <= 90) || (*iter >= 97 && *iter <= 122) ||
+           *iter == 95) {
+      start = iter;
+      if (!iter.backward_char())
+        break;
+    }
+    while ((*end >= 48 && *end <= 57) || (*end >= 65 && *end <= 90) || (*end >= 97 && *end <= 122) || *end == 95) {
+      if (!end.forward_char())
+        break;
+    }
+    get_buffer()->select_range(start, end);
+    return true;
+  }
 
-    // Go to implementation or declaration
-    if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)) {
+  // Go to implementation or declaration
+  if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)) {
 #ifdef __APPLE__
-        GdkModifierType mask=GDK_MOD2_MASK;
+    GdkModifierType mask=GDK_MOD2_MASK;
 #else
-        GdkModifierType mask = GDK_CONTROL_MASK;
+    GdkModifierType mask = GDK_CONTROL_MASK;
 #endif
-        if (event->state & mask) {
-            int x, y;
-            window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
-            Gtk::TextIter iter;
-            get_iter_at_location(iter, x, y);
-            if (iter)
-                get_buffer()->place_cursor(iter);
-
-            Menu::get().actions["source_goto_declaration_or_implementation"]->activate();
-            return true;
-        }
+    if (event->state & mask) {
+      int x, y;
+      window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
+      Gtk::TextIter iter;
+      get_iter_at_location(iter, x, y);
+      if (iter)
+        get_buffer()->place_cursor(iter);
+
+      Menu::get().actions["source_goto_declaration_or_implementation"]->activate();
+      return true;
     }
+  }
 
-    // Open right click menu
-    if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) {
-        hide_tooltips();
-        if (!get_buffer()->get_has_selection()) {
-            int x, y;
-            window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
-            Gtk::TextIter iter;
-            get_iter_at_location(iter, x, y);
-            if (iter)
-                get_buffer()->place_cursor(iter);
-            Menu::get().right_click_line_menu->popup(event->button, event->time);
-        } else {
-            Menu::get().right_click_selected_menu->popup(event->button, event->time);
-        }
-        return true;
+  // Open right click menu
+  if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) {
+    hide_tooltips();
+    if (!get_buffer()->get_has_selection()) {
+      int x, y;
+      window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
+      Gtk::TextIter iter;
+      get_iter_at_location(iter, x, y);
+      if (iter)
+        get_buffer()->place_cursor(iter);
+      Menu::get().right_click_line_menu->popup(event->button, event->time);
+    } else {
+      Menu::get().right_click_selected_menu->popup(event->button, event->time);
     }
-    return Gsv::View::on_button_press_event(event);
+    return true;
+  }
+  return Gsv::View::on_button_press_event(event);
 }
 
 bool Source::View::on_motion_notify_event(GdkEventMotion *event) {
-    // Workaround for drag-and-drop crash on MacOS
-    // TODO 2018: check if this bug has been fixed
+  // Workaround for drag-and-drop crash on MacOS
+  // TODO 2018: check if this bug has been fixed
 #ifdef __APPLE__
-                                                                                                                            if((event->state & GDK_BUTTON1_MASK) == 0)
-    return Gsv::View::on_motion_notify_event(event);
-  else {
-    int x, y;
-    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
-    Gtk::TextIter iter;
-    get_iter_at_location(iter, x, y);
-    get_buffer()->select_range(get_buffer()->get_insert()->get_iter(), iter);
-    return true;
-  }
+  if((event->state & GDK_BUTTON1_MASK) == 0)
+return Gsv::View::on_motion_notify_event(event);
+else {
+int x, y;
+window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
+Gtk::TextIter iter;
+get_iter_at_location(iter, x, y);
+get_buffer()->select_range(get_buffer()->get_insert()->get_iter(), iter);
+return true;
+}
 #else
-    return Gsv::View::on_motion_notify_event(event);
+  return Gsv::View::on_motion_notify_event(event);
 #endif
 }
 
 std::pair<char, unsigned> Source::View::find_tab_char_and_size() {
-    std::unordered_map<char, size_t> tab_chars;
-    std::unordered_map<unsigned, size_t> tab_sizes;
-    auto iter = get_buffer()->begin();
-    long tab_count = -1;
-    long last_tab_count = 0;
-    bool single_quoted = false;
-    bool double_quoted = false;
-    //For bracket languages, TODO: add more language ids
-    if (is_bracket_language && !(language && language->get_id() == "html")) {
-        bool line_comment = false;
-        bool comment = false;
-        bool bracket_last_line = false;
-        char last_char = 0;
-        long last_tab_diff = -1;
-        while (iter) {
-            if (iter.starts_line()) {
-                line_comment = false;
-                single_quoted = false;
-                double_quoted = false;
-                tab_count = 0;
-                if (last_char == '{')
-                    bracket_last_line = true;
-                else
-                    bracket_last_line = false;
-            }
-            if (bracket_last_line && tab_count != -1) {
-                if (*iter == ' ') {
-                    tab_chars[' ']++;
-                    tab_count++;
-                } else if (*iter == '\t') {
-                    tab_chars['\t']++;
-                    tab_count++;
-                } else {
-                    auto line_iter = iter;
-                    char last_line_char = 0;
-                    while (line_iter && !line_iter.ends_line()) {
-                        if (*line_iter != ' ' && *line_iter != '\t')
-                            last_line_char = *line_iter;
-                        if (*line_iter == '(')
-                            break;
-                        line_iter.forward_char();
-                    }
-                    if (last_line_char == ':' || *iter == '#') {
-                        tab_count = 0;
-                        if ((iter.get_line() + 1) < get_buffer()->get_line_count()) {
-                            iter = get_buffer()->get_iter_at_line(iter.get_line() + 1);
-                            continue;
-                        }
-                    } else if (!iter.ends_line()) {
-                        if (tab_count != last_tab_count)
-                            tab_sizes[std::abs(tab_count - last_tab_count)]++;
-                        last_tab_diff = std::abs(tab_count - last_tab_count);
-                        last_tab_count = tab_count;
-                        last_char = 0;
-                    }
-                }
-            }
-
-            auto prev_iter = iter;
-            prev_iter.backward_char();
-            auto prev_prev_iter = prev_iter;
-            prev_prev_iter.backward_char();
-            if (!double_quoted && *iter == '\'' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
-                single_quoted = !single_quoted;
-            else if (!single_quoted && *iter == '\"' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
-                double_quoted = !double_quoted;
-            else if (!single_quoted && !double_quoted) {
-                auto next_iter = iter;
-                next_iter.forward_char();
-                if (*iter == '/' && *next_iter == '/')
-                    line_comment = true;
-                else if (*iter == '/' && *next_iter == '*')
-                    comment = true;
-                else if (*iter == '*' && *next_iter == '/') {
-                    iter.forward_char();
-                    iter.forward_char();
-                    comment = false;
-                }
-            }
-            if (!single_quoted && !double_quoted && !comment && !line_comment && *iter != ' ' && *iter != '\t' &&
-                !iter.ends_line())
-                last_char = *iter;
-            if (!single_quoted && !double_quoted && !comment && !line_comment && *iter == '}' && tab_count != -1 &&
-                last_tab_diff != -1)
-                last_tab_count -= last_tab_diff;
-            if (*iter != ' ' && *iter != '\t')
-                tab_count = -1;
-
-            iter.forward_char();
-        }
-    } else {
-        long para_count = 0;
-        while (iter) {
-            if (iter.starts_line())
-                tab_count = 0;
-            if (tab_count != -1 && para_count == 0 && single_quoted == false && double_quoted == false) {
-                if (*iter == ' ') {
-                    tab_chars[' ']++;
-                    tab_count++;
-                } else if (*iter == '\t') {
-                    tab_chars['\t']++;
-                    tab_count++;
-                } else if (!iter.ends_line()) {
-                    if (tab_count != last_tab_count)
-                        tab_sizes[std::abs(tab_count - last_tab_count)]++;
-                    last_tab_count = tab_count;
-                }
-            }
-            auto prev_iter = iter;
-            prev_iter.backward_char();
-            auto prev_prev_iter = prev_iter;
-            prev_prev_iter.backward_char();
-            if (!double_quoted && *iter == '\'' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
-                single_quoted = !single_quoted;
-            else if (!single_quoted && *iter == '\"' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
-                double_quoted = !double_quoted;
-            else if (!single_quoted && !double_quoted) {
-                if (*iter == '(')
-                    para_count++;
-                else if (*iter == ')')
-                    para_count--;
-            }
-            if (*iter != ' ' && *iter != '\t')
-                tab_count = -1;
-
-            iter.forward_char();
-        }
+  std::unordered_map<char, size_t> tab_chars;
+  std::unordered_map<unsigned, size_t> tab_sizes;
+  auto iter = get_buffer()->begin();
+  long tab_count = -1;
+  long last_tab_count = 0;
+  bool single_quoted = false;
+  bool double_quoted = false;
+  //For bracket languages, TODO: add more language ids
+  if (is_bracket_language && !(language && language->get_id() == "html")) {
+    bool line_comment = false;
+    bool comment = false;
+    bool bracket_last_line = false;
+    char last_char = 0;
+    long last_tab_diff = -1;
+    while (iter) {
+      if (iter.starts_line()) {
+        line_comment = false;
+        single_quoted = false;
+        double_quoted = false;
+        tab_count = 0;
+        if (last_char == '{')
+          bracket_last_line = true;
+        else
+          bracket_last_line = false;
+      }
+      if (bracket_last_line && tab_count != -1) {
+        if (*iter == ' ') {
+          tab_chars[' ']++;
+          tab_count++;
+        } else if (*iter == '\t') {
+          tab_chars['\t']++;
+          tab_count++;
+        } else {
+          auto line_iter = iter;
+          char last_line_char = 0;
+          while (line_iter && !line_iter.ends_line()) {
+            if (*line_iter != ' ' && *line_iter != '\t')
+              last_line_char = *line_iter;
+            if (*line_iter == '(')
+              break;
+            line_iter.forward_char();
+          }
+          if (last_line_char == ':' || *iter == '#') {
+            tab_count = 0;
+            if ((iter.get_line() + 1) < get_buffer()->get_line_count()) {
+              iter = get_buffer()->get_iter_at_line(iter.get_line() + 1);
+              continue;
+            }
+          } else if (!iter.ends_line()) {
+            if (tab_count != last_tab_count)
+              tab_sizes[std::abs(tab_count - last_tab_count)]++;
+            last_tab_diff = std::abs(tab_count - last_tab_count);
+            last_tab_count = tab_count;
+            last_char = 0;
+          }
+        }
+      }
+
+      auto prev_iter = iter;
+      prev_iter.backward_char();
+      auto prev_prev_iter = prev_iter;
+      prev_prev_iter.backward_char();
+      if (!double_quoted && *iter == '\'' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
+        single_quoted = !single_quoted;
+      else if (!single_quoted && *iter == '\"' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
+        double_quoted = !double_quoted;
+      else if (!single_quoted && !double_quoted) {
+        auto next_iter = iter;
+        next_iter.forward_char();
+        if (*iter == '/' && *next_iter == '/')
+          line_comment = true;
+        else if (*iter == '/' && *next_iter == '*')
+          comment = true;
+        else if (*iter == '*' && *next_iter == '/') {
+          iter.forward_char();
+          iter.forward_char();
+          comment = false;
+        }
+      }
+      if (!single_quoted && !double_quoted && !comment && !line_comment && *iter != ' ' && *iter != '\t' &&
+          !iter.ends_line())
+        last_char = *iter;
+      if (!single_quoted && !double_quoted && !comment && !line_comment && *iter == '}' && tab_count != -1 &&
+          last_tab_diff != -1)
+        last_tab_count -= last_tab_diff;
+      if (*iter != ' ' && *iter != '\t')
+        tab_count = -1;
+
+      iter.forward_char();
+    }
+  } else {
+    long para_count = 0;
+    while (iter) {
+      if (iter.starts_line())
+        tab_count = 0;
+      if (tab_count != -1 && para_count == 0 && single_quoted == false && double_quoted == false) {
+        if (*iter == ' ') {
+          tab_chars[' ']++;
+          tab_count++;
+        } else if (*iter == '\t') {
+          tab_chars['\t']++;
+          tab_count++;
+        } else if (!iter.ends_line()) {
+          if (tab_count != last_tab_count)
+            tab_sizes[std::abs(tab_count - last_tab_count)]++;
+          last_tab_count = tab_count;
+        }
+      }
+      auto prev_iter = iter;
+      prev_iter.backward_char();
+      auto prev_prev_iter = prev_iter;
+      prev_prev_iter.backward_char();
+      if (!double_quoted && *iter == '\'' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
+        single_quoted = !single_quoted;
+      else if (!single_quoted && *iter == '\"' && !(*prev_iter == '\\' && *prev_prev_iter != '\\'))
+        double_quoted = !double_quoted;
+      else if (!single_quoted && !double_quoted) {
+        if (*iter == '(')
+          para_count++;
+        else if (*iter == ')')
+          para_count--;
+      }
+      if (*iter != ' ' && *iter != '\t')
+        tab_count = -1;
+
+      iter.forward_char();
     }
+  }
 
-    char found_tab_char = 0;
-    size_t occurences = 0;
-    for (auto &tab_char: tab_chars) {
-        if (tab_char.second > occurences) {
-            found_tab_char = tab_char.first;
-            occurences = tab_char.second;
-        }
+  char found_tab_char = 0;
+  size_t occurences = 0;
+  for (auto &tab_char: tab_chars) {
+    if (tab_char.second > occurences) {
+      found_tab_char = tab_char.first;
+      occurences = tab_char.second;
     }
-    unsigned found_tab_size = 0;
-    occurences = 0;
-    for (auto &tab_size: tab_sizes) {
-        if (tab_size.second > occurences) {
-            found_tab_size = tab_size.first;
-            occurences = tab_size.second;
-        }
+  }
+  unsigned found_tab_size = 0;
+  occurences = 0;
+  for (auto &tab_size: tab_sizes) {
+    if (tab_size.second > occurences) {
+      found_tab_size = tab_size.first;
+      occurences = tab_size.second;
     }
-    return {found_tab_char, found_tab_size};
+  }
+  return {found_tab_char, found_tab_size};
 }
 
 
@@ -2903,83 +2903,83 @@ std::pair<char, unsigned> Source::View::find_tab_char_and_size() {
 //// GenericView ////
 /////////////////////
 Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language)
-        : BaseView(file_path, language), View(file_path, language, true) {
-    configure();
-    spellcheck_all = true;
-
-    if (language)
-        get_source_buffer()->set_language(language);
-
-    auto completion = get_completion();
-    completion->property_show_headers() = false;
-    completion->property_show_icons() = false;
-    completion->property_accelerators() = 0;
-
-    auto completion_words = Gsv::CompletionWords::create("", Glib::RefPtr<Gdk::Pixbuf>());
-    completion_words->register_provider(get_buffer());
-    completion->add_provider(completion_words);
-
-    if (language) {
-        auto language_manager = LanguageManager::get_default();
-        auto search_paths = language_manager->get_search_path();
-        bool found_language_file = false;
-        boost::filesystem::path language_file;
-        for (auto &search_path: search_paths) {
-            boost::filesystem::path p(
-                    static_cast<std::string>(search_path) + '/' + static_cast<std::string>(language->get_id()) +
-                    ".lang");
-            if (boost::filesystem::exists(p) && boost::filesystem::is_regular_file(p)) {
-                language_file = p;
-                found_language_file = true;
-                break;
-            }
-        }
-        if (found_language_file) {
-            auto completion_buffer_keywords = CompletionBuffer::create();
-            boost::property_tree::ptree pt;
-            try {
-                boost::property_tree::xml_parser::read_xml(language_file.string(), pt);
-            }
-            catch (const std::exception &e) {
-                Terminal::get().print(
-                        "Error: error parsing language file " + language_file.string() + ": " + e.what() + '\n', true);
-            }
-            bool has_context_class = false;
-            parse_language_file(completion_buffer_keywords, has_context_class, pt);
-            if (!has_context_class)
-                spellcheck_all = false;
-            completion_words->register_provider(completion_buffer_keywords);
-        }
+    : BaseView(file_path, language), View(file_path, language, true) {
+  configure();
+  spellcheck_all = true;
+
+  if (language)
+    get_source_buffer()->set_language(language);
+
+  auto completion = get_completion();
+  completion->property_show_headers() = false;
+  completion->property_show_icons() = false;
+  completion->property_accelerators() = 0;
+
+  auto completion_words = Gsv::CompletionWords::create("", Glib::RefPtr<Gdk::Pixbuf>());
+  completion_words->register_provider(get_buffer());
+  completion->add_provider(completion_words);
+
+  if (language) {
+    auto language_manager = LanguageManager::get_default();
+    auto search_paths = language_manager->get_search_path();
+    bool found_language_file = false;
+    boost::filesystem::path language_file;
+    for (auto &search_path: search_paths) {
+      boost::filesystem::path p(
+          static_cast<std::string>(search_path) + '/' + static_cast<std::string>(language->get_id()) +
+          ".lang");
+      if (boost::filesystem::exists(p) && boost::filesystem::is_regular_file(p)) {
+        language_file = p;
+        found_language_file = true;
+        break;
+      }
+    }
+    if (found_language_file) {
+      auto completion_buffer_keywords = CompletionBuffer::create();
+      boost::property_tree::ptree pt;
+      try {
+        boost::property_tree::xml_parser::read_xml(language_file.string(), pt);
+      }
+      catch (const std::exception &e) {
+        Terminal::get().print(
+            "Error: error parsing language file " + language_file.string() + ": " + e.what() + '\n', true);
+      }
+      bool has_context_class = false;
+      parse_language_file(completion_buffer_keywords, has_context_class, pt);
+      if (!has_context_class)
+        spellcheck_all = false;
+      completion_words->register_provider(completion_buffer_keywords);
     }
+  }
 }
 
 void
 Source::GenericView::parse_language_file(Glib::RefPtr<CompletionBuffer> &completion_buffer, bool &has_context_class,
                                          const boost::property_tree::ptree &pt) {
-    bool case_insensitive = false;
-    for (auto &node: pt) {
-        if (node.first == "<xmlcomment>") {
-            auto data = static_cast<std::string>(node.second.data());
-            std::transform(data.begin(), data.end(), data.begin(), ::tolower);
-            if (data.find("case insensitive") != std::string::npos)
-                case_insensitive = true;
-        } else if (node.first == "keyword") {
-            auto data = static_cast<std::string>(node.second.data());
-            completion_buffer->insert_at_cursor(data + '\n');
-            if (case_insensitive) {
-                std::transform(data.begin(), data.end(), data.begin(), ::tolower);
-                completion_buffer->insert_at_cursor(data + '\n');
-            }
-        } else if (!has_context_class && node.first == "context") {
-            auto class_attribute = node.second.get<std::string>("<xmlattr>.class", "");
-            auto class_disabled_attribute = node.second.get<std::string>("<xmlattr>.class-disabled", "");
-            if (class_attribute.size() > 0 || class_disabled_attribute.size() > 0)
-                has_context_class = true;
-        }
-        try {
-            parse_language_file(completion_buffer, has_context_class, node.second);
-        }
-        catch (const std::exception &e) {
-        }
+  bool case_insensitive = false;
+  for (auto &node: pt) {
+    if (node.first == "<xmlcomment>") {
+      auto data = static_cast<std::string>(node.second.data());
+      std::transform(data.begin(), data.end(), data.begin(), ::tolower);
+      if (data.find("case insensitive") != std::string::npos)
+        case_insensitive = true;
+    } else if (node.first == "keyword") {
+      auto data = static_cast<std::string>(node.second.data());
+      completion_buffer->insert_at_cursor(data + '\n');
+      if (case_insensitive) {
+        std::transform(data.begin(), data.end(), data.begin(), ::tolower);
+        completion_buffer->insert_at_cursor(data + '\n');
+      }
+    } else if (!has_context_class && node.first == "context") {
+      auto class_attribute = node.second.get<std::string>("<xmlattr>.class", "");
+      auto class_disabled_attribute = node.second.get<std::string>("<xmlattr>.class-disabled", "");
+      if (class_attribute.size() > 0 || class_disabled_attribute.size() > 0)
+        has_context_class = true;
+    }
+    try {
+      parse_language_file(completion_buffer, has_context_class, node.second);
+    }
+    catch (const std::exception &e) {
     }
+  }
 }
diff --git a/src/source.h b/src/source.h
index 48d52d2e..c261e036 100644
--- a/src/source.h
+++ b/src/source.h
@@ -11,213 +11,213 @@
 #include <tuple>
 
 namespace Source {
-    /// Workaround for buggy Gsv::LanguageManager::get_default()
-    class LanguageManager {
-    public:
-        static Glib::RefPtr<Gsv::LanguageManager> get_default();
-    };
+  /// Workaround for buggy Gsv::LanguageManager::get_default()
+  class LanguageManager {
+  public:
+    static Glib::RefPtr<Gsv::LanguageManager> get_default();
+  };
 
-    /// Workaround for buggy Gsv::StyleSchemeManager::get_default()
-    class StyleSchemeManager {
-    public:
-        static Glib::RefPtr<Gsv::StyleSchemeManager> get_default();
-    };
+  /// Workaround for buggy Gsv::StyleSchemeManager::get_default()
+  class StyleSchemeManager {
+  public:
+    static Glib::RefPtr<Gsv::StyleSchemeManager> get_default();
+  };
 
-    Glib::RefPtr<Gsv::Language> guess_language(const boost::filesystem::path &file_path);
+  Glib::RefPtr<Gsv::Language> guess_language(const boost::filesystem::path &file_path);
 
-    class Offset {
-    public:
-        Offset() {}
+  class Offset {
+  public:
+    Offset() {}
+
+    Offset(unsigned line, unsigned index, const boost::filesystem::path &file_path = "") : line(line), index(index),
+                                                                                           file_path(file_path) {}
 
-        Offset(unsigned line, unsigned index, const boost::filesystem::path &file_path = "") : line(line), index(index),
-                                                                                               file_path(file_path) {}
+    operator bool() { return !file_path.empty(); }
 
-        operator bool() { return !file_path.empty(); }
+    bool operator==(const Offset &o) { return (line == o.line && index == o.index); }
 
-        bool operator==(const Offset &o) { return (line == o.line && index == o.index); }
+    unsigned line;
+    unsigned index;
+    boost::filesystem::path file_path;
+  };
 
-        unsigned line;
-        unsigned index;
-        boost::filesystem::path file_path;
+  class FixIt {
+  public:
+    enum class Type {
+      INSERT, REPLACE, ERASE
     };
 
-    class FixIt {
-    public:
-        enum class Type {
-            INSERT, REPLACE, ERASE
-        };
+    FixIt(const std::string &source, const std::pair<Offset, Offset> &offsets);
 
-        FixIt(const std::string &source, const std::pair<Offset, Offset> &offsets);
+    std::string string(Glib::RefPtr<Gtk::TextBuffer> buffer);
 
-        std::string string(Glib::RefPtr<Gtk::TextBuffer> buffer);
+    Type type;
+    std::string source;
+    std::pair<Offset, Offset> offsets;
+  };
 
-        Type type;
-        std::string source;
-        std::pair<Offset, Offset> offsets;
-    };
+  class View : public SpellCheckView, public DiffView {
+  public:
+    static std::unordered_set<View *> non_deleted_views;
+    static std::unordered_set<View *> views;
 
-    class View : public SpellCheckView, public DiffView {
-    public:
-        static std::unordered_set<View *> non_deleted_views;
-        static std::unordered_set<View *> views;
+    View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language,
+         bool is_generic_view = false);
 
-        View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language,
-             bool is_generic_view = false);
+    ~View();
 
-        ~View();
+    bool save() override;
 
-        bool save() override;
+    void configure() override;
 
-        void configure() override;
+    void search_highlight(const std::string &text, bool case_sensitive, bool regex);
 
-        void search_highlight(const std::string &text, bool case_sensitive, bool regex);
+    std::function<void(int number)> update_search_occurrences;
 
-        std::function<void(int number)> update_search_occurrences;
+    void search_forward();
 
-        void search_forward();
+    void search_backward();
 
-        void search_backward();
+    void replace_forward(const std::string &replacement);
 
-        void replace_forward(const std::string &replacement);
+    void replace_backward(const std::string &replacement);
 
-        void replace_backward(const std::string &replacement);
+    void replace_all(const std::string &replacement);
 
-        void replace_all(const std::string &replacement);
+    void paste();
 
-        void paste();
+    std::function<void()> non_interactive_completion;
+    std::function<void(bool)> format_style;
+    std::function<Offset()> get_declaration_location;
+    std::function<Offset()> get_type_declaration_location;
+    std::function<std::vector<Offset>()> get_implementation_locations;
+    std::function<std::vector<Offset>()> get_declaration_or_implementation_locations;
+    std::function<std::vector<std::pair<Offset, std::string> >()> get_usages;
+    std::function<std::string()> get_method;
+    std::function<std::vector<std::pair<Offset, std::string> >()> get_methods;
+    std::function<std::vector<std::string>()> get_token_data;
+    std::function<std::string()> get_token_spelling;
+    std::function<void(const std::string &text)> rename_similar_tokens;
+    std::function<void()> goto_next_diagnostic;
+    std::function<std::vector<FixIt>()> get_fix_its;
+    std::function<void()> toggle_comments;
+    std::function<std::tuple<Source::Offset, std::string, size_t>()> get_documentation_template;
+    std::function<void(int)> toggle_breakpoint;
 
-        std::function<void()> non_interactive_completion;
-        std::function<void(bool)> format_style;
-        std::function<Offset()> get_declaration_location;
-        std::function<Offset()> get_type_declaration_location;
-        std::function<std::vector<Offset>()> get_implementation_locations;
-        std::function<std::vector<Offset>()> get_declaration_or_implementation_locations;
-        std::function<std::vector<std::pair<Offset, std::string> >()> get_usages;
-        std::function<std::string()> get_method;
-        std::function<std::vector<std::pair<Offset, std::string> >()> get_methods;
-        std::function<std::vector<std::string>()> get_token_data;
-        std::function<std::string()> get_token_spelling;
-        std::function<void(const std::string &text)> rename_similar_tokens;
-        std::function<void()> goto_next_diagnostic;
-        std::function<std::vector<FixIt>()> get_fix_its;
-        std::function<void()> toggle_comments;
-        std::function<std::tuple<Source::Offset, std::string, size_t>()> get_documentation_template;
-        std::function<void(int)> toggle_breakpoint;
+    void hide_tooltips() override;
 
-        void hide_tooltips() override;
+    void hide_dialogs() override;
 
-        void hide_dialogs() override;
+    void set_tab_char_and_size(char tab_char, unsigned tab_size);
 
-        void set_tab_char_and_size(char tab_char, unsigned tab_size);
+    std::pair<char, unsigned> get_tab_char_and_size() { return {tab_char, tab_size}; }
 
-        std::pair<char, unsigned> get_tab_char_and_size() { return {tab_char, tab_size}; }
+    bool soft_reparse_needed = false;
+    bool full_reparse_needed = false;
 
-        bool soft_reparse_needed = false;
-        bool full_reparse_needed = false;
+    virtual void soft_reparse(bool delayed = false) { soft_reparse_needed = false; }
 
-        virtual void soft_reparse(bool delayed = false) { soft_reparse_needed = false; }
+    virtual void full_reparse() { full_reparse_needed = false; }
 
-        virtual void full_reparse() { full_reparse_needed = false; }
+  protected:
+    bool parsed = true;
+    Tooltips diagnostic_tooltips;
+    Tooltips type_tooltips;
+    sigc::connection delayed_tooltips_connection;
 
-    protected:
-        bool parsed = true;
-        Tooltips diagnostic_tooltips;
-        Tooltips type_tooltips;
-        sigc::connection delayed_tooltips_connection;
+    virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) { diagnostic_tooltips.show(rectangle); }
 
-        virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) { diagnostic_tooltips.show(rectangle); }
+    void
+    add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, std::string spelling, bool error);
 
-        void
-        add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, std::string spelling, bool error);
+    void clear_diagnostic_tooltips();
 
-        void clear_diagnostic_tooltips();
+    virtual void show_type_tooltips(const Gdk::Rectangle &rectangle) {}
 
-        virtual void show_type_tooltips(const Gdk::Rectangle &rectangle) {}
+    gdouble on_motion_last_x = 0.0;
+    gdouble on_motion_last_y = 0.0;
 
-        gdouble on_motion_last_x = 0.0;
-        gdouble on_motion_last_y = 0.0;
+    /// Usually returns at start of line, but not always
+    Gtk::TextIter find_start_of_sentence(Gtk::TextIter iter);
 
-        /// Usually returns at start of line, but not always
-        Gtk::TextIter find_start_of_sentence(Gtk::TextIter iter);
+    bool find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
 
-        bool find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
+    bool find_open_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
 
-        bool find_open_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
+    bool find_close_curly_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
 
-        bool find_close_curly_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
+    long symbol_count(Gtk::TextIter iter, unsigned int positive_char, unsigned int negative_char);
 
-        long symbol_count(Gtk::TextIter iter, unsigned int positive_char, unsigned int negative_char);
+    bool is_templated_function(Gtk::TextIter iter, Gtk::TextIter &parenthesis_end_iter);
 
-        bool is_templated_function(Gtk::TextIter iter, Gtk::TextIter &parenthesis_end_iter);
+    std::string get_token(Gtk::TextIter iter);
 
-        std::string get_token(Gtk::TextIter iter);
+    void cleanup_whitespace_characters_on_return(const Gtk::TextIter &iter);
 
-        void cleanup_whitespace_characters_on_return(const Gtk::TextIter &iter);
+    bool is_bracket_language = false;
 
-        bool is_bracket_language = false;
+    bool on_key_press_event(GdkEventKey *key) override;
 
-        bool on_key_press_event(GdkEventKey *key) override;
+    bool on_key_press_event_basic(GdkEventKey *key);
 
-        bool on_key_press_event_basic(GdkEventKey *key);
+    bool on_key_press_event_bracket_language(GdkEventKey *key);
 
-        bool on_key_press_event_bracket_language(GdkEventKey *key);
+    bool on_key_press_event_smart_brackets(GdkEventKey *key);
 
-        bool on_key_press_event_smart_brackets(GdkEventKey *key);
+    bool on_key_press_event_smart_inserts(GdkEventKey *key);
 
-        bool on_key_press_event_smart_inserts(GdkEventKey *key);
+    bool on_button_press_event(GdkEventButton *event) override;
 
-        bool on_button_press_event(GdkEventButton *event) override;
+    bool on_motion_notify_event(GdkEventMotion *motion_event) override;
 
-        bool on_motion_notify_event(GdkEventMotion *motion_event) override;
+    std::pair<char, unsigned> find_tab_char_and_size();
 
-        std::pair<char, unsigned> find_tab_char_and_size();
+    unsigned tab_size;
+    char tab_char;
+    std::string tab;
 
-        unsigned tab_size;
-        char tab_char;
-        std::string tab;
+    bool interactive_completion = true;
 
-        bool interactive_completion = true;
+    guint previous_non_modifier_keyval = 0;
+  private:
+    void setup_tooltip_and_dialog_events();
 
-        guint previous_non_modifier_keyval = 0;
-    private:
-        void setup_tooltip_and_dialog_events();
+    void setup_format_style(bool is_generic_view);
 
-        void setup_format_style(bool is_generic_view);
+    void cleanup_whitespace_characters();
 
-        void cleanup_whitespace_characters();
+    Gsv::DrawSpacesFlags parse_show_whitespace_characters(const std::string &text);
 
-        Gsv::DrawSpacesFlags parse_show_whitespace_characters(const std::string &text);
+    GtkSourceSearchContext *search_context;
+    GtkSourceSearchSettings *search_settings;
 
-        GtkSourceSearchContext *search_context;
-        GtkSourceSearchSettings *search_settings;
+    static void search_occurrences_updated(GtkWidget *widget, GParamSpec *property, gpointer data);
 
-        static void search_occurrences_updated(GtkWidget *widget, GParamSpec *property, gpointer data);
+    sigc::connection renderer_activate_connection;
 
-        sigc::connection renderer_activate_connection;
+    bool multiple_cursors_signals_set = false;
+    bool multiple_cursors_use = false;
+    std::vector<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, int>> multiple_cursors_extra_cursors;
+    Glib::RefPtr<Gtk::TextBuffer::Mark> multiple_cursors_last_insert;
+    int multiple_cursors_erase_backward_length;
+    int multiple_cursors_erase_forward_length;
 
-        bool multiple_cursors_signals_set = false;
-        bool multiple_cursors_use = false;
-        std::vector<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, int>> multiple_cursors_extra_cursors;
-        Glib::RefPtr<Gtk::TextBuffer::Mark> multiple_cursors_last_insert;
-        int multiple_cursors_erase_backward_length;
-        int multiple_cursors_erase_forward_length;
+    bool on_key_press_event_multiple_cursors(GdkEventKey *key);
+  };
 
-        bool on_key_press_event_multiple_cursors(GdkEventKey *key);
+  class GenericView : public View {
+  private:
+    class CompletionBuffer : public Gtk::TextBuffer {
+    public:
+      static Glib::RefPtr<CompletionBuffer> create() {
+        return Glib::RefPtr<CompletionBuffer>(new CompletionBuffer());
+      }
     };
 
-    class GenericView : public View {
-    private:
-        class CompletionBuffer : public Gtk::TextBuffer {
-        public:
-            static Glib::RefPtr<CompletionBuffer> create() {
-                return Glib::RefPtr<CompletionBuffer>(new CompletionBuffer());
-            }
-        };
+  public:
+    GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
 
-    public:
-        GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
-
-        void parse_language_file(Glib::RefPtr<CompletionBuffer> &completion_buffer, bool &has_context_class,
-                                 const boost::property_tree::ptree &pt);
-    };
+    void parse_language_file(Glib::RefPtr<CompletionBuffer> &completion_buffer, bool &has_context_class,
+                             const boost::property_tree::ptree &pt);
+  };
 }
diff --git a/src/source_base.cc b/src/source_base.cc
index 20778a5b..c768bf5f 100644
--- a/src/source_base.cc
+++ b/src/source_base.cc
@@ -6,400 +6,400 @@
 #include <fstream>
 
 Source::BaseView::BaseView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language)
-        : Gsv::View(), file_path(file_path), language(language), status_diagnostics(0, 0, 0) {
-    load(true);
-    get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0));
+    : Gsv::View(), file_path(file_path), language(language), status_diagnostics(0, 0, 0) {
+  load(true);
+  get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0));
 
-    signal_focus_in_event().connect([this](GdkEventFocus *event) {
-        if (this->last_write_time != static_cast<std::time_t>(-1))
-            check_last_write_time();
-        return false;
-    });
+  signal_focus_in_event().connect([this](GdkEventFocus *event) {
+    if (this->last_write_time != static_cast<std::time_t>(-1))
+      check_last_write_time();
+    return false;
+  });
 
-    monitor_file();
+  monitor_file();
 }
 
 Source::BaseView::~BaseView() {
-    monitor_changed_connection.disconnect();
-    delayed_monitor_changed_connection.disconnect();
+  monitor_changed_connection.disconnect();
+  delayed_monitor_changed_connection.disconnect();
 }
 
 bool Source::BaseView::load(bool not_undoable_action) {
-    boost::system::error_code ec;
-    last_write_time = boost::filesystem::last_write_time(file_path, ec);
-    if (ec)
-        last_write_time = static_cast<std::time_t>(-1);
-
-    disable_spellcheck = true;
-    if (not_undoable_action)
-        get_source_buffer()->begin_not_undoable_action();
-
-    class Guard {
-    public:
-        Source::BaseView *view;
-        bool not_undoable_action;
-
-        ~Guard() {
-            if (not_undoable_action)
-                view->get_source_buffer()->end_not_undoable_action();
-            view->disable_spellcheck = false;
-        }
-    };
-    Guard guard{this, not_undoable_action};
-
-    if (language) {
-        std::ifstream input(file_path.string(), std::ofstream::binary);
-        if (input) {
-            std::stringstream ss;
-            ss << input.rdbuf();
-            Glib::ustring ustr = ss.str();
-
-            bool valid = true;
-            Glib::ustring::iterator iter;
-            while (!ustr.validate(iter)) {
-                auto next_char_iter = iter;
-                next_char_iter++;
-                ustr.replace(iter, next_char_iter, "?");
-                valid = false;
-            }
-
-            if (!valid)
-                Terminal::get().print("Warning: " + file_path.string() +
-                                      " is not a valid UTF-8 file. Saving might corrupt the file.\n");
-
-            if (get_buffer()->size() == 0)
-                get_buffer()->insert_at_cursor(ustr);
-            else
-                replace_text(ustr.raw());
-        } else
-            return false;
-    } else {
-        std::ifstream input(file_path.string(), std::ofstream::binary);
-        if (input) {
-            std::stringstream ss;
-            ss << input.rdbuf();
-            Glib::ustring ustr = ss.str();
-
-            if (ustr.validate()) {
-                if (get_buffer()->size() == 0)
-                    get_buffer()->insert_at_cursor(ustr);
-                else
-                    replace_text(ustr.raw());
-            } else {
-                Terminal::get().print("Error: " + file_path.string() + " is not a valid UTF-8 file.\n", true);
-                return false;
-            }
-        } else
-            return false;
+  boost::system::error_code ec;
+  last_write_time = boost::filesystem::last_write_time(file_path, ec);
+  if (ec)
+    last_write_time = static_cast<std::time_t>(-1);
+
+  disable_spellcheck = true;
+  if (not_undoable_action)
+    get_source_buffer()->begin_not_undoable_action();
+
+  class Guard {
+  public:
+    Source::BaseView *view;
+    bool not_undoable_action;
+
+    ~Guard() {
+      if (not_undoable_action)
+        view->get_source_buffer()->end_not_undoable_action();
+      view->disable_spellcheck = false;
     }
+  };
+  Guard guard{this, not_undoable_action};
+
+  if (language) {
+    std::ifstream input(file_path.string(), std::ofstream::binary);
+    if (input) {
+      std::stringstream ss;
+      ss << input.rdbuf();
+      Glib::ustring ustr = ss.str();
+
+      bool valid = true;
+      Glib::ustring::iterator iter;
+      while (!ustr.validate(iter)) {
+        auto next_char_iter = iter;
+        next_char_iter++;
+        ustr.replace(iter, next_char_iter, "?");
+        valid = false;
+      }
 
-    get_buffer()->set_modified(false);
-    return true;
+      if (!valid)
+        Terminal::get().print("Warning: " + file_path.string() +
+                              " is not a valid UTF-8 file. Saving might corrupt the file.\n");
+
+      if (get_buffer()->size() == 0)
+        get_buffer()->insert_at_cursor(ustr);
+      else
+        replace_text(ustr.raw());
+    } else
+      return false;
+  } else {
+    std::ifstream input(file_path.string(), std::ofstream::binary);
+    if (input) {
+      std::stringstream ss;
+      ss << input.rdbuf();
+      Glib::ustring ustr = ss.str();
+
+      if (ustr.validate()) {
+        if (get_buffer()->size() == 0)
+          get_buffer()->insert_at_cursor(ustr);
+        else
+          replace_text(ustr.raw());
+      } else {
+        Terminal::get().print("Error: " + file_path.string() + " is not a valid UTF-8 file.\n", true);
+        return false;
+      }
+    } else
+      return false;
+  }
+
+  get_buffer()->set_modified(false);
+  return true;
 }
 
 void Source::BaseView::replace_text(const std::string &new_text) {
-    get_buffer()->begin_user_action();
+  get_buffer()->begin_user_action();
 
-    if (get_buffer()->size() == 0) {
-        get_buffer()->insert_at_cursor(new_text);
-        get_buffer()->end_user_action();
-        return;
-    } else if (new_text.empty()) {
-        get_buffer()->set_text(new_text);
-        get_buffer()->end_user_action();
-        return;
-    }
+  if (get_buffer()->size() == 0) {
+    get_buffer()->insert_at_cursor(new_text);
+    get_buffer()->end_user_action();
+    return;
+  } else if (new_text.empty()) {
+    get_buffer()->set_text(new_text);
+    get_buffer()->end_user_action();
+    return;
+  }
 
-    auto iter = get_buffer()->get_insert()->get_iter();
-    int cursor_line_nr = iter.get_line();
-    int cursor_line_offset = iter.ends_line() ? std::numeric_limits<int>::max() : iter.get_line_offset();
+  auto iter = get_buffer()->get_insert()->get_iter();
+  int cursor_line_nr = iter.get_line();
+  int cursor_line_offset = iter.ends_line() ? std::numeric_limits<int>::max() : iter.get_line_offset();
 
-    std::vector<std::pair<const char *, const char *>> new_lines;
+  std::vector<std::pair<const char *, const char *>> new_lines;
 
-    const char *line_start = new_text.c_str();
-    for (size_t i = 0; i < new_text.size(); ++i) {
-        if (new_text[i] == '\n') {
-            new_lines.emplace_back(line_start, &new_text[i] + 1);
-            line_start = &new_text[i] + 1;
-        }
+  const char *line_start = new_text.c_str();
+  for (size_t i = 0; i < new_text.size(); ++i) {
+    if (new_text[i] == '\n') {
+      new_lines.emplace_back(line_start, &new_text[i] + 1);
+      line_start = &new_text[i] + 1;
     }
-    if (new_text.empty() || new_text.back() != '\n')
-        new_lines.emplace_back(line_start, &new_text[new_text.size()]);
-
-    try {
-        auto hunks = Git::Repository::Diff::get_hunks(get_buffer()->get_text().raw(), new_text);
-
-        for (auto it = hunks.rbegin(); it != hunks.rend(); ++it) {
-            bool place_cursor = false;
-            Gtk::TextIter start;
-            if (it->old_lines.second != 0) {
-                start = get_buffer()->get_iter_at_line(it->old_lines.first - 1);
-                auto end = get_buffer()->get_iter_at_line(it->old_lines.first - 1 + it->old_lines.second);
-
-                if (cursor_line_nr >= start.get_line() && cursor_line_nr < end.get_line()) {
-                    if (it->new_lines.second != 0) {
-                        place_cursor = true;
-                        int line_diff = cursor_line_nr - start.get_line();
-                        cursor_line_nr += static_cast<int>(0.5 +
-                                                           (static_cast<float>(line_diff) / it->old_lines.second) *
-                                                           it->new_lines.second) - line_diff;
-                    }
-                }
-
-                get_buffer()->erase(start, end);
-                start = get_buffer()->get_iter_at_line(it->old_lines.first - 1);
-            } else
-                start = get_buffer()->get_iter_at_line(it->old_lines.first);
-            if (it->new_lines.second != 0) {
-                get_buffer()->insert(start, new_lines[it->new_lines.first - 1].first,
-                                     new_lines[it->new_lines.first - 1 + it->new_lines.second - 1].second);
-                if (place_cursor)
-                    place_cursor_at_line_offset(cursor_line_nr, cursor_line_offset);
-            }
+  }
+  if (new_text.empty() || new_text.back() != '\n')
+    new_lines.emplace_back(line_start, &new_text[new_text.size()]);
+
+  try {
+    auto hunks = Git::Repository::Diff::get_hunks(get_buffer()->get_text().raw(), new_text);
+
+    for (auto it = hunks.rbegin(); it != hunks.rend(); ++it) {
+      bool place_cursor = false;
+      Gtk::TextIter start;
+      if (it->old_lines.second != 0) {
+        start = get_buffer()->get_iter_at_line(it->old_lines.first - 1);
+        auto end = get_buffer()->get_iter_at_line(it->old_lines.first - 1 + it->old_lines.second);
+
+        if (cursor_line_nr >= start.get_line() && cursor_line_nr < end.get_line()) {
+          if (it->new_lines.second != 0) {
+            place_cursor = true;
+            int line_diff = cursor_line_nr - start.get_line();
+            cursor_line_nr += static_cast<int>(0.5 +
+                                               (static_cast<float>(line_diff) / it->old_lines.second) *
+                                               it->new_lines.second) - line_diff;
+          }
         }
+
+        get_buffer()->erase(start, end);
+        start = get_buffer()->get_iter_at_line(it->old_lines.first - 1);
+      } else
+        start = get_buffer()->get_iter_at_line(it->old_lines.first);
+      if (it->new_lines.second != 0) {
+        get_buffer()->insert(start, new_lines[it->new_lines.first - 1].first,
+                             new_lines[it->new_lines.first - 1 + it->new_lines.second - 1].second);
+        if (place_cursor)
+          place_cursor_at_line_offset(cursor_line_nr, cursor_line_offset);
+      }
     }
-    catch (...) {
-        Terminal::get().print("Error: Could not replace text in buffer\n", true);
-    }
+  }
+  catch (...) {
+    Terminal::get().print("Error: Could not replace text in buffer\n", true);
+  }
 
-    get_buffer()->end_user_action();
+  get_buffer()->end_user_action();
 }
 
 void Source::BaseView::rename(const boost::filesystem::path &path) {
-    file_path = path;
+  file_path = path;
 
-    if (update_status_file_path)
-        update_status_file_path(this);
-    if (update_tab_label)
-        update_tab_label(this);
+  if (update_status_file_path)
+    update_status_file_path(this);
+  if (update_tab_label)
+    update_tab_label(this);
 }
 
 void Source::BaseView::monitor_file() {
 #ifdef __APPLE__ // TODO: Gio file monitor is bugged on MacOS
-    class Recursive {
-    public:
-      static void f(BaseView *view, std::time_t last_write_time_) {
-        view->delayed_monitor_changed_connection.disconnect();
-        view->delayed_monitor_changed_connection=Glib::signal_timeout().connect([view, last_write_time_]() {
-          boost::system::error_code ec;
-          auto last_write_time=boost::filesystem::last_write_time(view->file_path, ec);
-          if(last_write_time!=last_write_time_)
-            view->check_last_write_time(last_write_time);
-          Recursive::f(view, last_write_time);
+  class Recursive {
+  public:
+    static void f(BaseView *view, std::time_t last_write_time_) {
+      view->delayed_monitor_changed_connection.disconnect();
+      view->delayed_monitor_changed_connection=Glib::signal_timeout().connect([view, last_write_time_]() {
+        boost::system::error_code ec;
+        auto last_write_time=boost::filesystem::last_write_time(view->file_path, ec);
+        if(last_write_time!=last_write_time_)
+          view->check_last_write_time(last_write_time);
+        Recursive::f(view, last_write_time);
+        return false;
+      }, 1000);
+    }
+  };
+  delayed_monitor_changed_connection.disconnect();
+  if(this->last_write_time!=static_cast<std::time_t>(-1))
+    Recursive::f(this, last_write_time);
+#else
+  if (this->last_write_time != static_cast<std::time_t>(-1)) {
+    monitor = Gio::File::create_for_path(file_path.string())->monitor_file(
+        Gio::FileMonitorFlags::FILE_MONITOR_NONE);
+    monitor_changed_connection.disconnect();
+    monitor_changed_connection = monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
+                                                                          const Glib::RefPtr<Gio::File> &,
+                                                                          Gio::FileMonitorEvent monitor_event) {
+      if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+        delayed_monitor_changed_connection.disconnect();
+        delayed_monitor_changed_connection = Glib::signal_timeout().connect([this]() {
+          check_last_write_time();
           return false;
-        }, 1000);
+        }, 500);
       }
-    };
-    delayed_monitor_changed_connection.disconnect();
-    if(this->last_write_time!=static_cast<std::time_t>(-1))
-      Recursive::f(this, last_write_time);
-#else
-    if (this->last_write_time != static_cast<std::time_t>(-1)) {
-        monitor = Gio::File::create_for_path(file_path.string())->monitor_file(
-                Gio::FileMonitorFlags::FILE_MONITOR_NONE);
-        monitor_changed_connection.disconnect();
-        monitor_changed_connection = monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
-                                                                              const Glib::RefPtr<Gio::File> &,
-                                                                              Gio::FileMonitorEvent monitor_event) {
-            if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-                delayed_monitor_changed_connection.disconnect();
-                delayed_monitor_changed_connection = Glib::signal_timeout().connect([this]() {
-                    check_last_write_time();
-                    return false;
-                }, 500);
-            }
-        });
-    }
+    });
+  }
 #endif
 }
 
 void Source::BaseView::check_last_write_time(std::time_t last_write_time_) {
-    if (this->last_write_time == static_cast<std::time_t>(-1))
-        return;
+  if (this->last_write_time == static_cast<std::time_t>(-1))
+    return;
 
-    if (Config::get().source.auto_reload_changed_files && !get_buffer()->get_modified()) {
-        boost::system::error_code ec;
-        auto last_write_time = last_write_time_ != static_cast<std::time_t>(-1) ? last_write_time_
-                                                                                : boost::filesystem::last_write_time(
-                        file_path, ec);
-        if (!ec && last_write_time != this->last_write_time) {
-            if (load())
-                return;
-        }
-    } else if (has_focus()) {
-        boost::system::error_code ec;
-        auto last_write_time = last_write_time_ != static_cast<std::time_t>(-1) ? last_write_time_
-                                                                                : boost::filesystem::last_write_time(
-                        file_path, ec);
-        if (!ec && last_write_time != this->last_write_time)
-            Info::get().print("Caution: " + file_path.filename().string() + " was changed outside of juCi++");
+  if (Config::get().source.auto_reload_changed_files && !get_buffer()->get_modified()) {
+    boost::system::error_code ec;
+    auto last_write_time = last_write_time_ != static_cast<std::time_t>(-1) ? last_write_time_
+                                                                            : boost::filesystem::last_write_time(
+            file_path, ec);
+    if (!ec && last_write_time != this->last_write_time) {
+      if (load())
+        return;
     }
+  } else if (has_focus()) {
+    boost::system::error_code ec;
+    auto last_write_time = last_write_time_ != static_cast<std::time_t>(-1) ? last_write_time_
+                                                                            : boost::filesystem::last_write_time(
+            file_path, ec);
+    if (!ec && last_write_time != this->last_write_time)
+      Info::get().print("Caution: " + file_path.filename().string() + " was changed outside of juCi++");
+  }
 }
 
 Gtk::TextIter Source::BaseView::get_iter_at_line_pos(int line, int pos) {
-    return get_iter_at_line_index(line, pos);
+  return get_iter_at_line_index(line, pos);
 }
 
 Gtk::TextIter Source::BaseView::get_iter_at_line_offset(int line, int offset) {
-    line = std::min(line, get_buffer()->get_line_count() - 1);
-    if (line < 0)
-        line = 0;
-    auto iter = get_iter_at_line_end(line);
-    offset = std::min(offset, iter.get_line_offset());
-    if (offset < 0)
-        offset = 0;
-    return get_buffer()->get_iter_at_line_offset(line, offset);
+  line = std::min(line, get_buffer()->get_line_count() - 1);
+  if (line < 0)
+    line = 0;
+  auto iter = get_iter_at_line_end(line);
+  offset = std::min(offset, iter.get_line_offset());
+  if (offset < 0)
+    offset = 0;
+  return get_buffer()->get_iter_at_line_offset(line, offset);
 }
 
 Gtk::TextIter Source::BaseView::get_iter_at_line_index(int line, int index) {
-    line = std::min(line, get_buffer()->get_line_count() - 1);
-    if (line < 0)
-        line = 0;
-    auto iter = get_iter_at_line_end(line);
-    index = std::min(index, iter.get_line_index());
-    if (index < 0)
-        index = 0;
-    return get_buffer()->get_iter_at_line_index(line, index);
+  line = std::min(line, get_buffer()->get_line_count() - 1);
+  if (line < 0)
+    line = 0;
+  auto iter = get_iter_at_line_end(line);
+  index = std::min(index, iter.get_line_index());
+  if (index < 0)
+    index = 0;
+  return get_buffer()->get_iter_at_line_index(line, index);
 }
 
 Gtk::TextIter Source::BaseView::get_iter_at_line_end(int line_nr) {
-    if (line_nr >= get_buffer()->get_line_count())
-        return get_buffer()->end();
-    else if (line_nr + 1 < get_buffer()->get_line_count()) {
-        auto iter = get_buffer()->get_iter_at_line(line_nr + 1);
-        iter.backward_char();
-        if (!iter.ends_line()) // for CR+LF
-            iter.backward_char();
-        return iter;
-    } else {
-        auto iter = get_buffer()->get_iter_at_line(line_nr);
-        while (!iter.ends_line() && iter.forward_char()) {}
-        return iter;
-    }
+  if (line_nr >= get_buffer()->get_line_count())
+    return get_buffer()->end();
+  else if (line_nr + 1 < get_buffer()->get_line_count()) {
+    auto iter = get_buffer()->get_iter_at_line(line_nr + 1);
+    iter.backward_char();
+    if (!iter.ends_line()) // for CR+LF
+      iter.backward_char();
+    return iter;
+  } else {
+    auto iter = get_buffer()->get_iter_at_line(line_nr);
+    while (!iter.ends_line() && iter.forward_char()) {}
+    return iter;
+  }
 }
 
 Gtk::TextIter Source::BaseView::get_iter_for_dialog() {
-    auto iter = get_buffer()->get_insert()->get_iter();
-    Gdk::Rectangle visible_rect;
-    get_visible_rect(visible_rect);
-    Gdk::Rectangle iter_rect;
+  auto iter = get_buffer()->get_insert()->get_iter();
+  Gdk::Rectangle visible_rect;
+  get_visible_rect(visible_rect);
+  Gdk::Rectangle iter_rect;
+  get_iter_location(iter, iter_rect);
+  iter_rect.set_width(1);
+  if (iter.get_line_offset() >= 80) {
+    get_iter_at_location(iter, visible_rect.get_x(), iter_rect.get_y());
     get_iter_location(iter, iter_rect);
-    iter_rect.set_width(1);
-    if (iter.get_line_offset() >= 80) {
-        get_iter_at_location(iter, visible_rect.get_x(), iter_rect.get_y());
-        get_iter_location(iter, iter_rect);
-    }
-    if (!visible_rect.intersects(iter_rect))
-        get_iter_at_location(iter, visible_rect.get_x(), visible_rect.get_y() + visible_rect.get_height() / 3);
-    return iter;
+  }
+  if (!visible_rect.intersects(iter_rect))
+    get_iter_at_location(iter, visible_rect.get_x(), visible_rect.get_y() + visible_rect.get_height() / 3);
+  return iter;
 }
 
 void Source::BaseView::place_cursor_at_line_pos(int line, int pos) {
-    get_buffer()->place_cursor(get_iter_at_line_pos(line, pos));
+  get_buffer()->place_cursor(get_iter_at_line_pos(line, pos));
 }
 
 void Source::BaseView::place_cursor_at_line_offset(int line, int offset) {
-    get_buffer()->place_cursor(get_iter_at_line_offset(line, offset));
+  get_buffer()->place_cursor(get_iter_at_line_offset(line, offset));
 }
 
 void Source::BaseView::place_cursor_at_line_index(int line, int index) {
-    get_buffer()->place_cursor(get_iter_at_line_index(line, index));
+  get_buffer()->place_cursor(get_iter_at_line_index(line, index));
 }
 
 Gtk::TextIter Source::BaseView::get_smart_home_iter(const Gtk::TextIter &iter) {
-    auto start_line_iter = get_buffer()->get_iter_at_line(iter.get_line());
-    auto start_sentence_iter = start_line_iter;
-    while (!start_sentence_iter.ends_line() &&
-           (*start_sentence_iter == ' ' || *start_sentence_iter == '\t') &&
-           start_sentence_iter.forward_char()) {}
-
-    if (iter > start_sentence_iter || iter == start_line_iter)
-        return start_sentence_iter;
-    else
-        return start_line_iter;
+  auto start_line_iter = get_buffer()->get_iter_at_line(iter.get_line());
+  auto start_sentence_iter = start_line_iter;
+  while (!start_sentence_iter.ends_line() &&
+         (*start_sentence_iter == ' ' || *start_sentence_iter == '\t') &&
+         start_sentence_iter.forward_char()) {}
+
+  if (iter > start_sentence_iter || iter == start_line_iter)
+    return start_sentence_iter;
+  else
+    return start_line_iter;
 }
 
 Gtk::TextIter Source::BaseView::get_smart_end_iter(const Gtk::TextIter &iter) {
-    auto end_line_iter = get_iter_at_line_end(iter.get_line());
-    auto end_sentence_iter = end_line_iter;
-    while (!end_sentence_iter.starts_line() &&
-           (*end_sentence_iter == ' ' || *end_sentence_iter == '\t' || end_sentence_iter.ends_line()) &&
-           end_sentence_iter.backward_char()) {}
-    if (!end_sentence_iter.ends_line() && *end_sentence_iter != ' ' && *end_sentence_iter != '\t')
-        end_sentence_iter.forward_char();
-
-    if (iter == end_line_iter)
-        return end_sentence_iter;
-    else
-        return end_line_iter;
+  auto end_line_iter = get_iter_at_line_end(iter.get_line());
+  auto end_sentence_iter = end_line_iter;
+  while (!end_sentence_iter.starts_line() &&
+         (*end_sentence_iter == ' ' || *end_sentence_iter == '\t' || end_sentence_iter.ends_line()) &&
+         end_sentence_iter.backward_char()) {}
+  if (!end_sentence_iter.ends_line() && *end_sentence_iter != ' ' && *end_sentence_iter != '\t')
+    end_sentence_iter.forward_char();
+
+  if (iter == end_line_iter)
+    return end_sentence_iter;
+  else
+    return end_line_iter;
 }
 
 std::string Source::BaseView::get_line(const Gtk::TextIter &iter) {
-    auto line_start_it = get_buffer()->get_iter_at_line(iter.get_line());
-    auto line_end_it = get_iter_at_line_end(iter.get_line());
-    std::string line(get_buffer()->get_text(line_start_it, line_end_it));
-    return line;
+  auto line_start_it = get_buffer()->get_iter_at_line(iter.get_line());
+  auto line_end_it = get_iter_at_line_end(iter.get_line());
+  std::string line(get_buffer()->get_text(line_start_it, line_end_it));
+  return line;
 }
 
 std::string Source::BaseView::get_line(Glib::RefPtr<Gtk::TextBuffer::Mark> mark) {
-    return get_line(mark->get_iter());
+  return get_line(mark->get_iter());
 }
 
 std::string Source::BaseView::get_line(int line_nr) {
-    return get_line(get_buffer()->get_iter_at_line(line_nr));
+  return get_line(get_buffer()->get_iter_at_line(line_nr));
 }
 
 std::string Source::BaseView::get_line() {
-    return get_line(get_buffer()->get_insert());
+  return get_line(get_buffer()->get_insert());
 }
 
 std::string Source::BaseView::get_line_before(const Gtk::TextIter &iter) {
-    auto line_it = get_buffer()->get_iter_at_line(iter.get_line());
-    std::string line(get_buffer()->get_text(line_it, iter));
-    return line;
+  auto line_it = get_buffer()->get_iter_at_line(iter.get_line());
+  std::string line(get_buffer()->get_text(line_it, iter));
+  return line;
 }
 
 std::string Source::BaseView::get_line_before(Glib::RefPtr<Gtk::TextBuffer::Mark> mark) {
-    return get_line_before(mark->get_iter());
+  return get_line_before(mark->get_iter());
 }
 
 std::string Source::BaseView::get_line_before() {
-    return get_line_before(get_buffer()->get_insert());
+  return get_line_before(get_buffer()->get_insert());
 }
 
 Gtk::TextIter Source::BaseView::get_tabs_end_iter(const Gtk::TextIter &iter) {
-    return get_tabs_end_iter(iter.get_line());
+  return get_tabs_end_iter(iter.get_line());
 }
 
 Gtk::TextIter Source::BaseView::get_tabs_end_iter(Glib::RefPtr<Gtk::TextBuffer::Mark> mark) {
-    return get_tabs_end_iter(mark->get_iter());
+  return get_tabs_end_iter(mark->get_iter());
 }
 
 Gtk::TextIter Source::BaseView::get_tabs_end_iter(int line_nr) {
-    auto sentence_iter = get_buffer()->get_iter_at_line(line_nr);
-    while ((*sentence_iter == ' ' || *sentence_iter == '\t') && !sentence_iter.ends_line() &&
-           sentence_iter.forward_char()) {}
-    return sentence_iter;
+  auto sentence_iter = get_buffer()->get_iter_at_line(line_nr);
+  while ((*sentence_iter == ' ' || *sentence_iter == '\t') && !sentence_iter.ends_line() &&
+         sentence_iter.forward_char()) {}
+  return sentence_iter;
 }
 
 Gtk::TextIter Source::BaseView::get_tabs_end_iter() {
-    return get_tabs_end_iter(get_buffer()->get_insert());
+  return get_tabs_end_iter(get_buffer()->get_insert());
 }
 
 void Source::BaseView::place_cursor_at_next_diagnostic() {
-    auto insert_offset = get_buffer()->get_insert()->get_iter().get_offset();
-    for (auto offset: diagnostic_offsets) {
-        if (offset > insert_offset) {
-            get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset));
-            scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-            return;
-        }
-    }
-    if (diagnostic_offsets.size() == 0)
-        Info::get().print("No diagnostics found in current buffer");
-    else {
-        auto iter = get_buffer()->get_iter_at_offset(*diagnostic_offsets.begin());
-        get_buffer()->place_cursor(iter);
-        scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+  auto insert_offset = get_buffer()->get_insert()->get_iter().get_offset();
+  for (auto offset: diagnostic_offsets) {
+    if (offset > insert_offset) {
+      get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset));
+      scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+      return;
     }
+  }
+  if (diagnostic_offsets.size() == 0)
+    Info::get().print("No diagnostics found in current buffer");
+  else {
+    auto iter = get_buffer()->get_iter_at_offset(*diagnostic_offsets.begin());
+    get_buffer()->place_cursor(iter);
+    scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+  }
 }
diff --git a/src/source_base.h b/src/source_base.h
index 34d4ca90..a13ee67f 100644
--- a/src/source_base.h
+++ b/src/source_base.h
@@ -6,113 +6,113 @@
 #include <boost/filesystem.hpp>
 
 namespace Source {
-    class BaseView : public Gsv::View {
-    public:
-        BaseView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+  class BaseView : public Gsv::View {
+  public:
+    BaseView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
 
-        ~BaseView();
+    ~BaseView();
 
-        boost::filesystem::path file_path;
+    boost::filesystem::path file_path;
 
-        Glib::RefPtr<Gsv::Language> language;
+    Glib::RefPtr<Gsv::Language> language;
 
-        bool load(bool not_undoable_action = false);
+    bool load(bool not_undoable_action = false);
 
-        /// Set new text more optimally and without unnecessary scrolling
-        void replace_text(const std::string &new_text);
+    /// Set new text more optimally and without unnecessary scrolling
+    void replace_text(const std::string &new_text);
 
-        virtual void rename(const boost::filesystem::path &path);
+    virtual void rename(const boost::filesystem::path &path);
 
-        virtual bool save() = 0;
+    virtual bool save() = 0;
 
-        Glib::RefPtr<Gio::FileMonitor> monitor;
-        sigc::connection monitor_changed_connection;
-        sigc::connection delayed_monitor_changed_connection;
+    Glib::RefPtr<Gio::FileMonitor> monitor;
+    sigc::connection monitor_changed_connection;
+    sigc::connection delayed_monitor_changed_connection;
 
-        virtual void configure() = 0;
+    virtual void configure() = 0;
 
-        virtual void hide_tooltips() = 0;
+    virtual void hide_tooltips() = 0;
 
-        virtual void hide_dialogs() = 0;
+    virtual void hide_dialogs() = 0;
 
-        std::function<void(BaseView *view, bool center, bool show_tooltips)> scroll_to_cursor_delayed = [](
-                BaseView *view, bool center, bool show_tooltips) {};
+    std::function<void(BaseView *view, bool center, bool show_tooltips)> scroll_to_cursor_delayed = [](
+        BaseView *view, bool center, bool show_tooltips) {};
 
-        /// Safely returns iter given line and an offset using either byte index or character offset. Defaults to using byte index.
-        virtual Gtk::TextIter get_iter_at_line_pos(int line, int pos);
+    /// Safely returns iter given line and an offset using either byte index or character offset. Defaults to using byte index.
+    virtual Gtk::TextIter get_iter_at_line_pos(int line, int pos);
 
-        /// Safely returns iter given line and character offset
-        Gtk::TextIter get_iter_at_line_offset(int line, int offset);
+    /// Safely returns iter given line and character offset
+    Gtk::TextIter get_iter_at_line_offset(int line, int offset);
 
-        /// Safely returns iter given line and byte index
-        Gtk::TextIter get_iter_at_line_index(int line, int index);
+    /// Safely returns iter given line and byte index
+    Gtk::TextIter get_iter_at_line_index(int line, int index);
 
-        Gtk::TextIter get_iter_at_line_end(int line_nr);
+    Gtk::TextIter get_iter_at_line_end(int line_nr);
 
-        Gtk::TextIter get_iter_for_dialog();
+    Gtk::TextIter get_iter_for_dialog();
 
-        /// Safely places cursor at line using get_iter_at_line_pos.
-        void place_cursor_at_line_pos(int line, int pos);
+    /// Safely places cursor at line using get_iter_at_line_pos.
+    void place_cursor_at_line_pos(int line, int pos);
 
-        /// Safely places cursor at line offset
-        void place_cursor_at_line_offset(int line, int offset);
+    /// Safely places cursor at line offset
+    void place_cursor_at_line_offset(int line, int offset);
 
-        /// Safely places cursor at line index
-        void place_cursor_at_line_index(int line, int index);
+    /// Safely places cursor at line index
+    void place_cursor_at_line_index(int line, int index);
 
-    protected:
-        std::time_t last_write_time;
+  protected:
+    std::time_t last_write_time;
 
-        void monitor_file();
+    void monitor_file();
 
-        void check_last_write_time(std::time_t last_write_time_ = static_cast<std::time_t>(-1));
+    void check_last_write_time(std::time_t last_write_time_ = static_cast<std::time_t>(-1));
 
-        /// Move iter to line start. Depending on iter position, before or after indentation.
-        /// Works with wrapped lines.
-        Gtk::TextIter get_smart_home_iter(const Gtk::TextIter &iter);
+    /// Move iter to line start. Depending on iter position, before or after indentation.
+    /// Works with wrapped lines.
+    Gtk::TextIter get_smart_home_iter(const Gtk::TextIter &iter);
 
-        /// Move iter to line end. Depending on iter position, before or after indentation.
-        /// Works with wrapped lines.
-        /// Note that smart end goes FIRST to end of line to avoid hiding empty chars after expressions.
-        Gtk::TextIter get_smart_end_iter(const Gtk::TextIter &iter);
+    /// Move iter to line end. Depending on iter position, before or after indentation.
+    /// Works with wrapped lines.
+    /// Note that smart end goes FIRST to end of line to avoid hiding empty chars after expressions.
+    Gtk::TextIter get_smart_end_iter(const Gtk::TextIter &iter);
 
-        std::string get_line(const Gtk::TextIter &iter);
+    std::string get_line(const Gtk::TextIter &iter);
 
-        std::string get_line(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
+    std::string get_line(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
 
-        std::string get_line(int line_nr);
+    std::string get_line(int line_nr);
 
-        std::string get_line();
+    std::string get_line();
 
-        std::string get_line_before(const Gtk::TextIter &iter);
+    std::string get_line_before(const Gtk::TextIter &iter);
 
-        std::string get_line_before(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
+    std::string get_line_before(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
 
-        std::string get_line_before();
+    std::string get_line_before();
 
-        Gtk::TextIter get_tabs_end_iter(const Gtk::TextIter &iter);
+    Gtk::TextIter get_tabs_end_iter(const Gtk::TextIter &iter);
 
-        Gtk::TextIter get_tabs_end_iter(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
+    Gtk::TextIter get_tabs_end_iter(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
 
-        Gtk::TextIter get_tabs_end_iter(int line_nr);
+    Gtk::TextIter get_tabs_end_iter(int line_nr);
 
-        Gtk::TextIter get_tabs_end_iter();
+    Gtk::TextIter get_tabs_end_iter();
 
-        std::set<int> diagnostic_offsets;
+    std::set<int> diagnostic_offsets;
 
-        void place_cursor_at_next_diagnostic();
+    void place_cursor_at_next_diagnostic();
 
-    public:
-        std::function<void(BaseView *view)> update_tab_label;
-        std::function<void(BaseView *view)> update_status_location;
-        std::function<void(BaseView *view)> update_status_file_path;
-        std::function<void(BaseView *view)> update_status_diagnostics;
-        std::function<void(BaseView *view)> update_status_state;
-        std::tuple<size_t, size_t, size_t> status_diagnostics;
-        std::string status_state;
-        std::function<void(BaseView *view)> update_status_branch;
-        std::string status_branch;
+  public:
+    std::function<void(BaseView *view)> update_tab_label;
+    std::function<void(BaseView *view)> update_status_location;
+    std::function<void(BaseView *view)> update_status_file_path;
+    std::function<void(BaseView *view)> update_status_diagnostics;
+    std::function<void(BaseView *view)> update_status_state;
+    std::tuple<size_t, size_t, size_t> status_diagnostics;
+    std::string status_state;
+    std::function<void(BaseView *view)> update_status_branch;
+    std::string status_branch;
 
-        bool disable_spellcheck = false;
-    };
+    bool disable_spellcheck = false;
+  };
 }
diff --git a/src/source_clang.cc b/src/source_clang.cc
index 68c39bbe..d52b0b7a 100644
--- a/src/source_clang.cc
+++ b/src/source_clang.cc
@@ -19,1899 +19,1899 @@
 clangmm::Index Source::ClangViewParse::clang_index(0, 0);
 
 Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) :
-        BaseView(file_path, language), Source::View(file_path, language) {
-    Usages::Clang::erase_cache(file_path);
+    BaseView(file_path, language), Source::View(file_path, language) {
+  Usages::Clang::erase_cache(file_path);
 
-    auto tag_table = get_buffer()->get_tag_table();
-    for (auto &item : clang_types()) {
-        if (!tag_table->lookup(item.second)) {
-            get_buffer()->create_tag(item.second);
-        }
+  auto tag_table = get_buffer()->get_tag_table();
+  for (auto &item : clang_types()) {
+    if (!tag_table->lookup(item.second)) {
+      get_buffer()->create_tag(item.second);
     }
-    configure();
+  }
+  configure();
 
-    if (get_buffer()->size() == 0 && (language->get_id() == "chdr" || language->get_id() == "cpphdr")) {
-        disable_spellcheck = true;
-        get_buffer()->insert_at_cursor("#pragma once\n");
-        disable_spellcheck = false;
-        Info::get().print("Added \"#pragma once\" to empty C/C++ header file");
-    }
+  if (get_buffer()->size() == 0 && (language->get_id() == "chdr" || language->get_id() == "cpphdr")) {
+    disable_spellcheck = true;
+    get_buffer()->insert_at_cursor("#pragma once\n");
+    disable_spellcheck = false;
+    Info::get().print("Added \"#pragma once\" to empty C/C++ header file");
+  }
 
-    parse_initialize();
+  parse_initialize();
 
-    get_buffer()->signal_changed().connect([this]() {
-        soft_reparse(true);
-    });
+  get_buffer()->signal_changed().connect([this]() {
+    soft_reparse(true);
+  });
 }
 
 bool Source::ClangViewParse::save() {
-    if (!Source::View::save())
-        return false;
+  if (!Source::View::save())
+    return false;
 
-    if (language->get_id() == "chdr" || language->get_id() == "cpphdr") {
-        for (auto &view: views) {
-            if (auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
-                if (this != clang_view)
-                    clang_view->soft_reparse_needed = true;
-            }
-        }
+  if (language->get_id() == "chdr" || language->get_id() == "cpphdr") {
+    for (auto &view: views) {
+      if (auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
+        if (this != clang_view)
+          clang_view->soft_reparse_needed = true;
+      }
     }
-    return true;
+  }
+  return true;
 }
 
 void Source::ClangViewParse::configure() {
-    Source::View::configure();
-
-    auto scheme = get_source_buffer()->get_style_scheme();
-    auto tag_table = get_buffer()->get_tag_table();
-    for (auto &item : clang_types()) {
-        auto tag = get_buffer()->get_tag_table()->lookup(item.second);
-        if (tag) {
-            auto style = scheme->get_style(item.second);
-            if (style) {
-                if (style->property_foreground_set())
-                    tag->property_foreground() = style->property_foreground();
-                if (style->property_background_set())
-                    tag->property_background() = style->property_background();
-                if (style->property_strikethrough_set())
-                    tag->property_strikethrough() = style->property_strikethrough();
-                //   //    if (style->property_bold_set()) tag->property_weight() = style->property_bold();
-                //   //    if (style->property_italic_set()) tag->property_italic() = style->property_italic();
-                //   //    if (style->property_line_background_set()) tag->property_line_background() = style->property_line_background();
-                //   // if (style->property_underline_set()) tag->property_underline() = style->property_underline();
-            }
-        }
+  Source::View::configure();
+
+  auto scheme = get_source_buffer()->get_style_scheme();
+  auto tag_table = get_buffer()->get_tag_table();
+  for (auto &item : clang_types()) {
+    auto tag = get_buffer()->get_tag_table()->lookup(item.second);
+    if (tag) {
+      auto style = scheme->get_style(item.second);
+      if (style) {
+        if (style->property_foreground_set())
+          tag->property_foreground() = style->property_foreground();
+        if (style->property_background_set())
+          tag->property_background() = style->property_background();
+        if (style->property_strikethrough_set())
+          tag->property_strikethrough() = style->property_strikethrough();
+        //   //    if (style->property_bold_set()) tag->property_weight() = style->property_bold();
+        //   //    if (style->property_italic_set()) tag->property_italic() = style->property_italic();
+        //   //    if (style->property_line_background_set()) tag->property_line_background() = style->property_line_background();
+        //   // if (style->property_underline_set()) tag->property_underline() = style->property_underline();
+      }
     }
+  }
 }
 
 void Source::ClangViewParse::parse_initialize() {
-    hide_tooltips();
-    parsed = false;
-    if (parse_thread.joinable())
-        parse_thread.join();
-    parse_state = ParseState::PROCESSING;
-    parse_process_state = ParseProcessState::STARTING;
-
-    auto buffer = get_buffer()->get_text();
-    //Remove includes for first parse for initial syntax highlighting
-    std::size_t pos = 0;
-    while ((pos = buffer.find("#include", pos)) != std::string::npos) {
-        auto start_pos = pos;
-        pos = buffer.find('\n', pos + 8);
-        if (pos == std::string::npos)
-            break;
-        if (start_pos == 0 || buffer[start_pos - 1] == '\n') {
-            buffer.replace(start_pos, pos - start_pos, pos - start_pos, ' ');
-        }
-        pos++;
+  hide_tooltips();
+  parsed = false;
+  if (parse_thread.joinable())
+    parse_thread.join();
+  parse_state = ParseState::PROCESSING;
+  parse_process_state = ParseProcessState::STARTING;
+
+  auto buffer = get_buffer()->get_text();
+  //Remove includes for first parse for initial syntax highlighting
+  std::size_t pos = 0;
+  while ((pos = buffer.find("#include", pos)) != std::string::npos) {
+    auto start_pos = pos;
+    pos = buffer.find('\n', pos + 8);
+    if (pos == std::string::npos)
+      break;
+    if (start_pos == 0 || buffer[start_pos - 1] == '\n') {
+      buffer.replace(start_pos, pos - start_pos, pos - start_pos, ' ');
     }
-    auto &buffer_raw = const_cast<std::string &>(buffer.raw());
-    if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr"))
-        clangmm::remove_include_guard(buffer_raw);
-
-    auto build = Project::Build::create(file_path);
-    if (build->project_path.empty())
-        Info::get().print(file_path.filename().string() + ": could not find a supported build system");
-    build->update_default();
-    auto arguments = CompileCommands::get_arguments(build->get_default_path(), file_path);
-    clang_tu = std::make_unique<clangmm::TranslationUnit>(clang_index, file_path.string(), arguments, buffer_raw);
-    clang_tokens = clang_tu->get_tokens();
-    clang_tokens_offsets.clear();
-    clang_tokens_offsets.reserve(clang_tokens->size());
-    for (auto &token: *clang_tokens)
-        clang_tokens_offsets.emplace_back(token.get_source_range().get_offsets());
-    update_syntax();
-
-    status_state = "parsing...";
-    if (update_status_state)
-        update_status_state(this);
-    parse_thread = std::thread([this]() {
-        while (true) {
-            while (parse_state == ParseState::PROCESSING && parse_process_state != ParseProcessState::STARTING &&
-                   parse_process_state != ParseProcessState::PROCESSING)
-                std::this_thread::sleep_for(std::chrono::milliseconds(10));
-            if (parse_state != ParseState::PROCESSING)
-                break;
-            auto expected = ParseProcessState::STARTING;
-            std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-            if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) {
-                dispatcher.post([this] {
-                    auto expected = ParseProcessState::PREPROCESSING;
-                    std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-                    if (parse_lock.try_lock()) {
-                        if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING))
-                            parse_thread_buffer = get_buffer()->get_text();
-                        parse_lock.unlock();
-                    } else
-                        parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING);
-                });
-            } else if (parse_process_state == ParseProcessState::PROCESSING && parse_lock.try_lock()) {
-                auto &parse_thread_buffer_raw = const_cast<std::string &>(parse_thread_buffer.raw());
-                if (this->language && (this->language->get_id() == "chdr" || this->language->get_id() == "cpphdr"))
-                    clangmm::remove_include_guard(parse_thread_buffer_raw);
-                auto status = clang_tu->reparse(parse_thread_buffer_raw);
-                if (status == 0) {
-                    auto expected = ParseProcessState::PROCESSING;
-                    if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) {
-                        clang_tokens = clang_tu->get_tokens();
-                        clang_tokens_offsets.clear();
-                        clang_tokens_offsets.reserve(clang_tokens->size());
-                        for (auto &token: *clang_tokens)
-                            clang_tokens_offsets.emplace_back(token.get_source_range().get_offsets());
-                        clang_diagnostics = clang_tu->get_diagnostics();
-                        parse_lock.unlock();
-                        dispatcher.post([this] {
-                            std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-                            if (parse_lock.try_lock()) {
-                                auto expected = ParseProcessState::POSTPROCESSING;
-                                if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) {
-                                    update_syntax();
-                                    update_diagnostics();
-                                    parsed = true;
-                                    status_state = "";
-                                    if (update_status_state)
-                                        update_status_state(this);
-                                }
-                                parse_lock.unlock();
-                            }
-                        });
-                    } else
-                        parse_lock.unlock();
-                } else {
-                    parse_state = ParseState::STOP;
-                    parse_lock.unlock();
-                    dispatcher.post([this] {
-                        Terminal::get().print("Error: failed to reparse " + this->file_path.string() + ".\n", true);
-                        status_state = "";
-                        if (update_status_state)
-                            update_status_state(this);
-                        status_diagnostics = std::make_tuple(0, 0, 0);
-                        if (update_status_diagnostics)
-                            update_status_diagnostics(this);
-                    });
+    pos++;
+  }
+  auto &buffer_raw = const_cast<std::string &>(buffer.raw());
+  if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr"))
+    clangmm::remove_include_guard(buffer_raw);
+
+  auto build = Project::Build::create(file_path);
+  if (build->project_path.empty())
+    Info::get().print(file_path.filename().string() + ": could not find a supported build system");
+  build->update_default();
+  auto arguments = CompileCommands::get_arguments(build->get_default_path(), file_path);
+  clang_tu = std::make_unique<clangmm::TranslationUnit>(clang_index, file_path.string(), arguments, buffer_raw);
+  clang_tokens = clang_tu->get_tokens();
+  clang_tokens_offsets.clear();
+  clang_tokens_offsets.reserve(clang_tokens->size());
+  for (auto &token: *clang_tokens)
+    clang_tokens_offsets.emplace_back(token.get_source_range().get_offsets());
+  update_syntax();
+
+  status_state = "parsing...";
+  if (update_status_state)
+    update_status_state(this);
+  parse_thread = std::thread([this]() {
+    while (true) {
+      while (parse_state == ParseState::PROCESSING && parse_process_state != ParseProcessState::STARTING &&
+             parse_process_state != ParseProcessState::PROCESSING)
+        std::this_thread::sleep_for(std::chrono::milliseconds(10));
+      if (parse_state != ParseState::PROCESSING)
+        break;
+      auto expected = ParseProcessState::STARTING;
+      std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+      if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) {
+        dispatcher.post([this] {
+          auto expected = ParseProcessState::PREPROCESSING;
+          std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+          if (parse_lock.try_lock()) {
+            if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING))
+              parse_thread_buffer = get_buffer()->get_text();
+            parse_lock.unlock();
+          } else
+            parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING);
+        });
+      } else if (parse_process_state == ParseProcessState::PROCESSING && parse_lock.try_lock()) {
+        auto &parse_thread_buffer_raw = const_cast<std::string &>(parse_thread_buffer.raw());
+        if (this->language && (this->language->get_id() == "chdr" || this->language->get_id() == "cpphdr"))
+          clangmm::remove_include_guard(parse_thread_buffer_raw);
+        auto status = clang_tu->reparse(parse_thread_buffer_raw);
+        if (status == 0) {
+          auto expected = ParseProcessState::PROCESSING;
+          if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) {
+            clang_tokens = clang_tu->get_tokens();
+            clang_tokens_offsets.clear();
+            clang_tokens_offsets.reserve(clang_tokens->size());
+            for (auto &token: *clang_tokens)
+              clang_tokens_offsets.emplace_back(token.get_source_range().get_offsets());
+            clang_diagnostics = clang_tu->get_diagnostics();
+            parse_lock.unlock();
+            dispatcher.post([this] {
+              std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+              if (parse_lock.try_lock()) {
+                auto expected = ParseProcessState::POSTPROCESSING;
+                if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) {
+                  update_syntax();
+                  update_diagnostics();
+                  parsed = true;
+                  status_state = "";
+                  if (update_status_state)
+                    update_status_state(this);
                 }
-            }
+                parse_lock.unlock();
+              }
+            });
+          } else
+            parse_lock.unlock();
+        } else {
+          parse_state = ParseState::STOP;
+          parse_lock.unlock();
+          dispatcher.post([this] {
+            Terminal::get().print("Error: failed to reparse " + this->file_path.string() + ".\n", true);
+            status_state = "";
+            if (update_status_state)
+              update_status_state(this);
+            status_diagnostics = std::make_tuple(0, 0, 0);
+            if (update_status_diagnostics)
+              update_status_diagnostics(this);
+          });
         }
-    });
+      }
+    }
+  });
 }
 
 void Source::ClangViewParse::soft_reparse(bool delayed) {
-    soft_reparse_needed = false;
+  soft_reparse_needed = false;
+  parsed = false;
+  if (parse_state != ParseState::PROCESSING)
+    return;
+  parse_process_state = ParseProcessState::IDLE;
+  delayed_reparse_connection.disconnect();
+  delayed_reparse_connection = Glib::signal_timeout().connect([this]() {
     parsed = false;
-    if (parse_state != ParseState::PROCESSING)
-        return;
-    parse_process_state = ParseProcessState::IDLE;
-    delayed_reparse_connection.disconnect();
-    delayed_reparse_connection = Glib::signal_timeout().connect([this]() {
-        parsed = false;
-        auto expected = ParseProcessState::IDLE;
-        if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING)) {
-            status_state = "parsing...";
-            if (update_status_state)
-                update_status_state(this);
-        }
-        return false;
-    }, delayed ? 1000 : 0);
+    auto expected = ParseProcessState::IDLE;
+    if (parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING)) {
+      status_state = "parsing...";
+      if (update_status_state)
+        update_status_state(this);
+    }
+    return false;
+  }, delayed ? 1000 : 0);
 }
 
 const std::unordered_map<int, std::string> &Source::ClangViewParse::clang_types() {
-    static std::unordered_map<int, std::string> types{
-            {8,   "def:function"},
-            {21,  "def:function"},
-            {22,  "def:identifier"},
-            {24,  "def:function"},
-            {25,  "def:function"},
-            {43,  "def:type"},
-            {44,  "def:type"},
-            {45,  "def:type"},
-            {46,  "def:identifier"},
-            {109, "def:string"},
-            {702, "def:statement"},
-            {705, "def:comment"}
-    };
-    return types;
+  static std::unordered_map<int, std::string> types{
+      {8,   "def:function"},
+      {21,  "def:function"},
+      {22,  "def:identifier"},
+      {24,  "def:function"},
+      {25,  "def:function"},
+      {43,  "def:type"},
+      {44,  "def:type"},
+      {45,  "def:type"},
+      {46,  "def:identifier"},
+      {109, "def:string"},
+      {702, "def:statement"},
+      {705, "def:comment"}
+  };
+  return types;
 }
 
 void Source::ClangViewParse::update_syntax() {
-    auto buffer = get_buffer();
-    const auto apply_tag = [this, buffer](const std::pair<clangmm::Offset, clangmm::Offset> &offsets, int type) {
-        auto type_it = clang_types().find(type);
-        if (type_it != clang_types().end()) {
-            last_syntax_tags.emplace(type_it->second);
-            Gtk::TextIter begin_iter = buffer->get_iter_at_line_index(offsets.first.line - 1, offsets.first.index - 1);
-            Gtk::TextIter end_iter = buffer->get_iter_at_line_index(offsets.second.line - 1, offsets.second.index - 1);
-            buffer->apply_tag_by_name(type_it->second, begin_iter, end_iter);
-        }
-    };
-
-    for (auto &tag: last_syntax_tags)
-        buffer->remove_tag_by_name(tag, buffer->begin(), buffer->end());
-    last_syntax_tags.clear();
-
-    for (size_t c = 0; c < clang_tokens->size(); ++c) {
-        auto &token = (*clang_tokens)[c];
-        auto &token_offsets = clang_tokens_offsets[c];
-        //if(token.get_kind()==clangmm::Token::Kind::Token_Punctuation)
-        //ranges.emplace_back(token_offset, static_cast<int>(token.get_cursor().get_kind()));
-        auto token_kind = token.get_kind();
-        if (token_kind == clangmm::Token::Kind::Keyword)
-            apply_tag(token_offsets, 702);
-        else if (token_kind == clangmm::Token::Kind::Identifier) {
-            auto cursor_kind = token.get_cursor().get_kind();
-            if (cursor_kind == clangmm::Cursor::Kind::DeclRefExpr ||
-                cursor_kind == clangmm::Cursor::Kind::MemberRefExpr)
-                cursor_kind = token.get_cursor().get_referenced().get_kind();
-            if (cursor_kind != clangmm::Cursor::Kind::PreprocessingDirective)
-                apply_tag(token_offsets, static_cast<int>(cursor_kind));
-        } else if (token_kind == clangmm::Token::Kind::Literal)
-            apply_tag(token_offsets, static_cast<int>(clangmm::Cursor::Kind::StringLiteral));
-        else if (token_kind == clangmm::Token::Kind::Comment)
-            apply_tag(token_offsets, 705);
+  auto buffer = get_buffer();
+  const auto apply_tag = [this, buffer](const std::pair<clangmm::Offset, clangmm::Offset> &offsets, int type) {
+    auto type_it = clang_types().find(type);
+    if (type_it != clang_types().end()) {
+      last_syntax_tags.emplace(type_it->second);
+      Gtk::TextIter begin_iter = buffer->get_iter_at_line_index(offsets.first.line - 1, offsets.first.index - 1);
+      Gtk::TextIter end_iter = buffer->get_iter_at_line_index(offsets.second.line - 1, offsets.second.index - 1);
+      buffer->apply_tag_by_name(type_it->second, begin_iter, end_iter);
     }
+  };
+
+  for (auto &tag: last_syntax_tags)
+    buffer->remove_tag_by_name(tag, buffer->begin(), buffer->end());
+  last_syntax_tags.clear();
+
+  for (size_t c = 0; c < clang_tokens->size(); ++c) {
+    auto &token = (*clang_tokens)[c];
+    auto &token_offsets = clang_tokens_offsets[c];
+    //if(token.get_kind()==clangmm::Token::Kind::Token_Punctuation)
+    //ranges.emplace_back(token_offset, static_cast<int>(token.get_cursor().get_kind()));
+    auto token_kind = token.get_kind();
+    if (token_kind == clangmm::Token::Kind::Keyword)
+      apply_tag(token_offsets, 702);
+    else if (token_kind == clangmm::Token::Kind::Identifier) {
+      auto cursor_kind = token.get_cursor().get_kind();
+      if (cursor_kind == clangmm::Cursor::Kind::DeclRefExpr ||
+          cursor_kind == clangmm::Cursor::Kind::MemberRefExpr)
+        cursor_kind = token.get_cursor().get_referenced().get_kind();
+      if (cursor_kind != clangmm::Cursor::Kind::PreprocessingDirective)
+        apply_tag(token_offsets, static_cast<int>(cursor_kind));
+    } else if (token_kind == clangmm::Token::Kind::Literal)
+      apply_tag(token_offsets, static_cast<int>(clangmm::Cursor::Kind::StringLiteral));
+    else if (token_kind == clangmm::Token::Kind::Comment)
+      apply_tag(token_offsets, 705);
+  }
 }
 
 void Source::ClangViewParse::update_diagnostics() {
-    clear_diagnostic_tooltips();
-    fix_its.clear();
-    size_t num_warnings = 0;
-    size_t num_errors = 0;
-    size_t num_fix_its = 0;
-    for (auto &diagnostic: clang_diagnostics) {
-        if (diagnostic.path == file_path.string()) {
-            int line = diagnostic.offsets.first.line - 1;
-            if (line < 0 || line >= get_buffer()->get_line_count())
-                line = get_buffer()->get_line_count() - 1;
-            auto start = get_iter_at_line_end(line);
-            int index = diagnostic.offsets.first.index - 1;
-            if (index >= 0 && index < start.get_line_index())
-                start = get_buffer()->get_iter_at_line_index(line, index);
-            if (start.ends_line()) {
-                while (!start.is_start() && start.ends_line())
-                    start.backward_char();
-            }
-            diagnostic_offsets.emplace(start.get_offset());
-
-            line = diagnostic.offsets.second.line - 1;
-            if (line < 0 || line >= get_buffer()->get_line_count())
-                line = get_buffer()->get_line_count() - 1;
-            auto end = get_iter_at_line_end(line);
-            index = diagnostic.offsets.second.index - 1;
-            if (index >= 0 && index < end.get_line_index())
-                end = get_buffer()->get_iter_at_line_index(line, index);
-
-            bool error = false;
-            std::string severity_tag_name;
-            if (diagnostic.severity <= clangmm::Diagnostic::Severity::Warning) {
-                severity_tag_name = "def:warning";
-                num_warnings++;
-            } else {
-                severity_tag_name = "def:error";
-                num_errors++;
-                error = true;
-            }
-
-            std::string fix_its_string;
-            unsigned fix_its_count = 0;
-            for (auto &fix_it: diagnostic.fix_its) {
-                auto clang_offsets = fix_it.offsets;
-                std::pair<Offset, Offset> offsets;
-                offsets.first.line = clang_offsets.first.line - 1;
-                offsets.first.index = clang_offsets.first.index - 1;
-                offsets.second.line = clang_offsets.second.line - 1;
-                offsets.second.index = clang_offsets.second.index - 1;
-
-                fix_its.emplace_back(fix_it.source, offsets);
-
-                if (fix_its_string.size() > 0)
-                    fix_its_string += '\n';
-                fix_its_string += fix_its.back().string(get_buffer());
-                fix_its_count++;
-                num_fix_its++;
-            }
-
-            if (fix_its_count == 1)
-                fix_its_string.insert(0, "Fix-it:\n");
-            else if (fix_its_count > 1)
-                fix_its_string.insert(0, "Fix-its:\n");
-
-            if (!fix_its_string.empty())
-                diagnostic.spelling += "\n\n" + fix_its_string;
-
-            add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
-        }
+  clear_diagnostic_tooltips();
+  fix_its.clear();
+  size_t num_warnings = 0;
+  size_t num_errors = 0;
+  size_t num_fix_its = 0;
+  for (auto &diagnostic: clang_diagnostics) {
+    if (diagnostic.path == file_path.string()) {
+      int line = diagnostic.offsets.first.line - 1;
+      if (line < 0 || line >= get_buffer()->get_line_count())
+        line = get_buffer()->get_line_count() - 1;
+      auto start = get_iter_at_line_end(line);
+      int index = diagnostic.offsets.first.index - 1;
+      if (index >= 0 && index < start.get_line_index())
+        start = get_buffer()->get_iter_at_line_index(line, index);
+      if (start.ends_line()) {
+        while (!start.is_start() && start.ends_line())
+          start.backward_char();
+      }
+      diagnostic_offsets.emplace(start.get_offset());
+
+      line = diagnostic.offsets.second.line - 1;
+      if (line < 0 || line >= get_buffer()->get_line_count())
+        line = get_buffer()->get_line_count() - 1;
+      auto end = get_iter_at_line_end(line);
+      index = diagnostic.offsets.second.index - 1;
+      if (index >= 0 && index < end.get_line_index())
+        end = get_buffer()->get_iter_at_line_index(line, index);
+
+      bool error = false;
+      std::string severity_tag_name;
+      if (diagnostic.severity <= clangmm::Diagnostic::Severity::Warning) {
+        severity_tag_name = "def:warning";
+        num_warnings++;
+      } else {
+        severity_tag_name = "def:error";
+        num_errors++;
+        error = true;
+      }
+
+      std::string fix_its_string;
+      unsigned fix_its_count = 0;
+      for (auto &fix_it: diagnostic.fix_its) {
+        auto clang_offsets = fix_it.offsets;
+        std::pair<Offset, Offset> offsets;
+        offsets.first.line = clang_offsets.first.line - 1;
+        offsets.first.index = clang_offsets.first.index - 1;
+        offsets.second.line = clang_offsets.second.line - 1;
+        offsets.second.index = clang_offsets.second.index - 1;
+
+        fix_its.emplace_back(fix_it.source, offsets);
+
+        if (fix_its_string.size() > 0)
+          fix_its_string += '\n';
+        fix_its_string += fix_its.back().string(get_buffer());
+        fix_its_count++;
+        num_fix_its++;
+      }
+
+      if (fix_its_count == 1)
+        fix_its_string.insert(0, "Fix-it:\n");
+      else if (fix_its_count > 1)
+        fix_its_string.insert(0, "Fix-its:\n");
+
+      if (!fix_its_string.empty())
+        diagnostic.spelling += "\n\n" + fix_its_string;
+
+      add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
     }
-    status_diagnostics = std::make_tuple(num_warnings, num_errors, num_fix_its);
-    if (update_status_diagnostics)
-        update_status_diagnostics(this);
+  }
+  status_diagnostics = std::make_tuple(num_warnings, num_errors, num_fix_its);
+  if (update_status_diagnostics)
+    update_status_diagnostics(this);
 }
 
 void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) {
-    if (parsed) {
-        Gtk::TextIter iter;
-        int location_x, location_y;
-        window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x,
-                                location_y);
-        location_x += (rectangle.get_width() - 1) / 2;
-        get_iter_at_location(iter, location_x, location_y);
-        Gdk::Rectangle iter_rectangle;
-        get_iter_location(iter, iter_rectangle);
-        if (iter.ends_line() && location_x > iter_rectangle.get_x())
-            return;
+  if (parsed) {
+    Gtk::TextIter iter;
+    int location_x, location_y;
+    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x,
+                            location_y);
+    location_x += (rectangle.get_width() - 1) / 2;
+    get_iter_at_location(iter, location_x, location_y);
+    Gdk::Rectangle iter_rectangle;
+    get_iter_location(iter, iter_rectangle);
+    if (iter.ends_line() && location_x > iter_rectangle.get_x())
+      return;
 
-        auto line = static_cast<unsigned>(iter.get_line());
-        auto index = static_cast<unsigned>(iter.get_line_index());
-        type_tooltips.clear();
-        for (size_t c = clang_tokens->size() - 1; c != static_cast<size_t>(-1); --c) {
-            auto &token = (*clang_tokens)[c];
-            auto &token_offsets = clang_tokens_offsets[c];
-            if (token.is_identifier() || token.get_spelling() == "auto") {
-                if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
-                    index <= token_offsets.second.index - 1) {
-                    auto cursor = token.get_cursor();
-                    auto referenced = cursor.get_referenced();
-                    if (referenced) {
-                        auto start = get_buffer()->get_iter_at_line_index(token_offsets.first.line - 1,
-                                                                          token_offsets.first.index - 1);
-                        auto end = get_buffer()->get_iter_at_line_index(token_offsets.second.line - 1,
-                                                                        token_offsets.second.index - 1);
-                        auto create_tooltip_buffer = [this, &token, &start, &end]() {
-                            auto tooltip_buffer = Gtk::TextBuffer::create(get_buffer()->get_tag_table());
-                            tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(),
-                                                   "Type: " + token.get_cursor().get_type_description());
-                            auto brief_comment = token.get_cursor().get_brief_comments();
-                            if (brief_comment != "")
-                                tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(),
-                                                       "\n\n" + brief_comment);
+    auto line = static_cast<unsigned>(iter.get_line());
+    auto index = static_cast<unsigned>(iter.get_line_index());
+    type_tooltips.clear();
+    for (size_t c = clang_tokens->size() - 1; c != static_cast<size_t>(-1); --c) {
+      auto &token = (*clang_tokens)[c];
+      auto &token_offsets = clang_tokens_offsets[c];
+      if (token.is_identifier() || token.get_spelling() == "auto") {
+        if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
+            index <= token_offsets.second.index - 1) {
+          auto cursor = token.get_cursor();
+          auto referenced = cursor.get_referenced();
+          if (referenced) {
+            auto start = get_buffer()->get_iter_at_line_index(token_offsets.first.line - 1,
+                                                              token_offsets.first.index - 1);
+            auto end = get_buffer()->get_iter_at_line_index(token_offsets.second.line - 1,
+                                                            token_offsets.second.index - 1);
+            auto create_tooltip_buffer = [this, &token, &start, &end]() {
+              auto tooltip_buffer = Gtk::TextBuffer::create(get_buffer()->get_tag_table());
+              tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(),
+                                     "Type: " + token.get_cursor().get_type_description());
+              auto brief_comment = token.get_cursor().get_brief_comments();
+              if (brief_comment != "")
+                tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(),
+                                       "\n\n" + brief_comment);
 
 #ifdef JUCI_ENABLE_DEBUG
-                                                                                                                                                    if(Debug::LLDB::get().is_stopped()) {
-                auto referenced=token.get_cursor().get_referenced();
-                auto location=referenced.get_source_location();
-                Glib::ustring value_type="Value";
-
-                auto iter=start;
-                while((*iter>='a' && *iter<='z') || (*iter>='A' && *iter<='Z') || (*iter>='0' && *iter<='9') || *iter=='_' || *iter=='.') {
-                  start=iter;
-                  if(!iter.backward_char())
-                    break;
-                  if(*iter=='>') {
-                    if(!(iter.backward_char() && *iter=='-' && iter.backward_char()))
-                      break;
-                  }
-                  else if(*iter==':') {
-                    if(!(iter.backward_char() && *iter==':' && iter.backward_char()))
-                      break;
-                  }
-                }
-                auto spelling=get_buffer()->get_text(start, end).raw();
-
-                Glib::ustring debug_value;
-                auto cursor_kind=referenced.get_kind();
-                if(cursor_kind!=clangmm::Cursor::Kind::FunctionDecl && cursor_kind!=clangmm::Cursor::Kind::CXXMethod &&
-                   cursor_kind!=clangmm::Cursor::Kind::Constructor && cursor_kind!=clangmm::Cursor::Kind::Destructor &&
-                   cursor_kind!=clangmm::Cursor::Kind::FunctionTemplate && cursor_kind!=clangmm::Cursor::Kind::ConversionFunction) {
-                  debug_value=Debug::LLDB::get().get_value(spelling, location.get_path(), location.get_offset().line, location.get_offset().index);
-                }
-                if(debug_value.empty()) {
-                  value_type="Return value";
-                  auto offsets=token.get_source_range().get_offsets();
-                  debug_value=Debug::LLDB::get().get_return_value(token.get_source_location().get_path(), offsets.first.line, offsets.first.index);
-                }
-                if(!debug_value.empty()) {
-                  size_t pos=debug_value.find(" = ");
-                  if(pos!=Glib::ustring::npos) {
-                    Glib::ustring::iterator iter;
-                    while(!debug_value.validate(iter)) {
-                      auto next_char_iter=iter;
-                      next_char_iter++;
-                      debug_value.replace(iter, next_char_iter, "?");
-                    }
-                    tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1));
-                  }
-                }
-              }
+              if(Debug::LLDB::get().is_stopped()) {
+auto referenced=token.get_cursor().get_referenced();
+auto location=referenced.get_source_location();
+Glib::ustring value_type="Value";
+
+auto iter=start;
+while((*iter>='a' && *iter<='z') || (*iter>='A' && *iter<='Z') || (*iter>='0' && *iter<='9') || *iter=='_' || *iter=='.') {
+start=iter;
+if(!iter.backward_char())
+break;
+if(*iter=='>') {
+if(!(iter.backward_char() && *iter=='-' && iter.backward_char()))
+break;
+}
+else if(*iter==':') {
+if(!(iter.backward_char() && *iter==':' && iter.backward_char()))
+break;
+}
+}
+auto spelling=get_buffer()->get_text(start, end).raw();
+
+Glib::ustring debug_value;
+auto cursor_kind=referenced.get_kind();
+if(cursor_kind!=clangmm::Cursor::Kind::FunctionDecl && cursor_kind!=clangmm::Cursor::Kind::CXXMethod &&
+cursor_kind!=clangmm::Cursor::Kind::Constructor && cursor_kind!=clangmm::Cursor::Kind::Destructor &&
+cursor_kind!=clangmm::Cursor::Kind::FunctionTemplate && cursor_kind!=clangmm::Cursor::Kind::ConversionFunction) {
+debug_value=Debug::LLDB::get().get_value(spelling, location.get_path(), location.get_offset().line, location.get_offset().index);
+}
+if(debug_value.empty()) {
+value_type="Return value";
+auto offsets=token.get_source_range().get_offsets();
+debug_value=Debug::LLDB::get().get_return_value(token.get_source_location().get_path(), offsets.first.line, offsets.first.index);
+}
+if(!debug_value.empty()) {
+size_t pos=debug_value.find(" = ");
+if(pos!=Glib::ustring::npos) {
+Glib::ustring::iterator iter;
+while(!debug_value.validate(iter)) {
+auto next_char_iter=iter;
+next_char_iter++;
+debug_value.replace(iter, next_char_iter, "?");
+}
+tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1));
+}
+}
+}
 #endif
 
-                            return tooltip_buffer;
-                        };
+              return tooltip_buffer;
+            };
 
-                        type_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start),
-                                                   get_buffer()->create_mark(end));
-                        type_tooltips.show();
-                        return;
-                    }
-                }
-            }
+            type_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start),
+                                       get_buffer()->create_mark(end));
+            type_tooltips.show();
+            return;
+          }
         }
+      }
     }
+  }
 }
 
 
 Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path,
                                                      Glib::RefPtr<Gsv::Language> language) :
-        BaseView(file_path, language), Source::ClangViewParse(file_path, language),
-        autocomplete(this, interactive_completion, last_keyval, true) {
-    non_interactive_completion = [this] {
-        if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
-            return;
-        autocomplete.run();
-    };
-
-    autocomplete.is_processing = [this] {
-        return parse_state == ParseState::PROCESSING;
-    };
+    BaseView(file_path, language), Source::ClangViewParse(file_path, language),
+    autocomplete(this, interactive_completion, last_keyval, true) {
+  non_interactive_completion = [this] {
+    if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
+      return;
+    autocomplete.run();
+  };
+
+  autocomplete.is_processing = [this] {
+    return parse_state == ParseState::PROCESSING;
+  };
+
+  autocomplete.reparse = [this] {
+    selected_completion_string = nullptr;
+    code_complete_results = nullptr;
+    soft_reparse(true);
+  };
+
+  autocomplete.cancel_reparse = [this] {
+    delayed_reparse_connection.disconnect();
+  };
 
-    autocomplete.reparse = [this] {
-        selected_completion_string = nullptr;
-        code_complete_results = nullptr;
-        soft_reparse(true);
-    };
+  autocomplete.get_parse_lock = [this]() {
+    return std::make_unique<std::lock_guard<std::mutex>>(parse_mutex);
+  };
 
-    autocomplete.cancel_reparse = [this] {
-        delayed_reparse_connection.disconnect();
-    };
+  autocomplete.stop_parse = [this]() {
+    parse_process_state = ParseProcessState::IDLE;
+  };
+
+  // Activate argument completions
+  get_buffer()->signal_changed().connect([this] {
+    if (!interactive_completion)
+      return;
+    if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
+      return;
+    if (!has_focus())
+      return;
+    if (show_arguments)
+      autocomplete.stop();
+    show_arguments = false;
+    delayed_show_arguments_connection.disconnect();
+    delayed_show_arguments_connection = Glib::signal_timeout().connect([this]() {
+      if (get_buffer()->get_has_selection())
+        return false;
+      if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
+        return false;
+      if (!has_focus())
+        return false;
+      if (is_possible_parameter()) {
+        autocomplete.stop();
+        autocomplete.run();
+      }
+      return false;
+    }, 500);
+  }, false);
+
+  // Remove argument completions
+  signal_key_press_event().connect([this](GdkEventKey *key) {
+    if (show_arguments && CompletionDialog::get() && CompletionDialog::get()->is_visible() &&
+        key->keyval != GDK_KEY_Down && key->keyval != GDK_KEY_Up &&
+        key->keyval != GDK_KEY_Return && key->keyval != GDK_KEY_KP_Enter &&
+        key->keyval != GDK_KEY_ISO_Left_Tab && key->keyval != GDK_KEY_Tab &&
+        (key->keyval < GDK_KEY_Shift_L || key->keyval > GDK_KEY_Hyper_R)) {
+      get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(),
+                          get_buffer()->get_insert()->get_iter());
+      CompletionDialog::get()->hide();
+    }
+    return false;
+  }, false);
 
-    autocomplete.get_parse_lock = [this]() {
-        return std::make_unique<std::lock_guard<std::mutex>>(parse_mutex);
-    };
+  autocomplete.is_continue_key = [](guint keyval) {
+    if ((keyval >= '0' && keyval <= '9') || (keyval >= 'a' && keyval <= 'z') || (keyval >= 'A' && keyval <= 'Z') ||
+        keyval == '_')
+      return true;
 
-    autocomplete.stop_parse = [this]() {
-        parse_process_state = ParseProcessState::IDLE;
-    };
+    return false;
+  };
 
-    // Activate argument completions
-    get_buffer()->signal_changed().connect([this] {
-        if (!interactive_completion)
-            return;
-        if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
-            return;
-        if (!has_focus())
-            return;
-        if (show_arguments)
-            autocomplete.stop();
-        show_arguments = false;
-        delayed_show_arguments_connection.disconnect();
-        delayed_show_arguments_connection = Glib::signal_timeout().connect([this]() {
-            if (get_buffer()->get_has_selection())
-                return false;
-            if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
-                return false;
-            if (!has_focus())
-                return false;
-            if (is_possible_parameter()) {
-                autocomplete.stop();
-                autocomplete.run();
-            }
-            return false;
-        }, 500);
-    }, false);
-
-    // Remove argument completions
-    signal_key_press_event().connect([this](GdkEventKey *key) {
-        if (show_arguments && CompletionDialog::get() && CompletionDialog::get()->is_visible() &&
-            key->keyval != GDK_KEY_Down && key->keyval != GDK_KEY_Up &&
-            key->keyval != GDK_KEY_Return && key->keyval != GDK_KEY_KP_Enter &&
-            key->keyval != GDK_KEY_ISO_Left_Tab && key->keyval != GDK_KEY_Tab &&
-            (key->keyval < GDK_KEY_Shift_L || key->keyval > GDK_KEY_Hyper_R)) {
-            get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(),
-                                get_buffer()->get_insert()->get_iter());
-            CompletionDialog::get()->hide();
-        }
-        return false;
-    }, false);
+  autocomplete.is_restart_key = [this](guint keyval) {
+    auto iter = get_buffer()->get_insert()->get_iter();
+    iter.backward_chars(2);
+    if (keyval == '.' || (keyval == ':' && *iter == ':') || (keyval == '>' && *iter == '-'))
+      return true;
+    return false;
+  };
 
-    autocomplete.is_continue_key = [](guint keyval) {
-        if ((keyval >= '0' && keyval <= '9') || (keyval >= 'a' && keyval <= 'z') || (keyval >= 'A' && keyval <= 'Z') ||
-            keyval == '_')
-            return true;
+  autocomplete.run_check = [this]() {
+    auto iter = get_buffer()->get_insert()->get_iter();
+    iter.backward_char();
+    if (!is_code_iter(iter))
+      return false;
+
+    show_arguments = false;
+
+    std::string line = " " + get_line_before();
+    const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>](\\.|->)([a-zA-Z0-9_]*)$");
+    const static std::regex colon_colon("^.*::([a-zA-Z0-9_]*)$");
+    const static std::regex part_of_symbol("^.*[^a-zA-Z0-9_]+([a-zA-Z0-9_]{3,})$");
+    std::smatch sm;
+    if (std::regex_match(line, sm, dot_or_arrow)) {
+      {
+        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+        autocomplete.prefix = sm[2].str();
+      }
+      if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+        return true;
+    } else if (std::regex_match(line, sm, colon_colon)) {
+      {
+        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+        autocomplete.prefix = sm[1].str();
+      }
+      if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+        return true;
+    } else if (std::regex_match(line, sm, part_of_symbol)) {
+      {
+        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+        autocomplete.prefix = sm[1].str();
+      }
+      if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+        return true;
+    } else if (is_possible_parameter()) {
+      show_arguments = true;
+      std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+      autocomplete.prefix = "";
+      return true;
+    } else if (!interactive_completion) {
+      auto end_iter = get_buffer()->get_insert()->get_iter();
+      auto iter = end_iter;
+      while (iter.backward_char() && autocomplete.is_continue_key(*iter)) {}
+      if (iter != end_iter)
+        iter.forward_char();
+      std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+      autocomplete.prefix = get_buffer()->get_text(iter, end_iter);
+      return true;
+    }
 
-        return false;
-    };
+    return false;
+  };
 
-    autocomplete.is_restart_key = [this](guint keyval) {
-        auto iter = get_buffer()->get_insert()->get_iter();
-        iter.backward_chars(2);
-        if (keyval == '.' || (keyval == ':' && *iter == ':') || (keyval == '>' && *iter == '-'))
-            return true;
-        return false;
-    };
+  autocomplete.before_add_rows = [this] {
+    status_state = "autocomplete...";
+    if (update_status_state)
+      update_status_state(this);
+  };
 
-    autocomplete.run_check = [this]() {
-        auto iter = get_buffer()->get_insert()->get_iter();
-        iter.backward_char();
-        if (!is_code_iter(iter))
-            return false;
+  autocomplete.after_add_rows = [this] {
+    status_state = "";
+    if (update_status_state)
+      update_status_state(this);
+  };
+
+  autocomplete.on_add_rows_error = [this] {
+    Terminal::get().print("Error: autocomplete failed, reparsing " + this->file_path.string() + "\n", true);
+    selected_completion_string = nullptr;
+    code_complete_results = nullptr;
+    full_reparse();
+  };
+
+  autocomplete.add_rows = [this](std::string &buffer, int line_number, int column) {
+    if (this->language && (this->language->get_id() == "chdr" || this->language->get_id() == "cpphdr"))
+      clangmm::remove_include_guard(buffer);
+    code_complete_results = std::make_unique<clangmm::CodeCompleteResults>(
+        clang_tu->get_code_completions(buffer, line_number, column));
+    if (code_complete_results->cx_results == nullptr) {
+      auto expected = ParseState::PROCESSING;
+      parse_state.compare_exchange_strong(expected, ParseState::RESTARTING);
+      return;
+    }
 
-        show_arguments = false;
-
-        std::string line = " " + get_line_before();
-        const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>](\\.|->)([a-zA-Z0-9_]*)$");
-        const static std::regex colon_colon("^.*::([a-zA-Z0-9_]*)$");
-        const static std::regex part_of_symbol("^.*[^a-zA-Z0-9_]+([a-zA-Z0-9_]{3,})$");
-        std::smatch sm;
-        if (std::regex_match(line, sm, dot_or_arrow)) {
-            {
-                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-                autocomplete.prefix = sm[2].str();
+    if (autocomplete.state == Autocomplete::State::STARTING) {
+      std::string prefix_copy;
+      {
+        std::lock_guard<std::mutex> lock(autocomplete.prefix_mutex);
+        prefix_copy = autocomplete.prefix;
+      }
+
+      completion_strings.clear();
+      for (unsigned i = 0; i < code_complete_results->size(); ++i) {
+        auto result = code_complete_results->get(i);
+        if (result.available()) {
+          std::string text;
+          if (show_arguments) {
+            class Recursive {
+            public:
+              static void f(const clangmm::CompletionString &completion_string, std::string &text) {
+                for (unsigned i = 0; i < completion_string.get_num_chunks(); ++i) {
+                  auto kind = static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(
+                      completion_string.cx_completion_string, i));
+                  if (kind == clangmm::CompletionChunk_Optional)
+                    f(clangmm::CompletionString(clang_getCompletionChunkCompletionString(
+                        completion_string.cx_completion_string, i)), text);
+                  else if (kind == clangmm::CompletionChunk_CurrentParameter) {
+                    auto chunk_cstr = clangmm::String(
+                        clang_getCompletionChunkText(completion_string.cx_completion_string,
+                                                     i));
+                    text += chunk_cstr.c_str;
+                  }
+                }
+              }
+            };
+            Recursive::f(result, text);
+            if (!text.empty()) {
+              bool already_added = false;
+              for (auto &row: autocomplete.rows) {
+                if (row == text) {
+                  already_added = true;
+                  break;
+                }
+              }
+              if (!already_added) {
+                autocomplete.rows.emplace_back(std::move(text));
+                completion_strings.emplace_back(result.cx_completion_string);
+              }
             }
-            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
-                return true;
-        } else if (std::regex_match(line, sm, colon_colon)) {
-            {
-                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-                autocomplete.prefix = sm[1].str();
+          } else {
+            std::string return_text;
+            bool match = false;
+            for (unsigned i = 0; i < result.get_num_chunks(); ++i) {
+              auto kind = static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(
+                  result.cx_completion_string, i));
+              if (kind != clangmm::CompletionChunk_Informative) {
+                auto chunk_cstr = clangmm::String(
+                    clang_getCompletionChunkText(result.cx_completion_string, i));
+                if (kind == clangmm::CompletionChunk_TypedText) {
+                  if (strlen(chunk_cstr.c_str) >= prefix_copy.size() &&
+                      prefix_copy.compare(0, prefix_copy.size(), chunk_cstr.c_str,
+                                          prefix_copy.size()) == 0)
+                    match = true;
+                  else
+                    break;
+                }
+                if (kind == clangmm::CompletionChunk_ResultType)
+                  return_text = std::string("  →  ") + chunk_cstr.c_str;
+                else
+                  text += chunk_cstr.c_str;
+              }
             }
-            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
-                return true;
-        } else if (std::regex_match(line, sm, part_of_symbol)) {
-            {
-                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-                autocomplete.prefix = sm[1].str();
+            if (match && !text.empty()) {
+              if (!return_text.empty())
+                text += return_text;
+              autocomplete.rows.emplace_back(std::move(text));
+              completion_strings.emplace_back(result.cx_completion_string);
             }
-            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
-                return true;
-        } else if (is_possible_parameter()) {
-            show_arguments = true;
-            std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-            autocomplete.prefix = "";
-            return true;
-        } else if (!interactive_completion) {
-            auto end_iter = get_buffer()->get_insert()->get_iter();
-            auto iter = end_iter;
-            while (iter.backward_char() && autocomplete.is_continue_key(*iter)) {}
-            if (iter != end_iter)
-                iter.forward_char();
-            std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-            autocomplete.prefix = get_buffer()->get_text(iter, end_iter);
-            return true;
+          }
         }
+      }
+    }
+  };
 
-        return false;
-    };
-
-    autocomplete.before_add_rows = [this] {
-        status_state = "autocomplete...";
-        if (update_status_state)
-            update_status_state(this);
-    };
-
-    autocomplete.after_add_rows = [this] {
-        status_state = "";
-        if (update_status_state)
-            update_status_state(this);
-    };
-
-    autocomplete.on_add_rows_error = [this] {
-        Terminal::get().print("Error: autocomplete failed, reparsing " + this->file_path.string() + "\n", true);
-        selected_completion_string = nullptr;
-        code_complete_results = nullptr;
-        full_reparse();
-    };
-
-    autocomplete.add_rows = [this](std::string &buffer, int line_number, int column) {
-        if (this->language && (this->language->get_id() == "chdr" || this->language->get_id() == "cpphdr"))
-            clangmm::remove_include_guard(buffer);
-        code_complete_results = std::make_unique<clangmm::CodeCompleteResults>(
-                clang_tu->get_code_completions(buffer, line_number, column));
-        if (code_complete_results->cx_results == nullptr) {
-            auto expected = ParseState::PROCESSING;
-            parse_state.compare_exchange_strong(expected, ParseState::RESTARTING);
-            return;
+  autocomplete.on_show = [this] {
+    hide_tooltips();
+  };
+
+  autocomplete.on_hide = [this] {
+    selected_completion_string = nullptr;
+    code_complete_results = nullptr;
+  };
+
+  autocomplete.on_changed = [this](unsigned int index, const std::string &text) {
+    selected_completion_string = completion_strings[index];
+  };
+
+  autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
+    std::string row;
+    auto pos = text.find("  →  ");
+    if (pos != std::string::npos)
+      row = text.substr(0, pos);
+    else
+      row = text;
+    //erase existing variable or function before insert iter
+    get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
+    //do not insert template argument or function parameters if they already exist
+    auto iter = get_buffer()->get_insert()->get_iter();
+    if (*iter == '<' || *iter == '(') {
+      auto bracket_pos = row.find(*iter);
+      if (bracket_pos != std::string::npos) {
+        row = row.substr(0, bracket_pos);
+      }
+    }
+    //Fixes for the most commonly used stream manipulators
+    auto manipulators_map = autocomplete_manipulators_map();
+    auto it = manipulators_map.find(row);
+    if (it != manipulators_map.end())
+      row = it->second;
+    //Do not insert template argument, function parameters or ':' unless hide_window is true
+    if (!hide_window) {
+      for (size_t c = 0; c < row.size(); ++c) {
+        if (row[c] == '<' || row[c] == '(' || row[c] == ':') {
+          row.erase(c);
+          break;
         }
-
-        if (autocomplete.state == Autocomplete::State::STARTING) {
-            std::string prefix_copy;
-            {
-                std::lock_guard<std::mutex> lock(autocomplete.prefix_mutex);
-                prefix_copy = autocomplete.prefix;
-            }
-
-            completion_strings.clear();
-            for (unsigned i = 0; i < code_complete_results->size(); ++i) {
-                auto result = code_complete_results->get(i);
-                if (result.available()) {
-                    std::string text;
-                    if (show_arguments) {
-                        class Recursive {
-                        public:
-                            static void f(const clangmm::CompletionString &completion_string, std::string &text) {
-                                for (unsigned i = 0; i < completion_string.get_num_chunks(); ++i) {
-                                    auto kind = static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(
-                                            completion_string.cx_completion_string, i));
-                                    if (kind == clangmm::CompletionChunk_Optional)
-                                        f(clangmm::CompletionString(clang_getCompletionChunkCompletionString(
-                                                completion_string.cx_completion_string, i)), text);
-                                    else if (kind == clangmm::CompletionChunk_CurrentParameter) {
-                                        auto chunk_cstr = clangmm::String(
-                                                clang_getCompletionChunkText(completion_string.cx_completion_string,
-                                                                             i));
-                                        text += chunk_cstr.c_str;
-                                    }
-                                }
-                            }
-                        };
-                        Recursive::f(result, text);
-                        if (!text.empty()) {
-                            bool already_added = false;
-                            for (auto &row: autocomplete.rows) {
-                                if (row == text) {
-                                    already_added = true;
-                                    break;
-                                }
-                            }
-                            if (!already_added) {
-                                autocomplete.rows.emplace_back(std::move(text));
-                                completion_strings.emplace_back(result.cx_completion_string);
-                            }
-                        }
-                    } else {
-                        std::string return_text;
-                        bool match = false;
-                        for (unsigned i = 0; i < result.get_num_chunks(); ++i) {
-                            auto kind = static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(
-                                    result.cx_completion_string, i));
-                            if (kind != clangmm::CompletionChunk_Informative) {
-                                auto chunk_cstr = clangmm::String(
-                                        clang_getCompletionChunkText(result.cx_completion_string, i));
-                                if (kind == clangmm::CompletionChunk_TypedText) {
-                                    if (strlen(chunk_cstr.c_str) >= prefix_copy.size() &&
-                                        prefix_copy.compare(0, prefix_copy.size(), chunk_cstr.c_str,
-                                                            prefix_copy.size()) == 0)
-                                        match = true;
-                                    else
-                                        break;
-                                }
-                                if (kind == clangmm::CompletionChunk_ResultType)
-                                    return_text = std::string("  →  ") + chunk_cstr.c_str;
-                                else
-                                    text += chunk_cstr.c_str;
-                            }
-                        }
-                        if (match && !text.empty()) {
-                            if (!return_text.empty())
-                                text += return_text;
-                            autocomplete.rows.emplace_back(std::move(text));
-                            completion_strings.emplace_back(result.cx_completion_string);
-                        }
-                    }
-                }
-            }
+      }
+    }
+    get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), row);
+    //if selection is finalized, select text inside template arguments or function parameters
+    if (hide_window) {
+      size_t start_pos = std::string::npos;
+      size_t end_pos = std::string::npos;
+      if (show_arguments) {
+        start_pos = 0;
+        end_pos = row.size();
+      } else {
+        auto para_pos = row.find('(');
+        auto angle_pos = row.find('<');
+        if (angle_pos < para_pos) {
+          start_pos = angle_pos + 1;
+          end_pos = row.find('>');
+        } else if (para_pos != std::string::npos) {
+          start_pos = para_pos + 1;
+          end_pos = row.size() - 1;
         }
-    };
-
-    autocomplete.on_show = [this] {
-        hide_tooltips();
-    };
-
-    autocomplete.on_hide = [this] {
-        selected_completion_string = nullptr;
-        code_complete_results = nullptr;
-    };
-
-    autocomplete.on_changed = [this](unsigned int index, const std::string &text) {
-        selected_completion_string = completion_strings[index];
-    };
-
-    autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
-        std::string row;
-        auto pos = text.find("  →  ");
-        if (pos != std::string::npos)
-            row = text.substr(0, pos);
-        else
-            row = text;
-        //erase existing variable or function before insert iter
-        get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
-        //do not insert template argument or function parameters if they already exist
-        auto iter = get_buffer()->get_insert()->get_iter();
-        if (*iter == '<' || *iter == '(') {
-            auto bracket_pos = row.find(*iter);
-            if (bracket_pos != std::string::npos) {
-                row = row.substr(0, bracket_pos);
-            }
+        if (start_pos == std::string::npos || end_pos == std::string::npos) {
+          if ((start_pos = row.find('\"')) != std::string::npos) {
+            end_pos = row.find('\"', start_pos + 1);
+            ++start_pos;
+          }
         }
-        //Fixes for the most commonly used stream manipulators
-        auto manipulators_map = autocomplete_manipulators_map();
-        auto it = manipulators_map.find(row);
-        if (it != manipulators_map.end())
-            row = it->second;
-        //Do not insert template argument, function parameters or ':' unless hide_window is true
-        if (!hide_window) {
-            for (size_t c = 0; c < row.size(); ++c) {
-                if (row[c] == '<' || row[c] == '(' || row[c] == ':') {
-                    row.erase(c);
-                    break;
-                }
+      }
+      if (start_pos == std::string::npos || end_pos == std::string::npos) {
+        if ((start_pos = row.find(' ')) != std::string::npos) {
+          std::vector<std::string> parameters = {"expression", "arguments", "identifier", "type name",
+                                                 "qualifier::name", "macro", "condition"};
+          for (auto &parameter: parameters) {
+            if ((start_pos = row.find(parameter, start_pos + 1)) != std::string::npos) {
+              end_pos = start_pos + parameter.size();
+              break;
             }
+          }
         }
-        get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), row);
-        //if selection is finalized, select text inside template arguments or function parameters
-        if (hide_window) {
-            size_t start_pos = std::string::npos;
-            size_t end_pos = std::string::npos;
-            if (show_arguments) {
-                start_pos = 0;
-                end_pos = row.size();
-            } else {
-                auto para_pos = row.find('(');
-                auto angle_pos = row.find('<');
-                if (angle_pos < para_pos) {
-                    start_pos = angle_pos + 1;
-                    end_pos = row.find('>');
-                } else if (para_pos != std::string::npos) {
-                    start_pos = para_pos + 1;
-                    end_pos = row.size() - 1;
-                }
-                if (start_pos == std::string::npos || end_pos == std::string::npos) {
-                    if ((start_pos = row.find('\"')) != std::string::npos) {
-                        end_pos = row.find('\"', start_pos + 1);
-                        ++start_pos;
-                    }
-                }
-            }
-            if (start_pos == std::string::npos || end_pos == std::string::npos) {
-                if ((start_pos = row.find(' ')) != std::string::npos) {
-                    std::vector<std::string> parameters = {"expression", "arguments", "identifier", "type name",
-                                                           "qualifier::name", "macro", "condition"};
-                    for (auto &parameter: parameters) {
-                        if ((start_pos = row.find(parameter, start_pos + 1)) != std::string::npos) {
-                            end_pos = start_pos + parameter.size();
-                            break;
-                        }
-                    }
-                }
-            }
-
-            if (start_pos != std::string::npos && end_pos != std::string::npos) {
-                int start_offset = CompletionDialog::get()->start_mark->get_iter().get_offset() + start_pos;
-                int end_offset = CompletionDialog::get()->start_mark->get_iter().get_offset() + end_pos;
-                auto size = get_buffer()->size();
-                if (start_offset != end_offset && start_offset < size && end_offset < size)
-                    get_buffer()->select_range(get_buffer()->get_iter_at_offset(start_offset),
-                                               get_buffer()->get_iter_at_offset(end_offset));
-            } else {
-                //new autocomplete after for instance when selecting "std::"
-                auto iter = get_buffer()->get_insert()->get_iter();
-                if (iter.backward_char() && *iter == ':') {
-                    autocomplete.run();
-                    return;
-                }
-            }
+      }
+
+      if (start_pos != std::string::npos && end_pos != std::string::npos) {
+        int start_offset = CompletionDialog::get()->start_mark->get_iter().get_offset() + start_pos;
+        int end_offset = CompletionDialog::get()->start_mark->get_iter().get_offset() + end_pos;
+        auto size = get_buffer()->size();
+        if (start_offset != end_offset && start_offset < size && end_offset < size)
+          get_buffer()->select_range(get_buffer()->get_iter_at_offset(start_offset),
+                                     get_buffer()->get_iter_at_offset(end_offset));
+      } else {
+        //new autocomplete after for instance when selecting "std::"
+        auto iter = get_buffer()->get_insert()->get_iter();
+        if (iter.backward_char() && *iter == ':') {
+          autocomplete.run();
+          return;
         }
-    };
+      }
+    }
+  };
 
-    autocomplete.get_tooltip = [this](unsigned int index) {
-        return clangmm::to_string(clang_getCompletionBriefComment(completion_strings[index]));
-    };
+  autocomplete.get_tooltip = [this](unsigned int index) {
+    return clangmm::to_string(clang_getCompletionBriefComment(completion_strings[index]));
+  };
 }
 
 bool Source::ClangViewAutocomplete::is_possible_parameter() {
-    auto iter = get_buffer()->get_insert()->get_iter();
-    if (iter.backward_char() &&
-        (!interactive_completion || last_keyval == '(' || last_keyval == ',' || last_keyval == ' ' ||
-         last_keyval == GDK_KEY_Return || last_keyval == GDK_KEY_KP_Enter)) {
-        while ((*iter == ' ' || *iter == '\t' || *iter == '\n' || *iter == '\r') && iter.backward_char()) {}
-        if (*iter == '(' || *iter == ',')
-            return true;
-    }
-    return false;
+  auto iter = get_buffer()->get_insert()->get_iter();
+  if (iter.backward_char() &&
+      (!interactive_completion || last_keyval == '(' || last_keyval == ',' || last_keyval == ' ' ||
+       last_keyval == GDK_KEY_Return || last_keyval == GDK_KEY_KP_Enter)) {
+    while ((*iter == ' ' || *iter == '\t' || *iter == '\n' || *iter == '\r') && iter.backward_char()) {}
+    if (*iter == '(' || *iter == ',')
+      return true;
+  }
+  return false;
 }
 
 const std::unordered_map<std::string, std::string> &Source::ClangViewAutocomplete::autocomplete_manipulators_map() {
-    //TODO: feel free to add more
-    static std::unordered_map<std::string, std::string> map = {
-            {"endl(basic_ostream<_CharT, _Traits> &__os)",  "endl"},
-            {"flush(basic_ostream<_CharT, _Traits> &__os)", "flush"},
-            {"hex(std::ios_base &__str)",                   "hex"}, //clang++ headers
-            {"hex(std::ios_base &__base)",                  "hex"}, //g++ headers
-            {"dec(std::ios_base &__str)",                   "dec"},
-            {"dec(std::ios_base &__base)",                  "dec"}
-    };
-    return map;
+  //TODO: feel free to add more
+  static std::unordered_map<std::string, std::string> map = {
+      {"endl(basic_ostream<_CharT, _Traits> &__os)",  "endl"},
+      {"flush(basic_ostream<_CharT, _Traits> &__os)", "flush"},
+      {"hex(std::ios_base &__str)",                   "hex"}, //clang++ headers
+      {"hex(std::ios_base &__base)",                  "hex"}, //g++ headers
+      {"dec(std::ios_base &__str)",                   "dec"},
+      {"dec(std::ios_base &__base)",                  "dec"}
+  };
+  return map;
 }
 
 
 Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path,
                                              Glib::RefPtr<Gsv::Language> language) :
-        BaseView(file_path, language), Source::ClangViewParse(file_path, language) {
-    similar_identifiers_tag = get_buffer()->create_tag();
-    similar_identifiers_tag->property_weight() = Pango::WEIGHT_ULTRAHEAVY;
-
-    get_buffer()->signal_changed().connect([this]() {
-        if (last_tagged_identifier) {
-            for (auto &mark: similar_identifiers_marks) {
-                get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
-                get_buffer()->delete_mark(mark.first);
-                get_buffer()->delete_mark(mark.second);
-            }
-            similar_identifiers_marks.clear();
-            last_tagged_identifier = Identifier();
-        }
-    });
+    BaseView(file_path, language), Source::ClangViewParse(file_path, language) {
+  similar_identifiers_tag = get_buffer()->create_tag();
+  similar_identifiers_tag->property_weight() = Pango::WEIGHT_ULTRAHEAVY;
+
+  get_buffer()->signal_changed().connect([this]() {
+    if (last_tagged_identifier) {
+      for (auto &mark: similar_identifiers_marks) {
+        get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
+        get_buffer()->delete_mark(mark.first);
+        get_buffer()->delete_mark(mark.second);
+      }
+      similar_identifiers_marks.clear();
+      last_tagged_identifier = Identifier();
+    }
+  });
 
-    get_token_spelling = [this]() {
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return std::string();
-        }
-        auto identifier = get_identifier();
-        if (identifier.spelling.empty() ||
-            identifier.spelling == "::" || identifier.spelling == "," || identifier.spelling == "=" ||
-            identifier.spelling == "(" || identifier.spelling == ")" ||
-            identifier.spelling == "[" || identifier.spelling == "]") {
-            Info::get().print("No valid symbol found at current cursor location");
-            return std::string();
-        }
-        return identifier.spelling;
-    };
+  get_token_spelling = [this]() {
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return std::string();
+    }
+    auto identifier = get_identifier();
+    if (identifier.spelling.empty() ||
+        identifier.spelling == "::" || identifier.spelling == "," || identifier.spelling == "=" ||
+        identifier.spelling == "(" || identifier.spelling == ")" ||
+        identifier.spelling == "[" || identifier.spelling == "]") {
+      Info::get().print("No valid symbol found at current cursor location");
+      return std::string();
+    }
+    return identifier.spelling;
+  };
 
-    rename_similar_tokens = [this](const std::string &text) {
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return;
+  rename_similar_tokens = [this](const std::string &text) {
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return;
+    }
+    auto identifier = get_identifier();
+    if (identifier) {
+      wait_parsing();
+
+      std::vector<clangmm::TranslationUnit *> translation_units;
+      translation_units.emplace_back(clang_tu.get());
+      for (auto &view: views) {
+        if (view != this) {
+          if (auto clang_view = dynamic_cast<Source::ClangView *>(view))
+            translation_units.emplace_back(clang_view->clang_tu.get());
         }
-        auto identifier = get_identifier();
-        if (identifier) {
-            wait_parsing();
-
-            std::vector<clangmm::TranslationUnit *> translation_units;
-            translation_units.emplace_back(clang_tu.get());
-            for (auto &view: views) {
-                if (view != this) {
-                    if (auto clang_view = dynamic_cast<Source::ClangView *>(view))
-                        translation_units.emplace_back(clang_view->clang_tu.get());
-                }
+      }
+
+      auto build = Project::Build::create(this->file_path);
+      auto usages = Usages::Clang::get_usages(build->project_path, build->get_default_path(),
+                                              build->get_debug_path(), identifier.spelling, identifier.cursor,
+                                              translation_units);
+
+      std::vector<Source::View *> renamed_views;
+      std::vector<Usages::Clang::Usages *> usages_renamed;
+      for (auto &usage: usages) {
+        size_t line_c = usage.lines.size() - 1;
+        auto view_it = views.end();
+        for (auto it = views.begin(); it != views.end(); ++it) {
+          if ((*it)->file_path == usage.path) {
+            view_it = it;
+            break;
+          }
+        }
+        if (view_it != views.end()) {
+          (*view_it)->get_buffer()->begin_user_action();
+          for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
+            auto start_iter = (*view_it)->get_buffer()->get_iter_at_line_index(offset_it->first.line - 1,
+                                                                               offset_it->first.index - 1);
+            auto end_iter = (*view_it)->get_buffer()->get_iter_at_line_index(offset_it->second.line - 1,
+                                                                             offset_it->second.index - 1);
+            (*view_it)->get_buffer()->erase(start_iter, end_iter);
+            start_iter = (*view_it)->get_buffer()->get_iter_at_line_index(offset_it->first.line - 1,
+                                                                          offset_it->first.index - 1);
+            (*view_it)->get_buffer()->insert(start_iter, text);
+            if (offset_it->first.index - 1 < usage.lines[line_c].size())
+              usage.lines[line_c].replace(offset_it->first.index - 1,
+                                          offset_it->second.index - offset_it->first.index, text);
+            --line_c;
+          }
+          (*view_it)->get_buffer()->end_user_action();
+          (*view_it)->save();
+          renamed_views.emplace_back(*view_it);
+          usages_renamed.emplace_back(&usage);
+        } else {
+          std::string buffer;
+          {
+            std::ifstream stream(usage.path.string(), std::ifstream::binary);
+            if (stream)
+              buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
+          }
+          std::ofstream stream(usage.path.string(), std::ifstream::binary);
+          if (!buffer.empty() && stream) {
+            std::vector<size_t> lines_start_pos = {0};
+            for (size_t c = 0; c < buffer.size(); ++c) {
+              if (buffer[c] == '\n')
+                lines_start_pos.emplace_back(c + 1);
             }
-
-            auto build = Project::Build::create(this->file_path);
-            auto usages = Usages::Clang::get_usages(build->project_path, build->get_default_path(),
-                                                    build->get_debug_path(), identifier.spelling, identifier.cursor,
-                                                    translation_units);
-
-            std::vector<Source::View *> renamed_views;
-            std::vector<Usages::Clang::Usages *> usages_renamed;
-            for (auto &usage: usages) {
-                size_t line_c = usage.lines.size() - 1;
-                auto view_it = views.end();
-                for (auto it = views.begin(); it != views.end(); ++it) {
-                    if ((*it)->file_path == usage.path) {
-                        view_it = it;
-                        break;
-                    }
-                }
-                if (view_it != views.end()) {
-                    (*view_it)->get_buffer()->begin_user_action();
-                    for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
-                        auto start_iter = (*view_it)->get_buffer()->get_iter_at_line_index(offset_it->first.line - 1,
-                                                                                           offset_it->first.index - 1);
-                        auto end_iter = (*view_it)->get_buffer()->get_iter_at_line_index(offset_it->second.line - 1,
-                                                                                         offset_it->second.index - 1);
-                        (*view_it)->get_buffer()->erase(start_iter, end_iter);
-                        start_iter = (*view_it)->get_buffer()->get_iter_at_line_index(offset_it->first.line - 1,
-                                                                                      offset_it->first.index - 1);
-                        (*view_it)->get_buffer()->insert(start_iter, text);
-                        if (offset_it->first.index - 1 < usage.lines[line_c].size())
-                            usage.lines[line_c].replace(offset_it->first.index - 1,
-                                                        offset_it->second.index - offset_it->first.index, text);
-                        --line_c;
-                    }
-                    (*view_it)->get_buffer()->end_user_action();
-                    (*view_it)->save();
-                    renamed_views.emplace_back(*view_it);
-                    usages_renamed.emplace_back(&usage);
-                } else {
-                    std::string buffer;
-                    {
-                        std::ifstream stream(usage.path.string(), std::ifstream::binary);
-                        if (stream)
-                            buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
-                    }
-                    std::ofstream stream(usage.path.string(), std::ifstream::binary);
-                    if (!buffer.empty() && stream) {
-                        std::vector<size_t> lines_start_pos = {0};
-                        for (size_t c = 0; c < buffer.size(); ++c) {
-                            if (buffer[c] == '\n')
-                                lines_start_pos.emplace_back(c + 1);
-                        }
-                        for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
-                            auto start_line = offset_it->first.line - 1;
-                            auto end_line = offset_it->second.line - 1;
-                            if (start_line < lines_start_pos.size() && end_line < lines_start_pos.size()) {
-                                auto start = lines_start_pos[start_line] + offset_it->first.index - 1;
-                                auto end = lines_start_pos[end_line] + offset_it->second.index - 1;
-                                if (start < buffer.size() && end <= buffer.size())
-                                    buffer.replace(start, end - start, text);
-                            }
-                            if (offset_it->first.index - 1 < usage.lines[line_c].size())
-                                usage.lines[line_c].replace(offset_it->first.index - 1,
-                                                            offset_it->second.index - offset_it->first.index, text);
-                            --line_c;
-                        }
-                        stream.write(buffer.data(), buffer.size());
-                        usages_renamed.emplace_back(&usage);
-                    } else
-                        Terminal::get().print("Error: could not write to file " + usage.path.string() + '\n', true);
-                }
+            for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
+              auto start_line = offset_it->first.line - 1;
+              auto end_line = offset_it->second.line - 1;
+              if (start_line < lines_start_pos.size() && end_line < lines_start_pos.size()) {
+                auto start = lines_start_pos[start_line] + offset_it->first.index - 1;
+                auto end = lines_start_pos[end_line] + offset_it->second.index - 1;
+                if (start < buffer.size() && end <= buffer.size())
+                  buffer.replace(start, end - start, text);
+              }
+              if (offset_it->first.index - 1 < usage.lines[line_c].size())
+                usage.lines[line_c].replace(offset_it->first.index - 1,
+                                            offset_it->second.index - offset_it->first.index, text);
+              --line_c;
             }
+            stream.write(buffer.data(), buffer.size());
+            usages_renamed.emplace_back(&usage);
+          } else
+            Terminal::get().print("Error: could not write to file " + usage.path.string() + '\n', true);
+        }
+      }
+
+      if (!usages_renamed.empty()) {
+        Terminal::get().print("Renamed ");
+        Terminal::get().print(identifier.spelling, true);
+        Terminal::get().print(" to ");
+        Terminal::get().print(text, true);
+        Terminal::get().print(" at:\n");
+      }
+      for (auto &usage: usages_renamed) {
+        size_t line_c = 0;
+        for (auto &offset: usage->offsets) {
+          Terminal::get().print(
+              filesystem::get_short_path(usage->path).string() + ':' + std::to_string(offset.first.line) +
+              ':' + std::to_string(offset.first.index) + ": ");
+          auto &line = usage->lines[line_c];
+          auto index = offset.first.index - 1;
+          unsigned start = 0;
+          for (auto &chr: line) {
+            if (chr != ' ' && chr != '\t')
+              break;
+            ++start;
+          }
+          if (start < line.size() && index + text.size() < line.size()) {
+            Terminal::get().print(line.substr(start, index - start));
+            Terminal::get().print(line.substr(index, text.size()), true);
+            Terminal::get().print(line.substr(index + text.size()));
+          }
+          Terminal::get().print("\n");
+          ++line_c;
+        }
+      }
 
-            if (!usages_renamed.empty()) {
-                Terminal::get().print("Renamed ");
-                Terminal::get().print(identifier.spelling, true);
-                Terminal::get().print(" to ");
-                Terminal::get().print(text, true);
-                Terminal::get().print(" at:\n");
-            }
-            for (auto &usage: usages_renamed) {
-                size_t line_c = 0;
-                for (auto &offset: usage->offsets) {
-                    Terminal::get().print(
-                            filesystem::get_short_path(usage->path).string() + ':' + std::to_string(offset.first.line) +
-                            ':' + std::to_string(offset.first.index) + ": ");
-                    auto &line = usage->lines[line_c];
-                    auto index = offset.first.index - 1;
-                    unsigned start = 0;
-                    for (auto &chr: line) {
-                        if (chr != ' ' && chr != '\t')
-                            break;
-                        ++start;
-                    }
-                    if (start < line.size() && index + text.size() < line.size()) {
-                        Terminal::get().print(line.substr(start, index - start));
-                        Terminal::get().print(line.substr(index, text.size()), true);
-                        Terminal::get().print(line.substr(index + text.size()));
-                    }
-                    Terminal::get().print("\n");
-                    ++line_c;
-                }
-            }
+      for (auto &view: renamed_views)
+        view->soft_reparse_needed = false;
+    }
+  };
 
-            for (auto &view: renamed_views)
-                view->soft_reparse_needed = false;
+  get_buffer()->signal_mark_set().connect(
+      [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+        if (mark->get_name() == "insert") {
+          delayed_tag_similar_identifiers_connection.disconnect();
+          delayed_tag_similar_identifiers_connection = Glib::signal_timeout().connect([this]() {
+            auto identifier = get_identifier();
+            tag_similar_identifiers(identifier);
+            return false;
+          }, 100);
         }
-    };
-
-    get_buffer()->signal_mark_set().connect(
-            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-                if (mark->get_name() == "insert") {
-                    delayed_tag_similar_identifiers_connection.disconnect();
-                    delayed_tag_similar_identifiers_connection = Glib::signal_timeout().connect([this]() {
-                        auto identifier = get_identifier();
-                        tag_similar_identifiers(identifier);
-                        return false;
-                    }, 100);
-                }
-            });
+      });
+
+  auto declaration_location = [this]() {
+    auto identifier = get_identifier();
+    if (identifier) {
+      auto source_location = identifier.cursor.get_canonical().get_source_location();
+      auto offset = source_location.get_offset();
+      return Offset(offset.line - 1, offset.index - 1, source_location.get_path());
+    } else {
+      // If cursor is at an include line, return offset to included file
+      const static std::regex include_regex("^[ \t]*#[ \t]*include[ \t]*[<\"]([^<>\"]+)[>\"].*$");
+      std::smatch sm;
+      auto line = get_line();
+      if (std::regex_match(line, sm, include_regex)) {
+        struct ClientData {
+          boost::filesystem::path &file_path;
+          std::string found_include;
+          int line_nr;
+          std::string sm_str;
+        };
+        ClientData client_data{this->file_path, std::string(),
+                               get_buffer()->get_insert()->get_iter().get_line(), sm[1].str()};
+
+        // Attempt to find the 100% correct include file first
+        clang_getInclusions(clang_tu->cx_tu,
+                            [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len,
+                               CXClientData client_data_) {
+                              auto client_data = static_cast<ClientData *>(client_data_);
+                              if (client_data->found_include.empty() && include_len > 0) {
+                                auto source_location = clangmm::SourceLocation(inclusion_stack[0]);
+                                if (static_cast<int>(source_location.get_offset().line) - 1 ==
+                                    client_data->line_nr &&
+                                    filesystem::get_normal_path(source_location.get_path()) ==
+                                    client_data->file_path)
+                                  client_data->found_include = clangmm::to_string(
+                                      clang_getFileName(included_file));
+                              }
+                            }, &client_data);
+
+        if (!client_data.found_include.empty())
+          return Offset(0, 0, client_data.found_include);
+
+        // Find a matching include file if no include was found previously
+        clang_getInclusions(clang_tu->cx_tu,
+                            [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len,
+                               CXClientData client_data_) {
+                              auto client_data = static_cast<ClientData *>(client_data_);
+                              if (client_data->found_include.empty()) {
+                                for (unsigned c = 1; c < include_len; ++c) {
+                                  auto source_location = clangmm::SourceLocation(inclusion_stack[c]);
+                                  if (static_cast<int>(source_location.get_offset().line) - 1 <=
+                                      client_data->line_nr &&
+                                      filesystem::get_normal_path(source_location.get_path()) ==
+                                      client_data->file_path) {
+                                    auto included_file_str = clangmm::to_string(
+                                        clang_getFileName(included_file));
+                                    if (included_file_str.size() >= client_data->sm_str.size() &&
+                                        included_file_str.compare(
+                                            included_file_str.size() - client_data->sm_str.size(),
+                                            client_data->sm_str.size(), client_data->sm_str) == 0) {
+                                      client_data->found_include = included_file_str;
+                                      break;
+                                    }
+                                  }
+                                }
+                              }
+                            }, &client_data);
+
+        if (!client_data.found_include.empty())
+          return Offset(0, 0, client_data.found_include);
+      }
+    }
+    return Offset();
+  };
+
+  get_declaration_location = [this, declaration_location]() {
+    if (!parsed) {
+      if (selected_completion_string) {
+        auto completion_cursor = clangmm::CompletionString(selected_completion_string).get_cursor(
+            clang_tu->cx_tu);
+        if (completion_cursor) {
+          auto source_location = completion_cursor.get_source_location();
+          auto source_location_offset = source_location.get_offset();
+          if (CompletionDialog::get())
+            CompletionDialog::get()->hide();
+          auto offset = Offset(source_location_offset.line - 1, source_location_offset.index - 1,
+                               source_location.get_path());
+
+          // Workaround for bug in ArchLinux's clang_getFileName()
+          // TODO: remove the workaround when this is fixed
+          auto include_path = filesystem::get_normal_path(offset.file_path);
+          boost::system::error_code ec;
+          if (!boost::filesystem::exists(include_path, ec))
+            offset.file_path = "/usr/include" / include_path;
 
-    auto declaration_location = [this]() {
-        auto identifier = get_identifier();
-        if (identifier) {
-            auto source_location = identifier.cursor.get_canonical().get_source_location();
-            auto offset = source_location.get_offset();
-            return Offset(offset.line - 1, offset.index - 1, source_location.get_path());
+          return offset;
         } else {
-            // If cursor is at an include line, return offset to included file
-            const static std::regex include_regex("^[ \t]*#[ \t]*include[ \t]*[<\"]([^<>\"]+)[>\"].*$");
-            std::smatch sm;
-            auto line = get_line();
-            if (std::regex_match(line, sm, include_regex)) {
-                struct ClientData {
-                    boost::filesystem::path &file_path;
-                    std::string found_include;
-                    int line_nr;
-                    std::string sm_str;
-                };
-                ClientData client_data{this->file_path, std::string(),
-                                       get_buffer()->get_insert()->get_iter().get_line(), sm[1].str()};
-
-                // Attempt to find the 100% correct include file first
-                clang_getInclusions(clang_tu->cx_tu,
-                                    [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len,
-                                       CXClientData client_data_) {
-                                        auto client_data = static_cast<ClientData *>(client_data_);
-                                        if (client_data->found_include.empty() && include_len > 0) {
-                                            auto source_location = clangmm::SourceLocation(inclusion_stack[0]);
-                                            if (static_cast<int>(source_location.get_offset().line) - 1 ==
-                                                client_data->line_nr &&
-                                                filesystem::get_normal_path(source_location.get_path()) ==
-                                                client_data->file_path)
-                                                client_data->found_include = clangmm::to_string(
-                                                        clang_getFileName(included_file));
-                                        }
-                                    }, &client_data);
-
-                if (!client_data.found_include.empty())
-                    return Offset(0, 0, client_data.found_include);
-
-                // Find a matching include file if no include was found previously
-                clang_getInclusions(clang_tu->cx_tu,
-                                    [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len,
-                                       CXClientData client_data_) {
-                                        auto client_data = static_cast<ClientData *>(client_data_);
-                                        if (client_data->found_include.empty()) {
-                                            for (unsigned c = 1; c < include_len; ++c) {
-                                                auto source_location = clangmm::SourceLocation(inclusion_stack[c]);
-                                                if (static_cast<int>(source_location.get_offset().line) - 1 <=
-                                                    client_data->line_nr &&
-                                                    filesystem::get_normal_path(source_location.get_path()) ==
-                                                    client_data->file_path) {
-                                                    auto included_file_str = clangmm::to_string(
-                                                            clang_getFileName(included_file));
-                                                    if (included_file_str.size() >= client_data->sm_str.size() &&
-                                                        included_file_str.compare(
-                                                                included_file_str.size() - client_data->sm_str.size(),
-                                                                client_data->sm_str.size(), client_data->sm_str) == 0) {
-                                                        client_data->found_include = included_file_str;
-                                                        break;
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }, &client_data);
-
-                if (!client_data.found_include.empty())
-                    return Offset(0, 0, client_data.found_include);
-            }
+          Info::get().print("No declaration found");
+          return Offset();
         }
-        return Offset();
-    };
-
-    get_declaration_location = [this, declaration_location]() {
-        if (!parsed) {
-            if (selected_completion_string) {
-                auto completion_cursor = clangmm::CompletionString(selected_completion_string).get_cursor(
-                        clang_tu->cx_tu);
-                if (completion_cursor) {
-                    auto source_location = completion_cursor.get_source_location();
-                    auto source_location_offset = source_location.get_offset();
-                    if (CompletionDialog::get())
-                        CompletionDialog::get()->hide();
-                    auto offset = Offset(source_location_offset.line - 1, source_location_offset.index - 1,
-                                         source_location.get_path());
-
-                    // Workaround for bug in ArchLinux's clang_getFileName()
-                    // TODO: remove the workaround when this is fixed
-                    auto include_path = filesystem::get_normal_path(offset.file_path);
-                    boost::system::error_code ec;
-                    if (!boost::filesystem::exists(include_path, ec))
-                        offset.file_path = "/usr/include" / include_path;
-
-                    return offset;
-                } else {
-                    Info::get().print("No declaration found");
-                    return Offset();
-                }
-            }
+      }
 
-            Info::get().print("Buffer is parsing");
-            return Offset();
-        }
-        auto offset = declaration_location();
-        if (!offset)
-            Info::get().print("No declaration found");
-
-        // Workaround for bug in ArchLinux's clang_getFileName()
-        // TODO: remove the workaround when this is fixed
-        auto include_path = filesystem::get_normal_path(offset.file_path);
-        boost::system::error_code ec;
-        if (!boost::filesystem::exists(include_path, ec))
+      Info::get().print("Buffer is parsing");
+      return Offset();
+    }
+    auto offset = declaration_location();
+    if (!offset)
+      Info::get().print("No declaration found");
+
+    // Workaround for bug in ArchLinux's clang_getFileName()
+    // TODO: remove the workaround when this is fixed
+    auto include_path = filesystem::get_normal_path(offset.file_path);
+    boost::system::error_code ec;
+    if (!boost::filesystem::exists(include_path, ec))
+      offset.file_path = "/usr/include" / include_path;
+
+    return offset;
+  };
+
+  get_type_declaration_location = [this]() {
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return Offset();
+    }
+    auto identifier = get_identifier();
+    if (identifier) {
+      auto type_cursor = identifier.cursor.get_type().get_cursor();
+      if (type_cursor) {
+        auto source_location = type_cursor.get_source_location();
+        auto path = source_location.get_path();
+        if (!path.empty()) {
+          auto source_location_offset = source_location.get_offset();
+          auto offset = Offset(source_location_offset.line - 1, source_location_offset.index - 1, path);
+
+          // Workaround for bug in ArchLinux's clang_getFileName()
+          // TODO: remove the workaround when this is fixed
+          auto include_path = filesystem::get_normal_path(offset.file_path);
+          boost::system::error_code ec;
+          if (!boost::filesystem::exists(include_path, ec))
             offset.file_path = "/usr/include" / include_path;
 
-        return offset;
-    };
-
-    get_type_declaration_location = [this]() {
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return Offset();
-        }
-        auto identifier = get_identifier();
-        if (identifier) {
-            auto type_cursor = identifier.cursor.get_type().get_cursor();
-            if (type_cursor) {
-                auto source_location = type_cursor.get_source_location();
-                auto path = source_location.get_path();
-                if (!path.empty()) {
-                    auto source_location_offset = source_location.get_offset();
-                    auto offset = Offset(source_location_offset.line - 1, source_location_offset.index - 1, path);
-
-                    // Workaround for bug in ArchLinux's clang_getFileName()
-                    // TODO: remove the workaround when this is fixed
-                    auto include_path = filesystem::get_normal_path(offset.file_path);
-                    boost::system::error_code ec;
-                    if (!boost::filesystem::exists(include_path, ec))
-                        offset.file_path = "/usr/include" / include_path;
-
-                    return offset;
-                }
-            }
+          return offset;
         }
-        Info::get().print("No type declaration found");
-        return Offset();
-    };
-
-    auto implementation_locations = [this](const Identifier &identifier) {
-        std::vector<Offset> offsets;
-        if (identifier) {
-            wait_parsing();
-
-            //First, look for a definition cursor that is equal
-            auto identifier_usr = identifier.cursor.get_usr();
-            for (auto &view: views) {
-                if (auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
-                    for (auto &token: *clang_view->clang_tokens) {
-                        auto cursor = token.get_cursor();
-                        auto cursor_kind = cursor.get_kind();
-                        if ((cursor_kind == clangmm::Cursor::Kind::FunctionDecl ||
-                             cursor_kind == clangmm::Cursor::Kind::CXXMethod ||
-                             cursor_kind == clangmm::Cursor::Kind::Constructor ||
-                             cursor_kind == clangmm::Cursor::Kind::Destructor ||
-                             cursor_kind == clangmm::Cursor::Kind::FunctionTemplate ||
-                             cursor_kind == clangmm::Cursor::Kind::ConversionFunction) &&
-                            token.is_identifier()) {
-                            auto token_spelling = token.get_spelling();
-                            if (identifier.kind == cursor.get_kind() && identifier.spelling == token_spelling &&
-                                identifier_usr == cursor.get_usr()) {
-                                if (clang_isCursorDefinition(cursor.cx_cursor)) {
-                                    Offset offset;
-                                    auto location = cursor.get_source_location();
-                                    auto clang_offset = location.get_offset();
-                                    offset.file_path = location.get_path();
-                                    offset.line = clang_offset.line - 1;
-                                    offset.index = clang_offset.index - 1;
-                                    offsets.emplace_back(offset);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            if (!offsets.empty())
-                return offsets;
-
-            //If no implementation was found, try using clang_getCursorDefinition
-            auto definition = identifier.cursor.get_definition();
-            if (definition) {
-                auto location = definition.get_source_location();
-                Offset offset;
-                offset.file_path = location.get_path();
-                auto clang_offset = location.get_offset();
-                offset.line = clang_offset.line - 1;
-                offset.index = clang_offset.index - 1;
-                offsets.emplace_back(offset);
-                return offsets;
-            }
-
-            //If no implementation was found, use declaration if it is a function template
-            auto canonical = identifier.cursor.get_canonical();
-            auto cursor = clang_tu->get_cursor(canonical.get_source_location());
-            if (cursor && cursor.get_kind() == clangmm::Cursor::Kind::FunctionTemplate) {
-                auto location = cursor.get_source_location();
-                Offset offset;
-                offset.file_path = location.get_path();
-                auto clang_offset = location.get_offset();
-                offset.line = clang_offset.line - 1;
-                offset.index = clang_offset.index - 1;
-                offsets.emplace_back(offset);
-                return offsets;
-            }
-
-            //If no implementation was found, try using Ctags
-            auto name = identifier.cursor.get_spelling();
-            auto parent = identifier.cursor.get_semantic_parent();
-            while (parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {
-                auto spelling = parent.get_spelling() + "::";
-                name.insert(0, spelling);
-                parent = parent.get_semantic_parent();
-            }
-            auto ctags_locations = Ctags::get_locations(this->file_path, name,
-                                                        identifier.cursor.get_type_description());
-            if (!ctags_locations.empty()) {
-                for (auto &ctags_location: ctags_locations) {
-                    Offset offset;
-                    offset.file_path = ctags_location.file_path;
-                    offset.line = ctags_location.line;
-                    offset.index = ctags_location.index;
-                    offsets.emplace_back(offset);
+      }
+    }
+    Info::get().print("No type declaration found");
+    return Offset();
+  };
+
+  auto implementation_locations = [this](const Identifier &identifier) {
+    std::vector<Offset> offsets;
+    if (identifier) {
+      wait_parsing();
+
+      //First, look for a definition cursor that is equal
+      auto identifier_usr = identifier.cursor.get_usr();
+      for (auto &view: views) {
+        if (auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
+          for (auto &token: *clang_view->clang_tokens) {
+            auto cursor = token.get_cursor();
+            auto cursor_kind = cursor.get_kind();
+            if ((cursor_kind == clangmm::Cursor::Kind::FunctionDecl ||
+                 cursor_kind == clangmm::Cursor::Kind::CXXMethod ||
+                 cursor_kind == clangmm::Cursor::Kind::Constructor ||
+                 cursor_kind == clangmm::Cursor::Kind::Destructor ||
+                 cursor_kind == clangmm::Cursor::Kind::FunctionTemplate ||
+                 cursor_kind == clangmm::Cursor::Kind::ConversionFunction) &&
+                token.is_identifier()) {
+              auto token_spelling = token.get_spelling();
+              if (identifier.kind == cursor.get_kind() && identifier.spelling == token_spelling &&
+                  identifier_usr == cursor.get_usr()) {
+                if (clang_isCursorDefinition(cursor.cx_cursor)) {
+                  Offset offset;
+                  auto location = cursor.get_source_location();
+                  auto clang_offset = location.get_offset();
+                  offset.file_path = location.get_path();
+                  offset.line = clang_offset.line - 1;
+                  offset.index = clang_offset.index - 1;
+                  offsets.emplace_back(offset);
                 }
-                return offsets;
+              }
             }
+          }
         }
+      }
+      if (!offsets.empty())
         return offsets;
-    };
-
-    get_implementation_locations = [this, implementation_locations]() {
-        if (!parsed) {
-            if (selected_completion_string) {
-                auto completion_cursor = clangmm::CompletionString(selected_completion_string).get_cursor(
-                        clang_tu->cx_tu);
-                if (completion_cursor) {
-                    auto offsets = implementation_locations(
-                            Identifier(completion_cursor.get_token_spelling(), completion_cursor));
-                    if (offsets.empty()) {
-                        Info::get().print("No implementation found");
-                        return std::vector<Offset>();
-                    }
-                    if (CompletionDialog::get())
-                        CompletionDialog::get()->hide();
-
-                    // Workaround for bug in ArchLinux's clang_getFileName()
-                    // TODO: remove the workaround when this is fixed
-                    for (auto &offset: offsets) {
-                        auto include_path = filesystem::get_normal_path(offset.file_path);
-                        boost::system::error_code ec;
-                        if (!boost::filesystem::exists(include_path, ec))
-                            offset.file_path = "/usr/include" / include_path;
-                    }
 
-                    return offsets;
-                } else {
-                    Info::get().print("No implementation found");
-                    return std::vector<Offset>();
-                }
-            }
-
-            Info::get().print("Buffer is parsing");
-            return std::vector<Offset>();
+      //If no implementation was found, try using clang_getCursorDefinition
+      auto definition = identifier.cursor.get_definition();
+      if (definition) {
+        auto location = definition.get_source_location();
+        Offset offset;
+        offset.file_path = location.get_path();
+        auto clang_offset = location.get_offset();
+        offset.line = clang_offset.line - 1;
+        offset.index = clang_offset.index - 1;
+        offsets.emplace_back(offset);
+        return offsets;
+      }
+
+      //If no implementation was found, use declaration if it is a function template
+      auto canonical = identifier.cursor.get_canonical();
+      auto cursor = clang_tu->get_cursor(canonical.get_source_location());
+      if (cursor && cursor.get_kind() == clangmm::Cursor::Kind::FunctionTemplate) {
+        auto location = cursor.get_source_location();
+        Offset offset;
+        offset.file_path = location.get_path();
+        auto clang_offset = location.get_offset();
+        offset.line = clang_offset.line - 1;
+        offset.index = clang_offset.index - 1;
+        offsets.emplace_back(offset);
+        return offsets;
+      }
+
+      //If no implementation was found, try using Ctags
+      auto name = identifier.cursor.get_spelling();
+      auto parent = identifier.cursor.get_semantic_parent();
+      while (parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {
+        auto spelling = parent.get_spelling() + "::";
+        name.insert(0, spelling);
+        parent = parent.get_semantic_parent();
+      }
+      auto ctags_locations = Ctags::get_locations(this->file_path, name,
+                                                  identifier.cursor.get_type_description());
+      if (!ctags_locations.empty()) {
+        for (auto &ctags_location: ctags_locations) {
+          Offset offset;
+          offset.file_path = ctags_location.file_path;
+          offset.line = ctags_location.line;
+          offset.index = ctags_location.index;
+          offsets.emplace_back(offset);
         }
-        auto offsets = implementation_locations(get_identifier());
-        if (offsets.empty())
+        return offsets;
+      }
+    }
+    return offsets;
+  };
+
+  get_implementation_locations = [this, implementation_locations]() {
+    if (!parsed) {
+      if (selected_completion_string) {
+        auto completion_cursor = clangmm::CompletionString(selected_completion_string).get_cursor(
+            clang_tu->cx_tu);
+        if (completion_cursor) {
+          auto offsets = implementation_locations(
+              Identifier(completion_cursor.get_token_spelling(), completion_cursor));
+          if (offsets.empty()) {
             Info::get().print("No implementation found");
+            return std::vector<Offset>();
+          }
+          if (CompletionDialog::get())
+            CompletionDialog::get()->hide();
 
-        // Workaround for bug in ArchLinux's clang_getFileName()
-        // TODO: remove the workaround when this is fixed
-        for (auto &offset: offsets) {
+          // Workaround for bug in ArchLinux's clang_getFileName()
+          // TODO: remove the workaround when this is fixed
+          for (auto &offset: offsets) {
             auto include_path = filesystem::get_normal_path(offset.file_path);
             boost::system::error_code ec;
             if (!boost::filesystem::exists(include_path, ec))
-                offset.file_path = "/usr/include" / include_path;
-        }
+              offset.file_path = "/usr/include" / include_path;
+          }
 
-        return offsets;
-    };
-
-    get_declaration_or_implementation_locations = [this, declaration_location, implementation_locations]() {
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return std::vector<Offset>();
-        }
-
-        std::vector<Offset> offsets;
-
-        bool is_implementation = false;
-        auto iter = get_buffer()->get_insert()->get_iter();
-        auto line = static_cast<unsigned>(iter.get_line());
-        auto index = static_cast<unsigned>(iter.get_line_index());
-        for (size_t c = 0; c < clang_tokens->size(); ++c) {
-            auto &token = (*clang_tokens)[c];
-            if (token.is_identifier()) {
-                auto &token_offsets = clang_tokens_offsets[c];
-                if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
-                    index <= token_offsets.second.index - 1) {
-                    if (clang_isCursorDefinition(token.get_cursor().cx_cursor) > 0)
-                        is_implementation = true;
-                    break;
-                }
-            }
-        }
-        // If cursor is at implementation, return declaration_location
-        if (is_implementation) {
-            auto offset = declaration_location();
-            if (offset)
-                offsets.emplace_back(offset);
+          return offsets;
         } else {
-            auto implementation_offsets = implementation_locations(get_identifier());
-            if (!implementation_offsets.empty()) {
-                offsets = std::move(implementation_offsets);
-            } else {
-                auto offset = declaration_location();
-                if (offset)
-                    offsets.emplace_back(offset);
-            }
+          Info::get().print("No implementation found");
+          return std::vector<Offset>();
         }
+      }
+
+      Info::get().print("Buffer is parsing");
+      return std::vector<Offset>();
+    }
+    auto offsets = implementation_locations(get_identifier());
+    if (offsets.empty())
+      Info::get().print("No implementation found");
+
+    // Workaround for bug in ArchLinux's clang_getFileName()
+    // TODO: remove the workaround when this is fixed
+    for (auto &offset: offsets) {
+      auto include_path = filesystem::get_normal_path(offset.file_path);
+      boost::system::error_code ec;
+      if (!boost::filesystem::exists(include_path, ec))
+        offset.file_path = "/usr/include" / include_path;
+    }
 
-        if (offsets.empty())
-            Info::get().print("No declaration or implementation found");
+    return offsets;
+  };
 
-        // Workaround for bug in ArchLinux's clang_getFileName()
-        // TODO: remove the workaround when this is fixed
-        for (auto &offset: offsets) {
-            auto include_path = filesystem::get_normal_path(offset.file_path);
-            boost::system::error_code ec;
-            if (!boost::filesystem::exists(include_path, ec))
-                offset.file_path = "/usr/include" / include_path;
-        }
+  get_declaration_or_implementation_locations = [this, declaration_location, implementation_locations]() {
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return std::vector<Offset>();
+    }
 
-        return offsets;
-    };
+    std::vector<Offset> offsets;
 
-    get_usages = [this]() {
-        std::vector<std::pair<Offset, std::string> > usages;
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return usages;
+    bool is_implementation = false;
+    auto iter = get_buffer()->get_insert()->get_iter();
+    auto line = static_cast<unsigned>(iter.get_line());
+    auto index = static_cast<unsigned>(iter.get_line_index());
+    for (size_t c = 0; c < clang_tokens->size(); ++c) {
+      auto &token = (*clang_tokens)[c];
+      if (token.is_identifier()) {
+        auto &token_offsets = clang_tokens_offsets[c];
+        if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
+            index <= token_offsets.second.index - 1) {
+          if (clang_isCursorDefinition(token.get_cursor().cx_cursor) > 0)
+            is_implementation = true;
+          break;
         }
-        auto identifier = get_identifier();
-        if (identifier) {
-            wait_parsing();
-
-            auto embolden_token = [](std::string &line, unsigned token_start_pos, unsigned token_end_pos) {
-                //markup token as bold
-                size_t pos = 0;
-                while ((pos = line.find('&', pos)) != std::string::npos) {
-                    size_t pos2 = line.find(';', pos + 2);
-                    if (token_start_pos > pos) {
-                        token_start_pos += pos2 - pos;
-                        token_end_pos += pos2 - pos;
-                    } else if (token_end_pos > pos)
-                        token_end_pos += pos2 - pos;
-                    else
-                        break;
-                    pos = pos2 + 1;
-                }
-                line.insert(token_end_pos, "</b>");
-                line.insert(token_start_pos, "<b>");
-
-                size_t start_pos = 0;
-                while (start_pos < line.size() && (line[start_pos] == ' ' || line[start_pos] == '\t'))
-                    ++start_pos;
-                if (start_pos > 0)
-                    line.erase(0, start_pos);
-            };
+      }
+    }
+    // If cursor is at implementation, return declaration_location
+    if (is_implementation) {
+      auto offset = declaration_location();
+      if (offset)
+        offsets.emplace_back(offset);
+    } else {
+      auto implementation_offsets = implementation_locations(get_identifier());
+      if (!implementation_offsets.empty()) {
+        offsets = std::move(implementation_offsets);
+      } else {
+        auto offset = declaration_location();
+        if (offset)
+          offsets.emplace_back(offset);
+      }
+    }
 
-            std::vector<clangmm::TranslationUnit *> translation_units;
-            translation_units.emplace_back(clang_tu.get());
-            for (auto &view: views) {
-                if (view != this) {
-                    if (auto clang_view = dynamic_cast<Source::ClangView *>(view))
-                        translation_units.emplace_back(clang_view->clang_tu.get());
-                }
-            }
+    if (offsets.empty())
+      Info::get().print("No declaration or implementation found");
 
-            auto build = Project::Build::create(this->file_path);
-            auto usages_clang = Usages::Clang::get_usages(build->project_path, build->get_default_path(),
-                                                          build->get_debug_path(), {identifier.spelling},
-                                                          {identifier.cursor}, translation_units);
-            for (auto &usage: usages_clang) {
-                for (size_t c = 0; c < usage.offsets.size(); ++c) {
-                    std::string line = Glib::Markup::escape_text(usage.lines[c]);
-                    embolden_token(line, usage.offsets[c].first.index - 1, usage.offsets[c].second.index - 1);
-                    usages.emplace_back(
-                            Offset(usage.offsets[c].first.line - 1, usage.offsets[c].first.index - 1, usage.path),
-                            line);
-                }
-            }
-        }
+    // Workaround for bug in ArchLinux's clang_getFileName()
+    // TODO: remove the workaround when this is fixed
+    for (auto &offset: offsets) {
+      auto include_path = filesystem::get_normal_path(offset.file_path);
+      boost::system::error_code ec;
+      if (!boost::filesystem::exists(include_path, ec))
+        offset.file_path = "/usr/include" / include_path;
+    }
 
-        if (usages.empty())
-            Info::get().print("No symbol found at current cursor location");
-        return usages;
-    };
+    return offsets;
+  };
 
-    get_method = [this] {
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return std::string();
+  get_usages = [this]() {
+    std::vector<std::pair<Offset, std::string> > usages;
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return usages;
+    }
+    auto identifier = get_identifier();
+    if (identifier) {
+      wait_parsing();
+
+      auto embolden_token = [](std::string &line, unsigned token_start_pos, unsigned token_end_pos) {
+        //markup token as bold
+        size_t pos = 0;
+        while ((pos = line.find('&', pos)) != std::string::npos) {
+          size_t pos2 = line.find(';', pos + 2);
+          if (token_start_pos > pos) {
+            token_start_pos += pos2 - pos;
+            token_end_pos += pos2 - pos;
+          } else if (token_end_pos > pos)
+            token_end_pos += pos2 - pos;
+          else
+            break;
+          pos = pos2 + 1;
         }
-        auto iter = get_buffer()->get_insert()->get_iter();
-        auto line = static_cast<unsigned>(iter.get_line());
-        auto index = static_cast<unsigned>(iter.get_line_index());
-        for (size_t c = clang_tokens->size() - 1; c != static_cast<size_t>(-1); --c) {
-            auto &token = (*clang_tokens)[c];
-            if (token.is_identifier()) {
-                auto &token_offsets = clang_tokens_offsets[c];
-                if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
-                    index <= token_offsets.second.index - 1) {
-                    auto token_spelling = token.get_spelling();
-                    if (!token_spelling.empty() &&
-                        (token_spelling.size() > 1 || (token_spelling.back() >= 'a' && token_spelling.back() <= 'z') ||
-                         (token_spelling.back() >= 'A' && token_spelling.back() <= 'Z') ||
-                         token_spelling.back() == '_')) {
-                        auto cursor = token.get_cursor();
-                        auto kind = cursor.get_kind();
-                        if (kind == clangmm::Cursor::Kind::FunctionDecl || kind == clangmm::Cursor::Kind::CXXMethod ||
-                            kind == clangmm::Cursor::Kind::Constructor || kind == clangmm::Cursor::Kind::Destructor ||
-                            kind == clangmm::Cursor::Kind::ConversionFunction) {
-                            auto referenced = cursor.get_referenced();
-                            if (referenced && referenced == cursor) {
-                                std::string result;
-                                std::string specifier;
-                                if (kind == clangmm::Cursor::Kind::FunctionDecl ||
-                                    kind == clangmm::Cursor::Kind::CXXMethod) {
-                                    auto start_offset = cursor.get_source_range().get_start().get_offset();
-                                    auto end_offset = token_offsets.first;
-
-                                    // To accurately get result type with needed namespace and class/struct names:
-                                    int angle_brackets = 0;
-                                    for (size_t c = 0; c < clang_tokens->size(); ++c) {
-                                        auto &token = (*clang_tokens)[c];
-                                        auto &token_offsets = clang_tokens_offsets[c];
-                                        if ((token_offsets.first.line == start_offset.line &&
-                                             token_offsets.second.line != end_offset.line &&
-                                             token_offsets.first.index >= start_offset.index) ||
-                                            (token_offsets.first.line > start_offset.line &&
-                                             token_offsets.second.line < end_offset.line) ||
-                                            (token_offsets.first.line != start_offset.line &&
-                                             token_offsets.second.line == end_offset.line &&
-                                             token_offsets.second.index <= end_offset.index) ||
-                                            (token_offsets.first.line == start_offset.line &&
-                                             token_offsets.second.line == end_offset.line &&
-                                             token_offsets.first.index >= start_offset.index &&
-                                             token_offsets.second.index <= end_offset.index)) {
-                                            auto token_spelling = token.get_spelling();
-                                            if (token.get_kind() == clangmm::Token::Kind::Identifier) {
-                                                if (c == 0 || (*clang_tokens)[c - 1].get_spelling() != "::") {
-                                                    auto name = token_spelling;
-                                                    auto parent = token.get_cursor().get_type().get_cursor().get_semantic_parent();
-                                                    while (parent && parent.get_kind() !=
-                                                                     clangmm::Cursor::Kind::TranslationUnit) {
-                                                        auto spelling = parent.get_token_spelling();
-                                                        name.insert(0, spelling + "::");
-                                                        parent = parent.get_semantic_parent();
-                                                    }
-                                                    result += name;
-                                                } else
-                                                    result += token_spelling;
-                                            } else if ((token_spelling == "*" || token_spelling == "&") &&
-                                                       !result.empty() && result.back() != '*' && result.back() != '&')
-                                                result += ' ' + token_spelling;
-                                            else if (token_spelling == "extern" || token_spelling == "static" ||
-                                                     token_spelling == "virtual" || token_spelling == "friend")
-                                                continue;
-                                            else if (token_spelling == "," ||
-                                                     (token_spelling.size() > 1 && token_spelling != "::" &&
-                                                      angle_brackets == 0))
-                                                result += token_spelling + ' ';
-                                            else {
-                                                if (token_spelling == "<")
-                                                    ++angle_brackets;
-                                                else if (token_spelling == ">")
-                                                    --angle_brackets;
-                                                result += token_spelling;
-                                            }
-                                        }
-                                    }
+        line.insert(token_end_pos, "</b>");
+        line.insert(token_start_pos, "<b>");
+
+        size_t start_pos = 0;
+        while (start_pos < line.size() && (line[start_pos] == ' ' || line[start_pos] == '\t'))
+          ++start_pos;
+        if (start_pos > 0)
+          line.erase(0, start_pos);
+      };
+
+      std::vector<clangmm::TranslationUnit *> translation_units;
+      translation_units.emplace_back(clang_tu.get());
+      for (auto &view: views) {
+        if (view != this) {
+          if (auto clang_view = dynamic_cast<Source::ClangView *>(view))
+            translation_units.emplace_back(clang_view->clang_tu.get());
+        }
+      }
+
+      auto build = Project::Build::create(this->file_path);
+      auto usages_clang = Usages::Clang::get_usages(build->project_path, build->get_default_path(),
+                                                    build->get_debug_path(), {identifier.spelling},
+                                                    {identifier.cursor}, translation_units);
+      for (auto &usage: usages_clang) {
+        for (size_t c = 0; c < usage.offsets.size(); ++c) {
+          std::string line = Glib::Markup::escape_text(usage.lines[c]);
+          embolden_token(line, usage.offsets[c].first.index - 1, usage.offsets[c].second.index - 1);
+          usages.emplace_back(
+              Offset(usage.offsets[c].first.line - 1, usage.offsets[c].first.index - 1, usage.path),
+              line);
+        }
+      }
+    }
 
-                                    if (!result.empty() && result.back() != '*' && result.back() != '&' &&
-                                        result.back() != ' ')
-                                        result += ' ';
+    if (usages.empty())
+      Info::get().print("No symbol found at current cursor location");
+    return usages;
+  };
 
-                                    if (clang_CXXMethod_isConst(cursor.cx_cursor))
-                                        specifier = " const";
-                                }
+  get_method = [this] {
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return std::string();
+    }
+    auto iter = get_buffer()->get_insert()->get_iter();
+    auto line = static_cast<unsigned>(iter.get_line());
+    auto index = static_cast<unsigned>(iter.get_line_index());
+    for (size_t c = clang_tokens->size() - 1; c != static_cast<size_t>(-1); --c) {
+      auto &token = (*clang_tokens)[c];
+      if (token.is_identifier()) {
+        auto &token_offsets = clang_tokens_offsets[c];
+        if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
+            index <= token_offsets.second.index - 1) {
+          auto token_spelling = token.get_spelling();
+          if (!token_spelling.empty() &&
+              (token_spelling.size() > 1 || (token_spelling.back() >= 'a' && token_spelling.back() <= 'z') ||
+               (token_spelling.back() >= 'A' && token_spelling.back() <= 'Z') ||
+               token_spelling.back() == '_')) {
+            auto cursor = token.get_cursor();
+            auto kind = cursor.get_kind();
+            if (kind == clangmm::Cursor::Kind::FunctionDecl || kind == clangmm::Cursor::Kind::CXXMethod ||
+                kind == clangmm::Cursor::Kind::Constructor || kind == clangmm::Cursor::Kind::Destructor ||
+                kind == clangmm::Cursor::Kind::ConversionFunction) {
+              auto referenced = cursor.get_referenced();
+              if (referenced && referenced == cursor) {
+                std::string result;
+                std::string specifier;
+                if (kind == clangmm::Cursor::Kind::FunctionDecl ||
+                    kind == clangmm::Cursor::Kind::CXXMethod) {
+                  auto start_offset = cursor.get_source_range().get_start().get_offset();
+                  auto end_offset = token_offsets.first;
+
+                  // To accurately get result type with needed namespace and class/struct names:
+                  int angle_brackets = 0;
+                  for (size_t c = 0; c < clang_tokens->size(); ++c) {
+                    auto &token = (*clang_tokens)[c];
+                    auto &token_offsets = clang_tokens_offsets[c];
+                    if ((token_offsets.first.line == start_offset.line &&
+                         token_offsets.second.line != end_offset.line &&
+                         token_offsets.first.index >= start_offset.index) ||
+                        (token_offsets.first.line > start_offset.line &&
+                         token_offsets.second.line < end_offset.line) ||
+                        (token_offsets.first.line != start_offset.line &&
+                         token_offsets.second.line == end_offset.line &&
+                         token_offsets.second.index <= end_offset.index) ||
+                        (token_offsets.first.line == start_offset.line &&
+                         token_offsets.second.line == end_offset.line &&
+                         token_offsets.first.index >= start_offset.index &&
+                         token_offsets.second.index <= end_offset.index)) {
+                      auto token_spelling = token.get_spelling();
+                      if (token.get_kind() == clangmm::Token::Kind::Identifier) {
+                        if (c == 0 || (*clang_tokens)[c - 1].get_spelling() != "::") {
+                          auto name = token_spelling;
+                          auto parent = token.get_cursor().get_type().get_cursor().get_semantic_parent();
+                          while (parent && parent.get_kind() !=
+                                           clangmm::Cursor::Kind::TranslationUnit) {
+                            auto spelling = parent.get_token_spelling();
+                            name.insert(0, spelling + "::");
+                            parent = parent.get_semantic_parent();
+                          }
+                          result += name;
+                        } else
+                          result += token_spelling;
+                      } else if ((token_spelling == "*" || token_spelling == "&") &&
+                                 !result.empty() && result.back() != '*' && result.back() != '&')
+                        result += ' ' + token_spelling;
+                      else if (token_spelling == "extern" || token_spelling == "static" ||
+                               token_spelling == "virtual" || token_spelling == "friend")
+                        continue;
+                      else if (token_spelling == "," ||
+                               (token_spelling.size() > 1 && token_spelling != "::" &&
+                                angle_brackets == 0))
+                        result += token_spelling + ' ';
+                      else {
+                        if (token_spelling == "<")
+                          ++angle_brackets;
+                        else if (token_spelling == ">")
+                          --angle_brackets;
+                        result += token_spelling;
+                      }
+                    }
+                  }
 
-                                auto name = cursor.get_spelling();
-                                auto parent = cursor.get_semantic_parent();
-                                std::vector<std::string> semantic_parents;
-                                while (parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {
-                                    auto spelling = parent.get_spelling() + "::";
-                                    if (spelling != "::") {
-                                        semantic_parents.emplace_back(spelling);
-                                        name.insert(0, spelling);
-                                    }
-                                    parent = parent.get_semantic_parent();
-                                }
+                  if (!result.empty() && result.back() != '*' && result.back() != '&' &&
+                      result.back() != ' ')
+                    result += ' ';
 
-                                std::string arguments;
-                                for (auto &argument_cursor: cursor.get_arguments()) {
-                                    auto argument_type = argument_cursor.get_type().get_spelling();
-                                    for (auto it = semantic_parents.rbegin(); it != semantic_parents.rend(); ++it) {
-                                        size_t pos = argument_type.find(*it);
-                                        if (pos == 0 || (pos != std::string::npos && argument_type[pos - 1] == ' '))
-                                            argument_type.erase(pos, it->size());
-                                    }
-                                    auto argument = argument_cursor.get_spelling();
-                                    if (!arguments.empty())
-                                        arguments += ", ";
-                                    arguments += argument_type;
-                                    if (!arguments.empty() && arguments.back() != '*' && arguments.back() != '&')
-                                        arguments += ' ';
-                                    arguments += argument;
-                                }
-                                return result + name + '(' + arguments + ")" + specifier + " {}";
-                            }
-                        }
-                    }
+                  if (clang_CXXMethod_isConst(cursor.cx_cursor))
+                    specifier = " const";
                 }
-            }
-        }
-        Info::get().print("No method found at current cursor location");
-        return std::string();
-    };
-
-    get_methods = [this]() {
-        std::vector<std::pair<Offset, std::string> > methods;
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return methods;
-        }
-        clangmm::Offset last_offset{static_cast<unsigned>(-1), static_cast<unsigned>(-1)};
-        for (auto &token: *clang_tokens) {
-            if (token.is_identifier()) {
-                auto cursor = token.get_cursor();
-                auto kind = cursor.get_kind();
-                if (kind == clangmm::Cursor::Kind::FunctionDecl || kind == clangmm::Cursor::Kind::CXXMethod ||
-                    kind == clangmm::Cursor::Kind::Constructor || kind == clangmm::Cursor::Kind::Destructor ||
-                    kind == clangmm::Cursor::Kind::FunctionTemplate ||
-                    kind == clangmm::Cursor::Kind::ConversionFunction) {
-                    auto offset = cursor.get_source_location().get_offset();
-                    if (offset == last_offset)
-                        continue;
-                    last_offset = offset;
-
-                    std::string method;
-                    if (kind != clangmm::Cursor::Kind::Constructor && kind != clangmm::Cursor::Kind::Destructor) {
-                        method += cursor.get_type().get_result().get_spelling();
-                        auto pos = method.find(" ");
-                        if (pos != std::string::npos)
-                            method.erase(pos, 1);
-                        method += " ";
-                    }
-                    method += cursor.get_display_name();
 
-                    std::string prefix;
-                    auto parent = cursor.get_semantic_parent();
-                    while (parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {
-                        prefix.insert(0, parent.get_display_name() + (prefix.empty() ? "" : "::"));
-                        parent = parent.get_semantic_parent();
-                    }
+                auto name = cursor.get_spelling();
+                auto parent = cursor.get_semantic_parent();
+                std::vector<std::string> semantic_parents;
+                while (parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {
+                  auto spelling = parent.get_spelling() + "::";
+                  if (spelling != "::") {
+                    semantic_parents.emplace_back(spelling);
+                    name.insert(0, spelling);
+                  }
+                  parent = parent.get_semantic_parent();
+                }
 
-                    method = Glib::Markup::escape_text(method);
-                    //Add bold method token
-                    size_t token_end_pos = method.find('(');
-                    if (token_end_pos == std::string::npos)
-                        continue;
-                    auto token_start_pos = token_end_pos;
-                    while (token_start_pos != 0 && method[token_start_pos] != ' ')
-                        --token_start_pos;
-                    method.insert(token_end_pos, "</b>");
-                    method.insert(token_start_pos, "<b>");
-
-                    if (!prefix.empty())
-                        prefix += ':';
-                    prefix += std::to_string(offset.line) + ": ";
-                    prefix = Glib::Markup::escape_text(prefix);
-
-                    methods.emplace_back(Offset(offset.line - 1, offset.index - 1), prefix + method);
+                std::string arguments;
+                for (auto &argument_cursor: cursor.get_arguments()) {
+                  auto argument_type = argument_cursor.get_type().get_spelling();
+                  for (auto it = semantic_parents.rbegin(); it != semantic_parents.rend(); ++it) {
+                    size_t pos = argument_type.find(*it);
+                    if (pos == 0 || (pos != std::string::npos && argument_type[pos - 1] == ' '))
+                      argument_type.erase(pos, it->size());
+                  }
+                  auto argument = argument_cursor.get_spelling();
+                  if (!arguments.empty())
+                    arguments += ", ";
+                  arguments += argument_type;
+                  if (!arguments.empty() && arguments.back() != '*' && arguments.back() != '&')
+                    arguments += ' ';
+                  arguments += argument;
                 }
+                return result + name + '(' + arguments + ")" + specifier + " {}";
+              }
             }
+          }
         }
-        if (methods.empty())
-            Info::get().print("No methods found in current buffer");
-
-        return methods;
-    };
-
-    get_token_data = [this]() -> std::vector<std::string> {
-        clangmm::Cursor cursor;
-
-        std::vector<std::string> data;
-        if (!parsed) {
-            if (selected_completion_string) {
-                cursor = clangmm::CompletionString(selected_completion_string).get_cursor(clang_tu->cx_tu);
-                if (!cursor) {
-                    Info::get().print("No symbol found");
-                    return data;
-                }
-            } else {
-                Info::get().print("Buffer is parsing");
-                return data;
-            }
+      }
+    }
+    Info::get().print("No method found at current cursor location");
+    return std::string();
+  };
+
+  get_methods = [this]() {
+    std::vector<std::pair<Offset, std::string> > methods;
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return methods;
+    }
+    clangmm::Offset last_offset{static_cast<unsigned>(-1), static_cast<unsigned>(-1)};
+    for (auto &token: *clang_tokens) {
+      if (token.is_identifier()) {
+        auto cursor = token.get_cursor();
+        auto kind = cursor.get_kind();
+        if (kind == clangmm::Cursor::Kind::FunctionDecl || kind == clangmm::Cursor::Kind::CXXMethod ||
+            kind == clangmm::Cursor::Kind::Constructor || kind == clangmm::Cursor::Kind::Destructor ||
+            kind == clangmm::Cursor::Kind::FunctionTemplate ||
+            kind == clangmm::Cursor::Kind::ConversionFunction) {
+          auto offset = cursor.get_source_location().get_offset();
+          if (offset == last_offset)
+            continue;
+          last_offset = offset;
+
+          std::string method;
+          if (kind != clangmm::Cursor::Kind::Constructor && kind != clangmm::Cursor::Kind::Destructor) {
+            method += cursor.get_type().get_result().get_spelling();
+            auto pos = method.find(" ");
+            if (pos != std::string::npos)
+              method.erase(pos, 1);
+            method += " ";
+          }
+          method += cursor.get_display_name();
+
+          std::string prefix;
+          auto parent = cursor.get_semantic_parent();
+          while (parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {
+            prefix.insert(0, parent.get_display_name() + (prefix.empty() ? "" : "::"));
+            parent = parent.get_semantic_parent();
+          }
+
+          method = Glib::Markup::escape_text(method);
+          //Add bold method token
+          size_t token_end_pos = method.find('(');
+          if (token_end_pos == std::string::npos)
+            continue;
+          auto token_start_pos = token_end_pos;
+          while (token_start_pos != 0 && method[token_start_pos] != ' ')
+            --token_start_pos;
+          method.insert(token_end_pos, "</b>");
+          method.insert(token_start_pos, "<b>");
+
+          if (!prefix.empty())
+            prefix += ':';
+          prefix += std::to_string(offset.line) + ": ";
+          prefix = Glib::Markup::escape_text(prefix);
+
+          methods.emplace_back(Offset(offset.line - 1, offset.index - 1), prefix + method);
         }
+      }
+    }
+    if (methods.empty())
+      Info::get().print("No methods found in current buffer");
+
+    return methods;
+  };
+
+  get_token_data = [this]() -> std::vector<std::string> {
+    clangmm::Cursor cursor;
 
+    std::vector<std::string> data;
+    if (!parsed) {
+      if (selected_completion_string) {
+        cursor = clangmm::CompletionString(selected_completion_string).get_cursor(clang_tu->cx_tu);
         if (!cursor) {
-            auto identifier = get_identifier();
-            if (identifier)
-                cursor = identifier.cursor.get_canonical();
+          Info::get().print("No symbol found");
+          return data;
         }
+      } else {
+        Info::get().print("Buffer is parsing");
+        return data;
+      }
+    }
 
-        if (cursor) {
-            data.emplace_back("clang");
-
-            std::string symbol;
-            clangmm::Cursor last_cursor;
-            auto it = data.end();
-            do {
-                auto token_spelling = cursor.get_token_spelling();
-                if (!token_spelling.empty() && token_spelling != "__1" && token_spelling.compare(0, 5, "__cxx") != 0) {
-                    it = data.emplace(it, token_spelling);
-                    if (symbol.empty())
-                        symbol = token_spelling;
-                    else
-                        symbol.insert(0, token_spelling + "::");
-                }
-                last_cursor = cursor;
-                cursor = cursor.get_semantic_parent();
-            } while (cursor.get_kind() != clangmm::Cursor::Kind::TranslationUnit);
-
-            if (last_cursor.get_kind() != clangmm::Cursor::Kind::Namespace)
-                data.emplace(++data.begin(), "");
+    if (!cursor) {
+      auto identifier = get_identifier();
+      if (identifier)
+        cursor = identifier.cursor.get_canonical();
+    }
 
-            auto url = Documentation::CppReference::get_url(symbol);
-            if (!url.empty())
-                return {url};
+    if (cursor) {
+      data.emplace_back("clang");
+
+      std::string symbol;
+      clangmm::Cursor last_cursor;
+      auto it = data.end();
+      do {
+        auto token_spelling = cursor.get_token_spelling();
+        if (!token_spelling.empty() && token_spelling != "__1" && token_spelling.compare(0, 5, "__cxx") != 0) {
+          it = data.emplace(it, token_spelling);
+          if (symbol.empty())
+            symbol = token_spelling;
+          else
+            symbol.insert(0, token_spelling + "::");
         }
+        last_cursor = cursor;
+        cursor = cursor.get_semantic_parent();
+      } while (cursor.get_kind() != clangmm::Cursor::Kind::TranslationUnit);
 
-        if (data.empty())
-            Info::get().print("No symbol found at current cursor location");
+      if (last_cursor.get_kind() != clangmm::Cursor::Kind::Namespace)
+        data.emplace(++data.begin(), "");
 
-        return data;
-    };
+      auto url = Documentation::CppReference::get_url(symbol);
+      if (!url.empty())
+        return {url};
+    }
 
-    goto_next_diagnostic = [this]() {
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return;
-        }
-        place_cursor_at_next_diagnostic();
-    };
+    if (data.empty())
+      Info::get().print("No symbol found at current cursor location");
 
-    get_fix_its = [this]() {
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return std::vector<FixIt>();
-        }
-        if (fix_its.empty())
-            Info::get().print("No fix-its found in current buffer");
-        return fix_its;
-    };
-
-    get_documentation_template = [this]() {
-        if (!parsed) {
-            Info::get().print("Buffer is parsing");
-            return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
-        }
-        auto identifier = get_identifier();
-        if (identifier) {
-            auto cursor = identifier.cursor.get_canonical();
-            if (!clang_Range_isNull(clang_Cursor_getCommentRange(cursor.cx_cursor))) {
-                Info::get().print("Symbol is already documented");
-                return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
-            }
-            auto clang_offsets = cursor.get_source_range().get_offsets();
-            auto source_offset = Offset(clang_offsets.first.line - 1, 0, cursor.get_source_location().get_path());
-            std::string tabs;
-            for (size_t c = 0; c < clang_offsets.first.index - 1; ++c)
-                tabs += ' ';
-            auto first_line = tabs + "/**\n";
-            auto second_line = tabs + " * \n";
-            auto iter_offset = first_line.size() + second_line.size() - 1;
-
-            std::string param_lines;
-            for (int c = 0; c < clang_Cursor_getNumArguments(cursor.cx_cursor); ++c)
-                param_lines += tabs + " * @param " +
-                               clangmm::Cursor(clang_Cursor_getArgument(cursor.cx_cursor, c)).get_spelling() + '\n';
-
-            std::string return_line;
-            auto return_spelling = cursor.get_type().get_result().get_spelling();
-            if (!return_spelling.empty() && return_spelling != "void")
-                return_line += tabs + " * @return\n";
-
-            auto documentation = first_line + second_line;
-            if (!param_lines.empty() || !return_line.empty())
-                documentation += tabs + " *\n";
-
-            documentation += param_lines + return_line + tabs + " */\n";
-
-            return std::tuple<Source::Offset, std::string, size_t>(source_offset, documentation, iter_offset);
-        } else {
-            Info::get().print("No symbol found at current cursor location");
-            return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
-        }
-    };
+    return data;
+  };
+
+  goto_next_diagnostic = [this]() {
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return;
+    }
+    place_cursor_at_next_diagnostic();
+  };
+
+  get_fix_its = [this]() {
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return std::vector<FixIt>();
+    }
+    if (fix_its.empty())
+      Info::get().print("No fix-its found in current buffer");
+    return fix_its;
+  };
+
+  get_documentation_template = [this]() {
+    if (!parsed) {
+      Info::get().print("Buffer is parsing");
+      return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
+    }
+    auto identifier = get_identifier();
+    if (identifier) {
+      auto cursor = identifier.cursor.get_canonical();
+      if (!clang_Range_isNull(clang_Cursor_getCommentRange(cursor.cx_cursor))) {
+        Info::get().print("Symbol is already documented");
+        return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
+      }
+      auto clang_offsets = cursor.get_source_range().get_offsets();
+      auto source_offset = Offset(clang_offsets.first.line - 1, 0, cursor.get_source_location().get_path());
+      std::string tabs;
+      for (size_t c = 0; c < clang_offsets.first.index - 1; ++c)
+        tabs += ' ';
+      auto first_line = tabs + "/**\n";
+      auto second_line = tabs + " * \n";
+      auto iter_offset = first_line.size() + second_line.size() - 1;
+
+      std::string param_lines;
+      for (int c = 0; c < clang_Cursor_getNumArguments(cursor.cx_cursor); ++c)
+        param_lines += tabs + " * @param " +
+                       clangmm::Cursor(clang_Cursor_getArgument(cursor.cx_cursor, c)).get_spelling() + '\n';
+
+      std::string return_line;
+      auto return_spelling = cursor.get_type().get_result().get_spelling();
+      if (!return_spelling.empty() && return_spelling != "void")
+        return_line += tabs + " * @return\n";
+
+      auto documentation = first_line + second_line;
+      if (!param_lines.empty() || !return_line.empty())
+        documentation += tabs + " *\n";
+
+      documentation += param_lines + return_line + tabs + " */\n";
+
+      return std::tuple<Source::Offset, std::string, size_t>(source_offset, documentation, iter_offset);
+    } else {
+      Info::get().print("No symbol found at current cursor location");
+      return std::tuple<Source::Offset, std::string, size_t>(Source::Offset(), "", 0);
+    }
+  };
 }
 
 Source::ClangViewRefactor::Identifier Source::ClangViewRefactor::get_identifier() {
-    if (!parsed)
-        return Identifier();
-    auto iter = get_buffer()->get_insert()->get_iter();
-    auto line = static_cast<unsigned>(iter.get_line());
-    auto index = static_cast<unsigned>(iter.get_line_index());
-    for (size_t c = clang_tokens->size() - 1; c != static_cast<size_t>(-1); --c) {
-        auto &token = (*clang_tokens)[c];
-        if (token.is_identifier()) {
-            auto &token_offsets = clang_tokens_offsets[c];
-            if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
-                index <= token_offsets.second.index - 1) {
-                auto referenced = token.get_cursor().get_referenced();
-                if (referenced)
-                    return Identifier(token.get_spelling(), referenced);
-            }
-        }
-    }
+  if (!parsed)
     return Identifier();
+  auto iter = get_buffer()->get_insert()->get_iter();
+  auto line = static_cast<unsigned>(iter.get_line());
+  auto index = static_cast<unsigned>(iter.get_line_index());
+  for (size_t c = clang_tokens->size() - 1; c != static_cast<size_t>(-1); --c) {
+    auto &token = (*clang_tokens)[c];
+    if (token.is_identifier()) {
+      auto &token_offsets = clang_tokens_offsets[c];
+      if (line == token_offsets.first.line - 1 && index >= token_offsets.first.index - 1 &&
+          index <= token_offsets.second.index - 1) {
+        auto referenced = token.get_cursor().get_referenced();
+        if (referenced)
+          return Identifier(token.get_spelling(), referenced);
+      }
+    }
+  }
+  return Identifier();
 }
 
 void Source::ClangViewRefactor::wait_parsing() {
-    std::unique_ptr<Dialog::Message> message;
-    std::vector<Source::ClangView *> clang_views;
-    for (auto &view: views) {
-        if (auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
-            if (!clang_view->parsed && !clang_view->selected_completion_string) {
-                clang_views.emplace_back(clang_view);
-                if (!message)
-                    message = std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing");
-            }
-        }
+  std::unique_ptr<Dialog::Message> message;
+  std::vector<Source::ClangView *> clang_views;
+  for (auto &view: views) {
+    if (auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
+      if (!clang_view->parsed && !clang_view->selected_completion_string) {
+        clang_views.emplace_back(clang_view);
+        if (!message)
+          message = std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing");
+      }
     }
-    if (message) {
-        for (;;) {
-            while (Gtk::Main::events_pending())
-                Gtk::Main::iteration(false);
-            bool all_parsed = true;
-            for (auto &clang_view: clang_views) {
-                if (!clang_view->parsed) {
-                    all_parsed = false;
-                    break;
-                }
-            }
-            if (all_parsed)
-                break;
-            std::this_thread::sleep_for(std::chrono::milliseconds(10));
+  }
+  if (message) {
+    for (;;) {
+      while (Gtk::Main::events_pending())
+        Gtk::Main::iteration(false);
+      bool all_parsed = true;
+      for (auto &clang_view: clang_views) {
+        if (!clang_view->parsed) {
+          all_parsed = false;
+          break;
         }
-        message->hide();
+      }
+      if (all_parsed)
+        break;
+      std::this_thread::sleep_for(std::chrono::milliseconds(10));
     }
+    message->hide();
+  }
 }
 
 void Source::ClangViewRefactor::tag_similar_identifiers(const Identifier &identifier) {
-    if (parsed) {
-        if (identifier && last_tagged_identifier != identifier) {
-            for (auto &mark: similar_identifiers_marks) {
-                get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
-                get_buffer()->delete_mark(mark.first);
-                get_buffer()->delete_mark(mark.second);
-            }
-            similar_identifiers_marks.clear();
-            auto offsets = clang_tokens->get_similar_token_offsets(identifier.kind, identifier.spelling,
-                                                                   identifier.cursor.get_all_usr_extended());
-            for (auto &offset: offsets) {
-                auto start_iter = get_buffer()->get_iter_at_line_index(offset.first.line - 1, offset.first.index - 1);
-                auto end_iter = get_buffer()->get_iter_at_line_index(offset.second.line - 1, offset.second.index - 1);
-                get_buffer()->apply_tag(similar_identifiers_tag, start_iter, end_iter);
-                similar_identifiers_marks.emplace_back(get_buffer()->create_mark(start_iter),
-                                                       get_buffer()->create_mark(end_iter));
-            }
-            last_tagged_identifier = identifier;
-        }
+  if (parsed) {
+    if (identifier && last_tagged_identifier != identifier) {
+      for (auto &mark: similar_identifiers_marks) {
+        get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
+        get_buffer()->delete_mark(mark.first);
+        get_buffer()->delete_mark(mark.second);
+      }
+      similar_identifiers_marks.clear();
+      auto offsets = clang_tokens->get_similar_token_offsets(identifier.kind, identifier.spelling,
+                                                             identifier.cursor.get_all_usr_extended());
+      for (auto &offset: offsets) {
+        auto start_iter = get_buffer()->get_iter_at_line_index(offset.first.line - 1, offset.first.index - 1);
+        auto end_iter = get_buffer()->get_iter_at_line_index(offset.second.line - 1, offset.second.index - 1);
+        get_buffer()->apply_tag(similar_identifiers_tag, start_iter, end_iter);
+        similar_identifiers_marks.emplace_back(get_buffer()->create_mark(start_iter),
+                                               get_buffer()->create_mark(end_iter));
+      }
+      last_tagged_identifier = identifier;
     }
-    if (!identifier && last_tagged_identifier) {
-        for (auto &mark: similar_identifiers_marks) {
-            get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
-            get_buffer()->delete_mark(mark.first);
-            get_buffer()->delete_mark(mark.second);
-        }
-        similar_identifiers_marks.clear();
-        last_tagged_identifier = Identifier();
+  }
+  if (!identifier && last_tagged_identifier) {
+    for (auto &mark: similar_identifiers_marks) {
+      get_buffer()->remove_tag(similar_identifiers_tag, mark.first->get_iter(), mark.second->get_iter());
+      get_buffer()->delete_mark(mark.first);
+      get_buffer()->delete_mark(mark.second);
     }
+    similar_identifiers_marks.clear();
+    last_tagged_identifier = Identifier();
+  }
 }
 
 
 Source::ClangView::ClangView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) :
-        BaseView(file_path, language), ClangViewParse(file_path, language), ClangViewAutocomplete(file_path, language),
-        ClangViewRefactor(file_path, language) {
-    if (language) {
-        get_source_buffer()->set_highlight_syntax(true);
-        get_source_buffer()->set_language(language);
-    }
-
-    do_delete_object.connect([this]() {
-        if (delete_thread.joinable())
-            delete_thread.join();
-        delete this;
-    });
+    BaseView(file_path, language), ClangViewParse(file_path, language), ClangViewAutocomplete(file_path, language),
+    ClangViewRefactor(file_path, language) {
+  if (language) {
+    get_source_buffer()->set_highlight_syntax(true);
+    get_source_buffer()->set_language(language);
+  }
+
+  do_delete_object.connect([this]() {
+    if (delete_thread.joinable())
+      delete_thread.join();
+    delete this;
+  });
 }
 
 void Source::ClangView::full_reparse() {
-    auto print_error = [this] {
-        Terminal::get().async_print(
-                "Error: failed to reparse " + file_path.string() + ". Please reopen the file manually.\n", true);
-    };
-    full_reparse_needed = false;
-    if (full_reparse_running) {
+  auto print_error = [this] {
+    Terminal::get().async_print(
+        "Error: failed to reparse " + file_path.string() + ". Please reopen the file manually.\n", true);
+  };
+  full_reparse_needed = false;
+  if (full_reparse_running) {
+    print_error();
+    return;
+  } else {
+    auto expected = ParseState::PROCESSING;
+    if (!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) {
+      expected = ParseState::RESTARTING;
+      if (!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) {
         print_error();
         return;
-    } else {
-        auto expected = ParseState::PROCESSING;
-        if (!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) {
-            expected = ParseState::RESTARTING;
-            if (!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) {
-                print_error();
-                return;
-            }
-        }
-        autocomplete.state = Autocomplete::State::IDLE;
-        soft_reparse_needed = false;
-        full_reparse_running = true;
-        if (full_reparse_thread.joinable())
-            full_reparse_thread.join();
-        full_reparse_thread = std::thread([this]() {
-            if (parse_thread.joinable())
-                parse_thread.join();
-            if (autocomplete.thread.joinable())
-                autocomplete.thread.join();
-            dispatcher.post([this] {
-                parse_initialize();
-                full_reparse_running = false;
-            });
-        });
+      }
     }
+    autocomplete.state = Autocomplete::State::IDLE;
+    soft_reparse_needed = false;
+    full_reparse_running = true;
+    if (full_reparse_thread.joinable())
+      full_reparse_thread.join();
+    full_reparse_thread = std::thread([this]() {
+      if (parse_thread.joinable())
+        parse_thread.join();
+      if (autocomplete.thread.joinable())
+        autocomplete.thread.join();
+      dispatcher.post([this] {
+        parse_initialize();
+        full_reparse_running = false;
+      });
+    });
+  }
 }
 
 void Source::ClangView::async_delete() {
-    delayed_show_arguments_connection.disconnect();
-    delayed_tag_similar_identifiers_connection.disconnect();
-
-    views.erase(this);
-    std::set<boost::filesystem::path> project_paths_in_use;
-    for (auto &view: views) {
-        if (dynamic_cast<ClangView *>(view)) {
-            auto build = Project::Build::create(view->file_path);
-            if (!build->project_path.empty())
-                project_paths_in_use.emplace(build->project_path);
-        }
-    }
-    Usages::Clang::erase_unused_caches(project_paths_in_use);
-    Usages::Clang::cache_in_progress();
-
-    if (!get_buffer()->get_modified()) {
-        if (full_reparse_needed)
-            full_reparse();
-        else if (soft_reparse_needed)
-            soft_reparse();
+  delayed_show_arguments_connection.disconnect();
+  delayed_tag_similar_identifiers_connection.disconnect();
+
+  views.erase(this);
+  std::set<boost::filesystem::path> project_paths_in_use;
+  for (auto &view: views) {
+    if (dynamic_cast<ClangView *>(view)) {
+      auto build = Project::Build::create(view->file_path);
+      if (!build->project_path.empty())
+        project_paths_in_use.emplace(build->project_path);
     }
+  }
+  Usages::Clang::erase_unused_caches(project_paths_in_use);
+  Usages::Clang::cache_in_progress();
+
+  if (!get_buffer()->get_modified()) {
+    if (full_reparse_needed)
+      full_reparse();
+    else if (soft_reparse_needed)
+      soft_reparse();
+  }
+
+  auto before_parse_time = std::time(nullptr);
+  delete_thread = std::thread([this, before_parse_time, project_paths_in_use = std::move(project_paths_in_use)] {
+    while (!parsed)
+      std::this_thread::sleep_for(std::chrono::milliseconds(10));
 
-    auto before_parse_time = std::time(nullptr);
-    delete_thread = std::thread([this, before_parse_time, project_paths_in_use = std::move(project_paths_in_use)] {
-        while (!parsed)
-            std::this_thread::sleep_for(std::chrono::milliseconds(10));
-
-        delayed_reparse_connection.disconnect();
-        parse_state = ParseState::STOP;
-        dispatcher.disconnect();
-
-        if (get_buffer()->get_modified()) {
-            std::ifstream stream(file_path.string(), std::ios::binary);
-            if (stream) {
-                std::string buffer;
-                buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
-                if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr"))
-                    clangmm::remove_include_guard(buffer);
-                clang_tu->reparse(buffer);
-                clang_tokens = clang_tu->get_tokens();
-            } else
-                clang_tokens = nullptr;
-        }
+    delayed_reparse_connection.disconnect();
+    parse_state = ParseState::STOP;
+    dispatcher.disconnect();
+
+    if (get_buffer()->get_modified()) {
+      std::ifstream stream(file_path.string(), std::ios::binary);
+      if (stream) {
+        std::string buffer;
+        buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
+        if (language && (language->get_id() == "chdr" || language->get_id() == "cpphdr"))
+          clangmm::remove_include_guard(buffer);
+        clang_tu->reparse(buffer);
+        clang_tokens = clang_tu->get_tokens();
+      } else
+        clang_tokens = nullptr;
+    }
 
-        if (clang_tokens) {
-            auto build = Project::Build::create(file_path);
-            Usages::Clang::cache(build->project_path, build->get_default_path(), file_path, before_parse_time,
-                                 project_paths_in_use, clang_tu.get(), clang_tokens.get());
-        }
+    if (clang_tokens) {
+      auto build = Project::Build::create(file_path);
+      Usages::Clang::cache(build->project_path, build->get_default_path(), file_path, before_parse_time,
+                           project_paths_in_use, clang_tu.get(), clang_tokens.get());
+    }
 
-        if (full_reparse_thread.joinable())
-            full_reparse_thread.join();
-        if (parse_thread.joinable())
-            parse_thread.join();
-        if (autocomplete.thread.joinable())
-            autocomplete.thread.join();
-        do_delete_object();
-    });
+    if (full_reparse_thread.joinable())
+      full_reparse_thread.join();
+    if (parse_thread.joinable())
+      parse_thread.join();
+    if (autocomplete.thread.joinable())
+      autocomplete.thread.join();
+    do_delete_object();
+  });
 }
diff --git a/src/source_clang.h b/src/source_clang.h
index b4184525..5ae25f87 100644
--- a/src/source_clang.h
+++ b/src/source_clang.h
@@ -11,134 +11,134 @@
 #include "autocomplete.h"
 
 namespace Source {
-    class ClangViewParse : public View {
-    protected:
-        enum class ParseState {
-            PROCESSING, RESTARTING, STOP
-        };
-        enum class ParseProcessState {
-            IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING
-        };
+  class ClangViewParse : public View {
+  protected:
+    enum class ParseState {
+      PROCESSING, RESTARTING, STOP
+    };
+    enum class ParseProcessState {
+      IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING
+    };
 
-    public:
-        ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+  public:
+    ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
 
-        bool save() override;
+    bool save() override;
 
-        void configure() override;
+    void configure() override;
 
-        void soft_reparse(bool delayed = false) override;
+    void soft_reparse(bool delayed = false) override;
 
-    protected:
-        Dispatcher dispatcher;
+  protected:
+    Dispatcher dispatcher;
 
-        void parse_initialize();
+    void parse_initialize();
 
-        std::unique_ptr<clangmm::TranslationUnit> clang_tu;
-        std::unique_ptr<clangmm::Tokens> clang_tokens;
-        std::vector<std::pair<clangmm::Offset, clangmm::Offset>> clang_tokens_offsets;
-        sigc::connection delayed_reparse_connection;
+    std::unique_ptr<clangmm::TranslationUnit> clang_tu;
+    std::unique_ptr<clangmm::Tokens> clang_tokens;
+    std::vector<std::pair<clangmm::Offset, clangmm::Offset>> clang_tokens_offsets;
+    sigc::connection delayed_reparse_connection;
 
-        void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
+    void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
 
-        std::vector<FixIt> fix_its;
+    std::vector<FixIt> fix_its;
 
-        std::thread parse_thread;
-        std::mutex parse_mutex;
-        std::atomic<ParseState> parse_state;
-        std::atomic<ParseProcessState> parse_process_state;
+    std::thread parse_thread;
+    std::mutex parse_mutex;
+    std::atomic<ParseState> parse_state;
+    std::atomic<ParseProcessState> parse_process_state;
 
-        CXCompletionString selected_completion_string = nullptr;
-    private:
-        Glib::ustring parse_thread_buffer;
+    CXCompletionString selected_completion_string = nullptr;
+  private:
+    Glib::ustring parse_thread_buffer;
 
-        static const std::unordered_map<int, std::string> &clang_types();
+    static const std::unordered_map<int, std::string> &clang_types();
 
-        void update_syntax();
+    void update_syntax();
 
-        std::set<std::string> last_syntax_tags;
+    std::set<std::string> last_syntax_tags;
 
-        void update_diagnostics();
+    void update_diagnostics();
 
-        std::vector<clangmm::Diagnostic> clang_diagnostics;
+    std::vector<clangmm::Diagnostic> clang_diagnostics;
 
-        static clangmm::Index clang_index;
-    };
+    static clangmm::Index clang_index;
+  };
 
-    class ClangViewAutocomplete : public virtual ClangViewParse {
-    public:
-        ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+  class ClangViewAutocomplete : public virtual ClangViewParse {
+  public:
+    ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
 
-    protected:
-        Autocomplete autocomplete;
-        std::unique_ptr<clangmm::CodeCompleteResults> code_complete_results;
-        std::vector<CXCompletionString> completion_strings;
-        sigc::connection delayed_show_arguments_connection;
-    private:
-        bool is_possible_parameter();
+  protected:
+    Autocomplete autocomplete;
+    std::unique_ptr<clangmm::CodeCompleteResults> code_complete_results;
+    std::vector<CXCompletionString> completion_strings;
+    sigc::connection delayed_show_arguments_connection;
+  private:
+    bool is_possible_parameter();
 
-        bool show_arguments;
+    bool show_arguments;
 
-        const std::unordered_map<std::string, std::string> &autocomplete_manipulators_map();
-    };
+    const std::unordered_map<std::string, std::string> &autocomplete_manipulators_map();
+  };
 
-    class ClangViewRefactor : public virtual ClangViewParse {
-        class Identifier {
-        public:
-            Identifier(const std::string &spelling, const clangmm::Cursor &cursor)
-                    : kind(cursor.get_kind()), spelling(spelling), usr_extended(cursor.get_usr_extended()),
-                      cursor(cursor) {}
+  class ClangViewRefactor : public virtual ClangViewParse {
+    class Identifier {
+    public:
+      Identifier(const std::string &spelling, const clangmm::Cursor &cursor)
+          : kind(cursor.get_kind()), spelling(spelling), usr_extended(cursor.get_usr_extended()),
+            cursor(cursor) {}
 
-            Identifier() : kind(static_cast<clangmm::Cursor::Kind>(0)) {}
+      Identifier() : kind(static_cast<clangmm::Cursor::Kind>(0)) {}
 
-            operator bool() const { return static_cast<int>(kind) != 0; }
+      operator bool() const { return static_cast<int>(kind) != 0; }
 
-            bool operator==(const Identifier &rhs) const {
-                return spelling == rhs.spelling && usr_extended == rhs.usr_extended;
-            }
+      bool operator==(const Identifier &rhs) const {
+        return spelling == rhs.spelling && usr_extended == rhs.usr_extended;
+      }
 
-            bool operator!=(const Identifier &rhs) const { return !(*this == rhs); }
+      bool operator!=(const Identifier &rhs) const { return !(*this == rhs); }
 
-            bool operator<(const Identifier &rhs) const {
-                return spelling < rhs.spelling || (spelling == rhs.spelling && usr_extended < rhs.usr_extended);
-            }
+      bool operator<(const Identifier &rhs) const {
+        return spelling < rhs.spelling || (spelling == rhs.spelling && usr_extended < rhs.usr_extended);
+      }
 
-            clangmm::Cursor::Kind kind;
-            std::string spelling;
-            std::string usr_extended;
-            clangmm::Cursor cursor;
-        };
+      clangmm::Cursor::Kind kind;
+      std::string spelling;
+      std::string usr_extended;
+      clangmm::Cursor cursor;
+    };
 
-    public:
-        ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+  public:
+    ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
 
-    protected:
-        sigc::connection delayed_tag_similar_identifiers_connection;
-    private:
-        Identifier get_identifier();
+  protected:
+    sigc::connection delayed_tag_similar_identifiers_connection;
+  private:
+    Identifier get_identifier();
 
-        void wait_parsing();
+    void wait_parsing();
 
-        std::list<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > similar_identifiers_marks;
+    std::list<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > similar_identifiers_marks;
 
-        void tag_similar_identifiers(const Identifier &identifier);
+    void tag_similar_identifiers(const Identifier &identifier);
 
-        Glib::RefPtr<Gtk::TextTag> similar_identifiers_tag;
-        Identifier last_tagged_identifier;
-    };
+    Glib::RefPtr<Gtk::TextTag> similar_identifiers_tag;
+    Identifier last_tagged_identifier;
+  };
 
-    class ClangView : public ClangViewAutocomplete, public ClangViewRefactor {
-    public:
-        ClangView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+  class ClangView : public ClangViewAutocomplete, public ClangViewRefactor {
+  public:
+    ClangView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
 
-        void full_reparse() override;
+    void full_reparse() override;
 
-        void async_delete();
+    void async_delete();
 
-    private:
-        Glib::Dispatcher do_delete_object;
-        std::thread delete_thread;
-        std::thread full_reparse_thread;
-        bool full_reparse_running = false;
-    };
+  private:
+    Glib::Dispatcher do_delete_object;
+    std::thread delete_thread;
+    std::thread full_reparse_thread;
+    bool full_reparse_running = false;
+  };
 }
diff --git a/src/source_diff.cc b/src/source_diff.cc
index e0bec547..535ef89d 100644
--- a/src/source_diff.cc
+++ b/src/source_diff.cc
@@ -6,366 +6,366 @@
 #include <boost/version.hpp>
 
 Source::DiffView::Renderer::Renderer() : Gsv::GutterRenderer() {
-    set_padding(4, 0);
+  set_padding(4, 0);
 }
 
 void
 Source::DiffView::Renderer::draw_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area,
                                        const Gdk::Rectangle &cell_area, Gtk::TextIter &start, Gtk::TextIter &end,
                                        Gsv::GutterRendererState p6) {
-    if (start.has_tag(tag_added) || end.has_tag(tag_added)) {
-        cr->set_source_rgba(0.0, 1.0, 0.0, 0.5);
-        cr->rectangle(cell_area.get_x(), cell_area.get_y(), 4, cell_area.get_height());
-        cr->fill();
-    } else if (start.has_tag(tag_modified) || end.has_tag(tag_modified)) {
-        cr->set_source_rgba(0.9, 0.9, 0.0, 0.75);
-        cr->rectangle(cell_area.get_x(), cell_area.get_y(), 4, cell_area.get_height());
-        cr->fill();
-    }
-    if (start.has_tag(tag_removed_below) || end.has_tag(tag_removed_below)) {
-        cr->set_source_rgba(0.75, 0.0, 0.0, 0.5);
-        cr->rectangle(cell_area.get_x() - 4, cell_area.get_y() + cell_area.get_height() - 2, 8, 2);
-        cr->fill();
-    }
-    if (start.has_tag(tag_removed_above) || end.has_tag(tag_removed_above)) {
-        cr->set_source_rgba(0.75, 0.0, 0.0, 0.5);
-        cr->rectangle(cell_area.get_x() - 4, cell_area.get_y(), 8, 2);
-        cr->fill();
-    }
+  if (start.has_tag(tag_added) || end.has_tag(tag_added)) {
+    cr->set_source_rgba(0.0, 1.0, 0.0, 0.5);
+    cr->rectangle(cell_area.get_x(), cell_area.get_y(), 4, cell_area.get_height());
+    cr->fill();
+  } else if (start.has_tag(tag_modified) || end.has_tag(tag_modified)) {
+    cr->set_source_rgba(0.9, 0.9, 0.0, 0.75);
+    cr->rectangle(cell_area.get_x(), cell_area.get_y(), 4, cell_area.get_height());
+    cr->fill();
+  }
+  if (start.has_tag(tag_removed_below) || end.has_tag(tag_removed_below)) {
+    cr->set_source_rgba(0.75, 0.0, 0.0, 0.5);
+    cr->rectangle(cell_area.get_x() - 4, cell_area.get_y() + cell_area.get_height() - 2, 8, 2);
+    cr->fill();
+  }
+  if (start.has_tag(tag_removed_above) || end.has_tag(tag_removed_above)) {
+    cr->set_source_rgba(0.75, 0.0, 0.0, 0.5);
+    cr->rectangle(cell_area.get_x() - 4, cell_area.get_y(), 8, 2);
+    cr->fill();
+  }
 }
 
 Source::DiffView::DiffView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) : BaseView(
-        file_path, language), renderer(new Renderer()) {
-    boost::system::error_code ec;
-    canonical_file_path = boost::filesystem::canonical(file_path, ec);
-    if (ec)
-        canonical_file_path = file_path;
+    file_path, language), renderer(new Renderer()) {
+  boost::system::error_code ec;
+  canonical_file_path = boost::filesystem::canonical(file_path, ec);
+  if (ec)
+    canonical_file_path = file_path;
 
-    renderer->tag_added = get_buffer()->create_tag("git_added");
-    renderer->tag_modified = get_buffer()->create_tag("git_modified");
-    renderer->tag_removed = get_buffer()->create_tag("git_removed");
-    renderer->tag_removed_below = get_buffer()->create_tag();
-    renderer->tag_removed_above = get_buffer()->create_tag();
+  renderer->tag_added = get_buffer()->create_tag("git_added");
+  renderer->tag_modified = get_buffer()->create_tag("git_modified");
+  renderer->tag_removed = get_buffer()->create_tag("git_removed");
+  renderer->tag_removed_below = get_buffer()->create_tag();
+  renderer->tag_removed_above = get_buffer()->create_tag();
 
-    configure();
+  configure();
 }
 
 Source::DiffView::~DiffView() {
-    dispatcher.disconnect();
-    if (repository) {
-        get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->remove(renderer.get());
-        buffer_insert_connection.disconnect();
-        buffer_erase_connection.disconnect();
-        monitor_changed_connection.disconnect();
-        delayed_buffer_changed_connection.disconnect();
-        delayed_monitor_changed_connection.disconnect();
+  dispatcher.disconnect();
+  if (repository) {
+    get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->remove(renderer.get());
+    buffer_insert_connection.disconnect();
+    buffer_erase_connection.disconnect();
+    monitor_changed_connection.disconnect();
+    delayed_buffer_changed_connection.disconnect();
+    delayed_monitor_changed_connection.disconnect();
 
-        parse_stop = true;
-        if (parse_thread.joinable())
-            parse_thread.join();
-    }
+    parse_stop = true;
+    if (parse_thread.joinable())
+      parse_thread.join();
+  }
 }
 
 void Source::DiffView::configure() {
-    if (Config::get().source.show_git_diff) {
-        if (repository)
-            return;
-    } else if (repository) {
-        get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->remove(renderer.get());
-        buffer_insert_connection.disconnect();
-        buffer_erase_connection.disconnect();
-        monitor_changed_connection.disconnect();
-        delayed_buffer_changed_connection.disconnect();
-        delayed_monitor_changed_connection.disconnect();
+  if (Config::get().source.show_git_diff) {
+    if (repository)
+      return;
+  } else if (repository) {
+    get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->remove(renderer.get());
+    buffer_insert_connection.disconnect();
+    buffer_erase_connection.disconnect();
+    monitor_changed_connection.disconnect();
+    delayed_buffer_changed_connection.disconnect();
+    delayed_monitor_changed_connection.disconnect();
 
-        parse_stop = true;
-        if (parse_thread.joinable())
-            parse_thread.join();
-        repository = nullptr;
-        diff = nullptr;
+    parse_stop = true;
+    if (parse_thread.joinable())
+      parse_thread.join();
+    repository = nullptr;
+    diff = nullptr;
 
-        return;
-    } else
-        return;
+    return;
+  } else
+    return;
 
-    try {
-        repository = Git::get_repository(this->file_path.parent_path());
-    }
-    catch (const std::exception &) {
-        return;
-    }
+  try {
+    repository = Git::get_repository(this->file_path.parent_path());
+  }
+  catch (const std::exception &) {
+    return;
+  }
 
-    get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->insert(renderer.get(), -40);
-    parse_state = ParseState::STARTING;
-    parse_stop = false;
-    monitor_changed = false;
+  get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->insert(renderer.get(), -40);
+  parse_state = ParseState::STARTING;
+  parse_stop = false;
+  monitor_changed = false;
 
-    buffer_insert_connection = get_buffer()->signal_insert().connect(
-            [this](const Gtk::TextBuffer::iterator &iter, const Glib::ustring &text, int) {
-                //Do not perform git diff if no newline is added and line is already marked as added
-                if (!iter.starts_line() && iter.has_tag(renderer->tag_added)) {
-                    bool newline = false;
-                    for (auto &c: text.raw()) {
-                        if (c == '\n') {
-                            newline = true;
-                            break;
-                        }
-                    }
-                    if (!newline)
-                        return;
-                }
-                    //Remove tag_removed_above/below if newline is inserted
-                else if (!text.empty() && text[0] == '\n' && iter.has_tag(renderer->tag_removed)) {
-                    auto start_iter = get_buffer()->get_iter_at_line(iter.get_line());
-                    auto end_iter = get_iter_at_line_end(iter.get_line());
-                    end_iter.forward_char();
-                    get_buffer()->remove_tag(renderer->tag_removed_above, start_iter, end_iter);
-                    get_buffer()->remove_tag(renderer->tag_removed_below, start_iter, end_iter);
-                }
-                parse_state = ParseState::IDLE;
-                delayed_buffer_changed_connection.disconnect();
-                delayed_buffer_changed_connection = Glib::signal_timeout().connect([this]() {
-                    parse_state = ParseState::STARTING;
-                    return false;
-                }, 250);
-            }, false);
-
-    buffer_erase_connection = get_buffer()->signal_erase().connect(
-            [this](const Gtk::TextBuffer::iterator &start_iter, const Gtk::TextBuffer::iterator &end_iter) {
-                //Do not perform git diff if start_iter and end_iter is at the same line in addition to the line is tagged added
-                if (start_iter.get_line() == end_iter.get_line() && start_iter.has_tag(renderer->tag_added))
-                    return;
+  buffer_insert_connection = get_buffer()->signal_insert().connect(
+      [this](const Gtk::TextBuffer::iterator &iter, const Glib::ustring &text, int) {
+        //Do not perform git diff if no newline is added and line is already marked as added
+        if (!iter.starts_line() && iter.has_tag(renderer->tag_added)) {
+          bool newline = false;
+          for (auto &c: text.raw()) {
+            if (c == '\n') {
+              newline = true;
+              break;
+            }
+          }
+          if (!newline)
+            return;
+        }
+          //Remove tag_removed_above/below if newline is inserted
+        else if (!text.empty() && text[0] == '\n' && iter.has_tag(renderer->tag_removed)) {
+          auto start_iter = get_buffer()->get_iter_at_line(iter.get_line());
+          auto end_iter = get_iter_at_line_end(iter.get_line());
+          end_iter.forward_char();
+          get_buffer()->remove_tag(renderer->tag_removed_above, start_iter, end_iter);
+          get_buffer()->remove_tag(renderer->tag_removed_below, start_iter, end_iter);
+        }
+        parse_state = ParseState::IDLE;
+        delayed_buffer_changed_connection.disconnect();
+        delayed_buffer_changed_connection = Glib::signal_timeout().connect([this]() {
+          parse_state = ParseState::STARTING;
+          return false;
+        }, 250);
+      }, false);
 
-                parse_state = ParseState::IDLE;
-                delayed_buffer_changed_connection.disconnect();
-                delayed_buffer_changed_connection = Glib::signal_timeout().connect([this]() {
-                    parse_state = ParseState::STARTING;
-                    return false;
-                }, 250);
-            }, false);
+  buffer_erase_connection = get_buffer()->signal_erase().connect(
+      [this](const Gtk::TextBuffer::iterator &start_iter, const Gtk::TextBuffer::iterator &end_iter) {
+        //Do not perform git diff if start_iter and end_iter is at the same line in addition to the line is tagged added
+        if (start_iter.get_line() == end_iter.get_line() && start_iter.has_tag(renderer->tag_added))
+          return;
 
-    monitor_changed_connection = repository->monitor->signal_changed().connect(
-            [this](const Glib::RefPtr<Gio::File> &file,
-                   const Glib::RefPtr<Gio::File> &,
-                   Gio::FileMonitorEvent monitor_event) {
-                if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
-                    delayed_monitor_changed_connection.disconnect();
-                    delayed_monitor_changed_connection = Glib::signal_timeout().connect([this]() {
-                        monitor_changed = true;
-                        parse_state = ParseState::STARTING;
-                        std::unique_lock<std::mutex> lock(parse_mutex);
-                        diff = nullptr;
-                        return false;
-                    }, 500);
-                }
-            });
+        parse_state = ParseState::IDLE;
+        delayed_buffer_changed_connection.disconnect();
+        delayed_buffer_changed_connection = Glib::signal_timeout().connect([this]() {
+          parse_state = ParseState::STARTING;
+          return false;
+        }, 250);
+      }, false);
 
-    parse_thread = std::thread([this]() {
-        std::string status_branch;
-        try {
-            diff = get_diff();
-            status_branch = repository->get_branch();
+  monitor_changed_connection = repository->monitor->signal_changed().connect(
+      [this](const Glib::RefPtr<Gio::File> &file,
+             const Glib::RefPtr<Gio::File> &,
+             Gio::FileMonitorEvent monitor_event) {
+        if (monitor_event != Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+          delayed_monitor_changed_connection.disconnect();
+          delayed_monitor_changed_connection = Glib::signal_timeout().connect([this]() {
+            monitor_changed = true;
+            parse_state = ParseState::STARTING;
+            std::unique_lock<std::mutex> lock(parse_mutex);
+            diff = nullptr;
+            return false;
+          }, 500);
         }
-        catch (const std::exception &) {
-            status_branch = "";
-        }
-        dispatcher.post([this, status_branch = std::move(status_branch)] {
-            this->status_branch = status_branch;
-            if (update_status_branch)
-                update_status_branch(this);
-        });
+      });
 
-        try {
-            while (true) {
-                while (!parse_stop && parse_state != ParseState::STARTING && parse_state != ParseState::PROCESSING)
-                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
-                if (parse_stop)
-                    break;
-                std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-                auto expected = ParseState::STARTING;
-                if (parse_state.compare_exchange_strong(expected, ParseState::PREPROCESSING)) {
-                    dispatcher.post([this] {
-                        auto expected = ParseState::PREPROCESSING;
-                        std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-                        if (parse_lock.try_lock()) {
-                            if (parse_state.compare_exchange_strong(expected, ParseState::PROCESSING))
-                                parse_buffer = get_buffer()->get_text();
-                            parse_lock.unlock();
-                        } else
-                            parse_state.compare_exchange_strong(expected, ParseState::STARTING);
-                    });
-                } else if (parse_state == ParseState::PROCESSING && parse_lock.try_lock()) {
-                    bool expected_monitor_changed = true;
-                    if (monitor_changed.compare_exchange_strong(expected_monitor_changed, false)) {
-                        try {
-                            diff = get_diff();
-                            dispatcher.post([this, status_branch = repository->get_branch()] {
-                                this->status_branch = status_branch;
-                                if (update_status_branch)
-                                    update_status_branch(this);
-                            });
-                        }
-                        catch (const std::exception &) {
-                            dispatcher.post([this] {
-                                get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(),
-                                                         get_buffer()->end());
-                                get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(),
-                                                         get_buffer()->end());
-                                get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(),
-                                                         get_buffer()->end());
-                                get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(),
-                                                         get_buffer()->end());
-                                get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(),
-                                                         get_buffer()->end());
-                                renderer->queue_draw();
-                                this->status_branch = "";
-                                if (update_status_branch)
-                                    update_status_branch(this);
-                            });
-                        }
-                    }
-                    if (diff)
-                        lines = diff->get_lines(parse_buffer.raw());
-                    else {
-                        lines.added.clear();
-                        lines.modified.clear();
-                        lines.removed.clear();
-                    }
-                    auto expected = ParseState::PROCESSING;
-                    if (parse_state.compare_exchange_strong(expected, ParseState::POSTPROCESSING)) {
-                        parse_lock.unlock();
-                        dispatcher.post([this] {
-                            std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
-                            if (parse_lock.try_lock()) {
-                                auto expected = ParseState::POSTPROCESSING;
-                                if (parse_state.compare_exchange_strong(expected, ParseState::IDLE))
-                                    update_lines();
-                            }
-                        });
-                    }
-                }
+  parse_thread = std::thread([this]() {
+    std::string status_branch;
+    try {
+      diff = get_diff();
+      status_branch = repository->get_branch();
+    }
+    catch (const std::exception &) {
+      status_branch = "";
+    }
+    dispatcher.post([this, status_branch = std::move(status_branch)] {
+      this->status_branch = status_branch;
+      if (update_status_branch)
+        update_status_branch(this);
+    });
+
+    try {
+      while (true) {
+        while (!parse_stop && parse_state != ParseState::STARTING && parse_state != ParseState::PROCESSING)
+          std::this_thread::sleep_for(std::chrono::milliseconds(10));
+        if (parse_stop)
+          break;
+        std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+        auto expected = ParseState::STARTING;
+        if (parse_state.compare_exchange_strong(expected, ParseState::PREPROCESSING)) {
+          dispatcher.post([this] {
+            auto expected = ParseState::PREPROCESSING;
+            std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+            if (parse_lock.try_lock()) {
+              if (parse_state.compare_exchange_strong(expected, ParseState::PROCESSING))
+                parse_buffer = get_buffer()->get_text();
+              parse_lock.unlock();
+            } else
+              parse_state.compare_exchange_strong(expected, ParseState::STARTING);
+          });
+        } else if (parse_state == ParseState::PROCESSING && parse_lock.try_lock()) {
+          bool expected_monitor_changed = true;
+          if (monitor_changed.compare_exchange_strong(expected_monitor_changed, false)) {
+            try {
+              diff = get_diff();
+              dispatcher.post([this, status_branch = repository->get_branch()] {
+                this->status_branch = status_branch;
+                if (update_status_branch)
+                  update_status_branch(this);
+              });
             }
-        }
-        catch (const std::exception &e) {
-            dispatcher.post([this, e_what = e.what()] {
-                get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(), get_buffer()->end());
-                get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(), get_buffer()->end());
-                get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(), get_buffer()->end());
-                get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
-                get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
+            catch (const std::exception &) {
+              dispatcher.post([this] {
+                get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(),
+                                         get_buffer()->end());
+                get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(),
+                                         get_buffer()->end());
+                get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(),
+                                         get_buffer()->end());
+                get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(),
+                                         get_buffer()->end());
+                get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(),
+                                         get_buffer()->end());
                 renderer->queue_draw();
-                Terminal::get().print(std::string("Error (git): ") + e_what + '\n', true);
+                this->status_branch = "";
+                if (update_status_branch)
+                  update_status_branch(this);
+              });
+            }
+          }
+          if (diff)
+            lines = diff->get_lines(parse_buffer.raw());
+          else {
+            lines.added.clear();
+            lines.modified.clear();
+            lines.removed.clear();
+          }
+          auto expected = ParseState::PROCESSING;
+          if (parse_state.compare_exchange_strong(expected, ParseState::POSTPROCESSING)) {
+            parse_lock.unlock();
+            dispatcher.post([this] {
+              std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
+              if (parse_lock.try_lock()) {
+                auto expected = ParseState::POSTPROCESSING;
+                if (parse_state.compare_exchange_strong(expected, ParseState::IDLE))
+                  update_lines();
+              }
             });
+          }
         }
-    });
+      }
+    }
+    catch (const std::exception &e) {
+      dispatcher.post([this, e_what = e.what()] {
+        get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(), get_buffer()->end());
+        get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(), get_buffer()->end());
+        get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(), get_buffer()->end());
+        get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
+        get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
+        renderer->queue_draw();
+        Terminal::get().print(std::string("Error (git): ") + e_what + '\n', true);
+      });
+    }
+  });
 }
 
 void Source::DiffView::rename(const boost::filesystem::path &path) {
-    Source::BaseView::rename(path);
+  Source::BaseView::rename(path);
 
-    std::lock_guard<std::mutex> lock(canonical_file_path_mutex);
-    boost::system::error_code ec;
-    canonical_file_path = boost::filesystem::canonical(path, ec);
-    if (ec)
-        canonical_file_path = path;
+  std::lock_guard<std::mutex> lock(canonical_file_path_mutex);
+  boost::system::error_code ec;
+  canonical_file_path = boost::filesystem::canonical(path, ec);
+  if (ec)
+    canonical_file_path = path;
 }
 
 void Source::DiffView::git_goto_next_diff() {
-    auto iter = get_buffer()->get_insert()->get_iter();
-    auto insert_iter = iter;
-    bool wrapped = false;
-    iter.forward_char();
-    for (;;) {
-        auto toggled_tags = iter.get_toggled_tags();
-        for (auto &toggled_tag: toggled_tags) {
-            if (toggled_tag->property_name() == "git_added" ||
-                toggled_tag->property_name() == "git_modified" ||
-                toggled_tag->property_name() == "git_removed") {
-                get_buffer()->place_cursor(iter);
-                scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-                return;
-            }
-        }
-        if (wrapped && (iter == insert_iter || iter == get_buffer()->end()))
-            break;
-        if (!wrapped && iter == get_buffer()->end()) {
-            iter = get_buffer()->begin();
-            wrapped = true;
-        } else
-            iter.forward_char();
+  auto iter = get_buffer()->get_insert()->get_iter();
+  auto insert_iter = iter;
+  bool wrapped = false;
+  iter.forward_char();
+  for (;;) {
+    auto toggled_tags = iter.get_toggled_tags();
+    for (auto &toggled_tag: toggled_tags) {
+      if (toggled_tag->property_name() == "git_added" ||
+          toggled_tag->property_name() == "git_modified" ||
+          toggled_tag->property_name() == "git_removed") {
+        get_buffer()->place_cursor(iter);
+        scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+        return;
+      }
     }
-    Info::get().print("No changes found in current buffer");
+    if (wrapped && (iter == insert_iter || iter == get_buffer()->end()))
+      break;
+    if (!wrapped && iter == get_buffer()->end()) {
+      iter = get_buffer()->begin();
+      wrapped = true;
+    } else
+      iter.forward_char();
+  }
+  Info::get().print("No changes found in current buffer");
 }
 
 std::string Source::DiffView::git_get_diff_details() {
-    std::string details;
-    if (diff) {
-        auto line_nr = get_buffer()->get_insert()->get_iter().get_line();
-        auto iter = get_buffer()->get_iter_at_line(line_nr);
-        if (iter.has_tag(renderer->tag_removed_above))
-            --line_nr;
-        std::unique_lock<std::mutex> lock(parse_mutex);
-        parse_buffer = get_buffer()->get_text();
-        details = diff->get_details(parse_buffer.raw(), line_nr);
-    }
-    if (details.empty())
-        Info::get().print("No changes found at current line");
-    return details;
+  std::string details;
+  if (diff) {
+    auto line_nr = get_buffer()->get_insert()->get_iter().get_line();
+    auto iter = get_buffer()->get_iter_at_line(line_nr);
+    if (iter.has_tag(renderer->tag_removed_above))
+      --line_nr;
+    std::unique_lock<std::mutex> lock(parse_mutex);
+    parse_buffer = get_buffer()->get_text();
+    details = diff->get_details(parse_buffer.raw(), line_nr);
+  }
+  if (details.empty())
+    Info::get().print("No changes found at current line");
+  return details;
 }
 
 ///Return repository diff instance. Throws exception on error
 std::unique_ptr<Git::Repository::Diff> Source::DiffView::get_diff() {
-    auto work_path = filesystem::get_normal_path(repository->get_work_path());
-    boost::filesystem::path relative_path;
-    {
-        std::unique_lock<std::mutex> lock(canonical_file_path_mutex);
-        relative_path = filesystem::get_relative_path(canonical_file_path, work_path);
-        if (relative_path.empty())
-            throw std::runtime_error("not a relative path");
-    }
-    return std::make_unique<Git::Repository::Diff>(repository->get_diff(relative_path));
+  auto work_path = filesystem::get_normal_path(repository->get_work_path());
+  boost::filesystem::path relative_path;
+  {
+    std::unique_lock<std::mutex> lock(canonical_file_path_mutex);
+    relative_path = filesystem::get_relative_path(canonical_file_path, work_path);
+    if (relative_path.empty())
+      throw std::runtime_error("not a relative path");
+  }
+  return std::make_unique<Git::Repository::Diff>(repository->get_diff(relative_path));
 }
 
 void Source::DiffView::update_lines() {
-    get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(), get_buffer()->end());
-    get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(), get_buffer()->end());
-    get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(), get_buffer()->end());
-    get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
-    get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
+  get_buffer()->remove_tag(renderer->tag_added, get_buffer()->begin(), get_buffer()->end());
+  get_buffer()->remove_tag(renderer->tag_modified, get_buffer()->begin(), get_buffer()->end());
+  get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(), get_buffer()->end());
+  get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
+  get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
 
-    for (auto &added: lines.added) {
-        auto start_iter = get_buffer()->get_iter_at_line(added.first);
-        auto end_iter = get_iter_at_line_end(added.second - 1);
-        end_iter.forward_char();
-        get_buffer()->apply_tag(renderer->tag_added, start_iter, end_iter);
-    }
-    for (auto &modified: lines.modified) {
-        auto start_iter = get_buffer()->get_iter_at_line(modified.first);
-        auto end_iter = get_iter_at_line_end(modified.second - 1);
-        end_iter.forward_char();
-        get_buffer()->apply_tag(renderer->tag_modified, start_iter, end_iter);
+  for (auto &added: lines.added) {
+    auto start_iter = get_buffer()->get_iter_at_line(added.first);
+    auto end_iter = get_iter_at_line_end(added.second - 1);
+    end_iter.forward_char();
+    get_buffer()->apply_tag(renderer->tag_added, start_iter, end_iter);
+  }
+  for (auto &modified: lines.modified) {
+    auto start_iter = get_buffer()->get_iter_at_line(modified.first);
+    auto end_iter = get_iter_at_line_end(modified.second - 1);
+    end_iter.forward_char();
+    get_buffer()->apply_tag(renderer->tag_modified, start_iter, end_iter);
+  }
+  for (auto &line_nr: lines.removed) {
+    Gtk::TextIter removed_start, removed_end;
+    if (line_nr >= 0) {
+      auto start_iter = get_buffer()->get_iter_at_line(line_nr);
+      removed_start = start_iter;
+      auto end_iter = get_iter_at_line_end(line_nr);
+      end_iter.forward_char();
+      removed_end = end_iter;
+      get_buffer()->apply_tag(renderer->tag_removed_below, start_iter, end_iter);
     }
-    for (auto &line_nr: lines.removed) {
-        Gtk::TextIter removed_start, removed_end;
-        if (line_nr >= 0) {
-            auto start_iter = get_buffer()->get_iter_at_line(line_nr);
-            removed_start = start_iter;
-            auto end_iter = get_iter_at_line_end(line_nr);
-            end_iter.forward_char();
-            removed_end = end_iter;
-            get_buffer()->apply_tag(renderer->tag_removed_below, start_iter, end_iter);
-        }
-        if (line_nr + 1 < get_buffer()->get_line_count()) {
-            auto start_iter = get_buffer()->get_iter_at_line(line_nr + 1);
-            if (line_nr < 0)
-                removed_start = start_iter;
-            auto end_iter = get_iter_at_line_end(line_nr + 1);
-            end_iter.forward_char();
-            removed_end = end_iter;
-            get_buffer()->apply_tag(renderer->tag_removed_above, start_iter, end_iter);
-        }
-        get_buffer()->apply_tag(renderer->tag_removed, removed_start, removed_end);
+    if (line_nr + 1 < get_buffer()->get_line_count()) {
+      auto start_iter = get_buffer()->get_iter_at_line(line_nr + 1);
+      if (line_nr < 0)
+        removed_start = start_iter;
+      auto end_iter = get_iter_at_line_end(line_nr + 1);
+      end_iter.forward_char();
+      removed_end = end_iter;
+      get_buffer()->apply_tag(renderer->tag_removed_above, start_iter, end_iter);
     }
+    get_buffer()->apply_tag(renderer->tag_removed, removed_start, removed_end);
+  }
 
-    renderer->queue_draw();
+  renderer->queue_draw();
 }
diff --git a/src/source_diff.h b/src/source_diff.h
index 5f48f931..db20c2d7 100644
--- a/src/source_diff.h
+++ b/src/source_diff.h
@@ -11,67 +11,67 @@
 #include "git.h"
 
 namespace Source {
-    class DiffView : virtual public Source::BaseView {
-        enum class ParseState {
-            IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING
-        };
-
-        class Renderer : public Gsv::GutterRenderer {
-        public:
-            Renderer();
-
-            Glib::RefPtr<Gtk::TextTag> tag_added;
-            Glib::RefPtr<Gtk::TextTag> tag_modified;
-            Glib::RefPtr<Gtk::TextTag> tag_removed;
-            Glib::RefPtr<Gtk::TextTag> tag_removed_below;
-            Glib::RefPtr<Gtk::TextTag> tag_removed_above;
-
-        protected:
-            void draw_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area,
-                            const Gdk::Rectangle &cell_area, Gtk::TextIter &start, Gtk::TextIter &end,
-                            Gsv::GutterRendererState p6) override;
-        };
+  class DiffView : virtual public Source::BaseView {
+    enum class ParseState {
+      IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING
+    };
 
+    class Renderer : public Gsv::GutterRenderer {
     public:
-        DiffView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+      Renderer();
+
+      Glib::RefPtr<Gtk::TextTag> tag_added;
+      Glib::RefPtr<Gtk::TextTag> tag_modified;
+      Glib::RefPtr<Gtk::TextTag> tag_removed;
+      Glib::RefPtr<Gtk::TextTag> tag_removed_below;
+      Glib::RefPtr<Gtk::TextTag> tag_removed_above;
+
+    protected:
+      void draw_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area,
+                      const Gdk::Rectangle &cell_area, Gtk::TextIter &start, Gtk::TextIter &end,
+                      Gsv::GutterRendererState p6) override;
+    };
 
-        ~DiffView();
+  public:
+    DiffView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
 
-        void configure() override;
+    ~DiffView();
 
-        void rename(const boost::filesystem::path &path) override;
+    void configure() override;
 
-        void git_goto_next_diff();
+    void rename(const boost::filesystem::path &path) override;
 
-        std::string git_get_diff_details();
+    void git_goto_next_diff();
 
-        /// Use canonical path to follow symbolic links
-        boost::filesystem::path canonical_file_path;
-    private:
-        std::mutex canonical_file_path_mutex;
+    std::string git_get_diff_details();
 
-        std::unique_ptr<Renderer> renderer;
-        Dispatcher dispatcher;
+    /// Use canonical path to follow symbolic links
+    boost::filesystem::path canonical_file_path;
+  private:
+    std::mutex canonical_file_path_mutex;
 
-        std::shared_ptr<Git::Repository> repository;
-        std::unique_ptr<Git::Repository::Diff> diff;
+    std::unique_ptr<Renderer> renderer;
+    Dispatcher dispatcher;
 
-        std::unique_ptr<Git::Repository::Diff> get_diff();
+    std::shared_ptr<Git::Repository> repository;
+    std::unique_ptr<Git::Repository::Diff> diff;
 
-        std::thread parse_thread;
-        std::atomic<ParseState> parse_state;
-        std::mutex parse_mutex;
-        std::atomic<bool> parse_stop;
-        Glib::ustring parse_buffer;
-        sigc::connection buffer_insert_connection;
-        sigc::connection buffer_erase_connection;
-        sigc::connection monitor_changed_connection;
-        sigc::connection delayed_buffer_changed_connection;
-        sigc::connection delayed_monitor_changed_connection;
-        std::atomic<bool> monitor_changed;
+    std::unique_ptr<Git::Repository::Diff> get_diff();
 
-        Git::Repository::Diff::Lines lines;
+    std::thread parse_thread;
+    std::atomic<ParseState> parse_state;
+    std::mutex parse_mutex;
+    std::atomic<bool> parse_stop;
+    Glib::ustring parse_buffer;
+    sigc::connection buffer_insert_connection;
+    sigc::connection buffer_erase_connection;
+    sigc::connection monitor_changed_connection;
+    sigc::connection delayed_buffer_changed_connection;
+    sigc::connection delayed_monitor_changed_connection;
+    std::atomic<bool> monitor_changed;
 
-        void update_lines();
-    };
+    Git::Repository::Diff::Lines lines;
+
+    void update_lines();
+  };
 }
diff --git a/src/source_language_protocol.cc b/src/source_language_protocol.cc
index 68c3b37c..4a140601 100644
--- a/src/source_language_protocol.cc
+++ b/src/source_language_protocol.cc
@@ -18,1535 +18,1535 @@ const bool output_messages_and_errors = false;
 
 LanguageProtocol::Client::Client(std::string root_uri_, std::string language_id_) : root_uri(std::move(root_uri_)),
                                                                                     language_id(
-                                                                                            std::move(language_id_)) {
-    process = std::make_unique<TinyProcessLib::Process>(language_id + "-language-server", root_uri,
-                                                        [this](const char *bytes, size_t n) {
-                                                            server_message_stream.write(bytes, n);
-                                                            parse_server_message();
-                                                        }, [](const char *bytes, size_t n) {
-                std::cerr.write(bytes, n);
-            }, true);
+                                                                                        std::move(language_id_)) {
+  process = std::make_unique<TinyProcessLib::Process>(language_id + "-language-server", root_uri,
+                                                      [this](const char *bytes, size_t n) {
+                                                        server_message_stream.write(bytes, n);
+                                                        parse_server_message();
+                                                      }, [](const char *bytes, size_t n) {
+        std::cerr.write(bytes, n);
+      }, true);
 }
 
 std::shared_ptr<LanguageProtocol::Client>
 LanguageProtocol::Client::get(const boost::filesystem::path &file_path, const std::string &language_id) {
-    std::string root_uri;
-    auto build = Project::Build::create(file_path);
-    if (!build->project_path.empty())
-        root_uri = build->project_path.string();
-    else
-        root_uri = file_path.parent_path().string();
-
-    auto cache_id = root_uri + '|' + language_id;
-
-    static std::unordered_map<std::string, std::weak_ptr<Client>> cache;
-    static std::mutex mutex;
-    std::lock_guard<std::mutex> lock(mutex);
-    auto it = cache.find(cache_id);
-    if (it == cache.end())
-        it = cache.emplace(cache_id, std::weak_ptr<Client>()).first;
-    auto instance = it->second.lock();
-    if (!instance)
-        it->second = instance = std::shared_ptr<Client>(new Client(root_uri, language_id), [](Client *client_ptr) {
-            std::thread delete_thread([client_ptr] {
-                delete client_ptr;
-            });
-            delete_thread.detach();
-        });
-    return instance;
+  std::string root_uri;
+  auto build = Project::Build::create(file_path);
+  if (!build->project_path.empty())
+    root_uri = build->project_path.string();
+  else
+    root_uri = file_path.parent_path().string();
+
+  auto cache_id = root_uri + '|' + language_id;
+
+  static std::unordered_map<std::string, std::weak_ptr<Client>> cache;
+  static std::mutex mutex;
+  std::lock_guard<std::mutex> lock(mutex);
+  auto it = cache.find(cache_id);
+  if (it == cache.end())
+    it = cache.emplace(cache_id, std::weak_ptr<Client>()).first;
+  auto instance = it->second.lock();
+  if (!instance)
+    it->second = instance = std::shared_ptr<Client>(new Client(root_uri, language_id), [](Client *client_ptr) {
+      std::thread delete_thread([client_ptr] {
+        delete client_ptr;
+      });
+      delete_thread.detach();
+    });
+  return instance;
 }
 
 LanguageProtocol::Client::~Client() {
-    std::promise<void> result_processed;
-    write_request(nullptr, "shutdown", "",
-                  [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
-                      if (!error)
-                          this->write_notification("exit", "");
-                      result_processed.set_value();
-                  });
-    result_processed.get_future().get();
-
-    std::unique_lock<std::mutex> lock(timeout_threads_mutex);
-    for (auto &thread: timeout_threads)
-        thread.join();
-
-    int exit_status = -1;
-    for (size_t c = 0; c < 20; ++c) {
-        std::this_thread::sleep_for(std::chrono::milliseconds(500));
-        if (process->try_get_exit_status(exit_status))
-            break;
-    }
-    if (output_messages_and_errors)
-        std::cout << "Language server exit status: " << exit_status << std::endl;
-    if (exit_status == -1)
-        process->kill();
+  std::promise<void> result_processed;
+  write_request(nullptr, "shutdown", "",
+                [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
+                  if (!error)
+                    this->write_notification("exit", "");
+                  result_processed.set_value();
+                });
+  result_processed.get_future().get();
+
+  std::unique_lock<std::mutex> lock(timeout_threads_mutex);
+  for (auto &thread: timeout_threads)
+    thread.join();
+
+  int exit_status = -1;
+  for (size_t c = 0; c < 20; ++c) {
+    std::this_thread::sleep_for(std::chrono::milliseconds(500));
+    if (process->try_get_exit_status(exit_status))
+      break;
+  }
+  if (output_messages_and_errors)
+    std::cout << "Language server exit status: " << exit_status << std::endl;
+  if (exit_status == -1)
+    process->kill();
 }
 
 LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::LanguageProtocolView *view) {
-    if (view) {
-        std::unique_lock<std::mutex> lock(views_mutex);
-        views.emplace(view);
-    }
+  if (view) {
+    std::unique_lock<std::mutex> lock(views_mutex);
+    views.emplace(view);
+  }
 
-    std::lock_guard<std::mutex> lock(initialize_mutex);
-
-    if (initialized)
-        return capabilities;
-
-    std::promise<void> result_processed;
-    write_request(nullptr, "initialize",
-                  "\"processId\":" + std::to_string(process->get_id()) + ",\"rootUri\":\"file://" + root_uri +
-                  "\",\"capabilities\":{\"workspace\":{\"didChangeConfiguration\":{\"dynamicRegistration\":true},\"didChangeWatchedFiles\":{\"dynamicRegistration\":true},\"symbol\":{\"dynamicRegistration\":true},\"executeCommand\":{\"dynamicRegistration\":true}},\"textDocument\":{\"synchronization\":{\"dynamicRegistration\":true,\"willSave\":true,\"willSaveWaitUntil\":true,\"didSave\":true},\"completion\":{\"dynamicRegistration\":true,\"completionItem\":{\"snippetSupport\":true}},\"hover\":{\"dynamicRegistration\":true},\"signatureHelp\":{\"dynamicRegistration\":true},\"definition\":{\"dynamicRegistration\":true},\"references\":{\"dynamicRegistration\":true},\"documentHighlight\":{\"dynamicRegistration\":true},\"documentSymbol\":{\"dynamicRegistration\":true},\"codeAction\":{\"dynamicRegistration\":true},\"codeLens\":{\"dynamicRegistration\":true},\"formatting\":{\"dynamicRegistration\":true},\"rangeFormatting\":{\"dynamicRegistration\":true},\"onTypeFormatting\":{\"dynamicRegistration\":true},\"rename\":{\"dynamicRegistration\":true},\"documentLink\":{\"dynamicRegistration\":true}}},\"initializationOptions\":{\"omitInitBuild\":true},\"trace\":\"off\"",
-                  [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
-                      if (!error) {
-                          auto capabilities_pt = result.find("capabilities");
-                          if (capabilities_pt != result.not_found()) {
-                              capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->second.get<unsigned>(
-                                      "textDocumentSync", 0));
-                              capabilities.hover = capabilities_pt->second.get<bool>("hoverProvider", false);
-                              capabilities.completion = capabilities_pt->second.find("completionProvider") !=
-                                                        capabilities_pt->second.not_found() ? true : false;
-                              capabilities.definition = capabilities_pt->second.get<bool>("definitionProvider", false);
-                              capabilities.references = capabilities_pt->second.get<bool>("referencesProvider", false);
-                              capabilities.document_highlight = capabilities_pt->second.get<bool>(
-                                      "documentHighlightProvider", false);
-                              capabilities.workspace_symbol = capabilities_pt->second.get<bool>(
-                                      "workspaceSymbolProvider", false);
-                              capabilities.document_formatting = capabilities_pt->second.get<bool>(
-                                      "documentFormattingProvider", false);
-                              capabilities.document_range_formatting = capabilities_pt->second.get<bool>(
-                                      "documentRangeFormattingProvider", false);
-                              capabilities.rename = capabilities_pt->second.get<bool>("renameProvider", false);
-                          }
-
-                          write_notification("initialized", "");
-                          if (language_id == "rust")
-                              write_notification("workspace/didChangeConfiguration",
-                                                 "\"settings\":{\"rust\":{\"sysroot\":null,\"target\":null,\"rustflags\":null,\"clear_env_rust_log\":true,\"build_lib\":null,\"build_bin\":null,\"cfg_test\":false,\"unstable_features\":false,\"wait_to_build\":500,\"show_warnings\":true,\"goto_def_racer_fallback\":false,\"use_crate_blacklist\":true,\"build_on_save\":false,\"workspace_mode\":true,\"analyze_package\":null,\"features\":[],\"all_features\":false,\"no_default_features\":false}}");
-                      }
-                      result_processed.set_value();
-                  });
-    result_processed.get_future().get();
+  std::lock_guard<std::mutex> lock(initialize_mutex);
 
-    initialized = true;
+  if (initialized)
     return capabilities;
+
+  std::promise<void> result_processed;
+  write_request(nullptr, "initialize",
+                "\"processId\":" + std::to_string(process->get_id()) + ",\"rootUri\":\"file://" + root_uri +
+                "\",\"capabilities\":{\"workspace\":{\"didChangeConfiguration\":{\"dynamicRegistration\":true},\"didChangeWatchedFiles\":{\"dynamicRegistration\":true},\"symbol\":{\"dynamicRegistration\":true},\"executeCommand\":{\"dynamicRegistration\":true}},\"textDocument\":{\"synchronization\":{\"dynamicRegistration\":true,\"willSave\":true,\"willSaveWaitUntil\":true,\"didSave\":true},\"completion\":{\"dynamicRegistration\":true,\"completionItem\":{\"snippetSupport\":true}},\"hover\":{\"dynamicRegistration\":true},\"signatureHelp\":{\"dynamicRegistration\":true},\"definition\":{\"dynamicRegistration\":true},\"references\":{\"dynamicRegistration\":true},\"documentHighlight\":{\"dynamicRegistration\":true},\"documentSymbol\":{\"dynamicRegistration\":true},\"codeAction\":{\"dynamicRegistration\":true},\"codeLens\":{\"dynamicRegistration\":true},\"formatting\":{\"dynamicRegistration\":true},\"rangeFormatting\":{\"dynamicRegistration\":true},\"onTypeFormatting\":{\"dynamicRegistration\":true},\"rename\":{\"dynamicRegistration\":true},\"documentLink\":{\"dynamicRegistration\":true}}},\"initializationOptions\":{\"omitInitBuild\":true},\"trace\":\"off\"",
+                [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
+                  if (!error) {
+                    auto capabilities_pt = result.find("capabilities");
+                    if (capabilities_pt != result.not_found()) {
+                      capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->second.get<unsigned>(
+                          "textDocumentSync", 0));
+                      capabilities.hover = capabilities_pt->second.get<bool>("hoverProvider", false);
+                      capabilities.completion = capabilities_pt->second.find("completionProvider") !=
+                                                capabilities_pt->second.not_found() ? true : false;
+                      capabilities.definition = capabilities_pt->second.get<bool>("definitionProvider", false);
+                      capabilities.references = capabilities_pt->second.get<bool>("referencesProvider", false);
+                      capabilities.document_highlight = capabilities_pt->second.get<bool>(
+                          "documentHighlightProvider", false);
+                      capabilities.workspace_symbol = capabilities_pt->second.get<bool>(
+                          "workspaceSymbolProvider", false);
+                      capabilities.document_formatting = capabilities_pt->second.get<bool>(
+                          "documentFormattingProvider", false);
+                      capabilities.document_range_formatting = capabilities_pt->second.get<bool>(
+                          "documentRangeFormattingProvider", false);
+                      capabilities.rename = capabilities_pt->second.get<bool>("renameProvider", false);
+                    }
+
+                    write_notification("initialized", "");
+                    if (language_id == "rust")
+                      write_notification("workspace/didChangeConfiguration",
+                                         "\"settings\":{\"rust\":{\"sysroot\":null,\"target\":null,\"rustflags\":null,\"clear_env_rust_log\":true,\"build_lib\":null,\"build_bin\":null,\"cfg_test\":false,\"unstable_features\":false,\"wait_to_build\":500,\"show_warnings\":true,\"goto_def_racer_fallback\":false,\"use_crate_blacklist\":true,\"build_on_save\":false,\"workspace_mode\":true,\"analyze_package\":null,\"features\":[],\"all_features\":false,\"no_default_features\":false}}");
+                  }
+                  result_processed.set_value();
+                });
+  result_processed.get_future().get();
+
+  initialized = true;
+  return capabilities;
 }
 
 void LanguageProtocol::Client::close(Source::LanguageProtocolView *view) {
-    {
-        std::unique_lock<std::mutex> lock(views_mutex);
-        auto it = views.find(view);
-        if (it != views.end())
-            views.erase(it);
-    }
-    std::unique_lock<std::mutex> lock(read_write_mutex);
-    for (auto it = handlers.begin(); it != handlers.end();) {
-        if (it->second.first == view)
-            it = handlers.erase(it);
-        else
-            it++;
-    }
+  {
+    std::unique_lock<std::mutex> lock(views_mutex);
+    auto it = views.find(view);
+    if (it != views.end())
+      views.erase(it);
+  }
+  std::unique_lock<std::mutex> lock(read_write_mutex);
+  for (auto it = handlers.begin(); it != handlers.end();) {
+    if (it->second.first == view)
+      it = handlers.erase(it);
+    else
+      it++;
+  }
 }
 
 void LanguageProtocol::Client::parse_server_message() {
-    if (!header_read) {
-        std::string line;
-        while (!header_read && std::getline(server_message_stream, line)) {
-            if (!line.empty()) {
-                if (line.back() == '\r')
-                    line.pop_back();
-                if (line.compare(0, 16, "Content-Length: ") == 0) {
-                    try {
-                        server_message_size = static_cast<size_t>(std::stoul(line.substr(16)));
-                    }
-                    catch (...) {}
-                }
-            }
-            if (line.empty()) {
-                server_message_content_pos = server_message_stream.tellg();
-                server_message_size += server_message_content_pos;
-                header_read = true;
-            }
+  if (!header_read) {
+    std::string line;
+    while (!header_read && std::getline(server_message_stream, line)) {
+      if (!line.empty()) {
+        if (line.back() == '\r')
+          line.pop_back();
+        if (line.compare(0, 16, "Content-Length: ") == 0) {
+          try {
+            server_message_size = static_cast<size_t>(std::stoul(line.substr(16)));
+          }
+          catch (...) {}
         }
+      }
+      if (line.empty()) {
+        server_message_content_pos = server_message_stream.tellg();
+        server_message_size += server_message_content_pos;
+        header_read = true;
+      }
     }
-
-    if (header_read) {
-        server_message_stream.seekg(0, std::ios::end);
-        size_t read_size = server_message_stream.tellg();
-        std::stringstream tmp;
-        if (read_size >= server_message_size) {
-            if (read_size > server_message_size) {
-                server_message_stream.seekg(server_message_size, std::ios::beg);
-                server_message_stream.seekp(server_message_size, std::ios::beg);
-                for (size_t c = server_message_size; c < read_size; ++c) {
-                    tmp.put(server_message_stream.get());
-                    server_message_stream.put(' ');
-                }
+  }
+
+  if (header_read) {
+    server_message_stream.seekg(0, std::ios::end);
+    size_t read_size = server_message_stream.tellg();
+    std::stringstream tmp;
+    if (read_size >= server_message_size) {
+      if (read_size > server_message_size) {
+        server_message_stream.seekg(server_message_size, std::ios::beg);
+        server_message_stream.seekp(server_message_size, std::ios::beg);
+        for (size_t c = server_message_size; c < read_size; ++c) {
+          tmp.put(server_message_stream.get());
+          server_message_stream.put(' ');
+        }
+      }
+
+      server_message_stream.seekg(server_message_content_pos, std::ios::beg);
+      boost::property_tree::ptree pt;
+      boost::property_tree::read_json(server_message_stream, pt);
+
+      if (output_messages_and_errors) {
+        std::cout << "language server: ";
+        boost::property_tree::write_json(std::cout, pt);
+      }
+
+      auto message_id = pt.get<size_t>("id", 0);
+      auto result_it = pt.find("result");
+      auto error_it = pt.find("error");
+      {
+        std::unique_lock<std::mutex> lock(read_write_mutex);
+        if (result_it != pt.not_found()) {
+          if (message_id) {
+            auto id_it = handlers.find(message_id);
+            if (id_it != handlers.end()) {
+              auto function = std::move(id_it->second.second);
+              handlers.erase(id_it->first);
+              lock.unlock();
+              function(result_it->second, false);
+              lock.lock();
             }
-
-            server_message_stream.seekg(server_message_content_pos, std::ios::beg);
-            boost::property_tree::ptree pt;
-            boost::property_tree::read_json(server_message_stream, pt);
-
-            if (output_messages_and_errors) {
-                std::cout << "language server: ";
-                boost::property_tree::write_json(std::cout, pt);
+          }
+        } else if (error_it != pt.not_found()) {
+          if (!output_messages_and_errors)
+            boost::property_tree::write_json(std::cerr, pt);
+          if (message_id) {
+            auto id_it = handlers.find(message_id);
+            if (id_it != handlers.end()) {
+              auto function = std::move(id_it->second.second);
+              handlers.erase(id_it->first);
+              lock.unlock();
+              function(result_it->second, true);
+              lock.lock();
             }
-
-            auto message_id = pt.get<size_t>("id", 0);
-            auto result_it = pt.find("result");
-            auto error_it = pt.find("error");
-            {
-                std::unique_lock<std::mutex> lock(read_write_mutex);
-                if (result_it != pt.not_found()) {
-                    if (message_id) {
-                        auto id_it = handlers.find(message_id);
-                        if (id_it != handlers.end()) {
-                            auto function = std::move(id_it->second.second);
-                            handlers.erase(id_it->first);
-                            lock.unlock();
-                            function(result_it->second, false);
-                            lock.lock();
-                        }
-                    }
-                } else if (error_it != pt.not_found()) {
-                    if (!output_messages_and_errors)
-                        boost::property_tree::write_json(std::cerr, pt);
-                    if (message_id) {
-                        auto id_it = handlers.find(message_id);
-                        if (id_it != handlers.end()) {
-                            auto function = std::move(id_it->second.second);
-                            handlers.erase(id_it->first);
-                            lock.unlock();
-                            function(result_it->second, true);
-                            lock.lock();
-                        }
-                    }
-                } else {
-                    auto method_it = pt.find("method");
-                    if (method_it != pt.not_found()) {
-                        auto params_it = pt.find("params");
-                        if (params_it != pt.not_found()) {
-                            lock.unlock();
-                            handle_server_request(method_it->second.get_value<std::string>(""), params_it->second);
-                            lock.lock();
-                        }
-                    }
-                }
-            }
-
-            server_message_stream = std::stringstream();
-            header_read = false;
-            server_message_size = static_cast<size_t>(-1);
-
-            tmp.seekg(0, std::ios::end);
-            if (tmp.tellg() > 0) {
-                tmp.seekg(0, std::ios::beg);
-                server_message_stream << tmp.rdbuf();
-                parse_server_message();
+          }
+        } else {
+          auto method_it = pt.find("method");
+          if (method_it != pt.not_found()) {
+            auto params_it = pt.find("params");
+            if (params_it != pt.not_found()) {
+              lock.unlock();
+              handle_server_request(method_it->second.get_value<std::string>(""), params_it->second);
+              lock.lock();
             }
+          }
         }
+      }
+
+      server_message_stream = std::stringstream();
+      header_read = false;
+      server_message_size = static_cast<size_t>(-1);
+
+      tmp.seekg(0, std::ios::end);
+      if (tmp.tellg() > 0) {
+        tmp.seekg(0, std::ios::beg);
+        server_message_stream << tmp.rdbuf();
+        parse_server_message();
+      }
     }
+  }
 }
 
 void LanguageProtocol::Client::write_request(Source::LanguageProtocolView *view, const std::string &method,
                                              const std::string &params,
                                              std::function<void(const boost::property_tree::ptree &,
                                                                 bool error)> &&function) {
-    std::unique_lock<std::mutex> lock(read_write_mutex);
-    if (function) {
-        handlers.emplace(message_id, std::make_pair(view, std::move(function)));
-
-        auto message_id = this->message_id;
-        std::unique_lock<std::mutex> lock(timeout_threads_mutex);
-        timeout_threads.emplace_back([this, message_id] {
-            for (size_t c = 0; c < 20; ++c) {
-                std::this_thread::sleep_for(std::chrono::milliseconds(500));
-                std::unique_lock<std::mutex> lock(read_write_mutex);
-                auto id_it = handlers.find(message_id);
-                if (id_it == handlers.end())
-                    return;
-            }
-            std::unique_lock<std::mutex> lock(read_write_mutex);
-            auto id_it = handlers.find(message_id);
-            if (id_it != handlers.end()) {
-                auto function = std::move(id_it->second.second);
-                handlers.erase(id_it->first);
-                lock.unlock();
-                function(boost::property_tree::ptree(), false);
-                lock.lock();
-            }
-        });
-    }
-    std::string content("{\"jsonrpc\":\"2.0\",\"id\":" + std::to_string(message_id++) + ",\"method\":\"" + method +
-                        "\",\"params\":{" + params + "}}");
-    auto message = "Content-Length: " + std::to_string(content.size()) + "\r\n\r\n" + content;
-    if (output_messages_and_errors)
-        std::cout << "Language client: " << content << std::endl;
-    if (!process->write(message)) {
-        Terminal::get().async_print(
-                "Error writing to language protocol server. Please close and reopen all project source files.\n", true);
-        auto id_it = handlers.find(message_id - 1);
-        if (id_it != handlers.end()) {
-            auto function = std::move(id_it->second.second);
-            handlers.erase(id_it->first);
-            lock.unlock();
-            function(boost::property_tree::ptree(), false);
-            lock.lock();
-        }
+  std::unique_lock<std::mutex> lock(read_write_mutex);
+  if (function) {
+    handlers.emplace(message_id, std::make_pair(view, std::move(function)));
+
+    auto message_id = this->message_id;
+    std::unique_lock<std::mutex> lock(timeout_threads_mutex);
+    timeout_threads.emplace_back([this, message_id] {
+      for (size_t c = 0; c < 20; ++c) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(500));
+        std::unique_lock<std::mutex> lock(read_write_mutex);
+        auto id_it = handlers.find(message_id);
+        if (id_it == handlers.end())
+          return;
+      }
+      std::unique_lock<std::mutex> lock(read_write_mutex);
+      auto id_it = handlers.find(message_id);
+      if (id_it != handlers.end()) {
+        auto function = std::move(id_it->second.second);
+        handlers.erase(id_it->first);
+        lock.unlock();
+        function(boost::property_tree::ptree(), false);
+        lock.lock();
+      }
+    });
+  }
+  std::string content("{\"jsonrpc\":\"2.0\",\"id\":" + std::to_string(message_id++) + ",\"method\":\"" + method +
+                      "\",\"params\":{" + params + "}}");
+  auto message = "Content-Length: " + std::to_string(content.size()) + "\r\n\r\n" + content;
+  if (output_messages_and_errors)
+    std::cout << "Language client: " << content << std::endl;
+  if (!process->write(message)) {
+    Terminal::get().async_print(
+        "Error writing to language protocol server. Please close and reopen all project source files.\n", true);
+    auto id_it = handlers.find(message_id - 1);
+    if (id_it != handlers.end()) {
+      auto function = std::move(id_it->second.second);
+      handlers.erase(id_it->first);
+      lock.unlock();
+      function(boost::property_tree::ptree(), false);
+      lock.lock();
     }
+  }
 }
 
 void LanguageProtocol::Client::write_notification(const std::string &method, const std::string &params) {
-    std::unique_lock<std::mutex> lock(read_write_mutex);
-    std::string content("{\"jsonrpc\":\"2.0\",\"method\":\"" + method + "\",\"params\":{" + params + "}}");
-    auto message = "Content-Length: " + std::to_string(content.size()) + "\r\n\r\n" + content;
-    if (output_messages_and_errors)
-        std::cout << "Language client: " << content << std::endl;
-    process->write(message);
+  std::unique_lock<std::mutex> lock(read_write_mutex);
+  std::string content("{\"jsonrpc\":\"2.0\",\"method\":\"" + method + "\",\"params\":{" + params + "}}");
+  auto message = "Content-Length: " + std::to_string(content.size()) + "\r\n\r\n" + content;
+  if (output_messages_and_errors)
+    std::cout << "Language client: " << content << std::endl;
+  process->write(message);
 }
 
 void
 LanguageProtocol::Client::handle_server_request(const std::string &method, const boost::property_tree::ptree &params) {
-    if (method == "textDocument/publishDiagnostics") {
-        std::vector<Diagnostic> diagnostics;
-        auto uri = params.get<std::string>("uri", "");
-        if (!uri.empty()) {
-            auto diagnostics_pt = params.get_child("diagnostics", boost::property_tree::ptree());
-            for (auto it = diagnostics_pt.begin(); it != diagnostics_pt.end(); ++it) {
-                auto range_it = it->second.find("range");
-                if (range_it != it->second.not_found()) {
-                    auto start_it = range_it->second.find("start");
-                    auto end_it = range_it->second.find("end");
-                    if (start_it != range_it->second.not_found() && start_it != range_it->second.not_found()) {
-                        diagnostics.emplace_back(Diagnostic{it->second.get<std::string>("message", ""),
-                                                            std::make_pair<Source::Offset, Source::Offset>(
-                                                                    Source::Offset(
-                                                                            start_it->second.get<unsigned>("line", 0),
-                                                                            start_it->second.get<unsigned>("character",
-                                                                                                           0)),
-                                                                    Source::Offset(
-                                                                            end_it->second.get<unsigned>("line", 0),
-                                                                            end_it->second.get<unsigned>("character",
-                                                                                                         0))),
-                                                            it->second.get<unsigned>("severity", 0), uri});
-                    }
-                }
-            }
-            std::unique_lock<std::mutex> lock(views_mutex);
-            for (auto view: views) {
-                if (view->uri == uri) {
-                    view->update_diagnostics(std::move(diagnostics));
-                    break;
-                }
-            }
+  if (method == "textDocument/publishDiagnostics") {
+    std::vector<Diagnostic> diagnostics;
+    auto uri = params.get<std::string>("uri", "");
+    if (!uri.empty()) {
+      auto diagnostics_pt = params.get_child("diagnostics", boost::property_tree::ptree());
+      for (auto it = diagnostics_pt.begin(); it != diagnostics_pt.end(); ++it) {
+        auto range_it = it->second.find("range");
+        if (range_it != it->second.not_found()) {
+          auto start_it = range_it->second.find("start");
+          auto end_it = range_it->second.find("end");
+          if (start_it != range_it->second.not_found() && start_it != range_it->second.not_found()) {
+            diagnostics.emplace_back(Diagnostic{it->second.get<std::string>("message", ""),
+                                                std::make_pair<Source::Offset, Source::Offset>(
+                                                    Source::Offset(
+                                                        start_it->second.get<unsigned>("line", 0),
+                                                        start_it->second.get<unsigned>("character",
+                                                                                       0)),
+                                                    Source::Offset(
+                                                        end_it->second.get<unsigned>("line", 0),
+                                                        end_it->second.get<unsigned>("character",
+                                                                                     0))),
+                                                it->second.get<unsigned>("severity", 0), uri});
+          }
         }
+      }
+      std::unique_lock<std::mutex> lock(views_mutex);
+      for (auto view: views) {
+        if (view->uri == uri) {
+          view->update_diagnostics(std::move(diagnostics));
+          break;
+        }
+      }
     }
+  }
 }
 
 Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path &file_path,
                                                    Glib::RefPtr<Gsv::Language> language, std::string language_id_)
-        : Source::BaseView(file_path, language), Source::View(file_path, language), uri("file://" + file_path.string()),
-          language_id(std::move(language_id_)), client(LanguageProtocol::Client::get(file_path, language_id)),
-          autocomplete(this, interactive_completion, last_keyval, false) {
-    configure();
-    get_source_buffer()->set_language(language);
-    get_source_buffer()->set_highlight_syntax(true);
-
-    similar_symbol_tag = get_buffer()->create_tag();
-    similar_symbol_tag->property_weight() = Pango::WEIGHT_ULTRAHEAVY;
-
-    status_state = "initializing...";
-    if (update_status_state)
-        update_status_state(this);
-
-    if (language_id == "javascript") {
-        boost::filesystem::path project_path;
-        auto build = Project::Build::create(file_path);
-        if (auto npm_build = dynamic_cast<Project::NpmBuild *>(build.get())) {
-            boost::system::error_code ec;
-            if (!npm_build->project_path.empty() &&
-                boost::filesystem::exists(npm_build->project_path / ".flowconfig", ec)) {
-                auto executable = npm_build->project_path / "node_modules" / ".bin" /
-                                  "flow"; // It is recommended to use Flow binary installed in project, despite the security risk of doing so...
-                if (boost::filesystem::exists(executable, ec))
-                    flow_coverage_executable = executable;
-                else
-                    flow_coverage_executable = filesystem::find_executable("flow");
-            }
-        }
+    : Source::BaseView(file_path, language), Source::View(file_path, language), uri("file://" + file_path.string()),
+      language_id(std::move(language_id_)), client(LanguageProtocol::Client::get(file_path, language_id)),
+      autocomplete(this, interactive_completion, last_keyval, false) {
+  configure();
+  get_source_buffer()->set_language(language);
+  get_source_buffer()->set_highlight_syntax(true);
+
+  similar_symbol_tag = get_buffer()->create_tag();
+  similar_symbol_tag->property_weight() = Pango::WEIGHT_ULTRAHEAVY;
+
+  status_state = "initializing...";
+  if (update_status_state)
+    update_status_state(this);
+
+  if (language_id == "javascript") {
+    boost::filesystem::path project_path;
+    auto build = Project::Build::create(file_path);
+    if (auto npm_build = dynamic_cast<Project::NpmBuild *>(build.get())) {
+      boost::system::error_code ec;
+      if (!npm_build->project_path.empty() &&
+          boost::filesystem::exists(npm_build->project_path / ".flowconfig", ec)) {
+        auto executable = npm_build->project_path / "node_modules" / ".bin" /
+                          "flow"; // It is recommended to use Flow binary installed in project, despite the security risk of doing so...
+        if (boost::filesystem::exists(executable, ec))
+          flow_coverage_executable = executable;
+        else
+          flow_coverage_executable = filesystem::find_executable("flow");
+      }
     }
+  }
 
-    initialize_thread = std::thread([this] {
-        auto capabilities = client->initialize(this);
+  initialize_thread = std::thread([this] {
+    auto capabilities = client->initialize(this);
 
-        if (!flow_coverage_executable.empty())
-            add_flow_coverage_tooltips(true);
-
-        dispatcher.post([this, capabilities] {
-            this->capabilities = capabilities;
+    if (!flow_coverage_executable.empty())
+      add_flow_coverage_tooltips(true);
 
-            std::string text = get_buffer()->get_text();
-            escape_text(text);
-            client->write_notification("textDocument/didOpen",
-                                       "\"textDocument\":{\"uri\":\"" + uri + "\",\"languageId\":\"" + language_id +
-                                       "\",\"version\":" + std::to_string(document_version++) + ",\"text\":\"" + text +
-                                       "\"}");
+    dispatcher.post([this, capabilities] {
+      this->capabilities = capabilities;
 
-            setup_autocomplete();
-            setup_navigation_and_refactoring();
-            Menu::get().toggle_menu_items();
+      std::string text = get_buffer()->get_text();
+      escape_text(text);
+      client->write_notification("textDocument/didOpen",
+                                 "\"textDocument\":{\"uri\":\"" + uri + "\",\"languageId\":\"" + language_id +
+                                 "\",\"version\":" + std::to_string(document_version++) + ",\"text\":\"" + text +
+                                 "\"}");
 
-            if (status_state == "initializing...") {
-                status_state = "";
-                if (update_status_state)
-                    update_status_state(this);
-            }
-        });
-    });
+      setup_autocomplete();
+      setup_navigation_and_refactoring();
+      Menu::get().toggle_menu_items();
 
-    get_buffer()->signal_changed().connect([this] {
-        get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(), get_buffer()->end());
+      if (status_state == "initializing...") {
+        status_state = "";
+        if (update_status_state)
+          update_status_state(this);
+      }
     });
-
-    get_buffer()->signal_mark_set().connect(
-            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-                if (mark->get_name() == "insert") {
-                    delayed_tag_similar_symbols_connection.disconnect();
-                    delayed_tag_similar_symbols_connection = Glib::signal_timeout().connect([this]() {
-                        tag_similar_symbols();
-                        return false;
-                    }, 200);
-                }
-            });
-
-    get_buffer()->signal_insert().connect(
-            [this](const Gtk::TextBuffer::iterator &start, const Glib::ustring &text_, int bytes) {
-                std::string content_changes;
-                if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::NONE)
-                    return;
-                if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::INCREMENTAL) {
-                    std::string text = text_;
-                    escape_text(text);
-                    content_changes =
-                            "{\"range\":{\"start\":{\"line\": " + std::to_string(start.get_line()) + ",\"character\":" +
-                            std::to_string(start.get_line_offset()) + "},\"end\":{\"line\":" +
-                            std::to_string(start.get_line()) + ",\"character\":" +
-                            std::to_string(start.get_line_offset()) + "}},\"text\":\"" + text + "\"}";
-                } else {
-                    std::string text = get_buffer()->get_text();
-                    escape_text(text);
-                    content_changes = "{\"text\":\"" + text + "\"}";
-                }
-                client->write_notification("textDocument/didChange",
-                                           "\"textDocument\":{\"uri\":\"" + uri + "\",\"version\":" +
-                                           std::to_string(document_version++) + "},\"contentChanges\":[" +
-                                           content_changes + "]");
-            }, false);
-
-    get_buffer()->signal_erase().connect(
-            [this](const Gtk::TextBuffer::iterator &start, const Gtk::TextBuffer::iterator &end) {
-                std::string content_changes;
-                if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::NONE)
-                    return;
-                if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::INCREMENTAL)
-                    content_changes =
-                            "{\"range\":{\"start\":{\"line\": " + std::to_string(start.get_line()) + ",\"character\":" +
-                            std::to_string(start.get_line_offset()) + "},\"end\":{\"line\":" +
-                            std::to_string(end.get_line()) + ",\"character\":" + std::to_string(end.get_line_offset()) +
-                            "}},\"text\":\"\"}";
-                else {
-                    std::string text = get_buffer()->get_text();
-                    escape_text(text);
-                    content_changes = "{\"text\":\"" + text + "\"}";
-                }
-                client->write_notification("textDocument/didChange",
-                                           "\"textDocument\":{\"uri\":\"" + uri + "\",\"version\":" +
-                                           std::to_string(document_version++) + "},\"contentChanges\":[" +
-                                           content_changes + "]");
-            }, false);
+  });
+
+  get_buffer()->signal_changed().connect([this] {
+    get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(), get_buffer()->end());
+  });
+
+  get_buffer()->signal_mark_set().connect(
+      [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+        if (mark->get_name() == "insert") {
+          delayed_tag_similar_symbols_connection.disconnect();
+          delayed_tag_similar_symbols_connection = Glib::signal_timeout().connect([this]() {
+            tag_similar_symbols();
+            return false;
+          }, 200);
+        }
+      });
+
+  get_buffer()->signal_insert().connect(
+      [this](const Gtk::TextBuffer::iterator &start, const Glib::ustring &text_, int bytes) {
+        std::string content_changes;
+        if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::NONE)
+          return;
+        if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::INCREMENTAL) {
+          std::string text = text_;
+          escape_text(text);
+          content_changes =
+              "{\"range\":{\"start\":{\"line\": " + std::to_string(start.get_line()) + ",\"character\":" +
+              std::to_string(start.get_line_offset()) + "},\"end\":{\"line\":" +
+              std::to_string(start.get_line()) + ",\"character\":" +
+              std::to_string(start.get_line_offset()) + "}},\"text\":\"" + text + "\"}";
+        } else {
+          std::string text = get_buffer()->get_text();
+          escape_text(text);
+          content_changes = "{\"text\":\"" + text + "\"}";
+        }
+        client->write_notification("textDocument/didChange",
+                                   "\"textDocument\":{\"uri\":\"" + uri + "\",\"version\":" +
+                                   std::to_string(document_version++) + "},\"contentChanges\":[" +
+                                   content_changes + "]");
+      }, false);
+
+  get_buffer()->signal_erase().connect(
+      [this](const Gtk::TextBuffer::iterator &start, const Gtk::TextBuffer::iterator &end) {
+        std::string content_changes;
+        if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::NONE)
+          return;
+        if (capabilities.text_document_sync == LanguageProtocol::Capabilities::TextDocumentSync::INCREMENTAL)
+          content_changes =
+              "{\"range\":{\"start\":{\"line\": " + std::to_string(start.get_line()) + ",\"character\":" +
+              std::to_string(start.get_line_offset()) + "},\"end\":{\"line\":" +
+              std::to_string(end.get_line()) + ",\"character\":" + std::to_string(end.get_line_offset()) +
+              "}},\"text\":\"\"}";
+        else {
+          std::string text = get_buffer()->get_text();
+          escape_text(text);
+          content_changes = "{\"text\":\"" + text + "\"}";
+        }
+        client->write_notification("textDocument/didChange",
+                                   "\"textDocument\":{\"uri\":\"" + uri + "\",\"version\":" +
+                                   std::to_string(document_version++) + "},\"contentChanges\":[" +
+                                   content_changes + "]");
+      }, false);
 }
 
 Source::LanguageProtocolView::~LanguageProtocolView() {
-    delayed_tag_similar_symbols_connection.disconnect();
+  delayed_tag_similar_symbols_connection.disconnect();
 
-    if (initialize_thread.joinable())
-        initialize_thread.join();
+  if (initialize_thread.joinable())
+    initialize_thread.join();
 
-    autocomplete.state = Autocomplete::State::IDLE;
-    if (autocomplete.thread.joinable())
-        autocomplete.thread.join();
+  autocomplete.state = Autocomplete::State::IDLE;
+  if (autocomplete.thread.joinable())
+    autocomplete.thread.join();
 
-    client->write_notification("textDocument/didClose", "\"textDocument\":{\"uri\":\"" + uri + "\"}");
-    client->close(this);
+  client->write_notification("textDocument/didClose", "\"textDocument\":{\"uri\":\"" + uri + "\"}");
+  client->close(this);
 
-    client = nullptr;
+  client = nullptr;
 }
 
 bool Source::LanguageProtocolView::save() {
-    if (!Source::View::save())
-        return false;
+  if (!Source::View::save())
+    return false;
 
-    if (!flow_coverage_executable.empty())
-        add_flow_coverage_tooltips(false);
+  if (!flow_coverage_executable.empty())
+    add_flow_coverage_tooltips(false);
 
-    return true;
+  return true;
 }
 
 void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
-    if (capabilities.document_formatting) {
-        format_style = [this](bool continue_without_style_file) {
-            if (!continue_without_style_file) {
-                bool has_style_file = false;
-                auto style_file_search_path = this->file_path.parent_path();
-                auto style_file = '.' + language_id + "-format";
-
-                while (true) {
-                    if (boost::filesystem::exists(style_file_search_path / style_file)) {
-                        has_style_file = true;
-                        break;
-                    }
-                    if (style_file_search_path == style_file_search_path.root_directory())
-                        break;
-                    style_file_search_path = style_file_search_path.parent_path();
-                }
-
-                if (!has_style_file && !continue_without_style_file)
-                    return;
-            }
-
-            class Replace {
-            public:
-                Offset start, end;
-                std::string text;
-            };
-            std::vector<Replace> replaces;
-            std::promise<void> result_processed;
-
-            std::string method;
-            std::string params;
-            std::string options("\"tabSize\":" + std::to_string(tab_size) + ",\"insertSpaces\":" +
-                                (tab_char == ' ' ? "true" : "false"));
-            if (get_buffer()->get_has_selection() && capabilities.document_range_formatting) {
-                method = "textDocument/rangeFormatting";
-                Gtk::TextIter start, end;
-                get_buffer()->get_selection_bounds(start, end);
-                params = "\"textDocument\":{\"uri\":\"" + uri + "\"},\"range\":{\"start\":{\"line\":" +
-                         std::to_string(start.get_line()) + ",\"character\":" +
-                         std::to_string(start.get_line_offset()) + "},\"end\":{\"line\":" +
-                         std::to_string(end.get_line()) + ",\"character\":" + std::to_string(end.get_line_offset()) +
-                         "}},\"options\":{" + options + "}";
-            } else {
-                method = "textDocument/formatting";
-                params = "\"textDocument\":{\"uri\":\"" + uri + "\"},\"options\":{" + options + "}";
-            }
+  if (capabilities.document_formatting) {
+    format_style = [this](bool continue_without_style_file) {
+      if (!continue_without_style_file) {
+        bool has_style_file = false;
+        auto style_file_search_path = this->file_path.parent_path();
+        auto style_file = '.' + language_id + "-format";
+
+        while (true) {
+          if (boost::filesystem::exists(style_file_search_path / style_file)) {
+            has_style_file = true;
+            break;
+          }
+          if (style_file_search_path == style_file_search_path.root_directory())
+            break;
+          style_file_search_path = style_file_search_path.parent_path();
+        }
 
-            client->write_request(this, method, params,
-                                  [&replaces, &result_processed](const boost::property_tree::ptree &result,
-                                                                 bool error) {
-                                      if (!error) {
-                                          for (auto it = result.begin(); it != result.end(); ++it) {
-                                              auto range_it = it->second.find("range");
-                                              auto text_it = it->second.find("newText");
-                                              if (range_it != it->second.not_found() &&
-                                                  text_it != it->second.not_found()) {
-                                                  auto start_it = range_it->second.find("start");
-                                                  auto end_it = range_it->second.find("end");
-                                                  if (start_it != range_it->second.not_found() &&
-                                                      end_it != range_it->second.not_found()) {
-                                                      try {
-                                                          replaces.emplace_back(
-                                                                  Replace{Offset(start_it->second.get<unsigned>("line"),
-                                                                                 start_it->second.get<unsigned>(
-                                                                                         "character")),
-                                                                          Offset(end_it->second.get<unsigned>("line"),
-                                                                                 end_it->second.get<unsigned>(
-                                                                                         "character")),
-                                                                          text_it->second.get_value<std::string>()});
-                                                      }
-                                                      catch (...) {}
-                                                  }
-                                              }
-                                          }
+        if (!has_style_file && !continue_without_style_file)
+          return;
+      }
+
+      class Replace {
+      public:
+        Offset start, end;
+        std::string text;
+      };
+      std::vector<Replace> replaces;
+      std::promise<void> result_processed;
+
+      std::string method;
+      std::string params;
+      std::string options("\"tabSize\":" + std::to_string(tab_size) + ",\"insertSpaces\":" +
+                          (tab_char == ' ' ? "true" : "false"));
+      if (get_buffer()->get_has_selection() && capabilities.document_range_formatting) {
+        method = "textDocument/rangeFormatting";
+        Gtk::TextIter start, end;
+        get_buffer()->get_selection_bounds(start, end);
+        params = "\"textDocument\":{\"uri\":\"" + uri + "\"},\"range\":{\"start\":{\"line\":" +
+                 std::to_string(start.get_line()) + ",\"character\":" +
+                 std::to_string(start.get_line_offset()) + "},\"end\":{\"line\":" +
+                 std::to_string(end.get_line()) + ",\"character\":" + std::to_string(end.get_line_offset()) +
+                 "}},\"options\":{" + options + "}";
+      } else {
+        method = "textDocument/formatting";
+        params = "\"textDocument\":{\"uri\":\"" + uri + "\"},\"options\":{" + options + "}";
+      }
+
+      client->write_request(this, method, params,
+                            [&replaces, &result_processed](const boost::property_tree::ptree &result,
+                                                           bool error) {
+                              if (!error) {
+                                for (auto it = result.begin(); it != result.end(); ++it) {
+                                  auto range_it = it->second.find("range");
+                                  auto text_it = it->second.find("newText");
+                                  if (range_it != it->second.not_found() &&
+                                      text_it != it->second.not_found()) {
+                                    auto start_it = range_it->second.find("start");
+                                    auto end_it = range_it->second.find("end");
+                                    if (start_it != range_it->second.not_found() &&
+                                        end_it != range_it->second.not_found()) {
+                                      try {
+                                        replaces.emplace_back(
+                                            Replace{Offset(start_it->second.get<unsigned>("line"),
+                                                           start_it->second.get<unsigned>(
+                                                               "character")),
+                                                    Offset(end_it->second.get<unsigned>("line"),
+                                                           end_it->second.get<unsigned>(
+                                                               "character")),
+                                                    text_it->second.get_value<std::string>()});
+                                      }
+                                      catch (...) {}
+                                    }
+                                  }
+                                }
+                              }
+                              result_processed.set_value();
+                            });
+      result_processed.get_future().get();
+
+      auto end_iter = get_buffer()->end();
+      if (replaces.size() == 1 &&
+          replaces[0].start.line == 0 && replaces[0].start.index == 0 &&
+          (replaces[0].end.line > static_cast<unsigned>(end_iter.get_line()) ||
+           (replaces[0].end.line == static_cast<unsigned>(end_iter.get_line()) &&
+            replaces[0].end.index >= static_cast<unsigned>(end_iter.get_line_offset())))) {
+        unescape_text(replaces[0].text);
+        replace_text(replaces[0].text);
+      } else {
+        get_buffer()->begin_user_action();
+        for (auto it = replaces.rbegin(); it != replaces.rend(); ++it) {
+          auto start = get_iter_at_line_pos(it->start.line, it->start.index);
+          auto end = get_iter_at_line_pos(it->end.line, it->end.index);
+          get_buffer()->erase(start, end);
+          start = get_iter_at_line_pos(it->start.line, it->start.index);
+          unescape_text(it->text);
+          get_buffer()->insert(start, it->text);
+        }
+        get_buffer()->end_user_action();
+      }
+      hide_tooltips();
+    };
+  }
+
+  if (capabilities.definition) {
+    get_declaration_location = [this]() {
+      auto offset = get_declaration(get_buffer()->get_insert()->get_iter());
+      if (!offset)
+        Info::get().print("No declaration found");
+      return offset;
+    };
+    get_declaration_or_implementation_locations = [this]() {
+      std::vector<Offset> offsets;
+      auto offset = get_declaration_location();
+      if (offset)
+        offsets.emplace_back(std::move(offset));
+      return offsets;
+    };
+  }
+
+  if (capabilities.references) {
+    get_usages = [this] {
+      auto iter = get_buffer()->get_insert()->get_iter();
+      std::vector<std::pair<Offset, std::string>> usages;
+      std::vector<Offset> end_offsets;
+      std::promise<void> result_processed;
+      client->write_request(this, "textDocument/references",
+                            "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                            std::to_string(iter.get_line()) + ", \"character\": " +
+                            std::to_string(iter.get_line_offset()) +
+                            "}, \"context\": {\"includeDeclaration\": true}",
+                            [&usages, &end_offsets, &result_processed](const boost::property_tree::ptree &result,
+                                                                       bool error) {
+                              if (!error) {
+                                try {
+                                  for (auto it = result.begin(); it != result.end(); ++it) {
+                                    auto path = it->second.get<std::string>("uri", "");
+                                    if (path.size() >= 7) {
+                                      path.erase(0, 7);
+                                      auto range_it = it->second.find("range");
+                                      if (range_it != it->second.not_found()) {
+                                        auto start_it = range_it->second.find("start");
+                                        auto end_it = range_it->second.find("end");
+                                        if (start_it != range_it->second.not_found() &&
+                                            end_it != range_it->second.not_found()) {
+                                          usages.emplace_back(std::make_pair(
+                                              Offset(start_it->second.get<unsigned>("line"),
+                                                     start_it->second.get<unsigned>(
+                                                         "character"), path), ""));
+                                          end_offsets.emplace_back(
+                                              end_it->second.get<unsigned>("line"),
+                                              end_it->second.get<unsigned>("character"));
+                                        }
                                       }
-                                      result_processed.set_value();
-                                  });
-            result_processed.get_future().get();
-
-            auto end_iter = get_buffer()->end();
-            if (replaces.size() == 1 &&
-                replaces[0].start.line == 0 && replaces[0].start.index == 0 &&
-                (replaces[0].end.line > static_cast<unsigned>(end_iter.get_line()) ||
-                 (replaces[0].end.line == static_cast<unsigned>(end_iter.get_line()) &&
-                  replaces[0].end.index >= static_cast<unsigned>(end_iter.get_line_offset())))) {
-                unescape_text(replaces[0].text);
-                replace_text(replaces[0].text);
+                                    }
+                                  }
+                                }
+                                catch (...) {
+                                  usages.clear();
+                                  end_offsets.clear();
+                                }
+                              }
+                              result_processed.set_value();
+                            });
+      result_processed.get_future().get();
+
+      auto embolden_token = [](std::string &line_, unsigned token_start_pos, unsigned token_end_pos) {
+        Glib::ustring line = line_;
+        if (token_start_pos >= line.size() || token_end_pos >= line.size())
+          return;
+
+        //markup token as bold
+        size_t pos = 0;
+        while ((pos = line.find('&', pos)) != Glib::ustring::npos) {
+          size_t pos2 = line.find(';', pos + 2);
+          if (token_start_pos > pos) {
+            token_start_pos += pos2 - pos;
+            token_end_pos += pos2 - pos;
+          } else if (token_end_pos > pos)
+            token_end_pos += pos2 - pos;
+          else
+            break;
+          pos = pos2 + 1;
+        }
+        line.insert(token_end_pos, "</b>");
+        line.insert(token_start_pos, "<b>");
+
+        size_t start_pos = 0;
+        while (start_pos < line.size() && (line[start_pos] == ' ' || line[start_pos] == '\t'))
+          ++start_pos;
+        if (start_pos > 0)
+          line.erase(0, start_pos);
+
+        line_ = line.raw();
+      };
+
+      std::map<boost::filesystem::path, std::vector<std::string>> file_lines;
+      size_t c = static_cast<size_t>(-1);
+      for (auto &usage: usages) {
+        ++c;
+        auto view_it = views.end();
+        for (auto it = views.begin(); it != views.end(); ++it) {
+          if (usage.first.file_path == (*it)->file_path) {
+            view_it = it;
+            break;
+          }
+        }
+        if (view_it != views.end()) {
+          if (usage.first.line < static_cast<unsigned>((*view_it)->get_buffer()->get_line_count())) {
+            auto start = (*view_it)->get_buffer()->get_iter_at_line(usage.first.line);
+            auto end = start;
+            end.forward_to_line_end();
+            usage.second = Glib::Markup::escape_text((*view_it)->get_buffer()->get_text(start, end));
+            embolden_token(usage.second, usage.first.index, end_offsets[c].index);
+          }
+        } else {
+          auto it = file_lines.find(usage.first.file_path);
+          if (it == file_lines.end()) {
+            std::ifstream ifs(usage.first.file_path.string());
+            if (ifs) {
+              std::vector<std::string> lines;
+              std::string line;
+              while (std::getline(ifs, line)) {
+                if (!line.empty() && line.back() == '\r')
+                  line.pop_back();
+                lines.emplace_back(line);
+              }
+              auto pair = file_lines.emplace(usage.first.file_path, lines);
+              it = pair.first;
             } else {
-                get_buffer()->begin_user_action();
-                for (auto it = replaces.rbegin(); it != replaces.rend(); ++it) {
-                    auto start = get_iter_at_line_pos(it->start.line, it->start.index);
-                    auto end = get_iter_at_line_pos(it->end.line, it->end.index);
-                    get_buffer()->erase(start, end);
-                    start = get_iter_at_line_pos(it->start.line, it->start.index);
-                    unescape_text(it->text);
-                    get_buffer()->insert(start, it->text);
-                }
-                get_buffer()->end_user_action();
+              auto pair = file_lines.emplace(usage.first.file_path, std::vector<std::string>());
+              it = pair.first;
             }
-            hide_tooltips();
-        };
-    }
-
-    if (capabilities.definition) {
-        get_declaration_location = [this]() {
-            auto offset = get_declaration(get_buffer()->get_insert()->get_iter());
-            if (!offset)
-                Info::get().print("No declaration found");
-            return offset;
-        };
-        get_declaration_or_implementation_locations = [this]() {
-            std::vector<Offset> offsets;
-            auto offset = get_declaration_location();
-            if (offset)
-                offsets.emplace_back(std::move(offset));
-            return offsets;
-        };
-    }
+          }
 
-    if (capabilities.references) {
-        get_usages = [this] {
-            auto iter = get_buffer()->get_insert()->get_iter();
-            std::vector<std::pair<Offset, std::string>> usages;
-            std::vector<Offset> end_offsets;
-            std::promise<void> result_processed;
-            client->write_request(this, "textDocument/references",
-                                  "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
-                                  std::to_string(iter.get_line()) + ", \"character\": " +
-                                  std::to_string(iter.get_line_offset()) +
-                                  "}, \"context\": {\"includeDeclaration\": true}",
-                                  [&usages, &end_offsets, &result_processed](const boost::property_tree::ptree &result,
-                                                                             bool error) {
-                                      if (!error) {
-                                          try {
-                                              for (auto it = result.begin(); it != result.end(); ++it) {
-                                                  auto path = it->second.get<std::string>("uri", "");
-                                                  if (path.size() >= 7) {
-                                                      path.erase(0, 7);
-                                                      auto range_it = it->second.find("range");
-                                                      if (range_it != it->second.not_found()) {
-                                                          auto start_it = range_it->second.find("start");
-                                                          auto end_it = range_it->second.find("end");
-                                                          if (start_it != range_it->second.not_found() &&
-                                                              end_it != range_it->second.not_found()) {
-                                                              usages.emplace_back(std::make_pair(
-                                                                      Offset(start_it->second.get<unsigned>("line"),
-                                                                             start_it->second.get<unsigned>(
-                                                                                     "character"), path), ""));
-                                                              end_offsets.emplace_back(
-                                                                      end_it->second.get<unsigned>("line"),
-                                                                      end_it->second.get<unsigned>("character"));
-                                                          }
-                                                      }
-                                                  }
-                                              }
-                                          }
-                                          catch (...) {
-                                              usages.clear();
-                                              end_offsets.clear();
-                                          }
-                                      }
-                                      result_processed.set_value();
-                                  });
-            result_processed.get_future().get();
-
-            auto embolden_token = [](std::string &line_, unsigned token_start_pos, unsigned token_end_pos) {
-                Glib::ustring line = line_;
-                if (token_start_pos >= line.size() || token_end_pos >= line.size())
-                    return;
-
-                //markup token as bold
-                size_t pos = 0;
-                while ((pos = line.find('&', pos)) != Glib::ustring::npos) {
-                    size_t pos2 = line.find(';', pos + 2);
-                    if (token_start_pos > pos) {
-                        token_start_pos += pos2 - pos;
-                        token_end_pos += pos2 - pos;
-                    } else if (token_end_pos > pos)
-                        token_end_pos += pos2 - pos;
-                    else
-                        break;
-                    pos = pos2 + 1;
-                }
-                line.insert(token_end_pos, "</b>");
-                line.insert(token_start_pos, "<b>");
-
-                size_t start_pos = 0;
-                while (start_pos < line.size() && (line[start_pos] == ' ' || line[start_pos] == '\t'))
-                    ++start_pos;
-                if (start_pos > 0)
-                    line.erase(0, start_pos);
-
-                line_ = line.raw();
-            };
-
-            std::map<boost::filesystem::path, std::vector<std::string>> file_lines;
-            size_t c = static_cast<size_t>(-1);
-            for (auto &usage: usages) {
-                ++c;
-                auto view_it = views.end();
-                for (auto it = views.begin(); it != views.end(); ++it) {
-                    if (usage.first.file_path == (*it)->file_path) {
-                        view_it = it;
-                        break;
-                    }
-                }
-                if (view_it != views.end()) {
-                    if (usage.first.line < static_cast<unsigned>((*view_it)->get_buffer()->get_line_count())) {
-                        auto start = (*view_it)->get_buffer()->get_iter_at_line(usage.first.line);
-                        auto end = start;
-                        end.forward_to_line_end();
-                        usage.second = Glib::Markup::escape_text((*view_it)->get_buffer()->get_text(start, end));
-                        embolden_token(usage.second, usage.first.index, end_offsets[c].index);
-                    }
-                } else {
-                    auto it = file_lines.find(usage.first.file_path);
-                    if (it == file_lines.end()) {
-                        std::ifstream ifs(usage.first.file_path.string());
-                        if (ifs) {
-                            std::vector<std::string> lines;
-                            std::string line;
-                            while (std::getline(ifs, line)) {
-                                if (!line.empty() && line.back() == '\r')
-                                    line.pop_back();
-                                lines.emplace_back(line);
-                            }
-                            auto pair = file_lines.emplace(usage.first.file_path, lines);
-                            it = pair.first;
-                        } else {
-                            auto pair = file_lines.emplace(usage.first.file_path, std::vector<std::string>());
-                            it = pair.first;
-                        }
-                    }
-
-                    if (usage.first.line < it->second.size()) {
-                        usage.second = it->second[usage.first.line];
-                        embolden_token(usage.second, usage.first.index, end_offsets[c].index);
-                    }
-                }
-            }
+          if (usage.first.line < it->second.size()) {
+            usage.second = it->second[usage.first.line];
+            embolden_token(usage.second, usage.first.index, end_offsets[c].index);
+          }
+        }
+      }
 
-            if (usages.empty())
-                Info::get().print("No symbol found at current cursor location");
+      if (usages.empty())
+        Info::get().print("No symbol found at current cursor location");
 
-            return usages;
-        };
+      return usages;
+    };
+  }
+
+  get_token_spelling = [this]() -> std::string {
+    auto start = get_buffer()->get_insert()->get_iter();
+    auto end = start;
+    auto previous = start;
+    while (previous.backward_char() &&
+           ((*previous >= 'A' && *previous <= 'Z') || (*previous >= 'a' && *previous <= 'z') ||
+            (*previous >= '0' && *previous <= '9') || *previous == '_') && start.backward_char()) {}
+    while (((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') ||
+            *end == '_') && end.forward_char()) {}
+
+    if (start == end) {
+      Info::get().print("No valid symbol found at current cursor location");
+      return "";
     }
 
-    get_token_spelling = [this]() -> std::string {
-        auto start = get_buffer()->get_insert()->get_iter();
-        auto end = start;
-        auto previous = start;
-        while (previous.backward_char() &&
-               ((*previous >= 'A' && *previous <= 'Z') || (*previous >= 'a' && *previous <= 'z') ||
-                (*previous >= '0' && *previous <= '9') || *previous == '_') && start.backward_char()) {}
-        while (((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') ||
-                *end == '_') && end.forward_char()) {}
+    return get_buffer()->get_text(start, end);
+  };
 
-        if (start == end) {
-            Info::get().print("No valid symbol found at current cursor location");
-            return "";
-        }
+  if (capabilities.rename) {
+    rename_similar_tokens = [this](const std::string &text) {
+      class Usages {
+      public:
+        boost::filesystem::path path;
+        std::unique_ptr<std::string> new_text;
+        std::vector<std::pair<Offset, Offset>> offsets;
+      };
 
-        return get_buffer()->get_text(start, end);
-    };
+      auto previous_text = get_token_spelling();
+      if (previous_text.empty())
+        return;
 
-    if (capabilities.rename) {
-        rename_similar_tokens = [this](const std::string &text) {
-            class Usages {
-            public:
-                boost::filesystem::path path;
-                std::unique_ptr<std::string> new_text;
-                std::vector<std::pair<Offset, Offset>> offsets;
-            };
-
-            auto previous_text = get_token_spelling();
-            if (previous_text.empty())
-                return;
-
-            auto iter = get_buffer()->get_insert()->get_iter();
-            std::vector<Usages> usages;
-            std::promise<void> result_processed;
-            client->write_request(this, "textDocument/rename",
-                                  "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
-                                  std::to_string(iter.get_line()) + ", \"character\": " +
-                                  std::to_string(iter.get_line_offset()) + "}, \"newName\": \"" + text + "\"",
-                                  [this, &usages, &result_processed](const boost::property_tree::ptree &result,
-                                                                     bool error) {
-                                      if (!error) {
-                                          boost::filesystem::path project_path;
-                                          auto build = Project::Build::create(file_path);
-                                          if (!build->project_path.empty())
-                                              project_path = build->project_path;
-                                          else
-                                              project_path = file_path.parent_path();
-                                          try {
-                                              auto changes_it = result.find("changes");
-                                              if (changes_it != result.not_found()) {
-                                                  for (auto file_it = changes_it->second.begin();
-                                                       file_it != changes_it->second.end(); ++file_it) {
-                                                      auto path = file_it->first;
-                                                      if (path.size() >= 7) {
-                                                          path.erase(0, 7);
-                                                          if (filesystem::file_in_path(path, project_path)) {
-                                                              usages.emplace_back(Usages{path, nullptr,
-                                                                                         std::vector<std::pair<Offset, Offset>>()});
-                                                              for (auto edit_it = file_it->second.begin();
-                                                                   edit_it != file_it->second.end(); ++edit_it) {
-                                                                  auto range_it = edit_it->second.find("range");
-                                                                  if (range_it != edit_it->second.not_found()) {
-                                                                      auto start_it = range_it->second.find("start");
-                                                                      auto end_it = range_it->second.find("end");
-                                                                      if (start_it != range_it->second.not_found() &&
-                                                                          end_it != range_it->second.not_found())
-                                                                          usages.back().offsets.emplace_back(
-                                                                                  std::make_pair(
-                                                                                          Offset(start_it->second.get<unsigned>(
-                                                                                                  "line"),
-                                                                                                 start_it->second.get<unsigned>(
-                                                                                                         "character")),
-                                                                                          Offset(end_it->second.get<unsigned>(
-                                                                                                  "line"),
-                                                                                                 end_it->second.get<unsigned>(
-                                                                                                         "character"))));
-                                                                  }
-                                                              }
-                                                          }
-                                                      }
-                                                  }
-                                              } else {
-                                                  auto changes_pt = result.get_child("documentChanges",
-                                                                                     boost::property_tree::ptree());
-                                                  for (auto change_it = changes_pt.begin();
-                                                       change_it != changes_pt.end(); ++change_it) {
-                                                      auto document_it = change_it->second.find("textDocument");
-                                                      if (document_it != change_it->second.not_found()) {
-                                                          auto path = document_it->second.get<std::string>("uri", "");
-                                                          if (path.size() >= 7) {
-                                                              path.erase(0, 7);
-                                                              if (filesystem::file_in_path(path, project_path)) {
-                                                                  usages.emplace_back(
-                                                                          Usages{path, std::make_unique<std::string>(),
-                                                                                 std::vector<std::pair<Offset, Offset>>()});
-                                                                  auto edits_pt = change_it->second.get_child("edits",
-                                                                                                              boost::property_tree::ptree());
-                                                                  for (auto edit_it = edits_pt.begin();
-                                                                       edit_it != edits_pt.end(); ++edit_it) {
-                                                                      auto new_text_it = edit_it->second.find(
-                                                                              "newText");
-                                                                      if (new_text_it != edit_it->second.not_found()) {
-                                                                          auto range_it = edit_it->second.find("range");
-                                                                          if (range_it != edit_it->second.not_found()) {
-                                                                              auto start_it = range_it->second.find(
-                                                                                      "start");
-                                                                              auto end_it = range_it->second.find(
-                                                                                      "end");
-                                                                              if (start_it !=
-                                                                                  range_it->second.not_found() &&
-                                                                                  end_it !=
-                                                                                  range_it->second.not_found()) {
-                                                                                  auto end_line = end_it->second.get<size_t>(
-                                                                                          "line");
-                                                                                  if (end_line >
-                                                                                      std::numeric_limits<int>::max())
-                                                                                      end_line = std::numeric_limits<int>::max();
-                                                                                  *usages.back().new_text = new_text_it->second.get_value<std::string>();
-                                                                                  usages.back().offsets.emplace_back(
-                                                                                          std::make_pair(
-                                                                                                  Offset(start_it->second.get<unsigned>(
-                                                                                                          "line"),
-                                                                                                         start_it->second.get<unsigned>(
-                                                                                                                 "character")),
-                                                                                                  Offset(static_cast<unsigned>(end_line),
-                                                                                                         end_it->second.get<unsigned>(
-                                                                                                                 "character"))));
-                                                                              }
-                                                                          }
-                                                                      }
-                                                                  }
-                                                              }
-                                                          }
-                                                      }
+      auto iter = get_buffer()->get_insert()->get_iter();
+      std::vector<Usages> usages;
+      std::promise<void> result_processed;
+      client->write_request(this, "textDocument/rename",
+                            "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                            std::to_string(iter.get_line()) + ", \"character\": " +
+                            std::to_string(iter.get_line_offset()) + "}, \"newName\": \"" + text + "\"",
+                            [this, &usages, &result_processed](const boost::property_tree::ptree &result,
+                                                               bool error) {
+                              if (!error) {
+                                boost::filesystem::path project_path;
+                                auto build = Project::Build::create(file_path);
+                                if (!build->project_path.empty())
+                                  project_path = build->project_path;
+                                else
+                                  project_path = file_path.parent_path();
+                                try {
+                                  auto changes_it = result.find("changes");
+                                  if (changes_it != result.not_found()) {
+                                    for (auto file_it = changes_it->second.begin();
+                                         file_it != changes_it->second.end(); ++file_it) {
+                                      auto path = file_it->first;
+                                      if (path.size() >= 7) {
+                                        path.erase(0, 7);
+                                        if (filesystem::file_in_path(path, project_path)) {
+                                          usages.emplace_back(Usages{path, nullptr,
+                                                                     std::vector<std::pair<Offset, Offset>>()});
+                                          for (auto edit_it = file_it->second.begin();
+                                               edit_it != file_it->second.end(); ++edit_it) {
+                                            auto range_it = edit_it->second.find("range");
+                                            if (range_it != edit_it->second.not_found()) {
+                                              auto start_it = range_it->second.find("start");
+                                              auto end_it = range_it->second.find("end");
+                                              if (start_it != range_it->second.not_found() &&
+                                                  end_it != range_it->second.not_found())
+                                                usages.back().offsets.emplace_back(
+                                                    std::make_pair(
+                                                        Offset(start_it->second.get<unsigned>(
+                                                            "line"),
+                                                               start_it->second.get<unsigned>(
+                                                                   "character")),
+                                                        Offset(end_it->second.get<unsigned>(
+                                                            "line"),
+                                                               end_it->second.get<unsigned>(
+                                                                   "character"))));
+                                            }
+                                          }
+                                        }
+                                      }
+                                    }
+                                  } else {
+                                    auto changes_pt = result.get_child("documentChanges",
+                                                                       boost::property_tree::ptree());
+                                    for (auto change_it = changes_pt.begin();
+                                         change_it != changes_pt.end(); ++change_it) {
+                                      auto document_it = change_it->second.find("textDocument");
+                                      if (document_it != change_it->second.not_found()) {
+                                        auto path = document_it->second.get<std::string>("uri", "");
+                                        if (path.size() >= 7) {
+                                          path.erase(0, 7);
+                                          if (filesystem::file_in_path(path, project_path)) {
+                                            usages.emplace_back(
+                                                Usages{path, std::make_unique<std::string>(),
+                                                       std::vector<std::pair<Offset, Offset>>()});
+                                            auto edits_pt = change_it->second.get_child("edits",
+                                                                                        boost::property_tree::ptree());
+                                            for (auto edit_it = edits_pt.begin();
+                                                 edit_it != edits_pt.end(); ++edit_it) {
+                                              auto new_text_it = edit_it->second.find(
+                                                  "newText");
+                                              if (new_text_it != edit_it->second.not_found()) {
+                                                auto range_it = edit_it->second.find("range");
+                                                if (range_it != edit_it->second.not_found()) {
+                                                  auto start_it = range_it->second.find(
+                                                      "start");
+                                                  auto end_it = range_it->second.find(
+                                                      "end");
+                                                  if (start_it !=
+                                                      range_it->second.not_found() &&
+                                                      end_it !=
+                                                      range_it->second.not_found()) {
+                                                    auto end_line = end_it->second.get<size_t>(
+                                                        "line");
+                                                    if (end_line >
+                                                        std::numeric_limits<int>::max())
+                                                      end_line = std::numeric_limits<int>::max();
+                                                    *usages.back().new_text = new_text_it->second.get_value<std::string>();
+                                                    usages.back().offsets.emplace_back(
+                                                        std::make_pair(
+                                                            Offset(start_it->second.get<unsigned>(
+                                                                "line"),
+                                                                   start_it->second.get<unsigned>(
+                                                                       "character")),
+                                                            Offset(static_cast<unsigned>(end_line),
+                                                                   end_it->second.get<unsigned>(
+                                                                       "character"))));
                                                   }
+                                                }
                                               }
+                                            }
                                           }
-                                          catch (...) {
-                                              usages.clear();
-                                          }
+                                        }
                                       }
-                                      result_processed.set_value();
-                                  });
-            result_processed.get_future().get();
-
-            std::vector<Usages *> usages_renamed;
-            for (auto &usage: usages) {
-                auto view_it = views.end();
-                for (auto it = views.begin(); it != views.end(); ++it) {
-                    if ((*it)->file_path == usage.path) {
-                        view_it = it;
-                        break;
-                    }
-                }
-                if (view_it != views.end()) {
-                    (*view_it)->get_buffer()->begin_user_action();
-                    auto iter = get_buffer()->get_insert()->get_iter();
-                    auto line = iter.get_line();
-                    auto offset = iter.get_line_offset();
-                    for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
-                        auto start_iter = (*view_it)->get_iter_at_line_pos(offset_it->first.line,
-                                                                           offset_it->first.index);
-                        auto end_iter = (*view_it)->get_iter_at_line_pos(offset_it->second.line,
-                                                                         offset_it->second.index);
-                        (*view_it)->get_buffer()->erase(start_iter, end_iter);
-                        start_iter = (*view_it)->get_iter_at_line_pos(offset_it->first.line, offset_it->first.index);
-                        if (usage.new_text)
-                            (*view_it)->get_buffer()->insert(start_iter, *usage.new_text);
-                        else
-                            (*view_it)->get_buffer()->insert(start_iter, text);
-                    }
-                    if (usage.new_text && get_buffer()->get_insert()->get_iter().is_end()) {
-                        place_cursor_at_line_offset(line, offset);
-                        hide_tooltips();
-                        scroll_to_cursor_delayed(this, true, false);
-                    }
-                    (*view_it)->get_buffer()->end_user_action();
-                    (*view_it)->save();
-                    usages_renamed.emplace_back(&usage);
-                } else {
-                    Glib::ustring buffer;
-                    {
-                        std::ifstream stream(usage.path.string(), std::ifstream::binary);
-                        if (stream)
-                            buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
-                    }
-                    std::ofstream stream(usage.path.string(), std::ifstream::binary);
-                    if (!buffer.empty() && stream) {
-                        std::vector<size_t> lines_start_pos = {0};
-                        for (size_t c = 0; c < buffer.size(); ++c) {
-                            if (buffer[c] == '\n')
-                                lines_start_pos.emplace_back(c + 1);
-                        }
-                        for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
-                            auto start_line = offset_it->first.line;
-                            auto end_line = offset_it->second.line;
-                            if (start_line < lines_start_pos.size()) {
-                                auto start = lines_start_pos[start_line] + offset_it->first.index;
-                                unsigned end;
-                                if (end_line >= lines_start_pos.size())
-                                    end = buffer.size();
-                                else
-                                    end = lines_start_pos[end_line] + offset_it->second.index;
-                                if (start < buffer.size() && end <= buffer.size()) {
-                                    if (usage.new_text)
-                                        buffer.replace(start, end - start, *usage.new_text);
-                                    else
-                                        buffer.replace(start, end - start, text);
+                                    }
+                                  }
                                 }
-                            }
-                        }
-                        stream.write(buffer.data(), buffer.bytes());
-                        usages_renamed.emplace_back(&usage);
-                    } else
-                        Terminal::get().print("Error: could not write to file " + usage.path.string() + '\n', true);
-                }
+                                catch (...) {
+                                  usages.clear();
+                                }
+                              }
+                              result_processed.set_value();
+                            });
+      result_processed.get_future().get();
+
+      std::vector<Usages *> usages_renamed;
+      for (auto &usage: usages) {
+        auto view_it = views.end();
+        for (auto it = views.begin(); it != views.end(); ++it) {
+          if ((*it)->file_path == usage.path) {
+            view_it = it;
+            break;
+          }
+        }
+        if (view_it != views.end()) {
+          (*view_it)->get_buffer()->begin_user_action();
+          auto iter = get_buffer()->get_insert()->get_iter();
+          auto line = iter.get_line();
+          auto offset = iter.get_line_offset();
+          for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
+            auto start_iter = (*view_it)->get_iter_at_line_pos(offset_it->first.line,
+                                                               offset_it->first.index);
+            auto end_iter = (*view_it)->get_iter_at_line_pos(offset_it->second.line,
+                                                             offset_it->second.index);
+            (*view_it)->get_buffer()->erase(start_iter, end_iter);
+            start_iter = (*view_it)->get_iter_at_line_pos(offset_it->first.line, offset_it->first.index);
+            if (usage.new_text)
+              (*view_it)->get_buffer()->insert(start_iter, *usage.new_text);
+            else
+              (*view_it)->get_buffer()->insert(start_iter, text);
+          }
+          if (usage.new_text && get_buffer()->get_insert()->get_iter().is_end()) {
+            place_cursor_at_line_offset(line, offset);
+            hide_tooltips();
+            scroll_to_cursor_delayed(this, true, false);
+          }
+          (*view_it)->get_buffer()->end_user_action();
+          (*view_it)->save();
+          usages_renamed.emplace_back(&usage);
+        } else {
+          Glib::ustring buffer;
+          {
+            std::ifstream stream(usage.path.string(), std::ifstream::binary);
+            if (stream)
+              buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
+          }
+          std::ofstream stream(usage.path.string(), std::ifstream::binary);
+          if (!buffer.empty() && stream) {
+            std::vector<size_t> lines_start_pos = {0};
+            for (size_t c = 0; c < buffer.size(); ++c) {
+              if (buffer[c] == '\n')
+                lines_start_pos.emplace_back(c + 1);
             }
-
-            if (!usages_renamed.empty()) {
-                Terminal::get().print("Renamed ");
-                Terminal::get().print(previous_text, true);
-                Terminal::get().print(" to ");
-                Terminal::get().print(text, true);
-                Terminal::get().print("\n");
+            for (auto offset_it = usage.offsets.rbegin(); offset_it != usage.offsets.rend(); ++offset_it) {
+              auto start_line = offset_it->first.line;
+              auto end_line = offset_it->second.line;
+              if (start_line < lines_start_pos.size()) {
+                auto start = lines_start_pos[start_line] + offset_it->first.index;
+                unsigned end;
+                if (end_line >= lines_start_pos.size())
+                  end = buffer.size();
+                else
+                  end = lines_start_pos[end_line] + offset_it->second.index;
+                if (start < buffer.size() && end <= buffer.size()) {
+                  if (usage.new_text)
+                    buffer.replace(start, end - start, *usage.new_text);
+                  else
+                    buffer.replace(start, end - start, text);
+                }
+              }
             }
-        };
-    }
-
-    goto_next_diagnostic = [this]() {
-        place_cursor_at_next_diagnostic();
+            stream.write(buffer.data(), buffer.bytes());
+            usages_renamed.emplace_back(&usage);
+          } else
+            Terminal::get().print("Error: could not write to file " + usage.path.string() + '\n', true);
+        }
+      }
+
+      if (!usages_renamed.empty()) {
+        Terminal::get().print("Renamed ");
+        Terminal::get().print(previous_text, true);
+        Terminal::get().print(" to ");
+        Terminal::get().print(text, true);
+        Terminal::get().print("\n");
+      }
     };
+  }
+
+  goto_next_diagnostic = [this]() {
+    place_cursor_at_next_diagnostic();
+  };
 }
 
 void Source::LanguageProtocolView::escape_text(std::string &text) {
-    for (size_t c = 0; c < text.size(); ++c) {
-        if (text[c] == '\n') {
-            text.replace(c, 1, "\\n");
-            ++c;
-        } else if (text[c] == '\r') {
-            text.replace(c, 1, "\\r");
-            ++c;
-        } else if (text[c] == '\"') {
-            text.replace(c, 1, "\\\"");
-            ++c;
-        }
+  for (size_t c = 0; c < text.size(); ++c) {
+    if (text[c] == '\n') {
+      text.replace(c, 1, "\\n");
+      ++c;
+    } else if (text[c] == '\r') {
+      text.replace(c, 1, "\\r");
+      ++c;
+    } else if (text[c] == '\"') {
+      text.replace(c, 1, "\\\"");
+      ++c;
     }
+  }
 }
 
 void Source::LanguageProtocolView::unescape_text(std::string &text) {
-    for (size_t c = 0; c < text.size(); ++c) {
-        if (text[c] == '\\' && c + 1 < text.size()) {
-            if (text[c + 1] == 'n')
-                text.replace(c, 2, "\n");
-            else if (text[c + 1] == 'r')
-                text.replace(c, 2, "\r");
-            else
-                text.erase(c, 1);
-        }
+  for (size_t c = 0; c < text.size(); ++c) {
+    if (text[c] == '\\' && c + 1 < text.size()) {
+      if (text[c + 1] == 'n')
+        text.replace(c, 2, "\n");
+      else if (text[c + 1] == 'r')
+        text.replace(c, 2, "\r");
+      else
+        text.erase(c, 1);
     }
+  }
 }
 
 void Source::LanguageProtocolView::update_diagnostics(std::vector<LanguageProtocol::Diagnostic> &&diagnostics) {
-    dispatcher.post([this, diagnostics = std::move(diagnostics)] {
-        clear_diagnostic_tooltips();
-        num_warnings = 0;
-        num_errors = 0;
-        num_fix_its = 0;
-        for (auto &diagnostic: diagnostics) {
-            if (diagnostic.uri == uri) {
-                auto start = get_iter_at_line_pos(diagnostic.offsets.first.line, diagnostic.offsets.first.index);
-                auto end = get_iter_at_line_pos(diagnostic.offsets.second.line, diagnostic.offsets.second.index);
-
-                if (start == end) {
-                    if (!end.is_end())
-                        end.forward_char();
-                    else
-                        start.forward_char();
-                }
+  dispatcher.post([this, diagnostics = std::move(diagnostics)] {
+    clear_diagnostic_tooltips();
+    num_warnings = 0;
+    num_errors = 0;
+    num_fix_its = 0;
+    for (auto &diagnostic: diagnostics) {
+      if (diagnostic.uri == uri) {
+        auto start = get_iter_at_line_pos(diagnostic.offsets.first.line, diagnostic.offsets.first.index);
+        auto end = get_iter_at_line_pos(diagnostic.offsets.second.line, diagnostic.offsets.second.index);
 
-                bool error = false;
-                std::string severity_tag_name;
-                if (diagnostic.severity >= 2) {
-                    severity_tag_name = "def:warning";
-                    num_warnings++;
-                } else {
-                    severity_tag_name = "def:error";
-                    num_errors++;
-                    error = true;
-                }
+        if (start == end) {
+          if (!end.is_end())
+            end.forward_char();
+          else
+            start.forward_char();
+        }
 
-                add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
-            }
+        bool error = false;
+        std::string severity_tag_name;
+        if (diagnostic.severity >= 2) {
+          severity_tag_name = "def:warning";
+          num_warnings++;
+        } else {
+          severity_tag_name = "def:error";
+          num_errors++;
+          error = true;
         }
 
-        for (auto &mark: flow_coverage_marks)
-            add_diagnostic_tooltip(mark.first->get_iter(), mark.second->get_iter(), flow_coverage_message, false);
+        add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
+      }
+    }
 
-        status_diagnostics = std::make_tuple(num_warnings + num_flow_coverage_warnings, num_errors, num_fix_its);
-        if (update_status_diagnostics)
-            update_status_diagnostics(this);
-    });
+    for (auto &mark: flow_coverage_marks)
+      add_diagnostic_tooltip(mark.first->get_iter(), mark.second->get_iter(), flow_coverage_message, false);
+
+    status_diagnostics = std::make_tuple(num_warnings + num_flow_coverage_warnings, num_errors, num_fix_its);
+    if (update_status_diagnostics)
+      update_status_diagnostics(this);
+  });
 }
 
 Gtk::TextIter Source::LanguageProtocolView::get_iter_at_line_pos(int line, int pos) {
-    return get_iter_at_line_offset(line, pos);
+  return get_iter_at_line_offset(line, pos);
 }
 
 void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rectangle) {
-    if (!capabilities.hover)
-        return;
-
-    Gtk::TextIter iter;
-    int location_x, location_y;
-    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x,
-                            location_y);
-    location_x += (rectangle.get_width() - 1) / 2;
-    get_iter_at_location(iter, location_x, location_y);
-    Gdk::Rectangle iter_rectangle;
-    get_iter_location(iter, iter_rectangle);
-    if (iter.ends_line() && location_x > iter_rectangle.get_x())
-        return;
-
-    auto offset = iter.get_offset();
+  if (!capabilities.hover)
+    return;
+
+  Gtk::TextIter iter;
+  int location_x, location_y;
+  window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x,
+                          location_y);
+  location_x += (rectangle.get_width() - 1) / 2;
+  get_iter_at_location(iter, location_x, location_y);
+  Gdk::Rectangle iter_rectangle;
+  get_iter_location(iter, iter_rectangle);
+  if (iter.ends_line() && location_x > iter_rectangle.get_x())
+    return;
+
+  auto offset = iter.get_offset();
+
+  static int request_count = 0;
+  request_count++;
+  auto current_request = request_count;
+  client->write_request(this, "textDocument/hover", "\"textDocument\": {\"uri\":\"file://" + file_path.string() +
+                                                    "\"}, \"position\": {\"line\": " +
+                                                    std::to_string(iter.get_line()) + ", \"character\": " +
+                                                    std::to_string(iter.get_line_offset()) + "}",
+                        [this, offset, current_request](const boost::property_tree::ptree &result, bool error) {
+                          if (!error) {
+                            // hover result structure vary significantly from the different language servers
+                            std::string content;
+                            auto contents_pt = result.get_child("contents", boost::property_tree::ptree());
+                            for (auto it = contents_pt.begin(); it != contents_pt.end(); ++it) {
+                              auto value = it->second.get<std::string>("value", "");
+                              if (!value.empty())
+                                content.insert(0, value + (content.empty() ? "" : "\n\n"));
+                              else {
+                                value = it->second.get_value<std::string>("");
+                                if (!value.empty())
+                                  content += (content.empty() ? "" : "\n\n") + value;
+                              }
+                            }
+                            if (content.empty()) {
+                              auto contents_it = result.find("contents");
+                              if (contents_it != result.not_found()) {
+                                content = contents_it->second.get<std::string>("value", "");
+                                if (content.empty())
+                                  content = contents_it->second.get_value<std::string>("");
+                              }
+                            }
+                            if (!content.empty()) {
+                              dispatcher.post([this, offset, content = std::move(content), current_request] {
+                                if (current_request != request_count)
+                                  return;
+                                if (offset >= get_buffer()->get_char_count())
+                                  return;
+                                type_tooltips.clear();
+                                auto create_tooltip_buffer = [this, offset, content = std::move(content)]() {
+                                  auto tooltip_buffer = Gtk::TextBuffer::create(
+                                      get_buffer()->get_tag_table());
+                                  tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), content);
 
-    static int request_count = 0;
-    request_count++;
-    auto current_request = request_count;
-    client->write_request(this, "textDocument/hover", "\"textDocument\": {\"uri\":\"file://" + file_path.string() +
-                                                      "\"}, \"position\": {\"line\": " +
-                                                      std::to_string(iter.get_line()) + ", \"character\": " +
-                                                      std::to_string(iter.get_line_offset()) + "}",
-                          [this, offset, current_request](const boost::property_tree::ptree &result, bool error) {
-                              if (!error) {
-                                  // hover result structure vary significantly from the different language servers
-                                  std::string content;
-                                  auto contents_pt = result.get_child("contents", boost::property_tree::ptree());
-                                  for (auto it = contents_pt.begin(); it != contents_pt.end(); ++it) {
-                                      auto value = it->second.get<std::string>("value", "");
-                                      if (!value.empty())
-                                          content.insert(0, value + (content.empty() ? "" : "\n\n"));
-                                      else {
-                                          value = it->second.get_value<std::string>("");
-                                          if (!value.empty())
-                                              content += (content.empty() ? "" : "\n\n") + value;
+#ifdef JUCI_ENABLE_DEBUG
+                                  if(language_id=="rust" && capabilities.definition) {
+                                    if(Debug::LLDB::get().is_stopped()) {
+                                      Glib::ustring value_type="Value";
+
+                                      auto start=get_buffer()->get_iter_at_offset(offset);
+                                      auto end=start;
+                                      auto previous=start;
+                                      while(previous.backward_char() && ((*previous>='A' && *previous<='Z') || (*previous>='a' && *previous<='z') || (*previous>='0' && *previous<='9') || *previous=='_') && start.backward_char()) {}
+                                      while(((*end>='A' && *end<='Z') || (*end>='a' && *end<='z') || (*end>='0' && *end<='9') || *end=='_') && end.forward_char()) {}
+
+                                      auto offset=get_declaration(start);
+                                      Glib::ustring debug_value=Debug::LLDB::get().get_value(get_buffer()->get_text(start, end), offset.file_path, offset.line+1, offset.index+1);
+                                      if(debug_value.empty()) {
+                                        value_type="Return value";
+                                        debug_value=Debug::LLDB::get().get_return_value(file_path, start.get_line()+1, start.get_line_index()+1);
                                       }
-                                  }
-                                  if (content.empty()) {
-                                      auto contents_it = result.find("contents");
-                                      if (contents_it != result.not_found()) {
-                                          content = contents_it->second.get<std::string>("value", "");
-                                          if (content.empty())
-                                              content = contents_it->second.get_value<std::string>("");
+                                      if(!debug_value.empty()) {
+                                        size_t pos=debug_value.find(" = ");
+                                        if(pos!=Glib::ustring::npos) {
+                                          Glib::ustring::iterator iter;
+                                          while(!debug_value.validate(iter)) {
+                                            auto next_char_iter=iter;
+                                            next_char_iter++;
+                                            debug_value.replace(iter, next_char_iter, "?");
+                                          }
+                                          tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1));
+                                        }
                                       }
+                                    }
                                   }
-                                  if (!content.empty()) {
-                                      dispatcher.post([this, offset, content = std::move(content), current_request] {
-                                          if (current_request != request_count)
-                                              return;
-                                          if (offset >= get_buffer()->get_char_count())
-                                              return;
-                                          type_tooltips.clear();
-                                          auto create_tooltip_buffer = [this, offset, content = std::move(content)]() {
-                                              auto tooltip_buffer = Gtk::TextBuffer::create(
-                                                      get_buffer()->get_tag_table());
-                                              tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), content);
-
-#ifdef JUCI_ENABLE_DEBUG
-                                              if(language_id=="rust" && capabilities.definition) {
-                                                if(Debug::LLDB::get().is_stopped()) {
-                                                  Glib::ustring value_type="Value";
-
-                                                  auto start=get_buffer()->get_iter_at_offset(offset);
-                                                  auto end=start;
-                                                  auto previous=start;
-                                                  while(previous.backward_char() && ((*previous>='A' && *previous<='Z') || (*previous>='a' && *previous<='z') || (*previous>='0' && *previous<='9') || *previous=='_') && start.backward_char()) {}
-                                                  while(((*end>='A' && *end<='Z') || (*end>='a' && *end<='z') || (*end>='0' && *end<='9') || *end=='_') && end.forward_char()) {}
-
-                                                  auto offset=get_declaration(start);
-                                                  Glib::ustring debug_value=Debug::LLDB::get().get_value(get_buffer()->get_text(start, end), offset.file_path, offset.line+1, offset.index+1);
-                                                  if(debug_value.empty()) {
-                                                    value_type="Return value";
-                                                    debug_value=Debug::LLDB::get().get_return_value(file_path, start.get_line()+1, start.get_line_index()+1);
-                                                  }
-                                                  if(!debug_value.empty()) {
-                                                    size_t pos=debug_value.find(" = ");
-                                                    if(pos!=Glib::ustring::npos) {
-                                                      Glib::ustring::iterator iter;
-                                                      while(!debug_value.validate(iter)) {
-                                                        auto next_char_iter=iter;
-                                                        next_char_iter++;
-                                                        debug_value.replace(iter, next_char_iter, "?");
-                                                      }
-                                                      tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1));
-                                                    }
-                                                  }
-                                                }
-                                              }
 #endif
 
-                                              return tooltip_buffer;
-                                          };
-
-                                          auto start = get_buffer()->get_iter_at_offset(offset);
-                                          auto end = start;
-                                          auto previous = start;
-                                          while (previous.backward_char() && ((*previous >= 'A' && *previous <= 'Z') ||
-                                                                              (*previous >= 'a' && *previous <= 'z') ||
-                                                                              (*previous >= '0' && *previous <= '9') ||
-                                                                              *previous == '_') &&
-                                                 start.backward_char()) {}
-                                          while (((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') ||
-                                                  (*end >= '0' && *end <= '9') || *end == '_') && end.forward_char()) {}
-                                          type_tooltips.emplace_back(create_tooltip_buffer, this,
-                                                                     get_buffer()->create_mark(start),
-                                                                     get_buffer()->create_mark(end));
-                                          type_tooltips.show();
-                                      });
-                                  }
-                              }
-                          });
+                                  return tooltip_buffer;
+                                };
+
+                                auto start = get_buffer()->get_iter_at_offset(offset);
+                                auto end = start;
+                                auto previous = start;
+                                while (previous.backward_char() && ((*previous >= 'A' && *previous <= 'Z') ||
+                                                                    (*previous >= 'a' && *previous <= 'z') ||
+                                                                    (*previous >= '0' && *previous <= '9') ||
+                                                                    *previous == '_') &&
+                                       start.backward_char()) {}
+                                while (((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') ||
+                                        (*end >= '0' && *end <= '9') || *end == '_') && end.forward_char()) {}
+                                type_tooltips.emplace_back(create_tooltip_buffer, this,
+                                                           get_buffer()->create_mark(start),
+                                                           get_buffer()->create_mark(end));
+                                type_tooltips.show();
+                              });
+                            }
+                          }
+                        });
 }
 
 void Source::LanguageProtocolView::tag_similar_symbols() {
-    if (!capabilities.document_highlight && !capabilities.references)
-        return;
-
-    auto iter = get_buffer()->get_insert()->get_iter();
-    std::string method;
-    if (capabilities.document_highlight)
-        method = "textDocument/documentHighlight";
-    else
-        method = "textDocument/references";
-
-    static int request_count = 0;
-    request_count++;
-    auto current_request = request_count;
-    client->write_request(this, method, "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
-                                        std::to_string(iter.get_line()) + ", \"character\": " +
-                                        std::to_string(iter.get_line_offset()) +
-                                        "}, \"context\": {\"includeDeclaration\": true}",
-                          [this, current_request](const boost::property_tree::ptree &result, bool error) {
-                              if (!error) {
-                                  std::vector<std::pair<Offset, Offset>> offsets;
-                                  for (auto it = result.begin(); it != result.end(); ++it) {
-                                      if (capabilities.document_highlight ||
-                                          it->second.get<std::string>("uri", "") == uri) {
-                                          auto range_it = it->second.find("range");
-                                          if (range_it != it->second.not_found()) {
-                                              auto start_it = range_it->second.find("start");
-                                              auto end_it = range_it->second.find("end");
-                                              if (start_it != range_it->second.not_found() &&
-                                                  end_it != range_it->second.not_found()) {
-                                                  try {
-                                                      offsets.emplace_back(std::make_pair(
-                                                              Offset(start_it->second.get<unsigned>("line"),
-                                                                     start_it->second.get<unsigned>("character")),
-                                                              Offset(end_it->second.get<unsigned>("line"),
-                                                                     end_it->second.get<unsigned>("character"))));
-                                                  }
-                                                  catch (...) {}
-                                              }
-                                          }
-                                      }
+  if (!capabilities.document_highlight && !capabilities.references)
+    return;
+
+  auto iter = get_buffer()->get_insert()->get_iter();
+  std::string method;
+  if (capabilities.document_highlight)
+    method = "textDocument/documentHighlight";
+  else
+    method = "textDocument/references";
+
+  static int request_count = 0;
+  request_count++;
+  auto current_request = request_count;
+  client->write_request(this, method, "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                                      std::to_string(iter.get_line()) + ", \"character\": " +
+                                      std::to_string(iter.get_line_offset()) +
+                                      "}, \"context\": {\"includeDeclaration\": true}",
+                        [this, current_request](const boost::property_tree::ptree &result, bool error) {
+                          if (!error) {
+                            std::vector<std::pair<Offset, Offset>> offsets;
+                            for (auto it = result.begin(); it != result.end(); ++it) {
+                              if (capabilities.document_highlight ||
+                                  it->second.get<std::string>("uri", "") == uri) {
+                                auto range_it = it->second.find("range");
+                                if (range_it != it->second.not_found()) {
+                                  auto start_it = range_it->second.find("start");
+                                  auto end_it = range_it->second.find("end");
+                                  if (start_it != range_it->second.not_found() &&
+                                      end_it != range_it->second.not_found()) {
+                                    try {
+                                      offsets.emplace_back(std::make_pair(
+                                          Offset(start_it->second.get<unsigned>("line"),
+                                                 start_it->second.get<unsigned>("character")),
+                                          Offset(end_it->second.get<unsigned>("line"),
+                                                 end_it->second.get<unsigned>("character"))));
+                                    }
+                                    catch (...) {}
                                   }
-                                  dispatcher.post([this, offsets = std::move(offsets), current_request] {
-                                      if (current_request != request_count)
-                                          return;
-                                      get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(),
-                                                               get_buffer()->end());
-                                      for (auto &pair: offsets) {
-                                          auto start = get_iter_at_line_pos(pair.first.line, pair.first.index);
-                                          auto end = get_iter_at_line_pos(pair.second.line, pair.second.index);
-                                          get_buffer()->apply_tag(similar_symbol_tag, start, end);
-                                      }
-                                  });
+                                }
                               }
-                          });
+                            }
+                            dispatcher.post([this, offsets = std::move(offsets), current_request] {
+                              if (current_request != request_count)
+                                return;
+                              get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(),
+                                                       get_buffer()->end());
+                              for (auto &pair: offsets) {
+                                auto start = get_iter_at_line_pos(pair.first.line, pair.first.index);
+                                auto end = get_iter_at_line_pos(pair.second.line, pair.second.index);
+                                get_buffer()->apply_tag(similar_symbol_tag, start, end);
+                              }
+                            });
+                          }
+                        });
 }
 
 Source::Offset Source::LanguageProtocolView::get_declaration(const Gtk::TextIter &iter) {
-    auto offset = std::make_shared<Offset>();
-    std::promise<void> result_processed;
-    client->write_request(this, "textDocument/definition",
-                          "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
-                          std::to_string(iter.get_line()) + ", \"character\": " +
-                          std::to_string(iter.get_line_offset()) + "}",
-                          [offset, &result_processed](const boost::property_tree::ptree &result, bool error) {
-                              if (!error) {
-                                  for (auto it = result.begin(); it != result.end(); ++it) {
-                                      auto uri = it->second.get<std::string>("uri", "");
-                                      if (uri.compare(0, 7, "file://") == 0)
-                                          uri.erase(0, 7);
-                                      auto range = it->second.find("range");
-                                      if (range != it->second.not_found()) {
-                                          auto start = range->second.find("start");
-                                          if (start != range->second.not_found())
-                                              *offset = Offset(start->second.get<unsigned>("line", 0),
-                                                               start->second.get<unsigned>("character", 0), uri);
-                                      }
-                                      break; // TODO: can a language server return several definitions?
-                                  }
+  auto offset = std::make_shared<Offset>();
+  std::promise<void> result_processed;
+  client->write_request(this, "textDocument/definition",
+                        "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                        std::to_string(iter.get_line()) + ", \"character\": " +
+                        std::to_string(iter.get_line_offset()) + "}",
+                        [offset, &result_processed](const boost::property_tree::ptree &result, bool error) {
+                          if (!error) {
+                            for (auto it = result.begin(); it != result.end(); ++it) {
+                              auto uri = it->second.get<std::string>("uri", "");
+                              if (uri.compare(0, 7, "file://") == 0)
+                                uri.erase(0, 7);
+                              auto range = it->second.find("range");
+                              if (range != it->second.not_found()) {
+                                auto start = range->second.find("start");
+                                if (start != range->second.not_found())
+                                  *offset = Offset(start->second.get<unsigned>("line", 0),
+                                                   start->second.get<unsigned>("character", 0), uri);
                               }
-                              result_processed.set_value();
-                          });
-    result_processed.get_future().get();
-    return *offset;
+                              break; // TODO: can a language server return several definitions?
+                            }
+                          }
+                          result_processed.set_value();
+                        });
+  result_processed.get_future().get();
+  return *offset;
 }
 
 void Source::LanguageProtocolView::setup_autocomplete() {
-    if (!capabilities.completion)
-        return;
+  if (!capabilities.completion)
+    return;
 
-    non_interactive_completion = [this] {
-        if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
-            return;
-        autocomplete.run();
-    };
+  non_interactive_completion = [this] {
+    if (CompletionDialog::get() && CompletionDialog::get()->is_visible())
+      return;
+    autocomplete.run();
+  };
 
-    autocomplete.reparse = [this] {
-        autocomplete_comment.clear();
-        autocomplete_insert.clear();
-    };
+  autocomplete.reparse = [this] {
+    autocomplete_comment.clear();
+    autocomplete_insert.clear();
+  };
 
-    autocomplete.is_continue_key = [](guint keyval) {
-        if ((keyval >= '0' && keyval <= '9') || (keyval >= 'a' && keyval <= 'z') || (keyval >= 'A' && keyval <= 'Z') ||
-            keyval == '_')
-            return true;
+  autocomplete.is_continue_key = [](guint keyval) {
+    if ((keyval >= '0' && keyval <= '9') || (keyval >= 'a' && keyval <= 'z') || (keyval >= 'A' && keyval <= 'Z') ||
+        keyval == '_')
+      return true;
 
-        return false;
-    };
-
-    autocomplete.is_restart_key = [this](guint keyval) {
-        auto iter = get_buffer()->get_insert()->get_iter();
-        iter.backward_chars(2);
-        if (keyval == '.' || (keyval == ':' && *iter == ':'))
-            return true;
-        return false;
-    };
-
-    autocomplete.run_check = [this]() {
-        auto iter = get_buffer()->get_insert()->get_iter();
-        iter.backward_char();
-        if (!is_code_iter(iter))
-            return false;
-
-        std::string line = " " + get_line_before();
-        const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>\"'](\\.)([a-zA-Z0-9_]*)$");
-        const static std::regex colon_colon("^.*::([a-zA-Z0-9_]*)$");
-        const static std::regex part_of_symbol("^.*[^a-zA-Z0-9_]+([a-zA-Z0-9_]{3,})$");
-        std::smatch sm;
-        if (std::regex_match(line, sm, dot_or_arrow)) {
-            {
-                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-                autocomplete.prefix = sm[2].str();
-            }
-            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
-                return true;
-        } else if (std::regex_match(line, sm, colon_colon)) {
-            {
-                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-                autocomplete.prefix = sm[1].str();
-            }
-            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
-                return true;
-        } else if (std::regex_match(line, sm, part_of_symbol)) {
-            {
-                std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-                autocomplete.prefix = sm[1].str();
-            }
-            if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
-                return true;
-        } else if (!interactive_completion) {
-            auto end_iter = get_buffer()->get_insert()->get_iter();
-            auto iter = end_iter;
-            while (iter.backward_char() && autocomplete.is_continue_key(*iter)) {}
-            if (iter != end_iter)
-                iter.forward_char();
-            std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
-            autocomplete.prefix = get_buffer()->get_text(iter, end_iter);
-            return true;
-        }
+    return false;
+  };
 
-        return false;
-    };
+  autocomplete.is_restart_key = [this](guint keyval) {
+    auto iter = get_buffer()->get_insert()->get_iter();
+    iter.backward_chars(2);
+    if (keyval == '.' || (keyval == ':' && *iter == ':'))
+      return true;
+    return false;
+  };
 
-    autocomplete.before_add_rows = [this] {
-        status_state = "autocomplete...";
-        if (update_status_state)
-            update_status_state(this);
-    };
+  autocomplete.run_check = [this]() {
+    auto iter = get_buffer()->get_insert()->get_iter();
+    iter.backward_char();
+    if (!is_code_iter(iter))
+      return false;
+
+    std::string line = " " + get_line_before();
+    const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>\"'](\\.)([a-zA-Z0-9_]*)$");
+    const static std::regex colon_colon("^.*::([a-zA-Z0-9_]*)$");
+    const static std::regex part_of_symbol("^.*[^a-zA-Z0-9_]+([a-zA-Z0-9_]{3,})$");
+    std::smatch sm;
+    if (std::regex_match(line, sm, dot_or_arrow)) {
+      {
+        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+        autocomplete.prefix = sm[2].str();
+      }
+      if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+        return true;
+    } else if (std::regex_match(line, sm, colon_colon)) {
+      {
+        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+        autocomplete.prefix = sm[1].str();
+      }
+      if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+        return true;
+    } else if (std::regex_match(line, sm, part_of_symbol)) {
+      {
+        std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+        autocomplete.prefix = sm[1].str();
+      }
+      if (autocomplete.prefix.size() == 0 || autocomplete.prefix[0] < '0' || autocomplete.prefix[0] > '9')
+        return true;
+    } else if (!interactive_completion) {
+      auto end_iter = get_buffer()->get_insert()->get_iter();
+      auto iter = end_iter;
+      while (iter.backward_char() && autocomplete.is_continue_key(*iter)) {}
+      if (iter != end_iter)
+        iter.forward_char();
+      std::unique_lock<std::mutex> lock(autocomplete.prefix_mutex);
+      autocomplete.prefix = get_buffer()->get_text(iter, end_iter);
+      return true;
+    }
 
-    autocomplete.after_add_rows = [this] {
-        status_state = "";
-        if (update_status_state)
-            update_status_state(this);
-    };
+    return false;
+  };
 
-    autocomplete.on_add_rows_error = [this] {
-        autocomplete_comment.clear();
-        autocomplete_insert.clear();
-    };
+  autocomplete.before_add_rows = [this] {
+    status_state = "autocomplete...";
+    if (update_status_state)
+      update_status_state(this);
+  };
 
-    autocomplete.add_rows = [this](std::string &buffer, int line_number, int column) {
-        if (autocomplete.state == Autocomplete::State::STARTING) {
-            autocomplete_comment.clear();
-            autocomplete_insert.clear();
-            std::promise<void> result_processed;
-            client->write_request(this, "textDocument/completion",
-                                  "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
-                                  std::to_string(line_number - 1) + ", \"character\": " + std::to_string(column - 1) +
-                                  "}",
-                                  [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
-                                      if (!error) {
-                                          auto begin = result.begin(); // rust language server is bugged
-                                          auto end = result.end();
-                                          auto items_it = result.find("items"); // correct
-                                          if (items_it != result.not_found()) {
-                                              begin = items_it->second.begin();
-                                              end = items_it->second.end();
-                                          }
-                                          for (auto it = begin; it != end; ++it) {
-                                              auto label = it->second.get<std::string>("label", "");
-                                              auto detail = it->second.get<std::string>("detail", "");
-                                              auto documentation = it->second.get<std::string>("documentation", "");
-                                              auto insert = it->second.get<std::string>("insertText", "");
-                                              if (insert.empty()) {
-                                                  insert = label;
-                                                  auto kind = it->second.get<unsigned>("kind", 0);
-                                                  if (kind >= 2 && kind <= 3) {
-                                                      bool found_bracket = false;
-                                                      for (auto &chr: insert) {
-                                                          if (chr == '(' || chr == '{') {
-                                                              found_bracket = true;
-                                                              break;
-                                                          }
-                                                      }
-                                                      if (!found_bracket)
-                                                          insert += "(${1:})";
-                                                  }
-                                              }
-                                              if (!label.empty()) {
-                                                  autocomplete.rows.emplace_back(std::move(label));
-                                                  autocomplete_comment.emplace_back(std::move(detail));
-                                                  if (!documentation.empty()) {
-                                                      if (!autocomplete_comment.back().empty())
-                                                          autocomplete_comment.back() += "\n\n";
-                                                      autocomplete_comment.back() += documentation;
-                                                  }
-                                                  autocomplete_insert.emplace_back(std::move(insert));
-                                              }
-                                          }
+  autocomplete.after_add_rows = [this] {
+    status_state = "";
+    if (update_status_state)
+      update_status_state(this);
+  };
+
+  autocomplete.on_add_rows_error = [this] {
+    autocomplete_comment.clear();
+    autocomplete_insert.clear();
+  };
+
+  autocomplete.add_rows = [this](std::string &buffer, int line_number, int column) {
+    if (autocomplete.state == Autocomplete::State::STARTING) {
+      autocomplete_comment.clear();
+      autocomplete_insert.clear();
+      std::promise<void> result_processed;
+      client->write_request(this, "textDocument/completion",
+                            "\"textDocument\":{\"uri\":\"" + uri + "\"}, \"position\": {\"line\": " +
+                            std::to_string(line_number - 1) + ", \"character\": " + std::to_string(column - 1) +
+                            "}",
+                            [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
+                              if (!error) {
+                                auto begin = result.begin(); // rust language server is bugged
+                                auto end = result.end();
+                                auto items_it = result.find("items"); // correct
+                                if (items_it != result.not_found()) {
+                                  begin = items_it->second.begin();
+                                  end = items_it->second.end();
+                                }
+                                for (auto it = begin; it != end; ++it) {
+                                  auto label = it->second.get<std::string>("label", "");
+                                  auto detail = it->second.get<std::string>("detail", "");
+                                  auto documentation = it->second.get<std::string>("documentation", "");
+                                  auto insert = it->second.get<std::string>("insertText", "");
+                                  if (insert.empty()) {
+                                    insert = label;
+                                    auto kind = it->second.get<unsigned>("kind", 0);
+                                    if (kind >= 2 && kind <= 3) {
+                                      bool found_bracket = false;
+                                      for (auto &chr: insert) {
+                                        if (chr == '(' || chr == '{') {
+                                          found_bracket = true;
+                                          break;
+                                        }
                                       }
-                                      result_processed.set_value();
-                                  });
-            result_processed.get_future().get();
-        }
-    };
-
-    signal_key_press_event().connect([this](GdkEventKey *event) {
-        if ((event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_ISO_Left_Tab) &&
-            (event->state & GDK_SHIFT_MASK) == 0) {
-            if (!autocomplete_marks.empty()) {
-                auto it = autocomplete_marks.begin();
-                auto start = it->first->get_iter();
-                auto end = it->second->get_iter();
-                if (start == end)
-                    return false;
-                autocomplete_keep_marks = true;
-                get_buffer()->select_range(it->first->get_iter(), it->second->get_iter());
-                autocomplete_keep_marks = false;
-                get_buffer()->delete_mark(it->first);
-                get_buffer()->delete_mark(it->second);
-                autocomplete_marks.erase(it);
-                return true;
+                                      if (!found_bracket)
+                                        insert += "(${1:})";
+                                    }
+                                  }
+                                  if (!label.empty()) {
+                                    autocomplete.rows.emplace_back(std::move(label));
+                                    autocomplete_comment.emplace_back(std::move(detail));
+                                    if (!documentation.empty()) {
+                                      if (!autocomplete_comment.back().empty())
+                                        autocomplete_comment.back() += "\n\n";
+                                      autocomplete_comment.back() += documentation;
+                                    }
+                                    autocomplete_insert.emplace_back(std::move(insert));
+                                  }
+                                }
+                              }
+                              result_processed.set_value();
+                            });
+      result_processed.get_future().get();
+    }
+  };
+
+  signal_key_press_event().connect([this](GdkEventKey *event) {
+    if ((event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_ISO_Left_Tab) &&
+        (event->state & GDK_SHIFT_MASK) == 0) {
+      if (!autocomplete_marks.empty()) {
+        auto it = autocomplete_marks.begin();
+        auto start = it->first->get_iter();
+        auto end = it->second->get_iter();
+        if (start == end)
+          return false;
+        autocomplete_keep_marks = true;
+        get_buffer()->select_range(it->first->get_iter(), it->second->get_iter());
+        autocomplete_keep_marks = false;
+        get_buffer()->delete_mark(it->first);
+        get_buffer()->delete_mark(it->second);
+        autocomplete_marks.erase(it);
+        return true;
+      }
+    }
+    return false;
+  }, false);
+
+  get_buffer()->signal_mark_set().connect(
+      [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+        if (mark->get_name() == "insert") {
+          if (!autocomplete_keep_marks) {
+            for (auto &pair: autocomplete_marks) {
+              get_buffer()->delete_mark(pair.first);
+              get_buffer()->delete_mark(pair.second);
             }
+            autocomplete_marks.clear();
+          }
         }
-        return false;
-    }, false);
-
-    get_buffer()->signal_mark_set().connect(
-            [this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-                if (mark->get_name() == "insert") {
-                    if (!autocomplete_keep_marks) {
-                        for (auto &pair: autocomplete_marks) {
-                            get_buffer()->delete_mark(pair.first);
-                            get_buffer()->delete_mark(pair.second);
-                        }
-                        autocomplete_marks.clear();
-                    }
-                }
-            });
+      });
 
-    autocomplete.on_show = [this] {
-        for (auto &pair: autocomplete_marks) {
-            get_buffer()->delete_mark(pair.first);
-            get_buffer()->delete_mark(pair.second);
+  autocomplete.on_show = [this] {
+    for (auto &pair: autocomplete_marks) {
+      get_buffer()->delete_mark(pair.first);
+      get_buffer()->delete_mark(pair.second);
+    }
+    autocomplete_marks.clear();
+    hide_tooltips();
+  };
+
+  autocomplete.on_hide = [this] {
+    autocomplete_comment.clear();
+    autocomplete_insert.clear();
+  };
+
+  autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
+    get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
+    if (hide_window) {
+      Glib::ustring insert = autocomplete_insert[index];
+
+      // Do not insert function/template parameters if they already exist
+      auto iter = get_buffer()->get_insert()->get_iter();
+      if (*iter == '(' || *iter == '<') {
+        auto bracket_pos = insert.find(*iter);
+        if (bracket_pos != std::string::npos) {
+          insert = insert.substr(0, bracket_pos);
         }
-        autocomplete_marks.clear();
-        hide_tooltips();
-    };
-
-    autocomplete.on_hide = [this] {
-        autocomplete_comment.clear();
-        autocomplete_insert.clear();
-    };
-
-    autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
-        get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
-        if (hide_window) {
-            Glib::ustring insert = autocomplete_insert[index];
-
-            // Do not insert function/template parameters if they already exist
-            auto iter = get_buffer()->get_insert()->get_iter();
-            if (*iter == '(' || *iter == '<') {
-                auto bracket_pos = insert.find(*iter);
-                if (bracket_pos != std::string::npos) {
-                    insert = insert.substr(0, bracket_pos);
-                }
-            }
-
-            // Find and add position marks that one can move to using tab-key
-            size_t pos1 = 0;
-            std::vector<std::pair<size_t, size_t>> mark_offsets;
-            while ((pos1 = insert.find("${"), pos1) != Glib::ustring::npos) {
-                size_t pos2 = insert.find(":", pos1 + 2);
-                if (pos2 != Glib::ustring::npos) {
-                    size_t pos3 = insert.find("}", pos2 + 1);
-                    if (pos3 != Glib::ustring::npos) {
-                        size_t length = pos3 - pos2 - 1;
-                        insert.erase(pos3, 1);
-                        insert.erase(pos1, pos2 - pos1 + 1);
-                        mark_offsets.emplace_back(pos1, pos1 + length);
-                        pos1 += length;
-                    } else
-                        break;
-                } else
-                    break;
-            }
-            get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), insert);
-            for (auto &offset: mark_offsets) {
-                auto start = CompletionDialog::get()->start_mark->get_iter();
-                auto end = start;
-                start.forward_chars(offset.first);
-                end.forward_chars(offset.second);
-                autocomplete_marks.emplace_back(get_buffer()->create_mark(start), get_buffer()->create_mark(end));
-            }
-            if (!autocomplete_marks.empty()) {
-                auto it = autocomplete_marks.begin();
-                autocomplete_keep_marks = true;
-                get_buffer()->select_range(it->first->get_iter(), it->second->get_iter());
-                autocomplete_keep_marks = false;
-                get_buffer()->delete_mark(it->first);
-                get_buffer()->delete_mark(it->second);
-                autocomplete_marks.erase(it);
-            }
+      }
+
+      // Find and add position marks that one can move to using tab-key
+      size_t pos1 = 0;
+      std::vector<std::pair<size_t, size_t>> mark_offsets;
+      while ((pos1 = insert.find("${"), pos1) != Glib::ustring::npos) {
+        size_t pos2 = insert.find(":", pos1 + 2);
+        if (pos2 != Glib::ustring::npos) {
+          size_t pos3 = insert.find("}", pos2 + 1);
+          if (pos3 != Glib::ustring::npos) {
+            size_t length = pos3 - pos2 - 1;
+            insert.erase(pos3, 1);
+            insert.erase(pos1, pos2 - pos1 + 1);
+            mark_offsets.emplace_back(pos1, pos1 + length);
+            pos1 += length;
+          } else
+            break;
         } else
-            get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), text);
-    };
-
-    autocomplete.get_tooltip = [this](unsigned int index) {
-        return autocomplete_comment[index];
-    };
+          break;
+      }
+      get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), insert);
+      for (auto &offset: mark_offsets) {
+        auto start = CompletionDialog::get()->start_mark->get_iter();
+        auto end = start;
+        start.forward_chars(offset.first);
+        end.forward_chars(offset.second);
+        autocomplete_marks.emplace_back(get_buffer()->create_mark(start), get_buffer()->create_mark(end));
+      }
+      if (!autocomplete_marks.empty()) {
+        auto it = autocomplete_marks.begin();
+        autocomplete_keep_marks = true;
+        get_buffer()->select_range(it->first->get_iter(), it->second->get_iter());
+        autocomplete_keep_marks = false;
+        get_buffer()->delete_mark(it->first);
+        get_buffer()->delete_mark(it->second);
+        autocomplete_marks.erase(it);
+      }
+    } else
+      get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), text);
+  };
+
+  autocomplete.get_tooltip = [this](unsigned int index) {
+    return autocomplete_comment[index];
+  };
 }
 
 void Source::LanguageProtocolView::add_flow_coverage_tooltips(bool called_in_thread) {
-    std::stringstream stdin_stream, stderr_stream;
-    auto stdout_stream = std::make_shared<std::stringstream>();
-    auto exit_status = Terminal::get().process(stdin_stream, *stdout_stream,
-                                               flow_coverage_executable.string() + " coverage --json " +
-                                               file_path.string(), "", &stderr_stream);
-    auto f = [this, exit_status, stdout_stream] {
-        clear_diagnostic_tooltips();
-        num_flow_coverage_warnings = 0;
-        for (auto &mark: flow_coverage_marks) {
-            get_buffer()->delete_mark(mark.first);
-            get_buffer()->delete_mark(mark.second);
-        }
-        flow_coverage_marks.clear();
-
-        if (exit_status == 0) {
-            boost::property_tree::ptree pt;
-            try {
-                boost::property_tree::read_json(*stdout_stream, pt);
-                auto uncovered_locs_pt = pt.get_child("expressions.uncovered_locs");
-                for (auto it = uncovered_locs_pt.begin(); it != uncovered_locs_pt.end(); ++it) {
-                    auto start_pt = it->second.get_child("start");
-                    auto start = get_iter_at_line_offset(start_pt.get<int>("line") - 1,
-                                                         start_pt.get<int>("column") - 1);
-                    auto end_pt = it->second.get_child("end");
-                    auto end = get_iter_at_line_offset(end_pt.get<int>("line") - 1, end_pt.get<int>("column"));
-
-                    add_diagnostic_tooltip(start, end, flow_coverage_message, false);
-                    ++num_flow_coverage_warnings;
-
-                    flow_coverage_marks.emplace_back(get_buffer()->create_mark(start), get_buffer()->create_mark(end));
-                }
-            }
-            catch (...) {}
+  std::stringstream stdin_stream, stderr_stream;
+  auto stdout_stream = std::make_shared<std::stringstream>();
+  auto exit_status = Terminal::get().process(stdin_stream, *stdout_stream,
+                                             flow_coverage_executable.string() + " coverage --json " +
+                                             file_path.string(), "", &stderr_stream);
+  auto f = [this, exit_status, stdout_stream] {
+    clear_diagnostic_tooltips();
+    num_flow_coverage_warnings = 0;
+    for (auto &mark: flow_coverage_marks) {
+      get_buffer()->delete_mark(mark.first);
+      get_buffer()->delete_mark(mark.second);
+    }
+    flow_coverage_marks.clear();
+
+    if (exit_status == 0) {
+      boost::property_tree::ptree pt;
+      try {
+        boost::property_tree::read_json(*stdout_stream, pt);
+        auto uncovered_locs_pt = pt.get_child("expressions.uncovered_locs");
+        for (auto it = uncovered_locs_pt.begin(); it != uncovered_locs_pt.end(); ++it) {
+          auto start_pt = it->second.get_child("start");
+          auto start = get_iter_at_line_offset(start_pt.get<int>("line") - 1,
+                                               start_pt.get<int>("column") - 1);
+          auto end_pt = it->second.get_child("end");
+          auto end = get_iter_at_line_offset(end_pt.get<int>("line") - 1, end_pt.get<int>("column"));
+
+          add_diagnostic_tooltip(start, end, flow_coverage_message, false);
+          ++num_flow_coverage_warnings;
+
+          flow_coverage_marks.emplace_back(get_buffer()->create_mark(start), get_buffer()->create_mark(end));
         }
-        status_diagnostics = std::make_tuple(num_warnings + num_flow_coverage_warnings, num_errors, num_fix_its);
-        if (update_status_diagnostics)
-            update_status_diagnostics(this);
-    };
-    if (called_in_thread)
-        dispatcher.post(std::move(f));
-    else
-        f();
+      }
+      catch (...) {}
+    }
+    status_diagnostics = std::make_tuple(num_warnings + num_flow_coverage_warnings, num_errors, num_fix_its);
+    if (update_status_diagnostics)
+      update_status_diagnostics(this);
+  };
+  if (called_in_thread)
+    dispatcher.post(std::move(f));
+  else
+    f();
 }
diff --git a/src/source_language_protocol.h b/src/source_language_protocol.h
index dccd3574..bb068108 100644
--- a/src/source_language_protocol.h
+++ b/src/source_language_protocol.h
@@ -11,144 +11,144 @@
 #include <unordered_set>
 
 namespace Source {
-    class LanguageProtocolView;
+  class LanguageProtocolView;
 }
 
 namespace LanguageProtocol {
-    class Diagnostic {
-    public:
-        std::string spelling;
-        std::pair<Source::Offset, Source::Offset> offsets;
-        unsigned severity;
-        std::string uri;
+  class Diagnostic {
+  public:
+    std::string spelling;
+    std::pair<Source::Offset, Source::Offset> offsets;
+    unsigned severity;
+    std::string uri;
+  };
+
+  class Capabilities {
+  public:
+    enum class TextDocumentSync {
+      NONE = 0,
+      FULL,
+      INCREMENTAL
     };
+    TextDocumentSync text_document_sync;
+    bool hover;
+    bool completion;
+    bool definition;
+    bool references;
+    bool document_highlight;
+    bool workspace_symbol;
+    bool document_formatting;
+    bool document_range_formatting;
+    bool rename;
+  };
 
-    class Capabilities {
-    public:
-        enum class TextDocumentSync {
-            NONE = 0,
-            FULL,
-            INCREMENTAL
-        };
-        TextDocumentSync text_document_sync;
-        bool hover;
-        bool completion;
-        bool definition;
-        bool references;
-        bool document_highlight;
-        bool workspace_symbol;
-        bool document_formatting;
-        bool document_range_formatting;
-        bool rename;
-    };
-
-    class Client {
-        Client(std::string root_uri, std::string language_id);
+  class Client {
+    Client(std::string root_uri, std::string language_id);
 
-        std::string root_uri;
-        std::string language_id;
+    std::string root_uri;
+    std::string language_id;
 
-        Capabilities capabilities;
+    Capabilities capabilities;
 
-        std::unordered_set<Source::LanguageProtocolView *> views;
-        std::mutex views_mutex;
+    std::unordered_set<Source::LanguageProtocolView *> views;
+    std::mutex views_mutex;
 
-        std::mutex initialize_mutex;
+    std::mutex initialize_mutex;
 
-        std::unique_ptr<TinyProcessLib::Process> process;
-        std::mutex read_write_mutex;
+    std::unique_ptr<TinyProcessLib::Process> process;
+    std::mutex read_write_mutex;
 
-        std::stringstream server_message_stream;
-        size_t server_message_size = static_cast<size_t>(-1);
-        size_t server_message_content_pos;
-        bool header_read = false;
+    std::stringstream server_message_stream;
+    size_t server_message_size = static_cast<size_t>(-1);
+    size_t server_message_content_pos;
+    bool header_read = false;
 
-        size_t message_id = 1;
+    size_t message_id = 1;
 
-        std::unordered_map<size_t, std::pair<Source::LanguageProtocolView *, std::function<void(
-                const boost::property_tree::ptree &, bool error)>>> handlers;
-        std::vector<std::thread> timeout_threads;
-        std::mutex timeout_threads_mutex;
+    std::unordered_map<size_t, std::pair<Source::LanguageProtocolView *, std::function<void(
+        const boost::property_tree::ptree &, bool error)>>> handlers;
+    std::vector<std::thread> timeout_threads;
+    std::mutex timeout_threads_mutex;
 
-    public:
-        static std::shared_ptr<Client> get(const boost::filesystem::path &file_path, const std::string &language_id);
+  public:
+    static std::shared_ptr<Client> get(const boost::filesystem::path &file_path, const std::string &language_id);
 
-        ~Client();
+    ~Client();
 
-        bool initialized = false;
+    bool initialized = false;
 
-        Capabilities initialize(Source::LanguageProtocolView *view);
+    Capabilities initialize(Source::LanguageProtocolView *view);
 
-        void close(Source::LanguageProtocolView *view);
+    void close(Source::LanguageProtocolView *view);
 
-        void parse_server_message();
+    void parse_server_message();
 
-        void write_request(Source::LanguageProtocolView *view, const std::string &method, const std::string &params,
-                           std::function<void(const boost::property_tree::ptree &, bool)> &&function = nullptr);
+    void write_request(Source::LanguageProtocolView *view, const std::string &method, const std::string &params,
+                       std::function<void(const boost::property_tree::ptree &, bool)> &&function = nullptr);
 
-        void write_notification(const std::string &method, const std::string &params);
+    void write_notification(const std::string &method, const std::string &params);
 
-        void handle_server_request(const std::string &method, const boost::property_tree::ptree &params);
-    };
+    void handle_server_request(const std::string &method, const boost::property_tree::ptree &params);
+  };
 } // namespace LanguageProtocol
 
 namespace Source {
-    class LanguageProtocolView : public View {
-    public:
-        LanguageProtocolView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language,
-                             std::string language_id_);
+  class LanguageProtocolView : public View {
+  public:
+    LanguageProtocolView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language,
+                         std::string language_id_);
 
-        ~LanguageProtocolView();
+    ~LanguageProtocolView();
 
-        std::string uri;
+    std::string uri;
 
-        bool save() override;
+    bool save() override;
 
-        void update_diagnostics(std::vector<LanguageProtocol::Diagnostic> &&diagnostics);
+    void update_diagnostics(std::vector<LanguageProtocol::Diagnostic> &&diagnostics);
 
-        Gtk::TextIter get_iter_at_line_pos(int line, int pos) override;
+    Gtk::TextIter get_iter_at_line_pos(int line, int pos) override;
 
-    protected:
-        void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
+  protected:
+    void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
 
-    private:
-        std::string language_id;
-        LanguageProtocol::Capabilities capabilities;
+  private:
+    std::string language_id;
+    LanguageProtocol::Capabilities capabilities;
 
-        std::shared_ptr<LanguageProtocol::Client> client;
+    std::shared_ptr<LanguageProtocol::Client> client;
 
-        size_t document_version = 1;
+    size_t document_version = 1;
 
-        std::thread initialize_thread;
-        Dispatcher dispatcher;
+    std::thread initialize_thread;
+    Dispatcher dispatcher;
 
-        void setup_navigation_and_refactoring();
+    void setup_navigation_and_refactoring();
 
-        void escape_text(std::string &text);
+    void escape_text(std::string &text);
 
-        void unescape_text(std::string &text);
+    void unescape_text(std::string &text);
 
-        Glib::RefPtr<Gtk::TextTag> similar_symbol_tag;
-        sigc::connection delayed_tag_similar_symbols_connection;
+    Glib::RefPtr<Gtk::TextTag> similar_symbol_tag;
+    sigc::connection delayed_tag_similar_symbols_connection;
 
-        void tag_similar_symbols();
+    void tag_similar_symbols();
 
-        Offset get_declaration(const Gtk::TextIter &iter);
+    Offset get_declaration(const Gtk::TextIter &iter);
 
-        Autocomplete autocomplete;
+    Autocomplete autocomplete;
 
-        void setup_autocomplete();
+    void setup_autocomplete();
 
-        std::vector<std::string> autocomplete_comment;
-        std::vector<std::string> autocomplete_insert;
-        std::list<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, Glib::RefPtr<Gtk::TextBuffer::Mark>>> autocomplete_marks;
-        bool autocomplete_keep_marks = false;
+    std::vector<std::string> autocomplete_comment;
+    std::vector<std::string> autocomplete_insert;
+    std::list<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, Glib::RefPtr<Gtk::TextBuffer::Mark>>> autocomplete_marks;
+    bool autocomplete_keep_marks = false;
 
-        boost::filesystem::path flow_coverage_executable;
-        std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark>>> flow_coverage_marks;
-        const std::string flow_coverage_message = "Not covered by Flow";
-        size_t num_warnings = 0, num_errors = 0, num_fix_its = 0, num_flow_coverage_warnings = 0;
+    boost::filesystem::path flow_coverage_executable;
+    std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark>>> flow_coverage_marks;
+    const std::string flow_coverage_message = "Not covered by Flow";
+    size_t num_warnings = 0, num_errors = 0, num_fix_its = 0, num_flow_coverage_warnings = 0;
 
-        void add_flow_coverage_tooltips(bool called_in_thread);
-    };
+    void add_flow_coverage_tooltips(bool called_in_thread);
+  };
 } // namespace Source
diff --git a/src/source_spellcheck.cc b/src/source_spellcheck.cc
index ff2bb227..3785ce4e 100644
--- a/src/source_spellcheck.cc
+++ b/src/source_spellcheck.cc
@@ -7,506 +7,506 @@
 AspellConfig *Source::SpellCheckView::spellcheck_config = nullptr;
 
 Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language)
-        : BaseView(file_path, language) {
-    if (spellcheck_config == nullptr)
-        spellcheck_config = new_aspell_config();
-    spellcheck_checker = nullptr;
-    spellcheck_error_tag = get_buffer()->create_tag("spellcheck_error");
-    spellcheck_error_tag->property_underline() = Pango::Underline::UNDERLINE_ERROR;
-
-    signal_key_press_event().connect([](GdkEventKey *event) {
-        if (SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
-            if (SelectionDialog::get()->on_key_press(event))
-                return true;
-        }
+    : BaseView(file_path, language) {
+  if (spellcheck_config == nullptr)
+    spellcheck_config = new_aspell_config();
+  spellcheck_checker = nullptr;
+  spellcheck_error_tag = get_buffer()->create_tag("spellcheck_error");
+  spellcheck_error_tag->property_underline() = Pango::Underline::UNDERLINE_ERROR;
+
+  signal_key_press_event().connect([](GdkEventKey *event) {
+    if (SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
+      if (SelectionDialog::get()->on_key_press(event))
+        return true;
+    }
 
-        return false;
-    }, false);
+    return false;
+  }, false);
 
-    //The following signal is added in case SpellCheckView is not subclassed
-    signal_key_press_event().connect([this](GdkEventKey *event) {
-        last_keyval = event->keyval;
-        return false;
-    });
+  //The following signal is added in case SpellCheckView is not subclassed
+  signal_key_press_event().connect([this](GdkEventKey *event) {
+    last_keyval = event->keyval;
+    return false;
+  });
 
-    get_buffer()->signal_changed().connect([this]() {
-        if (spellcheck_checker == nullptr)
-            return;
+  get_buffer()->signal_changed().connect([this]() {
+    if (spellcheck_checker == nullptr)
+      return;
 
-        delayed_spellcheck_suggestions_connection.disconnect();
+    delayed_spellcheck_suggestions_connection.disconnect();
 
-        auto iter = get_buffer()->get_insert()->get_iter();
-        if (!is_word_iter(iter) && !iter.starts_line())
-            iter.backward_char();
+    auto iter = get_buffer()->get_insert()->get_iter();
+    if (!is_word_iter(iter) && !iter.starts_line())
+      iter.backward_char();
+
+    if (disable_spellcheck) {
+      if (is_word_iter(iter)) {
+        auto word = get_word(iter);
+        get_buffer()->remove_tag(spellcheck_error_tag, word.first, word.second);
+      }
+      return;
+    }
 
-        if (disable_spellcheck) {
-            if (is_word_iter(iter)) {
-                auto word = get_word(iter);
-                get_buffer()->remove_tag(spellcheck_error_tag, word.first, word.second);
-            }
-            return;
+    if (!is_code_iter(iter)) {
+      if (last_keyval == GDK_KEY_Return || last_keyval == GDK_KEY_KP_Enter) {
+        auto previous_line_iter = iter;
+        while (previous_line_iter.backward_char() && !previous_line_iter.ends_line()) {}
+        if (previous_line_iter.backward_char()) {
+          get_buffer()->remove_tag(spellcheck_error_tag, previous_line_iter, iter);
+          if (!is_code_iter(previous_line_iter)) {
+            auto word = get_word(previous_line_iter);
+            spellcheck_word(word.first, word.second);
+          }
+          auto word = get_word(iter);
+          spellcheck_word(word.first, word.second);
         }
+      } else {
+        auto previous_iter = iter;
+        //When for instance using space to split two words
+        if (!iter.starts_line() && !iter.ends_line() && is_word_iter(iter) &&
+            previous_iter.backward_char() && !previous_iter.starts_line() && !is_word_iter(previous_iter)) {
+          auto first = previous_iter;
+          auto second = iter;
+          if (first.backward_char()) {
+            get_buffer()->remove_tag(spellcheck_error_tag, first, second);
+            auto word = get_word(first);
+            spellcheck_word(word.first, word.second);
+            word = get_word(second);
+            spellcheck_word(word.first, word.second);
+          }
+        } else {
+          auto word = get_word(iter);
+          spellcheck_word(word.first, word.second);
+        }
+      }
+    }
+    delayed_spellcheck_error_clear.disconnect();
+    delayed_spellcheck_error_clear = Glib::signal_timeout().connect([this]() {
+      auto iter = get_buffer()->begin();
+      Gtk::TextIter begin_no_spellcheck_iter;
+      if (spellcheck_all) {
+        bool spell_check = !get_source_buffer()->iter_has_context_class(iter, "no-spell-check");
+        if (!spell_check)
+          begin_no_spellcheck_iter = iter;
+        while (iter != get_buffer()->end()) {
+          if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
+            iter = get_buffer()->end();
+
+          spell_check = !spell_check;
+          if (!spell_check)
+            begin_no_spellcheck_iter = iter;
+          else
+            get_buffer()->remove_tag(spellcheck_error_tag, begin_no_spellcheck_iter, iter);
+        }
+        return false;
+      }
+
+      bool spell_check = get_source_buffer()->iter_has_context_class(iter, "string") ||
+                         get_source_buffer()->iter_has_context_class(iter, "comment");
+      if (!spell_check)
+        begin_no_spellcheck_iter = iter;
+      while (iter != get_buffer()->end()) {
+        auto iter1 = iter;
+        auto iter2 = iter;
+        if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string"))
+          iter1 = get_buffer()->end();
+        if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
+          iter2 = get_buffer()->end();
+
+        if (iter2 < iter1)
+          iter = iter2;
+        else
+          iter = iter1;
+        spell_check = !spell_check;
+        if (!spell_check)
+          begin_no_spellcheck_iter = iter;
+        else
+          get_buffer()->remove_tag(spellcheck_error_tag, begin_no_spellcheck_iter, iter);
+      }
+      return false;
+    }, 1000);
+  });
+
+  // In case of for instance text paste or undo/redo
+  get_buffer()->signal_insert().connect(
+      [this](const Gtk::TextIter &start_iter, const Glib::ustring &inserted_string, int) {
+        if (spellcheck_checker == nullptr)
+          return;
 
-        if (!is_code_iter(iter)) {
-            if (last_keyval == GDK_KEY_Return || last_keyval == GDK_KEY_KP_Enter) {
-                auto previous_line_iter = iter;
-                while (previous_line_iter.backward_char() && !previous_line_iter.ends_line()) {}
-                if (previous_line_iter.backward_char()) {
-                    get_buffer()->remove_tag(spellcheck_error_tag, previous_line_iter, iter);
-                    if (!is_code_iter(previous_line_iter)) {
-                        auto word = get_word(previous_line_iter);
-                        spellcheck_word(word.first, word.second);
-                    }
-                    auto word = get_word(iter);
-                    spellcheck_word(word.first, word.second);
-                }
-            } else {
-                auto previous_iter = iter;
-                //When for instance using space to split two words
-                if (!iter.starts_line() && !iter.ends_line() && is_word_iter(iter) &&
-                    previous_iter.backward_char() && !previous_iter.starts_line() && !is_word_iter(previous_iter)) {
-                    auto first = previous_iter;
-                    auto second = iter;
-                    if (first.backward_char()) {
-                        get_buffer()->remove_tag(spellcheck_error_tag, first, second);
-                        auto word = get_word(first);
-                        spellcheck_word(word.first, word.second);
-                        word = get_word(second);
-                        spellcheck_word(word.first, word.second);
-                    }
-                } else {
-                    auto word = get_word(iter);
-                    spellcheck_word(word.first, word.second);
-                }
-            }
+        if (!disable_spellcheck)
+          return;
+
+        auto iter = start_iter;
+        if (!is_word_iter(iter) && !iter.starts_line())
+          iter.backward_char();
+        if (is_word_iter(iter)) {
+          auto word = get_word(iter);
+          get_buffer()->remove_tag(spellcheck_error_tag, word.first, word.second);
         }
-        delayed_spellcheck_error_clear.disconnect();
-        delayed_spellcheck_error_clear = Glib::signal_timeout().connect([this]() {
-            auto iter = get_buffer()->begin();
-            Gtk::TextIter begin_no_spellcheck_iter;
-            if (spellcheck_all) {
-                bool spell_check = !get_source_buffer()->iter_has_context_class(iter, "no-spell-check");
-                if (!spell_check)
-                    begin_no_spellcheck_iter = iter;
-                while (iter != get_buffer()->end()) {
-                    if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
-                        iter = get_buffer()->end();
-
-                    spell_check = !spell_check;
-                    if (!spell_check)
-                        begin_no_spellcheck_iter = iter;
-                    else
-                        get_buffer()->remove_tag(spellcheck_error_tag, begin_no_spellcheck_iter, iter);
+      }, false);
+
+  get_buffer()->signal_mark_set().connect(
+      [this](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+        if (spellcheck_checker == nullptr)
+          return;
+
+        if (mark->get_name() == "insert") {
+          if (SelectionDialog::get())
+            SelectionDialog::get()->hide();
+          delayed_spellcheck_suggestions_connection.disconnect();
+          delayed_spellcheck_suggestions_connection = Glib::signal_timeout().connect([this]() {
+            if (get_buffer()->get_insert()->get_iter().has_tag(spellcheck_error_tag)) {
+              SelectionDialog::create(this,
+                                      get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()),
+                                      false);
+              auto word = get_word(get_buffer()->get_insert()->get_iter());
+              if (*word.first == '\'' && word.second.get_offset() - word.first.get_offset() >= 3) {
+                auto before_end = word.second;
+                if (before_end.backward_char() && *before_end == '\'') {
+                  word.first.forward_char();
+                  word.second.backward_char();
                 }
+              }
+              auto suggestions = get_spellcheck_suggestions(word.first, word.second);
+              if (suggestions.size() == 0)
                 return false;
-            }
-
-            bool spell_check = get_source_buffer()->iter_has_context_class(iter, "string") ||
-                               get_source_buffer()->iter_has_context_class(iter, "comment");
-            if (!spell_check)
-                begin_no_spellcheck_iter = iter;
-            while (iter != get_buffer()->end()) {
-                auto iter1 = iter;
-                auto iter2 = iter;
-                if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string"))
-                    iter1 = get_buffer()->end();
-                if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
-                    iter2 = get_buffer()->end();
-
-                if (iter2 < iter1)
-                    iter = iter2;
-                else
-                    iter = iter1;
-                spell_check = !spell_check;
-                if (!spell_check)
-                    begin_no_spellcheck_iter = iter;
-                else
-                    get_buffer()->remove_tag(spellcheck_error_tag, begin_no_spellcheck_iter, iter);
+              for (auto &suggestion: suggestions)
+                SelectionDialog::get()->add_row(suggestion);
+              SelectionDialog::get()->on_select = [this, word](unsigned int index,
+                                                               const std::string &text,
+                                                               bool hide_window) {
+                get_buffer()->begin_user_action();
+                get_buffer()->erase(word.first, word.second);
+                get_buffer()->insert(get_buffer()->get_insert()->get_iter(), text);
+                get_buffer()->end_user_action();
+              };
+              hide_tooltips();
+              SelectionDialog::get()->show();
             }
             return false;
-        }, 1000);
-    });
-
-    // In case of for instance text paste or undo/redo
-    get_buffer()->signal_insert().connect(
-            [this](const Gtk::TextIter &start_iter, const Glib::ustring &inserted_string, int) {
-                if (spellcheck_checker == nullptr)
-                    return;
-
-                if (!disable_spellcheck)
-                    return;
-
-                auto iter = start_iter;
-                if (!is_word_iter(iter) && !iter.starts_line())
-                    iter.backward_char();
-                if (is_word_iter(iter)) {
-                    auto word = get_word(iter);
-                    get_buffer()->remove_tag(spellcheck_error_tag, word.first, word.second);
-                }
-            }, false);
-
-    get_buffer()->signal_mark_set().connect(
-            [this](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-                if (spellcheck_checker == nullptr)
-                    return;
-
-                if (mark->get_name() == "insert") {
-                    if (SelectionDialog::get())
-                        SelectionDialog::get()->hide();
-                    delayed_spellcheck_suggestions_connection.disconnect();
-                    delayed_spellcheck_suggestions_connection = Glib::signal_timeout().connect([this]() {
-                        if (get_buffer()->get_insert()->get_iter().has_tag(spellcheck_error_tag)) {
-                            SelectionDialog::create(this,
-                                                    get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()),
-                                                    false);
-                            auto word = get_word(get_buffer()->get_insert()->get_iter());
-                            if (*word.first == '\'' && word.second.get_offset() - word.first.get_offset() >= 3) {
-                                auto before_end = word.second;
-                                if (before_end.backward_char() && *before_end == '\'') {
-                                    word.first.forward_char();
-                                    word.second.backward_char();
-                                }
-                            }
-                            auto suggestions = get_spellcheck_suggestions(word.first, word.second);
-                            if (suggestions.size() == 0)
-                                return false;
-                            for (auto &suggestion: suggestions)
-                                SelectionDialog::get()->add_row(suggestion);
-                            SelectionDialog::get()->on_select = [this, word](unsigned int index,
-                                                                             const std::string &text,
-                                                                             bool hide_window) {
-                                get_buffer()->begin_user_action();
-                                get_buffer()->erase(word.first, word.second);
-                                get_buffer()->insert(get_buffer()->get_insert()->get_iter(), text);
-                                get_buffer()->end_user_action();
-                            };
-                            hide_tooltips();
-                            SelectionDialog::get()->show();
-                        }
-                        return false;
-                    }, 500);
-                }
-            });
+          }, 500);
+        }
+      });
 
-    get_buffer()->signal_mark_set().connect(
-            [](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
-                if (mark->get_name() == "insert") {
-                    if (SelectionDialog::get())
-                        SelectionDialog::get()->hide();
-                }
-            });
+  get_buffer()->signal_mark_set().connect(
+      [](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
+        if (mark->get_name() == "insert") {
+          if (SelectionDialog::get())
+            SelectionDialog::get()->hide();
+        }
+      });
 
-    signal_focus_out_event().connect([this](GdkEventFocus *event) {
-        delayed_spellcheck_suggestions_connection.disconnect();
-        return false;
-    });
+  signal_focus_out_event().connect([this](GdkEventFocus *event) {
+    delayed_spellcheck_suggestions_connection.disconnect();
+    return false;
+  });
 
-    signal_leave_notify_event().connect([this](GdkEventCrossing *) {
-        delayed_spellcheck_suggestions_connection.disconnect();
-        return false;
-    });
-
-    signal_tag_added_connection = get_buffer()->get_tag_table()->signal_tag_added().connect(
-            [this](const Glib::RefPtr<Gtk::TextTag> &tag) {
-                if (tag->property_name() == "gtksourceview:context-classes:comment")
-                    comment_tag = tag;
-                else if (tag->property_name() == "gtksourceview:context-classes:string")
-                    string_tag = tag;
-                else if (tag->property_name() == "gtksourceview:context-classes:no-spell-check")
-                    no_spell_check_tag = tag;
-            });
-    signal_tag_removed_connection = get_buffer()->get_tag_table()->signal_tag_removed().connect(
-            [this](const Glib::RefPtr<Gtk::TextTag> &tag) {
-                if (tag->property_name() == "gtksourceview:context-classes:comment")
-                    comment_tag.reset();
-                else if (tag->property_name() == "gtksourceview:context-classes:string")
-                    string_tag.reset();
-                else if (tag->property_name() == "gtksourceview:context-classes:no-spell-check")
-                    no_spell_check_tag.reset();
-            });
+  signal_leave_notify_event().connect([this](GdkEventCrossing *) {
+    delayed_spellcheck_suggestions_connection.disconnect();
+    return false;
+  });
+
+  signal_tag_added_connection = get_buffer()->get_tag_table()->signal_tag_added().connect(
+      [this](const Glib::RefPtr<Gtk::TextTag> &tag) {
+        if (tag->property_name() == "gtksourceview:context-classes:comment")
+          comment_tag = tag;
+        else if (tag->property_name() == "gtksourceview:context-classes:string")
+          string_tag = tag;
+        else if (tag->property_name() == "gtksourceview:context-classes:no-spell-check")
+          no_spell_check_tag = tag;
+      });
+  signal_tag_removed_connection = get_buffer()->get_tag_table()->signal_tag_removed().connect(
+      [this](const Glib::RefPtr<Gtk::TextTag> &tag) {
+        if (tag->property_name() == "gtksourceview:context-classes:comment")
+          comment_tag.reset();
+        else if (tag->property_name() == "gtksourceview:context-classes:string")
+          string_tag.reset();
+        else if (tag->property_name() == "gtksourceview:context-classes:no-spell-check")
+          no_spell_check_tag.reset();
+      });
 }
 
 Source::SpellCheckView::~SpellCheckView() {
-    delayed_spellcheck_suggestions_connection.disconnect();
-    delayed_spellcheck_error_clear.disconnect();
+  delayed_spellcheck_suggestions_connection.disconnect();
+  delayed_spellcheck_error_clear.disconnect();
 
-    if (spellcheck_checker != nullptr)
-        delete_aspell_speller(spellcheck_checker);
+  if (spellcheck_checker != nullptr)
+    delete_aspell_speller(spellcheck_checker);
 
-    signal_tag_added_connection.disconnect();
-    signal_tag_removed_connection.disconnect();
+  signal_tag_added_connection.disconnect();
+  signal_tag_removed_connection.disconnect();
 }
 
 void Source::SpellCheckView::configure() {
-    if (Config::get().source.spellcheck_language.size() > 0) {
-        aspell_config_replace(spellcheck_config, "lang", Config::get().source.spellcheck_language.c_str());
-        aspell_config_replace(spellcheck_config, "encoding", "utf-8");
-    }
-    spellcheck_possible_err = new_aspell_speller(spellcheck_config);
-    if (spellcheck_checker != nullptr)
-        delete_aspell_speller(spellcheck_checker);
-    spellcheck_checker = nullptr;
-    if (aspell_error_number(spellcheck_possible_err) != 0)
-        std::cerr << "Spell check error: " << aspell_error_message(spellcheck_possible_err) << std::endl;
-    else
-        spellcheck_checker = to_aspell_speller(spellcheck_possible_err);
-    get_buffer()->remove_tag(spellcheck_error_tag, get_buffer()->begin(), get_buffer()->end());
+  if (Config::get().source.spellcheck_language.size() > 0) {
+    aspell_config_replace(spellcheck_config, "lang", Config::get().source.spellcheck_language.c_str());
+    aspell_config_replace(spellcheck_config, "encoding", "utf-8");
+  }
+  spellcheck_possible_err = new_aspell_speller(spellcheck_config);
+  if (spellcheck_checker != nullptr)
+    delete_aspell_speller(spellcheck_checker);
+  spellcheck_checker = nullptr;
+  if (aspell_error_number(spellcheck_possible_err) != 0)
+    std::cerr << "Spell check error: " << aspell_error_message(spellcheck_possible_err) << std::endl;
+  else
+    spellcheck_checker = to_aspell_speller(spellcheck_possible_err);
+  get_buffer()->remove_tag(spellcheck_error_tag, get_buffer()->begin(), get_buffer()->end());
 }
 
 void Source::SpellCheckView::hide_dialogs() {
-    delayed_spellcheck_suggestions_connection.disconnect();
-    if (SelectionDialog::get())
-        SelectionDialog::get()->hide();
+  delayed_spellcheck_suggestions_connection.disconnect();
+  if (SelectionDialog::get())
+    SelectionDialog::get()->hide();
 }
 
 void Source::SpellCheckView::spellcheck(const Gtk::TextIter &start, const Gtk::TextIter &end) {
-    if (spellcheck_checker == nullptr)
-        return;
-    auto iter = start;
-    while (iter && iter < end) {
-        if (is_word_iter(iter)) {
-            auto word = get_word(iter);
-            spellcheck_word(word.first, word.second);
-            iter = word.second;
-        }
-        iter.forward_char();
+  if (spellcheck_checker == nullptr)
+    return;
+  auto iter = start;
+  while (iter && iter < end) {
+    if (is_word_iter(iter)) {
+      auto word = get_word(iter);
+      spellcheck_word(word.first, word.second);
+      iter = word.second;
     }
+    iter.forward_char();
+  }
 }
 
 void Source::SpellCheckView::spellcheck() {
-    auto iter = get_buffer()->begin();
-    Gtk::TextIter begin_spellcheck_iter;
-    if (spellcheck_all) {
-        bool spell_check = !get_source_buffer()->iter_has_context_class(iter, "no-spell-check");
-        if (spell_check)
-            begin_spellcheck_iter = iter;
-        while (iter != get_buffer()->end()) {
-            if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
-                iter = get_buffer()->end();
-
-            spell_check = !spell_check;
-            if (spell_check)
-                begin_spellcheck_iter = iter;
-            else
-                spellcheck(begin_spellcheck_iter, iter);
-        }
-    } else {
-        bool spell_check = !is_code_iter(iter);
-        if (spell_check)
-            begin_spellcheck_iter = iter;
-        while (iter != get_buffer()->end()) {
-            auto iter1 = iter;
-            auto iter2 = iter;
-            if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string"))
-                iter1 = get_buffer()->end();
-            if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
-                iter2 = get_buffer()->end();
-
-            if (iter2 < iter1)
-                iter = iter2;
-            else
-                iter = iter1;
-            spell_check = !spell_check;
-            if (spell_check)
-                begin_spellcheck_iter = iter;
-            else
-                spellcheck(begin_spellcheck_iter, iter);
-        }
+  auto iter = get_buffer()->begin();
+  Gtk::TextIter begin_spellcheck_iter;
+  if (spellcheck_all) {
+    bool spell_check = !get_source_buffer()->iter_has_context_class(iter, "no-spell-check");
+    if (spell_check)
+      begin_spellcheck_iter = iter;
+    while (iter != get_buffer()->end()) {
+      if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
+        iter = get_buffer()->end();
+
+      spell_check = !spell_check;
+      if (spell_check)
+        begin_spellcheck_iter = iter;
+      else
+        spellcheck(begin_spellcheck_iter, iter);
     }
+  } else {
+    bool spell_check = !is_code_iter(iter);
+    if (spell_check)
+      begin_spellcheck_iter = iter;
+    while (iter != get_buffer()->end()) {
+      auto iter1 = iter;
+      auto iter2 = iter;
+      if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string"))
+        iter1 = get_buffer()->end();
+      if (!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
+        iter2 = get_buffer()->end();
+
+      if (iter2 < iter1)
+        iter = iter2;
+      else
+        iter = iter1;
+      spell_check = !spell_check;
+      if (spell_check)
+        begin_spellcheck_iter = iter;
+      else
+        spellcheck(begin_spellcheck_iter, iter);
+    }
+  }
 }
 
 void Source::SpellCheckView::remove_spellcheck_errors() {
-    get_buffer()->remove_tag(spellcheck_error_tag, get_buffer()->begin(), get_buffer()->end());
+  get_buffer()->remove_tag(spellcheck_error_tag, get_buffer()->begin(), get_buffer()->end());
 }
 
 void Source::SpellCheckView::goto_next_spellcheck_error() {
-    auto iter = get_buffer()->get_insert()->get_iter();
-    auto insert_iter = iter;
-    bool wrapped = false;
+  auto iter = get_buffer()->get_insert()->get_iter();
+  auto insert_iter = iter;
+  bool wrapped = false;
+  iter.forward_char();
+  while (!wrapped || iter < insert_iter) {
+    auto toggled_tags = iter.get_toggled_tags();
+    for (auto &toggled_tag: toggled_tags) {
+      if (toggled_tag == spellcheck_error_tag) {
+        get_buffer()->place_cursor(iter);
+        scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+        return;
+      }
+    }
     iter.forward_char();
-    while (!wrapped || iter < insert_iter) {
-        auto toggled_tags = iter.get_toggled_tags();
-        for (auto &toggled_tag: toggled_tags) {
-            if (toggled_tag == spellcheck_error_tag) {
-                get_buffer()->place_cursor(iter);
-                scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-                return;
-            }
-        }
-        iter.forward_char();
-        if (!wrapped && iter == get_buffer()->end()) {
-            iter = get_buffer()->begin();
-            wrapped = true;
-        }
+    if (!wrapped && iter == get_buffer()->end()) {
+      iter = get_buffer()->begin();
+      wrapped = true;
     }
-    Info::get().print("No spelling errors found in current buffer");
+  }
+  Info::get().print("No spelling errors found in current buffer");
 }
 
 bool Source::SpellCheckView::is_code_iter(const Gtk::TextIter &iter) {
-    if (*iter == '\'') {
-        auto previous_iter = iter;
-        if (!iter.starts_line() && previous_iter.backward_char() && *previous_iter == '\'')
-            return false;
-    }
-    if (spellcheck_all) {
-        if (no_spell_check_tag && (iter.has_tag(no_spell_check_tag) || iter.begins_tag(no_spell_check_tag) ||
-                                   iter.ends_tag(no_spell_check_tag)))
+  if (*iter == '\'') {
+    auto previous_iter = iter;
+    if (!iter.starts_line() && previous_iter.backward_char() && *previous_iter == '\'')
+      return false;
+  }
+  if (spellcheck_all) {
+    if (no_spell_check_tag && (iter.has_tag(no_spell_check_tag) || iter.begins_tag(no_spell_check_tag) ||
+                               iter.ends_tag(no_spell_check_tag)))
+      return true;
+    // workaround for gtksourceview bug
+    if (iter.ends_line()) {
+      auto previous_iter = iter;
+      if (previous_iter.backward_char()) {
+        if (*previous_iter == '\'' || *previous_iter == '"') {
+          auto next_iter = iter;
+          next_iter.forward_char();
+          if (next_iter.begins_tag(no_spell_check_tag) || next_iter.is_end())
             return true;
-        // workaround for gtksourceview bug
-        if (iter.ends_line()) {
-            auto previous_iter = iter;
-            if (previous_iter.backward_char()) {
-                if (*previous_iter == '\'' || *previous_iter == '"') {
-                    auto next_iter = iter;
-                    next_iter.forward_char();
-                    if (next_iter.begins_tag(no_spell_check_tag) || next_iter.is_end())
-                        return true;
-                }
-            }
         }
-        // for example, mark first " as code iter in this case: r""
-        if (*iter == '\'' || *iter == '"') {
-            auto previous_iter = iter;
-            if (previous_iter.backward_char() && *previous_iter != '\'' && *previous_iter != '\"' &&
-                previous_iter.ends_tag(no_spell_check_tag))
-                return true;
-        }
-        return false;
+      }
     }
-    if (comment_tag) {
-        if (iter.has_tag(comment_tag) && !iter.begins_tag(comment_tag))
-            return false;
-            //Exception at the end of /**/
-        else if (iter.ends_tag(comment_tag)) {
-            auto previous_iter = iter;
-            if (previous_iter.backward_char() && *previous_iter == '/') {
-                auto previous_previous_iter = previous_iter;
-                if (previous_previous_iter.backward_char() && *previous_previous_iter == '*') {
-                    auto it = previous_iter;
-                    while (!it.begins_tag(comment_tag) && it.backward_to_tag_toggle(comment_tag)) {}
-                    auto next_iter = it;
-                    if (it.begins_tag(comment_tag) && next_iter.forward_char() && *it == '/' && *next_iter == '*' &&
-                        previous_iter != it)
-                        return true;
-                }
-            }
-            return false;
+    // for example, mark first " as code iter in this case: r""
+    if (*iter == '\'' || *iter == '"') {
+      auto previous_iter = iter;
+      if (previous_iter.backward_char() && *previous_iter != '\'' && *previous_iter != '\"' &&
+          previous_iter.ends_tag(no_spell_check_tag))
+        return true;
+    }
+    return false;
+  }
+  if (comment_tag) {
+    if (iter.has_tag(comment_tag) && !iter.begins_tag(comment_tag))
+      return false;
+      //Exception at the end of /**/
+    else if (iter.ends_tag(comment_tag)) {
+      auto previous_iter = iter;
+      if (previous_iter.backward_char() && *previous_iter == '/') {
+        auto previous_previous_iter = previous_iter;
+        if (previous_previous_iter.backward_char() && *previous_previous_iter == '*') {
+          auto it = previous_iter;
+          while (!it.begins_tag(comment_tag) && it.backward_to_tag_toggle(comment_tag)) {}
+          auto next_iter = it;
+          if (it.begins_tag(comment_tag) && next_iter.forward_char() && *it == '/' && *next_iter == '*' &&
+              previous_iter != it)
+            return true;
         }
+      }
+      return false;
     }
-    if (string_tag) {
-        if (iter.has_tag(string_tag)) {
-            // When ending an open ''-string with ', the last '-iter is not correctly marked as end iter for string_tag
-            // For instance 'test, when inserting ' at end, would lead to spellcheck error of test'
-            if (*iter == '\'') {
-                long backslash_count = 0;
-                auto it = iter;
-                while (it.backward_char() && *it == '\\')
-                    ++backslash_count;
-                if (backslash_count % 2 == 0) {
-                    auto it = iter;
-                    while (!it.begins_tag(string_tag) && it.backward_to_tag_toggle(string_tag)) {}
-                    if (it.begins_tag(string_tag) && *it == '\'' && iter != it)
-                        return true;
-                }
-            }
-            if (!iter.begins_tag(string_tag))
-                return false;
+  }
+  if (string_tag) {
+    if (iter.has_tag(string_tag)) {
+      // When ending an open ''-string with ', the last '-iter is not correctly marked as end iter for string_tag
+      // For instance 'test, when inserting ' at end, would lead to spellcheck error of test'
+      if (*iter == '\'') {
+        long backslash_count = 0;
+        auto it = iter;
+        while (it.backward_char() && *it == '\\')
+          ++backslash_count;
+        if (backslash_count % 2 == 0) {
+          auto it = iter;
+          while (!it.begins_tag(string_tag) && it.backward_to_tag_toggle(string_tag)) {}
+          if (it.begins_tag(string_tag) && *it == '\'' && iter != it)
+            return true;
         }
-            // If iter is at the end of string_tag, with exception of after " and '
-        else if (iter.ends_tag(string_tag)) {
-            auto previous_iter = iter;
-            if (!iter.starts_line() && previous_iter.backward_char()) {
-                if ((*previous_iter == '"' || *previous_iter == '\'')) {
-                    long backslash_count = 0;
-                    auto it = previous_iter;
-                    while (it.backward_char() && *it == '\\')
-                        ++backslash_count;
-                    if (backslash_count % 2 == 0) {
-                        auto it = previous_iter;
-                        while (!it.begins_tag(string_tag) && it.backward_to_tag_toggle(string_tag)) {}
-                        if (it.begins_tag(string_tag) && *previous_iter == *it && previous_iter != it)
-                            return true;
-                    }
-                }
-                return false;
-            }
+      }
+      if (!iter.begins_tag(string_tag))
+        return false;
+    }
+      // If iter is at the end of string_tag, with exception of after " and '
+    else if (iter.ends_tag(string_tag)) {
+      auto previous_iter = iter;
+      if (!iter.starts_line() && previous_iter.backward_char()) {
+        if ((*previous_iter == '"' || *previous_iter == '\'')) {
+          long backslash_count = 0;
+          auto it = previous_iter;
+          while (it.backward_char() && *it == '\\')
+            ++backslash_count;
+          if (backslash_count % 2 == 0) {
+            auto it = previous_iter;
+            while (!it.begins_tag(string_tag) && it.backward_to_tag_toggle(string_tag)) {}
+            if (it.begins_tag(string_tag) && *previous_iter == *it && previous_iter != it)
+              return true;
+          }
         }
+        return false;
+      }
     }
-    return true;
+  }
+  return true;
 }
 
 bool Source::SpellCheckView::is_word_iter(const Gtk::TextIter &iter) {
-    auto previous_iter = iter;
-    size_t backslash_count = 0;
-    while (previous_iter.backward_char() && *previous_iter == '\\')
-        ++backslash_count;
-    if (backslash_count % 2 == 1)
-        return false;
-    if (((*iter >= 'A' && *iter <= 'Z') || (*iter >= 'a' && *iter <= 'z') || *iter >= 128))
-        return true;
-    if (*iter == '\'') {
-        if (is_code_iter(iter))
-            return false;
-        auto next_iter = iter;
-        if (next_iter.forward_char() && is_code_iter(next_iter) &&
-            !(comment_tag && iter.ends_tag(comment_tag))) // additional check for end of line comment
-            return false;
-        return true;
-    }
+  auto previous_iter = iter;
+  size_t backslash_count = 0;
+  while (previous_iter.backward_char() && *previous_iter == '\\')
+    ++backslash_count;
+  if (backslash_count % 2 == 1)
     return false;
+  if (((*iter >= 'A' && *iter <= 'Z') || (*iter >= 'a' && *iter <= 'z') || *iter >= 128))
+    return true;
+  if (*iter == '\'') {
+    if (is_code_iter(iter))
+      return false;
+    auto next_iter = iter;
+    if (next_iter.forward_char() && is_code_iter(next_iter) &&
+        !(comment_tag && iter.ends_tag(comment_tag))) // additional check for end of line comment
+      return false;
+    return true;
+  }
+  return false;
 }
 
 std::pair<Gtk::TextIter, Gtk::TextIter> Source::SpellCheckView::get_word(Gtk::TextIter iter) {
-    auto start = iter;
-    auto end = iter;
-
-    while (is_word_iter(iter)) {
-        start = iter;
-        if (!iter.backward_char())
-            break;
-    }
-    while (is_word_iter(end)) {
-        if (!end.forward_char())
-            break;
-    }
-
-    return {start, end};
+  auto start = iter;
+  auto end = iter;
+
+  while (is_word_iter(iter)) {
+    start = iter;
+    if (!iter.backward_char())
+      break;
+  }
+  while (is_word_iter(end)) {
+    if (!end.forward_char())
+      break;
+  }
+
+  return {start, end};
 }
 
 void Source::SpellCheckView::spellcheck_word(Gtk::TextIter start, Gtk::TextIter end) {
-    if (*start == '\'' && end.get_offset() - start.get_offset() >= 3) {
-        auto before_end = end;
-        if (before_end.backward_char() && *before_end == '\'') {
-            get_buffer()->remove_tag(spellcheck_error_tag, start, end);
-            start.forward_char();
-            end.backward_char();
-        }
+  if (*start == '\'' && end.get_offset() - start.get_offset() >= 3) {
+    auto before_end = end;
+    if (before_end.backward_char() && *before_end == '\'') {
+      get_buffer()->remove_tag(spellcheck_error_tag, start, end);
+      start.forward_char();
+      end.backward_char();
     }
+  }
 
-    auto word = get_buffer()->get_text(start, end);
-    if (word.size() > 0) {
-        auto correct = aspell_speller_check(spellcheck_checker, word.data(), word.bytes());
-        if (correct == 0)
-            get_buffer()->apply_tag(spellcheck_error_tag, start, end);
-        else
-            get_buffer()->remove_tag(spellcheck_error_tag, start, end);
-    }
+  auto word = get_buffer()->get_text(start, end);
+  if (word.size() > 0) {
+    auto correct = aspell_speller_check(spellcheck_checker, word.data(), word.bytes());
+    if (correct == 0)
+      get_buffer()->apply_tag(spellcheck_error_tag, start, end);
+    else
+      get_buffer()->remove_tag(spellcheck_error_tag, start, end);
+  }
 }
 
 std::vector<std::string>
 Source::SpellCheckView::get_spellcheck_suggestions(const Gtk::TextIter &start, const Gtk::TextIter &end) {
-    auto word_with_error = get_buffer()->get_text(start, end);
+  auto word_with_error = get_buffer()->get_text(start, end);
 
-    const AspellWordList *suggestions = aspell_speller_suggest(spellcheck_checker, word_with_error.data(),
-                                                               word_with_error.bytes());
-    AspellStringEnumeration *elements = aspell_word_list_elements(suggestions);
+  const AspellWordList *suggestions = aspell_speller_suggest(spellcheck_checker, word_with_error.data(),
+                                                             word_with_error.bytes());
+  AspellStringEnumeration *elements = aspell_word_list_elements(suggestions);
 
-    std::vector<std::string> words;
-    const char *word;
-    while ((word = aspell_string_enumeration_next(elements)) != nullptr) {
-        words.emplace_back(word);
-    }
-    delete_aspell_string_enumeration(elements);
+  std::vector<std::string> words;
+  const char *word;
+  while ((word = aspell_string_enumeration_next(elements)) != nullptr) {
+    words.emplace_back(word);
+  }
+  delete_aspell_string_enumeration(elements);
 
-    return words;
+  return words;
 }
diff --git a/src/source_spellcheck.h b/src/source_spellcheck.h
index 1b6b476e..4ae97b63 100644
--- a/src/source_spellcheck.h
+++ b/src/source_spellcheck.h
@@ -4,52 +4,52 @@
 #include <aspell.h>
 
 namespace Source {
-    class SpellCheckView : virtual public Source::BaseView {
-    public:
-        SpellCheckView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
+  class SpellCheckView : virtual public Source::BaseView {
+  public:
+    SpellCheckView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
 
-        ~SpellCheckView();
+    ~SpellCheckView();
 
-        void configure() override;
+    void configure() override;
 
-        void hide_dialogs() override;
+    void hide_dialogs() override;
 
-        void spellcheck();
+    void spellcheck();
 
-        void remove_spellcheck_errors();
+    void remove_spellcheck_errors();
 
-        void goto_next_spellcheck_error();
+    void goto_next_spellcheck_error();
 
-    protected:
-        bool is_code_iter(const Gtk::TextIter &iter);
+  protected:
+    bool is_code_iter(const Gtk::TextIter &iter);
 
-        bool spellcheck_all = false;
-        guint last_keyval = 0;
+    bool spellcheck_all = false;
+    guint last_keyval = 0;
 
-        Glib::RefPtr<Gtk::TextTag> comment_tag;
-        Glib::RefPtr<Gtk::TextTag> string_tag;
-        Glib::RefPtr<Gtk::TextTag> no_spell_check_tag;
-    private:
-        Glib::RefPtr<Gtk::TextTag> spellcheck_error_tag;
+    Glib::RefPtr<Gtk::TextTag> comment_tag;
+    Glib::RefPtr<Gtk::TextTag> string_tag;
+    Glib::RefPtr<Gtk::TextTag> no_spell_check_tag;
+  private:
+    Glib::RefPtr<Gtk::TextTag> spellcheck_error_tag;
 
-        sigc::connection signal_tag_added_connection;
-        sigc::connection signal_tag_removed_connection;
+    sigc::connection signal_tag_added_connection;
+    sigc::connection signal_tag_removed_connection;
 
-        static AspellConfig *spellcheck_config;
-        AspellCanHaveError *spellcheck_possible_err;
-        AspellSpeller *spellcheck_checker;
+    static AspellConfig *spellcheck_config;
+    AspellCanHaveError *spellcheck_possible_err;
+    AspellSpeller *spellcheck_checker;
 
-        bool is_word_iter(const Gtk::TextIter &iter);
+    bool is_word_iter(const Gtk::TextIter &iter);
 
-        std::pair<Gtk::TextIter, Gtk::TextIter> get_word(Gtk::TextIter iter);
+    std::pair<Gtk::TextIter, Gtk::TextIter> get_word(Gtk::TextIter iter);
 
-        void spellcheck_word(Gtk::TextIter start, Gtk::TextIter end);
+    void spellcheck_word(Gtk::TextIter start, Gtk::TextIter end);
 
-        std::vector<std::string> get_spellcheck_suggestions(const Gtk::TextIter &start, const Gtk::TextIter &end);
+    std::vector<std::string> get_spellcheck_suggestions(const Gtk::TextIter &start, const Gtk::TextIter &end);
 
-        sigc::connection delayed_spellcheck_suggestions_connection;
-        sigc::connection delayed_spellcheck_error_clear;
+    sigc::connection delayed_spellcheck_suggestions_connection;
+    sigc::connection delayed_spellcheck_error_clear;
 
-        void spellcheck(const Gtk::TextIter &start, const Gtk::TextIter &end);
-    };
+    void spellcheck(const Gtk::TextIter &start, const Gtk::TextIter &end);
+  };
 }
diff --git a/src/terminal.cc b/src/terminal.cc
index ab285590..6ee3e95f 100644
--- a/src/terminal.cc
+++ b/src/terminal.cc
@@ -9,426 +9,426 @@
 #include <thread>
 
 Terminal::Terminal() {
-    set_editable(false);
+  set_editable(false);
 
-    bold_tag = get_buffer()->create_tag();
-    bold_tag->property_weight() = Pango::WEIGHT_ULTRAHEAVY;
+  bold_tag = get_buffer()->create_tag();
+  bold_tag->property_weight() = Pango::WEIGHT_ULTRAHEAVY;
 
-    link_tag = get_buffer()->create_tag();
-    link_tag->property_underline() = Pango::Underline::UNDERLINE_SINGLE;
+  link_tag = get_buffer()->create_tag();
+  link_tag->property_underline() = Pango::Underline::UNDERLINE_SINGLE;
 
-    link_mouse_cursor = Gdk::Cursor::create(Gdk::CursorType::HAND1);
-    default_mouse_cursor = Gdk::Cursor::create(Gdk::CursorType::XTERM);
+  link_mouse_cursor = Gdk::Cursor::create(Gdk::CursorType::HAND1);
+  default_mouse_cursor = Gdk::Cursor::create(Gdk::CursorType::XTERM);
 }
 
 int Terminal::process(const std::string &command, const boost::filesystem::path &path, bool use_pipes) {
-    std::unique_ptr<TinyProcessLib::Process> process;
-    if (use_pipes)
-        process = std::make_unique<TinyProcessLib::Process>(command, path.string(),
-                                                            [this](const char *bytes, size_t n) {
-                                                                async_print(std::string(bytes, n));
-                                                            }, [this](const char *bytes, size_t n) {
-                    async_print(std::string(bytes, n), true);
-                });
-    else
-        process = std::make_unique<TinyProcessLib::Process>(command, path.string());
-
-    if (process->get_id() <= 0) {
-        async_print("Error: failed to run command: " + command + "\n", true);
-        return -1;
-    }
-
-    return process->get_exit_status();
+  std::unique_ptr<TinyProcessLib::Process> process;
+  if (use_pipes)
+    process = std::make_unique<TinyProcessLib::Process>(command, path.string(),
+                                                        [this](const char *bytes, size_t n) {
+                                                          async_print(std::string(bytes, n));
+                                                        }, [this](const char *bytes, size_t n) {
+          async_print(std::string(bytes, n), true);
+        });
+  else
+    process = std::make_unique<TinyProcessLib::Process>(command, path.string());
+
+  if (process->get_id() <= 0) {
+    async_print("Error: failed to run command: " + command + "\n", true);
+    return -1;
+  }
+
+  return process->get_exit_status();
 }
 
 int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command,
                       const boost::filesystem::path &path, std::ostream *stderr_stream) {
-    TinyProcessLib::Process process(command, path.string(), [&stdout_stream](const char *bytes, size_t n) {
-        Glib::ustring umessage(std::string(bytes, n));
-        Glib::ustring::iterator iter;
-        while (!umessage.validate(iter)) {
-            auto next_char_iter = iter;
-            next_char_iter++;
-            umessage.replace(iter, next_char_iter, "?");
-        }
-        stdout_stream.write(umessage.data(), n);
-    }, [this, stderr_stream](const char *bytes, size_t n) {
-        if (stderr_stream)
-            stderr_stream->write(bytes, n);
-        else
-            async_print(std::string(bytes, n), true);
-    }, true);
-
-    if (process.get_id() <= 0) {
-        async_print("Error: failed to run command: " + command + "\n", true);
-        return -1;
+  TinyProcessLib::Process process(command, path.string(), [&stdout_stream](const char *bytes, size_t n) {
+    Glib::ustring umessage(std::string(bytes, n));
+    Glib::ustring::iterator iter;
+    while (!umessage.validate(iter)) {
+      auto next_char_iter = iter;
+      next_char_iter++;
+      umessage.replace(iter, next_char_iter, "?");
     }
-
-    char buffer[131072];
-    for (;;) {
-        stdin_stream.readsome(buffer, 131072);
-        auto read_n = stdin_stream.gcount();
-        if (read_n == 0)
-            break;
-        if (!process.write(buffer, read_n)) {
-            break;
-        }
+    stdout_stream.write(umessage.data(), n);
+  }, [this, stderr_stream](const char *bytes, size_t n) {
+    if (stderr_stream)
+      stderr_stream->write(bytes, n);
+    else
+      async_print(std::string(bytes, n), true);
+  }, true);
+
+  if (process.get_id() <= 0) {
+    async_print("Error: failed to run command: " + command + "\n", true);
+    return -1;
+  }
+
+  char buffer[131072];
+  for (;;) {
+    stdin_stream.readsome(buffer, 131072);
+    auto read_n = stdin_stream.gcount();
+    if (read_n == 0)
+      break;
+    if (!process.write(buffer, read_n)) {
+      break;
     }
-    process.close_stdin();
+  }
+  process.close_stdin();
 
-    return process.get_exit_status();
+  return process.get_exit_status();
 }
 
 void Terminal::async_process(const std::string &command, const boost::filesystem::path &path,
                              std::function<void(int exit_status)> callback, bool quiet) {
-    std::thread async_execute_thread([this, command, path, callback, quiet]() {
-        std::unique_lock<std::mutex> processes_lock(processes_mutex);
-        stdin_buffer.clear();
-        auto process = std::make_shared<TinyProcessLib::Process>(command, path.string(),
-                                                                 [this, quiet](const char *bytes, size_t n) {
-                                                                     if (!quiet)
-                                                                         async_print(std::string(bytes, n));
-                                                                 }, [this, quiet](const char *bytes, size_t n) {
-                    if (!quiet)
-                        async_print(std::string(bytes, n), true);
-                }, true);
-        auto pid = process->get_id();
-        if (pid <= 0) {
-            processes_lock.unlock();
-            async_print("Error: failed to run command: " + command + "\n", true);
-            if (callback)
-                callback(-1);
-            return;
-        } else {
-            processes.emplace_back(process);
-            processes_lock.unlock();
-        }
+  std::thread async_execute_thread([this, command, path, callback, quiet]() {
+    std::unique_lock<std::mutex> processes_lock(processes_mutex);
+    stdin_buffer.clear();
+    auto process = std::make_shared<TinyProcessLib::Process>(command, path.string(),
+                                                             [this, quiet](const char *bytes, size_t n) {
+                                                               if (!quiet)
+                                                                 async_print(std::string(bytes, n));
+                                                             }, [this, quiet](const char *bytes, size_t n) {
+          if (!quiet)
+            async_print(std::string(bytes, n), true);
+        }, true);
+    auto pid = process->get_id();
+    if (pid <= 0) {
+      processes_lock.unlock();
+      async_print("Error: failed to run command: " + command + "\n", true);
+      if (callback)
+        callback(-1);
+      return;
+    } else {
+      processes.emplace_back(process);
+      processes_lock.unlock();
+    }
 
-        auto exit_status = process->get_exit_status();
+    auto exit_status = process->get_exit_status();
 
-        processes_lock.lock();
-        for (auto it = processes.begin(); it != processes.end(); it++) {
-            if ((*it)->get_id() == pid) {
-                processes.erase(it);
-                break;
-            }
-        }
-        stdin_buffer.clear();
-        processes_lock.unlock();
+    processes_lock.lock();
+    for (auto it = processes.begin(); it != processes.end(); it++) {
+      if ((*it)->get_id() == pid) {
+        processes.erase(it);
+        break;
+      }
+    }
+    stdin_buffer.clear();
+    processes_lock.unlock();
 
-        if (callback)
-            callback(exit_status);
-    });
-    async_execute_thread.detach();
+    if (callback)
+      callback(exit_status);
+  });
+  async_execute_thread.detach();
 }
 
 void Terminal::kill_last_async_process(bool force) {
-    std::unique_lock<std::mutex> lock(processes_mutex);
-    if (processes.empty())
-        Info::get().print("No running processes");
-    else
-        processes.back()->kill(force);
+  std::unique_lock<std::mutex> lock(processes_mutex);
+  if (processes.empty())
+    Info::get().print("No running processes");
+  else
+    processes.back()->kill(force);
 }
 
 void Terminal::kill_async_processes(bool force) {
-    std::unique_lock<std::mutex> lock(processes_mutex);
-    for (auto &process: processes)
-        process->kill(force);
+  std::unique_lock<std::mutex> lock(processes_mutex);
+  for (auto &process: processes)
+    process->kill(force);
 }
 
 bool Terminal::on_motion_notify_event(GdkEventMotion *event) {
-    Gtk::TextIter iter;
-    int location_x, location_y;
-    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, location_x, location_y);
-    get_iter_at_location(iter, location_x, location_y);
-    if (iter.has_tag(link_tag))
-        get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(link_mouse_cursor);
-    else
-        get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(default_mouse_cursor);
-
-    // Workaround for drag-and-drop crash on MacOS
-    // TODO 2018: check if this bug has been fixed
+  Gtk::TextIter iter;
+  int location_x, location_y;
+  window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, location_x, location_y);
+  get_iter_at_location(iter, location_x, location_y);
+  if (iter.has_tag(link_tag))
+    get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(link_mouse_cursor);
+  else
+    get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(default_mouse_cursor);
+
+  // Workaround for drag-and-drop crash on MacOS
+  // TODO 2018: check if this bug has been fixed
 #ifdef __APPLE__
-    if((event->state & GDK_BUTTON1_MASK) == 0)
-      return Gtk::TextView::on_motion_notify_event(event);
-    else {
-      int x, y;
-      window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
-      Gtk::TextIter iter;
-      get_iter_at_location(iter, x, y);
-      get_buffer()->select_range(get_buffer()->get_insert()->get_iter(), iter);
-      return true;
-    }
-#else
+  if((event->state & GDK_BUTTON1_MASK) == 0)
     return Gtk::TextView::on_motion_notify_event(event);
+  else {
+    int x, y;
+    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, event->x, event->y, x, y);
+    Gtk::TextIter iter;
+    get_iter_at_location(iter, x, y);
+    get_buffer()->select_range(get_buffer()->get_insert()->get_iter(), iter);
+    return true;
+  }
+#else
+  return Gtk::TextView::on_motion_notify_event(event);
 #endif
 
-    return Gtk::TextView::on_motion_notify_event(event);
+  return Gtk::TextView::on_motion_notify_event(event);
 }
 
 std::tuple<size_t, size_t, std::string, std::string, std::string> Terminal::find_link(const std::string &line) {
-    const static std::regex link_regex("^([A-Z]:)?([^:]+):([0-9]+):([0-9]+): .*$|" //compile warning/error/rename usages
-                                       "^Assertion failed: .*file ([A-Z]:)?([^:]+), line ([0-9]+)\\.$|" //clang assert()
-                                       "^[^:]*: ([A-Z]:)?([^:]+):([0-9]+): .* Assertion .* failed\\.$|" //gcc assert()
-                                       "^ERROR:([A-Z]:)?([^:]+):([0-9]+):.*$"); //g_assert (glib.h)
-    size_t start_position = -1, end_position = -1;
-    std::string path, line_number, line_offset;
-    std::smatch sm;
-    if (std::regex_match(line, sm, link_regex)) {
-        for (size_t sub = 1; sub < link_regex.mark_count();) {
-            size_t subs = sub == 1 ? 4 : 3;
-            if (sm.length(sub + 1)) {
-                start_position = sm.position(sub + 1) - sm.length(sub);
-                end_position = sm.position(sub + subs - 1) + sm.length(sub + subs - 1);
-                if (sm.length(sub))
-                    path += sm[sub].str();
-                path += sm[sub + 1].str();
-                line_number = sm[sub + 2].str();
-                line_offset = subs == 4 ? sm[sub + 3].str() : "1";
-                break;
-            }
-            sub += subs;
-        }
+  const static std::regex link_regex("^([A-Z]:)?([^:]+):([0-9]+):([0-9]+): .*$|" //compile warning/error/rename usages
+                                     "^Assertion failed: .*file ([A-Z]:)?([^:]+), line ([0-9]+)\\.$|" //clang assert()
+                                     "^[^:]*: ([A-Z]:)?([^:]+):([0-9]+): .* Assertion .* failed\\.$|" //gcc assert()
+                                     "^ERROR:([A-Z]:)?([^:]+):([0-9]+):.*$"); //g_assert (glib.h)
+  size_t start_position = -1, end_position = -1;
+  std::string path, line_number, line_offset;
+  std::smatch sm;
+  if (std::regex_match(line, sm, link_regex)) {
+    for (size_t sub = 1; sub < link_regex.mark_count();) {
+      size_t subs = sub == 1 ? 4 : 3;
+      if (sm.length(sub + 1)) {
+        start_position = sm.position(sub + 1) - sm.length(sub);
+        end_position = sm.position(sub + subs - 1) + sm.length(sub + subs - 1);
+        if (sm.length(sub))
+          path += sm[sub].str();
+        path += sm[sub + 1].str();
+        line_number = sm[sub + 2].str();
+        line_offset = subs == 4 ? sm[sub + 3].str() : "1";
+        break;
+      }
+      sub += subs;
     }
-    return std::make_tuple(start_position, end_position, path, line_number, line_offset);
+  }
+  return std::make_tuple(start_position, end_position, path, line_number, line_offset);
 }
 
 void Terminal::apply_link_tags(Gtk::TextIter start_iter, Gtk::TextIter end_iter) {
-    auto iter = start_iter;
-    Gtk::TextIter line_start;
-    bool line_start_set = false;
-    bool delimiter_found = false;
-    bool dot_found = false;
-    bool number_found = false;
-    do {
-        if (iter.starts_line()) {
-            line_start = iter;
-            line_start_set = true;
-            delimiter_found = false;
-            dot_found = false;
-            number_found = false;
-        }
-        if (line_start_set && (*iter == '\\' || *iter == '/'))
-            delimiter_found = true;
-        else if (line_start_set && *iter == '.')
-            dot_found = true;
-        else if (line_start_set && (*iter >= '0' && *iter <= '9'))
-            number_found = true;
-        else if (line_start_set && delimiter_found && dot_found && number_found && iter.ends_line()) {
-            auto line = get_buffer()->get_text(line_start, iter);
-            //Convert to ascii for std::regex and Gtk::Iter::forward_chars
-            for (size_t c = 0; c < line.size(); ++c) {
-                if (line[c] > 127)
-                    line.replace(c, 1, "a");
-            }
-            auto link = find_link(line.raw());
-            if (std::get<0>(link) != static_cast<size_t>(-1)) {
-                auto link_start = line_start;
-                auto link_end = line_start;
-                link_start.forward_chars(std::get<0>(link));
-                link_end.forward_chars(std::get<1>(link));
-                get_buffer()->apply_tag(link_tag, link_start, link_end);
-            }
-            line_start_set = false;
-        }
-    } while (iter.forward_char() && iter != end_iter);
+  auto iter = start_iter;
+  Gtk::TextIter line_start;
+  bool line_start_set = false;
+  bool delimiter_found = false;
+  bool dot_found = false;
+  bool number_found = false;
+  do {
+    if (iter.starts_line()) {
+      line_start = iter;
+      line_start_set = true;
+      delimiter_found = false;
+      dot_found = false;
+      number_found = false;
+    }
+    if (line_start_set && (*iter == '\\' || *iter == '/'))
+      delimiter_found = true;
+    else if (line_start_set && *iter == '.')
+      dot_found = true;
+    else if (line_start_set && (*iter >= '0' && *iter <= '9'))
+      number_found = true;
+    else if (line_start_set && delimiter_found && dot_found && number_found && iter.ends_line()) {
+      auto line = get_buffer()->get_text(line_start, iter);
+      //Convert to ascii for std::regex and Gtk::Iter::forward_chars
+      for (size_t c = 0; c < line.size(); ++c) {
+        if (line[c] > 127)
+          line.replace(c, 1, "a");
+      }
+      auto link = find_link(line.raw());
+      if (std::get<0>(link) != static_cast<size_t>(-1)) {
+        auto link_start = line_start;
+        auto link_end = line_start;
+        link_start.forward_chars(std::get<0>(link));
+        link_end.forward_chars(std::get<1>(link));
+        get_buffer()->apply_tag(link_tag, link_start, link_end);
+      }
+      line_start_set = false;
+    }
+  } while (iter.forward_char() && iter != end_iter);
 }
 
 size_t Terminal::print(const std::string &message, bool bold) {
 #ifdef _WIN32
-    //Remove color codes
-    auto message_no_color = message; //copy here since operations on Glib::ustring is too slow
-    size_t pos = 0;
-    while ((pos = message_no_color.find('\e', pos)) != std::string::npos) {
-        if ((pos + 2) >= message_no_color.size())
-            break;
-        if (message_no_color[pos + 1] == '[') {
-            size_t end_pos = pos + 2;
-            bool color_code_found = false;
-            while (end_pos < message_no_color.size()) {
-                if ((message_no_color[end_pos] >= '0' && message_no_color[end_pos] <= '9') ||
-                    message_no_color[end_pos] == ';')
-                    end_pos++;
-                else if (message_no_color[end_pos] == 'm') {
-                    color_code_found = true;
-                    break;
-                } else
-                    break;
-            }
-            if (color_code_found)
-                message_no_color.erase(pos, end_pos - pos + 1);
-        }
+  //Remove color codes
+  auto message_no_color = message; //copy here since operations on Glib::ustring is too slow
+  size_t pos = 0;
+  while ((pos = message_no_color.find('\e', pos)) != std::string::npos) {
+    if ((pos + 2) >= message_no_color.size())
+      break;
+    if (message_no_color[pos + 1] == '[') {
+      size_t end_pos = pos + 2;
+      bool color_code_found = false;
+      while (end_pos < message_no_color.size()) {
+        if ((message_no_color[end_pos] >= '0' && message_no_color[end_pos] <= '9') ||
+            message_no_color[end_pos] == ';')
+          end_pos++;
+        else if (message_no_color[end_pos] == 'm') {
+          color_code_found = true;
+          break;
+        } else
+          break;
+      }
+      if (color_code_found)
+        message_no_color.erase(pos, end_pos - pos + 1);
     }
-    Glib::ustring umessage = message_no_color;
+  }
+  Glib::ustring umessage = message_no_color;
 #else
-    Glib::ustring umessage=message;
+  Glib::ustring umessage=message;
 #endif
 
-    Glib::ustring::iterator iter;
-    while (!umessage.validate(iter)) {
-        auto next_char_iter = iter;
-        next_char_iter++;
-        umessage.replace(iter, next_char_iter, "?");
-    }
-
-    auto start_mark = get_buffer()->create_mark(get_buffer()->get_iter_at_line(get_buffer()->end().get_line()));
-    if (bold)
-        get_buffer()->insert_with_tag(get_buffer()->end(), umessage, bold_tag);
-    else
-        get_buffer()->insert(get_buffer()->end(), umessage);
-    auto start_iter = start_mark->get_iter();
-    get_buffer()->delete_mark(start_mark);
-    auto end_iter = get_buffer()->get_insert()->get_iter();
-
-    apply_link_tags(start_iter, end_iter);
-
-    if (get_buffer()->get_line_count() > Config::get().terminal.history_size) {
-        int lines = get_buffer()->get_line_count() - Config::get().terminal.history_size;
-        get_buffer()->erase(get_buffer()->begin(), get_buffer()->get_iter_at_line(lines));
-        deleted_lines += static_cast<size_t>(lines);
-    }
-
-    return static_cast<size_t>(get_buffer()->end().get_line()) + deleted_lines;
+  Glib::ustring::iterator iter;
+  while (!umessage.validate(iter)) {
+    auto next_char_iter = iter;
+    next_char_iter++;
+    umessage.replace(iter, next_char_iter, "?");
+  }
+
+  auto start_mark = get_buffer()->create_mark(get_buffer()->get_iter_at_line(get_buffer()->end().get_line()));
+  if (bold)
+    get_buffer()->insert_with_tag(get_buffer()->end(), umessage, bold_tag);
+  else
+    get_buffer()->insert(get_buffer()->end(), umessage);
+  auto start_iter = start_mark->get_iter();
+  get_buffer()->delete_mark(start_mark);
+  auto end_iter = get_buffer()->get_insert()->get_iter();
+
+  apply_link_tags(start_iter, end_iter);
+
+  if (get_buffer()->get_line_count() > Config::get().terminal.history_size) {
+    int lines = get_buffer()->get_line_count() - Config::get().terminal.history_size;
+    get_buffer()->erase(get_buffer()->begin(), get_buffer()->get_iter_at_line(lines));
+    deleted_lines += static_cast<size_t>(lines);
+  }
+
+  return static_cast<size_t>(get_buffer()->end().get_line()) + deleted_lines;
 }
 
 void Terminal::async_print(const std::string &message, bool bold) {
-    dispatcher.post([message, bold] {
-        Terminal::get().print(message, bold);
-    });
+  dispatcher.post([message, bold] {
+    Terminal::get().print(message, bold);
+  });
 }
 
 void Terminal::async_print(size_t line_nr, const std::string &message) {
-    dispatcher.post([this, line_nr, message] {
-        if (line_nr < deleted_lines)
-            return;
-
-        Glib::ustring umessage = message;
-        Glib::ustring::iterator iter;
-        while (!umessage.validate(iter)) {
-            auto next_char_iter = iter;
-            next_char_iter++;
-            umessage.replace(iter, next_char_iter, "?");
-        }
+  dispatcher.post([this, line_nr, message] {
+    if (line_nr < deleted_lines)
+      return;
+
+    Glib::ustring umessage = message;
+    Glib::ustring::iterator iter;
+    while (!umessage.validate(iter)) {
+      auto next_char_iter = iter;
+      next_char_iter++;
+      umessage.replace(iter, next_char_iter, "?");
+    }
 
-        auto end_line_iter = get_buffer()->get_iter_at_line(static_cast<int>(line_nr - deleted_lines));
-        while (!end_line_iter.ends_line() && end_line_iter.forward_char()) {}
-        get_buffer()->insert(end_line_iter, umessage);
-    });
+    auto end_line_iter = get_buffer()->get_iter_at_line(static_cast<int>(line_nr - deleted_lines));
+    while (!end_line_iter.ends_line() && end_line_iter.forward_char()) {}
+    get_buffer()->insert(end_line_iter, umessage);
+  });
 }
 
 void Terminal::configure() {
-    link_tag->property_foreground_rgba() = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_LINK);
-
-    if (Config::get().terminal.font.size() > 0) {
-        override_font(Pango::FontDescription(Config::get().terminal.font));
-    } else if (Config::get().source.font.size() > 0) {
-        Pango::FontDescription font_description(Config::get().source.font);
-        auto font_description_size = font_description.get_size();
-        if (font_description_size == 0) {
-            Pango::FontDescription default_font_description(Gtk::Settings::get_default()->property_gtk_font_name());
-            font_description_size = default_font_description.get_size();
-        }
-        if (font_description_size > 0)
-            font_description.set_size(font_description_size * 0.95);
-        override_font(font_description);
+  link_tag->property_foreground_rgba() = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_LINK);
+
+  if (Config::get().terminal.font.size() > 0) {
+    override_font(Pango::FontDescription(Config::get().terminal.font));
+  } else if (Config::get().source.font.size() > 0) {
+    Pango::FontDescription font_description(Config::get().source.font);
+    auto font_description_size = font_description.get_size();
+    if (font_description_size == 0) {
+      Pango::FontDescription default_font_description(Gtk::Settings::get_default()->property_gtk_font_name());
+      font_description_size = default_font_description.get_size();
     }
+    if (font_description_size > 0)
+      font_description.set_size(font_description_size * 0.95);
+    override_font(font_description);
+  }
 }
 
 void Terminal::clear() {
-    get_buffer()->set_text("");
+  get_buffer()->set_text("");
 }
 
 bool Terminal::on_button_press_event(GdkEventButton *button_event) {
-    //open clicked link in terminal
-    if (button_event->type == GDK_BUTTON_PRESS && button_event->button == GDK_BUTTON_PRIMARY) {
-        Gtk::TextIter iter;
-        int location_x, location_y;
-        window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, button_event->x, button_event->y, location_x,
-                                location_y);
-        get_iter_at_location(iter, location_x, location_y);
-        if (iter.has_tag(link_tag)) {
-            auto start_iter = get_buffer()->get_iter_at_line(iter.get_line());
-            auto end_iter = start_iter;
-            while (!end_iter.ends_line() && end_iter.forward_char()) {}
-            auto link = find_link(get_buffer()->get_text(start_iter, end_iter).raw());
-            if (std::get<0>(link) != static_cast<size_t>(-1)) {
-                boost::filesystem::path path = std::get<2>(link);
-                std::string line = std::get<3>(link);
-                std::string index = std::get<4>(link);
-
-                if (!path.empty() && *path.begin() == "~") { // boost::filesystem does not recognize ~
-                    boost::filesystem::path corrected_path;
-                    corrected_path = filesystem::get_home_path();
-                    if (!corrected_path.empty()) {
-                        auto it = path.begin();
-                        ++it;
-                        for (; it != path.end(); ++it)
-                            corrected_path /= *it;
-                        path = corrected_path;
-                    }
-                }
-
-                if (path.is_relative()) {
-                    if (Project::current) {
-                        auto absolute_path = Project::current->build->get_default_path() / path;
-                        if (boost::filesystem::exists(absolute_path))
-                            path = absolute_path;
-                        else
-                            path = Project::current->build->get_debug_path() / path;
-                    } else
-                        return Gtk::TextView::on_button_press_event(button_event);
-                }
-                if (boost::filesystem::is_regular_file(path)) {
-                    Notebook::get().open(path);
-                    if (auto view = Notebook::get().get_current_view()) {
-                        try {
-                            int line_int = std::stoi(line) - 1;
-                            int index_int = std::stoi(index) - 1;
-                            view->place_cursor_at_line_index(line_int, index_int);
-                            view->scroll_to_cursor_delayed(view, true, true);
-                            return true;
-                        }
-                        catch (...) {}
-                    }
-                }
+  //open clicked link in terminal
+  if (button_event->type == GDK_BUTTON_PRESS && button_event->button == GDK_BUTTON_PRIMARY) {
+    Gtk::TextIter iter;
+    int location_x, location_y;
+    window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, button_event->x, button_event->y, location_x,
+                            location_y);
+    get_iter_at_location(iter, location_x, location_y);
+    if (iter.has_tag(link_tag)) {
+      auto start_iter = get_buffer()->get_iter_at_line(iter.get_line());
+      auto end_iter = start_iter;
+      while (!end_iter.ends_line() && end_iter.forward_char()) {}
+      auto link = find_link(get_buffer()->get_text(start_iter, end_iter).raw());
+      if (std::get<0>(link) != static_cast<size_t>(-1)) {
+        boost::filesystem::path path = std::get<2>(link);
+        std::string line = std::get<3>(link);
+        std::string index = std::get<4>(link);
+
+        if (!path.empty() && *path.begin() == "~") { // boost::filesystem does not recognize ~
+          boost::filesystem::path corrected_path;
+          corrected_path = filesystem::get_home_path();
+          if (!corrected_path.empty()) {
+            auto it = path.begin();
+            ++it;
+            for (; it != path.end(); ++it)
+              corrected_path /= *it;
+            path = corrected_path;
+          }
+        }
+
+        if (path.is_relative()) {
+          if (Project::current) {
+            auto absolute_path = Project::current->build->get_default_path() / path;
+            if (boost::filesystem::exists(absolute_path))
+              path = absolute_path;
+            else
+              path = Project::current->build->get_debug_path() / path;
+          } else
+            return Gtk::TextView::on_button_press_event(button_event);
+        }
+        if (boost::filesystem::is_regular_file(path)) {
+          Notebook::get().open(path);
+          if (auto view = Notebook::get().get_current_view()) {
+            try {
+              int line_int = std::stoi(line) - 1;
+              int index_int = std::stoi(index) - 1;
+              view->place_cursor_at_line_index(line_int, index_int);
+              view->scroll_to_cursor_delayed(view, true, true);
+              return true;
             }
+            catch (...) {}
+          }
         }
+      }
     }
-    return Gtk::TextView::on_button_press_event(button_event);
+  }
+  return Gtk::TextView::on_button_press_event(button_event);
 }
 
 bool Terminal::on_key_press_event(GdkEventKey *event) {
-    std::unique_lock<std::mutex> lock(processes_mutex);
-    bool debug_is_running = false;
+  std::unique_lock<std::mutex> lock(processes_mutex);
+  bool debug_is_running = false;
 #ifdef JUCI_ENABLE_DEBUG
-    debug_is_running=Project::current?Project::current->debug_is_running():false;
+  debug_is_running=Project::current?Project::current->debug_is_running():false;
 #endif
-    if (processes.size() > 0 || debug_is_running) {
-        auto unicode = gdk_keyval_to_unicode(event->keyval);
-        if (unicode >= 32 && unicode != 126 && unicode != 0) {
-            get_buffer()->place_cursor(get_buffer()->end());
-            stdin_buffer += unicode;
-            get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size() - 1));
-        } else if (event->keyval == GDK_KEY_BackSpace) {
-            get_buffer()->place_cursor(get_buffer()->end());
-            if (stdin_buffer.size() > 0 && get_buffer()->get_char_count() > 0) {
-                auto iter = get_buffer()->end();
-                iter--;
-                stdin_buffer.erase(stdin_buffer.size() - 1);
-                get_buffer()->erase(iter, get_buffer()->end());
-            }
-        } else if (event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) {
-            get_buffer()->place_cursor(get_buffer()->end());
-            stdin_buffer += '\n';
-            if (debug_is_running) {
+  if (processes.size() > 0 || debug_is_running) {
+    auto unicode = gdk_keyval_to_unicode(event->keyval);
+    if (unicode >= 32 && unicode != 126 && unicode != 0) {
+      get_buffer()->place_cursor(get_buffer()->end());
+      stdin_buffer += unicode;
+      get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size() - 1));
+    } else if (event->keyval == GDK_KEY_BackSpace) {
+      get_buffer()->place_cursor(get_buffer()->end());
+      if (stdin_buffer.size() > 0 && get_buffer()->get_char_count() > 0) {
+        auto iter = get_buffer()->end();
+        iter--;
+        stdin_buffer.erase(stdin_buffer.size() - 1);
+        get_buffer()->erase(iter, get_buffer()->end());
+      }
+    } else if (event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) {
+      get_buffer()->place_cursor(get_buffer()->end());
+      stdin_buffer += '\n';
+      if (debug_is_running) {
 #ifdef JUCI_ENABLE_DEBUG
-                Project::current->debug_write(stdin_buffer);
+        Project::current->debug_write(stdin_buffer);
 #endif
-            } else
-                processes.back()->write(stdin_buffer);
-            get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size() - 1));
-            stdin_buffer.clear();
-        }
+      } else
+        processes.back()->write(stdin_buffer);
+      get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size() - 1));
+      stdin_buffer.clear();
     }
-    return true;
+  }
+  return true;
 }
diff --git a/src/terminal.h b/src/terminal.h
index 88eb03df..a93118c8 100644
--- a/src/terminal.h
+++ b/src/terminal.h
@@ -10,56 +10,56 @@
 #include <tuple>
 
 class Terminal : public Gtk::TextView {
-    Terminal();
+  Terminal();
 
 public:
-    static Terminal &get() {
-        static Terminal singleton;
-        return singleton;
-    }
+  static Terminal &get() {
+    static Terminal singleton;
+    return singleton;
+  }
 
-    int process(const std::string &command, const boost::filesystem::path &path = "", bool use_pipes = true);
+  int process(const std::string &command, const boost::filesystem::path &path = "", bool use_pipes = true);
 
-    int process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command,
-                const boost::filesystem::path &path = "", std::ostream *stderr_stream = nullptr);
+  int process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command,
+              const boost::filesystem::path &path = "", std::ostream *stderr_stream = nullptr);
 
-    void async_process(const std::string &command, const boost::filesystem::path &path = "",
-                       std::function<void(int exit_status)> callback = nullptr, bool quiet = false);
+  void async_process(const std::string &command, const boost::filesystem::path &path = "",
+                     std::function<void(int exit_status)> callback = nullptr, bool quiet = false);
 
-    void kill_last_async_process(bool force = false);
+  void kill_last_async_process(bool force = false);
 
-    void kill_async_processes(bool force = false);
+  void kill_async_processes(bool force = false);
 
-    size_t print(const std::string &message, bool bold = false);
+  size_t print(const std::string &message, bool bold = false);
 
-    void async_print(const std::string &message, bool bold = false);
+  void async_print(const std::string &message, bool bold = false);
 
-    void async_print(size_t line_nr, const std::string &message);
+  void async_print(size_t line_nr, const std::string &message);
 
-    void configure();
+  void configure();
 
-    void clear();
+  void clear();
 
 protected:
-    bool on_motion_notify_event(GdkEventMotion *motion_event) override;
+  bool on_motion_notify_event(GdkEventMotion *motion_event) override;
 
-    bool on_button_press_event(GdkEventButton *button_event) override;
+  bool on_button_press_event(GdkEventButton *button_event) override;
 
-    bool on_key_press_event(GdkEventKey *event) override;
+  bool on_key_press_event(GdkEventKey *event) override;
 
 private:
-    Dispatcher dispatcher;
-    Glib::RefPtr<Gtk::TextTag> bold_tag;
-    Glib::RefPtr<Gtk::TextTag> link_tag;
-    Glib::RefPtr<Gdk::Cursor> link_mouse_cursor;
-    Glib::RefPtr<Gdk::Cursor> default_mouse_cursor;
-    size_t deleted_lines = 0;
+  Dispatcher dispatcher;
+  Glib::RefPtr<Gtk::TextTag> bold_tag;
+  Glib::RefPtr<Gtk::TextTag> link_tag;
+  Glib::RefPtr<Gdk::Cursor> link_mouse_cursor;
+  Glib::RefPtr<Gdk::Cursor> default_mouse_cursor;
+  size_t deleted_lines = 0;
 
-    std::tuple<size_t, size_t, std::string, std::string, std::string> find_link(const std::string &line);
+  std::tuple<size_t, size_t, std::string, std::string, std::string> find_link(const std::string &line);
 
-    void apply_link_tags(Gtk::TextIter start_iter, Gtk::TextIter end_iter);
+  void apply_link_tags(Gtk::TextIter start_iter, Gtk::TextIter end_iter);
 
-    std::vector<std::shared_ptr<TinyProcessLib::Process>> processes;
-    std::mutex processes_mutex;
-    Glib::ustring stdin_buffer;
+  std::vector<std::shared_ptr<TinyProcessLib::Process>> processes;
+  std::mutex processes_mutex;
+  Glib::ustring stdin_buffer;
 };
diff --git a/src/tooltips.cc b/src/tooltips.cc
index 22437cba..69e30e51 100644
--- a/src/tooltips.cc
+++ b/src/tooltips.cc
@@ -6,249 +6,249 @@ Gdk::Rectangle Tooltips::drawn_tooltips_rectangle = Gdk::Rectangle();
 
 Tooltip::Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer, Gtk::TextView *text_view,
                  Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark)
-        : start_mark(start_mark), end_mark(end_mark), create_tooltip_buffer(create_tooltip_buffer),
-          text_view(text_view) {}
+    : start_mark(start_mark), end_mark(end_mark), create_tooltip_buffer(create_tooltip_buffer),
+      text_view(text_view) {}
 
 Tooltip::~Tooltip() {
-    Tooltips::shown_tooltips.erase(this);
-    if (text_view) {
-        text_view->get_buffer()->delete_mark(start_mark);
-        text_view->get_buffer()->delete_mark(end_mark);
-    }
+  Tooltips::shown_tooltips.erase(this);
+  if (text_view) {
+    text_view->get_buffer()->delete_mark(start_mark);
+    text_view->get_buffer()->delete_mark(end_mark);
+  }
 }
 
 void Tooltip::update() {
-    if (text_view) {
-        auto iter = start_mark->get_iter();
-        auto end_iter = end_mark->get_iter();
-        text_view->get_iter_location(iter, activation_rectangle);
-        if (iter.get_offset() < end_iter.get_offset()) {
-            while (iter.forward_char() && iter != end_iter) {
-                Gdk::Rectangle rectangle;
-                text_view->get_iter_location(iter, rectangle);
-                activation_rectangle.join(rectangle);
-            }
-        }
-        int location_window_x, location_window_y;
-        text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, activation_rectangle.get_x(),
-                                           activation_rectangle.get_y(), location_window_x, location_window_y);
-        activation_rectangle.set_x(location_window_x);
-        activation_rectangle.set_y(location_window_y);
+  if (text_view) {
+    auto iter = start_mark->get_iter();
+    auto end_iter = end_mark->get_iter();
+    text_view->get_iter_location(iter, activation_rectangle);
+    if (iter.get_offset() < end_iter.get_offset()) {
+      while (iter.forward_char() && iter != end_iter) {
+        Gdk::Rectangle rectangle;
+        text_view->get_iter_location(iter, rectangle);
+        activation_rectangle.join(rectangle);
+      }
     }
+    int location_window_x, location_window_y;
+    text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, activation_rectangle.get_x(),
+                                       activation_rectangle.get_y(), location_window_x, location_window_y);
+    activation_rectangle.set_x(location_window_x);
+    activation_rectangle.set_y(location_window_y);
+  }
 }
 
 void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion) {
-    Tooltips::shown_tooltips.emplace(this);
+  Tooltips::shown_tooltips.emplace(this);
 
-    if (!window) {
-        //init window
-        window = std::make_unique<Gtk::Window>(Gtk::WindowType::WINDOW_POPUP);
+  if (!window) {
+    //init window
+    window = std::make_unique<Gtk::Window>(Gtk::WindowType::WINDOW_POPUP);
 
-        auto g_application = g_application_get_default();
-        auto gio_application = Glib::wrap(g_application, true);
-        auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
-        window->set_transient_for(*application->get_active_window());
+    auto g_application = g_application_get_default();
+    auto gio_application = Glib::wrap(g_application, true);
+    auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
+    window->set_transient_for(*application->get_active_window());
 
-        window->set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_TOOLTIP);
+    window->set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_TOOLTIP);
 
-        window->set_events(Gdk::POINTER_MOTION_MASK);
-        window->property_decorated() = false;
-        window->set_accept_focus(false);
-        window->set_skip_taskbar_hint(true);
-        window->set_default_size(0, 0);
+    window->set_events(Gdk::POINTER_MOTION_MASK);
+    window->property_decorated() = false;
+    window->set_accept_focus(false);
+    window->set_skip_taskbar_hint(true);
+    window->set_default_size(0, 0);
 
-        window->signal_motion_notify_event().connect([on_motion](GdkEventMotion *event) {
-            if (on_motion)
-                on_motion();
-            return false;
-        });
+    window->signal_motion_notify_event().connect([on_motion](GdkEventMotion *event) {
+      if (on_motion)
+        on_motion();
+      return false;
+    });
 
-        window->get_style_context()->add_class("juci_tooltip_window");
-        auto visual = window->get_screen()->get_rgba_visual();
-        if (visual)
-            gtk_widget_set_visual(reinterpret_cast<GtkWidget *>(window->gobj()), visual->gobj());
+    window->get_style_context()->add_class("juci_tooltip_window");
+    auto visual = window->get_screen()->get_rgba_visual();
+    if (visual)
+      gtk_widget_set_visual(reinterpret_cast<GtkWidget *>(window->gobj()), visual->gobj());
 
-        auto box = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-        box->get_style_context()->add_class("juci_tooltip_box");
-        window->add(*box);
+    auto box = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+    box->get_style_context()->add_class("juci_tooltip_box");
+    window->add(*box);
 
-        text_buffer = create_tooltip_buffer();
-        wrap_lines();
+    text_buffer = create_tooltip_buffer();
+    wrap_lines();
 
-        auto tooltip_text_view = Gtk::manage(new Gtk::TextView(text_buffer));
-        tooltip_text_view->get_style_context()->add_class("juci_tooltip_text_view");
-        tooltip_text_view->set_editable(false);
+    auto tooltip_text_view = Gtk::manage(new Gtk::TextView(text_buffer));
+    tooltip_text_view->get_style_context()->add_class("juci_tooltip_text_view");
+    tooltip_text_view->set_editable(false);
 
 #if GTK_VERSION_GE(3, 20)
-        box->add(*tooltip_text_view);
+    box->add(*tooltip_text_view);
 #else
-        auto box2=Gtk::manage(new Gtk::Box());
-        box2->pack_start(*tooltip_text_view, true, true, 3);
-        box->pack_start(*box2, true, true, 3);
+    auto box2=Gtk::manage(new Gtk::Box());
+    box2->pack_start(*tooltip_text_view, true, true, 3);
+    box->pack_start(*box2, true, true, 3);
 #endif
 
-        auto layout = Pango::Layout::create(tooltip_text_view->get_pango_context());
-        layout->set_text(text_buffer->get_text());
-        layout->get_pixel_size(size.first, size.second);
-        size.first += 6; // 2xpadding
-        size.second += 8; // 2xpadding + 2
-
-        window->signal_realize().connect([this] {
-            if (!text_view) {
-                auto &dialog = SelectionDialog::get();
-                if (dialog && dialog->is_visible()) {
-                    int root_x, root_y;
-                    dialog->get_position(root_x, root_y);
-                    root_x -= 3; // -1xpadding
-                    rectangle.set_x(root_x);
-                    rectangle.set_y(root_y - size.second);
-                    if (rectangle.get_y() < 0)
-                        rectangle.set_y(0);
-                }
-            }
-            window->move(rectangle.get_x(), rectangle.get_y());
-        });
-    }
-
-    int root_x = 0, root_y = 0;
-    if (text_view) {
-        //Adjust if tooltip is left of text_view
-        Gdk::Rectangle visible_rect;
-        text_view->get_visible_rect(visible_rect);
-        int visible_x, visible_y;
-        text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(),
-                                           visible_rect.get_y(), visible_x, visible_y);
-        auto activation_rectangle_x = std::max(activation_rectangle.get_x(), visible_x);
-
-        text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle_x,
-                                                                                      activation_rectangle.get_y(),
-                                                                                      root_x, root_y);
-        root_x -= 3; // -1xpadding
-        if (root_y < size.second)
-            root_x += visible_rect.get_width() * 0.1;
-    }
-    rectangle.set_x(root_x);
-    rectangle.set_y(std::max(0, root_y - size.second));
-    rectangle.set_width(size.first);
-    rectangle.set_height(size.second);
-
-    if (!disregard_drawn) {
-        if (Tooltips::drawn_tooltips_rectangle.get_width() != 0) {
-            if (rectangle.intersects(Tooltips::drawn_tooltips_rectangle)) {
-                int new_y = Tooltips::drawn_tooltips_rectangle.get_y() - size.second;
-                if (new_y >= 0)
-                    rectangle.set_y(new_y);
-                else
-                    rectangle.set_x(Tooltips::drawn_tooltips_rectangle.get_x() +
-                                    Tooltips::drawn_tooltips_rectangle.get_width() + 2);
-            }
-            Tooltips::drawn_tooltips_rectangle.join(rectangle);
-        } else
-            Tooltips::drawn_tooltips_rectangle = rectangle;
-    }
-
-    if (window->get_realized())
-        window->move(rectangle.get_x(), rectangle.get_y());
-    window->show_all();
-    shown = true;
+    auto layout = Pango::Layout::create(tooltip_text_view->get_pango_context());
+    layout->set_text(text_buffer->get_text());
+    layout->get_pixel_size(size.first, size.second);
+    size.first += 6; // 2xpadding
+    size.second += 8; // 2xpadding + 2
+
+    window->signal_realize().connect([this] {
+      if (!text_view) {
+        auto &dialog = SelectionDialog::get();
+        if (dialog && dialog->is_visible()) {
+          int root_x, root_y;
+          dialog->get_position(root_x, root_y);
+          root_x -= 3; // -1xpadding
+          rectangle.set_x(root_x);
+          rectangle.set_y(root_y - size.second);
+          if (rectangle.get_y() < 0)
+            rectangle.set_y(0);
+        }
+      }
+      window->move(rectangle.get_x(), rectangle.get_y());
+    });
+  }
+
+  int root_x = 0, root_y = 0;
+  if (text_view) {
+    //Adjust if tooltip is left of text_view
+    Gdk::Rectangle visible_rect;
+    text_view->get_visible_rect(visible_rect);
+    int visible_x, visible_y;
+    text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(),
+                                       visible_rect.get_y(), visible_x, visible_y);
+    auto activation_rectangle_x = std::max(activation_rectangle.get_x(), visible_x);
+
+    text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle_x,
+                                                                                  activation_rectangle.get_y(),
+                                                                                  root_x, root_y);
+    root_x -= 3; // -1xpadding
+    if (root_y < size.second)
+      root_x += visible_rect.get_width() * 0.1;
+  }
+  rectangle.set_x(root_x);
+  rectangle.set_y(std::max(0, root_y - size.second));
+  rectangle.set_width(size.first);
+  rectangle.set_height(size.second);
+
+  if (!disregard_drawn) {
+    if (Tooltips::drawn_tooltips_rectangle.get_width() != 0) {
+      if (rectangle.intersects(Tooltips::drawn_tooltips_rectangle)) {
+        int new_y = Tooltips::drawn_tooltips_rectangle.get_y() - size.second;
+        if (new_y >= 0)
+          rectangle.set_y(new_y);
+        else
+          rectangle.set_x(Tooltips::drawn_tooltips_rectangle.get_x() +
+                          Tooltips::drawn_tooltips_rectangle.get_width() + 2);
+      }
+      Tooltips::drawn_tooltips_rectangle.join(rectangle);
+    } else
+      Tooltips::drawn_tooltips_rectangle = rectangle;
+  }
+
+  if (window->get_realized())
+    window->move(rectangle.get_x(), rectangle.get_y());
+  window->show_all();
+  shown = true;
 }
 
 void Tooltip::hide(const std::pair<int, int> &last_mouse_pos, const std::pair<int, int> &mouse_pos) {
-    // Keep tooltip if mouse is moving towards it
-    // Calculated using dot product between the mouse_pos vector and the corners of the tooltip window
-    if (text_view && window && shown && last_mouse_pos.first != -1 && last_mouse_pos.second != -1 &&
-        mouse_pos.first != -1 && mouse_pos.second != -1) {
-        static int root_x, root_y;
-        text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(last_mouse_pos.first,
-                                                                                      last_mouse_pos.second, root_x,
-                                                                                      root_y);
-        int diff_x = mouse_pos.first - last_mouse_pos.first;
-        int diff_y = mouse_pos.second - last_mouse_pos.second;
-        class Corner {
-        public:
-            Corner(int x, int y) : x(x - root_x), y(y - root_y) {}
-
-            int x, y;
-        };
-        std::vector<Corner> corners;
-        corners.emplace_back(rectangle.get_x(), rectangle.get_y());
-        corners.emplace_back(rectangle.get_x() + rectangle.get_width(), rectangle.get_y());
-        corners.emplace_back(rectangle.get_x(), rectangle.get_y() + rectangle.get_height());
-        corners.emplace_back(rectangle.get_x() + rectangle.get_width(), rectangle.get_y() + rectangle.get_height());
-        for (auto &corner: corners) {
-            if (diff_x * corner.x + diff_y * corner.y >= 0)
-                return;
-        }
+  // Keep tooltip if mouse is moving towards it
+  // Calculated using dot product between the mouse_pos vector and the corners of the tooltip window
+  if (text_view && window && shown && last_mouse_pos.first != -1 && last_mouse_pos.second != -1 &&
+      mouse_pos.first != -1 && mouse_pos.second != -1) {
+    static int root_x, root_y;
+    text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(last_mouse_pos.first,
+                                                                                  last_mouse_pos.second, root_x,
+                                                                                  root_y);
+    int diff_x = mouse_pos.first - last_mouse_pos.first;
+    int diff_y = mouse_pos.second - last_mouse_pos.second;
+    class Corner {
+    public:
+      Corner(int x, int y) : x(x - root_x), y(y - root_y) {}
+
+      int x, y;
+    };
+    std::vector<Corner> corners;
+    corners.emplace_back(rectangle.get_x(), rectangle.get_y());
+    corners.emplace_back(rectangle.get_x() + rectangle.get_width(), rectangle.get_y());
+    corners.emplace_back(rectangle.get_x(), rectangle.get_y() + rectangle.get_height());
+    corners.emplace_back(rectangle.get_x() + rectangle.get_width(), rectangle.get_y() + rectangle.get_height());
+    for (auto &corner: corners) {
+      if (diff_x * corner.x + diff_y * corner.y >= 0)
+        return;
     }
-    Tooltips::shown_tooltips.erase(this);
-    if (window)
-        window->hide();
-    shown = false;
+  }
+  Tooltips::shown_tooltips.erase(this);
+  if (window)
+    window->hide();
+  shown = false;
 }
 
 void Tooltip::wrap_lines() {
-    if (!text_buffer)
-        return;
-
-    auto iter = text_buffer->begin();
-
-    while (iter) {
-        auto last_space = text_buffer->end();
-        bool end = false;
-        for (unsigned c = 0; c <= 80; c++) {
-            if (!iter) {
-                end = true;
-                break;
-            }
-            if (*iter == ' ')
-                last_space = iter;
-            if (*iter == '\n') {
-                end = true;
-                iter.forward_char();
-                break;
-            }
-            iter.forward_char();
-        }
-        if (!end) {
-            while (!last_space && iter) { //If no space (word longer than 80)
-                iter.forward_char();
-                if (iter && *iter == ' ')
-                    last_space = iter;
-            }
-            if (iter && last_space) {
-                auto mark = text_buffer->create_mark(last_space);
-                auto last_space_p = last_space;
-                last_space.forward_char();
-                text_buffer->erase(last_space_p, last_space);
-                text_buffer->insert(mark->get_iter(), "\n");
-
-                iter = mark->get_iter();
-                iter.forward_char();
-
-                text_buffer->delete_mark(mark);
-            }
-        }
+  if (!text_buffer)
+    return;
+
+  auto iter = text_buffer->begin();
+
+  while (iter) {
+    auto last_space = text_buffer->end();
+    bool end = false;
+    for (unsigned c = 0; c <= 80; c++) {
+      if (!iter) {
+        end = true;
+        break;
+      }
+      if (*iter == ' ')
+        last_space = iter;
+      if (*iter == '\n') {
+        end = true;
+        iter.forward_char();
+        break;
+      }
+      iter.forward_char();
     }
+    if (!end) {
+      while (!last_space && iter) { //If no space (word longer than 80)
+        iter.forward_char();
+        if (iter && *iter == ' ')
+          last_space = iter;
+      }
+      if (iter && last_space) {
+        auto mark = text_buffer->create_mark(last_space);
+        auto last_space_p = last_space;
+        last_space.forward_char();
+        text_buffer->erase(last_space_p, last_space);
+        text_buffer->insert(mark->get_iter(), "\n");
+
+        iter = mark->get_iter();
+        iter.forward_char();
+
+        text_buffer->delete_mark(mark);
+      }
+    }
+  }
 }
 
 void Tooltips::show(const Gdk::Rectangle &rectangle, bool disregard_drawn) {
-    for (auto &tooltip : tooltip_list) {
-        tooltip.update();
-        if (rectangle.intersects(tooltip.activation_rectangle))
-            tooltip.show(disregard_drawn, on_motion);
-        else
-            tooltip.hide();
-    }
+  for (auto &tooltip : tooltip_list) {
+    tooltip.update();
+    if (rectangle.intersects(tooltip.activation_rectangle))
+      tooltip.show(disregard_drawn, on_motion);
+    else
+      tooltip.hide();
+  }
 }
 
 void Tooltips::show(bool disregard_drawn) {
-    for (auto &tooltip : tooltip_list) {
-        tooltip.update();
-        tooltip.show(disregard_drawn, on_motion);
-    }
+  for (auto &tooltip : tooltip_list) {
+    tooltip.update();
+    tooltip.show(disregard_drawn, on_motion);
+  }
 }
 
 void Tooltips::hide(const std::pair<int, int> &last_mouse_pos, const std::pair<int, int> &mouse_pos) {
-    for (auto &tooltip : tooltip_list)
-        tooltip.hide(last_mouse_pos, mouse_pos);
+  for (auto &tooltip : tooltip_list)
+    tooltip.hide(last_mouse_pos, mouse_pos);
 }
diff --git a/src/tooltips.h b/src/tooltips.h
index 2cca4554..2b9ac105 100644
--- a/src/tooltips.h
+++ b/src/tooltips.h
@@ -8,62 +8,62 @@
 
 class Tooltip {
 public:
-    Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer, Gtk::TextView *text_view,
-            Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark);
+  Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer, Gtk::TextView *text_view,
+          Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark);
 
-    Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer) : Tooltip(create_tooltip_buffer,
-                                                                                            nullptr,
-                                                                                            Glib::RefPtr<Gtk::TextBuffer::Mark>(),
-                                                                                            Glib::RefPtr<Gtk::TextBuffer::Mark>()) {}
+  Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer) : Tooltip(create_tooltip_buffer,
+                                                                                          nullptr,
+                                                                                          Glib::RefPtr<Gtk::TextBuffer::Mark>(),
+                                                                                          Glib::RefPtr<Gtk::TextBuffer::Mark>()) {}
 
-    ~Tooltip();
+  ~Tooltip();
 
-    void update();
+  void update();
 
-    void show(bool disregard_drawn = false, const std::function<void()> &on_motion = nullptr);
+  void show(bool disregard_drawn = false, const std::function<void()> &on_motion = nullptr);
 
-    void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
+  void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
 
-    Gdk::Rectangle activation_rectangle;
-    Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
-    Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
+  Gdk::Rectangle activation_rectangle;
+  Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
+  Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
 
-    Glib::RefPtr<Gtk::TextBuffer> text_buffer;
+  Glib::RefPtr<Gtk::TextBuffer> text_buffer;
 private:
-    std::unique_ptr<Gtk::Window> window;
+  std::unique_ptr<Gtk::Window> window;
 
-    void wrap_lines();
+  void wrap_lines();
 
-    std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer;
-    Gtk::TextView *text_view;
-    std::pair<int, int> size;
-    Gdk::Rectangle rectangle;
+  std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer;
+  Gtk::TextView *text_view;
+  std::pair<int, int> size;
+  Gdk::Rectangle rectangle;
 
-    bool shown = false;
+  bool shown = false;
 };
 
 class Tooltips {
 public:
-    static std::set<Tooltip *> shown_tooltips;
-    static Gdk::Rectangle drawn_tooltips_rectangle;
+  static std::set<Tooltip *> shown_tooltips;
+  static Gdk::Rectangle drawn_tooltips_rectangle;
 
-    static void init() { drawn_tooltips_rectangle = Gdk::Rectangle(); }
+  static void init() { drawn_tooltips_rectangle = Gdk::Rectangle(); }
 
-    void show(const Gdk::Rectangle &rectangle, bool disregard_drawn = false);
+  void show(const Gdk::Rectangle &rectangle, bool disregard_drawn = false);
 
-    void show(bool disregard_drawn = false);
+  void show(bool disregard_drawn = false);
 
-    void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
+  void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
 
-    void clear() { tooltip_list.clear(); };
+  void clear() { tooltip_list.clear(); };
 
-    template<typename... Ts>
-    void emplace_back(Ts &&... params) {
-        tooltip_list.emplace_back(std::forward<Ts>(params)...);
-    }
+  template<typename... Ts>
+  void emplace_back(Ts &&... params) {
+    tooltip_list.emplace_back(std::forward<Ts>(params)...);
+  }
 
-    std::function<void()> on_motion;
+  std::function<void()> on_motion;
 
 private:
-    std::list<Tooltip> tooltip_list;
+  std::list<Tooltip> tooltip_list;
 };
diff --git a/src/usages_clang.cc b/src/usages_clang.cc
index 71719539..22c53190 100644
--- a/src/usages_clang.cc
+++ b/src/usages_clang.cc
@@ -13,7 +13,7 @@
 #include <windows.h>
 
 DWORD get_current_process_id() {
-    return GetCurrentProcessId();
+  return GetCurrentProcessId();
 }
 
 #else
@@ -29,100 +29,100 @@ std::mutex Usages::Clang::caches_mutex;
 std::atomic<size_t> Usages::Clang::cache_in_progress_count(0);
 
 bool Usages::Clang::Cache::Cursor::operator==(const Cursor &o) {
-    for (auto &usr : usrs) {
-        if (clangmm::Cursor::is_similar_kind(o.kind, kind) && o.usrs.count(usr))
-            return true;
-    }
-    return false;
+  for (auto &usr : usrs) {
+    if (clangmm::Cursor::is_similar_kind(o.kind, kind) && o.usrs.count(usr))
+      return true;
+  }
+  return false;
 }
 
 Usages::Clang::Cache::Cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
                             const boost::filesystem::path &path,
                             std::time_t before_parse_time, clangmm::TranslationUnit *translation_unit,
                             clangmm::Tokens *clang_tokens)
-        : project_path(project_path), build_path(build_path) {
-    for (auto &clang_token : *clang_tokens) {
-        tokens.emplace_back(Token{clang_token.get_spelling(), clang_token.get_source_range().get_offsets(),
-                                  static_cast<size_t>(-1)});
-
-        if (clang_token.is_identifier()) {
-            auto clang_cursor = clang_token.get_cursor().get_referenced();
-            if (clang_cursor) {
-                Cursor cursor{clang_cursor.get_kind(), clang_cursor.get_all_usr_extended()};
-                for (size_t c = 0; c < cursors.size(); ++c) {
-                    if (cursor == cursors[c]) {
-                        tokens.back().cursor_id = c;
-                        break;
-                    }
-                }
-                if (tokens.back().cursor_id == static_cast<size_t>(-1)) {
-                    cursors.emplace_back(cursor);
-                    tokens.back().cursor_id = cursors.size() - 1;
-                }
-            }
+    : project_path(project_path), build_path(build_path) {
+  for (auto &clang_token : *clang_tokens) {
+    tokens.emplace_back(Token{clang_token.get_spelling(), clang_token.get_source_range().get_offsets(),
+                              static_cast<size_t>(-1)});
+
+    if (clang_token.is_identifier()) {
+      auto clang_cursor = clang_token.get_cursor().get_referenced();
+      if (clang_cursor) {
+        Cursor cursor{clang_cursor.get_kind(), clang_cursor.get_all_usr_extended()};
+        for (size_t c = 0; c < cursors.size(); ++c) {
+          if (cursor == cursors[c]) {
+            tokens.back().cursor_id = c;
+            break;
+          }
+        }
+        if (tokens.back().cursor_id == static_cast<size_t>(-1)) {
+          cursors.emplace_back(cursor);
+          tokens.back().cursor_id = cursors.size() - 1;
         }
+      }
     }
-    boost::system::error_code ec;
-    auto last_write_time = boost::filesystem::last_write_time(path, ec);
-    if (ec)
-        last_write_time = 0;
-    if (last_write_time > before_parse_time)
-        last_write_time = 0;
-    paths_and_last_write_times.emplace(path, last_write_time);
-
-    class VisitorData {
-    public:
-        const boost::filesystem::path &project_path;
-        const boost::filesystem::path &path;
-        std::time_t before_parse_time;
-        std::map<boost::filesystem::path, std::time_t> &paths_and_last_write_times;
-    };
-    VisitorData visitor_data{project_path, path, before_parse_time, paths_and_last_write_times};
-
-    clang_getInclusions(translation_unit->cx_tu,
-                        [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len,
-                           CXClientData data) {
-                            auto visitor_data = static_cast<VisitorData *>(data);
-                            auto path = filesystem::get_normal_path(
-                                    clangmm::to_string(clang_getFileName(included_file)));
-                            if (filesystem::file_in_path(path, visitor_data->project_path)) {
-                                for (unsigned c = 0; c < include_len; ++c) {
-                                    auto from_path = filesystem::get_normal_path(
-                                            clangmm::SourceLocation(inclusion_stack[c]).get_path());
-                                    if (from_path == visitor_data->path) {
-                                        boost::system::error_code ec;
-                                        auto last_write_time = boost::filesystem::last_write_time(path, ec);
-                                        if (ec)
-                                            last_write_time = 0;
-                                        if (last_write_time > visitor_data->before_parse_time)
-                                            last_write_time = 0;
-                                        visitor_data->paths_and_last_write_times.emplace(path, last_write_time);
-                                        break;
-                                    }
-                                }
+  }
+  boost::system::error_code ec;
+  auto last_write_time = boost::filesystem::last_write_time(path, ec);
+  if (ec)
+    last_write_time = 0;
+  if (last_write_time > before_parse_time)
+    last_write_time = 0;
+  paths_and_last_write_times.emplace(path, last_write_time);
+
+  class VisitorData {
+  public:
+    const boost::filesystem::path &project_path;
+    const boost::filesystem::path &path;
+    std::time_t before_parse_time;
+    std::map<boost::filesystem::path, std::time_t> &paths_and_last_write_times;
+  };
+  VisitorData visitor_data{project_path, path, before_parse_time, paths_and_last_write_times};
+
+  clang_getInclusions(translation_unit->cx_tu,
+                      [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len,
+                         CXClientData data) {
+                        auto visitor_data = static_cast<VisitorData *>(data);
+                        auto path = filesystem::get_normal_path(
+                            clangmm::to_string(clang_getFileName(included_file)));
+                        if (filesystem::file_in_path(path, visitor_data->project_path)) {
+                          for (unsigned c = 0; c < include_len; ++c) {
+                            auto from_path = filesystem::get_normal_path(
+                                clangmm::SourceLocation(inclusion_stack[c]).get_path());
+                            if (from_path == visitor_data->path) {
+                              boost::system::error_code ec;
+                              auto last_write_time = boost::filesystem::last_write_time(path, ec);
+                              if (ec)
+                                last_write_time = 0;
+                              if (last_write_time > visitor_data->before_parse_time)
+                                last_write_time = 0;
+                              visitor_data->paths_and_last_write_times.emplace(path, last_write_time);
+                              break;
                             }
-                        },
-                        &visitor_data);
+                          }
+                        }
+                      },
+                      &visitor_data);
 }
 
 std::vector<std::pair<clangmm::Offset, clangmm::Offset>>
 Usages::Clang::Cache::get_similar_token_offsets(clangmm::Cursor::Kind kind, const std::string &spelling,
                                                 const std::unordered_set<std::string> &usrs) const {
-    std::vector<std::pair<clangmm::Offset, clangmm::Offset>> offsets;
-    for (auto &token : tokens) {
-        if (token.cursor_id != static_cast<size_t>(-1)) {
-            auto &cursor = cursors[token.cursor_id];
-            if (clangmm::Cursor::is_similar_kind(cursor.kind, kind) && token.spelling == spelling) {
-                for (auto &usr : cursor.usrs) {
-                    if (usrs.count(usr)) {
-                        offsets.emplace_back(token.offsets);
-                        break;
-                    }
-                }
-            }
+  std::vector<std::pair<clangmm::Offset, clangmm::Offset>> offsets;
+  for (auto &token : tokens) {
+    if (token.cursor_id != static_cast<size_t>(-1)) {
+      auto &cursor = cursors[token.cursor_id];
+      if (clangmm::Cursor::is_similar_kind(cursor.kind, kind) && token.spelling == spelling) {
+        for (auto &usr : cursor.usrs) {
+          if (usrs.count(usr)) {
+            offsets.emplace_back(token.offsets);
+            break;
+          }
         }
+      }
     }
-    return offsets;
+  }
+  return offsets;
 }
 
 std::vector<Usages::Clang::Usages>
@@ -130,296 +130,296 @@ Usages::Clang::get_usages(const boost::filesystem::path &project_path, const boo
                           const boost::filesystem::path &debug_path,
                           const std::string &spelling, const clangmm::Cursor &cursor,
                           const std::vector<clangmm::TranslationUnit *> &translation_units) {
-    std::vector<Usages> usages;
+  std::vector<Usages> usages;
 
-    if (spelling.empty())
-        return usages;
+  if (spelling.empty())
+    return usages;
 
-    PathSet visited;
+  PathSet visited;
 
-    auto usr_extended = cursor.get_usr_extended();
-    if (!usr_extended.empty() && usr_extended[0] >= '0' &&
-        usr_extended[0] <= '9') { //if declared within a function, return
-        if (!translation_units.empty())
-            add_usages(project_path, build_path, boost::filesystem::path(), usages, visited, spelling, cursor,
-                       translation_units.front(), false);
-        return usages;
-    }
+  auto usr_extended = cursor.get_usr_extended();
+  if (!usr_extended.empty() && usr_extended[0] >= '0' &&
+      usr_extended[0] <= '9') { //if declared within a function, return
+    if (!translation_units.empty())
+      add_usages(project_path, build_path, boost::filesystem::path(), usages, visited, spelling, cursor,
+                 translation_units.front(), false);
+    return usages;
+  }
 
-    for (auto &translation_unit : translation_units)
-        add_usages(project_path, build_path, boost::filesystem::path(), usages, visited, spelling, cursor,
-                   translation_unit, false);
-
-    for (auto &translation_unit : translation_units)
-        add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor, translation_unit, false);
-
-    if (project_path.empty())
-        return usages;
-
-    auto paths = find_paths(project_path, build_path, debug_path);
-    auto pair = parse_paths(spelling, paths);
-    PathSet all_cursors_paths;
-    auto canonical = cursor.get_canonical();
-    all_cursors_paths.emplace(canonical.get_source_location().get_path());
-    for (auto &cursor: canonical.get_all_overridden_cursors())
-        all_cursors_paths.emplace(cursor.get_source_location().get_path());
-    auto pair2 = find_potential_paths(all_cursors_paths, project_path, pair.first, pair.second);
-    auto &potential_paths = pair2.first;
-    auto &all_includes = pair2.second;
-
-    // Remove visited paths
-    for (auto it = potential_paths.begin(); it != potential_paths.end();) {
-        if (visited.find(*it) != visited.end())
-            it = potential_paths.erase(it);
-        else
-            ++it;
-    }
+  for (auto &translation_unit : translation_units)
+    add_usages(project_path, build_path, boost::filesystem::path(), usages, visited, spelling, cursor,
+               translation_unit, false);
 
-    // Wait for current caching to finish
-    std::unique_ptr<Dialog::Message> message;
-    const std::string message_string = "Please wait while finding usages";
-    if (cache_in_progress_count != 0) {
-        message = std::make_unique<Dialog::Message>(message_string);
-        while (cache_in_progress_count != 0) {
-            while (Gtk::Main::events_pending())
-                Gtk::Main::iteration(false);
-        }
-    }
+  for (auto &translation_unit : translation_units)
+    add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor, translation_unit, false);
 
-    // Use cache
-    for (auto it = potential_paths.begin(); it != potential_paths.end();) {
-        std::unique_lock<std::mutex> lock(caches_mutex);
-        auto caches_it = caches.find(*it);
-
-        // Load cache from file if not found in memory and if cache file exists
-        if (caches_it == caches.end()) {
-            auto cache = read_cache(project_path, build_path, *it);
-            if (cache) {
-                auto pair = caches.emplace(*it, std::move(cache));
-                caches_it = pair.first;
-            }
-        }
+  if (project_path.empty())
+    return usages;
 
-        if (caches_it != caches.end()) {
-            if (add_usages_from_cache(caches_it->first, usages, visited, spelling, cursor, caches_it->second))
-                it = potential_paths.erase(it);
-            else {
-                caches.erase(caches_it);
-                ++it;
-            }
-        } else
-            ++it;
+  auto paths = find_paths(project_path, build_path, debug_path);
+  auto pair = parse_paths(spelling, paths);
+  PathSet all_cursors_paths;
+  auto canonical = cursor.get_canonical();
+  all_cursors_paths.emplace(canonical.get_source_location().get_path());
+  for (auto &cursor: canonical.get_all_overridden_cursors())
+    all_cursors_paths.emplace(cursor.get_source_location().get_path());
+  auto pair2 = find_potential_paths(all_cursors_paths, project_path, pair.first, pair.second);
+  auto &potential_paths = pair2.first;
+  auto &all_includes = pair2.second;
+
+  // Remove visited paths
+  for (auto it = potential_paths.begin(); it != potential_paths.end();) {
+    if (visited.find(*it) != visited.end())
+      it = potential_paths.erase(it);
+    else
+      ++it;
+  }
+
+  // Wait for current caching to finish
+  std::unique_ptr<Dialog::Message> message;
+  const std::string message_string = "Please wait while finding usages";
+  if (cache_in_progress_count != 0) {
+    message = std::make_unique<Dialog::Message>(message_string);
+    while (cache_in_progress_count != 0) {
+      while (Gtk::Main::events_pending())
+        Gtk::Main::iteration(false);
     }
+  }
 
-    // Remove paths that has been included
-    for (auto it = potential_paths.begin(); it != potential_paths.end();) {
-        if (all_includes.find(*it) != all_includes.end())
-            it = potential_paths.erase(it);
-        else
-            ++it;
+  // Use cache
+  for (auto it = potential_paths.begin(); it != potential_paths.end();) {
+    std::unique_lock<std::mutex> lock(caches_mutex);
+    auto caches_it = caches.find(*it);
+
+    // Load cache from file if not found in memory and if cache file exists
+    if (caches_it == caches.end()) {
+      auto cache = read_cache(project_path, build_path, *it);
+      if (cache) {
+        auto pair = caches.emplace(*it, std::move(cache));
+        caches_it = pair.first;
+      }
     }
 
-    // Parse potential paths
-    if (!potential_paths.empty()) {
-        if (!message)
-            message = std::make_unique<Dialog::Message>(message_string);
-
-        std::vector<std::thread> threads;
-        auto it = potential_paths.begin();
-        auto number_of_threads = Config::get().source.clang_usages_threads;
-        if (number_of_threads == static_cast<unsigned>(-1)) {
-            number_of_threads = std::thread::hardware_concurrency();
-            if (number_of_threads == 0)
-                number_of_threads = 1;
-        }
-        for (unsigned thread_id = 0; thread_id < number_of_threads; ++thread_id) {
-            threads.emplace_back([&potential_paths, &it, &build_path,
-                                         &project_path, &usages, &visited, &spelling, &cursor] {
-                while (true) {
-                    boost::filesystem::path path;
-                    {
-                        static std::mutex mutex;
-                        std::unique_lock<std::mutex> lock(mutex);
-                        if (it == potential_paths.end())
-                            return;
-                        path = *it;
-                        ++it;
-                    }
-                    clangmm::Index index(0, 0);
-
-                    {
-                        static std::mutex mutex;
-                        std::unique_lock<std::mutex> lock(mutex);
-                        // std::cout << "parsing: " << path << std::endl;
-                    }
-                    // auto before_time = std::chrono::system_clock::now();
-
-                    std::ifstream stream(path.string(), std::ifstream::binary);
-                    std::string buffer;
-                    buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
-
-                    auto arguments = CompileCommands::get_arguments(build_path, path);
-                    arguments.emplace_back("-w"); // Disable all warnings
-                    for (auto it = arguments.begin(); it != arguments.end();) { // remove comments from system headers
-                        if (*it == "-fretain-comments-from-system-headers")
-                            it = arguments.erase(it);
-                        else
-                            ++it;
-                    }
-                    int flags = CXTranslationUnit_Incomplete;
+    if (caches_it != caches.end()) {
+      if (add_usages_from_cache(caches_it->first, usages, visited, spelling, cursor, caches_it->second))
+        it = potential_paths.erase(it);
+      else {
+        caches.erase(caches_it);
+        ++it;
+      }
+    } else
+      ++it;
+  }
+
+  // Remove paths that has been included
+  for (auto it = potential_paths.begin(); it != potential_paths.end();) {
+    if (all_includes.find(*it) != all_includes.end())
+      it = potential_paths.erase(it);
+    else
+      ++it;
+  }
+
+  // Parse potential paths
+  if (!potential_paths.empty()) {
+    if (!message)
+      message = std::make_unique<Dialog::Message>(message_string);
+
+    std::vector<std::thread> threads;
+    auto it = potential_paths.begin();
+    auto number_of_threads = Config::get().source.clang_usages_threads;
+    if (number_of_threads == static_cast<unsigned>(-1)) {
+      number_of_threads = std::thread::hardware_concurrency();
+      if (number_of_threads == 0)
+        number_of_threads = 1;
+    }
+    for (unsigned thread_id = 0; thread_id < number_of_threads; ++thread_id) {
+      threads.emplace_back([&potential_paths, &it, &build_path,
+                               &project_path, &usages, &visited, &spelling, &cursor] {
+        while (true) {
+          boost::filesystem::path path;
+          {
+            static std::mutex mutex;
+            std::unique_lock<std::mutex> lock(mutex);
+            if (it == potential_paths.end())
+              return;
+            path = *it;
+            ++it;
+          }
+          clangmm::Index index(0, 0);
+
+          {
+            static std::mutex mutex;
+            std::unique_lock<std::mutex> lock(mutex);
+            // std::cout << "parsing: " << path << std::endl;
+          }
+          // auto before_time = std::chrono::system_clock::now();
+
+          std::ifstream stream(path.string(), std::ifstream::binary);
+          std::string buffer;
+          buffer.assign(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
+
+          auto arguments = CompileCommands::get_arguments(build_path, path);
+          arguments.emplace_back("-w"); // Disable all warnings
+          for (auto it = arguments.begin(); it != arguments.end();) { // remove comments from system headers
+            if (*it == "-fretain-comments-from-system-headers")
+              it = arguments.erase(it);
+            else
+              ++it;
+          }
+          int flags = CXTranslationUnit_Incomplete;
 #if CINDEX_VERSION_MAJOR > 0 || (CINDEX_VERSION_MAJOR == 0 && CINDEX_VERSION_MINOR >= 35)
-                    flags |= CXTranslationUnit_KeepGoing;
+          flags |= CXTranslationUnit_KeepGoing;
 #endif
 
-                    clangmm::TranslationUnit translation_unit(index, path.string(), arguments, buffer, flags);
-
-                    {
-                        static std::mutex mutex;
-                        std::unique_lock<std::mutex> lock(mutex);
-                        add_usages(project_path, build_path, path, usages, visited, spelling, cursor, &translation_unit,
-                                   true);
-                        add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor,
-                                                 &translation_unit, true);
-                    }
-
-                    // auto time = std::chrono::system_clock::now();
-                    // std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(time - before_time).count() << std::endl;
-                }
-            });
+          clangmm::TranslationUnit translation_unit(index, path.string(), arguments, buffer, flags);
+
+          {
+            static std::mutex mutex;
+            std::unique_lock<std::mutex> lock(mutex);
+            add_usages(project_path, build_path, path, usages, visited, spelling, cursor, &translation_unit,
+                       true);
+            add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor,
+                                     &translation_unit, true);
+          }
+
+          // auto time = std::chrono::system_clock::now();
+          // std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(time - before_time).count() << std::endl;
         }
-        for (auto &thread : threads)
-            thread.join();
+      });
     }
+    for (auto &thread : threads)
+      thread.join();
+  }
 
-    if (message)
-        message->hide();
+  if (message)
+    message->hide();
 
-    return usages;
+  return usages;
 }
 
 void Usages::Clang::cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
                           const boost::filesystem::path &path,
                           std::time_t before_parse_time, const PathSet &project_paths_in_use,
                           clangmm::TranslationUnit *translation_unit, clangmm::Tokens *tokens) {
-    class ScopeExit {
-    public:
-        std::function<void()> f;
+  class ScopeExit {
+  public:
+    std::function<void()> f;
 
-        ~ScopeExit() {
-            f();
-        }
-    };
-    ScopeExit scope_exit{[] {
-        --cache_in_progress_count;
-    }};
-
-    if (project_path.empty())
-        return;
-
-    {
-        std::unique_lock<std::mutex> lock(caches_mutex);
-        if (project_paths_in_use.count(project_path)) {
-            caches.erase(path);
-            caches.emplace(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens));
-        } else
-            write_cache(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens));
+    ~ScopeExit() {
+      f();
     }
+  };
+  ScopeExit scope_exit{[] {
+    --cache_in_progress_count;
+  }};
 
-    class VisitorData {
-    public:
-        const boost::filesystem::path &project_path;
-        PathSet paths;
-    };
-    VisitorData visitor_data{project_path, {}};
+  if (project_path.empty())
+    return;
 
-    auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
-    clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
-                            auto visitor_data = static_cast<VisitorData *>(data);
+  {
+    std::unique_lock<std::mutex> lock(caches_mutex);
+    if (project_paths_in_use.count(project_path)) {
+      caches.erase(path);
+      caches.emplace(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens));
+    } else
+      write_cache(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens));
+  }
+
+  class VisitorData {
+  public:
+    const boost::filesystem::path &project_path;
+    PathSet paths;
+  };
+  VisitorData visitor_data{project_path, {}};
 
-                            auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
-                            if (filesystem::file_in_path(path, visitor_data->project_path))
-                                visitor_data->paths.emplace(path);
+  auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
+  clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
+                        auto visitor_data = static_cast<VisitorData *>(data);
 
-                            return CXChildVisit_Continue;
-                        },
-                        &visitor_data);
+                        auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
+                        if (filesystem::file_in_path(path, visitor_data->project_path))
+                          visitor_data->paths.emplace(path);
 
-    visitor_data.paths.erase(path);
+                        return CXChildVisit_Continue;
+                      },
+                      &visitor_data);
 
-    for (auto &path : visitor_data.paths) {
-        boost::system::error_code ec;
-        auto file_size = boost::filesystem::file_size(path, ec);
-        if (file_size == static_cast<boost::uintmax_t>(-1) || ec)
-            continue;
-        auto tokens = translation_unit->get_tokens(path.string(), 0, file_size - 1);
-        std::unique_lock<std::mutex> lock(caches_mutex);
-        if (project_paths_in_use.count(project_path)) {
-            caches.erase(path);
-            caches.emplace(path,
-                           Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
-        } else
-            write_cache(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
-    }
+  visitor_data.paths.erase(path);
+
+  for (auto &path : visitor_data.paths) {
+    boost::system::error_code ec;
+    auto file_size = boost::filesystem::file_size(path, ec);
+    if (file_size == static_cast<boost::uintmax_t>(-1) || ec)
+      continue;
+    auto tokens = translation_unit->get_tokens(path.string(), 0, file_size - 1);
+    std::unique_lock<std::mutex> lock(caches_mutex);
+    if (project_paths_in_use.count(project_path)) {
+      caches.erase(path);
+      caches.emplace(path,
+                     Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
+    } else
+      write_cache(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
+  }
 }
 
 void Usages::Clang::erase_unused_caches(const PathSet &project_paths_in_use) {
-    std::unique_lock<std::mutex> lock(caches_mutex);
-    for (auto it = caches.begin(); it != caches.end();) {
-        bool found = false;
-        for (auto &project_path : project_paths_in_use) {
-            if (filesystem::file_in_path(it->first, project_path)) {
-                found = true;
-                break;
-            }
-        }
-        if (!found) {
-            write_cache(it->first, it->second);
-            it = caches.erase(it);
-        } else
-            ++it;
+  std::unique_lock<std::mutex> lock(caches_mutex);
+  for (auto it = caches.begin(); it != caches.end();) {
+    bool found = false;
+    for (auto &project_path : project_paths_in_use) {
+      if (filesystem::file_in_path(it->first, project_path)) {
+        found = true;
+        break;
+      }
     }
+    if (!found) {
+      write_cache(it->first, it->second);
+      it = caches.erase(it);
+    } else
+      ++it;
+  }
 }
 
 void Usages::Clang::erase_cache(const boost::filesystem::path &path) {
-    std::unique_lock<std::mutex> lock(caches_mutex);
+  std::unique_lock<std::mutex> lock(caches_mutex);
 
-    auto it = caches.find(path);
-    if (it == caches.end())
-        return;
+  auto it = caches.find(path);
+  if (it == caches.end())
+    return;
 
-    auto paths_and_last_write_times = std::move(it->second.paths_and_last_write_times);
-    for (auto &path_and_last_write_time : paths_and_last_write_times)
-        caches.erase(path_and_last_write_time.first);
+  auto paths_and_last_write_times = std::move(it->second.paths_and_last_write_times);
+  for (auto &path_and_last_write_time : paths_and_last_write_times)
+    caches.erase(path_and_last_write_time.first);
 }
 
 void Usages::Clang::erase_all_caches_for_project(const boost::filesystem::path &project_path,
                                                  const boost::filesystem::path &build_path) {
-    if (project_path.empty())
-        return;
-
-    if (cache_in_progress_count != 0)
-        std::this_thread::sleep_for(std::chrono::milliseconds(10));
-
-    std::unique_lock<std::mutex> lock(caches_mutex);
-    boost::system::error_code ec;
-    auto usages_clang_path = build_path / cache_folder;
-    if (boost::filesystem::exists(usages_clang_path, ec) && boost::filesystem::is_directory(usages_clang_path, ec)) {
-        for (boost::filesystem::directory_iterator it(usages_clang_path), end; it != end; ++it) {
-            if (it->path().extension() == ".usages")
-                boost::filesystem::remove(it->path(), ec);
-        }
+  if (project_path.empty())
+    return;
+
+  if (cache_in_progress_count != 0)
+    std::this_thread::sleep_for(std::chrono::milliseconds(10));
+
+  std::unique_lock<std::mutex> lock(caches_mutex);
+  boost::system::error_code ec;
+  auto usages_clang_path = build_path / cache_folder;
+  if (boost::filesystem::exists(usages_clang_path, ec) && boost::filesystem::is_directory(usages_clang_path, ec)) {
+    for (boost::filesystem::directory_iterator it(usages_clang_path), end; it != end; ++it) {
+      if (it->path().extension() == ".usages")
+        boost::filesystem::remove(it->path(), ec);
     }
+  }
 
-    for (auto it = caches.begin(); it != caches.end();) {
-        if (filesystem::file_in_path(it->first, project_path))
-            it = caches.erase(it);
-        else
-            ++it;
-    }
+  for (auto it = caches.begin(); it != caches.end();) {
+    if (filesystem::file_in_path(it->first, project_path))
+      it = caches.erase(it);
+    else
+      ++it;
+  }
 }
 
 void Usages::Clang::cache_in_progress() {
-    ++cache_in_progress_count;
+  ++cache_in_progress_count;
 }
 
 void Usages::Clang::add_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
@@ -427,86 +427,86 @@ void Usages::Clang::add_usages(const boost::filesystem::path &project_path, cons
                                std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
                                clangmm::Cursor cursor,
                                clangmm::TranslationUnit *translation_unit, bool store_in_cache) {
-    std::unique_ptr<clangmm::Tokens> tokens;
-    boost::filesystem::path path;
-    auto before_parse_time = std::time(nullptr);
-    auto all_usr_extended = cursor.get_all_usr_extended();
-    if (path_.empty()) {
-        path = clangmm::to_string(clang_getTranslationUnitSpelling(translation_unit->cx_tu));
-        if (visited.find(path) != visited.end() || !filesystem::file_in_path(path, project_path))
-            return;
-        tokens = translation_unit->get_tokens();
-    } else {
-        path = path_;
-        if (visited.find(path) != visited.end() || !filesystem::file_in_path(path, project_path))
-            return;
-        boost::system::error_code ec;
-        auto file_size = boost::filesystem::file_size(path, ec);
-        if (file_size == static_cast<boost::uintmax_t>(-1) || ec)
-            return;
-        tokens = translation_unit->get_tokens(path.string(), 0, file_size - 1);
-    }
-
-    auto offsets = tokens->get_similar_token_offsets(cursor.get_kind(), spelling, all_usr_extended);
-    std::vector<std::string> lines;
-    for (auto &offset : offsets) {
-        std::string line;
-        auto line_nr = offset.second.line;
-        for (auto &token : *tokens) {
-            auto offset = token.get_source_location().get_offset();
-            if (offset.line == line_nr) {
-                while (line.size() < offset.index - 1)
-                    line += ' ';
-                line += token.get_spelling();
-            }
-        }
-        lines.emplace_back(std::move(line));
+  std::unique_ptr<clangmm::Tokens> tokens;
+  boost::filesystem::path path;
+  auto before_parse_time = std::time(nullptr);
+  auto all_usr_extended = cursor.get_all_usr_extended();
+  if (path_.empty()) {
+    path = clangmm::to_string(clang_getTranslationUnitSpelling(translation_unit->cx_tu));
+    if (visited.find(path) != visited.end() || !filesystem::file_in_path(path, project_path))
+      return;
+    tokens = translation_unit->get_tokens();
+  } else {
+    path = path_;
+    if (visited.find(path) != visited.end() || !filesystem::file_in_path(path, project_path))
+      return;
+    boost::system::error_code ec;
+    auto file_size = boost::filesystem::file_size(path, ec);
+    if (file_size == static_cast<boost::uintmax_t>(-1) || ec)
+      return;
+    tokens = translation_unit->get_tokens(path.string(), 0, file_size - 1);
+  }
+
+  auto offsets = tokens->get_similar_token_offsets(cursor.get_kind(), spelling, all_usr_extended);
+  std::vector<std::string> lines;
+  for (auto &offset : offsets) {
+    std::string line;
+    auto line_nr = offset.second.line;
+    for (auto &token : *tokens) {
+      auto offset = token.get_source_location().get_offset();
+      if (offset.line == line_nr) {
+        while (line.size() < offset.index - 1)
+          line += ' ';
+        line += token.get_spelling();
+      }
     }
+    lines.emplace_back(std::move(line));
+  }
 
-    if (store_in_cache && filesystem::file_in_path(path, project_path)) {
-        std::unique_lock<std::mutex> lock(caches_mutex);
-        caches.erase(path);
-        caches.emplace(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
-    }
+  if (store_in_cache && filesystem::file_in_path(path, project_path)) {
+    std::unique_lock<std::mutex> lock(caches_mutex);
+    caches.erase(path);
+    caches.emplace(path, Cache(project_path, build_path, path, before_parse_time, translation_unit, tokens.get()));
+  }
 
-    visited.emplace(path);
-    if (!offsets.empty())
-        usages.emplace_back(Usages{std::move(path), std::move(offsets), lines});
+  visited.emplace(path);
+  if (!offsets.empty())
+    usages.emplace_back(Usages{std::move(path), std::move(offsets), lines});
 }
 
 bool
 Usages::Clang::add_usages_from_cache(const boost::filesystem::path &path, std::vector<Usages> &usages, PathSet &visited,
                                      const std::string &spelling, const clangmm::Cursor &cursor, const Cache &cache) {
-    for (auto &path_and_last_write_time : cache.paths_and_last_write_times) {
-        boost::system::error_code ec;
-        auto last_write_time = boost::filesystem::last_write_time(path_and_last_write_time.first, ec);
-        if (ec || last_write_time != path_and_last_write_time.second) {
-            // std::cout << "updated file: " << path_and_last_write_time.first << ", included from " << path << std::endl;
-            return false;
-        }
+  for (auto &path_and_last_write_time : cache.paths_and_last_write_times) {
+    boost::system::error_code ec;
+    auto last_write_time = boost::filesystem::last_write_time(path_and_last_write_time.first, ec);
+    if (ec || last_write_time != path_and_last_write_time.second) {
+      // std::cout << "updated file: " << path_and_last_write_time.first << ", included from " << path << std::endl;
+      return false;
     }
-
-    auto offsets = cache.get_similar_token_offsets(cursor.get_kind(), spelling, cursor.get_all_usr_extended());
-
-    std::vector<std::string> lines;
-    for (auto &offset : offsets) {
-        std::string line;
-        auto line_nr = offset.second.line;
-        for (auto &token : cache.tokens) {
-            auto &offset = token.offsets.first;
-            if (offset.line == line_nr) {
-                while (line.size() < offset.index - 1)
-                    line += ' ';
-                line += token.spelling;
-            }
-        }
-        lines.emplace_back(std::move(line));
+  }
+
+  auto offsets = cache.get_similar_token_offsets(cursor.get_kind(), spelling, cursor.get_all_usr_extended());
+
+  std::vector<std::string> lines;
+  for (auto &offset : offsets) {
+    std::string line;
+    auto line_nr = offset.second.line;
+    for (auto &token : cache.tokens) {
+      auto &offset = token.offsets.first;
+      if (offset.line == line_nr) {
+        while (line.size() < offset.index - 1)
+          line += ' ';
+        line += token.spelling;
+      }
     }
+    lines.emplace_back(std::move(line));
+  }
 
-    visited.emplace(path);
-    if (!offsets.empty())
-        usages.emplace_back(Usages{path, std::move(offsets), lines});
-    return true;
+  visited.emplace(path);
+  if (!offsets.empty())
+    usages.emplace_back(Usages{path, std::move(offsets), lines});
+  return true;
 }
 
 void Usages::Clang::add_usages_from_includes(const boost::filesystem::path &project_path,
@@ -514,268 +514,268 @@ void Usages::Clang::add_usages_from_includes(const boost::filesystem::path &proj
                                              std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
                                              const clangmm::Cursor &cursor,
                                              clangmm::TranslationUnit *translation_unit, bool store_in_cache) {
-    if (project_path.empty())
-        return;
-
-    class VisitorData {
-    public:
-        const boost::filesystem::path &project_path;
-        const std::string &spelling;
-        PathSet &visited;
-        PathSet paths;
-    };
-    VisitorData visitor_data{project_path, spelling, visited, {}};
-
-    auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
-    clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
-                            auto visitor_data = static_cast<VisitorData *>(data);
-
-                            auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
-                            if (visitor_data->visited.find(path) == visitor_data->visited.end() &&
-                                filesystem::file_in_path(path, visitor_data->project_path))
-                                visitor_data->paths.emplace(path);
-
-                            return CXChildVisit_Continue;
-                        },
-                        &visitor_data);
-
-    for (auto &path : visitor_data.paths)
-        add_usages(project_path, build_path, path, usages, visited, spelling, cursor, translation_unit, store_in_cache);
+  if (project_path.empty())
+    return;
+
+  class VisitorData {
+  public:
+    const boost::filesystem::path &project_path;
+    const std::string &spelling;
+    PathSet &visited;
+    PathSet paths;
+  };
+  VisitorData visitor_data{project_path, spelling, visited, {}};
+
+  auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
+  clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
+                        auto visitor_data = static_cast<VisitorData *>(data);
+
+                        auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
+                        if (visitor_data->visited.find(path) == visitor_data->visited.end() &&
+                            filesystem::file_in_path(path, visitor_data->project_path))
+                          visitor_data->paths.emplace(path);
+
+                        return CXChildVisit_Continue;
+                      },
+                      &visitor_data);
+
+  for (auto &path : visitor_data.paths)
+    add_usages(project_path, build_path, path, usages, visited, spelling, cursor, translation_unit, store_in_cache);
 }
 
 Usages::Clang::PathSet Usages::Clang::find_paths(const boost::filesystem::path &project_path,
                                                  const boost::filesystem::path &build_path,
                                                  const boost::filesystem::path &debug_path) {
-    PathSet paths;
+  PathSet paths;
 
-    CompileCommands compile_commands(build_path);
+  CompileCommands compile_commands(build_path);
 
-    for (boost::filesystem::recursive_directory_iterator it(project_path), end; it != end; ++it) {
-        auto &path = it->path();
-        if (!boost::filesystem::is_regular_file(path)) {
-            if (path == build_path || path == debug_path || path.filename() == ".git")
-                it.no_push();
-            continue;
-        }
+  for (boost::filesystem::recursive_directory_iterator it(project_path), end; it != end; ++it) {
+    auto &path = it->path();
+    if (!boost::filesystem::is_regular_file(path)) {
+      if (path == build_path || path == debug_path || path.filename() == ".git")
+        it.no_push();
+      continue;
+    }
 
-        if (is_header(path))
-            paths.emplace(path);
-        else if (is_source(path)) {
-            for (auto &command : compile_commands.commands) {
-                if (filesystem::get_normal_path(command.file) == path) {
-                    paths.emplace(path);
-                    break;
-                }
-            }
+    if (is_header(path))
+      paths.emplace(path);
+    else if (is_source(path)) {
+      for (auto &command : compile_commands.commands) {
+        if (filesystem::get_normal_path(command.file) == path) {
+          paths.emplace(path);
+          break;
         }
+      }
     }
+  }
 
-    return paths;
+  return paths;
 }
 
 bool Usages::Clang::is_header(const boost::filesystem::path &path) {
-    auto ext = path.extension();
-    if (ext == ".h" || // c headers
-        ext == ".hh" || ext == ".hp" || ext == ".hpp" || ext == ".h++" || ext == ".tcc" || // c++ headers
-        ext == ".cuh") // CUDA headers
-        return true;
-    else
-        return false;
+  auto ext = path.extension();
+  if (ext == ".h" || // c headers
+      ext == ".hh" || ext == ".hp" || ext == ".hpp" || ext == ".h++" || ext == ".tcc" || // c++ headers
+      ext == ".cuh") // CUDA headers
+    return true;
+  else
+    return false;
 }
 
 bool Usages::Clang::is_source(const boost::filesystem::path &path) {
-    auto ext = path.extension();
-    if (ext == ".c" || // c sources
-        ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".C" || ext == ".c++" || // c++ sources
-        ext == ".cu" || // CUDA sources
-        ext == ".cl") // OpenCL sources
-        return true;
-    else
-        return false;
+  auto ext = path.extension();
+  if (ext == ".c" || // c sources
+      ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".C" || ext == ".c++" || // c++ sources
+      ext == ".cu" || // CUDA sources
+      ext == ".cl") // OpenCL sources
+    return true;
+  else
+    return false;
 }
 
 std::pair<std::map<boost::filesystem::path, Usages::Clang::PathSet>, Usages::Clang::PathSet>
 Usages::Clang::parse_paths(const std::string &spelling, const PathSet &paths) {
-    std::map<boost::filesystem::path, PathSet> paths_includes;
-    PathSet paths_with_spelling;
-
-    const static std::regex include_regex("^[ \t]*#[ \t]*include[ \t]*[\"]([^\"]+)[\"].*$");
-
-    auto is_spelling_char = [](char chr) {
-        return (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr == '_';
-    };
-
-    for (auto &path : paths) {
-        auto paths_includes_it = paths_includes.emplace(path, PathSet()).first;
-        bool paths_with_spelling_emplaced = false;
-
-        std::ifstream stream(path.string(), std::ifstream::binary);
-        if (!stream)
+  std::map<boost::filesystem::path, PathSet> paths_includes;
+  PathSet paths_with_spelling;
+
+  const static std::regex include_regex("^[ \t]*#[ \t]*include[ \t]*[\"]([^\"]+)[\"].*$");
+
+  auto is_spelling_char = [](char chr) {
+    return (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr == '_';
+  };
+
+  for (auto &path : paths) {
+    auto paths_includes_it = paths_includes.emplace(path, PathSet()).first;
+    bool paths_with_spelling_emplaced = false;
+
+    std::ifstream stream(path.string(), std::ifstream::binary);
+    if (!stream)
+      continue;
+    std::string line;
+    while (std::getline(stream, line)) {
+      std::smatch sm;
+      if (std::regex_match(line, sm, include_regex)) {
+        boost::filesystem::path path(sm[1].str());
+        boost::filesystem::path include_path;
+        // remove .. and .
+        for (auto &part : path) {
+          if (part == "..")
+            include_path = include_path.parent_path();
+          else if (part == ".")
             continue;
-        std::string line;
-        while (std::getline(stream, line)) {
-            std::smatch sm;
-            if (std::regex_match(line, sm, include_regex)) {
-                boost::filesystem::path path(sm[1].str());
-                boost::filesystem::path include_path;
-                // remove .. and .
-                for (auto &part : path) {
-                    if (part == "..")
-                        include_path = include_path.parent_path();
-                    else if (part == ".")
-                        continue;
-                    else
-                        include_path /= part;
-                }
-                auto distance = std::distance(include_path.begin(), include_path.end());
-                for (auto &path : paths) {
-                    auto path_distance = std::distance(path.begin(), path.end());
-                    if (path_distance >= distance) {
-                        auto it = path.begin();
-                        std::advance(it, path_distance - distance);
-                        if (std::equal(it, path.end(), include_path.begin(), include_path.end()))
-                            paths_includes_it->second.emplace(path);
-                    }
-                }
-            } else if (!paths_with_spelling_emplaced) {
-                auto pos = line.find(spelling);
-                if (pos != std::string::npos &&
-                    ((!spelling.empty() && !is_spelling_char(spelling[0])) ||
-                     ((pos == 0 || !is_spelling_char(line[pos - 1])) &&
-                      (pos + spelling.size() >= line.size() - 1 || !is_spelling_char(line[pos + spelling.size()]))))) {
-                    paths_with_spelling.emplace(path);
-                    paths_with_spelling_emplaced = true;
-                }
-            }
+          else
+            include_path /= part;
+        }
+        auto distance = std::distance(include_path.begin(), include_path.end());
+        for (auto &path : paths) {
+          auto path_distance = std::distance(path.begin(), path.end());
+          if (path_distance >= distance) {
+            auto it = path.begin();
+            std::advance(it, path_distance - distance);
+            if (std::equal(it, path.end(), include_path.begin(), include_path.end()))
+              paths_includes_it->second.emplace(path);
+          }
+        }
+      } else if (!paths_with_spelling_emplaced) {
+        auto pos = line.find(spelling);
+        if (pos != std::string::npos &&
+            ((!spelling.empty() && !is_spelling_char(spelling[0])) ||
+             ((pos == 0 || !is_spelling_char(line[pos - 1])) &&
+              (pos + spelling.size() >= line.size() - 1 || !is_spelling_char(line[pos + spelling.size()]))))) {
+          paths_with_spelling.emplace(path);
+          paths_with_spelling_emplaced = true;
         }
+      }
     }
-    return {paths_includes, paths_with_spelling};
+  }
+  return {paths_includes, paths_with_spelling};
 }
 
 Usages::Clang::PathSet Usages::Clang::get_all_includes(const boost::filesystem::path &path,
                                                        const std::map<boost::filesystem::path, PathSet> &paths_includes) {
-    PathSet all_includes;
-
-    class Recursive {
-    public:
-        static void f(PathSet &all_includes, const boost::filesystem::path &path,
-                      const std::map<boost::filesystem::path, PathSet> &paths_includes) {
-            auto paths_includes_it = paths_includes.find(path);
-            if (paths_includes_it != paths_includes.end()) {
-                for (auto &include : paths_includes_it->second) {
-                    auto pair = all_includes.emplace(include);
-                    if (pair.second)
-                        f(all_includes, include, paths_includes);
-                }
-            }
+  PathSet all_includes;
+
+  class Recursive {
+  public:
+    static void f(PathSet &all_includes, const boost::filesystem::path &path,
+                  const std::map<boost::filesystem::path, PathSet> &paths_includes) {
+      auto paths_includes_it = paths_includes.find(path);
+      if (paths_includes_it != paths_includes.end()) {
+        for (auto &include : paths_includes_it->second) {
+          auto pair = all_includes.emplace(include);
+          if (pair.second)
+            f(all_includes, include, paths_includes);
         }
-    };
-    Recursive::f(all_includes, path, paths_includes);
+      }
+    }
+  };
+  Recursive::f(all_includes, path, paths_includes);
 
-    return all_includes;
+  return all_includes;
 }
 
 std::pair<Usages::Clang::PathSet, Usages::Clang::PathSet>
 Usages::Clang::find_potential_paths(const PathSet &paths, const boost::filesystem::path &project_path,
                                     const std::map<boost::filesystem::path, PathSet> &paths_includes,
                                     const PathSet &paths_with_spelling) {
-    PathSet potential_paths;
-    PathSet all_includes;
-
-    bool first = true;
-    for (auto &path: paths) {
-        if (filesystem::file_in_path(path, project_path)) {
-            for (auto &path_with_spelling : paths_with_spelling) {
-                auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
-                if ((path_all_includes.find(path) != path_all_includes.end() || path_with_spelling == path)) {
-                    potential_paths.emplace(path_with_spelling);
-
-                    for (auto &include : path_all_includes)
-                        all_includes.emplace(include);
-                }
-            }
-        } else {
-            if (first) {
-                for (auto &path_with_spelling : paths_with_spelling) {
-                    potential_paths.emplace(path_with_spelling);
-
-                    auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
-                    for (auto &include : path_all_includes)
-                        all_includes.emplace(include);
-                }
-                first = false;
-            }
+  PathSet potential_paths;
+  PathSet all_includes;
+
+  bool first = true;
+  for (auto &path: paths) {
+    if (filesystem::file_in_path(path, project_path)) {
+      for (auto &path_with_spelling : paths_with_spelling) {
+        auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
+        if ((path_all_includes.find(path) != path_all_includes.end() || path_with_spelling == path)) {
+          potential_paths.emplace(path_with_spelling);
+
+          for (auto &include : path_all_includes)
+            all_includes.emplace(include);
+        }
+      }
+    } else {
+      if (first) {
+        for (auto &path_with_spelling : paths_with_spelling) {
+          potential_paths.emplace(path_with_spelling);
+
+          auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
+          for (auto &include : path_all_includes)
+            all_includes.emplace(include);
         }
+        first = false;
+      }
     }
+  }
 
-    return {potential_paths, all_includes};
+  return {potential_paths, all_includes};
 }
 
 void Usages::Clang::write_cache(const boost::filesystem::path &path, const Clang::Cache &cache) {
-    auto cache_path = cache.build_path / cache_folder;
-    boost::system::error_code ec;
-    if (!boost::filesystem::exists(cache_path, ec)) {
-        boost::filesystem::create_directory(cache_path, ec);
-        if (ec)
-            return;
-    } else if (!boost::filesystem::is_directory(cache_path, ec) || ec)
-        return;
-
-    auto path_str = filesystem::get_relative_path(path, cache.project_path).string();
-    for (auto &chr : path_str) {
-        if (chr == '/' || chr == '\\')
-            chr = '_';
-    }
-    path_str += ".usages";
-
-    auto full_cache_path = cache_path / path_str;
-    auto tmp_file = boost::filesystem::temp_directory_path(ec);
+  auto cache_path = cache.build_path / cache_folder;
+  boost::system::error_code ec;
+  if (!boost::filesystem::exists(cache_path, ec)) {
+    boost::filesystem::create_directory(cache_path, ec);
     if (ec)
-        return;
-    tmp_file /= ("jucipp" + std::to_string(get_current_process_id()) + path_str);
-
-    std::ofstream stream(tmp_file.string());
-    if (stream) {
-        try {
-            boost::archive::text_oarchive text_oarchive(stream);
-            text_oarchive << cache;
-            stream.close();
-            boost::filesystem::rename(tmp_file, full_cache_path, ec);
-            if (ec) {
-                boost::filesystem::copy_file(tmp_file, full_cache_path,
-                                             boost::filesystem::copy_option::overwrite_if_exists);
-                boost::filesystem::remove(tmp_file, ec);
-            }
-        }
-        catch (...) {
-            boost::filesystem::remove(tmp_file, ec);
-        }
+      return;
+  } else if (!boost::filesystem::is_directory(cache_path, ec) || ec)
+    return;
+
+  auto path_str = filesystem::get_relative_path(path, cache.project_path).string();
+  for (auto &chr : path_str) {
+    if (chr == '/' || chr == '\\')
+      chr = '_';
+  }
+  path_str += ".usages";
+
+  auto full_cache_path = cache_path / path_str;
+  auto tmp_file = boost::filesystem::temp_directory_path(ec);
+  if (ec)
+    return;
+  tmp_file /= ("jucipp" + std::to_string(get_current_process_id()) + path_str);
+
+  std::ofstream stream(tmp_file.string());
+  if (stream) {
+    try {
+      boost::archive::text_oarchive text_oarchive(stream);
+      text_oarchive << cache;
+      stream.close();
+      boost::filesystem::rename(tmp_file, full_cache_path, ec);
+      if (ec) {
+        boost::filesystem::copy_file(tmp_file, full_cache_path,
+                                     boost::filesystem::copy_option::overwrite_if_exists);
+        boost::filesystem::remove(tmp_file, ec);
+      }
+    }
+    catch (...) {
+      boost::filesystem::remove(tmp_file, ec);
     }
+  }
 }
 
 Usages::Clang::Cache
 Usages::Clang::read_cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
                           const boost::filesystem::path &path) {
-    auto path_str = filesystem::get_relative_path(path, project_path).string();
-    for (auto &chr : path_str) {
-        if (chr == '/' || chr == '\\')
-            chr = '_';
-    }
-    auto cache_path = build_path / cache_folder / (path_str + ".usages");
-
-    boost::system::error_code ec;
-    if (boost::filesystem::exists(cache_path, ec)) {
-        std::ifstream stream(cache_path.string());
-        if (stream) {
-            Cache cache;
-            boost::archive::text_iarchive text_iarchive(stream);
-            try {
-                text_iarchive >> cache;
-                return cache;
-            }
-            catch (...) {
-            }
-        }
+  auto path_str = filesystem::get_relative_path(path, project_path).string();
+  for (auto &chr : path_str) {
+    if (chr == '/' || chr == '\\')
+      chr = '_';
+  }
+  auto cache_path = build_path / cache_folder / (path_str + ".usages");
+
+  boost::system::error_code ec;
+  if (boost::filesystem::exists(cache_path, ec)) {
+    std::ifstream stream(cache_path.string());
+    if (stream) {
+      Cache cache;
+      boost::archive::text_iarchive text_iarchive(stream);
+      try {
+        text_iarchive >> cache;
+        return cache;
+      }
+      catch (...) {
+      }
     }
-    return Cache();
+  }
+  return Cache();
 }
diff --git a/src/usages_clang.h b/src/usages_clang.h
index 61f127fa..e3bf4835 100644
--- a/src/usages_clang.h
+++ b/src/usages_clang.h
@@ -15,167 +15,167 @@
 #include <unordered_set>
 
 namespace boost {
-    namespace serialization {
-        template<class Archive>
-        void serialize(Archive &ar, boost::filesystem::path &path, const unsigned int version) {
-            std::string path_str;
-            if (Archive::is_saving::value)
-                path_str = path.string();
-            ar & path_str;
-            if (Archive::is_loading::value)
-                path = path_str;
-        }
-    } // namespace serialization
+  namespace serialization {
+    template<class Archive>
+    void serialize(Archive &ar, boost::filesystem::path &path, const unsigned int version) {
+      std::string path_str;
+      if (Archive::is_saving::value)
+        path_str = path.string();
+      ar & path_str;
+      if (Archive::is_loading::value)
+        path = path_str;
+    }
+  } // namespace serialization
 } // namespace boost
 
 namespace Usages {
-    class Clang {
+  class Clang {
+  public:
+    typedef std::set<boost::filesystem::path> PathSet;
+
+    class Usages {
     public:
-        typedef std::set<boost::filesystem::path> PathSet;
-
-        class Usages {
-        public:
-            boost::filesystem::path path;
-            std::vector<std::pair<clangmm::Offset, clangmm::Offset>> offsets;
-            std::vector<std::string> lines;
-        };
-
-        class Cache {
-            friend class boost::serialization::access;
-
-            template<class Archive>
-            void serialize(Archive &ar, const unsigned int version) {
-                ar & project_path;
-                ar & build_path;
-                ar & tokens;
-                ar & cursors;
-                ar & paths_and_last_write_times;
-            }
-
-        public:
-            class Cursor {
-                friend class boost::serialization::access;
-
-                template<class Archive>
-                void serialize(Archive &ar, const unsigned int version) {
-                    ar & kind;
-                    ar & usrs;
-                }
-
-            public:
-                clangmm::Cursor::Kind kind;
-                std::unordered_set<std::string> usrs;
-
-                bool operator==(const Cursor &o);
-            };
-
-            class Token {
-                friend class boost::serialization::access;
-
-                template<class Archive>
-                void serialize(Archive &ar, const unsigned int version) {
-                    ar & spelling;
-                    ar & offsets.first.line & offsets.first.index;
-                    ar & offsets.second.line & offsets.second.index;
-                    ar & cursor_id;
-                }
-
-            public:
-                std::string spelling;
-                std::pair<clangmm::Offset, clangmm::Offset> offsets;
-                size_t cursor_id;
-            };
-
-            boost::filesystem::path project_path;
-            boost::filesystem::path build_path;
-
-            std::vector<Token> tokens;
-            std::vector<Cursor> cursors;
-            std::map<boost::filesystem::path, std::time_t> paths_and_last_write_times;
-
-            Cache() {}
-
-            Cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
-                  const boost::filesystem::path &path,
-                  std::time_t before_parse_time, clangmm::TranslationUnit *translation_unit,
-                  clangmm::Tokens *clang_tokens);
-
-            operator bool() const { return !paths_and_last_write_times.empty(); }
-
-            std::vector<std::pair<clangmm::Offset, clangmm::Offset>>
-            get_similar_token_offsets(clangmm::Cursor::Kind kind, const std::string &spelling,
-                                      const std::unordered_set<std::string> &usrs) const;
-        };
-
-    private:
-        const static boost::filesystem::path cache_folder;
-
-        static std::map<boost::filesystem::path, Cache> caches;
-        static std::mutex caches_mutex;
-
-        static std::atomic<size_t> cache_in_progress_count;
+      boost::filesystem::path path;
+      std::vector<std::pair<clangmm::Offset, clangmm::Offset>> offsets;
+      std::vector<std::string> lines;
+    };
+
+    class Cache {
+      friend class boost::serialization::access;
+
+      template<class Archive>
+      void serialize(Archive &ar, const unsigned int version) {
+        ar & project_path;
+        ar & build_path;
+        ar & tokens;
+        ar & cursors;
+        ar & paths_and_last_write_times;
+      }
 
     public:
-        static std::vector<Usages>
-        get_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
-                   const boost::filesystem::path &debug_path,
-                   const std::string &spelling, const clangmm::Cursor &cursor,
-                   const std::vector<clangmm::TranslationUnit *> &translation_units);
+      class Cursor {
+        friend class boost::serialization::access;
+
+        template<class Archive>
+        void serialize(Archive &ar, const unsigned int version) {
+          ar & kind;
+          ar & usrs;
+        }
 
-        static void cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
-                          const boost::filesystem::path &path,
-                          std::time_t before_parse_time, const PathSet &project_paths_in_use,
-                          clangmm::TranslationUnit *translation_unit, clangmm::Tokens *tokens);
+      public:
+        clangmm::Cursor::Kind kind;
+        std::unordered_set<std::string> usrs;
 
-        static void erase_unused_caches(const PathSet &project_paths_in_use);
+        bool operator==(const Cursor &o);
+      };
 
-        static void erase_cache(const boost::filesystem::path &path);
+      class Token {
+        friend class boost::serialization::access;
 
-        static void erase_all_caches_for_project(const boost::filesystem::path &project_path,
-                                                 const boost::filesystem::path &build_path);
+        template<class Archive>
+        void serialize(Archive &ar, const unsigned int version) {
+          ar & spelling;
+          ar & offsets.first.line & offsets.first.index;
+          ar & offsets.second.line & offsets.second.index;
+          ar & cursor_id;
+        }
 
-        static void cache_in_progress();
+      public:
+        std::string spelling;
+        std::pair<clangmm::Offset, clangmm::Offset> offsets;
+        size_t cursor_id;
+      };
 
-    private:
-        static void add_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
-                               const boost::filesystem::path &path_,
-                               std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
-                               clangmm::Cursor cursor,
-                               clangmm::TranslationUnit *translation_unit, bool store_in_cache);
+      boost::filesystem::path project_path;
+      boost::filesystem::path build_path;
 
-        static bool
-        add_usages_from_cache(const boost::filesystem::path &path, std::vector<Usages> &usages, PathSet &visited,
-                              const std::string &spelling, const clangmm::Cursor &cursor, const Cache &cache);
+      std::vector<Token> tokens;
+      std::vector<Cursor> cursors;
+      std::map<boost::filesystem::path, std::time_t> paths_and_last_write_times;
 
-        static void
-        add_usages_from_includes(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
-                                 std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
-                                 const clangmm::Cursor &cursor,
-                                 clangmm::TranslationUnit *translation_unit, bool store_in_cache);
+      Cache() {}
 
-        static PathSet find_paths(const boost::filesystem::path &project_path,
-                                  const boost::filesystem::path &build_path, const boost::filesystem::path &debug_path);
+      Cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+            const boost::filesystem::path &path,
+            std::time_t before_parse_time, clangmm::TranslationUnit *translation_unit,
+            clangmm::Tokens *clang_tokens);
 
-        static bool is_header(const boost::filesystem::path &path);
+      operator bool() const { return !paths_and_last_write_times.empty(); }
 
-        static bool is_source(const boost::filesystem::path &path);
+      std::vector<std::pair<clangmm::Offset, clangmm::Offset>>
+      get_similar_token_offsets(clangmm::Cursor::Kind kind, const std::string &spelling,
+                                const std::unordered_set<std::string> &usrs) const;
+    };
 
-        static std::pair<std::map<boost::filesystem::path, PathSet>, PathSet>
-        parse_paths(const std::string &spelling, const PathSet &paths);
+  private:
+    const static boost::filesystem::path cache_folder;
 
-        /// Recursively find and return all the include paths of path
-        static PathSet get_all_includes(const boost::filesystem::path &path,
-                                        const std::map<boost::filesystem::path, PathSet> &paths_includes);
+    static std::map<boost::filesystem::path, Cache> caches;
+    static std::mutex caches_mutex;
 
-        /// Based on cursor paths, paths_includes and paths_with_spelling return potential paths that might contain the sought after symbol
-        static std::pair<Clang::PathSet, Clang::PathSet>
-        find_potential_paths(const PathSet &paths, const boost::filesystem::path &project_path,
-                             const std::map<boost::filesystem::path, PathSet> &paths_includes,
-                             const PathSet &paths_with_spelling);
+    static std::atomic<size_t> cache_in_progress_count;
 
-        static void write_cache(const boost::filesystem::path &path, const Cache &cache);
+  public:
+    static std::vector<Usages>
+    get_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+               const boost::filesystem::path &debug_path,
+               const std::string &spelling, const clangmm::Cursor &cursor,
+               const std::vector<clangmm::TranslationUnit *> &translation_units);
 
-        static Cache read_cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
-                                const boost::filesystem::path &path);
-    };
+    static void cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                      const boost::filesystem::path &path,
+                      std::time_t before_parse_time, const PathSet &project_paths_in_use,
+                      clangmm::TranslationUnit *translation_unit, clangmm::Tokens *tokens);
+
+    static void erase_unused_caches(const PathSet &project_paths_in_use);
+
+    static void erase_cache(const boost::filesystem::path &path);
+
+    static void erase_all_caches_for_project(const boost::filesystem::path &project_path,
+                                             const boost::filesystem::path &build_path);
+
+    static void cache_in_progress();
+
+  private:
+    static void add_usages(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                           const boost::filesystem::path &path_,
+                           std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
+                           clangmm::Cursor cursor,
+                           clangmm::TranslationUnit *translation_unit, bool store_in_cache);
+
+    static bool
+    add_usages_from_cache(const boost::filesystem::path &path, std::vector<Usages> &usages, PathSet &visited,
+                          const std::string &spelling, const clangmm::Cursor &cursor, const Cache &cache);
+
+    static void
+    add_usages_from_includes(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                             std::vector<Usages> &usages, PathSet &visited, const std::string &spelling,
+                             const clangmm::Cursor &cursor,
+                             clangmm::TranslationUnit *translation_unit, bool store_in_cache);
+
+    static PathSet find_paths(const boost::filesystem::path &project_path,
+                              const boost::filesystem::path &build_path, const boost::filesystem::path &debug_path);
+
+    static bool is_header(const boost::filesystem::path &path);
+
+    static bool is_source(const boost::filesystem::path &path);
+
+    static std::pair<std::map<boost::filesystem::path, PathSet>, PathSet>
+    parse_paths(const std::string &spelling, const PathSet &paths);
+
+    /// Recursively find and return all the include paths of path
+    static PathSet get_all_includes(const boost::filesystem::path &path,
+                                    const std::map<boost::filesystem::path, PathSet> &paths_includes);
+
+    /// Based on cursor paths, paths_includes and paths_with_spelling return potential paths that might contain the sought after symbol
+    static std::pair<Clang::PathSet, Clang::PathSet>
+    find_potential_paths(const PathSet &paths, const boost::filesystem::path &project_path,
+                         const std::map<boost::filesystem::path, PathSet> &paths_includes,
+                         const PathSet &paths_with_spelling);
+
+    static void write_cache(const boost::filesystem::path &path, const Cache &cache);
+
+    static Cache read_cache(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path,
+                            const boost::filesystem::path &path);
+  };
 } // namespace Usages
diff --git a/src/window.cc b/src/window.cc
index 9371207a..04eb6bbb 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -12,1776 +12,1776 @@
 #include "terminal.h"
 
 Window::Window() {
-    Gsv::init();
+  Gsv::init();
 
-    set_title("juCi++");
-    set_events(Gdk::POINTER_MOTION_MASK | Gdk::FOCUS_CHANGE_MASK | Gdk::SCROLL_MASK | Gdk::LEAVE_NOTIFY_MASK);
+  set_title("juCi++");
+  set_events(Gdk::POINTER_MOTION_MASK | Gdk::FOCUS_CHANGE_MASK | Gdk::SCROLL_MASK | Gdk::LEAVE_NOTIFY_MASK);
 
-    auto provider = Gtk::CssProvider::create();
-    auto screen = get_screen();
-    std::string border_radius_style;
-    if (screen->get_rgba_visual())
-        border_radius_style = "border-radius: 5px; ";
+  auto provider = Gtk::CssProvider::create();
+  auto screen = get_screen();
+  std::string border_radius_style;
+  if (screen->get_rgba_visual())
+    border_radius_style = "border-radius: 5px; ";
 #if GTK_VERSION_GE(3, 20)
-    std::string notebook_style(".juci_notebook tab {border-radius: 5px 5px 0 0; padding: 0 4px; margin: 0;}");
+  std::string notebook_style(".juci_notebook tab {border-radius: 5px 5px 0 0; padding: 0 4px; margin: 0;}");
 #else
-    std::string notebook_style(".juci_notebook {-GtkNotebook-tab-overlap: 0px;} .juci_notebook tab {border-radius: 5px 5px 0 0; padding: 4px 4px;}");
+  std::string notebook_style(".juci_notebook {-GtkNotebook-tab-overlap: 0px;} .juci_notebook tab {border-radius: 5px 5px 0 0; padding: 4px 4px;}");
 #endif
-    provider->load_from_data(R"(
+  provider->load_from_data(R"(
     .juci_directories *:selected {border-left-color: inherit; color: inherit; background-color: rgba(128, 128, 128 , 0.2); background-image: inherit;}
     )" + notebook_style + R"(
     .juci_info {border-radius: 5px;}
     .juci_tooltip_window {background-color: transparent;}
     .juci_tooltip_box {)" + border_radius_style + R"(padding: 3px;}
   )");
-    get_style_context()->add_provider_for_screen(screen, provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+  get_style_context()->add_provider_for_screen(screen, provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 
-    set_menu_actions();
-    configure();
-    Menu::get().toggle_menu_items();
+  set_menu_actions();
+  configure();
+  Menu::get().toggle_menu_items();
 
-    Menu::get().right_click_line_menu->attach_to_widget(*this);
-    Menu::get().right_click_selected_menu->attach_to_widget(*this);
+  Menu::get().right_click_line_menu->attach_to_widget(*this);
+  Menu::get().right_click_selected_menu->attach_to_widget(*this);
 
-    EntryBox::get().signal_hide().connect([]() {
-        if (auto view = Notebook::get().get_current_view())
-            view->grab_focus();
-    });
+  EntryBox::get().signal_hide().connect([]() {
+    if (auto view = Notebook::get().get_current_view())
+      view->grab_focus();
+  });
 
-    Notebook::get().on_change_page = [this](Source::View *view) {
-        if (search_entry_shown && EntryBox::get().labels.size() > 0) {
-            view->update_search_occurrences = [](int number) {
-                EntryBox::get().labels.begin()->update(0, std::to_string(number));
-            };
-            view->search_highlight(last_search, case_sensitive_search, regex_search);
-        }
+  Notebook::get().on_change_page = [this](Source::View *view) {
+    if (search_entry_shown && EntryBox::get().labels.size() > 0) {
+      view->update_search_occurrences = [](int number) {
+        EntryBox::get().labels.begin()->update(0, std::to_string(number));
+      };
+      view->search_highlight(last_search, case_sensitive_search, regex_search);
+    }
 
-        Menu::get().toggle_menu_items();
+    Menu::get().toggle_menu_items();
 
-        Directories::get().select(view->file_path);
+    Directories::get().select(view->file_path);
 
-        if (view->full_reparse_needed)
-            view->full_reparse();
-        else if (view->soft_reparse_needed)
-            view->soft_reparse();
+    if (view->full_reparse_needed)
+      view->full_reparse();
+    else if (view->soft_reparse_needed)
+      view->soft_reparse();
 
-        Notebook::get().update_status(view);
+    Notebook::get().update_status(view);
 
 #ifdef JUCI_ENABLE_DEBUG
-        if(Project::debugging)
-          Project::debug_update_stop();
+    if(Project::debugging)
+      Project::debug_update_stop();
 #endif
-    };
-    Notebook::get().on_close_page = [](Source::View *view) {
+  };
+  Notebook::get().on_close_page = [](Source::View *view) {
 #ifdef JUCI_ENABLE_DEBUG
-        if(Project::current && Project::debugging) {
-          auto iter=view->get_buffer()->begin();
-          while(view->get_source_buffer()->forward_iter_to_source_mark(iter, "debug_breakpoint") ||
-             view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size()) {
-            auto end_iter=view->get_iter_at_line_end(iter.get_line());
-            view->get_source_buffer()->remove_source_marks(iter, end_iter, "debug_breakpoint");
-            Project::current->debug_remove_breakpoint(view->file_path, iter.get_line()+1, view->get_buffer()->get_line_count()+1);
-          }
-        }
+    if(Project::current && Project::debugging) {
+      auto iter=view->get_buffer()->begin();
+      while(view->get_source_buffer()->forward_iter_to_source_mark(iter, "debug_breakpoint") ||
+         view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size()) {
+        auto end_iter=view->get_iter_at_line_end(iter.get_line());
+        view->get_source_buffer()->remove_source_marks(iter, end_iter, "debug_breakpoint");
+        Project::current->debug_remove_breakpoint(view->file_path, iter.get_line()+1, view->get_buffer()->get_line_count()+1);
+      }
+    }
 #endif
-        EntryBox::get().hide();
-        if (auto view = Notebook::get().get_current_view())
-            Notebook::get().update_status(view);
-        else {
-            Notebook::get().clear_status();
-
-            Menu::get().toggle_menu_items();
-        }
-    };
-
-    signal_focus_out_event().connect([](GdkEventFocus *event) {
-        if (auto view = Notebook::get().get_current_view()) {
-            view->hide_tooltips();
-            view->hide_dialogs();
-        }
-        return false;
-    });
+    EntryBox::get().hide();
+    if (auto view = Notebook::get().get_current_view())
+      Notebook::get().update_status(view);
+    else {
+      Notebook::get().clear_status();
 
-    signal_hide().connect([] {
-        while (!Source::View::non_deleted_views.empty()) {
-            while (Gtk::Main::events_pending())
-                Gtk::Main::iteration(false);
-        }
-        // TODO 2022 (after Debian Stretch LTS has ended, see issue #354): remove:
-        Project::current = nullptr;
-    });
+      Menu::get().toggle_menu_items();
+    }
+  };
 
-    Gtk::Settings::get_default()->connect_property_changed("gtk-theme-name", [] {
-        Directories::get().update();
-        if (auto view = Notebook::get().get_current_view())
-            Notebook::get().update_status(view);
-    });
+  signal_focus_out_event().connect([](GdkEventFocus *event) {
+    if (auto view = Notebook::get().get_current_view()) {
+      view->hide_tooltips();
+      view->hide_dialogs();
+    }
+    return false;
+  });
 
-    about.signal_response().connect([this](int d) {
-        about.hide();
-    });
+  signal_hide().connect([] {
+    while (!Source::View::non_deleted_views.empty()) {
+      while (Gtk::Main::events_pending())
+        Gtk::Main::iteration(false);
+    }
+    // TODO 2022 (after Debian Stretch LTS has ended, see issue #354): remove:
+    Project::current = nullptr;
+  });
 
-    about.set_logo_icon_name("juci");
-    about.set_version(Config::get().window.version);
-    about.set_authors({"(in order of appearance)",
-                       "Ted Johan Kristoffersen",
-                       "Jørgen Lien Sellæg",
-                       "Geir Morten Larsen",
-                       "Ole Christian Eidheim"});
-    about.set_name("About juCi++");
-    about.set_program_name("juCi++");
-    about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy");
-    about.set_license_type(Gtk::License::LICENSE_MIT_X11);
-    about.set_transient_for(*this);
+  Gtk::Settings::get_default()->connect_property_changed("gtk-theme-name", [] {
+    Directories::get().update();
+    if (auto view = Notebook::get().get_current_view())
+      Notebook::get().update_status(view);
+  });
+
+  about.signal_response().connect([this](int d) {
+    about.hide();
+  });
+
+  about.set_logo_icon_name("juci");
+  about.set_version(Config::get().window.version);
+  about.set_authors({"(in order of appearance)",
+                     "Ted Johan Kristoffersen",
+                     "Jørgen Lien Sellæg",
+                     "Geir Morten Larsen",
+                     "Ole Christian Eidheim"});
+  about.set_name("About juCi++");
+  about.set_program_name("juCi++");
+  about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy");
+  about.set_license_type(Gtk::License::LICENSE_MIT_X11);
+  about.set_transient_for(*this);
 } // Window constructor
 
 void Window::configure() {
-    Config::get().load();
-    auto screen = get_screen();
-    if (css_provider_theme)
-        Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_theme);
-    if (Config::get().window.theme_name.empty()) {
-        css_provider_theme = Gtk::CssProvider::create();
-        Gtk::Settings::get_default()->property_gtk_application_prefer_dark_theme() = (
-                Config::get().window.theme_variant == "dark");
-    } else
-        css_provider_theme = Gtk::CssProvider::get_named(Config::get().window.theme_name,
-                                                         Config::get().window.theme_variant);
-    //TODO: add check if theme exists, or else write error to terminal
-    Gtk::StyleContext::add_provider_for_screen(screen, css_provider_theme, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
-
-    auto style_scheme_manager = Source::StyleSchemeManager::get_default();
-    if (css_provider_tooltips)
-        Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_tooltips);
-    else
-        css_provider_tooltips = Gtk::CssProvider::create();
-    Glib::RefPtr<Gsv::Style> style;
-    if (Config::get().source.style.size() > 0) {
-        auto scheme = style_scheme_manager->get_scheme(Config::get().source.style);
-        if (scheme)
-            style = scheme->get_style("def:note");
-        else {
-            Terminal::get().print("Error: Could not find gtksourceview style: " + Config::get().source.style + '\n',
-                                  true);
-        }
+  Config::get().load();
+  auto screen = get_screen();
+  if (css_provider_theme)
+    Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_theme);
+  if (Config::get().window.theme_name.empty()) {
+    css_provider_theme = Gtk::CssProvider::create();
+    Gtk::Settings::get_default()->property_gtk_application_prefer_dark_theme() = (
+        Config::get().window.theme_variant == "dark");
+  } else
+    css_provider_theme = Gtk::CssProvider::get_named(Config::get().window.theme_name,
+                                                     Config::get().window.theme_variant);
+  //TODO: add check if theme exists, or else write error to terminal
+  Gtk::StyleContext::add_provider_for_screen(screen, css_provider_theme, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
+
+  auto style_scheme_manager = Source::StyleSchemeManager::get_default();
+  if (css_provider_tooltips)
+    Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_tooltips);
+  else
+    css_provider_tooltips = Gtk::CssProvider::create();
+  Glib::RefPtr<Gsv::Style> style;
+  if (Config::get().source.style.size() > 0) {
+    auto scheme = style_scheme_manager->get_scheme(Config::get().source.style);
+    if (scheme)
+      style = scheme->get_style("def:note");
+    else {
+      Terminal::get().print("Error: Could not find gtksourceview style: " + Config::get().source.style + '\n',
+                            true);
     }
-    auto foreground_value = style && style->property_foreground_set() ? style->property_foreground().get_value()
-                                                                      : get_style_context()->get_color().to_string();
-    auto background_value = style && style->property_background_set() ? style->property_background().get_value()
-                                                                      : get_style_context()->get_background_color().to_string();
+  }
+  auto foreground_value = style && style->property_foreground_set() ? style->property_foreground().get_value()
+                                                                    : get_style_context()->get_color().to_string();
+  auto background_value = style && style->property_background_set() ? style->property_background().get_value()
+                                                                    : get_style_context()->get_background_color().to_string();
 #if GTK_VERSION_GE(3, 20)
-    css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: " + background_value + ";}"
-                                                                                                       ".juci_tooltip_text_view text {color: " +
-                                          foreground_value + ";background-color: " + background_value + ";}");
+  css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: " + background_value + ";}"
+                                                                                                     ".juci_tooltip_text_view text {color: " +
+                                        foreground_value + ";background-color: " + background_value + ";}");
 #else
-    css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: "+background_value+";}"
-                                          ".juci_tooltip_text_view *:not(:selected) {color: "+foreground_value+";background-color: "+background_value+";}");
+  css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: "+background_value+";}"
+                                        ".juci_tooltip_text_view *:not(:selected) {color: "+foreground_value+";background-color: "+background_value+";}");
 #endif
-    get_style_context()->add_provider_for_screen(screen, css_provider_tooltips,
-                                                 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-
-    Menu::get().set_keys();
-    Terminal::get().configure();
-    Directories::get().update();
-    if (auto view = Notebook::get().get_current_view())
-        Notebook::get().update_status(view);
+  get_style_context()->add_provider_for_screen(screen, css_provider_tooltips,
+                                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+  Menu::get().set_keys();
+  Terminal::get().configure();
+  Directories::get().update();
+  if (auto view = Notebook::get().get_current_view())
+    Notebook::get().update_status(view);
 }
 
 void Window::set_menu_actions() {
-    auto &menu = Menu::get();
-
-    menu.add_action("about", [this]() {
-        about.show();
-        about.present();
-    });
-    menu.add_action("preferences", []() {
-        Notebook::get().open(Config::get().home_juci_path / "config" / "config.json");
-    });
-    menu.add_action("quit", [this]() {
-        close();
-    });
-
-    menu.add_action("file_new_file", []() {
-        boost::filesystem::path path = Dialog::new_file(Notebook::get().get_current_folder());
-        if (path != "") {
-            if (boost::filesystem::exists(path)) {
-                Terminal::get().print("Error: " + path.string() + " already exists.\n", true);
-            } else {
-                if (filesystem::write(path)) {
-                    if (Directories::get().path != "")
-                        Directories::get().update();
-                    Notebook::get().open(path);
-                    if (Directories::get().path != "")
-                        Directories::get().on_save_file(path);
-                    Terminal::get().print("New file " + path.string() + " created.\n");
-                } else
-                    Terminal::get().print("Error: could not create new file " + path.string() + ".\n", true);
-            }
-        }
-    });
-    menu.add_action("file_new_folder", []() {
-        auto time_now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
-        boost::filesystem::path path = Dialog::new_folder(Notebook::get().get_current_folder());
-        if (path != "" && boost::filesystem::exists(path)) {
-            boost::system::error_code ec;
-            auto last_write_time = boost::filesystem::last_write_time(path, ec);
-            if (!ec && last_write_time >= time_now) {
-                if (Directories::get().path != "")
-                    Directories::get().update();
-                Terminal::get().print("New folder " + path.string() + " created.\n");
-            } else
-                Terminal::get().print("Error: " + path.string() + " already exists.\n", true);
-            Directories::get().select(path);
-        }
-    });
-    menu.add_action("file_new_project_c", []() {
-        boost::filesystem::path project_path = Dialog::new_folder(Notebook::get().get_current_folder());
-        if (project_path != "") {
-            auto project_name = project_path.filename().string();
-            for (size_t c = 0; c < project_name.size(); c++) {
-                if (project_name[c] == ' ')
-                    project_name[c] = '_';
-            }
-            auto cmakelists_path = project_path;
-            cmakelists_path /= "CMakeLists.txt";
-            auto c_main_path = project_path;
-            c_main_path /= "main.c";
-            if (boost::filesystem::exists(cmakelists_path)) {
-                Terminal::get().print("Error: " + cmakelists_path.string() + " already exists.\n", true);
-                return;
-            }
-            if (boost::filesystem::exists(c_main_path)) {
-                Terminal::get().print("Error: " + c_main_path.string() + " already exists.\n", true);
-                return;
-            }
-            std::string cmakelists = "cmake_minimum_required(VERSION 2.8)\n\nproject(" + project_name +
-                                     ")\n\nset(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -std=c11 -Wall -Wextra\")\n\nadd_executable(" +
-                                     project_name + " main.c)\n";
-            std::string c_main = "#include <stdio.h>\n\nint main() {\n  printf(\"Hello World!\\n\");\n}\n";
-            if (filesystem::write(cmakelists_path, cmakelists) && filesystem::write(c_main_path, c_main)) {
-                Directories::get().open(project_path);
-                Notebook::get().open(c_main_path);
-                Directories::get().update();
-                Terminal::get().print("C project " + project_name + " created.\n");
-            } else
-                Terminal::get().print("Error: Could not create project " + project_path.string() + "\n", true);
-        }
-    });
-    menu.add_action("file_new_project_cpp", []() {
-        boost::filesystem::path project_path = Dialog::new_folder(Notebook::get().get_current_folder());
-        if (project_path != "") {
-            auto project_name = project_path.filename().string();
-            for (size_t c = 0; c < project_name.size(); c++) {
-                if (project_name[c] == ' ')
-                    project_name[c] = '_';
-            }
-            auto cmakelists_path = project_path;
-            cmakelists_path /= "CMakeLists.txt";
-            auto cpp_main_path = project_path;
-            cpp_main_path /= "main.cpp";
-            if (boost::filesystem::exists(cmakelists_path)) {
-                Terminal::get().print("Error: " + cmakelists_path.string() + " already exists.\n", true);
-                return;
-            }
-            if (boost::filesystem::exists(cpp_main_path)) {
-                Terminal::get().print("Error: " + cpp_main_path.string() + " already exists.\n", true);
-                return;
-            }
-            std::string cmakelists = "cmake_minimum_required(VERSION 2.8)\n\nproject(" + project_name +
-                                     ")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra\")\n\nadd_executable(" +
-                                     project_name + " main.cpp)\n";
-            std::string cpp_main = "#include <iostream>\n\nint main() {\n  std::cout << \"Hello World!\\n\";\n}\n";
-            if (filesystem::write(cmakelists_path, cmakelists) && filesystem::write(cpp_main_path, cpp_main)) {
-                Directories::get().open(project_path);
-                Notebook::get().open(cpp_main_path);
-                Directories::get().update();
-                Terminal::get().print("C++ project " + project_name + " created.\n");
-            } else
-                Terminal::get().print("Error: Could not create project " + project_path.string() + "\n", true);
-        }
-    });
-
-    menu.add_action("file_open_file", []() {
-        auto folder_path = Notebook::get().get_current_folder();
-        if (auto view = Notebook::get().get_current_view()) {
-            if (!Directories::get().path.empty() && !filesystem::file_in_path(view->file_path, Directories::get().path))
-                folder_path = view->file_path.parent_path();
-        }
-        auto path = Dialog::open_file(folder_path);
-        if (path != "")
-            Notebook::get().open(path);
-    });
-    menu.add_action("file_open_folder", []() {
-        auto path = Dialog::open_folder(Notebook::get().get_current_folder());
-        if (path != "" && boost::filesystem::exists(path))
-            Directories::get().open(path);
-    });
-
-    menu.add_action("file_reload_file", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (boost::filesystem::exists(view->file_path)) {
-                std::ifstream can_read(view->file_path.string());
-                if (!can_read) {
-                    Terminal::get().print("Error: could not read " + view->file_path.string() + "\n", true);
-                    return;
-                }
-                can_read.close();
-            } else {
-                Terminal::get().print("Error: " + view->file_path.string() + " does not exist\n", true);
-                return;
-            }
+  auto &menu = Menu::get();
+
+  menu.add_action("about", [this]() {
+    about.show();
+    about.present();
+  });
+  menu.add_action("preferences", []() {
+    Notebook::get().open(Config::get().home_juci_path / "config" / "config.json");
+  });
+  menu.add_action("quit", [this]() {
+    close();
+  });
+
+  menu.add_action("file_new_file", []() {
+    boost::filesystem::path path = Dialog::new_file(Notebook::get().get_current_folder());
+    if (path != "") {
+      if (boost::filesystem::exists(path)) {
+        Terminal::get().print("Error: " + path.string() + " already exists.\n", true);
+      } else {
+        if (filesystem::write(path)) {
+          if (Directories::get().path != "")
+            Directories::get().update();
+          Notebook::get().open(path);
+          if (Directories::get().path != "")
+            Directories::get().on_save_file(path);
+          Terminal::get().print("New file " + path.string() + " created.\n");
+        } else
+          Terminal::get().print("Error: could not create new file " + path.string() + ".\n", true);
+      }
+    }
+  });
+  menu.add_action("file_new_folder", []() {
+    auto time_now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+    boost::filesystem::path path = Dialog::new_folder(Notebook::get().get_current_folder());
+    if (path != "" && boost::filesystem::exists(path)) {
+      boost::system::error_code ec;
+      auto last_write_time = boost::filesystem::last_write_time(path, ec);
+      if (!ec && last_write_time >= time_now) {
+        if (Directories::get().path != "")
+          Directories::get().update();
+        Terminal::get().print("New folder " + path.string() + " created.\n");
+      } else
+        Terminal::get().print("Error: " + path.string() + " already exists.\n", true);
+      Directories::get().select(path);
+    }
+  });
+  menu.add_action("file_new_project_c", []() {
+    boost::filesystem::path project_path = Dialog::new_folder(Notebook::get().get_current_folder());
+    if (project_path != "") {
+      auto project_name = project_path.filename().string();
+      for (size_t c = 0; c < project_name.size(); c++) {
+        if (project_name[c] == ' ')
+          project_name[c] = '_';
+      }
+      auto cmakelists_path = project_path;
+      cmakelists_path /= "CMakeLists.txt";
+      auto c_main_path = project_path;
+      c_main_path /= "main.c";
+      if (boost::filesystem::exists(cmakelists_path)) {
+        Terminal::get().print("Error: " + cmakelists_path.string() + " already exists.\n", true);
+        return;
+      }
+      if (boost::filesystem::exists(c_main_path)) {
+        Terminal::get().print("Error: " + c_main_path.string() + " already exists.\n", true);
+        return;
+      }
+      std::string cmakelists = "cmake_minimum_required(VERSION 2.8)\n\nproject(" + project_name +
+                               ")\n\nset(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -std=c11 -Wall -Wextra\")\n\nadd_executable(" +
+                               project_name + " main.c)\n";
+      std::string c_main = "#include <stdio.h>\n\nint main() {\n  printf(\"Hello World!\\n\");\n}\n";
+      if (filesystem::write(cmakelists_path, cmakelists) && filesystem::write(c_main_path, c_main)) {
+        Directories::get().open(project_path);
+        Notebook::get().open(c_main_path);
+        Directories::get().update();
+        Terminal::get().print("C project " + project_name + " created.\n");
+      } else
+        Terminal::get().print("Error: Could not create project " + project_path.string() + "\n", true);
+    }
+  });
+  menu.add_action("file_new_project_cpp", []() {
+    boost::filesystem::path project_path = Dialog::new_folder(Notebook::get().get_current_folder());
+    if (project_path != "") {
+      auto project_name = project_path.filename().string();
+      for (size_t c = 0; c < project_name.size(); c++) {
+        if (project_name[c] == ' ')
+          project_name[c] = '_';
+      }
+      auto cmakelists_path = project_path;
+      cmakelists_path /= "CMakeLists.txt";
+      auto cpp_main_path = project_path;
+      cpp_main_path /= "main.cpp";
+      if (boost::filesystem::exists(cmakelists_path)) {
+        Terminal::get().print("Error: " + cmakelists_path.string() + " already exists.\n", true);
+        return;
+      }
+      if (boost::filesystem::exists(cpp_main_path)) {
+        Terminal::get().print("Error: " + cpp_main_path.string() + " already exists.\n", true);
+        return;
+      }
+      std::string cmakelists = "cmake_minimum_required(VERSION 2.8)\n\nproject(" + project_name +
+                               ")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra\")\n\nadd_executable(" +
+                               project_name + " main.cpp)\n";
+      std::string cpp_main = "#include <iostream>\n\nint main() {\n  std::cout << \"Hello World!\\n\";\n}\n";
+      if (filesystem::write(cmakelists_path, cmakelists) && filesystem::write(cpp_main_path, cpp_main)) {
+        Directories::get().open(project_path);
+        Notebook::get().open(cpp_main_path);
+        Directories::get().update();
+        Terminal::get().print("C++ project " + project_name + " created.\n");
+      } else
+        Terminal::get().print("Error: Could not create project " + project_path.string() + "\n", true);
+    }
+  });
 
-            if (view->load())
-                view->full_reparse();
+  menu.add_action("file_open_file", []() {
+    auto folder_path = Notebook::get().get_current_folder();
+    if (auto view = Notebook::get().get_current_view()) {
+      if (!Directories::get().path.empty() && !filesystem::file_in_path(view->file_path, Directories::get().path))
+        folder_path = view->file_path.parent_path();
+    }
+    auto path = Dialog::open_file(folder_path);
+    if (path != "")
+      Notebook::get().open(path);
+  });
+  menu.add_action("file_open_folder", []() {
+    auto path = Dialog::open_folder(Notebook::get().get_current_folder());
+    if (path != "" && boost::filesystem::exists(path))
+      Directories::get().open(path);
+  });
+
+  menu.add_action("file_reload_file", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (boost::filesystem::exists(view->file_path)) {
+        std::ifstream can_read(view->file_path.string());
+        if (!can_read) {
+          Terminal::get().print("Error: could not read " + view->file_path.string() + "\n", true);
+          return;
         }
-    });
+        can_read.close();
+      } else {
+        Terminal::get().print("Error: " + view->file_path.string() + " does not exist\n", true);
+        return;
+      }
 
-    menu.add_action("file_save", [this]() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (Notebook::get().save_current()) {
-                if (view->file_path == Config::get().home_juci_path / "config" / "config.json") {
-                    configure();
-                    for (size_t c = 0; c < Notebook::get().size(); c++) {
-                        Notebook::get().get_view(c)->configure();
-                        Notebook::get().configure(c);
-                    }
-                }
-            }
-        }
-    });
-    menu.add_action("file_save_as", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            auto path = Dialog::save_file_as(view->file_path);
-            if (path != "") {
-                std::ofstream file(path, std::ofstream::binary);
-                if (file) {
-                    file << view->get_buffer()->get_text().raw();
-                    file.close();
-                    if (Directories::get().path != "")
-                        Directories::get().update();
-                    Notebook::get().open(path);
-                    Terminal::get().print(
-                            "File saved to: " + Notebook::get().get_current_view()->file_path.string() + "\n");
-                } else
-                    Terminal::get().print("Error saving file\n", true);
-            }
-        }
-    });
+      if (view->load())
+        view->full_reparse();
+    }
+  });
 
-    menu.add_action("file_print", [this]() {
-        if (auto view = Notebook::get().get_current_view()) {
-            auto print_operation = Gtk::PrintOperation::create();
-            auto print_compositor = Gsv::PrintCompositor::create(*view);
-
-            print_operation->set_job_name(view->file_path.filename().string());
-            print_compositor->set_wrap_mode(Gtk::WrapMode::WRAP_WORD_CHAR);
-
-            print_operation->signal_begin_print().connect(
-                    [print_operation, print_compositor](const Glib::RefPtr<Gtk::PrintContext> &print_context) {
-                        while (!print_compositor->paginate(print_context));
-                        print_operation->set_n_pages(print_compositor->get_n_pages());
-                    });
-            print_operation->signal_draw_page().connect(
-                    [print_compositor](const Glib::RefPtr<Gtk::PrintContext> &print_context, int page_nr) {
-                        print_compositor->draw_page(print_context, page_nr);
-                    });
-
-            print_operation->run(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG, *this);
+  menu.add_action("file_save", [this]() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (Notebook::get().save_current()) {
+        if (view->file_path == Config::get().home_juci_path / "config" / "config.json") {
+          configure();
+          for (size_t c = 0; c < Notebook::get().size(); c++) {
+            Notebook::get().get_view(c)->configure();
+            Notebook::get().configure(c);
+          }
         }
-    });
+      }
+    }
+  });
+  menu.add_action("file_save_as", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      auto path = Dialog::save_file_as(view->file_path);
+      if (path != "") {
+        std::ofstream file(path, std::ofstream::binary);
+        if (file) {
+          file << view->get_buffer()->get_text().raw();
+          file.close();
+          if (Directories::get().path != "")
+            Directories::get().update();
+          Notebook::get().open(path);
+          Terminal::get().print(
+              "File saved to: " + Notebook::get().get_current_view()->file_path.string() + "\n");
+        } else
+          Terminal::get().print("Error saving file\n", true);
+      }
+    }
+  });
 
-    menu.add_action("edit_undo", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            auto undo_manager = view->get_source_buffer()->get_undo_manager();
-            if (undo_manager->can_undo()) {
-                view->disable_spellcheck = true;
-                undo_manager->undo();
-                view->disable_spellcheck = false;
-                view->scroll_to(view->get_buffer()->get_insert());
-            }
-        }
-    });
-    menu.add_action("edit_redo", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            auto undo_manager = view->get_source_buffer()->get_undo_manager();
-            if (undo_manager->can_redo()) {
-                view->disable_spellcheck = true;
-                undo_manager->redo();
-                view->disable_spellcheck = false;
-                view->scroll_to(view->get_buffer()->get_insert());
-            }
-        }
-    });
+  menu.add_action("file_print", [this]() {
+    if (auto view = Notebook::get().get_current_view()) {
+      auto print_operation = Gtk::PrintOperation::create();
+      auto print_compositor = Gsv::PrintCompositor::create(*view);
+
+      print_operation->set_job_name(view->file_path.filename().string());
+      print_compositor->set_wrap_mode(Gtk::WrapMode::WRAP_WORD_CHAR);
+
+      print_operation->signal_begin_print().connect(
+          [print_operation, print_compositor](const Glib::RefPtr<Gtk::PrintContext> &print_context) {
+            while (!print_compositor->paginate(print_context));
+            print_operation->set_n_pages(print_compositor->get_n_pages());
+          });
+      print_operation->signal_draw_page().connect(
+          [print_compositor](const Glib::RefPtr<Gtk::PrintContext> &print_context, int page_nr) {
+            print_compositor->draw_page(print_context, page_nr);
+          });
+
+      print_operation->run(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG, *this);
+    }
+  });
 
-    menu.add_action("edit_cut", [this]() {
-        // Return if a shown tooltip has selected text
-        for (auto tooltip: Tooltips::shown_tooltips) {
-            auto buffer = tooltip->text_buffer;
-            if (buffer && buffer->get_has_selection())
-                return;
-        }
+  menu.add_action("edit_undo", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      auto undo_manager = view->get_source_buffer()->get_undo_manager();
+      if (undo_manager->can_undo()) {
+        view->disable_spellcheck = true;
+        undo_manager->undo();
+        view->disable_spellcheck = false;
+        view->scroll_to(view->get_buffer()->get_insert());
+      }
+    }
+  });
+  menu.add_action("edit_redo", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      auto undo_manager = view->get_source_buffer()->get_undo_manager();
+      if (undo_manager->can_redo()) {
+        view->disable_spellcheck = true;
+        undo_manager->redo();
+        view->disable_spellcheck = false;
+        view->scroll_to(view->get_buffer()->get_insert());
+      }
+    }
+  });
 
-        auto widget = get_focus();
-        if (auto entry = dynamic_cast<Gtk::Entry *>(widget))
-            entry->cut_clipboard();
-        else if (auto view = dynamic_cast<Gtk::TextView *>(widget)) {
-            if (!view->get_editable())
-                return;
-            auto source_view = dynamic_cast<Source::View *>(view);
-            if (source_view)
-                source_view->disable_spellcheck = true;
-            if (!view->get_buffer()->get_has_selection()) {
-                auto start = view->get_buffer()->get_iter_at_line(
-                        view->get_buffer()->get_insert()->get_iter().get_line());
-                auto end = start;
-                if (!end.ends_line())
-                    end.forward_to_line_end();
-                end.forward_char();
-                if (!end.starts_line()) // In case of \r\n
-                    end.forward_char();
-                Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
-                view->get_buffer()->erase(start, end);
-            } else
-                view->get_buffer()->cut_clipboard(Gtk::Clipboard::get());
-            if (source_view)
-                source_view->disable_spellcheck = false;
-        }
-    });
-    menu.add_action("edit_copy", [this]() {
-        // Copy from a tooltip if it has selected text
-        for (auto tooltip: Tooltips::shown_tooltips) {
-            auto buffer = tooltip->text_buffer;
-            if (buffer && buffer->get_has_selection()) {
-                buffer->copy_clipboard(Gtk::Clipboard::get());
-                return;
-            }
-        }
+  menu.add_action("edit_cut", [this]() {
+    // Return if a shown tooltip has selected text
+    for (auto tooltip: Tooltips::shown_tooltips) {
+      auto buffer = tooltip->text_buffer;
+      if (buffer && buffer->get_has_selection())
+        return;
+    }
 
-        auto widget = get_focus();
-        if (auto entry = dynamic_cast<Gtk::Entry *>(widget))
-            entry->copy_clipboard();
-        else if (auto view = dynamic_cast<Gtk::TextView *>(widget)) {
-            if (!view->get_buffer()->get_has_selection()) {
-                auto start = view->get_buffer()->get_iter_at_line(
-                        view->get_buffer()->get_insert()->get_iter().get_line());
-                auto end = start;
-                if (!end.ends_line())
-                    end.forward_to_line_end();
-                end.forward_char();
-                if (!end.starts_line()) // In case of \r\n
-                    end.forward_char();
-                Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
-            } else
-                view->get_buffer()->copy_clipboard(Gtk::Clipboard::get());
-        }
-    });
-    menu.add_action("edit_paste", [this]() {
-        auto widget = get_focus();
-        if (auto entry = dynamic_cast<Gtk::Entry *>(widget))
-            entry->paste_clipboard();
-        else if (auto view = dynamic_cast<Gtk::TextView *>(widget)) {
-            auto source_view = dynamic_cast<Source::View *>(view);
-            if (source_view) {
-                source_view->disable_spellcheck = true;
-                source_view->paste();
-                source_view->disable_spellcheck = false;
-            } else if (view->get_editable())
-                view->get_buffer()->paste_clipboard(Gtk::Clipboard::get());
-        }
-    });
+    auto widget = get_focus();
+    if (auto entry = dynamic_cast<Gtk::Entry *>(widget))
+      entry->cut_clipboard();
+    else if (auto view = dynamic_cast<Gtk::TextView *>(widget)) {
+      if (!view->get_editable())
+        return;
+      auto source_view = dynamic_cast<Source::View *>(view);
+      if (source_view)
+        source_view->disable_spellcheck = true;
+      if (!view->get_buffer()->get_has_selection()) {
+        auto start = view->get_buffer()->get_iter_at_line(
+            view->get_buffer()->get_insert()->get_iter().get_line());
+        auto end = start;
+        if (!end.ends_line())
+          end.forward_to_line_end();
+        end.forward_char();
+        if (!end.starts_line()) // In case of \r\n
+          end.forward_char();
+        Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
+        view->get_buffer()->erase(start, end);
+      } else
+        view->get_buffer()->cut_clipboard(Gtk::Clipboard::get());
+      if (source_view)
+        source_view->disable_spellcheck = false;
+    }
+  });
+  menu.add_action("edit_copy", [this]() {
+    // Copy from a tooltip if it has selected text
+    for (auto tooltip: Tooltips::shown_tooltips) {
+      auto buffer = tooltip->text_buffer;
+      if (buffer && buffer->get_has_selection()) {
+        buffer->copy_clipboard(Gtk::Clipboard::get());
+        return;
+      }
+    }
 
-    menu.add_action("edit_find", [this]() {
-        search_and_replace_entry();
-    });
+    auto widget = get_focus();
+    if (auto entry = dynamic_cast<Gtk::Entry *>(widget))
+      entry->copy_clipboard();
+    else if (auto view = dynamic_cast<Gtk::TextView *>(widget)) {
+      if (!view->get_buffer()->get_has_selection()) {
+        auto start = view->get_buffer()->get_iter_at_line(
+            view->get_buffer()->get_insert()->get_iter().get_line());
+        auto end = start;
+        if (!end.ends_line())
+          end.forward_to_line_end();
+        end.forward_char();
+        if (!end.starts_line()) // In case of \r\n
+          end.forward_char();
+        Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
+      } else
+        view->get_buffer()->copy_clipboard(Gtk::Clipboard::get());
+    }
+  });
+  menu.add_action("edit_paste", [this]() {
+    auto widget = get_focus();
+    if (auto entry = dynamic_cast<Gtk::Entry *>(widget))
+      entry->paste_clipboard();
+    else if (auto view = dynamic_cast<Gtk::TextView *>(widget)) {
+      auto source_view = dynamic_cast<Source::View *>(view);
+      if (source_view) {
+        source_view->disable_spellcheck = true;
+        source_view->paste();
+        source_view->disable_spellcheck = false;
+      } else if (view->get_editable())
+        view->get_buffer()->paste_clipboard(Gtk::Clipboard::get());
+    }
+  });
 
-    menu.add_action("source_spellcheck", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            view->remove_spellcheck_errors();
-            view->spellcheck();
-        }
-    });
-    menu.add_action("source_spellcheck_clear", []() {
-        if (auto view = Notebook::get().get_current_view())
-            view->remove_spellcheck_errors();
-    });
-    menu.add_action("source_spellcheck_next_error", []() {
-        if (auto view = Notebook::get().get_current_view())
-            view->goto_next_spellcheck_error();
-    });
+  menu.add_action("edit_find", [this]() {
+    search_and_replace_entry();
+  });
 
-    menu.add_action("source_git_next_diff", []() {
-        if (auto view = Notebook::get().get_current_view())
-            view->git_goto_next_diff();
-    });
-    menu.add_action("source_git_show_diff", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            auto diff_details = view->git_get_diff_details();
-            if (diff_details.empty())
-                return;
-            std::string postfix;
-            if (diff_details.size() > 2) {
-                size_t pos = diff_details.find("@@", 2);
-                if (pos != std::string::npos)
-                    postfix = diff_details.substr(0, pos + 2);
-            }
-            Notebook::get().open(view->file_path.string() + postfix + ".diff");
-            if (auto new_view = Notebook::get().get_current_view()) {
-                if (new_view->get_buffer()->get_text().empty()) {
-                    new_view->get_source_buffer()->begin_not_undoable_action();
-                    new_view->get_buffer()->set_text(diff_details);
-                    new_view->get_source_buffer()->end_not_undoable_action();
-                    new_view->get_buffer()->set_modified(false);
-                }
-            }
-        }
-    });
+  menu.add_action("source_spellcheck", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      view->remove_spellcheck_errors();
+      view->spellcheck();
+    }
+  });
+  menu.add_action("source_spellcheck_clear", []() {
+    if (auto view = Notebook::get().get_current_view())
+      view->remove_spellcheck_errors();
+  });
+  menu.add_action("source_spellcheck_next_error", []() {
+    if (auto view = Notebook::get().get_current_view())
+      view->goto_next_spellcheck_error();
+  });
 
-    menu.add_action("source_indentation_set_buffer_tab", [this]() {
-        set_tab_entry();
-    });
-    menu.add_action("source_indentation_auto_indent_buffer", []() {
-        auto view = Notebook::get().get_current_view();
-        if (view && view->format_style) {
-            view->disable_spellcheck = true;
-            view->format_style(true);
-            view->disable_spellcheck = false;
+  menu.add_action("source_git_next_diff", []() {
+    if (auto view = Notebook::get().get_current_view())
+      view->git_goto_next_diff();
+  });
+  menu.add_action("source_git_show_diff", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      auto diff_details = view->git_get_diff_details();
+      if (diff_details.empty())
+        return;
+      std::string postfix;
+      if (diff_details.size() > 2) {
+        size_t pos = diff_details.find("@@", 2);
+        if (pos != std::string::npos)
+          postfix = diff_details.substr(0, pos + 2);
+      }
+      Notebook::get().open(view->file_path.string() + postfix + ".diff");
+      if (auto new_view = Notebook::get().get_current_view()) {
+        if (new_view->get_buffer()->get_text().empty()) {
+          new_view->get_source_buffer()->begin_not_undoable_action();
+          new_view->get_buffer()->set_text(diff_details);
+          new_view->get_source_buffer()->end_not_undoable_action();
+          new_view->get_buffer()->set_modified(false);
         }
-    });
+      }
+    }
+  });
+
+  menu.add_action("source_indentation_set_buffer_tab", [this]() {
+    set_tab_entry();
+  });
+  menu.add_action("source_indentation_auto_indent_buffer", []() {
+    auto view = Notebook::get().get_current_view();
+    if (view && view->format_style) {
+      view->disable_spellcheck = true;
+      view->format_style(true);
+      view->disable_spellcheck = false;
+    }
+  });
 
-    menu.add_action("source_goto_line", [this]() {
-        goto_line_entry();
-    });
-    menu.add_action("source_center_cursor", []() {
-        if (auto view = Notebook::get().get_current_view())
-            view->scroll_to_cursor_delayed(view, true, false);
-    });
-    menu.add_action("source_cursor_history_back", []() {
-        if (Notebook::get().cursor_locations.size() == 0)
-            return;
-        if (Notebook::get().current_cursor_location == static_cast<size_t>(-1))
-            Notebook::get().current_cursor_location = Notebook::get().cursor_locations.size() - 1;
-
-        auto cursor_location = &Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
-        // Move to current position if current position's view is not current view
-        // (in case one is looking at a new file but has not yet placed the cursor within the file)
-        if (cursor_location->view != Notebook::get().get_current_view())
-            Notebook::get().open(cursor_location->view->file_path);
-        else {
-            if (Notebook::get().cursor_locations.size() <= 1)
-                return;
-            if (Notebook::get().current_cursor_location == 0)
-                return;
-
-            --Notebook::get().current_cursor_location;
-            cursor_location = &Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
-            if (Notebook::get().get_current_view() != cursor_location->view)
-                Notebook::get().open(cursor_location->view->file_path);
-        }
-        Notebook::get().disable_next_update_cursor_locations = true;
-        cursor_location->view->get_buffer()->place_cursor(cursor_location->mark->get_iter());
-        cursor_location->view->scroll_to_cursor_delayed(cursor_location->view, true, false);
-    });
-    menu.add_action("source_cursor_history_forward", []() {
-        if (Notebook::get().cursor_locations.size() <= 1)
-            return;
-        if (Notebook::get().current_cursor_location == static_cast<size_t>(-1))
-            Notebook::get().current_cursor_location = Notebook::get().cursor_locations.size() - 1;
-        if (Notebook::get().current_cursor_location == Notebook::get().cursor_locations.size() - 1)
-            return;
+  menu.add_action("source_goto_line", [this]() {
+    goto_line_entry();
+  });
+  menu.add_action("source_center_cursor", []() {
+    if (auto view = Notebook::get().get_current_view())
+      view->scroll_to_cursor_delayed(view, true, false);
+  });
+  menu.add_action("source_cursor_history_back", []() {
+    if (Notebook::get().cursor_locations.size() == 0)
+      return;
+    if (Notebook::get().current_cursor_location == static_cast<size_t>(-1))
+      Notebook::get().current_cursor_location = Notebook::get().cursor_locations.size() - 1;
+
+    auto cursor_location = &Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
+    // Move to current position if current position's view is not current view
+    // (in case one is looking at a new file but has not yet placed the cursor within the file)
+    if (cursor_location->view != Notebook::get().get_current_view())
+      Notebook::get().open(cursor_location->view->file_path);
+    else {
+      if (Notebook::get().cursor_locations.size() <= 1)
+        return;
+      if (Notebook::get().current_cursor_location == 0)
+        return;
 
-        ++Notebook::get().current_cursor_location;
-        auto &cursor_location = Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
-        if (Notebook::get().get_current_view() != cursor_location.view)
-            Notebook::get().open(cursor_location.view->file_path);
-        Notebook::get().disable_next_update_cursor_locations = true;
-        cursor_location.view->get_buffer()->place_cursor(cursor_location.mark->get_iter());
-        cursor_location.view->scroll_to_cursor_delayed(cursor_location.view, true, false);
-    });
+      --Notebook::get().current_cursor_location;
+      cursor_location = &Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
+      if (Notebook::get().get_current_view() != cursor_location->view)
+        Notebook::get().open(cursor_location->view->file_path);
+    }
+    Notebook::get().disable_next_update_cursor_locations = true;
+    cursor_location->view->get_buffer()->place_cursor(cursor_location->mark->get_iter());
+    cursor_location->view->scroll_to_cursor_delayed(cursor_location->view, true, false);
+  });
+  menu.add_action("source_cursor_history_forward", []() {
+    if (Notebook::get().cursor_locations.size() <= 1)
+      return;
+    if (Notebook::get().current_cursor_location == static_cast<size_t>(-1))
+      Notebook::get().current_cursor_location = Notebook::get().cursor_locations.size() - 1;
+    if (Notebook::get().current_cursor_location == Notebook::get().cursor_locations.size() - 1)
+      return;
+
+    ++Notebook::get().current_cursor_location;
+    auto &cursor_location = Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
+    if (Notebook::get().get_current_view() != cursor_location.view)
+      Notebook::get().open(cursor_location.view->file_path);
+    Notebook::get().disable_next_update_cursor_locations = true;
+    cursor_location.view->get_buffer()->place_cursor(cursor_location.mark->get_iter());
+    cursor_location.view->scroll_to_cursor_delayed(cursor_location.view, true, false);
+  });
+
+  menu.add_action("source_show_completion", [] {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->non_interactive_completion)
+        view->non_interactive_completion();
+      else
+        g_signal_emit_by_name(view->gobj(), "show-completion");
+    }
+  });
+
+  menu.add_action("source_find_symbol", []() {
+    auto project = Project::create();
+    project->show_symbols();
+  });
+
+  menu.add_action("source_find_file", []() {
+    auto view = Notebook::get().get_current_view();
+
+    boost::filesystem::path search_path;
+    if (view)
+      search_path = view->file_path.parent_path();
+    else if (!Directories::get().path.empty())
+      search_path = Directories::get().path;
+    else {
+      boost::system::error_code ec;
+      search_path = boost::filesystem::current_path(ec);
+      if (ec) {
+        Terminal::get().print("Error: could not find current path\n", true);
+        return;
+      }
+    }
+    auto build = Project::Build::create(search_path);
+    auto project_path = build->project_path;
+    boost::filesystem::path default_path, debug_path;
+    if (!project_path.empty()) {
+      search_path = project_path;
+      default_path = build->get_default_path();
+      debug_path = build->get_debug_path();
+    }
 
-    menu.add_action("source_show_completion", [] {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->non_interactive_completion)
-                view->non_interactive_completion();
-            else
-                g_signal_emit_by_name(view->gobj(), "show-completion");
-        }
-    });
+    if (view) {
+      auto dialog_iter = view->get_iter_for_dialog();
+      SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+    } else
+      SelectionDialog::create(true, true);
+
+    std::unordered_set<std::string> buffer_paths;
+    for (auto view: Notebook::get().get_views())
+      buffer_paths.emplace(view->file_path.string());
+
+    std::vector<boost::filesystem::path> paths;
+    // populate with all files in search_path
+    for (boost::filesystem::recursive_directory_iterator iter(search_path), end; iter != end; iter++) {
+      auto path = iter->path();
+      // ignore folders
+      if (!boost::filesystem::is_regular_file(path)) {
+        if (path == default_path || path == debug_path || path.filename() == ".git")
+          iter.no_push();
+        continue;
+      }
 
-    menu.add_action("source_find_symbol", []() {
-        auto project = Project::create();
-        project->show_symbols();
-    });
+      // remove project base path
+      auto row_str = filesystem::get_relative_path(path, search_path).string();
+      if (buffer_paths.count(path.string()))
+        row_str = "<b>" + row_str + "</b>";
+      paths.emplace_back(path);
+      SelectionDialog::get()->add_row(row_str);
+    }
 
-    menu.add_action("source_find_file", []() {
-        auto view = Notebook::get().get_current_view();
+    if (paths.empty()) {
+      Info::get().print("No files found in current project");
+      return;
+    }
 
-        boost::filesystem::path search_path;
-        if (view)
-            search_path = view->file_path.parent_path();
-        else if (!Directories::get().path.empty())
-            search_path = Directories::get().path;
-        else {
-            boost::system::error_code ec;
-            search_path = boost::filesystem::current_path(ec);
-            if (ec) {
-                Terminal::get().print("Error: could not find current path\n", true);
-                return;
-            }
-        }
-        auto build = Project::Build::create(search_path);
-        auto project_path = build->project_path;
-        boost::filesystem::path default_path, debug_path;
-        if (!project_path.empty()) {
-            search_path = project_path;
-            default_path = build->get_default_path();
-            debug_path = build->get_debug_path();
-        }
+    SelectionDialog::get()->on_select = [paths = std::move(paths)](unsigned int index, const std::string &text,
+                                                                   bool hide_window) {
+      if (index >= paths.size())
+        return;
+      Notebook::get().open(paths[index]);
+      if (auto view = Notebook::get().get_current_view())
+        view->hide_tooltips();
+    };
 
-        if (view) {
-            auto dialog_iter = view->get_iter_for_dialog();
-            SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-        } else
-            SelectionDialog::create(true, true);
-
-        std::unordered_set<std::string> buffer_paths;
-        for (auto view: Notebook::get().get_views())
-            buffer_paths.emplace(view->file_path.string());
-
-        std::vector<boost::filesystem::path> paths;
-        // populate with all files in search_path
-        for (boost::filesystem::recursive_directory_iterator iter(search_path), end; iter != end; iter++) {
-            auto path = iter->path();
-            // ignore folders
-            if (!boost::filesystem::is_regular_file(path)) {
-                if (path == default_path || path == debug_path || path.filename() == ".git")
-                    iter.no_push();
-                continue;
-            }
+    if (view)
+      view->hide_tooltips();
+    SelectionDialog::get()->show();
 
-            // remove project base path
-            auto row_str = filesystem::get_relative_path(path, search_path).string();
-            if (buffer_paths.count(path.string()))
-                row_str = "<b>" + row_str + "</b>";
-            paths.emplace_back(path);
-            SelectionDialog::get()->add_row(row_str);
-        }
+  });
 
-        if (paths.empty()) {
-            Info::get().print("No files found in current project");
+  menu.add_action("source_comments_toggle", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->toggle_comments) {
+        view->toggle_comments();
+      }
+    }
+  });
+  menu.add_action("source_comments_add_documentation", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_documentation_template) {
+        auto documentation_template = view->get_documentation_template();
+        auto offset = std::get<0>(documentation_template);
+        if (offset) {
+          if (!boost::filesystem::is_regular_file(offset.file_path))
             return;
+          Notebook::get().open(offset.file_path);
+          auto view = Notebook::get().get_current_view();
+          auto iter = view->get_iter_at_line_pos(offset.line, offset.index);
+          view->get_buffer()->insert(iter, std::get<1>(documentation_template));
+          iter = view->get_iter_at_line_pos(offset.line, offset.index);
+          iter.forward_chars(std::get<2>(documentation_template));
+          view->get_buffer()->place_cursor(iter);
+          view->scroll_to_cursor_delayed(view, true, false);
         }
-
-        SelectionDialog::get()->on_select = [paths = std::move(paths)](unsigned int index, const std::string &text,
-                                                                       bool hide_window) {
-            if (index >= paths.size())
-                return;
-            Notebook::get().open(paths[index]);
-            if (auto view = Notebook::get().get_current_view())
-                view->hide_tooltips();
-        };
-
-        if (view)
-            view->hide_tooltips();
-        SelectionDialog::get()->show();
-
-    });
-
-    menu.add_action("source_comments_toggle", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->toggle_comments) {
-                view->toggle_comments();
+      }
+    }
+  });
+  menu.add_action("source_find_documentation", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_token_data) {
+        auto data = view->get_token_data();
+        std::string url;
+        if (data.size() == 1)
+          url = data[0];
+        else if (data.size() > 1) {
+          auto documentation_search = Config::get().source.documentation_searches.find(data[0]);
+          if (documentation_search != Config::get().source.documentation_searches.end()) {
+            std::string token_query;
+            for (size_t c = 1; c < data.size(); c++) {
+              if (data[c].size() > 0) {
+                if (token_query.size() > 0)
+                  token_query += documentation_search->second.separator;
+                token_query += data[c];
+              }
             }
-        }
-    });
-    menu.add_action("source_comments_add_documentation", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_documentation_template) {
-                auto documentation_template = view->get_documentation_template();
-                auto offset = std::get<0>(documentation_template);
-                if (offset) {
-                    if (!boost::filesystem::is_regular_file(offset.file_path))
-                        return;
-                    Notebook::get().open(offset.file_path);
-                    auto view = Notebook::get().get_current_view();
-                    auto iter = view->get_iter_at_line_pos(offset.line, offset.index);
-                    view->get_buffer()->insert(iter, std::get<1>(documentation_template));
-                    iter = view->get_iter_at_line_pos(offset.line, offset.index);
-                    iter.forward_chars(std::get<2>(documentation_template));
-                    view->get_buffer()->place_cursor(iter);
-                    view->scroll_to_cursor_delayed(view, true, false);
-                }
+            if (token_query.size() > 0) {
+              std::unordered_map<std::string, std::string>::iterator query;
+              if (data[1].size() > 0)
+                query = documentation_search->second.queries.find(data[1]);
+              else
+                query = documentation_search->second.queries.find("@empty");
+              if (query == documentation_search->second.queries.end())
+                query = documentation_search->second.queries.find("@any");
+
+              if (query != documentation_search->second.queries.end())
+                url = query->second + token_query;
             }
+          }
         }
-    });
-    menu.add_action("source_find_documentation", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_token_data) {
-                auto data = view->get_token_data();
-                std::string url;
-                if (data.size() == 1)
-                    url = data[0];
-                else if (data.size() > 1) {
-                    auto documentation_search = Config::get().source.documentation_searches.find(data[0]);
-                    if (documentation_search != Config::get().source.documentation_searches.end()) {
-                        std::string token_query;
-                        for (size_t c = 1; c < data.size(); c++) {
-                            if (data[c].size() > 0) {
-                                if (token_query.size() > 0)
-                                    token_query += documentation_search->second.separator;
-                                token_query += data[c];
-                            }
-                        }
-                        if (token_query.size() > 0) {
-                            std::unordered_map<std::string, std::string>::iterator query;
-                            if (data[1].size() > 0)
-                                query = documentation_search->second.queries.find(data[1]);
-                            else
-                                query = documentation_search->second.queries.find("@empty");
-                            if (query == documentation_search->second.queries.end())
-                                query = documentation_search->second.queries.find("@any");
-
-                            if (query != documentation_search->second.queries.end())
-                                url = query->second + token_query;
-                        }
-                    }
-                }
-                if (!url.empty()) {
+        if (!url.empty()) {
 #ifdef __APPLE__
-                    Terminal::get().process("open \""+url+"\"");
+          Terminal::get().process("open \""+url+"\"");
 #else
-                    GError *error = nullptr;
+          GError *error = nullptr;
 #if GTK_VERSION_GE(3, 22)
-                    gtk_show_uri_on_window(nullptr, url.c_str(), GDK_CURRENT_TIME, &error);
+          gtk_show_uri_on_window(nullptr, url.c_str(), GDK_CURRENT_TIME, &error);
 #else
-                    gtk_show_uri(nullptr, url.c_str(), GDK_CURRENT_TIME, &error);
+          gtk_show_uri(nullptr, url.c_str(), GDK_CURRENT_TIME, &error);
 #endif
-                    g_clear_error(&error);
+          g_clear_error(&error);
 #endif
-                }
-            }
         }
-    });
-
-    menu.add_action("source_goto_declaration", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_declaration_location) {
-                auto location = view->get_declaration_location();
-                if (location) {
-                    if (!boost::filesystem::is_regular_file(location.file_path))
-                        return;
-                    Notebook::get().open(location.file_path);
-                    auto view = Notebook::get().get_current_view();
-                    auto line = static_cast<int>(location.line);
-                    auto index = static_cast<int>(location.index);
-                    view->place_cursor_at_line_pos(line, index);
-                    view->scroll_to_cursor_delayed(view, true, false);
-                }
-            }
-        }
-    });
-    menu.add_action("source_goto_type_declaration", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_type_declaration_location) {
-                auto location = view->get_type_declaration_location();
-                if (location) {
-                    if (!boost::filesystem::is_regular_file(location.file_path))
-                        return;
-                    Notebook::get().open(location.file_path);
-                    auto view = Notebook::get().get_current_view();
-                    auto line = static_cast<int>(location.line);
-                    auto index = static_cast<int>(location.index);
-                    view->place_cursor_at_line_pos(line, index);
-                    view->scroll_to_cursor_delayed(view, true, false);
-                }
-            }
-        }
-    });
-    auto goto_selected_location = [](Source::View *view, const std::vector<Source::Offset> &locations) {
-        if (!locations.empty()) {
-            auto dialog_iter = view->get_iter_for_dialog();
-            SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-            std::vector<Source::Offset> rows;
-            auto project_path = Project::Build::create(view->file_path)->project_path;
-            if (project_path.empty()) {
-                if (!Directories::get().path.empty())
-                    project_path = Directories::get().path;
-                else
-                    project_path = view->file_path.parent_path();
-            }
-            for (auto &location: locations) {
-                auto path = filesystem::get_relative_path(filesystem::get_normal_path(location.file_path),
-                                                          project_path);
-                if (path.empty())
-                    path = location.file_path.filename();
-                auto row = path.string() + ":" + std::to_string(location.line + 1);
-                rows.emplace_back(location);
-                SelectionDialog::get()->add_row(row);
-            }
+      }
+    }
+  });
 
-            if (rows.size() == 0)
-                return;
-            else if (rows.size() == 1) {
-                auto location = *rows.begin();
-                if (!boost::filesystem::is_regular_file(location.file_path))
-                    return;
-                Notebook::get().open(location.file_path);
-                auto view = Notebook::get().get_current_view();
-                auto line = static_cast<int>(location.line);
-                auto index = static_cast<int>(location.index);
-                view->place_cursor_at_line_pos(line, index);
-                view->scroll_to_cursor_delayed(view, true, false);
-                return;
-            }
-            SelectionDialog::get()->on_select = [rows = std::move(rows)](unsigned int index, const std::string &text,
-                                                                         bool hide_window) {
-                if (index >= rows.size())
-                    return;
-                auto location = rows[index];
-                if (!boost::filesystem::is_regular_file(location.file_path))
-                    return;
-                Notebook::get().open(location.file_path);
-                auto view = Notebook::get().get_current_view();
-                view->place_cursor_at_line_pos(location.line, location.index);
-                view->scroll_to_cursor_delayed(view, true, false);
-                view->hide_tooltips();
-            };
-            view->hide_tooltips();
-            SelectionDialog::get()->show();
-        }
-    };
-    menu.add_action("source_goto_implementation", [goto_selected_location]() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_implementation_locations)
-                goto_selected_location(view, view->get_implementation_locations());
+  menu.add_action("source_goto_declaration", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_declaration_location) {
+        auto location = view->get_declaration_location();
+        if (location) {
+          if (!boost::filesystem::is_regular_file(location.file_path))
+            return;
+          Notebook::get().open(location.file_path);
+          auto view = Notebook::get().get_current_view();
+          auto line = static_cast<int>(location.line);
+          auto index = static_cast<int>(location.index);
+          view->place_cursor_at_line_pos(line, index);
+          view->scroll_to_cursor_delayed(view, true, false);
         }
-    });
-    menu.add_action("source_goto_declaration_or_implementation", [goto_selected_location]() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_declaration_or_implementation_locations)
-                goto_selected_location(view, view->get_declaration_or_implementation_locations());
+      }
+    }
+  });
+  menu.add_action("source_goto_type_declaration", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_type_declaration_location) {
+        auto location = view->get_type_declaration_location();
+        if (location) {
+          if (!boost::filesystem::is_regular_file(location.file_path))
+            return;
+          Notebook::get().open(location.file_path);
+          auto view = Notebook::get().get_current_view();
+          auto line = static_cast<int>(location.line);
+          auto index = static_cast<int>(location.index);
+          view->place_cursor_at_line_pos(line, index);
+          view->scroll_to_cursor_delayed(view, true, false);
         }
-    });
+      }
+    }
+  });
+  auto goto_selected_location = [](Source::View *view, const std::vector<Source::Offset> &locations) {
+    if (!locations.empty()) {
+      auto dialog_iter = view->get_iter_for_dialog();
+      SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+      std::vector<Source::Offset> rows;
+      auto project_path = Project::Build::create(view->file_path)->project_path;
+      if (project_path.empty()) {
+        if (!Directories::get().path.empty())
+          project_path = Directories::get().path;
+        else
+          project_path = view->file_path.parent_path();
+      }
+      for (auto &location: locations) {
+        auto path = filesystem::get_relative_path(filesystem::get_normal_path(location.file_path),
+                                                  project_path);
+        if (path.empty())
+          path = location.file_path.filename();
+        auto row = path.string() + ":" + std::to_string(location.line + 1);
+        rows.emplace_back(location);
+        SelectionDialog::get()->add_row(row);
+      }
 
-    menu.add_action("source_goto_usage", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_usages) {
-                auto usages = view->get_usages();
-                if (!usages.empty()) {
-                    auto dialog_iter = view->get_iter_for_dialog();
-                    SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-                    std::vector<Source::Offset> rows;
-
-                    auto iter = view->get_buffer()->get_insert()->get_iter();
-                    for (auto &usage: usages) {
-                        std::string row;
-                        bool current_page = true;
-                        //add file name if usage is not in current page
-                        if (view->file_path != usage.first.file_path) {
-                            row = usage.first.file_path.filename().string() + ":";
-                            current_page = false;
-                        }
-                        row += std::to_string(usage.first.line + 1) + ": " + usage.second;
-                        rows.emplace_back(usage.first);
-                        SelectionDialog::get()->add_row(row);
-
-                        //Set dialog cursor to the last row if the textview cursor is at the same line
-                        if (current_page &&
-                            iter.get_line() == static_cast<int>(usage.first.line) &&
-                            iter.get_line_index() >= static_cast<int>(usage.first.index)) {
-                            SelectionDialog::get()->set_cursor_at_last_row();
-                        }
-                    }
-
-                    if (rows.size() == 0)
-                        return;
-                    SelectionDialog::get()->on_select = [rows = std::move(rows)](unsigned int index,
-                                                                                 const std::string &text,
-                                                                                 bool hide_window) {
-                        if (index >= rows.size())
-                            return;
-                        auto offset = rows[index];
-                        if (!boost::filesystem::is_regular_file(offset.file_path))
-                            return;
-                        Notebook::get().open(offset.file_path);
-                        auto view = Notebook::get().get_current_view();
-                        view->place_cursor_at_line_pos(offset.line, offset.index);
-                        view->scroll_to_cursor_delayed(view, true, false);
-                        view->hide_tooltips();
-                    };
-                    view->hide_tooltips();
-                    SelectionDialog::get()->show();
-                }
-            }
-        }
-    });
-    menu.add_action("source_goto_method", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_methods) {
-                auto methods = Notebook::get().get_current_view()->get_methods();
-                if (!methods.empty()) {
-                    auto dialog_iter = view->get_iter_for_dialog();
-                    SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
-                    std::vector<Source::Offset> rows;
-                    auto iter = view->get_buffer()->get_insert()->get_iter();
-                    for (auto &method: methods) {
-                        rows.emplace_back(method.first);
-                        SelectionDialog::get()->add_row(method.second);
-                        if (iter.get_line() >= static_cast<int>(method.first.line))
-                            SelectionDialog::get()->set_cursor_at_last_row();
-                    }
-                    SelectionDialog::get()->on_select = [view, rows = std::move(rows)](unsigned int index,
-                                                                                       const std::string &text,
-                                                                                       bool hide_window) {
-                        if (index >= rows.size())
-                            return;
-                        auto offset = rows[index];
-                        view->get_buffer()->place_cursor(view->get_iter_at_line_pos(offset.line, offset.index));
-                        view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
-                        view->hide_tooltips();
-                    };
-                    view->hide_tooltips();
-                    SelectionDialog::get()->show();
-                }
-            }
-        }
-    });
-    menu.add_action("source_rename", [this]() {
-        rename_token_entry();
-    });
-    menu.add_action("source_implement_method", []() {
-        const static std::string button_text = "Insert Method Implementation";
-
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_method) {
-                auto iter = view->get_buffer()->get_insert()->get_iter();
-                if (!EntryBox::get().buttons.empty() && EntryBox::get().buttons.back().get_label() == button_text &&
-                    iter.ends_line() && iter.starts_line()) {
-                    EntryBox::get().buttons.back().activate();
-                    return;
-                }
-                auto method = view->get_method();
-                if (method.empty())
-                    return;
-
-                EntryBox::get().clear();
-                EntryBox::get().labels.emplace_back();
-                EntryBox::get().labels.back().set_text(method);
-                EntryBox::get().buttons.emplace_back(button_text, [method = std::move(method)]() {
-                    if (auto view = Notebook::get().get_current_view()) {
-                        view->get_buffer()->insert_at_cursor(method);
-                        EntryBox::get().clear();
-                    }
-                });
-                EntryBox::get().show();
-            }
-        }
-    });
+      if (rows.size() == 0)
+        return;
+      else if (rows.size() == 1) {
+        auto location = *rows.begin();
+        if (!boost::filesystem::is_regular_file(location.file_path))
+          return;
+        Notebook::get().open(location.file_path);
+        auto view = Notebook::get().get_current_view();
+        auto line = static_cast<int>(location.line);
+        auto index = static_cast<int>(location.index);
+        view->place_cursor_at_line_pos(line, index);
+        view->scroll_to_cursor_delayed(view, true, false);
+        return;
+      }
+      SelectionDialog::get()->on_select = [rows = std::move(rows)](unsigned int index, const std::string &text,
+                                                                   bool hide_window) {
+        if (index >= rows.size())
+          return;
+        auto location = rows[index];
+        if (!boost::filesystem::is_regular_file(location.file_path))
+          return;
+        Notebook::get().open(location.file_path);
+        auto view = Notebook::get().get_current_view();
+        view->place_cursor_at_line_pos(location.line, location.index);
+        view->scroll_to_cursor_delayed(view, true, false);
+        view->hide_tooltips();
+      };
+      view->hide_tooltips();
+      SelectionDialog::get()->show();
+    }
+  };
+  menu.add_action("source_goto_implementation", [goto_selected_location]() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_implementation_locations)
+        goto_selected_location(view, view->get_implementation_locations());
+    }
+  });
+  menu.add_action("source_goto_declaration_or_implementation", [goto_selected_location]() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_declaration_or_implementation_locations)
+        goto_selected_location(view, view->get_declaration_or_implementation_locations());
+    }
+  });
 
-    menu.add_action("source_goto_next_diagnostic", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->goto_next_diagnostic) {
-                view->goto_next_diagnostic();
+  menu.add_action("source_goto_usage", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_usages) {
+        auto usages = view->get_usages();
+        if (!usages.empty()) {
+          auto dialog_iter = view->get_iter_for_dialog();
+          SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+          std::vector<Source::Offset> rows;
+
+          auto iter = view->get_buffer()->get_insert()->get_iter();
+          for (auto &usage: usages) {
+            std::string row;
+            bool current_page = true;
+            //add file name if usage is not in current page
+            if (view->file_path != usage.first.file_path) {
+              row = usage.first.file_path.filename().string() + ":";
+              current_page = false;
             }
-        }
-    });
-    menu.add_action("source_apply_fix_its", []() {
-        if (auto view = Notebook::get().get_current_view()) {
-            if (view->get_fix_its) {
-                auto buffer = view->get_buffer();
-                auto fix_its = view->get_fix_its();
-                std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > fix_it_marks;
-                for (auto &fix_it: fix_its) {
-                    auto start_iter = view->get_iter_at_line_pos(fix_it.offsets.first.line, fix_it.offsets.first.index);
-                    auto end_iter = view->get_iter_at_line_pos(fix_it.offsets.second.line, fix_it.offsets.second.index);
-                    fix_it_marks.emplace_back(buffer->create_mark(start_iter), buffer->create_mark(end_iter));
-                }
-                size_t c = 0;
-                buffer->begin_user_action();
-                for (auto &fix_it: fix_its) {
-                    if (fix_it.type == Source::FixIt::Type::INSERT) {
-                        buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source);
-                    }
-                    if (fix_it.type == Source::FixIt::Type::REPLACE) {
-                        buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter());
-                        buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source);
-                    }
-                    if (fix_it.type == Source::FixIt::Type::ERASE) {
-                        buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter());
-                    }
-                    c++;
-                }
-                for (auto &mark_pair: fix_it_marks) {
-                    buffer->delete_mark(mark_pair.first);
-                    buffer->delete_mark(mark_pair.second);
-                }
-                buffer->end_user_action();
+            row += std::to_string(usage.first.line + 1) + ": " + usage.second;
+            rows.emplace_back(usage.first);
+            SelectionDialog::get()->add_row(row);
+
+            //Set dialog cursor to the last row if the textview cursor is at the same line
+            if (current_page &&
+                iter.get_line() == static_cast<int>(usage.first.line) &&
+                iter.get_line_index() >= static_cast<int>(usage.first.index)) {
+              SelectionDialog::get()->set_cursor_at_last_row();
             }
-        }
-    });
+          }
 
-    menu.add_action("project_set_run_arguments", []() {
-        auto project = Project::create();
-        auto run_arguments = project->get_run_arguments();
-        if (run_arguments.second.empty())
+          if (rows.size() == 0)
             return;
+          SelectionDialog::get()->on_select = [rows = std::move(rows)](unsigned int index,
+                                                                       const std::string &text,
+                                                                       bool hide_window) {
+            if (index >= rows.size())
+              return;
+            auto offset = rows[index];
+            if (!boost::filesystem::is_regular_file(offset.file_path))
+              return;
+            Notebook::get().open(offset.file_path);
+            auto view = Notebook::get().get_current_view();
+            view->place_cursor_at_line_pos(offset.line, offset.index);
+            view->scroll_to_cursor_delayed(view, true, false);
+            view->hide_tooltips();
+          };
+          view->hide_tooltips();
+          SelectionDialog::get()->show();
+        }
+      }
+    }
+  });
+  menu.add_action("source_goto_method", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_methods) {
+        auto methods = Notebook::get().get_current_view()->get_methods();
+        if (!methods.empty()) {
+          auto dialog_iter = view->get_iter_for_dialog();
+          SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
+          std::vector<Source::Offset> rows;
+          auto iter = view->get_buffer()->get_insert()->get_iter();
+          for (auto &method: methods) {
+            rows.emplace_back(method.first);
+            SelectionDialog::get()->add_row(method.second);
+            if (iter.get_line() >= static_cast<int>(method.first.line))
+              SelectionDialog::get()->set_cursor_at_last_row();
+          }
+          SelectionDialog::get()->on_select = [view, rows = std::move(rows)](unsigned int index,
+                                                                             const std::string &text,
+                                                                             bool hide_window) {
+            if (index >= rows.size())
+              return;
+            auto offset = rows[index];
+            view->get_buffer()->place_cursor(view->get_iter_at_line_pos(offset.line, offset.index));
+            view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
+            view->hide_tooltips();
+          };
+          view->hide_tooltips();
+          SelectionDialog::get()->show();
+        }
+      }
+    }
+  });
+  menu.add_action("source_rename", [this]() {
+    rename_token_entry();
+  });
+  menu.add_action("source_implement_method", []() {
+    const static std::string button_text = "Insert Method Implementation";
+
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_method) {
+        auto iter = view->get_buffer()->get_insert()->get_iter();
+        if (!EntryBox::get().buttons.empty() && EntryBox::get().buttons.back().get_label() == button_text &&
+            iter.ends_line() && iter.starts_line()) {
+          EntryBox::get().buttons.back().activate();
+          return;
+        }
+        auto method = view->get_method();
+        if (method.empty())
+          return;
 
         EntryBox::get().clear();
         EntryBox::get().labels.emplace_back();
-        auto label_it = EntryBox::get().labels.begin();
-        label_it->update = [label_it](int state, const std::string &message) {
-            label_it->set_text(
-                    "Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
-        };
-        label_it->update(0, "");
-        EntryBox::get().entries.emplace_back(run_arguments.second,
-                                             [run_arguments_first = std::move(run_arguments.first)](
-                                                     const std::string &content) {
-                                                 Project::run_arguments[run_arguments_first] = content;
-                                                 EntryBox::get().hide();
-                                             }, 50);
-        auto entry_it = EntryBox::get().entries.begin();
-        entry_it->set_placeholder_text("Project: Set Run Arguments");
-        EntryBox::get().buttons.emplace_back("Project: set run arguments", [entry_it]() {
-            entry_it->activate();
+        EntryBox::get().labels.back().set_text(method);
+        EntryBox::get().buttons.emplace_back(button_text, [method = std::move(method)]() {
+          if (auto view = Notebook::get().get_current_view()) {
+            view->get_buffer()->insert_at_cursor(method);
+            EntryBox::get().clear();
+          }
         });
         EntryBox::get().show();
-    });
-    menu.add_action("project_compile_and_run", []() {
-        if (Project::compiling || Project::debugging) {
-            Info::get().print("Compile or debug in progress");
-            return;
-        }
+      }
+    }
+  });
 
-        Project::current = Project::create();
+  menu.add_action("source_goto_next_diagnostic", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->goto_next_diagnostic) {
+        view->goto_next_diagnostic();
+      }
+    }
+  });
+  menu.add_action("source_apply_fix_its", []() {
+    if (auto view = Notebook::get().get_current_view()) {
+      if (view->get_fix_its) {
+        auto buffer = view->get_buffer();
+        auto fix_its = view->get_fix_its();
+        std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > fix_it_marks;
+        for (auto &fix_it: fix_its) {
+          auto start_iter = view->get_iter_at_line_pos(fix_it.offsets.first.line, fix_it.offsets.first.index);
+          auto end_iter = view->get_iter_at_line_pos(fix_it.offsets.second.line, fix_it.offsets.second.index);
+          fix_it_marks.emplace_back(buffer->create_mark(start_iter), buffer->create_mark(end_iter));
+        }
+        size_t c = 0;
+        buffer->begin_user_action();
+        for (auto &fix_it: fix_its) {
+          if (fix_it.type == Source::FixIt::Type::INSERT) {
+            buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source);
+          }
+          if (fix_it.type == Source::FixIt::Type::REPLACE) {
+            buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter());
+            buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source);
+          }
+          if (fix_it.type == Source::FixIt::Type::ERASE) {
+            buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter());
+          }
+          c++;
+        }
+        for (auto &mark_pair: fix_it_marks) {
+          buffer->delete_mark(mark_pair.first);
+          buffer->delete_mark(mark_pair.second);
+        }
+        buffer->end_user_action();
+      }
+    }
+  });
 
-        if (Config::get().project.save_on_compile_or_run)
-            Project::save_files(Project::current->build->project_path);
+  menu.add_action("project_set_run_arguments", []() {
+    auto project = Project::create();
+    auto run_arguments = project->get_run_arguments();
+    if (run_arguments.second.empty())
+      return;
 
-        Project::current->compile_and_run();
+    EntryBox::get().clear();
+    EntryBox::get().labels.emplace_back();
+    auto label_it = EntryBox::get().labels.begin();
+    label_it->update = [label_it](int state, const std::string &message) {
+      label_it->set_text(
+          "Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
+    };
+    label_it->update(0, "");
+    EntryBox::get().entries.emplace_back(run_arguments.second,
+                                         [run_arguments_first = std::move(run_arguments.first)](
+                                             const std::string &content) {
+                                           Project::run_arguments[run_arguments_first] = content;
+                                           EntryBox::get().hide();
+                                         }, 50);
+    auto entry_it = EntryBox::get().entries.begin();
+    entry_it->set_placeholder_text("Project: Set Run Arguments");
+    EntryBox::get().buttons.emplace_back("Project: set run arguments", [entry_it]() {
+      entry_it->activate();
     });
-    menu.add_action("project_compile", []() {
-        if (Project::compiling || Project::debugging) {
-            Info::get().print("Compile or debug in progress");
-            return;
-        }
-
-        Project::current = Project::create();
+    EntryBox::get().show();
+  });
+  menu.add_action("project_compile_and_run", []() {
+    if (Project::compiling || Project::debugging) {
+      Info::get().print("Compile or debug in progress");
+      return;
+    }
 
-        if (Config::get().project.save_on_compile_or_run)
-            Project::save_files(Project::current->build->project_path);
+    Project::current = Project::create();
 
-        Project::current->compile();
-    });
-    menu.add_action("project_recreate_build", []() {
-        if (Project::compiling || Project::debugging) {
-            Info::get().print("Compile or debug in progress");
-            return;
-        }
+    if (Config::get().project.save_on_compile_or_run)
+      Project::save_files(Project::current->build->project_path);
 
-        Project::current = Project::create();
+    Project::current->compile_and_run();
+  });
+  menu.add_action("project_compile", []() {
+    if (Project::compiling || Project::debugging) {
+      Info::get().print("Compile or debug in progress");
+      return;
+    }
 
-        Project::current->recreate_build();
-    });
+    Project::current = Project::create();
 
-    menu.add_action("project_run_command", [this]() {
-        EntryBox::get().clear();
-        EntryBox::get().labels.emplace_back();
-        auto label_it = EntryBox::get().labels.begin();
-        label_it->update = [label_it](int state, const std::string &message) {
-            label_it->set_text("Run Command directory order: opened directory, file path, current directory");
-        };
-        label_it->update(0, "");
-        EntryBox::get().entries.emplace_back(last_run_command, [this](const std::string &content) {
-            if (content != "") {
-                last_run_command = content;
-                auto run_path = Notebook::get().get_current_folder();
-                Terminal::get().async_print("Running: " + content + '\n');
-
-                Terminal::get().async_process(content, run_path, [content](int exit_status) {
-                    Terminal::get().async_print(content + " returned: " + std::to_string(exit_status) + '\n');
-                });
-            }
-            EntryBox::get().hide();
-        }, 30);
-        auto entry_it = EntryBox::get().entries.begin();
-        entry_it->set_placeholder_text("Command");
-        EntryBox::get().buttons.emplace_back("Run command", [entry_it]() {
-            entry_it->activate();
-        });
-        EntryBox::get().show();
-    });
+    if (Config::get().project.save_on_compile_or_run)
+      Project::save_files(Project::current->build->project_path);
 
-    menu.add_action("project_kill_last_running", []() {
-        Terminal::get().kill_last_async_process();
-    });
-    menu.add_action("project_force_kill_last_running", []() {
-        Terminal::get().kill_last_async_process(true);
-    });
+    Project::current->compile();
+  });
+  menu.add_action("project_recreate_build", []() {
+    if (Project::compiling || Project::debugging) {
+      Info::get().print("Compile or debug in progress");
+      return;
+    }
 
-#ifdef JUCI_ENABLE_DEBUG
-    menu.add_action("debug_set_run_arguments", []() {
-      auto project=Project::create();
-      auto run_arguments=project->debug_get_run_arguments();
-      if(run_arguments.second.empty())
-        return;
+    Project::current = Project::create();
 
-      EntryBox::get().clear();
-      EntryBox::get().labels.emplace_back();
-      auto label_it=EntryBox::get().labels.begin();
-      label_it->update=[label_it](int state, const std::string& message){
-        label_it->set_text("Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
-      };
-      label_it->update(0, "");
-      EntryBox::get().entries.emplace_back(run_arguments.second, [run_arguments_first=std::move(run_arguments.first)](const std::string& content){
-        Project::debug_run_arguments[run_arguments_first].arguments=content;
-        EntryBox::get().hide();
-      }, 50);
-      auto entry_it=EntryBox::get().entries.begin();
-      entry_it->set_placeholder_text("Debug: Set Run Arguments");
+    Project::current->recreate_build();
+  });
 
-      if(auto options=project->debug_get_options()) {
-        EntryBox::get().buttons.emplace_back("", [options]() {
-          options->show_all();
+  menu.add_action("project_run_command", [this]() {
+    EntryBox::get().clear();
+    EntryBox::get().labels.emplace_back();
+    auto label_it = EntryBox::get().labels.begin();
+    label_it->update = [label_it](int state, const std::string &message) {
+      label_it->set_text("Run Command directory order: opened directory, file path, current directory");
+    };
+    label_it->update(0, "");
+    EntryBox::get().entries.emplace_back(last_run_command, [this](const std::string &content) {
+      if (content != "") {
+        last_run_command = content;
+        auto run_path = Notebook::get().get_current_folder();
+        Terminal::get().async_print("Running: " + content + '\n');
+
+        Terminal::get().async_process(content, run_path, [content](int exit_status) {
+          Terminal::get().async_print(content + " returned: " + std::to_string(exit_status) + '\n');
         });
-        EntryBox::get().buttons.back().set_image_from_icon_name("preferences-system");
-        EntryBox::get().buttons.back().set_always_show_image(true);
-        EntryBox::get().buttons.back().set_tooltip_text("Additional Options");
-        options->set_relative_to(EntryBox::get().buttons.back());
       }
-
-      EntryBox::get().buttons.emplace_back("Debug: set run arguments", [entry_it](){
-        entry_it->activate();
-      });
-      EntryBox::get().show();
+      EntryBox::get().hide();
+    }, 30);
+    auto entry_it = EntryBox::get().entries.begin();
+    entry_it->set_placeholder_text("Command");
+    EntryBox::get().buttons.emplace_back("Run command", [entry_it]() {
+      entry_it->activate();
     });
-    menu.add_action("debug_start_continue", [](){
-      if(Project::compiling) {
-        Info::get().print("Compile in progress");
-        return;
-      }
-      else if(Project::debugging) {
-        Project::current->debug_continue();
-        return;
-      }
+    EntryBox::get().show();
+  });
 
-      Project::current=Project::create();
+  menu.add_action("project_kill_last_running", []() {
+    Terminal::get().kill_last_async_process();
+  });
+  menu.add_action("project_force_kill_last_running", []() {
+    Terminal::get().kill_last_async_process(true);
+  });
 
-      if(Config::get().project.save_on_compile_or_run)
-        Project::save_files(Project::current->build->project_path);
+#ifdef JUCI_ENABLE_DEBUG
+  menu.add_action("debug_set_run_arguments", []() {
+    auto project=Project::create();
+    auto run_arguments=project->debug_get_run_arguments();
+    if(run_arguments.second.empty())
+      return;
 
-      Project::current->debug_start();
-    });
-    menu.add_action("debug_stop", []() {
-      if(Project::current)
-        Project::current->debug_stop();
-    });
-    menu.add_action("debug_kill", []() {
-      if(Project::current)
-        Project::current->debug_kill();
-    });
-    menu.add_action("debug_step_over", []() {
-      if(Project::current)
-        Project::current->debug_step_over();
-    });
-    menu.add_action("debug_step_into", []() {
-      if(Project::current)
-        Project::current->debug_step_into();
-    });
-    menu.add_action("debug_step_out", []() {
-      if(Project::current)
-        Project::current->debug_step_out();
-    });
-    menu.add_action("debug_backtrace", []() {
-      if(Project::current)
-        Project::current->debug_backtrace();
-    });
-    menu.add_action("debug_show_variables", []() {
-      if(Project::current)
-        Project::current->debug_show_variables();
-    });
-    menu.add_action("debug_run_command", [this]() {
-      EntryBox::get().clear();
-      EntryBox::get().entries.emplace_back(last_run_debug_command, [this](const std::string& content){
-        if(content!="") {
-          if(Project::current)
-            Project::current->debug_run_command(content);
-          last_run_debug_command=content;
-        }
-        EntryBox::get().hide();
-      }, 30);
-      auto entry_it=EntryBox::get().entries.begin();
-      entry_it->set_placeholder_text("Debug Command");
-      EntryBox::get().buttons.emplace_back("Run debug command", [entry_it](){
-        entry_it->activate();
+    EntryBox::get().clear();
+    EntryBox::get().labels.emplace_back();
+    auto label_it=EntryBox::get().labels.begin();
+    label_it->update=[label_it](int state, const std::string& message){
+      label_it->set_text("Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
+    };
+    label_it->update(0, "");
+    EntryBox::get().entries.emplace_back(run_arguments.second, [run_arguments_first=std::move(run_arguments.first)](const std::string& content){
+      Project::debug_run_arguments[run_arguments_first].arguments=content;
+      EntryBox::get().hide();
+    }, 50);
+    auto entry_it=EntryBox::get().entries.begin();
+    entry_it->set_placeholder_text("Debug: Set Run Arguments");
+
+    if(auto options=project->debug_get_options()) {
+      EntryBox::get().buttons.emplace_back("", [options]() {
+        options->show_all();
       });
-      EntryBox::get().show();
+      EntryBox::get().buttons.back().set_image_from_icon_name("preferences-system");
+      EntryBox::get().buttons.back().set_always_show_image(true);
+      EntryBox::get().buttons.back().set_tooltip_text("Additional Options");
+      options->set_relative_to(EntryBox::get().buttons.back());
+    }
+
+    EntryBox::get().buttons.emplace_back("Debug: set run arguments", [entry_it](){
+      entry_it->activate();
     });
-    menu.add_action("debug_toggle_breakpoint", [](){
-      if(auto view=Notebook::get().get_current_view()) {
-        if(view->toggle_breakpoint)
-          view->toggle_breakpoint(view->get_buffer()->get_insert()->get_iter().get_line());
+    EntryBox::get().show();
+  });
+  menu.add_action("debug_start_continue", [](){
+    if(Project::compiling) {
+      Info::get().print("Compile in progress");
+      return;
+    }
+    else if(Project::debugging) {
+      Project::current->debug_continue();
+      return;
+    }
+
+    Project::current=Project::create();
+
+    if(Config::get().project.save_on_compile_or_run)
+      Project::save_files(Project::current->build->project_path);
+
+    Project::current->debug_start();
+  });
+  menu.add_action("debug_stop", []() {
+    if(Project::current)
+      Project::current->debug_stop();
+  });
+  menu.add_action("debug_kill", []() {
+    if(Project::current)
+      Project::current->debug_kill();
+  });
+  menu.add_action("debug_step_over", []() {
+    if(Project::current)
+      Project::current->debug_step_over();
+  });
+  menu.add_action("debug_step_into", []() {
+    if(Project::current)
+      Project::current->debug_step_into();
+  });
+  menu.add_action("debug_step_out", []() {
+    if(Project::current)
+      Project::current->debug_step_out();
+  });
+  menu.add_action("debug_backtrace", []() {
+    if(Project::current)
+      Project::current->debug_backtrace();
+  });
+  menu.add_action("debug_show_variables", []() {
+    if(Project::current)
+      Project::current->debug_show_variables();
+  });
+  menu.add_action("debug_run_command", [this]() {
+    EntryBox::get().clear();
+    EntryBox::get().entries.emplace_back(last_run_debug_command, [this](const std::string& content){
+      if(content!="") {
+        if(Project::current)
+          Project::current->debug_run_command(content);
+        last_run_debug_command=content;
       }
+      EntryBox::get().hide();
+    }, 30);
+    auto entry_it=EntryBox::get().entries.begin();
+    entry_it->set_placeholder_text("Debug Command");
+    EntryBox::get().buttons.emplace_back("Run debug command", [entry_it](){
+      entry_it->activate();
     });
-    menu.add_action("debug_goto_stop", [](){
-      if(Project::debugging) {
-        if(!Project::debug_stop.first.empty()) {
-          Notebook::get().open(Project::debug_stop.first);
-          if(auto view=Notebook::get().get_current_view()) {
-            int line=Project::debug_stop.second.first;
-            int index=Project::debug_stop.second.second;
-            view->place_cursor_at_line_index(line, index);
-            view->scroll_to_cursor_delayed(view, true, true);
-          }
+    EntryBox::get().show();
+  });
+  menu.add_action("debug_toggle_breakpoint", [](){
+    if(auto view=Notebook::get().get_current_view()) {
+      if(view->toggle_breakpoint)
+        view->toggle_breakpoint(view->get_buffer()->get_insert()->get_iter().get_line());
+    }
+  });
+  menu.add_action("debug_goto_stop", [](){
+    if(Project::debugging) {
+      if(!Project::debug_stop.first.empty()) {
+        Notebook::get().open(Project::debug_stop.first);
+        if(auto view=Notebook::get().get_current_view()) {
+          int line=Project::debug_stop.second.first;
+          int index=Project::debug_stop.second.second;
+          view->place_cursor_at_line_index(line, index);
+          view->scroll_to_cursor_delayed(view, true, true);
         }
       }
-    });
+    }
+  });
 
-    Project::debug_update_status("");
+  Project::debug_update_status("");
 #endif
 
-    menu.add_action("window_next_tab", []() {
-        Notebook::get().next();
-    });
-    menu.add_action("window_previous_tab", []() {
-        Notebook::get().previous();
-    });
-    menu.add_action("window_close_tab", []() {
-        if (Notebook::get().get_current_view())
-            Notebook::get().close_current();
-    });
-    menu.add_action("window_toggle_split", [] {
-        Notebook::get().toggle_split();
-    });
-    menu.add_action("window_toggle_full_screen", [this] {
-        if (this->get_window()->get_state() & Gdk::WindowState::WINDOW_STATE_FULLSCREEN)
-            unfullscreen();
-        else
-            fullscreen();
-    });
-    menu.add_action("window_toggle_tabs", [] {
-        Notebook::get().toggle_tabs();
-    });
-    menu.add_action("window_clear_terminal", [] {
-        Terminal::get().clear();
-    });
-
-    menu.toggle_menu_items = [] {
-        auto &menu = Menu::get();
-        auto view = Notebook::get().get_current_view();
-
-        menu.actions["file_reload_file"]->set_enabled(view);
-        menu.actions["source_spellcheck"]->set_enabled(view);
-        menu.actions["source_spellcheck_clear"]->set_enabled(view);
-        menu.actions["source_spellcheck_next_error"]->set_enabled(view);
-        menu.actions["source_git_next_diff"]->set_enabled(view);
-        menu.actions["source_git_show_diff"]->set_enabled(view);
-        menu.actions["source_indentation_set_buffer_tab"]->set_enabled(view);
-        menu.actions["source_goto_line"]->set_enabled(view);
-        menu.actions["source_center_cursor"]->set_enabled(view);
-
-        menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && view->format_style);
-        menu.actions["source_comments_toggle"]->set_enabled(view && view->toggle_comments);
-        menu.actions["source_comments_add_documentation"]->set_enabled(view && view->get_documentation_template);
-        menu.actions["source_find_documentation"]->set_enabled(view && view->get_token_data);
-        menu.actions["source_goto_declaration"]->set_enabled(view && view->get_declaration_location);
-        menu.actions["source_goto_type_declaration"]->set_enabled(view && view->get_type_declaration_location);
-        menu.actions["source_goto_implementation"]->set_enabled(view && view->get_implementation_locations);
-        menu.actions["source_goto_declaration_or_implementation"]->set_enabled(
-                view && view->get_declaration_or_implementation_locations);
-        menu.actions["source_goto_usage"]->set_enabled(view && view->get_usages);
-        menu.actions["source_goto_method"]->set_enabled(view && view->get_methods);
-        menu.actions["source_rename"]->set_enabled(view && view->rename_similar_tokens);
-        menu.actions["source_implement_method"]->set_enabled(view && view->get_method);
-        menu.actions["source_goto_next_diagnostic"]->set_enabled(view && view->goto_next_diagnostic);
-        menu.actions["source_apply_fix_its"]->set_enabled(view && view->get_fix_its);
+  menu.add_action("window_next_tab", []() {
+    Notebook::get().next();
+  });
+  menu.add_action("window_previous_tab", []() {
+    Notebook::get().previous();
+  });
+  menu.add_action("window_close_tab", []() {
+    if (Notebook::get().get_current_view())
+      Notebook::get().close_current();
+  });
+  menu.add_action("window_toggle_split", [] {
+    Notebook::get().toggle_split();
+  });
+  menu.add_action("window_toggle_full_screen", [this] {
+    if (this->get_window()->get_state() & Gdk::WindowState::WINDOW_STATE_FULLSCREEN)
+      unfullscreen();
+    else
+      fullscreen();
+  });
+  menu.add_action("window_toggle_tabs", [] {
+    Notebook::get().toggle_tabs();
+  });
+  menu.add_action("window_clear_terminal", [] {
+    Terminal::get().clear();
+  });
+
+  menu.toggle_menu_items = [] {
+    auto &menu = Menu::get();
+    auto view = Notebook::get().get_current_view();
+
+    menu.actions["file_reload_file"]->set_enabled(view);
+    menu.actions["source_spellcheck"]->set_enabled(view);
+    menu.actions["source_spellcheck_clear"]->set_enabled(view);
+    menu.actions["source_spellcheck_next_error"]->set_enabled(view);
+    menu.actions["source_git_next_diff"]->set_enabled(view);
+    menu.actions["source_git_show_diff"]->set_enabled(view);
+    menu.actions["source_indentation_set_buffer_tab"]->set_enabled(view);
+    menu.actions["source_goto_line"]->set_enabled(view);
+    menu.actions["source_center_cursor"]->set_enabled(view);
+
+    menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && view->format_style);
+    menu.actions["source_comments_toggle"]->set_enabled(view && view->toggle_comments);
+    menu.actions["source_comments_add_documentation"]->set_enabled(view && view->get_documentation_template);
+    menu.actions["source_find_documentation"]->set_enabled(view && view->get_token_data);
+    menu.actions["source_goto_declaration"]->set_enabled(view && view->get_declaration_location);
+    menu.actions["source_goto_type_declaration"]->set_enabled(view && view->get_type_declaration_location);
+    menu.actions["source_goto_implementation"]->set_enabled(view && view->get_implementation_locations);
+    menu.actions["source_goto_declaration_or_implementation"]->set_enabled(
+        view && view->get_declaration_or_implementation_locations);
+    menu.actions["source_goto_usage"]->set_enabled(view && view->get_usages);
+    menu.actions["source_goto_method"]->set_enabled(view && view->get_methods);
+    menu.actions["source_rename"]->set_enabled(view && view->rename_similar_tokens);
+    menu.actions["source_implement_method"]->set_enabled(view && view->get_method);
+    menu.actions["source_goto_next_diagnostic"]->set_enabled(view && view->goto_next_diagnostic);
+    menu.actions["source_apply_fix_its"]->set_enabled(view && view->get_fix_its);
 #ifdef JUCI_ENABLE_DEBUG
-        Project::debug_activate_menu_items();
+    Project::debug_activate_menu_items();
 #endif
-    };
+  };
 }
 
 void Window::add_widgets() {
-    auto directories_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());
-    directories_scrolled_window->add(Directories::get());
-
-    auto notebook_vbox = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-    notebook_vbox->pack_start(Notebook::get());
-    notebook_vbox->pack_end(EntryBox::get(), Gtk::PACK_SHRINK);
-
-    auto terminal_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());
-    terminal_scrolled_window->add(Terminal::get());
-
-    int width, height;
-    get_default_size(width, height);
-
-    auto notebook_and_terminal_vpaned = Gtk::manage(new Gtk::Paned(Gtk::Orientation::ORIENTATION_VERTICAL));
-    notebook_and_terminal_vpaned->set_position(static_cast<int>(0.75 * height));
-    notebook_and_terminal_vpaned->pack1(*notebook_vbox, Gtk::SHRINK);
-    notebook_and_terminal_vpaned->pack2(*terminal_scrolled_window, Gtk::SHRINK);
-
-    auto hpaned = Gtk::manage(new Gtk::Paned());
-    hpaned->set_position(static_cast<int>(0.2 * width));
-    hpaned->pack1(*directories_scrolled_window, Gtk::SHRINK);
-    hpaned->pack2(*notebook_and_terminal_vpaned, Gtk::SHRINK);
-
-    auto status_hbox = Gtk::manage(new Gtk::Box());
-    status_hbox->set_homogeneous(true);
-    status_hbox->pack_start(*Gtk::manage(new Gtk::Box()));
-    auto status_right_hbox = Gtk::manage(new Gtk::Box());
-    status_right_hbox->pack_end(Notebook::get().status_state, Gtk::PACK_SHRINK);
-    auto status_right_overlay = Gtk::manage(new Gtk::Overlay());
-    status_right_overlay->add(*status_right_hbox);
-    status_right_overlay->add_overlay(Notebook::get().status_diagnostics);
-    status_hbox->pack_end(*status_right_overlay);
-
-    auto status_overlay = Gtk::manage(new Gtk::Overlay());
-    status_overlay->add(*status_hbox);
-    auto status_file_info_hbox = Gtk::manage(new Gtk::Box);
-    status_file_info_hbox->pack_start(Notebook::get().status_file_path, Gtk::PACK_SHRINK);
-    status_file_info_hbox->pack_start(Notebook::get().status_branch, Gtk::PACK_SHRINK);
-    status_file_info_hbox->pack_start(Notebook::get().status_location, Gtk::PACK_SHRINK);
-    status_overlay->add_overlay(*status_file_info_hbox);
-    status_overlay->add_overlay(Project::debug_status_label());
-
-    auto vbox = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-    vbox->pack_start(*hpaned);
-    vbox->pack_start(*status_overlay, Gtk::PACK_SHRINK);
-
-    auto overlay_vbox = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
-    auto overlay_hbox = Gtk::manage(new Gtk::Box());
-    overlay_vbox->set_hexpand(false);
-    overlay_vbox->set_halign(Gtk::Align::ALIGN_START);
-    overlay_vbox->pack_start(Info::get(), Gtk::PACK_SHRINK, 20);
-    overlay_hbox->set_hexpand(false);
-    overlay_hbox->set_halign(Gtk::Align::ALIGN_END);
-    overlay_hbox->pack_end(*overlay_vbox, Gtk::PACK_SHRINK, 20);
-
-    auto overlay = Gtk::manage(new Gtk::Overlay());
-    overlay->add(*vbox);
-    overlay->add_overlay(*overlay_hbox);
-    overlay->set_overlay_pass_through(*overlay_hbox, true);
-    add(*overlay);
-
-    show_all_children();
-    Info::get().hide();
-
-    //Scroll to end of terminal whenever info is printed
-    Terminal::get().signal_size_allocate().connect([terminal_scrolled_window](Gtk::Allocation &allocation) {
-        auto adjustment = terminal_scrolled_window->get_vadjustment();
-        adjustment->set_value(adjustment->get_upper() - adjustment->get_page_size());
-        Terminal::get().queue_draw();
-    });
-
-    EntryBox::get().signal_show().connect([hpaned, notebook_and_terminal_vpaned, notebook_vbox]() {
-        hpaned->set_focus_chain({notebook_and_terminal_vpaned});
-        notebook_and_terminal_vpaned->set_focus_chain({notebook_vbox});
-        notebook_vbox->set_focus_chain({&EntryBox::get()});
-    });
-    EntryBox::get().signal_hide().connect([hpaned, notebook_and_terminal_vpaned, notebook_vbox]() {
-        hpaned->unset_focus_chain();
-        notebook_and_terminal_vpaned->unset_focus_chain();
-        notebook_vbox->unset_focus_chain();
-    });
+  auto directories_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());
+  directories_scrolled_window->add(Directories::get());
+
+  auto notebook_vbox = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+  notebook_vbox->pack_start(Notebook::get());
+  notebook_vbox->pack_end(EntryBox::get(), Gtk::PACK_SHRINK);
+
+  auto terminal_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());
+  terminal_scrolled_window->add(Terminal::get());
+
+  int width, height;
+  get_default_size(width, height);
+
+  auto notebook_and_terminal_vpaned = Gtk::manage(new Gtk::Paned(Gtk::Orientation::ORIENTATION_VERTICAL));
+  notebook_and_terminal_vpaned->set_position(static_cast<int>(0.75 * height));
+  notebook_and_terminal_vpaned->pack1(*notebook_vbox, Gtk::SHRINK);
+  notebook_and_terminal_vpaned->pack2(*terminal_scrolled_window, Gtk::SHRINK);
+
+  auto hpaned = Gtk::manage(new Gtk::Paned());
+  hpaned->set_position(static_cast<int>(0.2 * width));
+  hpaned->pack1(*directories_scrolled_window, Gtk::SHRINK);
+  hpaned->pack2(*notebook_and_terminal_vpaned, Gtk::SHRINK);
+
+  auto status_hbox = Gtk::manage(new Gtk::Box());
+  status_hbox->set_homogeneous(true);
+  status_hbox->pack_start(*Gtk::manage(new Gtk::Box()));
+  auto status_right_hbox = Gtk::manage(new Gtk::Box());
+  status_right_hbox->pack_end(Notebook::get().status_state, Gtk::PACK_SHRINK);
+  auto status_right_overlay = Gtk::manage(new Gtk::Overlay());
+  status_right_overlay->add(*status_right_hbox);
+  status_right_overlay->add_overlay(Notebook::get().status_diagnostics);
+  status_hbox->pack_end(*status_right_overlay);
+
+  auto status_overlay = Gtk::manage(new Gtk::Overlay());
+  status_overlay->add(*status_hbox);
+  auto status_file_info_hbox = Gtk::manage(new Gtk::Box);
+  status_file_info_hbox->pack_start(Notebook::get().status_file_path, Gtk::PACK_SHRINK);
+  status_file_info_hbox->pack_start(Notebook::get().status_branch, Gtk::PACK_SHRINK);
+  status_file_info_hbox->pack_start(Notebook::get().status_location, Gtk::PACK_SHRINK);
+  status_overlay->add_overlay(*status_file_info_hbox);
+  status_overlay->add_overlay(Project::debug_status_label());
+
+  auto vbox = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+  vbox->pack_start(*hpaned);
+  vbox->pack_start(*status_overlay, Gtk::PACK_SHRINK);
+
+  auto overlay_vbox = Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
+  auto overlay_hbox = Gtk::manage(new Gtk::Box());
+  overlay_vbox->set_hexpand(false);
+  overlay_vbox->set_halign(Gtk::Align::ALIGN_START);
+  overlay_vbox->pack_start(Info::get(), Gtk::PACK_SHRINK, 20);
+  overlay_hbox->set_hexpand(false);
+  overlay_hbox->set_halign(Gtk::Align::ALIGN_END);
+  overlay_hbox->pack_end(*overlay_vbox, Gtk::PACK_SHRINK, 20);
+
+  auto overlay = Gtk::manage(new Gtk::Overlay());
+  overlay->add(*vbox);
+  overlay->add_overlay(*overlay_hbox);
+  overlay->set_overlay_pass_through(*overlay_hbox, true);
+  add(*overlay);
+
+  show_all_children();
+  Info::get().hide();
+
+  //Scroll to end of terminal whenever info is printed
+  Terminal::get().signal_size_allocate().connect([terminal_scrolled_window](Gtk::Allocation &allocation) {
+    auto adjustment = terminal_scrolled_window->get_vadjustment();
+    adjustment->set_value(adjustment->get_upper() - adjustment->get_page_size());
+    Terminal::get().queue_draw();
+  });
+
+  EntryBox::get().signal_show().connect([hpaned, notebook_and_terminal_vpaned, notebook_vbox]() {
+    hpaned->set_focus_chain({notebook_and_terminal_vpaned});
+    notebook_and_terminal_vpaned->set_focus_chain({notebook_vbox});
+    notebook_vbox->set_focus_chain({&EntryBox::get()});
+  });
+  EntryBox::get().signal_hide().connect([hpaned, notebook_and_terminal_vpaned, notebook_vbox]() {
+    hpaned->unset_focus_chain();
+    notebook_and_terminal_vpaned->unset_focus_chain();
+    notebook_vbox->unset_focus_chain();
+  });
 }
 
 bool Window::on_key_press_event(GdkEventKey *event) {
-    if (event->keyval == GDK_KEY_Escape) {
-        EntryBox::get().hide();
-    }
+  if (event->keyval == GDK_KEY_Escape) {
+    EntryBox::get().hide();
+  }
 #ifdef __APPLE__ //For Apple's Command-left, right, up, down keys
-    else if((event->state & GDK_META_MASK)>0 && (event->state & GDK_MOD1_MASK)==0) {
-      if(event->keyval==GDK_KEY_Left || event->keyval==GDK_KEY_KP_Left) {
-        event->keyval=GDK_KEY_Home;
-        event->state=event->state & GDK_SHIFT_MASK;
-        event->hardware_keycode=115;
-      }
-      else if(event->keyval==GDK_KEY_Right || event->keyval==GDK_KEY_KP_Right) {
-        event->keyval=GDK_KEY_End;
-        event->state=event->state & GDK_SHIFT_MASK;
-        event->hardware_keycode=119;
-      }
-      else if(event->keyval==GDK_KEY_Up || event->keyval==GDK_KEY_KP_Up) {
-        event->keyval=GDK_KEY_Home;
-        event->state=event->state & GDK_SHIFT_MASK;
-        event->state+=GDK_CONTROL_MASK;
-        event->hardware_keycode=115;
-      }
-      else if(event->keyval==GDK_KEY_Down || event->keyval==GDK_KEY_KP_Down) {
-        event->keyval=GDK_KEY_End;
-        event->state=event->state & GDK_SHIFT_MASK;
-        event->state+=GDK_CONTROL_MASK;
-        event->hardware_keycode=119;
-      }
+  else if((event->state & GDK_META_MASK)>0 && (event->state & GDK_MOD1_MASK)==0) {
+    if(event->keyval==GDK_KEY_Left || event->keyval==GDK_KEY_KP_Left) {
+      event->keyval=GDK_KEY_Home;
+      event->state=event->state & GDK_SHIFT_MASK;
+      event->hardware_keycode=115;
+    }
+    else if(event->keyval==GDK_KEY_Right || event->keyval==GDK_KEY_KP_Right) {
+      event->keyval=GDK_KEY_End;
+      event->state=event->state & GDK_SHIFT_MASK;
+      event->hardware_keycode=119;
+    }
+    else if(event->keyval==GDK_KEY_Up || event->keyval==GDK_KEY_KP_Up) {
+      event->keyval=GDK_KEY_Home;
+      event->state=event->state & GDK_SHIFT_MASK;
+      event->state+=GDK_CONTROL_MASK;
+      event->hardware_keycode=115;
     }
+    else if(event->keyval==GDK_KEY_Down || event->keyval==GDK_KEY_KP_Down) {
+      event->keyval=GDK_KEY_End;
+      event->state=event->state & GDK_SHIFT_MASK;
+      event->state+=GDK_CONTROL_MASK;
+      event->hardware_keycode=119;
+    }
+  }
 #endif
 
-    if (SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
-        if (SelectionDialog::get()->on_key_press(event))
-            return true;
-    }
+  if (SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
+    if (SelectionDialog::get()->on_key_press(event))
+      return true;
+  }
 
-    return Gtk::ApplicationWindow::on_key_press_event(event);
+  return Gtk::ApplicationWindow::on_key_press_event(event);
 }
 
 bool Window::on_delete_event(GdkEventAny *event) {
-    save_session();
+  save_session();
 
-    for (size_t c = Notebook::get().size() - 1; c != static_cast<size_t>(-1); --c) {
-        if (!Notebook::get().close(c))
-            return true;
-    }
-    Terminal::get().kill_async_processes();
+  for (size_t c = Notebook::get().size() - 1; c != static_cast<size_t>(-1); --c) {
+    if (!Notebook::get().close(c))
+      return true;
+  }
+  Terminal::get().kill_async_processes();
 #ifdef JUCI_ENABLE_DEBUG
-    if(Project::current)
-      Project::current->debug_cancel();
+  if(Project::current)
+    Project::current->debug_cancel();
 #endif
 
-    return false;
+  return false;
 }
 
 void Window::search_and_replace_entry() {
-    EntryBox::get().clear();
-    EntryBox::get().labels.emplace_back();
-    auto label_it = EntryBox::get().labels.begin();
-    label_it->update = [label_it](int state, const std::string &message) {
-        if (state == 0) {
-            try {
-                auto number = stoi(message);
-                if (number == 0)
-                    label_it->set_text("");
-                else if (number == 1)
-                    label_it->set_text("1 result found");
-                else if (number > 1)
-                    label_it->set_text(message + " results found");
-            }
-            catch (const std::exception &e) {}
-        }
+  EntryBox::get().clear();
+  EntryBox::get().labels.emplace_back();
+  auto label_it = EntryBox::get().labels.begin();
+  label_it->update = [label_it](int state, const std::string &message) {
+    if (state == 0) {
+      try {
+        auto number = stoi(message);
+        if (number == 0)
+          label_it->set_text("");
+        else if (number == 1)
+          label_it->set_text("1 result found");
+        else if (number > 1)
+          label_it->set_text(message + " results found");
+      }
+      catch (const std::exception &e) {}
+    }
+  };
+  EntryBox::get().entries.emplace_back(last_search, [](const std::string &content) {
+    if (auto view = Notebook::get().get_current_view())
+      view->search_forward();
+  });
+  auto search_entry_it = EntryBox::get().entries.begin();
+  search_entry_it->set_placeholder_text("Find");
+  if (auto view = Notebook::get().get_current_view()) {
+    view->update_search_occurrences = [label_it](int number) {
+      label_it->update(0, std::to_string(number));
     };
-    EntryBox::get().entries.emplace_back(last_search, [](const std::string &content) {
-        if (auto view = Notebook::get().get_current_view())
-            view->search_forward();
-    });
-    auto search_entry_it = EntryBox::get().entries.begin();
-    search_entry_it->set_placeholder_text("Find");
+    view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
+  }
+  search_entry_it->signal_key_press_event().connect([](GdkEventKey *event) {
+    if ((event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) &&
+        (event->state & GDK_SHIFT_MASK) > 0) {
+      if (auto view = Notebook::get().get_current_view())
+        view->search_backward();
+    }
+    return false;
+  });
+  search_entry_it->signal_changed().connect([this, search_entry_it]() {
+    last_search = search_entry_it->get_text();
+    if (auto view = Notebook::get().get_current_view())
+      view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
+  });
+
+  EntryBox::get().entries.emplace_back(last_replace, [](const std::string &content) {
+    if (auto view = Notebook::get().get_current_view())
+      view->replace_forward(content);
+  });
+  auto replace_entry_it = EntryBox::get().entries.begin();
+  replace_entry_it++;
+  replace_entry_it->set_placeholder_text("Replace");
+  replace_entry_it->signal_key_press_event().connect([replace_entry_it](GdkEventKey *event) {
+    if ((event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) &&
+        (event->state & GDK_SHIFT_MASK) > 0) {
+      if (auto view = Notebook::get().get_current_view())
+        view->replace_backward(replace_entry_it->get_text());
+    }
+    return false;
+  });
+  replace_entry_it->signal_changed().connect([this, replace_entry_it]() {
+    last_replace = replace_entry_it->get_text();
+  });
+
+  EntryBox::get().buttons.emplace_back("↑", []() {
+    if (auto view = Notebook::get().get_current_view())
+      view->search_backward();
+  });
+  EntryBox::get().buttons.back().set_tooltip_text("Find Previous\n\nShortcut: Shift+Enter in the Find entry field");
+  EntryBox::get().buttons.emplace_back("⇄", [replace_entry_it]() {
     if (auto view = Notebook::get().get_current_view()) {
-        view->update_search_occurrences = [label_it](int number) {
-            label_it->update(0, std::to_string(number));
-        };
-        view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
-    }
-    search_entry_it->signal_key_press_event().connect([](GdkEventKey *event) {
-        if ((event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) &&
-            (event->state & GDK_SHIFT_MASK) > 0) {
-            if (auto view = Notebook::get().get_current_view())
-                view->search_backward();
+      view->replace_forward(replace_entry_it->get_text());
+    }
+  });
+  EntryBox::get().buttons.back().set_tooltip_text("Replace Next\n\nShortcut: Enter in the Replace entry field");
+  EntryBox::get().buttons.emplace_back("↓", []() {
+    if (auto view = Notebook::get().get_current_view())
+      view->search_forward();
+  });
+  EntryBox::get().buttons.back().set_tooltip_text("Find Next\n\nShortcut: Enter in the Find entry field");
+  EntryBox::get().buttons.emplace_back("Replace All", [replace_entry_it]() {
+    if (auto view = Notebook::get().get_current_view())
+      view->replace_all(replace_entry_it->get_text());
+  });
+  EntryBox::get().buttons.back().set_tooltip_text("Replace All");
+
+  EntryBox::get().toggle_buttons.emplace_back("Aa");
+  EntryBox::get().toggle_buttons.back().set_tooltip_text("Match Case");
+  EntryBox::get().toggle_buttons.back().set_active(case_sensitive_search);
+  EntryBox::get().toggle_buttons.back().on_activate = [this, search_entry_it]() {
+    case_sensitive_search = !case_sensitive_search;
+    if (auto view = Notebook::get().get_current_view())
+      view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
+  };
+  EntryBox::get().toggle_buttons.emplace_back(".*");
+  EntryBox::get().toggle_buttons.back().set_tooltip_text("Use Regex");
+  EntryBox::get().toggle_buttons.back().set_active(regex_search);
+  EntryBox::get().toggle_buttons.back().on_activate = [this, search_entry_it]() {
+    regex_search = !regex_search;
+    if (auto view = Notebook::get().get_current_view())
+      view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
+  };
+  EntryBox::get().signal_hide().connect([this]() {
+    for (size_t c = 0; c < Notebook::get().size(); c++) {
+      Notebook::get().get_view(c)->update_search_occurrences = nullptr;
+      Notebook::get().get_view(c)->search_highlight("", case_sensitive_search, regex_search);
+    }
+    search_entry_shown = false;
+  });
+  search_entry_shown = true;
+  EntryBox::get().show();
+}
+
+void Window::set_tab_entry() {
+  EntryBox::get().clear();
+  if (auto view = Notebook::get().get_current_view()) {
+    auto tab_char_and_size = view->get_tab_char_and_size();
+
+    EntryBox::get().labels.emplace_back();
+    auto label_it = EntryBox::get().labels.begin();
+
+    EntryBox::get().entries.emplace_back(std::to_string(tab_char_and_size.second));
+    auto entry_tab_size_it = EntryBox::get().entries.begin();
+    entry_tab_size_it->set_placeholder_text("Tab size");
+
+    char tab_char = tab_char_and_size.first;
+    std::string tab_char_string;
+    if (tab_char == ' ')
+      tab_char_string = "space";
+    else if (tab_char == '\t')
+      tab_char_string = "tab";
+
+    EntryBox::get().entries.emplace_back(tab_char_string);
+    auto entry_tab_char_it = EntryBox::get().entries.rbegin();
+    entry_tab_char_it->set_placeholder_text("Tab char");
+
+    const auto activate_function = [entry_tab_char_it, entry_tab_size_it, label_it](const std::string &content) {
+      if (auto view = Notebook::get().get_current_view()) {
+        char tab_char = 0;
+        unsigned tab_size = 0;
+        try {
+          tab_size = static_cast<unsigned>(std::stoul(entry_tab_size_it->get_text()));
+          std::string tab_char_string = entry_tab_char_it->get_text();
+          std::transform(tab_char_string.begin(), tab_char_string.end(), tab_char_string.begin(), ::tolower);
+          if (tab_char_string == "space")
+            tab_char = ' ';
+          else if (tab_char_string == "tab")
+            tab_char = '\t';
         }
-        return false;
-    });
-    search_entry_it->signal_changed().connect([this, search_entry_it]() {
-        last_search = search_entry_it->get_text();
-        if (auto view = Notebook::get().get_current_view())
-            view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
-    });
+        catch (const std::exception &e) {}
 
-    EntryBox::get().entries.emplace_back(last_replace, [](const std::string &content) {
-        if (auto view = Notebook::get().get_current_view())
-            view->replace_forward(content);
-    });
-    auto replace_entry_it = EntryBox::get().entries.begin();
-    replace_entry_it++;
-    replace_entry_it->set_placeholder_text("Replace");
-    replace_entry_it->signal_key_press_event().connect([replace_entry_it](GdkEventKey *event) {
-        if ((event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) &&
-            (event->state & GDK_SHIFT_MASK) > 0) {
-            if (auto view = Notebook::get().get_current_view())
-                view->replace_backward(replace_entry_it->get_text());
+        if (tab_char != 0 && tab_size > 0) {
+          view->set_tab_char_and_size(tab_char, tab_size);
+          EntryBox::get().hide();
+        } else {
+          label_it->set_text("Tab size must be >0 and tab char set to either 'space' or 'tab'");
         }
-        return false;
-    });
-    replace_entry_it->signal_changed().connect([this, replace_entry_it]() {
-        last_replace = replace_entry_it->get_text();
-    });
+      }
+    };
 
-    EntryBox::get().buttons.emplace_back("↑", []() {
-        if (auto view = Notebook::get().get_current_view())
-            view->search_backward();
+    entry_tab_char_it->on_activate = activate_function;
+    entry_tab_size_it->on_activate = activate_function;
+
+    EntryBox::get().buttons.emplace_back("Set tab in current buffer", [entry_tab_char_it]() {
+      entry_tab_char_it->activate();
     });
-    EntryBox::get().buttons.back().set_tooltip_text("Find Previous\n\nShortcut: Shift+Enter in the Find entry field");
-    EntryBox::get().buttons.emplace_back("⇄", [replace_entry_it]() {
-        if (auto view = Notebook::get().get_current_view()) {
-            view->replace_forward(replace_entry_it->get_text());
+
+    EntryBox::get().show();
+  }
+}
+
+void Window::goto_line_entry() {
+  EntryBox::get().clear();
+  if (Notebook::get().get_current_view()) {
+    EntryBox::get().entries.emplace_back("", [](const std::string &content) {
+      if (auto view = Notebook::get().get_current_view()) {
+        try {
+          view->place_cursor_at_line_index(stoi(content) - 1, 0);
+          view->scroll_to_cursor_delayed(view, true, false);
         }
+        catch (const std::exception &e) {}
+        EntryBox::get().hide();
+      }
     });
-    EntryBox::get().buttons.back().set_tooltip_text("Replace Next\n\nShortcut: Enter in the Replace entry field");
-    EntryBox::get().buttons.emplace_back("↓", []() {
-        if (auto view = Notebook::get().get_current_view())
-            view->search_forward();
-    });
-    EntryBox::get().buttons.back().set_tooltip_text("Find Next\n\nShortcut: Enter in the Find entry field");
-    EntryBox::get().buttons.emplace_back("Replace All", [replace_entry_it]() {
-        if (auto view = Notebook::get().get_current_view())
-            view->replace_all(replace_entry_it->get_text());
-    });
-    EntryBox::get().buttons.back().set_tooltip_text("Replace All");
-
-    EntryBox::get().toggle_buttons.emplace_back("Aa");
-    EntryBox::get().toggle_buttons.back().set_tooltip_text("Match Case");
-    EntryBox::get().toggle_buttons.back().set_active(case_sensitive_search);
-    EntryBox::get().toggle_buttons.back().on_activate = [this, search_entry_it]() {
-        case_sensitive_search = !case_sensitive_search;
-        if (auto view = Notebook::get().get_current_view())
-            view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
-    };
-    EntryBox::get().toggle_buttons.emplace_back(".*");
-    EntryBox::get().toggle_buttons.back().set_tooltip_text("Use Regex");
-    EntryBox::get().toggle_buttons.back().set_active(regex_search);
-    EntryBox::get().toggle_buttons.back().on_activate = [this, search_entry_it]() {
-        regex_search = !regex_search;
-        if (auto view = Notebook::get().get_current_view())
-            view->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
-    };
-    EntryBox::get().signal_hide().connect([this]() {
-        for (size_t c = 0; c < Notebook::get().size(); c++) {
-            Notebook::get().get_view(c)->update_search_occurrences = nullptr;
-            Notebook::get().get_view(c)->search_highlight("", case_sensitive_search, regex_search);
-        }
-        search_entry_shown = false;
+    auto entry_it = EntryBox::get().entries.begin();
+    entry_it->set_placeholder_text("Line number");
+    EntryBox::get().buttons.emplace_back("Go to line", [entry_it]() {
+      entry_it->activate();
     });
-    search_entry_shown = true;
     EntryBox::get().show();
+  }
 }
 
-void Window::set_tab_entry() {
-    EntryBox::get().clear();
-    if (auto view = Notebook::get().get_current_view()) {
-        auto tab_char_and_size = view->get_tab_char_and_size();
-
-        EntryBox::get().labels.emplace_back();
-        auto label_it = EntryBox::get().labels.begin();
-
-        EntryBox::get().entries.emplace_back(std::to_string(tab_char_and_size.second));
-        auto entry_tab_size_it = EntryBox::get().entries.begin();
-        entry_tab_size_it->set_placeholder_text("Tab size");
-
-        char tab_char = tab_char_and_size.first;
-        std::string tab_char_string;
-        if (tab_char == ' ')
-            tab_char_string = "space";
-        else if (tab_char == '\t')
-            tab_char_string = "tab";
-
-        EntryBox::get().entries.emplace_back(tab_char_string);
-        auto entry_tab_char_it = EntryBox::get().entries.rbegin();
-        entry_tab_char_it->set_placeholder_text("Tab char");
-
-        const auto activate_function = [entry_tab_char_it, entry_tab_size_it, label_it](const std::string &content) {
-            if (auto view = Notebook::get().get_current_view()) {
-                char tab_char = 0;
-                unsigned tab_size = 0;
-                try {
-                    tab_size = static_cast<unsigned>(std::stoul(entry_tab_size_it->get_text()));
-                    std::string tab_char_string = entry_tab_char_it->get_text();
-                    std::transform(tab_char_string.begin(), tab_char_string.end(), tab_char_string.begin(), ::tolower);
-                    if (tab_char_string == "space")
-                        tab_char = ' ';
-                    else if (tab_char_string == "tab")
-                        tab_char = '\t';
-                }
-                catch (const std::exception &e) {}
-
-                if (tab_char != 0 && tab_size > 0) {
-                    view->set_tab_char_and_size(tab_char, tab_size);
-                    EntryBox::get().hide();
-                } else {
-                    label_it->set_text("Tab size must be >0 and tab char set to either 'space' or 'tab'");
-                }
-            }
-        };
-
-        entry_tab_char_it->on_activate = activate_function;
-        entry_tab_size_it->on_activate = activate_function;
-
-        EntryBox::get().buttons.emplace_back("Set tab in current buffer", [entry_tab_char_it]() {
-            entry_tab_char_it->activate();
+void Window::rename_token_entry() {
+  EntryBox::get().clear();
+  if (auto view = Notebook::get().get_current_view()) {
+    if (view->get_token_spelling && view->rename_similar_tokens) {
+      auto spelling = std::make_shared<std::string>(view->get_token_spelling());
+      if (!spelling->empty()) {
+        EntryBox::get().entries.emplace_back(*spelling,
+                                             [view, spelling, iter = view->get_buffer()->get_insert()->get_iter()](
+                                                 const std::string &content) {
+                                               //TODO: gtk needs a way to check if iter is valid without dumping g_error message
+                                               //iter->get_buffer() will print such a message, but no segfault will occur
+                                               if (Notebook::get().get_current_view() == view &&
+                                                   content != *spelling && iter.get_buffer() &&
+                                                   view->get_buffer()->get_insert()->get_iter() == iter)
+                                                 view->rename_similar_tokens(content);
+                                               else
+                                                 Info::get().print("Operation canceled");
+                                               EntryBox::get().hide();
+                                             });
+        auto entry_it = EntryBox::get().entries.begin();
+        entry_it->set_placeholder_text("New name");
+        EntryBox::get().buttons.emplace_back("Rename", [entry_it]() {
+          entry_it->activate();
         });
-
         EntryBox::get().show();
+      }
     }
+  }
 }
 
-void Window::goto_line_entry() {
-    EntryBox::get().clear();
-    if (Notebook::get().get_current_view()) {
-        EntryBox::get().entries.emplace_back("", [](const std::string &content) {
-            if (auto view = Notebook::get().get_current_view()) {
-                try {
-                    view->place_cursor_at_line_index(stoi(content) - 1, 0);
-                    view->scroll_to_cursor_delayed(view, true, false);
-                }
-                catch (const std::exception &e) {}
-                EntryBox::get().hide();
-            }
-        });
-        auto entry_it = EntryBox::get().entries.begin();
-        entry_it->set_placeholder_text("Line number");
-        EntryBox::get().buttons.emplace_back("Go to line", [entry_it]() {
-            entry_it->activate();
-        });
-        EntryBox::get().show();
+void Window::save_session() {
+  try {
+    boost::property_tree::ptree root_pt;
+    root_pt.put("folder", Directories::get().path.string());
+
+    boost::property_tree::ptree files_pt;
+    for (auto &notebook_view: Notebook::get().get_notebook_views()) {
+      boost::property_tree::ptree file_pt;
+      file_pt.put("path", notebook_view.second->file_path.string());
+      file_pt.put("notebook", notebook_view.first);
+      auto iter = notebook_view.second->get_buffer()->get_insert()->get_iter();
+      file_pt.put("line", iter.get_line());
+      file_pt.put("line_offset", iter.get_line_offset());
+      files_pt.push_back(std::make_pair("", file_pt));
     }
-}
+    root_pt.add_child("files", files_pt);
 
-void Window::rename_token_entry() {
-    EntryBox::get().clear();
+    boost::property_tree::ptree current_file_pt;
     if (auto view = Notebook::get().get_current_view()) {
-        if (view->get_token_spelling && view->rename_similar_tokens) {
-            auto spelling = std::make_shared<std::string>(view->get_token_spelling());
-            if (!spelling->empty()) {
-                EntryBox::get().entries.emplace_back(*spelling,
-                                                     [view, spelling, iter = view->get_buffer()->get_insert()->get_iter()](
-                                                             const std::string &content) {
-                                                         //TODO: gtk needs a way to check if iter is valid without dumping g_error message
-                                                         //iter->get_buffer() will print such a message, but no segfault will occur
-                                                         if (Notebook::get().get_current_view() == view &&
-                                                             content != *spelling && iter.get_buffer() &&
-                                                             view->get_buffer()->get_insert()->get_iter() == iter)
-                                                             view->rename_similar_tokens(content);
-                                                         else
-                                                             Info::get().print("Operation canceled");
-                                                         EntryBox::get().hide();
-                                                     });
-                auto entry_it = EntryBox::get().entries.begin();
-                entry_it->set_placeholder_text("New name");
-                EntryBox::get().buttons.emplace_back("Rename", [entry_it]() {
-                    entry_it->activate();
-                });
-                EntryBox::get().show();
-            }
-        }
+      current_file_pt.put("path", view->file_path.string());
+      auto iter = view->get_buffer()->get_insert()->get_iter();
+      current_file_pt.put("line", iter.get_line());
+      current_file_pt.put("line_offset", iter.get_line_offset());
     }
-}
-
-void Window::save_session() {
-    try {
-        boost::property_tree::ptree root_pt;
-        root_pt.put("folder", Directories::get().path.string());
-
-        boost::property_tree::ptree files_pt;
-        for (auto &notebook_view: Notebook::get().get_notebook_views()) {
-            boost::property_tree::ptree file_pt;
-            file_pt.put("path", notebook_view.second->file_path.string());
-            file_pt.put("notebook", notebook_view.first);
-            auto iter = notebook_view.second->get_buffer()->get_insert()->get_iter();
-            file_pt.put("line", iter.get_line());
-            file_pt.put("line_offset", iter.get_line_offset());
-            files_pt.push_back(std::make_pair("", file_pt));
-        }
-        root_pt.add_child("files", files_pt);
-
-        boost::property_tree::ptree current_file_pt;
-        if (auto view = Notebook::get().get_current_view()) {
-            current_file_pt.put("path", view->file_path.string());
-            auto iter = view->get_buffer()->get_insert()->get_iter();
-            current_file_pt.put("line", iter.get_line());
-            current_file_pt.put("line_offset", iter.get_line_offset());
-        }
-        std::string current_path;
-        if (auto view = Notebook::get().get_current_view())
-            current_path = view->file_path.string();
-        root_pt.put("current_file", current_path);
-
-        boost::property_tree::ptree run_arguments_pt;
-        for (auto &run_argument: Project::run_arguments) {
-            if (run_argument.second.empty())
-                continue;
-            boost::system::error_code ec;
-            if (boost::filesystem::exists(run_argument.first, ec) &&
-                boost::filesystem::is_directory(run_argument.first, ec)) {
-                boost::property_tree::ptree run_argument_pt;
-                run_argument_pt.put("path", run_argument.first);
-                run_argument_pt.put("arguments", run_argument.second);
-                run_arguments_pt.push_back(std::make_pair("", run_argument_pt));
-            }
-        }
-        root_pt.add_child("run_arguments", run_arguments_pt);
-
-        boost::property_tree::ptree debug_run_arguments_pt;
-        for (auto &debug_run_argument: Project::debug_run_arguments) {
-            if (debug_run_argument.second.arguments.empty() && !debug_run_argument.second.remote_enabled &&
-                debug_run_argument.second.remote_host_port.empty())
-                continue;
-            boost::system::error_code ec;
-            if (boost::filesystem::exists(debug_run_argument.first, ec) &&
-                boost::filesystem::is_directory(debug_run_argument.first, ec)) {
-                boost::property_tree::ptree debug_run_argument_pt;
-                debug_run_argument_pt.put("path", debug_run_argument.first);
-                debug_run_argument_pt.put("arguments", debug_run_argument.second.arguments);
-                debug_run_argument_pt.put("remote_enabled", debug_run_argument.second.remote_enabled);
-                debug_run_argument_pt.put("remote_host_port", debug_run_argument.second.remote_host_port);
-                debug_run_arguments_pt.push_back(std::make_pair("", debug_run_argument_pt));
-            }
-        }
-        root_pt.add_child("debug_run_arguments", debug_run_arguments_pt);
-
-        int width, height;
-        get_size(width, height);
-        boost::property_tree::ptree window_pt;
-        window_pt.put("width", width);
-        window_pt.put("height", height);
-        root_pt.add_child("window", window_pt);
-
-        boost::property_tree::write_json((Config::get().home_juci_path / "last_session.json").string(), root_pt);
+    std::string current_path;
+    if (auto view = Notebook::get().get_current_view())
+      current_path = view->file_path.string();
+    root_pt.put("current_file", current_path);
+
+    boost::property_tree::ptree run_arguments_pt;
+    for (auto &run_argument: Project::run_arguments) {
+      if (run_argument.second.empty())
+        continue;
+      boost::system::error_code ec;
+      if (boost::filesystem::exists(run_argument.first, ec) &&
+          boost::filesystem::is_directory(run_argument.first, ec)) {
+        boost::property_tree::ptree run_argument_pt;
+        run_argument_pt.put("path", run_argument.first);
+        run_argument_pt.put("arguments", run_argument.second);
+        run_arguments_pt.push_back(std::make_pair("", run_argument_pt));
+      }
+    }
+    root_pt.add_child("run_arguments", run_arguments_pt);
+
+    boost::property_tree::ptree debug_run_arguments_pt;
+    for (auto &debug_run_argument: Project::debug_run_arguments) {
+      if (debug_run_argument.second.arguments.empty() && !debug_run_argument.second.remote_enabled &&
+          debug_run_argument.second.remote_host_port.empty())
+        continue;
+      boost::system::error_code ec;
+      if (boost::filesystem::exists(debug_run_argument.first, ec) &&
+          boost::filesystem::is_directory(debug_run_argument.first, ec)) {
+        boost::property_tree::ptree debug_run_argument_pt;
+        debug_run_argument_pt.put("path", debug_run_argument.first);
+        debug_run_argument_pt.put("arguments", debug_run_argument.second.arguments);
+        debug_run_argument_pt.put("remote_enabled", debug_run_argument.second.remote_enabled);
+        debug_run_argument_pt.put("remote_host_port", debug_run_argument.second.remote_host_port);
+        debug_run_arguments_pt.push_back(std::make_pair("", debug_run_argument_pt));
+      }
     }
-    catch (...) {}
+    root_pt.add_child("debug_run_arguments", debug_run_arguments_pt);
+
+    int width, height;
+    get_size(width, height);
+    boost::property_tree::ptree window_pt;
+    window_pt.put("width", width);
+    window_pt.put("height", height);
+    root_pt.add_child("window", window_pt);
+
+    boost::property_tree::write_json((Config::get().home_juci_path / "last_session.json").string(), root_pt);
+  }
+  catch (...) {}
 }
 
 void Window::load_session(std::vector<boost::filesystem::path> &directories,
                           std::vector<std::pair<boost::filesystem::path, size_t> > &files,
                           std::vector<std::pair<int, int> > &file_offsets, std::string &current_file,
                           bool read_directories_and_files) {
-    try {
-        boost::property_tree::ptree root_pt;
-        boost::property_tree::read_json((Config::get().home_juci_path / "last_session.json").string(), root_pt);
-        if (read_directories_and_files) {
-            auto folder = root_pt.get<std::string>("folder");
-            if (!folder.empty() && boost::filesystem::exists(folder) && boost::filesystem::is_directory(folder))
-                directories.emplace_back(folder);
-
-            for (auto &file_pt: root_pt.get_child("files")) {
-                auto file = file_pt.second.get<std::string>("path");
-                auto notebook = file_pt.second.get<size_t>("notebook");
-                auto line = file_pt.second.get<int>("line");
-                auto line_offset = file_pt.second.get<int>("line_offset");
-                if (!file.empty() && boost::filesystem::exists(file) && !boost::filesystem::is_directory(file)) {
-                    files.emplace_back(file, notebook);
-                    file_offsets.emplace_back(line, line_offset);
-                }
-            }
-
-            current_file = root_pt.get<std::string>("current_file");
-        }
-
-        for (auto &run_argument: root_pt.get_child(("run_arguments"))) {
-            auto path = run_argument.second.get<std::string>("path");
-            boost::system::error_code ec;
-            if (boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec))
-                Project::run_arguments.emplace(path, run_argument.second.get<std::string>("arguments"));
+  try {
+    boost::property_tree::ptree root_pt;
+    boost::property_tree::read_json((Config::get().home_juci_path / "last_session.json").string(), root_pt);
+    if (read_directories_and_files) {
+      auto folder = root_pt.get<std::string>("folder");
+      if (!folder.empty() && boost::filesystem::exists(folder) && boost::filesystem::is_directory(folder))
+        directories.emplace_back(folder);
+
+      for (auto &file_pt: root_pt.get_child("files")) {
+        auto file = file_pt.second.get<std::string>("path");
+        auto notebook = file_pt.second.get<size_t>("notebook");
+        auto line = file_pt.second.get<int>("line");
+        auto line_offset = file_pt.second.get<int>("line_offset");
+        if (!file.empty() && boost::filesystem::exists(file) && !boost::filesystem::is_directory(file)) {
+          files.emplace_back(file, notebook);
+          file_offsets.emplace_back(line, line_offset);
         }
+      }
 
-        for (auto &debug_run_argument: root_pt.get_child(("debug_run_arguments"))) {
-            auto path = debug_run_argument.second.get<std::string>("path");
-            boost::system::error_code ec;
-            if (boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec))
-                Project::debug_run_arguments.emplace(path, Project::DebugRunArguments{
-                        debug_run_argument.second.get<std::string>("arguments"),
-                        debug_run_argument.second.get<bool>("remote_enabled"),
-                        debug_run_argument.second.get<std::string>("remote_host_port")});
-        }
+      current_file = root_pt.get<std::string>("current_file");
+    }
 
-        auto window_pt = root_pt.get_child("window");
-        set_default_size(window_pt.get<int>("width"), window_pt.get<int>("height"));
+    for (auto &run_argument: root_pt.get_child(("run_arguments"))) {
+      auto path = run_argument.second.get<std::string>("path");
+      boost::system::error_code ec;
+      if (boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec))
+        Project::run_arguments.emplace(path, run_argument.second.get<std::string>("arguments"));
     }
-    catch (...) {
-        set_default_size(800, 600);
+
+    for (auto &debug_run_argument: root_pt.get_child(("debug_run_arguments"))) {
+      auto path = debug_run_argument.second.get<std::string>("path");
+      boost::system::error_code ec;
+      if (boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec))
+        Project::debug_run_arguments.emplace(path, Project::DebugRunArguments{
+            debug_run_argument.second.get<std::string>("arguments"),
+            debug_run_argument.second.get<bool>("remote_enabled"),
+            debug_run_argument.second.get<std::string>("remote_host_port")});
     }
+
+    auto window_pt = root_pt.get_child("window");
+    set_default_size(window_pt.get<int>("width"), window_pt.get<int>("height"));
+  }
+  catch (...) {
+    set_default_size(800, 600);
+  }
 }
diff --git a/src/window.h b/src/window.h
index 7f9b062e..1aa7e30d 100644
--- a/src/window.h
+++ b/src/window.h
@@ -5,51 +5,51 @@
 #include <boost/filesystem.hpp>
 
 class Window : public Gtk::ApplicationWindow {
-    Window();
+  Window();
 
 public:
-    static Window &get() {
-        static Window singleton;
-        return singleton;
-    }
+  static Window &get() {
+    static Window singleton;
+    return singleton;
+  }
 
-    void add_widgets();
+  void add_widgets();
 
-    void save_session();
+  void save_session();
 
-    void load_session(std::vector<boost::filesystem::path> &directories,
-                      std::vector<std::pair<boost::filesystem::path, size_t>> &files,
-                      std::vector<std::pair<int, int>> &file_offsets, std::string &current_file,
-                      bool read_directories_and_files);
+  void load_session(std::vector<boost::filesystem::path> &directories,
+                    std::vector<std::pair<boost::filesystem::path, size_t>> &files,
+                    std::vector<std::pair<int, int>> &file_offsets, std::string &current_file,
+                    bool read_directories_and_files);
 
 protected:
-    bool on_key_press_event(GdkEventKey *event) override;
+  bool on_key_press_event(GdkEventKey *event) override;
 
-    bool on_delete_event(GdkEventAny *event) override;
+  bool on_delete_event(GdkEventAny *event) override;
 
 private:
-    Gtk::AboutDialog about;
+  Gtk::AboutDialog about;
 
-    Glib::RefPtr<Gtk::CssProvider> css_provider_theme;
-    Glib::RefPtr<Gtk::CssProvider> css_provider_tooltips;
+  Glib::RefPtr<Gtk::CssProvider> css_provider_theme;
+  Glib::RefPtr<Gtk::CssProvider> css_provider_tooltips;
 
-    void configure();
+  void configure();
 
-    void set_menu_actions();
+  void set_menu_actions();
 
-    void search_and_replace_entry();
+  void search_and_replace_entry();
 
-    void set_tab_entry();
+  void set_tab_entry();
 
-    void goto_line_entry();
+  void goto_line_entry();
 
-    void rename_token_entry();
+  void rename_token_entry();
 
-    std::string last_search;
-    std::string last_replace;
-    std::string last_run_command;
-    std::string last_run_debug_command;
-    bool case_sensitive_search = true;
-    bool regex_search = false;
-    bool search_entry_shown = false;
+  std::string last_search;
+  std::string last_replace;
+  std::string last_run_command;
+  std::string last_run_debug_command;
+  bool case_sensitive_search = true;
+  bool regex_search = false;
+  bool search_entry_shown = false;
 };

From dcaf1c42026e4f3da947a009c3bb9f9313a9951d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E4=BA=88=E9=A1=BA?= <ys_37677@126.com>
Date: Mon, 21 May 2018 17:14:07 +0800
Subject: [PATCH 06/12] Idea

---
 .gitignore        | 1 +
 .idea/.name       | 1 +
 .idea/jucipp.iml  | 2 ++
 .idea/misc.xml    | 4 ++++
 .idea/modules.xml | 8 ++++++++
 .idea/vcs.xml     | 8 ++++++++
 6 files changed, 24 insertions(+)
 create mode 100644 .idea/.name
 create mode 100644 .idea/jucipp.iml
 create mode 100644 .idea/misc.xml
 create mode 100644 .idea/modules.xml
 create mode 100644 .idea/vcs.xml

diff --git a/.gitignore b/.gitignore
index 8448ec26..58f0e817 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@
 !config.json
 !*.py
 !debian/*
+!.idea/*
 
 build
 .usages_clang
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 00000000..c2470e11
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+juci
\ No newline at end of file
diff --git a/.idea/jucipp.iml b/.idea/jucipp.iml
new file mode 100644
index 00000000..f08604bb
--- /dev/null
+++ b/.idea/jucipp.iml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module classpath="CMake" type="CPP_MODULE" version="4" />
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..79b3c948
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..b168f94e
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/jucipp.iml" filepath="$PROJECT_DIR$/.idea/jucipp.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..0388d1c5
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+    <mapping directory="$PROJECT_DIR$/libclangmm" vcs="Git" />
+    <mapping directory="$PROJECT_DIR$/tiny-process-library" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file

From 3c23846067021d01263eee4183800fec6d7ae02d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BA=88=E9=A1=BA=20=E5=88=98?= <yshliu0321@icloud.com>
Date: Wed, 23 May 2018 11:39:51 +0800
Subject: [PATCH 07/12] Simplfy Code

---
 src/CMakeLists.txt                       |  2 +-
 src/cmake.cc                             | 43 +++++++-------------
 src/cmake.h                              |  6 +--
 src/ctags.cc                             |  2 +-
 src/{buildsystem.cc => makefile_base.cc} |  6 +--
 src/{buildsystem.h => makefile_base.h}   |  6 +--
 src/meson.cc                             | 18 +++-----
 src/meson.h                              |  4 +-
 src/project.cc                           | 47 ++++++++++-----------
 src/project_build.cc                     | 46 +++++++--------------
 src/project_build.h                      | 52 ++++++++++++++++--------
 src/source_clang.cc                      | 12 +++---
 src/source_language_protocol.cc          | 12 +++---
 src/window.cc                            | 10 ++---
 14 files changed, 123 insertions(+), 143 deletions(-)
 rename src/{buildsystem.cc => makefile_base.cc} (85%)
 rename src/{buildsystem.h => makefile_base.h} (80%)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b988f114..b84b87e9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,6 @@
 # Files used both in ../src and ../tests
 
-file(GLOB JUCI_SRC_BUILDSYSTEMS buildsystem/*.*)
+file(GLOB JUCI_SRC_BUILDSYSTEMS cmake.h cmake.cc meson.h meson.cc makefile_base.h makefile_base.cc)
 
 set(JUCI_SHARED_FILES
         ${JUCI_SRC_BUILDSYSTEMS}
diff --git a/src/cmake.cc b/src/cmake.cc
index 5e9b13e5..cfcc2479 100644
--- a/src/cmake.cc
+++ b/src/cmake.cc
@@ -6,30 +6,24 @@
 #include <regex>
 #include "compile_commands.h"
 
-CMake::CMake(const boost::filesystem::path &path) : BuildSystemBase(path, "CMakeLists.txt") {}
+CMake::CMake(const boost::filesystem::path &path) : MakefileBase(path, "CMakeLists.txt") {}
 
 bool CMake::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
-  if(project_path.empty() || !boost::filesystem::exists(project_path/"CMakeLists.txt") || default_build_path.empty())
+  if(get_project_path().empty() || !boost::filesystem::exists(get_project_path()/"CMakeLists.txt") || default_build_path.empty())
     return false;
-  
-  if(!boost::filesystem::exists(default_build_path)) {
-    boost::system::error_code ec;
-    boost::filesystem::create_directories(default_build_path, ec);
-    if(ec) {
-      Terminal::get().print("Error: could not create "+default_build_path.string()+": "+ec.message()+"\n", true);
-      return false;
-    }
-  }
-  
+
+  if (!create_build_directory(default_build_path)) return false;
+
   if(!force && boost::filesystem::exists(default_build_path/"compile_commands.json"))
     return true;
   
   auto compile_commands_path=default_build_path/"compile_commands.json";
   Dialog::Message message("Creating/updating default build");
   auto exit_status=Terminal::get().process(Config::get().project.cmake.command+' '+
-                                           filesystem::escape_argument(project_path.string())+" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path);
+                                           filesystem::escape_argument(get_project_path().string())+" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path);
   message.hide();
   if(exit_status==EXIT_SUCCESS) {
+
 #ifdef _WIN32 //Temporary fix to MSYS2's libclang
     auto compile_commands_file=filesystem::read(compile_commands_path);
     auto replace_drive = [&compile_commands_file](const std::string& param) {
@@ -52,28 +46,19 @@ bool CMake::update_default_build(const boost::filesystem::path &default_build_pa
 }
 
 bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-  if(project_path.empty() || !boost::filesystem::exists(project_path/"CMakeLists.txt") || debug_build_path.empty())
+  if(get_project_path().empty() || !boost::filesystem::exists(get_project_path()/"CMakeLists.txt") || debug_build_path.empty())
     return false;
-  
-  if(!boost::filesystem::exists(debug_build_path)) {
-    boost::system::error_code ec;
-    boost::filesystem::create_directories(debug_build_path, ec);
-    if(ec) {
-      Terminal::get().print("Error: could not create "+debug_build_path.string()+": "+ec.message()+"\n", true);
-      return false;
-    }
-  }
-  
+
+  if (!create_build_directory(debug_build_path)) return false;
+
   if(!force && boost::filesystem::exists(debug_build_path/"CMakeCache.txt"))
     return true;
   
   Dialog::Message message("Creating/updating debug build");
   auto exit_status=Terminal::get().process(Config::get().project.cmake.command+' '+
-                                           filesystem::escape_argument(project_path.string())+" -DCMAKE_BUILD_TYPE=Debug", debug_build_path);
+                                           filesystem::escape_argument(get_project_path().string())+" -DCMAKE_BUILD_TYPE=Debug", debug_build_path);
   message.hide();
-  if(exit_status==EXIT_SUCCESS)
-    return true;
-  return false;
+  return exit_status == EXIT_SUCCESS;
 }
 
 boost::filesystem::path CMake::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
@@ -87,7 +72,7 @@ boost::filesystem::path CMake::get_executable(const boost::filesystem::path &bui
   for(auto &parameter: parameters) {
     if(parameter.second.size()>1 && parameter.second[0].size()>0 && parameter.second[0].compare(0, 2, "${")!=0) {
       auto executable=(parameter.first.parent_path()/parameter.second[0]).string();
-      auto project_path_str=project_path.string();
+      auto project_path_str=get_project_path().string();
       size_t pos=executable.find(project_path_str);
       if(pos!=std::string::npos)
         executable.replace(pos, project_path_str.size(), build_path.string());
diff --git a/src/cmake.h b/src/cmake.h
index 7783ae28..ebb68671 100644
--- a/src/cmake.h
+++ b/src/cmake.h
@@ -1,12 +1,12 @@
 #pragma once
 
-#include "buildsystem.h"
+#include "makefile_base.h"
 #include <unordered_map>
 #include <unordered_set>
 
-class CMake : public BuildSystemBase {
+class CMake : public MakefileBase {
 public:
-  CMake(const boost::filesystem::path &path);
+  explicit CMake(const boost::filesystem::path &path);
 
   bool update_default_build(const boost::filesystem::path &default_build_path, bool force) override;
 
diff --git a/src/ctags.cc b/src/ctags.cc
index 55b9fb43..1f34f6dc 100644
--- a/src/ctags.cc
+++ b/src/ctags.cc
@@ -10,7 +10,7 @@
 
 std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> > Ctags::get_result(const boost::filesystem::path &path) {
   auto build=Project::Build::create(path);
-  auto run_path=build->project_path;
+  auto run_path=build->get_project_path();
   std::string exclude;
   if(!run_path.empty()) {
     auto relative_default_path=filesystem::get_relative_path(build->get_default_path(), run_path);
diff --git a/src/buildsystem.cc b/src/makefile_base.cc
similarity index 85%
rename from src/buildsystem.cc
rename to src/makefile_base.cc
index e6ddefae..a73a76b4 100644
--- a/src/buildsystem.cc
+++ b/src/makefile_base.cc
@@ -1,10 +1,10 @@
 #include <regex>
 #include "meson.h"
-#include "buildsystem.h"
+#include "makefile_base.h"
 #include "terminal.h"
 #include "filesystem.h"
 
-bool BuildSystemBase::create_build_directory(const boost::filesystem::path &build_path) {
+bool MakefileBase::create_build_directory(const boost::filesystem::path &build_path) {
   if (!boost::filesystem::exists(build_path)) {
     boost::system::error_code ec;
     boost::filesystem::create_directories(build_path, ec);
@@ -45,5 +45,5 @@ namespace {
   }
 }
 
-BuildSystemBase::BuildSystemBase(const boost::filesystem::path &path, const std::string &filename) : project_path(
+MakefileBase::MakefileBase(const boost::filesystem::path &path, const std::string &filename) : project_path(
     find_project(path, filename)) {}
diff --git a/src/buildsystem.h b/src/makefile_base.h
similarity index 80%
rename from src/buildsystem.h
rename to src/makefile_base.h
index 202a5674..cd080804 100644
--- a/src/buildsystem.h
+++ b/src/makefile_base.h
@@ -3,11 +3,11 @@
 #include <boost/filesystem.hpp>
 #include <vector>
 
-class BuildSystemBase {
+class MakefileBase {
 public:
-  BuildSystemBase(const boost::filesystem::path &path, const std::string &filename);
+  MakefileBase(const boost::filesystem::path &path, const std::string &filename);
 
-  virtual ~BuildSystemBase() = default;
+  virtual ~MakefileBase() = default;
 
   auto &get_project_path() const { return project_path; }
 
diff --git a/src/meson.cc b/src/meson.cc
index ac1f6cb1..04b30de6 100644
--- a/src/meson.cc
+++ b/src/meson.cc
@@ -6,7 +6,7 @@
 #include "dialogs.h"
 #include "config.h"
 
-Meson::Meson(const boost::filesystem::path &path) : BuildSystemBase(path, "meson.build") {}
+Meson::Meson(const boost::filesystem::path &path) : MakefileBase(path, "meson.build") {}
 
 bool Meson::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
   if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") ||
@@ -31,17 +31,11 @@ bool Meson::update_default_build(const boost::filesystem::path &default_build_pa
 }
 
 bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-  if(project_path.empty() || !boost::filesystem::exists(project_path/"meson.build") || debug_build_path.empty())
+  if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") ||
+      debug_build_path.empty())
     return false;
-  
-  if(!boost::filesystem::exists(debug_build_path)) {
-    boost::system::error_code ec;
-    boost::filesystem::create_directories(debug_build_path, ec);
-    if(ec) {
-      Terminal::get().print("Error: could not create "+debug_build_path.string()+": "+ec.message()+"\n", true);
-      return false;
-    }
-  }
+
+  if (!create_build_directory(debug_build_path)) return false;
   
   bool compile_commands_exists=boost::filesystem::exists(debug_build_path/"compile_commands.json");
   if(!force && compile_commands_exists)
@@ -49,7 +43,7 @@ bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path,
   
   Dialog::Message message("Creating/updating debug build");
   auto exit_status=Terminal::get().process(Config::get().project.meson.command+' '+(compile_commands_exists?"--internal regenerate ":"")+
-                                           "--buildtype debug "+filesystem::escape_argument(project_path.string()), debug_build_path);
+                                           "--buildtype debug "+filesystem::escape_argument(get_project_path().string()), debug_build_path);
   message.hide();
   if(exit_status==EXIT_SUCCESS)
     return true;
diff --git a/src/meson.h b/src/meson.h
index cd31dbfa..43c5b1c4 100644
--- a/src/meson.h
+++ b/src/meson.h
@@ -1,8 +1,8 @@
 #pragma once
 
-#include "buildsystem.h"
+#include "makefile_base.h"
 
-class Meson : public BuildSystemBase {
+class Meson : public MakefileBase {
 public:
   Meson(const boost::filesystem::path &path);
 
diff --git a/src/project.cc b/src/project.cc
index eea330f2..2f32f8e9 100644
--- a/src/project.cc
+++ b/src/project.cc
@@ -16,6 +16,7 @@
 #include "usages_clang.h"
 #include "ctags.h"
 #include <future>
+#include <memory>
 
 boost::filesystem::path Project::debug_last_stop_file_path;
 std::unordered_map<std::string, std::string> Project::run_arguments;
@@ -64,7 +65,7 @@ void Project::on_save(size_t index) {
     auto build=Build::create(build_path);
     if(dynamic_cast<CMakeBuild*>(build.get()) || dynamic_cast<MesonBuild*>(build.get())) {
       build->update_default(true);
-      Usages::Clang::erase_all_caches_for_project(build->project_path, build->get_default_path());
+      Usages::Clang::erase_all_caches_for_project(build->get_project_path(), build->get_default_path());
       boost::system::error_code ec;
       if(boost::filesystem::exists(build->get_debug_path()), ec)
         build->update_debug(true);
@@ -72,7 +73,7 @@ void Project::on_save(size_t index) {
       for(size_t c=0;c<Notebook::get().size();c++) {
         auto source_view=Notebook::get().get_view(c);
         if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
-          if(filesystem::file_in_path(source_clang_view->file_path, build->project_path))
+          if(filesystem::file_in_path(source_clang_view->file_path, build->get_project_path()))
             source_clang_view->full_reparse_needed=true;
         }
       }
@@ -159,7 +160,7 @@ std::shared_ptr<Project::Base> Project::create() {
   else if(dynamic_cast<NpmBuild*>(build.get()))
     return std::shared_ptr<Project::Base>(new Project::JavaScript(std::move(build)));
   else
-    return std::shared_ptr<Project::Base>(new Project::Base(std::move(build)));
+    return std::make_shared<Project::Base>(std::move(build));
 }
 
 std::pair<std::string, std::string> Project::Base::get_run_arguments() {
@@ -260,7 +261,7 @@ std::pair<std::string, std::string> Project::LLDB::debug_get_run_arguments() {
   if(debug_build_path.empty() || default_build_path.empty())
     return {"", ""};
   
-  auto project_path=build->project_path.string();
+  auto project_path=build->get_project_path().string();
   auto run_arguments_it=debug_run_arguments.find(project_path);
   std::string arguments;
   if(run_arguments_it!=debug_run_arguments.end())
@@ -284,12 +285,12 @@ std::pair<std::string, std::string> Project::LLDB::debug_get_run_arguments() {
 }
 
 Project::DebugOptions *Project::LLDB::debug_get_options() {
-  if(build->project_path.empty())
+  if(build->get_project_path().empty())
     return nullptr;
   
   debug_options=std::make_unique<DebugOptions>();
   
-  auto &arguments=Project::debug_run_arguments[build->project_path.string()];
+  auto &arguments=Project::debug_run_arguments[build->get_project_path().string()];
   
   auto remote_enabled=Gtk::manage(new Gtk::CheckButton());
   auto remote_host_port=Gtk::manage(new Gtk::Entry());
@@ -308,7 +309,7 @@ Project::DebugOptions *Project::LLDB::debug_get_options() {
   
   auto self=this->shared_from_this();
   debug_options->signal_hide().connect([self, remote_enabled, remote_host_port] {
-    auto &arguments=Project::debug_run_arguments[self->build->project_path.string()];
+    auto &arguments=Project::debug_run_arguments[self->build->get_project_path().string()];
     arguments.remote_enabled=remote_enabled->get_active();
     arguments.remote_host_port=remote_host_port->get_text();
   });
@@ -332,7 +333,7 @@ void Project::LLDB::debug_start() {
   if(debug_build_path.empty() || !build->update_debug() || default_build_path.empty())
     return;
   
-  auto project_path=std::make_shared<boost::filesystem::path>(build->project_path);
+  auto project_path=std::make_shared<boost::filesystem::path>(build->get_project_path());
   
   auto run_arguments_it=debug_run_arguments.find(project_path->string());
   auto run_arguments=std::make_shared<std::string>();
@@ -667,7 +668,7 @@ void Project::LLDB::debug_cancel() {
 #endif
 
 void Project::LanguageProtocol::show_symbols() {
-  if(build->project_path.empty()) {
+  if(build->get_project_path().empty()) {
     Info::get().print("Could not find project folder");
     return;
   }
@@ -679,7 +680,7 @@ void Project::LanguageProtocol::show_symbols() {
     return;
   }
   
-  auto project_path=std::make_shared<boost::filesystem::path>(build->project_path);
+  auto project_path=std::make_shared<boost::filesystem::path>(build->get_project_path());
   
   auto client=::LanguageProtocol::Client::get(*project_path, language_id);
   auto capabilities=client->initialize(nullptr);
@@ -767,7 +768,7 @@ std::pair<std::string, std::string> Project::Clang::get_run_arguments() {
   if(build_path.empty())
     return {"", ""};
   
-  auto project_path=build->project_path.string();
+  auto project_path=build->get_project_path().string();
   auto run_arguments_it=run_arguments.find(project_path);
   std::string arguments;
   if(run_arguments_it!=run_arguments.end())
@@ -796,7 +797,7 @@ void Project::Clang::compile() {
   if(Config::get().project.clear_terminal_on_compile)
     Terminal::get().clear();
   
-  Terminal::get().print("Compiling project "+filesystem::get_short_path(build->project_path).string()+"\n");
+  Terminal::get().print("Compiling project "+filesystem::get_short_path(build->get_project_path()).string()+"\n");
   Terminal::get().async_process(build->get_compile_command(), default_build_path, [](int exit_status) {
     compiling=false;
   });
@@ -807,7 +808,7 @@ void Project::Clang::compile_and_run() {
   if(default_build_path.empty() || !build->update_default())
     return;
   
-  auto project_path=build->project_path;
+  auto project_path=build->get_project_path();
   
   auto run_arguments_it=run_arguments.find(project_path.string());
   std::string arguments;
@@ -842,7 +843,7 @@ void Project::Clang::compile_and_run() {
 }
 
 void Project::Clang::recreate_build() {
-  if(build->project_path.empty())
+  if(build->get_project_path().empty())
     return;
   auto default_build_path=build->get_default_path();
   if(default_build_path.empty())
@@ -866,7 +867,7 @@ void Project::Clang::recreate_build() {
     dialog.set_secondary_text(message+"?");
     if(dialog.run()!=Gtk::RESPONSE_YES)
       return;
-    Usages::Clang::erase_all_caches_for_project(build->project_path, default_build_path);
+    Usages::Clang::erase_all_caches_for_project(build->get_project_path(), default_build_path);
     try {
       if(has_default_build)
         boost::filesystem::remove_all(default_build_path);
@@ -886,7 +887,7 @@ void Project::Clang::recreate_build() {
   for(size_t c=0;c<Notebook::get().size();c++) {
     auto source_view=Notebook::get().get_view(c);
     if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
-      if(filesystem::file_in_path(source_clang_view->file_path, build->project_path))
+      if(filesystem::file_in_path(source_clang_view->file_path, build->get_project_path()))
         source_clang_view->full_reparse_needed=true;
     }
   }
@@ -932,9 +933,9 @@ void Project::Python::compile_and_run() {
 void Project::JavaScript::compile_and_run() {
   std::string command;
   boost::filesystem::path path;
-  if(!build->project_path.empty()) {
+  if(!build->get_project_path().empty()) {
     command="npm start";
-    path=build->project_path;
+    path=build->get_project_path();
   }
   else {
     auto view=Notebook::get().get_current_view();
@@ -970,7 +971,7 @@ void Project::HTML::compile_and_run() {
 }
 
 std::pair<std::string, std::string> Project::Rust::get_run_arguments() {
-  auto project_path=build->project_path.string();
+  auto project_path=build->get_project_path().string();
   auto run_arguments_it=run_arguments.find(project_path);
   std::string arguments;
   if(run_arguments_it!=run_arguments.end())
@@ -988,10 +989,10 @@ void Project::Rust::compile() {
   if(Config::get().project.clear_terminal_on_compile)
     Terminal::get().clear();
   
-  Terminal::get().print("Compiling project "+filesystem::get_short_path(build->project_path).string()+"\n");
+  Terminal::get().print("Compiling project "+filesystem::get_short_path(build->get_project_path()).string()+"\n");
   
   auto command=build->get_compile_command();
-  Terminal::get().async_process(command, build->project_path, [](int exit_status) {
+  Terminal::get().async_process(command, build->get_project_path(), [](int exit_status) {
     compiling=false;
   });
 }
@@ -1006,10 +1007,10 @@ void Project::Rust::compile_and_run() {
   Terminal::get().print("Compiling and running "+arguments+"\n");
   
   auto self=this->shared_from_this();
-  Terminal::get().async_process(build->get_compile_command(), build->project_path, [self, arguments=std::move(arguments)](int exit_status) {
+  Terminal::get().async_process(build->get_compile_command(), build->get_project_path(), [self, arguments=std::move(arguments)](int exit_status) {
     compiling=false;
     if(exit_status==EXIT_SUCCESS) {
-      Terminal::get().async_process(arguments, self->build->project_path, [arguments](int exit_status) {
+      Terminal::get().async_process(arguments, self->build->get_project_path(), [arguments](int exit_status) {
         Terminal::get().async_print(arguments+" returned: "+std::to_string(exit_status)+'\n');
       });
     }
diff --git a/src/project_build.cc b/src/project_build.cc
index a1f6f003..3398086a 100644
--- a/src/project_build.cc
+++ b/src/project_build.cc
@@ -40,22 +40,25 @@ std::unique_ptr<Project::Build> Project::Build::create(const boost::filesystem::
   return std::make_unique<Project::Build>();
 }
 
+namespace {
+  void replace_variable_in_path(boost::filesystem::path& path, const std::string& var, const std::string& with) {
+    size_t pos = 0;
+    auto path_string = path.string();
+    while ((pos = path_string.find(var, pos)) != std::string::npos) {
+      path_string.replace(pos, var.size(), with);
+      pos += with.size();
+    }
+    if (pos != 0)
+      path = path_string;
+  }
+}
 boost::filesystem::path Project::Build::get_default_path() {
   if (project_path.empty())
     return boost::filesystem::path();
 
   boost::filesystem::path default_build_path = Config::get().project.default_build_path;
 
-  const std::string path_variable_project_directory_name = "<project_directory_name>";
-  size_t pos = 0;
-  auto default_build_path_string = default_build_path.string();
-  auto path_filename_string = project_path.filename().string();
-  while ((pos = default_build_path_string.find(path_variable_project_directory_name, pos)) != std::string::npos) {
-    default_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
-    pos += path_filename_string.size();
-  }
-  if (pos != 0)
-    default_build_path = default_build_path_string;
+  replace_variable_in_path(default_build_path, "<project_directory_name>", project_path.filename().string());
 
   if (default_build_path.is_relative())
     default_build_path = project_path / default_build_path;
@@ -69,27 +72,8 @@ boost::filesystem::path Project::Build::get_debug_path() {
 
   boost::filesystem::path debug_build_path = Config::get().project.debug_build_path;
 
-  const std::string path_variable_project_directory_name = "<project_directory_name>";
-  size_t pos = 0;
-  auto debug_build_path_string = debug_build_path.string();
-  auto path_filename_string = project_path.filename().string();
-  while ((pos = debug_build_path_string.find(path_variable_project_directory_name, pos)) != std::string::npos) {
-    debug_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string);
-    pos += path_filename_string.size();
-  }
-  if (pos != 0)
-    debug_build_path = debug_build_path_string;
-
-  const std::string path_variable_default_build_path = "<default_build_path>";
-  pos = 0;
-  debug_build_path_string = debug_build_path.string();
-  auto default_build_path = Config::get().project.default_build_path;
-  while ((pos = debug_build_path_string.find(path_variable_default_build_path, pos)) != std::string::npos) {
-    debug_build_path_string.replace(pos, path_variable_default_build_path.size(), default_build_path);
-    pos += default_build_path.size();
-  }
-  if (pos != 0)
-    debug_build_path = debug_build_path_string;
+  replace_variable_in_path(debug_build_path, "<project_directory_name>", project_path.filename().string());
+  replace_variable_in_path(debug_build_path, "<default_build_path>", Config::get().project.default_build_path);
 
   if (debug_build_path.is_relative())
     debug_build_path = project_path / debug_build_path;
diff --git a/src/project_build.h b/src/project_build.h
index 0198c88b..058ccd6e 100644
--- a/src/project_build.h
+++ b/src/project_build.h
@@ -8,8 +8,6 @@ namespace Project {
   public:
     virtual ~Build() {}
     
-    boost::filesystem::path project_path;
-    
     virtual boost::filesystem::path get_default_path();
     virtual bool update_default(bool force=false) {return false;}
     virtual boost::filesystem::path get_debug_path();
@@ -17,44 +15,62 @@ namespace Project {
     
     virtual std::string get_compile_command() { return std::string(); }
     virtual boost::filesystem::path get_executable(const boost::filesystem::path &path) {return boost::filesystem::path();}
+
+    const boost::filesystem::path& get_project_path() const noexcept { return project_path; }
     
     static std::unique_ptr<Build> create(const boost::filesystem::path &path);
+
+  protected:
+    boost::filesystem::path project_path;
   };
-  
+
+
   class CMakeBuild : public Build {
     ::CMake cmake;
   public:
     CMakeBuild(const boost::filesystem::path &path);
-    
-    bool update_default(bool force=false) override;
-    bool update_debug(bool force=false) override;
-    
+
+    bool update_default(bool force) override;
+
+    bool update_debug(bool force) override;
+
     std::string get_compile_command() override;
+
     boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
   };
-  
+
   class MesonBuild : public Build {
     Meson meson;
   public:
     MesonBuild(const boost::filesystem::path &path);
-    
-    bool update_default(bool force=false) override;
-    bool update_debug(bool force=false) override;
-    
+
+    bool update_default(bool force) override;
+
+    bool update_debug(bool force) override;
+
     std::string get_compile_command() override;
+
     boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
   };
 
   class CargoBuild : public Build {
   public:
-    boost::filesystem::path get_default_path() override { return project_path/"target"/"debug"; }
-    bool update_default(bool force=false) override { return true; }
+    boost::filesystem::path get_default_path() override { return project_path / "target" / "debug"; }
+
+    bool update_default(bool force) override { return true; }
+
     boost::filesystem::path get_debug_path() override { return get_default_path(); }
-    bool update_debug(bool force=false) override { return true; }
-    
+
+    bool update_debug(bool force) override { return true; }
+
     std::string get_compile_command() override { return "cargo build"; }
-    boost::filesystem::path get_executable(const boost::filesystem::path &path) override { return get_debug_path()/project_path.filename(); }
+
+    boost::filesystem::path get_executable(const boost::filesystem::path &path) override {
+      return get_debug_path() / project_path.filename();
+    }
+  };
+
+  class NpmBuild : public Build {
   };
 
-  class NpmBuild : public Build {};
 }
diff --git a/src/source_clang.cc b/src/source_clang.cc
index 81c5357d..b3e14388 100644
--- a/src/source_clang.cc
+++ b/src/source_clang.cc
@@ -109,7 +109,7 @@ void Source::ClangViewParse::parse_initialize() {
     clangmm::remove_include_guard(buffer_raw);
   
   auto build=Project::Build::create(file_path);
-  if(build->project_path.empty())
+  if(build->get_project_path().empty())
     Info::get().print(file_path.filename().string()+": could not find a supported build system");
   build->update_default();
   auto arguments=CompileCommands::get_arguments(build->get_default_path(), file_path);
@@ -868,7 +868,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
       }
       
       auto build=Project::Build::create(this->file_path);
-      auto usages=Usages::Clang::get_usages(build->project_path, build->get_default_path(), build->get_debug_path(), identifier.spelling, identifier.cursor, translation_units);
+      auto usages=Usages::Clang::get_usages(build->get_project_path(), build->get_default_path(), build->get_debug_path(), identifier.spelling, identifier.cursor, translation_units);
       
       std::vector<Source::View*> renamed_views;
       std::vector<Usages::Clang::Usages*> usages_renamed;
@@ -1347,7 +1347,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
       }
       
       auto build=Project::Build::create(this->file_path);
-      auto usages_clang=Usages::Clang::get_usages(build->project_path, build->get_default_path(), build->get_debug_path(), {identifier.spelling}, {identifier.cursor}, translation_units);
+      auto usages_clang=Usages::Clang::get_usages(build->get_project_path(), build->get_default_path(), build->get_debug_path(), {identifier.spelling}, {identifier.cursor}, translation_units);
       for(auto &usage: usages_clang) {
         for(size_t c=0;c<usage.offsets.size();++c) {
           std::string line=Glib::Markup::escape_text(usage.lines[c]);
@@ -1808,8 +1808,8 @@ void Source::ClangView::async_delete() {
   for(auto &view: views) {
     if(dynamic_cast<ClangView*>(view)) {
       auto build=Project::Build::create(view->file_path);
-      if(!build->project_path.empty())
-        project_paths_in_use.emplace(build->project_path);
+      if(!build->get_project_path().empty())
+        project_paths_in_use.emplace(build->get_project_path());
     }
   }
   Usages::Clang::erase_unused_caches(project_paths_in_use);
@@ -1847,7 +1847,7 @@ void Source::ClangView::async_delete() {
     
     if(clang_tokens) {
       auto build=Project::Build::create(file_path);
-      Usages::Clang::cache(build->project_path, build->get_default_path(), file_path, before_parse_time, project_paths_in_use, clang_tu.get(), clang_tokens.get());
+      Usages::Clang::cache(build->get_project_path(), build->get_default_path(), file_path, before_parse_time, project_paths_in_use, clang_tu.get(), clang_tokens.get());
     }
     
     if(full_reparse_thread.joinable())
diff --git a/src/source_language_protocol.cc b/src/source_language_protocol.cc
index 3057c51d..f6f5de98 100644
--- a/src/source_language_protocol.cc
+++ b/src/source_language_protocol.cc
@@ -27,8 +27,8 @@ LanguageProtocol::Client::Client(std::string root_uri_, std::string language_id_
 std::shared_ptr<LanguageProtocol::Client> LanguageProtocol::Client::get(const boost::filesystem::path &file_path, const std::string &language_id) {
   std::string root_uri;
   auto build=Project::Build::create(file_path);
-  if(!build->project_path.empty())
-    root_uri=build->project_path.string();
+  if(!build->get_project_path().empty())
+    root_uri=build->get_project_path().string();
   else
     root_uri=file_path.parent_path().string();
   
@@ -335,8 +335,8 @@ Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path
     auto build=Project::Build::create(file_path);
     if(auto npm_build=dynamic_cast<Project::NpmBuild*>(build.get())) {
       boost::system::error_code ec;
-      if(!npm_build->project_path.empty() && boost::filesystem::exists(npm_build->project_path/".flowconfig", ec)) {
-        auto executable=npm_build->project_path/"node_modules"/".bin"/"flow"; // It is recommended to use Flow binary installed in project, despite the security risk of doing so...
+      if(!npm_build->get_project_path().empty() && boost::filesystem::exists(npm_build->get_project_path()/".flowconfig", ec)) {
+        auto executable=npm_build->get_project_path()/"node_modules"/".bin"/"flow"; // It is recommended to use Flow binary installed in project, despite the security risk of doing so...
         if(boost::filesystem::exists(executable, ec))
           flow_coverage_executable=executable;
         else
@@ -701,8 +701,8 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
         if(!error) {
           boost::filesystem::path project_path;
           auto build=Project::Build::create(file_path);
-          if(!build->project_path.empty())
-            project_path=build->project_path;
+          if(!build->get_project_path().empty())
+            project_path=build->get_project_path();
           else
             project_path=file_path.parent_path();
           try {
diff --git a/src/window.cc b/src/window.cc
index 62a6dc83..83f4a889 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -628,7 +628,7 @@ void Window::set_menu_actions() {
       }
     }
     auto build=Project::Build::create(search_path);
-    auto project_path=build->project_path;
+    auto project_path=build->get_project_path();
     boost::filesystem::path default_path, debug_path;
     if(!project_path.empty()) {
       search_path=project_path;
@@ -800,7 +800,7 @@ void Window::set_menu_actions() {
       auto dialog_iter=view->get_iter_for_dialog();
       SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
       std::vector<Source::Offset> rows;
-      auto project_path=Project::Build::create(view->file_path)->project_path;
+      auto project_path=Project::Build::create(view->file_path)->get_project_path();
       if(project_path.empty()) {
         if(!Directories::get().path.empty())
           project_path=Directories::get().path;
@@ -1044,7 +1044,7 @@ void Window::set_menu_actions() {
     Project::current=Project::create();
     
     if(Config::get().project.save_on_compile_or_run)
-      Project::save_files(Project::current->build->project_path);
+      Project::save_files(Project::current->build->get_project_path());
     
     Project::current->compile_and_run();
   });
@@ -1057,7 +1057,7 @@ void Window::set_menu_actions() {
     Project::current=Project::create();
     
     if(Config::get().project.save_on_compile_or_run)
-      Project::save_files(Project::current->build->project_path);
+      Project::save_files(Project::current->build->get_project_path());
     
     Project::current->compile();
   });
@@ -1156,7 +1156,7 @@ void Window::set_menu_actions() {
     Project::current=Project::create();
     
     if(Config::get().project.save_on_compile_or_run)
-      Project::save_files(Project::current->build->project_path);
+      Project::save_files(Project::current->build->get_project_path());
     
     Project::current->debug_start();
   });

From 6df4473e7c777635e50d81c3eabb4fae6a140b9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BA=88=E9=A1=BA=20=E5=88=98?= <yshliu0321@icloud.com>
Date: Thu, 24 May 2018 13:59:05 +0800
Subject: [PATCH 08/12] Reimplement CMake support with CBP

---
 src/cmake.cc        | 434 ++++++++++++++------------------------------
 src/cmake.h         |  26 ---
 src/files.h         |   4 +-
 src/makefile_base.h |   1 -
 4 files changed, 135 insertions(+), 330 deletions(-)

diff --git a/src/cmake.cc b/src/cmake.cc
index cfcc2479..b3f72b9d 100644
--- a/src/cmake.cc
+++ b/src/cmake.cc
@@ -3,336 +3,168 @@
 #include "dialogs.h"
 #include "config.h"
 #include "terminal.h"
-#include <regex>
 #include "compile_commands.h"
-
-CMake::CMake(const boost::filesystem::path &path) : MakefileBase(path, "CMakeLists.txt") {}
-
-bool CMake::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
-  if(get_project_path().empty() || !boost::filesystem::exists(get_project_path()/"CMakeLists.txt") || default_build_path.empty())
-    return false;
-
-  if (!create_build_directory(default_build_path)) return false;
-
-  if(!force && boost::filesystem::exists(default_build_path/"compile_commands.json"))
-    return true;
-  
-  auto compile_commands_path=default_build_path/"compile_commands.json";
-  Dialog::Message message("Creating/updating default build");
-  auto exit_status=Terminal::get().process(Config::get().project.cmake.command+' '+
-                                           filesystem::escape_argument(get_project_path().string())+" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path);
-  message.hide();
-  if(exit_status==EXIT_SUCCESS) {
-
-#ifdef _WIN32 //Temporary fix to MSYS2's libclang
-    auto compile_commands_file=filesystem::read(compile_commands_path);
-    auto replace_drive = [&compile_commands_file](const std::string& param) {
-      size_t pos=0;
-      auto param_size = param.length();
-      while((pos=compile_commands_file.find(param+"/", pos))!=std::string::npos) {
-        if(pos+param_size+1<compile_commands_file.size())
-          compile_commands_file.replace(pos, param_size+2, param+compile_commands_file[pos+param_size+1]+":");
-        else
-          break;
-      }
-    };
-    replace_drive("-I");
-    replace_drive("-isystem ");
-    filesystem::write(compile_commands_path, compile_commands_file);
+#include "rapidxml/rapidxml.hpp"
+
+namespace {
+  enum class Configuration {
+    Debug, Release
+  };
+
+  class CMakeProjectUpdater {
+  public:
+    CMakeProjectUpdater(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path) :
+        m_ref_project_path(project_path), m_ref_build_path(build_path) {}
+
+    CMakeProjectUpdater &set_configuration(Configuration conf) noexcept {
+      m_configuration = conf;
+      return *this;
+    }
+
+    void do_update(bool force) {
+      check_arguments();
+      boost::filesystem::create_directory(m_ref_build_path);
+      if(!force && boost::filesystem::exists(m_ref_build_path / "CMakeCache.txt")) return;
+      auto compile_commands_path = m_ref_build_path / "compile_commands.json";
+      Dialog::Message message("Creating/updating build");
+      auto exit_status = Terminal::get().process(Config::get().project.cmake.command+' '+
+                                                 filesystem::escape_argument(m_ref_project_path.string())+
+                                                 " -DCMAKE_EXPORT_COMPILE_COMMANDS=ON"+get_extra_arguments(),
+                                                 m_ref_build_path);
+      if(exit_status == EXIT_SUCCESS)
+#ifdef _WIN32
+        applyMsys2Patch(compile_commands_path);
 #endif
-    return true;
-  }
-  return false;
-}
-
-bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-  if(get_project_path().empty() || !boost::filesystem::exists(get_project_path()/"CMakeLists.txt") || debug_build_path.empty())
-    return false;
-
-  if (!create_build_directory(debug_build_path)) return false;
-
-  if(!force && boost::filesystem::exists(debug_build_path/"CMakeCache.txt"))
-    return true;
-  
-  Dialog::Message message("Creating/updating debug build");
-  auto exit_status=Terminal::get().process(Config::get().project.cmake.command+' '+
-                                           filesystem::escape_argument(get_project_path().string())+" -DCMAKE_BUILD_TYPE=Debug", debug_build_path);
-  message.hide();
-  return exit_status == EXIT_SUCCESS;
-}
+      message.hide();
+    }
 
-boost::filesystem::path CMake::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
-  // CMake does not store in compile_commands.json if an object is part of an executable or not.
-  // Therefore, executables are first attempted found in the cmake files. These executables
-  // are then used to identify if a file in compile_commands.json is part of an executable or not
-  
-  auto parameters = get_functions_parameters("add_executable");
-  
-  std::vector<boost::filesystem::path> cmake_executables;
-  for(auto &parameter: parameters) {
-    if(parameter.second.size()>1 && parameter.second[0].size()>0 && parameter.second[0].compare(0, 2, "${")!=0) {
-      auto executable=(parameter.first.parent_path()/parameter.second[0]).string();
-      auto project_path_str=get_project_path().string();
-      size_t pos=executable.find(project_path_str);
-      if(pos!=std::string::npos)
-        executable.replace(pos, project_path_str.size(), build_path.string());
-      cmake_executables.emplace_back(executable);
+  private:
+    void check_arguments() {
+      if(m_ref_project_path.empty() || m_ref_build_path.empty())
+        throw std::runtime_error("Arguments Incomplete");
+      if(!boost::filesystem::exists(m_ref_project_path / "CMakeLists.txt"))
+        throw std::runtime_error("CMake Project Not Found");
     }
-  }
-  
-  
-  CompileCommands compile_commands(build_path);
-  std::vector<std::pair<boost::filesystem::path, boost::filesystem::path>> command_files_and_maybe_executables;
-  for(auto &command: compile_commands.commands) {
-    auto command_file=filesystem::get_normal_path(command.file);
-    auto values=command.parameter_values("-o");
-    if(!values.empty()) {
-      size_t pos;
-      values[0].erase(0, 11);
-      if((pos=values[0].find(".dir"))!=std::string::npos) {
-        auto executable=command.directory/values[0].substr(0, pos);
-        command_files_and_maybe_executables.emplace_back(command_file, executable);
-      }
+
+    std::string get_extra_arguments() const {
+      return m_configuration == Configuration::Debug ? " -DCMAKE_BUILD_TYPE=Debug" : " -DCMAKE_BUILD_TYPE=Release";
     }
-  }
-  
-  size_t best_match_size=-1;
-  boost::filesystem::path best_match_executable;
-  
-  for(auto &cmake_executable: cmake_executables) {
-    for(auto &command_file_and_maybe_executable: command_files_and_maybe_executables) {
-      auto &command_file=command_file_and_maybe_executable.first;
-      auto &maybe_executable=command_file_and_maybe_executable.second;
-      if(cmake_executable==maybe_executable) {
-        if(command_file==file_path)
-          return maybe_executable;
-        auto command_file_directory=command_file.parent_path();
-        if(filesystem::file_in_path(file_path, command_file_directory)) {
-          auto size=static_cast<size_t>(std::distance(command_file_directory.begin(), command_file_directory.end()));
-          if(best_match_size==static_cast<size_t>(-1) || best_match_size<size) {
-            best_match_size=size;
-            best_match_executable=maybe_executable;
-          }
+
+    //Temporary fix to MSYS2's libclang
+    void applyMsys2Patch(const boost::filesystem::path &compile_commands_path) const {
+      auto compile_commands_file = filesystem::read(compile_commands_path);
+      const std::array<const std::string, 2> drives = {"-I", "-isystem"};
+      for(const auto &target: drives) {
+        size_t pos = 0;
+        auto param_size = target.length();
+        while((pos = compile_commands_file.find(target+"/", pos)) != std::string::npos) {
+          if(pos+param_size+1 < compile_commands_file.size())
+            compile_commands_file.replace(pos, param_size+2, target+compile_commands_file[pos+param_size+1]+":");
+          else
+            break;
         }
       }
+      filesystem::write(compile_commands_path, compile_commands_file);
     }
-  }
-  if(!best_match_executable.empty())
-    return best_match_executable;
-  
-  for(auto &command_file_and_maybe_executable: command_files_and_maybe_executables) {
-    auto &command_file=command_file_and_maybe_executable.first;
-    auto &maybe_executable=command_file_and_maybe_executable.second;
-    if(command_file==file_path)
-      return maybe_executable;
-    auto command_file_directory=command_file.parent_path();
-    if(filesystem::file_in_path(file_path, command_file_directory)) {
-      auto size=static_cast<size_t>(std::distance(command_file_directory.begin(), command_file_directory.end()));
-      if(best_match_size==static_cast<size_t>(-1) || best_match_size<size) {
-        best_match_size=size;
-        best_match_executable=maybe_executable;
-      }
-    }
-  }
-  return best_match_executable;
-}
 
-void CMake::read_files() {
-  for(auto &path: paths)
-    files.emplace_back(filesystem::read(path));
+    Configuration m_configuration;
+    const boost::filesystem::path &m_ref_project_path;
+    const boost::filesystem::path &m_ref_build_path;
+  };
 }
 
-void CMake::remove_tabs() {
-  for(auto &file: files) {
-    for(auto &chr: file) {
-      if(chr=='\t')
-        chr=' ';
-    }
+CMake::CMake(const boost::filesystem::path &path) : MakefileBase(path, "CMakeLists.txt") {}
+
+bool CMake::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
+  try {
+    CMakeProjectUpdater(get_project_path(), default_build_path).set_configuration(Configuration::Release).do_update(
+        force);
   }
+  catch(std::exception &e) {
+    Terminal::get().print("Configuration For: "+get_project_path().string()+" Failed With: "+e.what()+'\n');
+    return false;
+  }
+  return true;
 }
 
-void CMake::remove_comments() {
-  for(auto &file: files) {
-    size_t pos=0;
-    size_t comment_start;
-    bool inside_comment=false;
-    while(pos<file.size()) {
-      if(!inside_comment && file[pos]=='#') {
-        comment_start=pos;
-        inside_comment=true;
-      }
-      if(inside_comment && file[pos]=='\n') {
-        file.erase(comment_start, pos-comment_start);
-        pos-=pos-comment_start;
-        inside_comment=false;
-      }
-      pos++;
-    }
-    if(inside_comment)
-      file.erase(comment_start);
+bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
+  try {
+    CMakeProjectUpdater(get_project_path(), debug_build_path).set_configuration(Configuration::Debug).do_update(force);
+  }
+  catch(std::exception &e) {
+    Terminal::get().print("Configuration For: "+get_project_path().string()+" Failed With: "+e.what()+'\n');
+    return false;
   }
+  return true;
 }
 
-void CMake::remove_newlines_inside_parentheses() {
-  for(auto &file: files) {
-    size_t pos=0;
-    bool inside_para=false;
-    bool inside_quote=false;
-    char last_char=0;
-    while(pos<file.size()) {
-      if(!inside_quote && file[pos]=='"' && last_char!='\\')
-        inside_quote=true;
-      else if(inside_quote && file[pos]=='"' && last_char!='\\')
-        inside_quote=false;
+namespace {
+  class GetExecutableHelper {
+  public:
+    explicit GetExecutableHelper(const boost::filesystem::path &build_path);
 
-      else if(!inside_quote && file[pos]=='(')
-        inside_para=true;
-      else if(!inside_quote && file[pos]==')')
-        inside_para=false;
+    auto &get_executables() const noexcept { return executables; }
 
-      else if(inside_para && file[pos]=='\n')
-        file.replace(pos, 1, 1, ' ');
-      last_char=file[pos];
-      pos++;
+  private:
+    static boost::filesystem::path find_project_file(const boost::filesystem::path &build_path) {
+      for(boost::filesystem::directory_iterator it(build_path), end; it != end; ++it) {
+        if(it->path().extension().compare(std::string(".cbp")) == 0)
+          return boost::filesystem::absolute(it->path());
+      }
+      return "";
     }
-  }
-}
 
-void CMake::parse_variable_parameters(std::string &data) {
-  size_t pos=0;
-  bool inside_quote=false;
-  char last_char=0;
-  while(pos<data.size()) {
-    if(!inside_quote && data[pos]=='"' && last_char!='\\') {
-      inside_quote=true;
-      data.erase(pos, 1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
-      pos--;
-    }
-    else if(inside_quote && data[pos]=='"' && last_char!='\\') {
-      inside_quote=false;
-      data.erase(pos, 1); //TODO: instead remove quote-mark if pasted into a quote, for instance: "test${test}test"<-remove quotes from ${test}
-      pos--;
+    static std::string file_reader(const boost::filesystem::path &build_path) {
+      std::stringstream ss;
+      std::ifstream inf(build_path.string());
+      ss << inf.rdbuf();
+      return ss.str();
     }
-    else if(!inside_quote && data[pos]==' ' && pos+1<data.size() && data[pos+1]==' ') {
-      data.erase(pos, 1);
-      pos--;
+
+    void parse_project(const boost::filesystem::path &build_path) {
+      const auto project_file = file_reader(find_project_file(build_path));
+      document.parse<0>(const_cast<char *>(project_file.c_str()));
     }
-    
-    if(pos!=static_cast<size_t>(-1))
-      last_char=data[pos];
-    pos++;
-  }
-  for(auto &var: variables) {
-    auto pos=data.find("${"+var.first+'}');
-    while(pos!=std::string::npos) {
-      data.replace(pos, var.first.size()+3, var.second);
-      pos=data.find("${"+var.first+'}');
+
+    static bool is_fast_target(const std::string &target) {
+      if(target.size() > 5)
+        return target.substr(target.size()-5, 5) == "/fast";
+      return false;
     }
-  }
-  
-  //Remove variables we do not know:
-  pos=data.find("${");
-  auto pos_end=data.find('}', pos+2);
-  while(pos!=std::string::npos && pos_end!=std::string::npos) {
-    data.erase(pos, pos_end-pos+1);
-    pos=data.find("${");
-    pos_end=data.find('}', pos+2);
-  }
-}
 
-void CMake::parse() {
-  read_files();
-  remove_tabs();
-  remove_comments();
-  remove_newlines_inside_parentheses();
-  parsed=true;
-}
+    static bool is_executable(int type) noexcept { return type == 0 || type == 1 || type == 5; }
 
-std::vector<std::string> CMake::get_function_parameters(std::string &data) {
-  std::vector<std::string> parameters;
-  size_t pos=0;
-  size_t parameter_pos=0;
-  bool inside_quote=false;
-  char last_char=0;
-  while(pos<data.size()) {
-    if(!inside_quote && data[pos]=='"' && last_char!='\\') {
-      inside_quote=true;
-      data.erase(pos, 1);
-      pos--;
-    }
-    else if(inside_quote && data[pos]=='"' && last_char!='\\') {
-      inside_quote=false;
-      data.erase(pos, 1);
-      pos--;
-    }
-    else if(!inside_quote && pos+1<data.size() && data[pos]==' ' && data[pos+1]==' ') {
-      data.erase(pos, 1);
-      pos--;
-    }
-    else if(!inside_quote && data[pos]==' ') {
-      parameters.emplace_back(data.substr(parameter_pos, pos-parameter_pos));
-      if(pos+1<data.size())
-        parameter_pos=pos+1;
-    }
-    
-    if(pos!=static_cast<size_t>(-1))
-      last_char=data[pos];
-    pos++;
-  }
-  parameters.emplace_back(data.substr(parameter_pos));
-  for(auto &var: variables) {
-    for(auto &parameter: parameters) {
-      auto pos=parameter.find("${"+var.first+'}');
-      while(pos!=std::string::npos) {
-        parameter.replace(pos, var.first.size()+3, var.second);
-        pos=parameter.find("${"+var.first+'}');
+    static auto get_options(const rapidxml::xml_node<> *target) {
+      std::map<std::string, std::string> options;
+      for(auto option = target->first_node("Option"); option != nullptr; option = option->next_sibling("Option")) {
+        auto attr = option->first_attribute();
+        options[std::string(attr->name(), attr->name_size())] = std::string(attr->value(), attr->value_size());
+      }
+      return options;
+    }
+
+    rapidxml::xml_document<> document;
+    std::vector<boost::filesystem::path> executables;
+  };
+
+  GetExecutableHelper::GetExecutableHelper(const boost::filesystem::path &build_path) {
+    parse_project(build_path);
+    auto build = document.first_node("CodeBlocks_project_file")->first_node("Project")->first_node("Build");
+    for(auto target = build->first_node("Target"); target != nullptr; target = target->next_sibling("Target")) {
+      auto title_attr = target->first_attribute("title");
+      if(!is_fast_target(std::string(title_attr->value(), title_attr->value_size()))) {
+        auto options = get_options(target);
+        if(is_executable(options["type"][0]-'0'))
+          executables.emplace_back(options["output"]);
       }
     }
   }
-  return parameters;
+
 }
 
-std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > > CMake::get_functions_parameters(const std::string &name) {
-  const std::regex function_regex("^ *"+name+R"( *\( *(.*)\) *\r?$)", std::regex::icase);
-  variables.clear();
-  if(!parsed)
-    parse();
-  std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > > functions;
-  for(size_t c=0;c<files.size();++c) {
-    size_t pos=0;
-    while(pos<files[c].size()) {
-      auto start_line=pos;
-      auto end_line=files[c].find('\n', start_line);
-      if(end_line==std::string::npos)
-        end_line=files[c].size();
-      if(end_line>start_line) {
-        auto line=files[c].substr(start_line, end_line-start_line);
-        std::smatch sm;
-        const static std::regex set_regex(R"(^ *set *\( *([A-Za-z_][A-Za-z_0-9]*) +(.*)\) *\r?$)", std::regex::icase);
-        const static std::regex project_regex(R"(^ *project *\( *([^ ]+).*\) *\r?$)", std::regex::icase);
-        if(std::regex_match(line, sm, set_regex)) {
-          auto data=sm[2].str();
-          while(data.size()>0 && data.back()==' ')
-            data.pop_back();
-          parse_variable_parameters(data);
-          variables[sm[1].str()]=data;
-        }
-        else if(std::regex_match(line, sm, project_regex)) {
-          auto data=sm[1].str();
-          parse_variable_parameters(data);
-          variables["CMAKE_PROJECT_NAME"]=data; //TODO: is this variable deprecated/non-standard?
-          variables["PROJECT_NAME"]=data;
-        }
-        if(std::regex_match(line, sm, function_regex)) {
-          auto data=sm[1].str();
-          while(data.size()>0 && data.back()==' ')
-            data.pop_back();
-          auto parameters=get_function_parameters(data);
-          functions.emplace_back(paths[c], parameters);
-        }
-      }
-      pos=end_line+1;
-    }
-  }
-  return functions;
+boost::filesystem::path
+CMake::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &) {
+  GetExecutableHelper helper(build_path);
+  auto &exec = helper.get_executables();
+  return exec.empty() ? "" : exec[0];
 }
diff --git a/src/cmake.h b/src/cmake.h
index ebb68671..1fa22ce9 100644
--- a/src/cmake.h
+++ b/src/cmake.h
@@ -1,8 +1,6 @@
 #pragma once
 
 #include "makefile_base.h"
-#include <unordered_map>
-#include <unordered_set>
 
 class CMake : public MakefileBase {
 public:
@@ -14,28 +12,4 @@ class CMake : public MakefileBase {
 
   boost::filesystem::path
   get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
-
-private:
-  std::vector<boost::filesystem::path> paths;
-  std::vector<std::string> files;
-  std::unordered_map<std::string, std::string> variables;
-
-  void read_files();
-
-  void remove_tabs();
-
-  void remove_comments();
-
-  void remove_newlines_inside_parentheses();
-
-  void parse_variable_parameters(std::string &data);
-
-  void parse();
-
-  std::vector<std::string> get_function_parameters(std::string &data);
-
-  std::vector<std::pair<boost::filesystem::path, std::vector<std::string> > >
-  get_functions_parameters(const std::string &name);
-
-  bool parsed = false;
 };
diff --git a/src/files.h b/src/files.h
index d72bbcf8..7e10dbe3 100644
--- a/src/files.h
+++ b/src/files.h
@@ -164,10 +164,10 @@ const std::string default_config_file = R"RAW({
         "cmake": {)RAW"
                                                     #ifdef _WIN32
                                                     R"RAW(
-            "command": "cmake -G\"MSYS Makefiles\"",)RAW"
+            "command": "cmake -G\"CodeBlocks - MinGW Makefiles\"",)RAW"
                                                     #else
                                                     R"RAW(
-            "command": "cmake",)RAW"
+            "command": "cmake -G\"CodeBlocks - Unix Makefiles\"",)RAW"
                                                     #endif
                                                     R"RAW(
             "compile_command": "cmake --build ."
diff --git a/src/makefile_base.h b/src/makefile_base.h
index cd080804..d2493ab6 100644
--- a/src/makefile_base.h
+++ b/src/makefile_base.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include <boost/filesystem.hpp>
-#include <vector>
 
 class MakefileBase {
 public:

From 42c54fcc0796f2d503839cf5c803232abffd822e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BA=88=E9=A1=BA=20=E5=88=98?= <yshliu0321@icloud.com>
Date: Thu, 24 May 2018 14:11:04 +0800
Subject: [PATCH 09/12] Add rapidxml

---
 src/cmake.cc            |    2 +-
 src/rapidxml/rapidxml.h | 1639 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 1640 insertions(+), 1 deletion(-)
 create mode 100644 src/rapidxml/rapidxml.h

diff --git a/src/cmake.cc b/src/cmake.cc
index b3f72b9d..118c3488 100644
--- a/src/cmake.cc
+++ b/src/cmake.cc
@@ -4,7 +4,7 @@
 #include "config.h"
 #include "terminal.h"
 #include "compile_commands.h"
-#include "rapidxml/rapidxml.hpp"
+#include "rapidxml/rapidxml.h"
 
 namespace {
   enum class Configuration {
diff --git a/src/rapidxml/rapidxml.h b/src/rapidxml/rapidxml.h
new file mode 100644
index 00000000..49e1b2aa
--- /dev/null
+++ b/src/rapidxml/rapidxml.h
@@ -0,0 +1,1639 @@
+#pragma once
+
+#include <cstdlib>
+#include <cassert>
+#include <new>
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+
+#include <exception>
+
+#define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where)
+
+namespace rapidxml {
+
+  class parse_error : public std::exception {
+  public:
+
+    parse_error(const char *what, void *where)
+        : m_what(what), m_where(where) {
+    }
+
+    virtual const char *what() const throw() {
+      return m_what;
+    }
+
+    template<class Ch>
+    Ch *where() const {
+      return reinterpret_cast<Ch *>(m_where);
+    }
+
+  private:
+    const char *m_what;
+    void *m_where;
+  };
+}
+
+#ifndef RAPIDXML_STATIC_POOL_SIZE
+
+#define RAPIDXML_STATIC_POOL_SIZE (64 * 1024)
+#endif
+#ifndef RAPIDXML_DYNAMIC_POOL_SIZE
+
+#define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024)
+#endif
+#ifndef RAPIDXML_ALIGNMENT
+
+#define RAPIDXML_ALIGNMENT sizeof(void *)
+#endif
+namespace rapidxml {
+  template<class Ch>
+  class xml_node;
+
+  template<class Ch>
+  class xml_attribute;
+
+  template<class Ch>
+  class xml_document;
+
+  enum node_type {
+    node_document,
+    node_element,
+    node_data,
+    node_cdata,
+    node_comment,
+    node_declaration,
+    node_doctype,
+    node_pi
+  };
+
+  const int parse_no_data_nodes = 0x1;
+
+  const int parse_no_element_values = 0x2;
+
+  const int parse_no_string_terminators = 0x4;
+
+  const int parse_no_entity_translation = 0x8;
+
+  const int parse_no_utf8 = 0x10;
+
+  const int parse_declaration_node = 0x20;
+
+  const int parse_comment_nodes = 0x40;
+
+  const int parse_doctype_node = 0x80;
+
+  const int parse_pi_nodes = 0x100;
+
+  const int parse_validate_closing_tags = 0x200;
+
+  const int parse_trim_whitespace = 0x400;
+
+  const int parse_normalize_whitespace = 0x800;
+
+  const int parse_default = 0;
+
+  const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation;
+
+  const int parse_fastest = parse_non_destructive | parse_no_data_nodes;
+
+  const int parse_full =
+      parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags;
+
+  namespace internal {
+
+    template<int Dummy>
+    struct lookup_tables {
+      static const unsigned char lookup_whitespace[256];
+      static const unsigned char lookup_node_name[256];
+      static const unsigned char lookup_text[256];
+      static const unsigned char lookup_text_pure_no_ws[256];
+      static const unsigned char lookup_text_pure_with_ws[256];
+      static const unsigned char lookup_attribute_name[256];
+      static const unsigned char lookup_attribute_data_1[256];
+      static const unsigned char lookup_attribute_data_1_pure[256];
+      static const unsigned char lookup_attribute_data_2[256];
+      static const unsigned char lookup_attribute_data_2_pure[256];
+      static const unsigned char lookup_digits[256];
+      static const unsigned char lookup_upcase[256];
+    };
+
+    template<class Ch>
+    inline std::size_t measure(const Ch *p) {
+      const Ch *tmp = p;
+      while(*tmp)
+        ++tmp;
+      return tmp-p;
+    }
+
+    template<class Ch>
+    inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, bool case_sensitive) {
+      if(size1 != size2)
+        return false;
+      if(case_sensitive) {
+        for(const Ch *end = p1+size1; p1 < end; ++p1, ++p2)
+          if(*p1 != *p2)
+            return false;
+      } else {
+        for(const Ch *end = p1+size1; p1 < end; ++p1, ++p2)
+          if(lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)] !=
+             lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)])
+            return false;
+      }
+      return true;
+    }
+  }
+
+  template<class Ch = char>
+  class memory_pool {
+  public:
+
+    typedef void *(alloc_func)(std::size_t);
+
+    typedef void (free_func)(void *);
+
+    memory_pool()
+        : m_alloc_func(0), m_free_func(0) {
+      init();
+    }
+
+    ~memory_pool() {
+      clear();
+    }
+
+    xml_node<Ch> *allocate_node(node_type type,
+                                const Ch *name = 0, const Ch *value = 0,
+                                std::size_t name_size = 0, std::size_t value_size = 0) {
+      void *memory = allocate_aligned(sizeof(xml_node<Ch>));
+      xml_node<Ch> *node = new(memory) xml_node<Ch>(type);
+      if(name) {
+        if(name_size > 0)
+          node->name(name, name_size);
+        else
+          node->name(name);
+      }
+      if(value) {
+        if(value_size > 0)
+          node->value(value, value_size);
+        else
+          node->value(value);
+      }
+      return node;
+    }
+
+    xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0,
+                                          std::size_t name_size = 0, std::size_t value_size = 0) {
+      void *memory = allocate_aligned(sizeof(xml_attribute<Ch>));
+      xml_attribute<Ch> *attribute = new(memory) xml_attribute<Ch>;
+      if(name) {
+        if(name_size > 0)
+          attribute->name(name, name_size);
+        else
+          attribute->name(name);
+      }
+      if(value) {
+        if(value_size > 0)
+          attribute->value(value, value_size);
+        else
+          attribute->value(value);
+      }
+      return attribute;
+    }
+
+    Ch *allocate_string(const Ch *source = 0, std::size_t size = 0) {
+      assert(source || size);
+      if(size == 0)
+        size = internal::measure(source)+1;
+      Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));
+      if(source)
+        for(std::size_t i = 0; i < size; ++i)
+          result[i] = source[i];
+      return result;
+    }
+
+    xml_node<Ch> *clone_node(const xml_node<Ch> *source, xml_node<Ch> *result = 0) {
+      if(result) {
+        result->remove_all_attributes();
+        result->remove_all_nodes();
+        result->type(source->type());
+      } else
+        result = allocate_node(source->type());
+
+      result->name(source->name(), source->name_size());
+      result->value(source->value(), source->value_size());
+
+      for(xml_node<Ch> *child = source->first_node(); child; child = child->next_sibling())
+        result->append_node(clone_node(child));
+      for(xml_attribute<Ch> *attr = source->first_attribute(); attr; attr = attr->next_attribute())
+        result->append_attribute(
+            allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size()));
+      return result;
+    }
+
+    void clear() {
+      while(m_begin != m_static_memory) {
+        char *previous_begin = reinterpret_cast<header *>(align(m_begin))->previous_begin;
+        if(m_free_func)
+          m_free_func(m_begin);
+        else
+          delete[] m_begin;
+        m_begin = previous_begin;
+      }
+      init();
+    }
+
+    void set_allocator(alloc_func *af, free_func *ff) {
+      assert(m_begin == m_static_memory && m_ptr == align(m_begin));
+      m_alloc_func = af;
+      m_free_func = ff;
+    }
+
+  private:
+    struct header {
+      char *previous_begin;
+    };
+
+    void init() {
+      m_begin = m_static_memory;
+      m_ptr = align(m_begin);
+      m_end = m_static_memory+sizeof(m_static_memory);
+    }
+
+    char *align(char *ptr) {
+      std::size_t alignment = ((RAPIDXML_ALIGNMENT-(std::size_t(ptr) & (RAPIDXML_ALIGNMENT-1))) &
+                               (RAPIDXML_ALIGNMENT-1));
+      return ptr+alignment;
+    }
+
+    char *allocate_raw(std::size_t size) {
+      void *memory;
+      if(m_alloc_func) {
+        memory = m_alloc_func(size);
+        assert(
+            memory);
+      } else {
+        memory = new char[size];
+#ifdef RAPIDXML_NO_EXCEPTIONS
+                                                                                                                                if (!memory)            
+                    RAPIDXML_PARSE_ERROR("out of memory", 0);
+#endif
+      }
+      return static_cast<char *>(memory);
+    }
+
+    void *allocate_aligned(std::size_t size) {
+      char *result = align(m_ptr);
+
+      if(result+size > m_end) {
+        std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE;
+        if(pool_size < size)
+          pool_size = size;
+
+        std::size_t alloc_size = sizeof(header)+(2 * RAPIDXML_ALIGNMENT-2)+
+                                 pool_size;
+        char *raw_memory = allocate_raw(alloc_size);
+
+        char *pool = align(raw_memory);
+        header *new_header = reinterpret_cast<header *>(pool);
+        new_header->previous_begin = m_begin;
+        m_begin = raw_memory;
+        m_ptr = pool+sizeof(header);
+        m_end = raw_memory+alloc_size;
+
+        result = align(m_ptr);
+      }
+
+      m_ptr = result+size;
+      return result;
+    }
+
+    char *m_begin;
+    char *m_ptr;
+    char *m_end;
+    char m_static_memory[RAPIDXML_STATIC_POOL_SIZE];
+    alloc_func *m_alloc_func;
+    free_func *m_free_func;
+  };
+
+  template<class Ch = char>
+  class xml_base {
+  public:
+
+    xml_base()
+        : m_name(0), m_value(0), m_parent(0) {
+    }
+
+    Ch *name() const {
+      return m_name ? m_name : nullstr();
+    }
+
+    std::size_t name_size() const {
+      return m_name ? m_name_size : 0;
+    }
+
+    Ch *value() const {
+      return m_value ? m_value : nullstr();
+    }
+
+    std::size_t value_size() const {
+      return m_value ? m_value_size : 0;
+    }
+
+    void name(const Ch *name, std::size_t size) {
+      m_name = const_cast<Ch *>(name);
+      m_name_size = size;
+    }
+
+    void name(const Ch *name) {
+      this->name(name, internal::measure(name));
+    }
+
+    void value(const Ch *value, std::size_t size) {
+      m_value = const_cast<Ch *>(value);
+      m_value_size = size;
+    }
+
+    void value(const Ch *value) {
+      this->value(value, internal::measure(value));
+    }
+
+    xml_node<Ch> *parent() const {
+      return m_parent;
+    }
+
+  protected:
+
+    static Ch *nullstr() {
+      static Ch zero = Ch('\0');
+      return &zero;
+    }
+
+    Ch *m_name;
+    Ch *m_value;
+    std::size_t m_name_size;
+    std::size_t m_value_size;
+    xml_node<Ch> *m_parent;
+  };
+
+  template<class Ch = char>
+  class xml_attribute : public xml_base<Ch> {
+    friend class xml_node<Ch>;
+
+  public:
+
+    xml_attribute() {
+    }
+
+    xml_document<Ch> *document() const {
+      if(xml_node<Ch> *node = this->parent()) {
+        while(node->parent())
+          node = node->parent();
+        return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
+      } else
+        return 0;
+    }
+
+    xml_attribute<Ch> *
+    previous_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const {
+      if(name) {
+        if(name_size == 0)
+          name_size = internal::measure(name);
+        for(xml_attribute<Ch> *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute)
+          if(internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
+            return attribute;
+        return 0;
+      } else
+        return this->m_parent ? m_prev_attribute : 0;
+    }
+
+    xml_attribute<Ch> *next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const {
+      if(name) {
+        if(name_size == 0)
+          name_size = internal::measure(name);
+        for(xml_attribute<Ch> *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute)
+          if(internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
+            return attribute;
+        return 0;
+      } else
+        return this->m_parent ? m_next_attribute : 0;
+    }
+
+  private:
+    xml_attribute<Ch> *m_prev_attribute;
+    xml_attribute<Ch> *m_next_attribute;
+  };
+
+  template<class Ch = char>
+  class xml_node : public xml_base<Ch> {
+  public:
+
+    xml_node(node_type type)
+        : m_type(type), m_first_node(0), m_first_attribute(0) {
+    }
+
+    node_type type() const {
+      return m_type;
+    }
+
+    xml_document<Ch> *document() const {
+      xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this);
+      while(node->parent())
+        node = node->parent();
+      return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
+    }
+
+    xml_node<Ch> *first_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const {
+      if(name) {
+        if(name_size == 0)
+          name_size = internal::measure(name);
+        for(xml_node<Ch> *child = m_first_node; child; child = child->next_sibling())
+          if(internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive))
+            return child;
+        return 0;
+      } else
+        return m_first_node;
+    }
+
+    xml_node<Ch> *last_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const {
+      assert(m_first_node);
+      if(name) {
+        if(name_size == 0)
+          name_size = internal::measure(name);
+        for(xml_node<Ch> *child = m_last_node; child; child = child->previous_sibling())
+          if(internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive))
+            return child;
+        return 0;
+      } else
+        return m_last_node;
+    }
+
+    xml_node<Ch> *previous_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const {
+      assert(this->m_parent);
+      if(name) {
+        if(name_size == 0)
+          name_size = internal::measure(name);
+        for(xml_node<Ch> *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling)
+          if(internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive))
+            return sibling;
+        return 0;
+      } else
+        return m_prev_sibling;
+    }
+
+    xml_node<Ch> *next_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const {
+      assert(this->m_parent);
+      if(name) {
+        if(name_size == 0)
+          name_size = internal::measure(name);
+        for(xml_node<Ch> *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling)
+          if(internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive))
+            return sibling;
+        return 0;
+      } else
+        return m_next_sibling;
+    }
+
+    xml_attribute<Ch> *
+    first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const {
+      if(name) {
+        if(name_size == 0)
+          name_size = internal::measure(name);
+        for(xml_attribute<Ch> *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute)
+          if(internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
+            return attribute;
+        return 0;
+      } else
+        return m_first_attribute;
+    }
+
+    xml_attribute<Ch> *last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const {
+      if(name) {
+        if(name_size == 0)
+          name_size = internal::measure(name);
+        for(xml_attribute<Ch> *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute)
+          if(internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
+            return attribute;
+        return 0;
+      } else
+        return m_first_attribute ? m_last_attribute : 0;
+    }
+
+    void type(node_type type) {
+      m_type = type;
+    }
+
+    void prepend_node(xml_node<Ch> *child) {
+      assert(child && !child->parent() && child->type() != node_document);
+      if(first_node()) {
+        child->m_next_sibling = m_first_node;
+        m_first_node->m_prev_sibling = child;
+      } else {
+        child->m_next_sibling = 0;
+        m_last_node = child;
+      }
+      m_first_node = child;
+      child->m_parent = this;
+      child->m_prev_sibling = 0;
+    }
+
+    void append_node(xml_node<Ch> *child) {
+      assert(child && !child->parent() && child->type() != node_document);
+      if(first_node()) {
+        child->m_prev_sibling = m_last_node;
+        m_last_node->m_next_sibling = child;
+      } else {
+        child->m_prev_sibling = 0;
+        m_first_node = child;
+      }
+      m_last_node = child;
+      child->m_parent = this;
+      child->m_next_sibling = 0;
+    }
+
+    void insert_node(xml_node<Ch> *where, xml_node<Ch> *child) {
+      assert(!where || where->parent() == this);
+      assert(child && !child->parent() && child->type() != node_document);
+      if(where == m_first_node)
+        prepend_node(child);
+      else if(where == 0)
+        append_node(child);
+      else {
+        child->m_prev_sibling = where->m_prev_sibling;
+        child->m_next_sibling = where;
+        where->m_prev_sibling->m_next_sibling = child;
+        where->m_prev_sibling = child;
+        child->m_parent = this;
+      }
+    }
+
+    void remove_first_node() {
+      assert(first_node());
+      xml_node<Ch> *child = m_first_node;
+      m_first_node = child->m_next_sibling;
+      if(child->m_next_sibling)
+        child->m_next_sibling->m_prev_sibling = 0;
+      else
+        m_last_node = 0;
+      child->m_parent = 0;
+    }
+
+    void remove_last_node() {
+      assert(first_node());
+      xml_node<Ch> *child = m_last_node;
+      if(child->m_prev_sibling) {
+        m_last_node = child->m_prev_sibling;
+        child->m_prev_sibling->m_next_sibling = 0;
+      } else
+        m_first_node = 0;
+      child->m_parent = 0;
+    }
+
+    void remove_node(xml_node<Ch> *where) {
+      assert(where && where->parent() == this);
+      assert(first_node());
+      if(where == m_first_node)
+        remove_first_node();
+      else if(where == m_last_node)
+        remove_last_node();
+      else {
+        where->m_prev_sibling->m_next_sibling = where->m_next_sibling;
+        where->m_next_sibling->m_prev_sibling = where->m_prev_sibling;
+        where->m_parent = 0;
+      }
+    }
+
+    void remove_all_nodes() {
+      for(xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling)
+        node->m_parent = 0;
+      m_first_node = 0;
+    }
+
+    void prepend_attribute(xml_attribute<Ch> *attribute) {
+      assert(attribute && !attribute->parent());
+      if(first_attribute()) {
+        attribute->m_next_attribute = m_first_attribute;
+        m_first_attribute->m_prev_attribute = attribute;
+      } else {
+        attribute->m_next_attribute = 0;
+        m_last_attribute = attribute;
+      }
+      m_first_attribute = attribute;
+      attribute->m_parent = this;
+      attribute->m_prev_attribute = 0;
+    }
+
+    void append_attribute(xml_attribute<Ch> *attribute) {
+      assert(attribute && !attribute->parent());
+      if(first_attribute()) {
+        attribute->m_prev_attribute = m_last_attribute;
+        m_last_attribute->m_next_attribute = attribute;
+      } else {
+        attribute->m_prev_attribute = 0;
+        m_first_attribute = attribute;
+      }
+      m_last_attribute = attribute;
+      attribute->m_parent = this;
+      attribute->m_next_attribute = 0;
+    }
+
+    void insert_attribute(xml_attribute<Ch> *where, xml_attribute<Ch> *attribute) {
+      assert(!where || where->parent() == this);
+      assert(attribute && !attribute->parent());
+      if(where == m_first_attribute)
+        prepend_attribute(attribute);
+      else if(where == 0)
+        append_attribute(attribute);
+      else {
+        attribute->m_prev_attribute = where->m_prev_attribute;
+        attribute->m_next_attribute = where;
+        where->m_prev_attribute->m_next_attribute = attribute;
+        where->m_prev_attribute = attribute;
+        attribute->m_parent = this;
+      }
+    }
+
+    void remove_first_attribute() {
+      assert(first_attribute());
+      xml_attribute<Ch> *attribute = m_first_attribute;
+      if(attribute->m_next_attribute) {
+        attribute->m_next_attribute->m_prev_attribute = 0;
+      } else
+        m_last_attribute = 0;
+      attribute->m_parent = 0;
+      m_first_attribute = attribute->m_next_attribute;
+    }
+
+    void remove_last_attribute() {
+      assert(first_attribute());
+      xml_attribute<Ch> *attribute = m_last_attribute;
+      if(attribute->m_prev_attribute) {
+        attribute->m_prev_attribute->m_next_attribute = 0;
+        m_last_attribute = attribute->m_prev_attribute;
+      } else
+        m_first_attribute = 0;
+      attribute->m_parent = 0;
+    }
+
+    void remove_attribute(xml_attribute<Ch> *where) {
+      assert(first_attribute() && where->parent() == this);
+      if(where == m_first_attribute)
+        remove_first_attribute();
+      else if(where == m_last_attribute)
+        remove_last_attribute();
+      else {
+        where->m_prev_attribute->m_next_attribute = where->m_next_attribute;
+        where->m_next_attribute->m_prev_attribute = where->m_prev_attribute;
+        where->m_parent = 0;
+      }
+    }
+
+    void remove_all_attributes() {
+      for(xml_attribute<Ch> *attribute = first_attribute(); attribute; attribute = attribute->m_next_attribute)
+        attribute->m_parent = 0;
+      m_first_attribute = 0;
+    }
+
+  private:
+
+    xml_node(const xml_node &);
+
+    void operator=(const xml_node &);
+
+
+
+    //
+
+
+    node_type m_type;
+    xml_node<Ch> *m_first_node;
+    xml_node<Ch> *m_last_node;
+    xml_attribute<Ch> *m_first_attribute;
+    xml_attribute<Ch> *m_last_attribute;
+    xml_node<Ch> *m_prev_sibling;
+    xml_node<Ch> *m_next_sibling;
+  };
+
+  template<class Ch = char>
+  class xml_document : public xml_node<Ch>, public memory_pool<Ch> {
+  public:
+
+    xml_document()
+        : xml_node<Ch>(node_document) {
+    }
+
+    template<int Flags>
+    void parse(Ch *text) {
+      assert(text);
+
+      this->remove_all_nodes();
+      this->remove_all_attributes();
+
+      parse_bom<Flags>(text);
+
+      while(1) {
+        skip<whitespace_pred, Flags>(text);
+        if(*text == 0)
+          break;
+
+        if(*text == Ch('<')) {
+          ++text;
+          if(xml_node<Ch> *node = parse_node<Flags>(text))
+            this->append_node(node);
+        } else
+          RAPIDXML_PARSE_ERROR("expected <", text);
+      }
+    }
+
+    void clear() {
+      this->remove_all_nodes();
+      this->remove_all_attributes();
+      memory_pool<Ch>::clear();
+    }
+
+  private:
+
+    struct whitespace_pred {
+      static unsigned char test(Ch ch) {
+        return internal::lookup_tables<0>::lookup_whitespace[static_cast<unsigned char>(ch)];
+      }
+    };
+
+    struct node_name_pred {
+      static unsigned char test(Ch ch) {
+        return internal::lookup_tables<0>::lookup_node_name[static_cast<unsigned char>(ch)];
+      }
+    };
+
+    struct attribute_name_pred {
+      static unsigned char test(Ch ch) {
+        return internal::lookup_tables<0>::lookup_attribute_name[static_cast<unsigned char>(ch)];
+      }
+    };
+
+    struct text_pred {
+      static unsigned char test(Ch ch) {
+        return internal::lookup_tables<0>::lookup_text[static_cast<unsigned char>(ch)];
+      }
+    };
+
+    struct text_pure_no_ws_pred {
+      static unsigned char test(Ch ch) {
+        return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast<unsigned char>(ch)];
+      }
+    };
+
+    struct text_pure_with_ws_pred {
+      static unsigned char test(Ch ch) {
+        return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast<unsigned char>(ch)];
+      }
+    };
+
+    template<Ch Quote>
+    struct attribute_value_pred {
+      static unsigned char test(Ch ch) {
+        if(Quote == Ch('\''))
+          return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast<unsigned char>(ch)];
+        if(Quote == Ch('\"'))
+          return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast<unsigned char>(ch)];
+        return 0;
+      }
+    };
+
+    template<Ch Quote>
+    struct attribute_value_pure_pred {
+      static unsigned char test(Ch ch) {
+        if(Quote == Ch('\''))
+          return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast<unsigned char>(ch)];
+        if(Quote == Ch('\"'))
+          return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast<unsigned char>(ch)];
+        return 0;
+      }
+    };
+
+    template<int Flags>
+    static void insert_coded_character(Ch *&text, unsigned long code) {
+      if(Flags & parse_no_utf8) {
+
+        text[0] = static_cast<unsigned char>(code);
+        text += 1;
+      } else {
+        if(code < 0x80) {
+          text[0] = static_cast<unsigned char>(code);
+          text += 1;
+        } else if(code < 0x800) {
+          text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+          code >>= 6;
+          text[0] = static_cast<unsigned char>(code | 0xC0);
+          text += 2;
+        } else if(code < 0x10000) {
+          text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+          code >>= 6;
+          text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+          code >>= 6;
+          text[0] = static_cast<unsigned char>(code | 0xE0);
+          text += 3;
+        } else if(code < 0x110000) {
+          text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+          code >>= 6;
+          text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+          code >>= 6;
+          text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+          code >>= 6;
+          text[0] = static_cast<unsigned char>(code | 0xF0);
+          text += 4;
+        } else {
+          RAPIDXML_PARSE_ERROR("invalid numeric character entity", text);
+        }
+      }
+    }
+
+    template<class StopPred, int Flags>
+    static void skip(Ch *&text) {
+      Ch *tmp = text;
+      while(StopPred::test(*tmp))
+        ++tmp;
+      text = tmp;
+    }
+
+    template<class StopPred, class StopPredPure, int Flags>
+    static Ch *skip_and_expand_character_refs(Ch *&text) {
+      if(Flags & parse_no_entity_translation &&
+         !(Flags & parse_normalize_whitespace) &&
+         !(Flags & parse_trim_whitespace)) {
+        skip<StopPred, Flags>(text);
+        return text;
+      }
+
+      skip<StopPredPure, Flags>(text);
+
+      Ch *src = text;
+      Ch *dest = src;
+      while(StopPred::test(*src)) {
+        if(!(Flags & parse_no_entity_translation)) {
+          if(src[0] == Ch('&')) {
+            switch(src[1]) {
+
+              case Ch('a'):
+                if(src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) {
+                  *dest = Ch('&');
+                  ++dest;
+                  src += 5;
+                  continue;
+                }
+                if(src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';')) {
+                  *dest = Ch('\'');
+                  ++dest;
+                  src += 6;
+                  continue;
+                }
+                break;
+
+              case Ch('q'):
+                if(src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';')) {
+                  *dest = Ch('"');
+                  ++dest;
+                  src += 6;
+                  continue;
+                }
+                break;
+
+              case Ch('g'):
+                if(src[2] == Ch('t') && src[3] == Ch(';')) {
+                  *dest = Ch('>');
+                  ++dest;
+                  src += 4;
+                  continue;
+                }
+                break;
+
+              case Ch('l'):
+                if(src[2] == Ch('t') && src[3] == Ch(';')) {
+                  *dest = Ch('<');
+                  ++dest;
+                  src += 4;
+                  continue;
+                }
+                break;
+
+              case Ch('#'):
+                if(src[2] == Ch('x')) {
+                  unsigned long code = 0;
+                  src += 3;
+                  while(1) {
+                    unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+                    if(digit == 0xFF)
+                      break;
+                    code = code * 16+digit;
+                    ++src;
+                  }
+                  insert_coded_character<Flags>(dest, code);
+                } else {
+                  unsigned long code = 0;
+                  src += 2;
+                  while(1) {
+                    unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+                    if(digit == 0xFF)
+                      break;
+                    code = code * 10+digit;
+                    ++src;
+                  }
+                  insert_coded_character<Flags>(dest, code);
+                }
+                if(*src == Ch(';'))
+                  ++src;
+                else
+                  RAPIDXML_PARSE_ERROR("expected ;", src);
+                continue;
+
+              default:
+                break;
+            }
+          }
+        }
+
+        if(Flags & parse_normalize_whitespace) {
+          if(whitespace_pred::test(*src)) {
+            *dest = Ch(' ');
+            ++dest;
+            ++src;
+            while(whitespace_pred::test(*src))
+              ++src;
+            continue;
+          }
+        }
+
+        *dest++ = *src++;
+      }
+
+      text = src;
+      return dest;
+    }
+
+    template<int Flags>
+    void parse_bom(Ch *&text) {
+      if(static_cast<unsigned char>(text[0]) == 0xEF &&
+         static_cast<unsigned char>(text[1]) == 0xBB &&
+         static_cast<unsigned char>(text[2]) == 0xBF) {
+        text += 3;
+      }
+    }
+
+    template<int Flags>
+    xml_node<Ch> *parse_xml_declaration(Ch *&text) {
+      if(!(Flags & parse_declaration_node)) {
+        while(text[0] != Ch('?') || text[1] != Ch('>')) {
+          if(!text[0])
+            RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+          ++text;
+        }
+        text += 2;
+        return 0;
+      }
+
+      xml_node<Ch> *declaration = this->allocate_node(node_declaration);
+
+      skip<whitespace_pred, Flags>(text);
+
+      parse_node_attributes<Flags>(text, declaration);
+
+      if(text[0] != Ch('?') || text[1] != Ch('>'))
+        RAPIDXML_PARSE_ERROR("expected ?>", text);
+      text += 2;
+      return declaration;
+    }
+
+    template<int Flags>
+    xml_node<Ch> *parse_comment(Ch *&text) {
+      if(!(Flags & parse_comment_nodes)) {
+        while(text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) {
+          if(!text[0])
+            RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+          ++text;
+        }
+        text += 3;
+        return 0;
+      }
+
+      Ch *value = text;
+
+      while(text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) {
+        if(!text[0])
+          RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+        ++text;
+      }
+
+      xml_node<Ch> *comment = this->allocate_node(node_comment);
+      comment->value(value, text-value);
+
+      if(!(Flags & parse_no_string_terminators))
+        *text = Ch('\0');
+      text += 3;
+      return comment;
+    }
+
+    template<int Flags>
+    xml_node<Ch> *parse_doctype(Ch *&text) {
+      Ch *value = text;
+
+      while(*text != Ch('>')) {
+        switch(*text) {
+
+          case Ch('['): {
+            ++text;
+            int depth = 1;
+            while(depth > 0) {
+              switch(*text) {
+                case Ch('['):
+                  ++depth;
+                  break;
+                case Ch(']'):
+                  --depth;
+                  break;
+                case 0:
+                  RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+              }
+              ++text;
+            }
+            break;
+          }
+
+          case Ch('\0'):
+            RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+
+          default:
+            ++text;
+        }
+      }
+
+      if(Flags & parse_doctype_node) {
+        xml_node<Ch> *doctype = this->allocate_node(node_doctype);
+        doctype->value(value, text-value);
+
+        if(!(Flags & parse_no_string_terminators))
+          *text = Ch('\0');
+        text += 1;
+        return doctype;
+      } else {
+        text += 1;
+        return 0;
+      }
+    }
+
+    template<int Flags>
+    xml_node<Ch> *parse_pi(Ch *&text) {
+      if(Flags & parse_pi_nodes) {
+        xml_node<Ch> *pi = this->allocate_node(node_pi);
+
+        Ch *name = text;
+        skip<node_name_pred, Flags>(text);
+        if(text == name)
+          RAPIDXML_PARSE_ERROR("expected PI target", text);
+        pi->name(name, text-name);
+
+        skip<whitespace_pred, Flags>(text);
+
+        Ch *value = text;
+
+        while(text[0] != Ch('?') || text[1] != Ch('>')) {
+          if(*text == Ch('\0'))
+            RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+          ++text;
+        }
+
+        pi->value(value, text-value);
+
+        if(!(Flags & parse_no_string_terminators)) {
+          pi->name()[pi->name_size()] = Ch('\0');
+          pi->value()[pi->value_size()] = Ch('\0');
+        }
+        text += 2;
+        return pi;
+      } else {
+        while(text[0] != Ch('?') || text[1] != Ch('>')) {
+          if(*text == Ch('\0'))
+            RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+          ++text;
+        }
+        text += 2;
+        return 0;
+      }
+    }
+
+    template<int Flags>
+    Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start) {
+      if(!(Flags & parse_trim_whitespace))
+        text = contents_start;
+
+      Ch *value = text, *end;
+      if(Flags & parse_normalize_whitespace)
+        end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred, Flags>(text);
+      else
+        end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred, Flags>(text);
+
+      if(Flags & parse_trim_whitespace) {
+        if(Flags & parse_normalize_whitespace) {
+          if(*(end-1) == Ch(' '))
+            --end;
+        } else {
+          while(whitespace_pred::test(*(end-1)))
+            --end;
+        }
+      }
+
+      if(!(Flags & parse_no_data_nodes)) {
+        xml_node<Ch> *data = this->allocate_node(node_data);
+        data->value(value, end-value);
+        node->append_node(data);
+      }
+
+      if(!(Flags & parse_no_element_values))
+        if(*node->value() == Ch('\0'))
+          node->value(value, end-value);
+
+      if(!(Flags & parse_no_string_terminators)) {
+        Ch ch = *text;
+        *end = Ch('\0');
+        return ch;
+      }
+
+      return *text;
+    }
+
+    template<int Flags>
+    xml_node<Ch> *parse_cdata(Ch *&text) {
+      if(Flags & parse_no_data_nodes) {
+        while(text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) {
+          if(!text[0])
+            RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+          ++text;
+        }
+        text += 3;
+        return 0;
+      }
+
+      Ch *value = text;
+      while(text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) {
+        if(!text[0])
+          RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+        ++text;
+      }
+
+      xml_node<Ch> *cdata = this->allocate_node(node_cdata);
+      cdata->value(value, text-value);
+
+      if(!(Flags & parse_no_string_terminators))
+        *text = Ch('\0');
+      text += 3;
+      return cdata;
+    }
+
+    template<int Flags>
+    xml_node<Ch> *parse_element(Ch *&text) {
+      xml_node<Ch> *element = this->allocate_node(node_element);
+
+      Ch *name = text;
+      skip<node_name_pred, Flags>(text);
+      if(text == name)
+        RAPIDXML_PARSE_ERROR("expected element name", text);
+      element->name(name, text-name);
+
+      skip<whitespace_pred, Flags>(text);
+
+      parse_node_attributes<Flags>(text, element);
+
+      if(*text == Ch('>')) {
+        ++text;
+        parse_node_contents<Flags>(text, element);
+      } else if(*text == Ch('/')) {
+        ++text;
+        if(*text != Ch('>'))
+          RAPIDXML_PARSE_ERROR("expected >", text);
+        ++text;
+      } else
+        RAPIDXML_PARSE_ERROR("expected >", text);
+
+      if(!(Flags & parse_no_string_terminators))
+        element->name()[element->name_size()] = Ch('\0');
+
+      return element;
+    }
+
+    template<int Flags>
+    xml_node<Ch> *parse_node(Ch *&text) {
+      switch(text[0]) {
+
+        default:
+          return parse_element<Flags>(text);
+
+        case Ch('?'):
+          ++text;
+          if((text[0] == Ch('x') || text[0] == Ch('X')) &&
+             (text[1] == Ch('m') || text[1] == Ch('M')) &&
+             (text[2] == Ch('l') || text[2] == Ch('L')) &&
+             whitespace_pred::test(text[3])) {
+            text += 4;
+            return parse_xml_declaration<Flags>(text);
+          } else {
+            return parse_pi<Flags>(text);
+          }
+
+        case Ch('!'):
+
+          switch(text[1]) {
+
+            case Ch('-'):
+              if(text[2] == Ch('-')) {
+                text += 3;
+                return parse_comment<Flags>(text);
+              }
+              break;
+
+            case Ch('['):
+              if(text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A') &&
+                 text[5] == Ch('T') && text[6] == Ch('A') && text[7] == Ch('[')) {
+                text += 8;
+                return parse_cdata<Flags>(text);
+              }
+              break;
+
+            case Ch('D'):
+              if(text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T') &&
+                 text[5] == Ch('Y') && text[6] == Ch('P') && text[7] == Ch('E') &&
+                 whitespace_pred::test(text[8])) {
+                text += 9;
+                return parse_doctype<Flags>(text);
+              }
+          }
+
+          ++text;
+          while(*text != Ch('>')) {
+            if(*text == 0)
+              RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+            ++text;
+          }
+          ++text;
+          return 0;
+      }
+    }
+
+    template<int Flags>
+    void parse_node_contents(Ch *&text, xml_node<Ch> *node) {
+      while(1) {
+        Ch *contents_start = text;
+        skip<whitespace_pred, Flags>(text);
+        Ch next_char = *text;
+
+        after_data_node:
+
+        switch(next_char) {
+
+          case Ch('<'):
+            if(text[1] == Ch('/')) {
+              text += 2;
+              if(Flags & parse_validate_closing_tags) {
+                Ch *closing_name = text;
+                skip<node_name_pred, Flags>(text);
+                if(!internal::compare(node->name(), node->name_size(), closing_name, text-closing_name, true))
+                  RAPIDXML_PARSE_ERROR("invalid closing tag name", text);
+              } else {
+                skip<node_name_pred, Flags>(text);
+              }
+              skip<whitespace_pred, Flags>(text);
+              if(*text != Ch('>'))
+                RAPIDXML_PARSE_ERROR("expected >", text);
+              ++text;
+              return;
+            } else {
+              ++text;
+              if(xml_node<Ch> *child = parse_node<Flags>(text))
+                node->append_node(child);
+            }
+            break;
+
+          case Ch('\0'):
+            RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+
+          default:
+            next_char = parse_and_append_data<Flags>(node, text, contents_start);
+            goto after_data_node;
+        }
+      }
+    }
+
+    template<int Flags>
+    void parse_node_attributes(Ch *&text, xml_node<Ch> *node) {
+      while(attribute_name_pred::test(*text)) {
+        Ch *name = text;
+        ++text;
+        skip<attribute_name_pred, Flags>(text);
+        if(text == name)
+          RAPIDXML_PARSE_ERROR("expected attribute name", name);
+
+        xml_attribute<Ch> *attribute = this->allocate_attribute();
+        attribute->name(name, text-name);
+        node->append_attribute(attribute);
+
+        skip<whitespace_pred, Flags>(text);
+
+        if(*text != Ch('='))
+          RAPIDXML_PARSE_ERROR("expected =", text);
+        ++text;
+
+        if(!(Flags & parse_no_string_terminators))
+          attribute->name()[attribute->name_size()] = 0;
+
+        skip<whitespace_pred, Flags>(text);
+
+        Ch quote = *text;
+        if(quote != Ch('\'') && quote != Ch('"'))
+          RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+        ++text;
+
+        Ch *value = text, *end;
+        const int AttFlags = Flags & ~parse_normalize_whitespace;
+        if(quote == Ch('\''))
+          end = skip_and_expand_character_refs<attribute_value_pred<Ch('\'')>, attribute_value_pure_pred<Ch(
+              '\'')>, AttFlags>(text);
+        else
+          end = skip_and_expand_character_refs<attribute_value_pred<Ch('"')>, attribute_value_pure_pred<Ch(
+              '"')>, AttFlags>(text);
+
+        attribute->value(value, end-value);
+
+        if(*text != quote)
+          RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+        ++text;
+
+        if(!(Flags & parse_no_string_terminators))
+          attribute->value()[attribute->value_size()] = 0;
+
+        skip<whitespace_pred, Flags>(text);
+      }
+    }
+  };
+
+  namespace internal {
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] =
+        {
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_node_name[256] =
+        {
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_text[256] =
+        {
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] =
+        {
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] =
+        {
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] =
+        {
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] =
+        {
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] =
+        {
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] =
+        {
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] =
+        {
+            0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_digits[256] =
+        {
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
+            255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
+        };
+
+    template<int Dummy>
+    const unsigned char lookup_tables<Dummy>::lookup_upcase[256] =
+        {
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+            32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+            48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+            64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+            80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+            96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+            80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127,
+            128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+            144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+            160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+            176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+            192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+            208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+            224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+            240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+        };
+  }
+
+}
+
+#undef RAPIDXML_PARSE_ERROR
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif

From fb87b8e0d69b09cbf7cdf41f2934e3f54918d0bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BA=88=E9=A1=BA=20=E5=88=98?= <yshliu0321@icloud.com>
Date: Thu, 24 May 2018 14:28:08 +0800
Subject: [PATCH 10/12] Remove Trailing Whitespace

---
 src/Doxyfile.in                   | 136 +++++++-------
 src/compile_commands.cc           |  26 +--
 src/ctags.cc                      |  28 +--
 src/debug_lldb.cc                 |  54 +++---
 src/directories.cc                | 146 +++++++--------
 src/directories.h                 |  26 +--
 src/documentation_cppreference.cc |   4 +-
 src/entrybox.h                    |   6 +-
 src/filesystem.cc                 |  16 +-
 src/git.cc                        |  18 +-
 src/git.h                         |  30 +--
 src/menu.h                        |   6 +-
 src/meson.cc                      |   8 +-
 src/notebook.cc                   |  70 +++----
 src/notebook.h                    |  22 +--
 src/project.cc                    | 176 +++++++++---------
 src/project.h                     |  58 +++---
 src/project_build.h               |   6 +-
 src/rapidxml/rapidxml.h           |   2 +-
 src/selection_dialog.cc           |  48 ++---
 src/selection_dialog.h            |  20 +-
 src/source.cc                     | 300 +++++++++++++++---------------
 src/source.h                      |  58 +++---
 src/source_base.cc                |  50 ++---
 src/source_base.h                 |  30 +--
 src/source_clang.cc               | 272 +++++++++++++--------------
 src/source_clang.h                |  30 +--
 src/source_diff.cc                |  30 +--
 src/source_diff.h                 |  22 +--
 src/source_language_protocol.cc   | 190 +++++++++----------
 src/source_language_protocol.h    |  18 +-
 src/source_spellcheck.cc          |  62 +++---
 src/source_spellcheck.h           |  14 +-
 src/terminal.cc                   |  48 ++---
 src/terminal.h                    |  10 +-
 src/tooltips.cc                   |  32 ++--
 src/tooltips.h                    |  18 +-
 src/usages_clang.cc               |   4 +-
 src/window.cc                     | 242 ++++++++++++------------
 39 files changed, 1168 insertions(+), 1168 deletions(-)

diff --git a/src/Doxyfile.in b/src/Doxyfile.in
index 500232b6..056b1357 100644
--- a/src/Doxyfile.in
+++ b/src/Doxyfile.in
@@ -38,27 +38,27 @@ PROJECT_NAME           = "juCi++"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 
+PROJECT_NUMBER         =
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
 # quick idea about the purpose of the project. Keep the description short.
 
-PROJECT_BRIEF          = 
+PROJECT_BRIEF          =
 
 # With the PROJECT_LOGO tag one can specify a logo or an icon that is included
 # in the documentation. The maximum height of the logo should not exceed 55
 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
 # the logo to the output directory.
 
-PROJECT_LOGO           = 
+PROJECT_LOGO           =
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
 # into which the generated documentation will be written. If a relative path is
 # entered, it will be relative to the location where doxygen was started. If
 # left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       = 
+OUTPUT_DIRECTORY       =
 
 # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
 # directories (in 2 levels) under the output directory of each output format and
@@ -118,7 +118,7 @@ REPEAT_BRIEF           = YES
 # the entity):The $name class, The $name widget, The $name file, is, provides,
 # specifies, contains, represents, a, an and the.
 
-ABBREVIATE_BRIEF       = 
+ABBREVIATE_BRIEF       =
 
 # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
 # doxygen will generate a detailed section even if there is only a brief
@@ -152,7 +152,7 @@ FULL_PATH_NAMES        = YES
 # will be relative from the directory where doxygen is started.
 # This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
-STRIP_FROM_PATH        = 
+STRIP_FROM_PATH        =
 
 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
 # path mentioned in the documentation of a class, which tells the reader which
@@ -161,7 +161,7 @@ STRIP_FROM_PATH        =
 # specify the list of include paths that are normally passed to the compiler
 # using the -I flag.
 
-STRIP_FROM_INC_PATH    = 
+STRIP_FROM_INC_PATH    =
 
 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
 # less readable) file names. This can be useful is your file systems doesn't
@@ -228,13 +228,13 @@ TAB_SIZE               = 4
 # "Side Effects:". You can put \n's in the value part of an alias to insert
 # newlines.
 
-ALIASES                = 
+ALIASES                =
 
 # This tag can be used to specify a number of word-keyword mappings (TCL only).
 # A mapping has the form "name=value". For example adding "class=itcl::class"
 # will allow you to use the command class in the itcl::class meaning.
 
-TCL_SUBST              = 
+TCL_SUBST              =
 
 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
 # only. Doxygen will then generate output that is more tailored for C. For
@@ -281,7 +281,7 @@ OPTIMIZE_OUTPUT_VHDL   = NO
 # Note that for custom extensions you also need to set FILE_PATTERNS otherwise
 # the files are not read by doxygen.
 
-EXTENSION_MAPPING      = 
+EXTENSION_MAPPING      =
 
 # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
 # according to the Markdown format, which allows for more readable
@@ -629,7 +629,7 @@ GENERATE_DEPRECATEDLIST= YES
 # sections, marked by \if <section_label> ... \endif and \cond <section_label>
 # ... \endcond blocks.
 
-ENABLED_SECTIONS       = 
+ENABLED_SECTIONS       =
 
 # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
 # initial value of a variable or macro / define can have for it to appear in the
@@ -671,7 +671,7 @@ SHOW_NAMESPACES        = YES
 # by doxygen. Whatever the program writes to standard output is used as the file
 # version. For an example see the documentation.
 
-FILE_VERSION_FILTER    = 
+FILE_VERSION_FILTER    =
 
 # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
 # by doxygen. The layout file controls the global structure of the generated
@@ -684,7 +684,7 @@ FILE_VERSION_FILTER    =
 # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
 # tag is left empty.
 
-LAYOUT_FILE            = 
+LAYOUT_FILE            =
 
 # The CITE_BIB_FILES tag can be used to specify one or more bib files containing
 # the reference definitions. This must be a list of .bib files. The .bib
@@ -694,7 +694,7 @@ LAYOUT_FILE            =
 # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
 # search path. See also \cite for info how to create references.
 
-CITE_BIB_FILES         = 
+CITE_BIB_FILES         =
 
 #---------------------------------------------------------------------------
 # Configuration options related to warning and progress messages
@@ -753,7 +753,7 @@ WARN_FORMAT            = "$file:$line: $text"
 # messages should be written. If left blank the output is written to standard
 # error (stderr).
 
-WARN_LOGFILE           = 
+WARN_LOGFILE           =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the input files
@@ -790,7 +790,7 @@ INPUT_ENCODING         = UTF-8
 # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
 # *.vhdl, *.ucf, *.qsf, *.as and *.js.
 
-FILE_PATTERNS          = 
+FILE_PATTERNS          =
 
 # The RECURSIVE tag can be used to specify whether or not subdirectories should
 # be searched for input files as well.
@@ -805,7 +805,7 @@ RECURSIVE              = YES
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                = 
+EXCLUDE                =
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded
@@ -821,7 +821,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = 
+EXCLUDE_PATTERNS       =
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -832,20 +832,20 @@ EXCLUDE_PATTERNS       =
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories use the pattern */test/*
 
-EXCLUDE_SYMBOLS        = 
+EXCLUDE_SYMBOLS        =
 
 # The EXAMPLE_PATH tag can be used to specify one or more files or directories
 # that contain example code fragments that are included (see the \include
 # command).
 
-EXAMPLE_PATH           = 
+EXAMPLE_PATH           =
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
 # *.h) to filter out the source-files in the directories. If left blank all
 # files are included.
 
-EXAMPLE_PATTERNS       = 
+EXAMPLE_PATTERNS       =
 
 # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
 # searched for input files to be used with the \include or \dontinclude commands
@@ -858,7 +858,7 @@ EXAMPLE_RECURSIVE      = NO
 # that contain images that are to be included in the documentation (see the
 # \image command).
 
-IMAGE_PATH             = 
+IMAGE_PATH             =
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program
@@ -875,7 +875,7 @@ IMAGE_PATH             =
 # code is scanned, but not when the output code is generated. If lines are added
 # or removed, the anchors will not be placed correctly.
 
-INPUT_FILTER           = 
+INPUT_FILTER           =
 
 # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
 # basis. Doxygen will compare the file name with each pattern and apply the
@@ -884,7 +884,7 @@ INPUT_FILTER           =
 # filters are used. If the FILTER_PATTERNS tag is empty or if none of the
 # patterns match the file name, INPUT_FILTER is applied.
 
-FILTER_PATTERNS        = 
+FILTER_PATTERNS        =
 
 # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
 # INPUT_FILTER) will also be used to filter the input files that are used for
@@ -899,14 +899,14 @@ FILTER_SOURCE_FILES    = NO
 # *.ext= (so without naming a filter).
 # This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
 
-FILTER_SOURCE_PATTERNS = 
+FILTER_SOURCE_PATTERNS =
 
 # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
 # is part of the input, its contents will be placed on the main page
 # (index.html). This can be useful if you have a project on for instance GitHub
 # and want to reuse the introduction page also for the doxygen output.
 
-USE_MDFILE_AS_MAINPAGE = 
+USE_MDFILE_AS_MAINPAGE =
 
 #---------------------------------------------------------------------------
 # Configuration options related to source browsing
@@ -1018,7 +1018,7 @@ COLS_IN_ALPHA_INDEX    = 5
 # while generating the index headers.
 # This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
 
-IGNORE_PREFIX          = 
+IGNORE_PREFIX          =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the HTML output
@@ -1062,7 +1062,7 @@ HTML_FILE_EXTENSION    = .html
 # of the possible markers and block names see the documentation.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_HEADER            = 
+HTML_HEADER            =
 
 # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
 # generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1072,7 +1072,7 @@ HTML_HEADER            =
 # that doxygen normally uses.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_FOOTER            = 
+HTML_FOOTER            =
 
 # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
 # sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1084,7 +1084,7 @@ HTML_FOOTER            =
 # obsolete.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_STYLESHEET        = 
+HTML_STYLESHEET        =
 
 # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
 # cascading style sheets that are included after the standard style sheets
@@ -1097,7 +1097,7 @@ HTML_STYLESHEET        =
 # list). For an example see the documentation.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_EXTRA_STYLESHEET  = 
+HTML_EXTRA_STYLESHEET  =
 
 # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the HTML output directory. Note
@@ -1107,7 +1107,7 @@ HTML_EXTRA_STYLESHEET  =
 # files will be copied as-is; there are no commands or markers available.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_EXTRA_FILES       = 
+HTML_EXTRA_FILES       =
 
 # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
 # will adjust the colors in the style sheet and background images according to
@@ -1236,7 +1236,7 @@ GENERATE_HTMLHELP      = NO
 # written to the html output directory.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-CHM_FILE               = 
+CHM_FILE               =
 
 # The HHC_LOCATION tag can be used to specify the location (absolute path
 # including file name) of the HTML help compiler (hhc.exe). If non-empty,
@@ -1244,7 +1244,7 @@ CHM_FILE               =
 # The file has to be specified with full path.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-HHC_LOCATION           = 
+HHC_LOCATION           =
 
 # The GENERATE_CHI flag controls if a separate .chi index file is generated
 # (YES) or that it should be included in the master .chm file (NO).
@@ -1257,7 +1257,7 @@ GENERATE_CHI           = NO
 # and project file content.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-CHM_INDEX_ENCODING     = 
+CHM_INDEX_ENCODING     =
 
 # The BINARY_TOC flag controls whether a binary table of contents is generated
 # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
@@ -1288,7 +1288,7 @@ GENERATE_QHP           = NO
 # the HTML output folder.
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QCH_FILE               = 
+QCH_FILE               =
 
 # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
 # Project output. For more information please see Qt Help Project / Namespace
@@ -1313,7 +1313,7 @@ QHP_VIRTUAL_FOLDER     = doc
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_CUST_FILTER_NAME   = 
+QHP_CUST_FILTER_NAME   =
 
 # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
 # custom filter to add. For more information please see Qt Help Project / Custom
@@ -1321,21 +1321,21 @@ QHP_CUST_FILTER_NAME   =
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_CUST_FILTER_ATTRS  = 
+QHP_CUST_FILTER_ATTRS  =
 
 # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
 # project's filter section matches. Qt Help Project / Filter Attributes (see:
 # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_SECT_FILTER_ATTRS  = 
+QHP_SECT_FILTER_ATTRS  =
 
 # The QHG_LOCATION tag can be used to specify the location of Qt's
 # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
 # generated .qhp file.
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHG_LOCATION           = 
+QHG_LOCATION           =
 
 # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
 # generated, together with the HTML files, they form an Eclipse help plugin. To
@@ -1468,7 +1468,7 @@ MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
 # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
 # This tag requires that the tag USE_MATHJAX is set to YES.
 
-MATHJAX_EXTENSIONS     = 
+MATHJAX_EXTENSIONS     =
 
 # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
 # of code that will be used on startup of the MathJax code. See the MathJax site
@@ -1476,7 +1476,7 @@ MATHJAX_EXTENSIONS     =
 # example see the documentation.
 # This tag requires that the tag USE_MATHJAX is set to YES.
 
-MATHJAX_CODEFILE       = 
+MATHJAX_CODEFILE       =
 
 # When the SEARCHENGINE tag is enabled doxygen will generate a search box for
 # the HTML output. The underlying search engine uses javascript and DHTML and
@@ -1536,7 +1536,7 @@ EXTERNAL_SEARCH        = NO
 # Searching" for details.
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-SEARCHENGINE_URL       = 
+SEARCHENGINE_URL       =
 
 # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
 # search data is written to a file for indexing by an external tool. With the
@@ -1552,7 +1552,7 @@ SEARCHDATA_FILE        = searchdata.xml
 # projects and redirect the results back to the right project.
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-EXTERNAL_SEARCH_ID     = 
+EXTERNAL_SEARCH_ID     =
 
 # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
 # projects other than the one defined by this configuration file, but that are
@@ -1562,7 +1562,7 @@ EXTERNAL_SEARCH_ID     =
 # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-EXTRA_SEARCH_MAPPINGS  = 
+EXTRA_SEARCH_MAPPINGS  =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the LaTeX output
@@ -1626,7 +1626,7 @@ PAPER_TYPE             = a4
 # If left blank no extra packages will be included.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-EXTRA_PACKAGES         = 
+EXTRA_PACKAGES         =
 
 # The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
 # generated LaTeX document. The header should contain everything until the first
@@ -1642,7 +1642,7 @@ EXTRA_PACKAGES         =
 # to HTML_HEADER.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_HEADER           = 
+LATEX_HEADER           =
 
 # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
 # generated LaTeX document. The footer should contain everything after the last
@@ -1653,7 +1653,7 @@ LATEX_HEADER           =
 # Note: Only use a user-defined footer if you know what you are doing!
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_FOOTER           = 
+LATEX_FOOTER           =
 
 # The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
 # LaTeX style sheets that are included after the standard style sheets created
@@ -1664,7 +1664,7 @@ LATEX_FOOTER           =
 # list).
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_EXTRA_STYLESHEET = 
+LATEX_EXTRA_STYLESHEET =
 
 # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the LATEX_OUTPUT output
@@ -1672,7 +1672,7 @@ LATEX_EXTRA_STYLESHEET =
 # markers available.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_EXTRA_FILES      = 
+LATEX_EXTRA_FILES      =
 
 # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
 # prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
@@ -1772,14 +1772,14 @@ RTF_HYPERLINKS         = NO
 # default style sheet that doxygen normally uses.
 # This tag requires that the tag GENERATE_RTF is set to YES.
 
-RTF_STYLESHEET_FILE    = 
+RTF_STYLESHEET_FILE    =
 
 # Set optional variables used in the generation of an RTF document. Syntax is
 # similar to doxygen's config file. A template extensions file can be generated
 # using doxygen -e rtf extensionFile.
 # This tag requires that the tag GENERATE_RTF is set to YES.
 
-RTF_EXTENSIONS_FILE    = 
+RTF_EXTENSIONS_FILE    =
 
 # If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
 # with syntax highlighting in the RTF output.
@@ -1824,7 +1824,7 @@ MAN_EXTENSION          = .3
 # MAN_EXTENSION with the initial . removed.
 # This tag requires that the tag GENERATE_MAN is set to YES.
 
-MAN_SUBDIR             = 
+MAN_SUBDIR             =
 
 # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
 # will generate one additional man file for each entity documented in the real
@@ -1937,7 +1937,7 @@ PERLMOD_PRETTY         = YES
 # overwrite each other's variables.
 # This tag requires that the tag GENERATE_PERLMOD is set to YES.
 
-PERLMOD_MAKEVAR_PREFIX = 
+PERLMOD_MAKEVAR_PREFIX =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the preprocessor
@@ -1978,7 +1978,7 @@ SEARCH_INCLUDES        = YES
 # preprocessor.
 # This tag requires that the tag SEARCH_INCLUDES is set to YES.
 
-INCLUDE_PATH           = 
+INCLUDE_PATH           =
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
 # patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1986,7 +1986,7 @@ INCLUDE_PATH           =
 # used.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-INCLUDE_FILE_PATTERNS  = 
+INCLUDE_FILE_PATTERNS  =
 
 # The PREDEFINED tag can be used to specify one or more macro names that are
 # defined before the preprocessor is started (similar to the -D option of e.g.
@@ -1996,7 +1996,7 @@ INCLUDE_FILE_PATTERNS  =
 # recursively expanded use the := operator instead of the = operator.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-PREDEFINED             = 
+PREDEFINED             =
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
@@ -2005,7 +2005,7 @@ PREDEFINED             =
 # definition found in the source code.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-EXPAND_AS_DEFINED      = 
+EXPAND_AS_DEFINED      =
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
 # remove all references to function-like macros that are alone on a line, have
@@ -2034,13 +2034,13 @@ SKIP_FUNCTION_MACROS   = YES
 # the path). If a tag file is not located in the directory in which doxygen is
 # run, you must also specify the path to the tagfile here.
 
-TAGFILES               = 
+TAGFILES               =
 
 # When a file name is specified after GENERATE_TAGFILE, doxygen will create a
 # tag file that is based on the input files it reads. See section "Linking to
 # external documentation" for more information about the usage of tag files.
 
-GENERATE_TAGFILE       = 
+GENERATE_TAGFILE       =
 
 # If the ALLEXTERNALS tag is set to YES, all external class will be listed in
 # the class index. If set to NO, only the inherited external classes will be
@@ -2089,14 +2089,14 @@ CLASS_DIAGRAMS         = YES
 # the mscgen tool resides. If left empty the tool is assumed to be found in the
 # default search path.
 
-MSCGEN_PATH            = 
+MSCGEN_PATH            =
 
 # You can include diagrams made with dia in doxygen documentation. Doxygen will
 # then run dia to produce the diagram and insert it in the documentation. The
 # DIA_PATH tag allows you to specify the directory where the dia binary resides.
 # If left empty dia is assumed to be found in the default search path.
 
-DIA_PATH               = 
+DIA_PATH               =
 
 # If set to YES the inheritance and collaboration graphs will hide inheritance
 # and usage relations if the target is undocumented or is not a class.
@@ -2145,7 +2145,7 @@ DOT_FONTSIZE           = 10
 # the path where dot can find it using this tag.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOT_FONTPATH           = 
+DOT_FONTPATH           =
 
 # If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
 # each documented class showing the direct and indirect inheritance relations.
@@ -2289,26 +2289,26 @@ INTERACTIVE_SVG        = NO
 # found. If left blank, it is assumed the dot tool can be found in the path.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOT_PATH               = 
+DOT_PATH               =
 
 # The DOTFILE_DIRS tag can be used to specify one or more directories that
 # contain dot files that are included in the documentation (see the \dotfile
 # command).
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOTFILE_DIRS           = 
+DOTFILE_DIRS           =
 
 # The MSCFILE_DIRS tag can be used to specify one or more directories that
 # contain msc files that are included in the documentation (see the \mscfile
 # command).
 
-MSCFILE_DIRS           = 
+MSCFILE_DIRS           =
 
 # The DIAFILE_DIRS tag can be used to specify one or more directories that
 # contain dia files that are included in the documentation (see the \diafile
 # command).
 
-DIAFILE_DIRS           = 
+DIAFILE_DIRS           =
 
 # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
 # path where java can find the plantuml.jar file. If left blank, it is assumed
@@ -2321,7 +2321,7 @@ PLANTUML_JAR_PATH      = @PLANTUML_JARFILE@
 # When using plantuml, the specified paths are searched for files specified by
 # the !include statement in a plantuml block.
 
-PLANTUML_INCLUDE_PATH  = 
+PLANTUML_INCLUDE_PATH  =
 
 # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
 # that will be shown in the graph. If the number of nodes in a graph becomes
diff --git a/src/compile_commands.cc b/src/compile_commands.cc
index 27f946bd..07c3d221 100644
--- a/src/compile_commands.cc
+++ b/src/compile_commands.cc
@@ -5,7 +5,7 @@
 
 std::vector<std::string> CompileCommands::Command::parameter_values(const std::string &parameter_name) const {
   std::vector<std::string> parameter_values;
-  
+
   bool found_argument=false;
   for(auto &parameter: parameters) {
     if(found_argument) {
@@ -15,7 +15,7 @@ std::vector<std::string> CompileCommands::Command::parameter_values(const std::s
     else if(parameter==parameter_name)
       found_argument=true;
   }
-  
+
   return parameter_values;
 }
 
@@ -23,13 +23,13 @@ CompileCommands::CompileCommands(const boost::filesystem::path &build_path) {
   try {
     boost::property_tree::ptree root_pt;
     boost::property_tree::json_parser::read_json((build_path/"compile_commands.json").string(), root_pt);
-    
+
     auto commands_pt=root_pt.get_child("");
     for(auto &command: commands_pt) {
       boost::filesystem::path directory=command.second.get<std::string>("directory");
       auto parameters_str=command.second.get<std::string>("command");
       boost::filesystem::path file=command.second.get<std::string>("file");
-      
+
       std::vector<std::string> parameters;
       bool backslash=false;
       bool single_quote=false;
@@ -66,14 +66,14 @@ CompileCommands::CompileCommands(const boost::filesystem::path &build_path) {
           double_quote=!double_quote;
           continue;
         }
-        
+
         if(parameter_start_pos==std::string::npos)
           parameter_start_pos=c;
         ++parameter_size;
       }
       if(parameter_start_pos!=std::string::npos)
         add_parameter();
-      
+
       commands.emplace_back(Command{directory, parameters, boost::filesystem::absolute(file, build_path)});
     }
   }
@@ -82,7 +82,7 @@ CompileCommands::CompileCommands(const boost::filesystem::path &build_path) {
 
 std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
   std::string default_std_argument="-std=c++1y";
-  
+
   std::vector<std::string> arguments;
   if(!build_path.empty()) {
     clangmm::CompilationDatabase db(build_path.string());
@@ -110,7 +110,7 @@ std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem:
   }
   else
     arguments.emplace_back(default_std_argument);
-  
+
   auto clang_version_string=clangmm::to_string(clang_getClangVersion());
   const static std::regex clang_version_regex(R"(^[A-Za-z ]+([0-9.]+).*$)");
   std::smatch sm;
@@ -130,23 +130,23 @@ std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem:
 #endif
   }
   arguments.emplace_back("-fretain-comments-from-system-headers");
-  
+
   auto extension=file_path.extension().string();
   if(extension==".h" ||  //TODO: temporary fix for .h-files (parse as c++)
      extension!=".c")
     arguments.emplace_back("-xc++");
-  
+
   if(extension.empty() || (1<extension.size() && extension[1]=='h') || extension==".tcc" || extension==".cuh") {
     arguments.emplace_back("-Wno-pragma-once-outside-header");
     arguments.emplace_back("-Wno-pragma-system-header-outside-header");
     arguments.emplace_back("-Wno-include-next-outside-header");
   }
-  
+
   if(extension==".cu" || extension==".cuh") {
     arguments.emplace_back("-include");
     arguments.emplace_back("cuda_runtime.h");
   }
-  
+
   if(extension==".cl") {
     arguments.emplace_back("-xcl");
     arguments.emplace_back("-cl-std=CL2.0");
@@ -154,7 +154,7 @@ std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem:
     arguments.emplace_back("-finclude-default-header");
     arguments.emplace_back("-Wno-gcc-compat");
   }
-  
+
   if(!build_path.empty()) {
     arguments.emplace_back("-working-directory");
     arguments.emplace_back(build_path.string());
diff --git a/src/ctags.cc b/src/ctags.cc
index 1f34f6dc..72bcda59 100644
--- a/src/ctags.cc
+++ b/src/ctags.cc
@@ -16,7 +16,7 @@ std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> > Ctags::g
     auto relative_default_path=filesystem::get_relative_path(build->get_default_path(), run_path);
     if(!relative_default_path.empty())
       exclude+=" --exclude="+relative_default_path.string();
-    
+
     auto relative_debug_path=filesystem::get_relative_path(build->get_debug_path(), run_path);
     if(!relative_debug_path.empty())
       exclude+=" --exclude="+relative_debug_path.string();
@@ -28,7 +28,7 @@ std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> > Ctags::g
     else
       run_path=path.parent_path();
   }
-  
+
   std::stringstream stdin_stream;
   //TODO: when debian stable gets newer g++ version that supports move on streams, remove unique_ptr below
   auto stdout_stream=std::make_unique<std::stringstream>();
@@ -58,7 +58,7 @@ Ctags::Location Ctags::get_location(const std::string &line, bool markup) {
       if(!((chr>='a' && chr<='z') || (chr>='A' && chr<='Z') || (chr>='0' && chr<='9') || chr=='_'))
         location.symbol.erase(8, 1);
     }
-    
+
     location.file_path=sm[2].str();
     location.source=sm[4].str();
     try {
@@ -70,11 +70,11 @@ Ctags::Location Ctags::get_location(const std::string &line, bool markup) {
     location.scope=sm[7].str();
     if(!sm[5].str().empty()) {
       location.index=sm[3].str().size();
-      
+
       size_t pos=location.source.find(location.symbol);
       if(pos!=std::string::npos)
         location.index+=pos;
-      
+
       if(markup) {
         location.source=Glib::Markup::escape_text(location.source);
         auto symbol=Glib::Markup::escape_text(location.symbol);
@@ -95,7 +95,7 @@ Ctags::Location Ctags::get_location(const std::string &line, bool markup) {
   }
   else
     std::cerr << "Warning (ctags): please report to the juCi++ project that the following line was not parsed:\n" << line << std::endl;
-  
+
   return location;
 }
 
@@ -127,7 +127,7 @@ std::vector<Ctags::Location> Ctags::get_locations(const boost::filesystem::path
   if(result.second->tellg()==0)
     return std::vector<Location>();
   result.second->seekg(0, std::ios::beg);
-  
+
   //insert name into type
   size_t c=0;
   size_t bracket_count=0;
@@ -141,9 +141,9 @@ std::vector<Ctags::Location> Ctags::get_locations(const boost::filesystem::path
   }
   auto full_type=type;
   full_type.insert(c, name);
-  
+
   auto parts=get_type_parts(full_type);
-  
+
   std::string line;
   long best_score=LONG_MIN;
   std::vector<Location> best_locations;
@@ -157,11 +157,11 @@ std::vector<Ctags::Location> Ctags::get_locations(const boost::filesystem::path
     }
     else if(location.symbol!=name)
       continue;
-    
+
     location.file_path=result.first/location.file_path;
-    
+
     auto source_parts=get_type_parts(location.source);
-    
+
     //Find match score
     long score=0;
     size_t source_index=0;
@@ -192,7 +192,7 @@ std::vector<Ctags::Location> Ctags::get_locations(const boost::filesystem::path
       if(!found)
         --score;
     }
-    
+
     if(score>best_score) {
       best_score=score;
       best_locations.clear();
@@ -201,6 +201,6 @@ std::vector<Ctags::Location> Ctags::get_locations(const boost::filesystem::path
     else if(score==best_score)
       best_locations.emplace_back(location);
   }
-  
+
   return best_locations;
 }
diff --git a/src/debug_lldb.cc b/src/debug_lldb.cc
index 71b1d3c3..1058aa5b 100644
--- a/src/debug_lldb.cc
+++ b/src/debug_lldb.cc
@@ -34,12 +34,12 @@ std::tuple<std::vector<std::string>, std::string, std::vector<std::string> > Deb
   std::vector<std::string> environment;
   std::string executable;
   std::vector<std::string> arguments;
-  
+
   size_t start_pos=std::string::npos;
   bool quote=false;
   bool double_quote=false;
   size_t backslash_count=0;
-  for(size_t c=0;c<=command.size();c++) { 
+  for(size_t c=0;c<=command.size();c++) {
     if(c==command.size() || (!quote && !double_quote && backslash_count%2==0 && command[c]==' ')) {
       if(c>0 && start_pos!=std::string::npos) {
         auto argument=command.substr(start_pos, c-start_pos);
@@ -58,7 +58,7 @@ std::tuple<std::vector<std::string>, std::string, std::vector<std::string> > Deb
             else
               break;
           }
-          
+
           if(!env_arg) {
             executable=filesystem::unescape_argument(argument);
 #ifdef _WIN32
@@ -83,7 +83,7 @@ std::tuple<std::vector<std::string>, std::string, std::vector<std::string> > Deb
     if(c<command.size() && start_pos==std::string::npos && command[c]!=' ')
       start_pos=c;
   }
-  
+
   return std::make_tuple(environment, executable, arguments);
 }
 
@@ -95,19 +95,19 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
     debugger=std::make_unique<lldb::SBDebugger>(lldb::SBDebugger::Create(true, log, nullptr));
     listener=std::make_unique<lldb::SBListener>("juCi++ lldb listener");
   }
-  
+
   //Create executable string and argument array
   auto parsed_run_arguments=parse_run_arguments(command);
   auto &environment_from_arguments=std::get<0>(parsed_run_arguments);
   auto &executable=std::get<1>(parsed_run_arguments);
   auto &arguments=std::get<2>(parsed_run_arguments);
-  
+
   std::vector<const char*> argv;
   argv.reserve(arguments.size());
   for(auto &argument : arguments)
     argv.emplace_back(argument.c_str());
   argv.emplace_back(nullptr);
-  
+
   auto target=debugger->CreateTarget(executable.c_str());
   if(!target.IsValid()) {
     Terminal::get().async_print("Error (debug): Could not create debug target to: "+executable+'\n', true);
@@ -115,7 +115,7 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
       handler(-1);
     return;
   }
-  
+
   //Set breakpoints
   for(auto &breakpoint: breakpoints) {
     if(!(target.BreakpointCreateByLocation(breakpoint.first.string().c_str(), breakpoint.second)).IsValid()) {
@@ -125,7 +125,7 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
       return;
     }
   }
-  
+
   lldb::SBError error;
   if(!remote_host.empty()) {
     auto connect_string="connect://"+remote_host;
@@ -147,14 +147,14 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
         }
       }
     }
-    
+
     // Create environment array
     std::vector<const char*> environment;
     environment.reserve(environment_from_arguments.size());
     for(auto &e: environment_from_arguments)
       environment.emplace_back(e.c_str());
     environment.emplace_back(nullptr);
-    
+
     process->RemoteLaunch(argv.data(), environment.data(), nullptr, nullptr, nullptr, nullptr, lldb::eLaunchFlagNone, false, error);
     if(!error.Fail())
       process->Continue();
@@ -171,7 +171,7 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
     for(size_t c=0;c<environ_size;++c)
       environment.emplace_back(environ[c]);
     environment.emplace_back(nullptr);
-    
+
     process = std::make_unique<lldb::SBProcess>(target.Launch(*listener, argv.data(), environment.data(), nullptr, nullptr, nullptr, path.string().c_str(), lldb::eLaunchFlagNone, false, error));
   }
   if(error.Fail()) {
@@ -184,12 +184,12 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
     debug_thread.join();
   for(auto &handler: on_start)
     handler(*process);
-  
+
   for(auto &command: startup_commands) {
     lldb::SBCommandReturnObject command_return_object;
     debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, false);
   }
-  
+
   debug_thread=std::thread([this]() {
     lldb::SBEvent event;
     while(true) {
@@ -198,7 +198,7 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
         if((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged)>0) {
           auto state=process->GetStateFromEvent(event);
           this->state=state;
-          
+
           if(state==lldb::StateType::eStateStopped) {
             for(uint32_t c=0;c<process->GetNumThreads();c++) {
               auto thread=process->GetThreadAtIndex(c);
@@ -208,12 +208,12 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
               }
             }
           }
-          
+
           lock.unlock();
           for(auto &handler: on_event)
             handler(event);
           lock.lock();
-          
+
           if(state==lldb::StateType::eStateExited || state==lldb::StateType::eStateCrashed) {
             auto exit_status=state==lldb::StateType::eStateCrashed?-1:process->GetExitStatus();
             lock.unlock();
@@ -314,17 +314,17 @@ std::vector<Debug::LLDB::Frame> Debug::LLDB::get_backtrace() {
     for(uint32_t c_f=0;c_f<thread.GetNumFrames();c_f++) {
       Frame backtrace_frame;
       auto frame=thread.GetFrameAtIndex(c_f);
-      
+
       backtrace_frame.index=c_f;
-      
+
       if(frame.GetFunctionName()!=nullptr)
         backtrace_frame.function_name=frame.GetFunctionName();
-      
+
       auto module_filename=frame.GetModule().GetFileSpec().GetFilename();
       if(module_filename!=nullptr) {
         backtrace_frame.module_filename=module_filename;
       }
-      
+
       auto line_entry=frame.GetLineEntry();
       if(line_entry.IsValid()) {
         lldb::SBStream stream;
@@ -354,7 +354,7 @@ std::vector<Debug::LLDB::Variable> Debug::LLDB::get_variables() {
         for(uint32_t value_index=0;value_index<values.GetSize();value_index++) {
           lldb::SBStream stream;
           auto value=values.GetValueAtIndex(value_index);
-        
+
           Debug::LLDB::Variable variable;
           variable.thread_index_id=thread.GetIndexID();
           variable.frame_index=c_f;
@@ -362,7 +362,7 @@ std::vector<Debug::LLDB::Variable> Debug::LLDB::get_variables() {
             variable.name=value.GetName();
           value.GetDescription(stream);
           variable.value=stream.GetData();
-          
+
           auto declaration=value.GetDeclaration();
           if(declaration.IsValid()) {
             variable.declaration_found=true;
@@ -370,7 +370,7 @@ std::vector<Debug::LLDB::Variable> Debug::LLDB::get_variables() {
             variable.line_index=declaration.GetColumn();
             if(variable.line_index==0)
               variable.line_index=1;
-            
+
             auto file_spec=declaration.GetFileSpec();
             variable.file_path=filesystem::get_normal_path(file_spec.GetDirectory());
             variable.file_path/=file_spec.GetFilename();
@@ -383,7 +383,7 @@ std::vector<Debug::LLDB::Variable> Debug::LLDB::get_variables() {
               variable.line_index=line_entry.GetColumn();
               if(variable.line_index==0)
                 variable.line_index=1;
-              
+
               auto file_spec=line_entry.GetFileSpec();
               variable.file_path=filesystem::get_normal_path(file_spec.GetDirectory());
               variable.file_path/=file_spec.GetFilename();
@@ -417,14 +417,14 @@ std::string Debug::LLDB::get_value(const std::string &variable, const boost::fil
   std::unique_lock<std::mutex> lock(mutex);
   if(state==lldb::StateType::eStateStopped) {
     auto frame=process->GetSelectedThread().GetSelectedFrame();
-    
+
     auto values=frame.GetVariables(true, true, true, false);
     //First try to find variable based on name, file and line number
     if(!file_path.empty()) {
       for(uint32_t value_index=0;value_index<values.GetSize();value_index++) {
         lldb::SBStream stream;
         auto value=values.GetValueAtIndex(value_index);
-  
+
         if(value.GetName()!=nullptr && value.GetName()==variable) {
           auto declaration=value.GetDeclaration();
           if(declaration.IsValid()) {
diff --git a/src/directories.cc b/src/directories.cc
index f8449493..3c14337a 100644
--- a/src/directories.cc
+++ b/src/directories.cc
@@ -12,7 +12,7 @@ bool Directories::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path
 
 bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) {
   auto &directories=Directories::get();
-  
+
   auto get_target_folder=[this, &directories](const TreeModel::Path &path) {
     if(path.size()==1)
       return directories.path;
@@ -40,36 +40,36 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat
     }
     return boost::filesystem::path();
   };
-  
+
   auto it=directories.get_selection()->get_selected();
   if(it) {
     auto source_path=it->get_value(directories.column_record.path);
     if(source_path.empty())
       return false;
-    
+
     auto target_path=get_target_folder(path);
     target_path/=source_path.filename();
-    
+
     if(source_path==target_path)
       return false;
-    
+
     if(boost::filesystem::exists(target_path)) {
       Terminal::get().print("Error: could not move file: "+target_path.string()+" already exists\n", true);
       return false;
     }
-    
+
     bool is_directory=boost::filesystem::is_directory(source_path);
-    
+
     if(is_directory)
       Directories::get().remove_path(source_path);
-    
+
     boost::system::error_code ec;
     boost::filesystem::rename(source_path, target_path, ec);
     if(ec) {
       Terminal::get().print("Error: could not move file: "+ec.message()+'\n', true);
       return false;
     }
-    
+
     for(size_t c=0;c<Notebook::get().size();c++) {
       auto view=Notebook::get().get_view(c);
       if(is_directory) {
@@ -88,12 +88,12 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat
         break;
       }
     }
-    
+
     Directories::get().update();
     Directories::get().on_save_file(target_path);
     directories.select(target_path);
   }
-  
+
   EntryBox::get().hide();
   return false;
 }
@@ -104,25 +104,25 @@ bool Directories::TreeStore::drag_data_delete_vfunc (const Gtk::TreeModel::Path
 
 Directories::Directories() : Gtk::ListViewText(1) {
   set_enable_tree_lines(true);
-  
+
   tree_store = TreeStore::create();
   tree_store->set_column_types(column_record);
   set_model(tree_store);
-  
+
   get_column(0)->set_title("");
-  
+
   auto renderer=dynamic_cast<Gtk::CellRendererText*>(get_column(0)->get_first_cell());
   get_column(0)->set_cell_data_func(*renderer, [this] (Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &iter) {
     if(auto renderer_text=dynamic_cast<Gtk::CellRendererText*>(renderer))
       renderer_text->property_markup()=iter->get_value(column_record.markup);
   });
-  
+
   get_style_context()->add_class("juci_directories");
-  
+
   tree_store->set_sort_column(column_record.id, Gtk::SortType::SORT_ASCENDING);
   set_enable_search(true); //TODO: why does this not work in OS X?
   set_search_column(column_record.name);
-  
+
   signal_row_activated().connect([this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column){
     auto iter = tree_store->get_iter(path);
     if (iter) {
@@ -135,7 +135,7 @@ Directories::Directories() : Gtk::ListViewText(1) {
       }
     }
   });
-  
+
   signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path){
     if(iter->children().begin()->get_value(column_record.path)=="")
       add_or_update_path(iter->get_value(column_record.path), *iter, true);
@@ -144,10 +144,10 @@ Directories::Directories() : Gtk::ListViewText(1) {
   signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path){
     this->remove_path(iter->get_value(column_record.path));
   });
-  
+
   enable_model_drag_source();
   enable_model_drag_dest();
-  
+
   auto new_file_label = "New File";
   auto new_file_function = [this] {
     if(menu_popup_row_path.empty())
@@ -171,7 +171,7 @@ Directories::Directories() : Gtk::ListViewText(1) {
         Terminal::get().print("Error: could not create "+target_path.string()+": already exists\n", true);
         return;
       }
-      
+
       EntryBox::get().hide();
     });
     auto entry_it=EntryBox::get().entries.begin();
@@ -181,15 +181,15 @@ Directories::Directories() : Gtk::ListViewText(1) {
     });
     EntryBox::get().show();
   };
-  
+
   menu_item_new_file.set_label(new_file_label);
   menu_item_new_file.signal_activate().connect(new_file_function);
   menu.append(menu_item_new_file);
-  
+
   menu_root_item_new_file.set_label(new_file_label);
   menu_root_item_new_file.signal_activate().connect(new_file_function);
   menu_root.append(menu_root_item_new_file);
-  
+
   auto new_folder_label = "New Folder";
   auto new_folder_function = [this] {
     if(menu_popup_row_path.empty())
@@ -214,7 +214,7 @@ Directories::Directories() : Gtk::ListViewText(1) {
         Terminal::get().print("Error: could not create "+target_path.string()+": already exists\n", true);
         return;
       }
-      
+
       EntryBox::get().hide();
     });
     auto entry_it=EntryBox::get().entries.begin();
@@ -224,17 +224,17 @@ Directories::Directories() : Gtk::ListViewText(1) {
     });
     EntryBox::get().show();
   };
-  
+
   menu_item_new_folder.set_label(new_folder_label);
   menu_item_new_folder.signal_activate().connect(new_folder_function);
   menu.append(menu_item_new_folder);
-  
+
   menu_root_item_new_folder.set_label(new_folder_label);
   menu_root_item_new_folder.signal_activate().connect(new_folder_function);
   menu_root.append(menu_root_item_new_folder);
-  
+
   menu.append(menu_item_separator);
-  
+
   menu_item_rename.set_label("Rename");
   menu_item_rename.signal_activate().connect([this] {
     if(menu_popup_row_path.empty())
@@ -242,17 +242,17 @@ Directories::Directories() : Gtk::ListViewText(1) {
     EntryBox::get().clear();
     EntryBox::get().entries.emplace_back(menu_popup_row_path.filename().string(), [this, source_path=menu_popup_row_path](const std::string &content){
       bool is_directory=boost::filesystem::is_directory(source_path);
-      
+
       auto target_path=source_path.parent_path()/content;
-      
+
       if(boost::filesystem::exists(target_path)) {
         Terminal::get().print("Error: could not rename to "+target_path.string()+": already exists\n", true);
         return;
       }
-      
+
       if(is_directory)
         this->remove_path(source_path);
-      
+
       boost::system::error_code ec;
       boost::filesystem::rename(source_path, target_path, ec);
       if(ec) {
@@ -262,7 +262,7 @@ Directories::Directories() : Gtk::ListViewText(1) {
       update();
       on_save_file(target_path);
       select(target_path);
-      
+
       for(size_t c=0;c<Notebook::get().size();c++) {
         auto view=Notebook::get().get_view(c);
         if(is_directory) {
@@ -278,7 +278,7 @@ Directories::Directories() : Gtk::ListViewText(1) {
         }
         else if(view->file_path==source_path) {
           view->rename(target_path);
-          
+
           std::string old_language_id;
           if(view->language)
             old_language_id=view->language->get_id();
@@ -290,7 +290,7 @@ Directories::Directories() : Gtk::ListViewText(1) {
             Terminal::get().print("Warning: language for "+target_path.string()+" has changed. Please reopen the file\n");
         }
       }
-      
+
       EntryBox::get().hide();
     });
     auto entry_it=EntryBox::get().entries.begin();
@@ -301,7 +301,7 @@ Directories::Directories() : Gtk::ListViewText(1) {
     EntryBox::get().show();
   });
   menu.append(menu_item_rename);
-  
+
   menu_item_delete.set_label("Delete");
   menu_item_delete.signal_activate().connect([this] {
     if(menu_popup_row_path.empty())
@@ -312,17 +312,17 @@ Directories::Directories() : Gtk::ListViewText(1) {
     int result = dialog.run();
     if(result==Gtk::RESPONSE_YES) {
       bool is_directory=boost::filesystem::is_directory(menu_popup_row_path);
-      
+
       boost::system::error_code ec;
       boost::filesystem::remove_all(menu_popup_row_path, ec);
       if(ec)
         Terminal::get().print("Error: could not delete "+menu_popup_row_path.string()+": "+ec.message()+"\n", true);
       else {
         update();
-        
+
         for(size_t c=0;c<Notebook::get().size();c++) {
           auto view=Notebook::get().get_view(c);
-          
+
           if(is_directory) {
             if(filesystem::file_in_path(view->file_path, menu_popup_row_path))
               view->get_buffer()->set_modified();
@@ -334,13 +334,13 @@ Directories::Directories() : Gtk::ListViewText(1) {
     }
   });
   menu.append(menu_item_delete);
-  
+
   menu.show_all();
   menu.accelerate(*this);
-  
+
   menu_root.show_all();
   menu_root.accelerate(*this);
-  
+
   set_headers_clickable();
   forall([this](Gtk::Widget &widget) {
     if(widget.get_name()=="GtkButton") {
@@ -363,11 +363,11 @@ void Directories::open(const boost::filesystem::path &dir_path) {
   boost::system::error_code ec;
   if(dir_path.empty() || !boost::filesystem::exists(dir_path, ec) || ec)
     return;
-  
+
   tree_store->clear();
-  
+
   path=filesystem::get_normal_path(dir_path);
-  
+
   //TODO: report that set_title does not handle '_' correctly?
   auto title=path.filename().string();
   size_t pos=0;
@@ -382,7 +382,7 @@ void Directories::open(const boost::filesystem::path &dir_path) {
       directory.second.repository->clear_saved_status();
   }
   directories.clear();
-  
+
   add_or_update_path(path, Gtk::TreeModel::Row(), true);
 }
 
@@ -406,24 +406,24 @@ void Directories::on_save_file(const boost::filesystem::path &file_path) {
 void Directories::select(const boost::filesystem::path &select_path) {
   if(path=="")
     return;
-  
+
   if(!filesystem::file_in_path(select_path, path))
     return;
-  
+
   //return if the select_path is already selected
   auto iter=get_selection()->get_selected();
   if(iter) {
     if(iter->get_value(column_record.path)==select_path)
       return;
   }
-  
+
   std::list<boost::filesystem::path> paths;
   boost::filesystem::path parent_path;
   if(boost::filesystem::is_directory(select_path))
     parent_path=select_path;
   else
     parent_path=select_path.parent_path();
-  
+
   //check if select_path is already expanded
   if(directories.find(parent_path.string())!=directories.end()) {
     //set cursor at select_path and return
@@ -438,7 +438,7 @@ void Directories::select(const boost::filesystem::path &select_path) {
     });
     return;
   }
-  
+
   paths.emplace_front(parent_path);
   while(parent_path!=path) {
     parent_path=parent_path.parent_path();
@@ -455,7 +455,7 @@ void Directories::select(const boost::filesystem::path &select_path) {
       return false;
     });
   }
-  
+
   //set cursor at select_path
   tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter){
     if(iter->get_value(column_record.path)==select_path) {
@@ -493,7 +493,7 @@ bool Directories::on_button_press_event(GdkEventButton* event) {
       return true;
     }
   }
-  
+
   return Gtk::TreeView::on_button_press_event(event);
 }
 
@@ -504,19 +504,19 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co
       directories.erase(path_it);
     return;
   }
-  
+
   if(path_it==directories.end()) {
     auto g_file=Gio::File::create_for_path(dir_path.string());
     auto monitor=g_file->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
     auto path_and_row=std::make_shared<std::pair<boost::filesystem::path, Gtk::TreeModel::Row> >(dir_path, row);
     auto connection=std::make_shared<sigc::connection>();
-    
+
     std::shared_ptr<Git::Repository> repository;
     try {
       repository=Git::get_repository(dir_path);
     }
     catch(const std::exception &) {}
-    
+
     monitor->signal_changed().connect([this, connection, path_and_row, repository] (const Glib::RefPtr<Gio::File> &file,
                                                                         const Glib::RefPtr<Gio::File>&,
                                                                         Gio::FileMonitorEvent monitor_event) {
@@ -531,12 +531,12 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co
         }, 500);
       }
     });
-    
+
     std::shared_ptr<sigc::connection> repository_connection(new sigc::connection(), [](sigc::connection *connection) {
       connection->disconnect();
       delete connection;
     });
-    
+
     if(repository) {
       auto connection=std::make_shared<sigc::connection>();
       *repository_connection=repository->monitor->signal_changed().connect([this, connection, path_and_row](const Glib::RefPtr<Gio::File> &file,
@@ -554,7 +554,7 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co
     }
     directories[dir_path.string()]={row, monitor, repository, repository_connection};
   }
-  
+
   Gtk::TreeNodeChildren children(row?row.children():tree_store->children());
   if(children) {
     if(children.begin()->get_value(column_record.path)=="")
@@ -589,7 +589,7 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co
       }
       else {
         child->set_value(column_record.id, '2'+filename);
-        
+
         auto language=Source::guess_language(it->path().filename());
         if(!language)
           child->set_value(column_record.type, PathType::UNKNOWN);
@@ -611,7 +611,7 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co
     child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)"));
     child->set_value(column_record.type, PathType::UNKNOWN);
   }
-  
+
   colorize_path(dir_path, include_parent_paths);
 }
 
@@ -620,14 +620,14 @@ void Directories::remove_path(const boost::filesystem::path &dir_path) {
   if(it==directories.end())
     return;
   auto children=it->second.row->children();
-  
+
   for(auto it=directories.begin();it!=directories.end();) {
     if(filesystem::file_in_path(it->first, dir_path))
       it=directories.erase(it);
     else
       it++;
   }
-  
+
   if(children) {
     while(children) {
       tree_store->erase(children.begin());
@@ -644,7 +644,7 @@ void Directories::colorize_path(boost::filesystem::path dir_path_, bool include_
   auto it=directories.find(dir_path->string());
   if(it==directories.end())
     return;
-  
+
   if(it!=directories.end() && it->second.repository) {
     auto repository=it->second.repository;
     std::thread git_status_thread([this, dir_path, repository, include_parent_paths] {
@@ -655,12 +655,12 @@ void Directories::colorize_path(boost::filesystem::path dir_path_, bool include_
       catch(const std::exception &e) {
         Terminal::get().async_print(std::string("Error (git): ")+e.what()+'\n', true);
       }
-      
+
       dispatcher.post([this, dir_path, include_parent_paths, status=std::move(status)] {
         auto it=directories.find(dir_path->string());
         if(it==directories.end())
           return;
-        
+
         auto normal_color=get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
         Gdk::RGBA gray;
         gray.set_rgba(0.5, 0.5, 0.5);
@@ -676,12 +676,12 @@ void Directories::colorize_path(boost::filesystem::path dir_path_, bool include_
         green.set_red(normal_color.get_red()+factor*(green.get_red()-normal_color.get_red()));
         green.set_green(normal_color.get_green()+factor*(green.get_green()-normal_color.get_green()));
         green.set_blue(normal_color.get_blue()+factor*(green.get_blue()-normal_color.get_blue()));
-        
+
         do {
           Gtk::TreeNodeChildren children(it->second.row?it->second.row.children():tree_store->children());
           if(!children)
             return;
-          
+
           for(auto &child: children) {
             auto name=Glib::Markup::escape_text(child.get_value(column_record.name));
             auto path=child.get_value(column_record.path);
@@ -692,22 +692,22 @@ void Directories::colorize_path(boost::filesystem::path dir_path_, bool include_
               color=&green;
             else
               color=&normal_color;
-            
+
             std::stringstream ss;
             ss << '#' << std::setfill('0') << std::hex;
             ss << std::setw(2) << std::hex << (color->get_red_u()>>8);
             ss << std::setw(2) << std::hex << (color->get_green_u()>>8);
             ss << std::setw(2) << std::hex << (color->get_blue_u()>>8);
             child.set_value(column_record.markup, "<span foreground=\""+ss.str()+"\">"+name+"</span>");
-            
+
             auto type=child.get_value(column_record.type);
             if(type==PathType::UNKNOWN)
               child.set_value(column_record.markup, "<i>"+child.get_value(column_record.markup)+"</i>");
           }
-          
+
           if(!include_parent_paths)
             break;
-          
+
           auto path=boost::filesystem::path(it->first);
           if(boost::filesystem::exists(path/".git"))
             break;
diff --git a/src/directories.h b/src/directories.h
index 73c28618..0bac8718 100644
--- a/src/directories.h
+++ b/src/directories.h
@@ -19,17 +19,17 @@ class Directories : public Gtk::ListViewText {
     std::shared_ptr<Git::Repository> repository;
     std::shared_ptr<sigc::connection> connection;
   };
-  
+
   enum class PathType {KNOWN, UNKNOWN};
-  
+
   class TreeStore : public Gtk::TreeStore {
   protected:
     TreeStore()=default;
-    
+
     bool row_drop_possible_vfunc(const Gtk::TreeModel::Path &path, const Gtk::SelectionData &selection_data) const override;
     bool drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) override;
     bool drag_data_delete_vfunc (const Gtk::TreeModel::Path &path) override;
-    
+
   public:
     class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
     public:
@@ -46,7 +46,7 @@ class Directories : public Gtk::ListViewText {
       Gtk::TreeModelColumn<boost::filesystem::path> path;
       Gtk::TreeModelColumn<PathType> type;
     };
-    
+
     static Glib::RefPtr<TreeStore> create() {return Glib::RefPtr<TreeStore>(new TreeStore());}
   };
 
@@ -57,29 +57,29 @@ class Directories : public Gtk::ListViewText {
     return singleton;
   }
   ~Directories() override;
-  
+
   void open(const boost::filesystem::path &dir_path="");
   void update();
   void on_save_file(const boost::filesystem::path &file_path);
   void select(const boost::filesystem::path &path);
-  
+
   boost::filesystem::path path;
-  
+
 protected:
   bool on_button_press_event(GdkEventButton *event) override;
-  
+
 private:
   void add_or_update_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row, bool include_parent_paths);
   void remove_path(const boost::filesystem::path &dir_path);
   void colorize_path(boost::filesystem::path dir_path_, bool include_parent_paths);
-  
+
   Glib::RefPtr<Gtk::TreeStore> tree_store;
   TreeStore::ColumnRecord column_record;
-  
+
   std::unordered_map<std::string, DirectoryData> directories;
-  
+
   Dispatcher dispatcher;
-  
+
   Gtk::Menu menu;
   Gtk::MenuItem menu_item_new_file;
   Gtk::MenuItem menu_item_new_folder;
diff --git a/src/documentation_cppreference.cc b/src/documentation_cppreference.cc
index fe132ea6..ceec6225 100644
--- a/src/documentation_cppreference.cc
+++ b/src/documentation_cppreference.cc
@@ -12173,7 +12173,7 @@ std::experimental::filesystem::is_socket	cpp/experimental/fs/is_socket
 std::experimental::filesystem::is_symlink	cpp/experimental/fs/is_symlink
 std::experimental::filesystem::status_known	cpp/experimental/fs/status_known"}
 )";
-  
+
   class SymbolToUrl {
   public:
     SymbolToUrl(const std::string &symbol_urls) {
@@ -12197,7 +12197,7 @@ std::experimental::filesystem::status_known	cpp/experimental/fs/status_known"}
     }
     std::unordered_map<std::string, std::string> map;
   };
-  
+
   static SymbolToUrl symbol_to_url(symbol_urls);
   auto it=symbol_to_url.map.find(symbol);
   if(it==symbol_to_url.map.end())
diff --git a/src/entrybox.h b/src/entrybox.h
index 7781e5c1..749ae7a6 100644
--- a/src/entrybox.h
+++ b/src/entrybox.h
@@ -30,7 +30,7 @@ class EntryBox : public Gtk::Box {
     Label(std::function<void(int state, const std::string& message)> update_=nullptr);
     std::function<void(int state, const std::string& message)> update;
   };
-  
+
 private:
   EntryBox();
 public:
@@ -38,7 +38,7 @@ class EntryBox : public Gtk::Box {
     static EntryBox singleton;
     return singleton;
   }
-  
+
   Gtk::Box upper_box;
   Gtk::Box lower_box;
   void clear();
@@ -48,7 +48,7 @@ class EntryBox : public Gtk::Box {
   std::list<Button> buttons;
   std::list<ToggleButton> toggle_buttons;
   std::list<Label> labels;
-  
+
 private:
   static std::unordered_map<std::string, std::vector<std::string> > entry_histories;
 };
diff --git a/src/filesystem.cc b/src/filesystem.cc
index 98df6a82..1d0e27e5 100644
--- a/src/filesystem.cc
+++ b/src/filesystem.cc
@@ -51,7 +51,7 @@ std::string filesystem::escape_argument(const std::string &argument) {
 
 std::string filesystem::unescape_argument(const std::string &argument) {
   auto unescaped=argument;
-  
+
   if(unescaped.size()>=2) {
     if((unescaped[0]=='\'' && unescaped[unescaped.size()-1]=='\'') ||
        (unescaped[0]=='"' && unescaped[unescaped.size()-1]=='"')) {
@@ -72,7 +72,7 @@ std::string filesystem::unescape_argument(const std::string &argument) {
       return unescaped;
     }
   }
-  
+
   size_t backslash_count=0;
   for(size_t pos=0;pos<unescaped.size();++pos) {
     if(backslash_count%2==1 && (unescaped[pos]=='\\' || unescaped[pos]==' ' || unescaped[pos]=='(' || unescaped[pos]==')' || unescaped[pos]=='\'' || unescaped[pos]=='"')) {
@@ -134,7 +134,7 @@ boost::filesystem::path filesystem::find_file_in_path_parents(const std::string
 
 boost::filesystem::path filesystem::get_normal_path(const boost::filesystem::path &path) noexcept {
   boost::filesystem::path normal_path;
-  
+
   for(auto &e: path) {
     if(e==".")
       continue;
@@ -150,7 +150,7 @@ boost::filesystem::path filesystem::get_normal_path(const boost::filesystem::pat
     else
       normal_path/=e;
   }
-  
+
   return normal_path;
 }
 
@@ -159,7 +159,7 @@ boost::filesystem::path filesystem::get_relative_path(const boost::filesystem::p
 
   if(std::distance(path.begin(), path.end())<std::distance(base.begin(), base.end()))
     return boost::filesystem::path();
-  
+
   auto base_it=base.begin();
   auto path_it=path.begin();
   while(path_it!=path.end() && base_it!=base.end()) {
@@ -180,13 +180,13 @@ boost::filesystem::path filesystem::get_executable(const boost::filesystem::path
 #endif
 
   static std::vector<boost::filesystem::path> bin_paths={"/usr/bin", "/usr/local/bin"};
-  
+
   try {
     for(auto &path: bin_paths) {
       if(boost::filesystem::exists(path/executable_name))
         return executable_name;
     }
-    
+
     auto &executable_name_str = executable_name.string();
     for(auto &path: bin_paths) {
       boost::filesystem::path executable;
@@ -211,7 +211,7 @@ boost::filesystem::path filesystem::get_executable(const boost::filesystem::path
     }
   }
   catch(...) {}
-  
+
   return executable_name;
 }
 
diff --git a/src/git.cc b/src/git.cc
index 99d21746..3c4dd34a 100644
--- a/src/git.cc
+++ b/src/git.cc
@@ -22,7 +22,7 @@ Git::Repository::Diff::Diff(const boost::filesystem::path &path, git_repository
   error.code = git_revparse_single(reinterpret_cast<git_object**>(&blob), repository, spec.c_str());
   if(error)
     throw std::runtime_error(error.message());
-  
+
   git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
   options.context_lines=0;
 }
@@ -38,7 +38,7 @@ int Git::Repository::Diff::hunk_cb(const git_diff_delta *delta, const git_diff_h
     lines->removed.emplace_back(start);
   else
     lines->modified.emplace_back(start, end);
-    
+
   return 0;
 }
 
@@ -105,11 +105,11 @@ Git::Repository::Repository(const boost::filesystem::path &path) {
   repository=std::unique_ptr<git_repository, std::function<void(git_repository *)> >(repository_ptr, [](git_repository *ptr) {
     git_repository_free(ptr);
   });
-  
+
   work_path=get_work_path();
   if(work_path.empty())
     throw std::runtime_error("Could not find work path");
-  
+
   auto git_directory=Gio::File::create_for_path(get_path().string());
   monitor=git_directory->monitor_directory(Gio::FileMonitorFlags::FILE_MONITOR_WATCH_MOVES);
   monitor_changed_connection=monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
@@ -142,7 +142,7 @@ std::string Git::Repository::status_string(STATUS status) noexcept {
 
 int Git::Repository::status_callback(const char *path, unsigned int status_flags, void *data) noexcept {
   auto callback=static_cast<std::function<void(const char *path, STATUS status)>*>(data);
-  
+
   STATUS status;
   if((status_flags&(GIT_STATUS_INDEX_NEW|GIT_STATUS_WT_NEW))>0)
     status=STATUS::NEW;
@@ -162,10 +162,10 @@ int Git::Repository::status_callback(const char *path, unsigned int status_flags
     status=STATUS::CONFLICTED;
   else
     status=STATUS::CURRENT;
-  
+
   if(*callback)
     (*callback)(path, status);
-  
+
   return 0;
 }
 
@@ -175,7 +175,7 @@ Git::Repository::Status Git::Repository::get_status() {
     if(has_saved_status)
       return saved_status;
   }
-  
+
   Status status;
   bool first=true;
   std::unique_lock<std::mutex> status_saved_lock(saved_status_mutex, std::defer_lock);
@@ -274,7 +274,7 @@ std::shared_ptr<Git::Repository> Git::get_repository(const boost::filesystem::pa
   initialize();
   static std::unordered_map<std::string, std::weak_ptr<Git::Repository> > cache;
   static std::mutex mutex;
-  
+
   std::lock_guard<std::mutex> lock(mutex);
   auto root_path=Repository::get_root_path(path).generic_string();
   auto it=cache.find(root_path);
diff --git a/src/git.h b/src/git.h
index 616e8b0d..a8952ae7 100644
--- a/src/git.h
+++ b/src/git.h
@@ -19,7 +19,7 @@ class Git {
     int code=0;
     operator bool() noexcept {return code<0;}
   };
-  
+
   class Repository {
   public:
     class Diff {
@@ -51,7 +51,7 @@ class Git {
       static std::vector<Hunk> get_hunks(const std::string &old_buffer, const std::string &new_buffer);
       std::string get_details(const std::string &buffer, int line_nr);
     };
-    
+
     enum class STATUS {CURRENT, NEW, MODIFIED, DELETED, RENAMED, TYPECHANGE, UNREADABLE, IGNORED, CONFLICTED};
     class Status {
     public:
@@ -61,11 +61,11 @@ class Git {
   private:
     friend class Git;
     Repository(const boost::filesystem::path &path);
-    
+
     static int status_callback(const char *path, unsigned int status_flags, void *data) noexcept;
-    
+
     std::unique_ptr<git_repository, std::function<void(git_repository *)> > repository;
-    
+
     boost::filesystem::path work_path;
     sigc::connection monitor_changed_connection;
     Status saved_status;
@@ -73,32 +73,32 @@ class Git {
     std::mutex saved_status_mutex;
   public:
     ~Repository();
-    
+
     static std::string status_string(STATUS status) noexcept;
-    
+
     Status get_status();
     void clear_saved_status();
-    
+
     boost::filesystem::path get_work_path() noexcept;
     boost::filesystem::path get_path() noexcept;
     static boost::filesystem::path get_root_path(const boost::filesystem::path &path);
-    
+
     Diff get_diff(const boost::filesystem::path &path);
-    
+
     std::string get_branch() noexcept;
-    
+
     Glib::RefPtr<Gio::FileMonitor> monitor;
   };
-  
+
 private:
   static bool initialized;
-  
+
   ///Mutex for thread safe operations
   static std::mutex mutex;
-  
+
   ///Call initialize in public static methods
   static void initialize() noexcept;
-  
+
   static boost::filesystem::path path(const char *cpath, size_t cpath_length=static_cast<size_t>(-1)) noexcept;
 public:
   static std::shared_ptr<Repository> get_repository(const boost::filesystem::path &path);
diff --git a/src/menu.h b/src/menu.h
index f1afec45..a028dd25 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -11,13 +11,13 @@ class Menu {
     static Menu singleton;
     return singleton;
   }
-  
+
   void add_action(const std::string &name, const std::function<void()> &action);
   std::unordered_map<std::string, Glib::RefPtr<Gio::SimpleAction> > actions;
   void set_keys();
-  
+
   void build();
-  
+
   Glib::RefPtr<Gio::Menu> juci_menu;
   Glib::RefPtr<Gio::Menu> window_menu;
   std::unique_ptr<Gtk::Menu> right_click_line_menu;
diff --git a/src/meson.cc b/src/meson.cc
index 04b30de6..30485f12 100644
--- a/src/meson.cc
+++ b/src/meson.cc
@@ -36,11 +36,11 @@ bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path,
     return false;
 
   if (!create_build_directory(debug_build_path)) return false;
-  
+
   bool compile_commands_exists=boost::filesystem::exists(debug_build_path/"compile_commands.json");
   if(!force && compile_commands_exists)
     return true;
-  
+
   Dialog::Message message("Creating/updating debug build");
   auto exit_status=Terminal::get().process(Config::get().project.meson.command+' '+(compile_commands_exists?"--internal regenerate ":"")+
                                            "--buildtype debug "+filesystem::escape_argument(get_project_path().string()), debug_build_path);
@@ -52,7 +52,7 @@ bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path,
 
 boost::filesystem::path Meson::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
   CompileCommands compile_commands(build_path);
-  
+
   size_t best_match_size=-1;
   boost::filesystem::path best_match_executable;
   for(auto &command: compile_commands.commands) {
@@ -77,6 +77,6 @@ boost::filesystem::path Meson::get_executable(const boost::filesystem::path &bui
       }
     }
   }
-  
+
   return best_match_executable;
 }
diff --git a/src/notebook.cc b/src/notebook.cc
index 4c30b683..4d65b9e6 100644
--- a/src/notebook.cc
+++ b/src/notebook.cc
@@ -12,20 +12,20 @@
 
 Notebook::TabLabel::TabLabel(const std::function<void()> &on_close) {
   set_can_focus(false);
-  
+
   auto button=Gtk::manage(new Gtk::Button());
   auto hbox=Gtk::manage(new Gtk::Box());
-  
+
   hbox->set_can_focus(false);
   label.set_can_focus(false);
   button->set_image_from_icon_name("window-close-symbolic", Gtk::ICON_SIZE_MENU);
   button->set_can_focus(false);
   button->set_relief(Gtk::ReliefStyle::RELIEF_NONE);
-  
+
   hbox->pack_start(label, Gtk::PACK_SHRINK);
   hbox->pack_end(*button, Gtk::PACK_SHRINK);
   add(*hbox);
-  
+
   button->signal_clicked().connect(on_close);
   signal_button_press_event().connect([on_close](GdkEventButton *event) {
     if(event->button==GDK_BUTTON_MIDDLE) {
@@ -34,7 +34,7 @@ Notebook::TabLabel::TabLabel(const std::function<void()> &on_close) {
     }
     return false;
   });
-  
+
   show_all();
 }
 
@@ -104,10 +104,10 @@ std::vector<Source::View*> &Notebook::get_views() {
 
 void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_index) {
   auto file_path=filesystem::get_normal_path(file_path_);
-  
+
   if(notebook_index==1 && !split)
     toggle_split();
-  
+
   // Use canonical path to follow symbolic links
   boost::system::error_code ec;
   auto canonical_file_path=boost::filesystem::canonical(file_path, ec);
@@ -121,7 +121,7 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
       return;
     }
   }
-  
+
   if(boost::filesystem::exists(file_path)) {
     std::ifstream can_read(file_path.string());
     if(!can_read) {
@@ -130,11 +130,11 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
     }
     can_read.close();
   }
-  
+
   auto last_view=get_current_view();
-  
+
   auto language=Source::guess_language(file_path);
-  
+
   std::string language_protocol_language_id;
   if(language) {
     language_protocol_language_id=language->get_id();
@@ -145,17 +145,17 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
         language_protocol_language_id="javascript";
     }
   }
-  
+
   if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc"))
     source_views.emplace_back(new Source::ClangView(file_path, language));
   else if(language && !language_protocol_language_id.empty() && !filesystem::find_executable(language_protocol_language_id+"-language-server").empty())
     source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id));
   else
     source_views.emplace_back(new Source::GenericView(file_path, language));
-  
+
   auto source_view=source_views.back();
   source_view->configure();
-  
+
   source_view->scroll_to_cursor_delayed=[this](Source::BaseView* view, bool center, bool show_tooltips) {
     while(Gtk::Main::events_pending())
       Gtk::Main::iteration(false);
@@ -189,7 +189,7 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
   source_view->update_status_diagnostics=[this](Source::BaseView* view) {
     if(get_current_view()==view) {
       std::string diagnostic_info;
-      
+
       auto num_warnings=std::get<0>(view->status_diagnostics);
       auto num_errors=std::get<1>(view->status_diagnostics);
       auto num_fix_its=std::get<2>(view->status_diagnostics);
@@ -213,7 +213,7 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
         green.set_red(normal_color.get_red()+factor*(green.get_red()-normal_color.get_red()));
         green.set_green(normal_color.get_green()+factor*(green.get_green()-normal_color.get_green()));
         green.set_blue(normal_color.get_blue()+factor*(green.get_blue()-normal_color.get_blue()));
-        
+
         std::stringstream yellow_ss, red_ss, green_ss;
         yellow_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(yellow.get_red_u()>>8) << std::setw(2) << (int)(yellow.get_green_u()>>8) << std::setw(2) << (int)(yellow.get_blue_u()>>8);
         red_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(red.get_red_u()>>8) << std::setw(2) << (int)(red.get_green_u()>>8) << std::setw(2) << (int)(red.get_blue_u()>>8);
@@ -251,7 +251,7 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
     if(get_current_view()==view)
       status_state.set_text(view->status_state+" ");
   };
-  
+
   scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
   hboxes.emplace_back(new Gtk::Box());
   scrolled_windows.back()->add(*source_view);
@@ -261,7 +261,7 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
   gtk_source_map_set_view(GTK_SOURCE_MAP(source_maps.back()->gobj()), source_view->gobj());
 
   configure(source_views.size()-1);
-  
+
   //Set up tab label
   tab_labels.emplace_back(new TabLabel([this, source_view]() {
     auto index=get_index(source_view);
@@ -284,13 +284,13 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
     }
   };
   source_view->update_tab_label(source_view);
-  
+
   //Add star on tab label when the page is not saved:
   source_view->get_buffer()->signal_modified_changed().connect([source_view]() {
     if(source_view->update_tab_label)
       source_view->update_tab_label(source_view);
   });
-  
+
   //Cursor history
   auto update_cursor_locations=[this, source_view](const Gtk::TextBuffer::iterator &iter) {
     bool mark_moved=false;
@@ -311,7 +311,7 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
       cursor_locations.emplace_back(source_view, source_view->get_buffer()->create_mark(iter));
       current_cursor_location=cursor_locations.size()-1;
     }
-    
+
     // Combine adjacent cursor histories that are similar
     if(!cursor_locations.empty()) {
       size_t cursor_locations_index=1;
@@ -331,7 +331,7 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
         }
       }
     }
-    
+
     // Remove start of cache if cache limit is exceeded
     while(cursor_locations.size()>10) {
       cursor_locations.begin()->view->get_buffer()->delete_mark(cursor_locations.begin()->mark);
@@ -339,7 +339,7 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
       if(current_cursor_location!=static_cast<size_t>(-1))
         --current_cursor_location;
     }
-    
+
     if(current_cursor_location>=cursor_locations.size())
       current_cursor_location=cursor_locations.size()-1;
   };
@@ -355,7 +355,7 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
   source_view->get_buffer()->signal_changed().connect([source_view, update_cursor_locations] {
     update_cursor_locations(source_view->get_buffer()->get_insert()->get_iter());
   });
-  
+
 #ifdef JUCI_ENABLE_DEBUG
   if(dynamic_cast<Source::ClangView*>(source_view) || (source_view->language && source_view->language->get_id()=="rust")) {
     source_view->toggle_breakpoint=[source_view](int line_nr) {
@@ -378,12 +378,12 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
     };
   }
 #endif
-  
+
   source_view->signal_focus_in_event().connect([this, source_view](GdkEventFocus *) {
     set_current_view(source_view);
     return false;
   });
-  
+
   if(notebook_index==static_cast<size_t>(-1)) {
     if(!split)
       notebook_index=0;
@@ -395,13 +395,13 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
       notebook_index=get_notebook_page(get_index(last_view)).first;
   }
   auto &notebook=notebooks[notebook_index];
-  
+
   notebook.append_page(*hboxes.back(), *tab_labels.back());
-  
+
   notebook.set_tab_reorderable(*hboxes.back(), true);
   notebook.set_tab_detachable(*hboxes.back(), true);
   show_all_children();
-  
+
   notebook.set_current_page(notebook.get_n_pages()-1);
   last_index=-1;
   if(last_view) {
@@ -410,14 +410,14 @@ void Notebook::open(const boost::filesystem::path &file_path_, size_t notebook_i
     if(notebook_page.first==notebook_index)
       last_index=index;
   }
-  
+
   set_focus_child(*source_views.back());
   focus_view(source_view);
 }
 
 void Notebook::configure(size_t index) {
   auto source_font_description=Pango::FontDescription(Config::get().source.font);
-  auto source_map_font_desc=Pango::FontDescription(static_cast<std::string>(source_font_description.get_family())+" "+Config::get().source.map_font_size); 
+  auto source_map_font_desc=Pango::FontDescription(static_cast<std::string>(source_font_description.get_family())+" "+Config::get().source.map_font_size);
   source_maps.at(index)->override_font(source_map_font_desc);
   if(Config::get().source.show_map) {
     if(hboxes.at(index)->get_children().size()==1)
@@ -474,19 +474,19 @@ bool Notebook::close(size_t index) {
       last_index=-1;
     else if(index<last_index && last_index!=static_cast<size_t>(-1))
       last_index--;
-    
+
     auto notebook_page=get_notebook_page(index);
     notebooks[notebook_page.first].remove_page(notebook_page.second);
     source_maps.erase(source_maps.begin()+index);
 
     if(on_close_page)
       on_close_page(view);
-    
+
     delete_cursor_locations(view);
-    
+
     SelectionDialog::get()=nullptr;
     CompletionDialog::get()=nullptr;
-    
+
     if(auto clang_view=dynamic_cast<Source::ClangView*>(view))
       clang_view->async_delete();
     else
diff --git a/src/notebook.h b/src/notebook.h
index 5aae90f4..eace7fd6 100644
--- a/src/notebook.h
+++ b/src/notebook.h
@@ -12,14 +12,14 @@ class Notebook : public Gtk::Paned {
     TabLabel(const std::function<void()> &on_close);
     Gtk::Label label;
   };
-  
+
   class CursorLocation {
   public:
     CursorLocation(Source::View *view, Glib::RefPtr<Gtk::TextBuffer::Mark> mark_) : view(view), mark(std::move(mark_)) {}
     Source::View *view;
     Glib::RefPtr<Gtk::TextBuffer::Mark> mark;
   };
-  
+
 private:
   Notebook();
 public:
@@ -27,12 +27,12 @@ class Notebook : public Gtk::Paned {
     static Notebook singleton;
     return singleton;
   }
-  
+
   size_t size();
   Source::View* get_view(size_t index);
   Source::View* get_current_view();
   std::vector<Source::View*> &get_views();
-  
+
   void open(const boost::filesystem::path &file_path, size_t notebook_index=-1);
   void configure(size_t index);
   bool save(size_t index);
@@ -54,35 +54,35 @@ class Notebook : public Gtk::Paned {
   Gtk::Label status_state;
   void update_status(Source::BaseView *view);
   void clear_status();
-  
+
   std::function<void(Source::View*)> on_change_page;
   std::function<void(Source::View*)> on_close_page;
-  
+
   /// Cursor history
   std::vector<CursorLocation> cursor_locations;
   size_t current_cursor_location=-1;
   bool disable_next_update_cursor_locations=false;
   void delete_cursor_locations(Source::View *view);
-  
+
 private:
   size_t get_index(Source::View *view);
   Source::View *get_view(size_t notebook_index, int page);
   void focus_view(Source::View *view);
   std::pair<size_t, int> get_notebook_page(size_t index);
-  
+
   std::vector<Gtk::Notebook> notebooks;
   std::vector<Source::View*> source_views; //Is NOT freed in destructor, this is intended for quick program exit.
   std::vector<std::unique_ptr<Gtk::Widget> > source_maps;
   std::vector<std::unique_ptr<Gtk::ScrolledWindow> > scrolled_windows;
   std::vector<std::unique_ptr<Gtk::Box> > hboxes;
   std::vector<std::unique_ptr<TabLabel> > tab_labels;
-  
+
   bool split=false;
   size_t last_index=-1;
-  
+
   void set_current_view(Source::View *view);
   Source::View* current_view=nullptr;
   Source::View* intermediate_view=nullptr;
-  
+
   bool save_modified_dialog(size_t index);
 };
diff --git a/src/project.cc b/src/project.cc
index 2f32f8e9..2740bbd8 100644
--- a/src/project.cc
+++ b/src/project.cc
@@ -60,7 +60,7 @@ void Project::on_save(size_t index) {
     else
       build_path=filesystem::find_file_in_path_parents("meson.build", view->file_path.parent_path());
   }
-  
+
   if(!build_path.empty()) {
     auto build=Build::create(build_path);
     if(dynamic_cast<CMakeBuild*>(build.get()) || dynamic_cast<MesonBuild*>(build.get())) {
@@ -69,7 +69,7 @@ void Project::on_save(size_t index) {
       boost::system::error_code ec;
       if(boost::filesystem::exists(build->get_debug_path()), ec)
         build->update_debug(true);
-      
+
       for(size_t c=0;c<Notebook::get().size();c++) {
         auto source_view=Notebook::get().get_view(c);
         if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
@@ -135,7 +135,7 @@ void Project::debug_update_stop() {
 
 std::shared_ptr<Project::Base> Project::create() {
   std::unique_ptr<Project::Build> build;
-  
+
   if(auto view=Notebook::get().get_current_view()) {
     build=Build::create(view->file_path);
     if(view->language) {
@@ -152,7 +152,7 @@ std::shared_ptr<Project::Base> Project::create() {
   }
   else
     build=Build::create(Directories::get().path);
-  
+
   if(dynamic_cast<CMakeBuild*>(build.get()) || dynamic_cast<MesonBuild*>(build.get()))
     return std::shared_ptr<Project::Base>(new Project::Clang(std::move(build)));
   else if(dynamic_cast<CargoBuild*>(build.get()))
@@ -182,7 +182,7 @@ void Project::Base::recreate_build() {
 
 void Project::Base::show_symbols() {
   auto view=Notebook::get().get_current_view();
-  
+
   boost::filesystem::path search_path;
   if(view)
     search_path=view->file_path.parent_path();
@@ -197,7 +197,7 @@ void Project::Base::show_symbols() {
     }
   }
   auto pair=Ctags::get_result(search_path);
-  
+
   auto path=std::move(pair.first);
   auto stream=std::move(pair.second);
   stream->seekg(0, std::ios::end);
@@ -206,25 +206,25 @@ void Project::Base::show_symbols() {
     return;
   }
   stream->seekg(0, std::ios::beg);
-  
+
   if(view) {
     auto dialog_iter=view->get_iter_for_dialog();
     SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
   }
   else
     SelectionDialog::create(true, true);
-  
+
   std::vector<Source::Offset> rows;
-    
+
   std::string line;
   while(std::getline(*stream, line)) {
     auto location=Ctags::get_location(line, true);
-    
+
     std::string row=location.file_path.string()+":"+std::to_string(location.line+1)+": "+location.source;
     rows.emplace_back(Source::Offset(location.line, location.index, location.file_path));
     SelectionDialog::get()->add_row(row);
   }
-    
+
   if(rows.size()==0)
     return;
   SelectionDialog::get()->on_select=[rows=std::move(rows), path=std::move(path)](unsigned int index, const std::string &text, bool hide_window) {
@@ -260,17 +260,17 @@ std::pair<std::string, std::string> Project::LLDB::debug_get_run_arguments() {
   auto default_build_path=build->get_default_path();
   if(debug_build_path.empty() || default_build_path.empty())
     return {"", ""};
-  
+
   auto project_path=build->get_project_path().string();
   auto run_arguments_it=debug_run_arguments.find(project_path);
   std::string arguments;
   if(run_arguments_it!=debug_run_arguments.end())
     arguments=run_arguments_it->second.arguments;
-  
+
   if(arguments.empty()) {
     auto view=Notebook::get().get_current_view();
     auto executable=build->get_executable(view?view->file_path:Directories::get().path).string();
-    
+
     if(!executable.empty()) {
       size_t pos=executable.find(default_build_path.string());
       if(pos!=std::string::npos)
@@ -280,18 +280,18 @@ std::pair<std::string, std::string> Project::LLDB::debug_get_run_arguments() {
     else
       arguments=filesystem::escape_argument(filesystem::get_short_path(build->get_debug_path()).string());
   }
-  
+
   return {project_path, arguments};
 }
 
 Project::DebugOptions *Project::LLDB::debug_get_options() {
   if(build->get_project_path().empty())
     return nullptr;
-  
+
   debug_options=std::make_unique<DebugOptions>();
-  
+
   auto &arguments=Project::debug_run_arguments[build->get_project_path().string()];
-  
+
   auto remote_enabled=Gtk::manage(new Gtk::CheckButton());
   auto remote_host_port=Gtk::manage(new Gtk::Entry());
   remote_enabled->set_active(arguments.remote_enabled);
@@ -299,31 +299,31 @@ Project::DebugOptions *Project::LLDB::debug_get_options() {
   remote_enabled->signal_clicked().connect([remote_enabled, remote_host_port] {
     remote_host_port->set_sensitive(remote_enabled->get_active());
   });
-  
+
   remote_host_port->set_sensitive(arguments.remote_enabled);
   remote_host_port->set_text(arguments.remote_host_port);
   remote_host_port->set_placeholder_text("host:port");
   remote_host_port->signal_activate().connect([] {
     debug_options->hide();
   });
-  
+
   auto self=this->shared_from_this();
   debug_options->signal_hide().connect([self, remote_enabled, remote_host_port] {
     auto &arguments=Project::debug_run_arguments[self->build->get_project_path().string()];
     arguments.remote_enabled=remote_enabled->get_active();
     arguments.remote_host_port=remote_host_port->get_text();
   });
-  
+
   auto remote_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
   remote_vbox->pack_start(*remote_enabled, true, true);
   remote_vbox->pack_end(*remote_host_port, true, true);
-  
+
   auto remote_frame=Gtk::manage(new Gtk::Frame());
   remote_frame->set_label("Remote Debugging");
   remote_frame->add(*remote_vbox);
-  
+
   debug_options->vbox.pack_end(*remote_frame, true, true);
-  
+
   return debug_options.get();
 }
 
@@ -332,14 +332,14 @@ void Project::LLDB::debug_start() {
   auto default_build_path=build->get_default_path();
   if(debug_build_path.empty() || !build->update_debug() || default_build_path.empty())
     return;
-  
+
   auto project_path=std::make_shared<boost::filesystem::path>(build->get_project_path());
-  
+
   auto run_arguments_it=debug_run_arguments.find(project_path->string());
   auto run_arguments=std::make_shared<std::string>();
   if(run_arguments_it!=debug_run_arguments.end())
     *run_arguments=run_arguments_it->second.arguments;
-  
+
   if(run_arguments->empty()) {
     auto view=Notebook::get().get_current_view();
     *run_arguments=build->get_executable(view?view->file_path:Directories::get().path).string();
@@ -353,12 +353,12 @@ void Project::LLDB::debug_start() {
       run_arguments->replace(pos, default_build_path.string().size(), debug_build_path.string());
     *run_arguments=filesystem::escape_argument(filesystem::get_short_path(*run_arguments).string());
   }
-  
+
   debugging=true;
-  
+
   if(Config::get().project.clear_terminal_on_compile)
     Terminal::get().clear();
-  
+
   Terminal::get().print("Compiling and debugging "+*run_arguments+"\n");
   Terminal::get().async_process(build->get_compile_command(), debug_build_path, [self=this->shared_from_this(), run_arguments, project_path](int exit_status){
     if(exit_status!=EXIT_SUCCESS)
@@ -376,12 +376,12 @@ void Project::LLDB::debug_start() {
               breakpoints.emplace_back(view->file_path, iter.get_line()+1);
           }
         }
-        
+
         std::string remote_host;
         auto debug_run_arguments_it=debug_run_arguments.find(project_path->string());
         if(debug_run_arguments_it!=debug_run_arguments.end() && debug_run_arguments_it->second.remote_enabled)
           remote_host=debug_run_arguments_it->second.remote_host_port;
-        
+
         static auto on_exit_it=Debug::LLDB::get().on_exit.end();
         if(on_exit_it!=Debug::LLDB::get().on_exit.end())
           Debug::LLDB::get().on_exit.erase(on_exit_it);
@@ -393,7 +393,7 @@ void Project::LLDB::debug_start() {
           });
         });
         on_exit_it=std::prev(Debug::LLDB::get().on_exit.end());
-        
+
         static auto on_event_it=Debug::LLDB::get().on_event.end();
         if(on_event_it!=Debug::LLDB::get().on_event.end())
           Debug::LLDB::get().on_event.erase(on_event_it);
@@ -401,7 +401,7 @@ void Project::LLDB::debug_start() {
           std::string status;
           boost::filesystem::path stop_path;
           unsigned stop_line=0, stop_column=0;
-          
+
           std::unique_lock<std::mutex> lock(Debug::LLDB::get().mutex);
           auto process=lldb::SBProcess::GetProcessFromEvent(event);
           auto state=lldb::SBProcess::GetStateFromEvent(event);
@@ -432,7 +432,7 @@ void Project::LLDB::debug_start() {
               stop_column=column-1;
             }
           }
-          
+
           self->dispatcher.post([status=std::move(status), stop_path=std::move(stop_path), stop_line, stop_column] {
             debug_update_status(status);
             Project::debug_stop.first=stop_path;
@@ -444,7 +444,7 @@ void Project::LLDB::debug_start() {
           });
         });
         on_event_it=std::prev(Debug::LLDB::get().on_event.end());
-        
+
         std::vector<std::string> startup_commands;
         if(dynamic_cast<CargoBuild*>(self->build.get())) {
           std::stringstream istream, ostream;
@@ -496,7 +496,7 @@ void Project::LLDB::debug_backtrace() {
   if(debugging) {
     auto view=Notebook::get().get_current_view();
     auto backtrace=Debug::LLDB::get().get_backtrace();
-    
+
     if(view) {
       auto iter=view->get_iter_for_dialog();
       SelectionDialog::create(view, view->get_buffer()->create_mark(iter), true, true);
@@ -508,11 +508,11 @@ void Project::LLDB::debug_backtrace() {
       Info::get().print("No backtrace found");
       return;
     }
-    
+
     bool cursor_set=false;
     for(auto &frame: backtrace) {
       std::string row="<i>"+frame.module_filename+"</i>";
-      
+
       //Shorten frame.function_name if it is too long
       if(frame.function_name.size()>120) {
         frame.function_name=frame.function_name.substr(0, 58)+"...."+frame.function_name.substr(frame.function_name.size()-58);
@@ -530,7 +530,7 @@ void Project::LLDB::debug_backtrace() {
         cursor_set=true;
       }
     }
-    
+
     SelectionDialog::get()->on_select=[rows=std::move(rows)](unsigned int index, const std::string &text, bool hide_window) {
       if(index>=rows.size())
         return;
@@ -539,7 +539,7 @@ void Project::LLDB::debug_backtrace() {
         Notebook::get().open(frame.file_path);
         if(auto view=Notebook::get().get_current_view()) {
           Debug::LLDB::get().select_frame(frame.index);
-          
+
           view->place_cursor_at_line_index(frame.line_nr-1, frame.line_index-1);
           view->scroll_to_cursor_delayed(view, true, true);
         }
@@ -555,7 +555,7 @@ void Project::LLDB::debug_show_variables() {
   if(debugging) {
     auto view=Notebook::get().get_current_view();
     auto variables=Debug::LLDB::get().get_variables();
-    
+
     Gtk::TextIter iter;
     if(view) {
       iter=view->get_iter_for_dialog();
@@ -568,14 +568,14 @@ void Project::LLDB::debug_show_variables() {
       Info::get().print("No variables found");
       return;
     }
-    
+
     for(auto &variable: variables) {
       std::string row="#"+std::to_string(variable.thread_index_id)+":#"+std::to_string(variable.frame_index)+":"+variable.file_path.filename().string()+":"+std::to_string(variable.line_nr)+" - <b>"+Glib::Markup::escape_text(variable.name)+"</b>";
-      
+
       rows->emplace_back(variable);
       SelectionDialog::get()->add_row(row);
     }
-    
+
     SelectionDialog::get()->on_select=[rows](unsigned int index, const std::string &text, bool hide_window) {
       if(index>=rows->size())
         return;
@@ -591,12 +591,12 @@ void Project::LLDB::debug_show_variables() {
       if(!variable.declaration_found)
         Info::get().print("Debugger did not find declaration for the variable: "+variable.name);
     };
-    
+
     SelectionDialog::get()->on_hide=[self=this->shared_from_this()]() {
       self->debug_variable_tooltips.hide();
       self->debug_variable_tooltips.clear();
     };
-    
+
     SelectionDialog::get()->on_changed=[self=this->shared_from_this(), rows, view, iter](unsigned int index, const std::string &text) {
       if(index>=rows->size()) {
         self->debug_variable_tooltips.hide();
@@ -606,7 +606,7 @@ void Project::LLDB::debug_show_variables() {
       auto create_tooltip_buffer=[rows, view, index]() {
         auto variable=(*rows)[index];
         auto tooltip_buffer=view?Gtk::TextBuffer::create(view->get_buffer()->get_tag_table()):Gtk::TextBuffer::create();
-        
+
         Glib::ustring value=variable.value;
         if(!value.empty()) {
           Glib::ustring::iterator iter;
@@ -620,18 +620,18 @@ void Project::LLDB::debug_show_variables() {
           else
             tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1));
         }
-        
+
         return tooltip_buffer;
       };
-      
+
       if(view)
         self->debug_variable_tooltips.emplace_back(create_tooltip_buffer, view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter));
       else
         self->debug_variable_tooltips.emplace_back(create_tooltip_buffer);
-  
+
       self->debug_variable_tooltips.show(true);
     };
-    
+
     if(view)
       view->hide_tooltips();
     SelectionDialog::get()->show();
@@ -672,24 +672,24 @@ void Project::LanguageProtocol::show_symbols() {
     Info::get().print("Could not find project folder");
     return;
   }
-  
+
   auto language_id=get_language_id();
   auto executable_name=language_id+"-language-server";
   if(filesystem::find_executable(executable_name).empty()) {
     Info::get().print("Executable "+executable_name+" not found");
     return;
   }
-  
+
   auto project_path=std::make_shared<boost::filesystem::path>(build->get_project_path());
-  
+
   auto client=::LanguageProtocol::Client::get(*project_path, language_id);
   auto capabilities=client->initialize(nullptr);
-  
+
   if(!capabilities.workspace_symbol) {
     Info::get().print("Language server does not support workspace/symbol");
     return;
   }
-  
+
   auto view=Notebook::get().get_current_view();
   if(view) {
     auto dialog_iter=view->get_iter_for_dialog();
@@ -697,11 +697,11 @@ void Project::LanguageProtocol::show_symbols() {
   }
   else
     SelectionDialog::create(true, true);
-  
+
   SelectionDialog::get()->on_hide=[] {
     SelectionDialog::get()->on_search_entry_changed=nullptr; // To delete client object
   };
-  
+
   auto offsets=std::make_shared<std::vector<Source::Offset>>();
   SelectionDialog::get()->on_search_entry_changed=[client, project_path, offsets](const std::string &text) {
     if(text.size()>1)
@@ -746,7 +746,7 @@ void Project::LanguageProtocol::show_symbols() {
     for(size_t c=0;c<offsets->size() && c<names.size();++c)
       SelectionDialog::get()->add_row(filesystem::get_relative_path((*offsets)[c].file_path, *project_path).string()+':'+std::to_string((*offsets)[c].line+1)+':'+std::to_string((*offsets)[c].index+1)+": "+names[c]);
   };
-  
+
   SelectionDialog::get()->on_select=[offsets](unsigned int index, const std::string &text, bool hide_window) {
     auto &offset=(*offsets)[index];
     if(!boost::filesystem::is_regular_file(offset.file_path))
@@ -757,7 +757,7 @@ void Project::LanguageProtocol::show_symbols() {
     view->scroll_to_cursor_delayed(view, true, false);
     view->hide_tooltips();
   };
-  
+
   if(view)
     view->hide_tooltips();
   SelectionDialog::get()->show();
@@ -767,23 +767,23 @@ std::pair<std::string, std::string> Project::Clang::get_run_arguments() {
   auto build_path=build->get_default_path();
   if(build_path.empty())
     return {"", ""};
-  
+
   auto project_path=build->get_project_path().string();
   auto run_arguments_it=run_arguments.find(project_path);
   std::string arguments;
   if(run_arguments_it!=run_arguments.end())
     arguments=run_arguments_it->second;
-  
+
   if(arguments.empty()) {
     auto view=Notebook::get().get_current_view();
     auto executable=build->get_executable(view?view->file_path:Directories::get().path);
-    
+
     if(!executable.empty())
       arguments=filesystem::escape_argument(filesystem::get_short_path(executable).string());
     else
       arguments=filesystem::escape_argument(filesystem::get_short_path(build->get_default_path()).string());
   }
-  
+
   return {project_path, arguments};
 }
 
@@ -791,12 +791,12 @@ void Project::Clang::compile() {
   auto default_build_path=build->get_default_path();
   if(default_build_path.empty() || !build->update_default())
     return;
-  
+
   compiling=true;
-  
+
   if(Config::get().project.clear_terminal_on_compile)
     Terminal::get().clear();
-  
+
   Terminal::get().print("Compiling project "+filesystem::get_short_path(build->get_project_path()).string()+"\n");
   Terminal::get().async_process(build->get_compile_command(), default_build_path, [](int exit_status) {
     compiling=false;
@@ -807,14 +807,14 @@ void Project::Clang::compile_and_run() {
   auto default_build_path=build->get_default_path();
   if(default_build_path.empty() || !build->update_default())
     return;
-  
+
   auto project_path=build->get_project_path();
-  
+
   auto run_arguments_it=run_arguments.find(project_path.string());
   std::string arguments;
   if(run_arguments_it!=run_arguments.end())
     arguments=run_arguments_it->second;
-  
+
   if(arguments.empty()) {
     auto view=Notebook::get().get_current_view();
     auto executable=build->get_executable(view?view->file_path:Directories::get().path);
@@ -825,12 +825,12 @@ void Project::Clang::compile_and_run() {
     }
     arguments=filesystem::escape_argument(filesystem::get_short_path(executable).string());
   }
-  
+
   compiling=true;
-  
+
   if(Config::get().project.clear_terminal_on_compile)
     Terminal::get().clear();
-  
+
   Terminal::get().print("Compiling and running "+arguments+"\n");
   Terminal::get().async_process(build->get_compile_command(), default_build_path, [arguments, project_path](int exit_status){
     compiling=false;
@@ -848,11 +848,11 @@ void Project::Clang::recreate_build() {
   auto default_build_path=build->get_default_path();
   if(default_build_path.empty())
     return;
-  
+
   auto debug_build_path=build->get_debug_path();
   bool has_default_build=boost::filesystem::exists(default_build_path);
   bool has_debug_build=!debug_build_path.empty() && boost::filesystem::exists(debug_build_path);
-  
+
   if(has_default_build || has_debug_build) {
     Gtk::MessageDialog dialog(*static_cast<Gtk::Window*>(Notebook::get().get_toplevel()), "Recreate Build", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
     dialog.set_default_response(Gtk::RESPONSE_NO);
@@ -879,11 +879,11 @@ void Project::Clang::recreate_build() {
       return;
     }
   }
-  
+
   build->update_default(true);
   if(has_debug_build)
     build->update_debug(true);
-  
+
   for(size_t c=0;c<Notebook::get().size();c++) {
     auto source_view=Notebook::get().get_view(c);
     if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
@@ -891,7 +891,7 @@ void Project::Clang::recreate_build() {
         source_clang_view->full_reparse_needed=true;
     }
   }
-  
+
   if(auto view=Notebook::get().get_current_view()) {
     if(view->full_reparse_needed)
       view->full_reparse();
@@ -910,7 +910,7 @@ void Project::Markdown::compile_and_run() {
     boost::filesystem::remove(last_temp_path);
     last_temp_path=boost::filesystem::path();
   }
-  
+
   std::stringstream stdin_stream, stdout_stream;
   auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, "command -v grip");
   if(exit_status==0) {
@@ -976,21 +976,21 @@ std::pair<std::string, std::string> Project::Rust::get_run_arguments() {
   std::string arguments;
   if(run_arguments_it!=run_arguments.end())
     arguments=run_arguments_it->second;
-  
+
   if(arguments.empty())
     arguments=filesystem::get_short_path(build->get_executable(project_path)).string();
-  
+
   return {project_path, arguments};
 }
 
 void Project::Rust::compile() {
   compiling=true;
-  
+
   if(Config::get().project.clear_terminal_on_compile)
     Terminal::get().clear();
-  
+
   Terminal::get().print("Compiling project "+filesystem::get_short_path(build->get_project_path()).string()+"\n");
-  
+
   auto command=build->get_compile_command();
   Terminal::get().async_process(command, build->get_project_path(), [](int exit_status) {
     compiling=false;
@@ -999,13 +999,13 @@ void Project::Rust::compile() {
 
 void Project::Rust::compile_and_run() {
   compiling=true;
-  
+
   if(Config::get().project.clear_terminal_on_compile)
     Terminal::get().clear();
-  
+
   auto arguments=get_run_arguments().second;
   Terminal::get().print("Compiling and running "+arguments+"\n");
-  
+
   auto self=this->shared_from_this();
   Terminal::get().async_process(build->get_compile_command(), build->get_project_path(), [self, arguments=std::move(arguments)](int exit_status) {
     compiling=false;
diff --git a/src/project.h b/src/project.h
index ca09ac52..ee01bfaf 100644
--- a/src/project.h
+++ b/src/project.h
@@ -15,17 +15,17 @@ namespace Project {
     bool remote_enabled;
     std::string remote_host_port;
   };
-  
+
   class DebugOptions : public Gtk::Popover {
   public:
     DebugOptions() : Gtk::Popover(), vbox(Gtk::Orientation::ORIENTATION_VERTICAL) { add(vbox); }
     Gtk::Box vbox;
   };
-  
+
   Gtk::Label &debug_status_label();
   void save_files(const boost::filesystem::path &path);
   void on_save(size_t index);
-  
+
   extern boost::filesystem::path debug_last_stop_file_path;
   extern std::unordered_map<std::string, std::string> run_arguments;
   extern std::unordered_map<std::string, DebugRunArguments> debug_run_arguments;
@@ -36,7 +36,7 @@ namespace Project {
   void debug_update_status(const std::string &new_debug_status);
   void debug_activate_menu_items();
   void debug_update_stop();
-  
+
   class Base : public std::enable_shared_from_this<Base> {
   protected:
     static std::unique_ptr<DebugOptions> debug_options;
@@ -44,18 +44,18 @@ namespace Project {
     Base() = default;
     Base(std::unique_ptr<Build> &&build): build(std::move(build)) {}
     virtual ~Base() = default;
-    
+
     std::unique_ptr<Build> build;
-    
+
     Dispatcher dispatcher;
-    
+
     virtual std::pair<std::string, std::string> get_run_arguments();
     virtual void compile();
     virtual void compile_and_run();
     virtual void recreate_build();
-    
+
     virtual void show_symbols();
-    
+
     virtual std::pair<std::string, std::string> debug_get_run_arguments();
     virtual Project::DebugOptions *debug_get_options() { return nullptr; }
     Tooltips debug_variable_tooltips;
@@ -75,11 +75,11 @@ namespace Project {
     virtual void debug_write(const std::string &buffer) {}
     virtual void debug_cancel() {}
   };
-  
+
   class LLDB : public virtual Base {
   public:
     ~LLDB() override { dispatcher.disconnect(); }
-    
+
 #ifdef JUCI_ENABLE_DEBUG
     std::pair<std::string, std::string> debug_get_run_arguments() override;
     Project::DebugOptions *debug_get_options() override;
@@ -100,68 +100,68 @@ namespace Project {
     void debug_cancel() override;
 #endif
   };
-  
+
   class LanguageProtocol : public virtual Base {
   public:
     virtual std::string get_language_id()=0;
     void show_symbols() override;
   };
-  
+
   class Clang : public LLDB {
   public:
     Clang(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
+
     std::pair<std::string, std::string> get_run_arguments() override;
     void compile() override;
     void compile_and_run() override;
-    void recreate_build() override;    
+    void recreate_build() override;
   };
-  
+
   class Markdown : public Base {
   public:
     Markdown(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
     ~Markdown() override;
-    
+
     boost::filesystem::path last_temp_path;
     void compile_and_run() override;
   };
-  
+
   class Python : public LanguageProtocol {
   public:
     Python(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
+
     void compile_and_run() override;
-    
+
     std::string get_language_id() override { return "python"; }
   };
-  
+
   class JavaScript : public LanguageProtocol {
   public:
     JavaScript(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
+
     void compile_and_run() override;
-    
+
     std::string get_language_id() override { return "javascript"; }
   };
-  
+
   class HTML : public Base {
   public:
     HTML(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
+
     void compile_and_run() override;
   };
-  
+
   class Rust : public LLDB, public LanguageProtocol {
   public:
     Rust(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
-    
+
     std::pair<std::string, std::string> get_run_arguments() override;
     void compile() override;
     void compile_and_run() override;
-    
+
     std::string get_language_id() override { return "rust"; }
   };
-  
+
   std::shared_ptr<Base> create();
   extern std::shared_ptr<Base> current;
 };
diff --git a/src/project_build.h b/src/project_build.h
index 058ccd6e..43c23d6d 100644
--- a/src/project_build.h
+++ b/src/project_build.h
@@ -7,17 +7,17 @@ namespace Project {
   class Build {
   public:
     virtual ~Build() {}
-    
+
     virtual boost::filesystem::path get_default_path();
     virtual bool update_default(bool force=false) {return false;}
     virtual boost::filesystem::path get_debug_path();
     virtual bool update_debug(bool force=false) {return false;}
-    
+
     virtual std::string get_compile_command() { return std::string(); }
     virtual boost::filesystem::path get_executable(const boost::filesystem::path &path) {return boost::filesystem::path();}
 
     const boost::filesystem::path& get_project_path() const noexcept { return project_path; }
-    
+
     static std::unique_ptr<Build> create(const boost::filesystem::path &path);
 
   protected:
diff --git a/src/rapidxml/rapidxml.h b/src/rapidxml/rapidxml.h
index 49e1b2aa..ee1b7d3b 100644
--- a/src/rapidxml/rapidxml.h
+++ b/src/rapidxml/rapidxml.h
@@ -277,7 +277,7 @@ namespace rapidxml {
       } else {
         memory = new char[size];
 #ifdef RAPIDXML_NO_EXCEPTIONS
-                                                                                                                                if (!memory)            
+                                                                                                                                if (!memory)
                     RAPIDXML_PARSE_ERROR("out of memory", 0);
 #endif
       }
diff --git a/src/selection_dialog.cc b/src/selection_dialog.cc
index aed3bda8..72793657 100644
--- a/src/selection_dialog.cc
+++ b/src/selection_dialog.cc
@@ -9,7 +9,7 @@ SelectionDialogBase::ListViewText::ListViewText(bool use_markup) : Gtk::TreeView
     get_column(0)->add_attribute(cell_renderer.property_markup(), column_record.text);
   else
     get_column(0)->add_attribute(cell_renderer.property_text(), column_record.text);
-  
+
   get_selection()->set_mode(Gtk::SelectionMode::SELECTION_BROWSE);
   set_enable_search(true);
   set_headers_visible(false);
@@ -42,20 +42,20 @@ SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, const Glib::R
   auto gio_application=Glib::wrap(g_application, true);
   auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
   window.set_transient_for(*application->get_active_window());
-  
+
   window.set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_COMBO);
-  
+
   search_entry.signal_changed().connect([this] {
     if(on_search_entry_changed)
       on_search_entry_changed(search_entry.get_text());
   }, false);
-  
+
   list_view_text.set_search_entry(search_entry);
-  
+
   window.set_default_size(0, 0);
   window.property_decorated()=false;
   window.set_skip_taskbar_hint(true);
-  
+
   scrolled_window.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC);
 
   scrolled_window.add(list_view_text);
@@ -69,7 +69,7 @@ SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, const Glib::R
     auto gio_application=Glib::wrap(g_application, true);
     auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
     auto application_window=application->get_active_window();
-    
+
     // Calculate window width and height
     int row_width=0, padding_height=0, window_height=0;
     Gdk::Rectangle rect;
@@ -84,19 +84,19 @@ SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, const Glib::R
       window_height+=rect.get_height()+padding_height;
       ++c;
     }
-    
+
     if(this->text_view && row_width>this->text_view->get_width()*2/3)
       row_width=this->text_view->get_width()*2/3;
     else if(row_width>application_window->get_width()/2)
       row_width=application_window->get_width()/2;
     else
       scrolled_window.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC);
-    
+
     if(this->show_search_entry)
       window_height+=search_entry.get_height();
     int window_width=row_width+1;
     window.resize(window_width, window_height);
-    
+
     if(this->text_view) {
       Gdk::Rectangle iter_rect;
       this->text_view->get_iter_location(this->start_mark->get_iter(), iter_rect);
@@ -118,7 +118,7 @@ SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, const Glib::R
       window.move(root_x, root_y);
     }
   });
-  
+
   list_view_text.signal_cursor_changed().connect([this] {
     cursor_changed();
   });
@@ -158,7 +158,7 @@ void SelectionDialogBase::show() {
   window.show_all();
   if(text_view)
     text_view->grab_focus();
-  
+
   if(list_view_text.get_model()->children().size()>0) {
     if(!list_view_text.get_selection()->get_selected()) {
       list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
@@ -198,7 +198,7 @@ std::unique_ptr<SelectionDialog> SelectionDialog::instance;
 SelectionDialog::SelectionDialog(Gtk::TextView *text_view, const Glib::RefPtr<Gtk::TextBuffer::Mark> &start_mark, bool show_search_entry, bool use_markup) : SelectionDialogBase(text_view, start_mark, show_search_entry, use_markup) {
   auto search_key=std::make_shared<std::string>();
   auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model());
-  
+
   filter_model->set_visible_func([this, search_key](const Gtk::TreeModel::const_iterator& iter){
     std::string row_lc;
     iter->get_value(0, row_lc);
@@ -217,13 +217,13 @@ SelectionDialog::SelectionDialog(Gtk::TextView *text_view, const Glib::RefPtr<Gt
       return true;
     return false;
   });
-  
+
   list_view_text.set_model(filter_model);
-  
+
   list_view_text.set_search_equal_func([](const Glib::RefPtr<Gtk::TreeModel>& model, int column, const Glib::ustring& key, const Gtk::TreeModel::iterator& iter) {
     return false;
   });
-  
+
   search_entry.signal_changed().connect([this, search_key, filter_model](){
     *search_key=search_entry.get_text();
     filter_model->refilter();
@@ -233,7 +233,7 @@ SelectionDialog::SelectionDialog(Gtk::TextView *text_view, const Glib::RefPtr<Gt
         list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()));
     }
   });
-  
+
   auto activate=[this](){
     auto it=list_view_text.get_selection()->get_selected();
     if(on_select && it) {
@@ -324,9 +324,9 @@ std::unique_ptr<CompletionDialog> CompletionDialog::instance;
 
 CompletionDialog::CompletionDialog(Gtk::TextView *text_view, const Glib::RefPtr<Gtk::TextBuffer::Mark> &start_mark) : SelectionDialogBase(text_view, start_mark, false, false) {
   show_offset=text_view->get_buffer()->get_insert()->get_iter().get_offset();
-  
+
   auto search_key=std::make_shared<std::string>();
-  auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model());  
+  auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model());
   if(show_offset==start_mark->get_iter().get_offset()) {
     filter_model->set_visible_func([search_key](const Gtk::TreeModel::const_iterator& iter){
       std::string row_lc;
@@ -354,11 +354,11 @@ CompletionDialog::CompletionDialog(Gtk::TextView *text_view, const Glib::RefPtr<
     filter_model->refilter();
     list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug)
   });
-  
+
   list_view_text.signal_row_activated().connect([this](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*) {
     select();
   });
-  
+
   auto text=text_view->get_buffer()->get_text(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter());
   if(text.size()>0) {
     search_entry.set_text(text);
@@ -368,7 +368,7 @@ CompletionDialog::CompletionDialog(Gtk::TextView *text_view, const Glib::RefPtr<
 
 void CompletionDialog::select(bool hide_window) {
   row_in_entry=true;
-  
+
   auto it=list_view_text.get_selection()->get_selected();
   if(on_select && it) {
     auto index=it->get_value(list_view_text.column_record.index);
@@ -382,7 +382,7 @@ void CompletionDialog::select(bool hide_window) {
 bool CompletionDialog::on_key_release(GdkEventKey* key) {
   if(key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down || key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up)
     return false;
-    
+
   if(show_offset>text_view->get_buffer()->get_insert()->get_iter().get_offset()) {
     hide();
   }
@@ -400,7 +400,7 @@ bool CompletionDialog::on_key_release(GdkEventKey* key) {
 }
 
 bool CompletionDialog::on_key_press(GdkEventKey* key) {
-  if((key->keyval>=GDK_KEY_0 && key->keyval<=GDK_KEY_9) || 
+  if((key->keyval>=GDK_KEY_0 && key->keyval<=GDK_KEY_9) ||
      (key->keyval>=GDK_KEY_A && key->keyval<=GDK_KEY_Z) ||
      (key->keyval>=GDK_KEY_a && key->keyval<=GDK_KEY_z) ||
      key->keyval==GDK_KEY_underscore || key->keyval==GDK_KEY_BackSpace) {
diff --git a/src/selection_dialog.h b/src/selection_dialog.h
index cf61f1aa..9c8d432a 100644
--- a/src/selection_dialog.h
+++ b/src/selection_dialog.h
@@ -26,13 +26,13 @@ class SelectionDialogBase {
     Gtk::CellRendererText cell_renderer;
     unsigned int size=0;
   };
-  
+
   class SearchEntry : public Gtk::Entry {
   public:
     SearchEntry() : Gtk::Entry() {}
     bool on_key_press_event(GdkEventKey *event) override { return Gtk::Entry::on_key_press_event(event); };
   };
-  
+
 public:
   SelectionDialogBase(Gtk::TextView *text_view, const Glib::RefPtr<Gtk::TextBuffer::Mark> &start_mark, bool show_search_entry, bool use_markup);
   virtual ~SelectionDialogBase();
@@ -41,20 +41,20 @@ class SelectionDialogBase {
   void set_cursor_at_last_row();
   void show();
   void hide();
-  
+
   bool is_visible() {return window.is_visible();}
   void get_position(int &root_x, int &root_y) {window.get_position(root_x, root_y);}
-  
+
   std::function<void()> on_show;
   std::function<void()> on_hide;
   std::function<void(unsigned int index, const std::string &text, bool hide_window)> on_select;
   std::function<void(unsigned int index, const std::string &text)> on_changed;
   std::function<void(const std::string &text)> on_search_entry_changed;
   Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
-  
+
 protected:
   void cursor_changed();
-  
+
   Gtk::TextView *text_view;
   Gtk::Window window;
   Gtk::Box vbox;
@@ -62,7 +62,7 @@ class SelectionDialogBase {
   ListViewText list_view_text;
   SearchEntry search_entry;
   bool show_search_entry;
-  
+
   unsigned int last_index=static_cast<unsigned int>(-1);
 };
 
@@ -71,7 +71,7 @@ class SelectionDialog : public SelectionDialogBase {
   static std::unique_ptr<SelectionDialog> instance;
 public:
   bool on_key_press(GdkEventKey* key);
-  
+
   static void create(Gtk::TextView *text_view, const Glib::RefPtr<Gtk::TextBuffer::Mark> &start_mark, bool show_search_entry=true, bool use_markup=false) {
     instance=std::unique_ptr<SelectionDialog>(new SelectionDialog(text_view, start_mark, show_search_entry, use_markup));
   }
@@ -87,14 +87,14 @@ class CompletionDialog : public SelectionDialogBase {
 public:
   bool on_key_release(GdkEventKey* key);
   bool on_key_press(GdkEventKey* key);
-  
+
   static void create(Gtk::TextView *text_view, const Glib::RefPtr<Gtk::TextBuffer::Mark> &start_mark) {
     instance=std::unique_ptr<CompletionDialog>(new CompletionDialog(text_view, start_mark));
   }
   static std::unique_ptr<CompletionDialog> &get() {return instance;}
 private:
   void select(bool hide_window=true);
-  
+
   int show_offset;
   bool row_in_entry=false;
 };
diff --git a/src/source.cc b/src/source.cc
index 6e5d40bb..3b4ce963 100644
--- a/src/source.cc
+++ b/src/source.cc
@@ -87,7 +87,7 @@ std::string Source::FixIt::string(const Glib::RefPtr<Gtk::TextBuffer> &buffer) {
   unsigned first_line_offset=iter.get_line_offset()+1;
   iter=buffer->get_iter_at_line_index(offsets.second.line, offsets.second.index);
   unsigned second_line_offset=iter.get_line_offset()+1;
-  
+
   std::string text;
   if(type==Type::INSERT) {
     text+="Insert "+source+" at ";
@@ -104,7 +104,7 @@ std::string Source::FixIt::string(const Glib::RefPtr<Gtk::TextBuffer> &buffer) {
     text+=std::to_string(offsets.first.line+1)+":"+std::to_string(first_line_offset)+" - ";
     text+=std::to_string(offsets.second.line+1)+":"+std::to_string(second_line_offset);
   }
-  
+
   return text;
 }
 
@@ -117,7 +117,7 @@ std::unordered_set<Source::View*> Source::View::views;
 Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language, bool is_generic_view): BaseView(file_path, language), SpellCheckView(file_path, language), DiffView(file_path, language) {
   non_deleted_views.emplace(this);
   views.emplace(this);
-  
+
   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);
@@ -127,16 +127,16 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr<
   //TODO: We can drop this, only work on newer versions of gtksourceview.
   //search_match_style=(GtkSourceStyle*)g_object_new(GTK_SOURCE_TYPE_STYLE, "background-set", 1, "background", "#00FF00", nullptr);
   //gtk_source_search_context_set_match_style(search_context, search_match_style);
-  
+
   //TODO: either use lambda if possible or create a gtkmm wrapper around search_context (including search_settings):
   //TODO: (gtkmm's Gtk::Object has connect_property_changed, so subclassing this might be an idea)
   g_signal_connect(search_context, "notify::occurrences-count", G_CALLBACK(search_occurrences_updated), this);
-  
+
   get_buffer()->create_tag("def:warning");
   get_buffer()->create_tag("def:warning_underline");
   get_buffer()->create_tag("def:error");
   get_buffer()->create_tag("def:error_underline");
-  
+
   auto mark_attr_debug_breakpoint=Gsv::MarkAttributes::create();
   Gdk::RGBA rgba;
   rgba.set_red(1.0);
@@ -157,12 +157,12 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr<
   rgba.set_blue(0.75);
   mark_attr_debug_breakpoint_and_stop->set_background(rgba);
   set_mark_attributes("debug_breakpoint_and_stop", mark_attr_debug_breakpoint_and_stop, 102);
-  
+
   get_buffer()->signal_changed().connect([this](){
     if(update_status_location)
       update_status_location(this);
   });
-  
+
   signal_realize().connect([this] {
     auto gutter=get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT);
     auto renderer=gutter->get_renderer_at_pos(15, 0);
@@ -174,7 +174,7 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr<
       });
     }
   });
-  
+
   if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" ||
                   language->get_id()=="cpp" || language->get_id()=="objc" || language->get_id()=="java" ||
                   language->get_id()=="js" || language->get_id()=="ts" || language->get_id()=="proto" ||
@@ -183,10 +183,10 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr<
                   language->get_id()=="go" || language->get_id()=="scala" || language->get_id()=="opencl" ||
                   language->get_id()=="json" || language->get_id()=="css"))
     is_bracket_language=true;
-  
+
   setup_tooltip_and_dialog_events();
   setup_format_style(is_generic_view);
-  
+
 #ifndef __APPLE__
   set_tab_width(4); //Visual size of a \t hardcoded to be equal to visual size of 4 spaces. Buggy on OS X
 #endif
@@ -202,13 +202,13 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr<
         else
           tab_str="<tab>";
       }
-      
+
       tab_char=tab_char_and_size.first;
       tab_size=tab_char_and_size.second;
     }
   }
   set_tab_char_and_size(tab_char, tab_size);
-  
+
   std::string comment_characters;
   if(is_bracket_language)
     comment_characters="//";
@@ -316,7 +316,7 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr<
 void Source::View::set_tab_char_and_size(char tab_char, unsigned tab_size) {
   this->tab_char=tab_char;
   this->tab_size=tab_size;
-      
+
   tab.clear();
   for(unsigned c=0;c<tab_size;c++)
     tab+=tab_char;
@@ -347,7 +347,7 @@ void Source::View::cleanup_whitespace_characters() {
 
 Gsv::DrawSpacesFlags Source::View::parse_show_whitespace_characters(const std::string &text) {
   namespace qi = boost::spirit::qi;
-  
+
   qi::symbols<char, Gsv::DrawSpacesFlags> options;
   options.add
     ("space",    Gsv::DRAW_SPACES_SPACE)
@@ -360,10 +360,10 @@ Gsv::DrawSpacesFlags Source::View::parse_show_whitespace_characters(const std::s
     ("all",      Gsv::DRAW_SPACES_ALL);
 
   std::set<Gsv::DrawSpacesFlags> out;
-  
+
   // parse comma-separated list of options
   qi::phrase_parse(text.begin(), text.end(), options % ',', qi::space, out);
-  
+
   return out.count(Gsv::DRAW_SPACES_ALL)>0 ?
     Gsv::DRAW_SPACES_ALL :
     static_cast<Gsv::DrawSpacesFlags>(std::accumulate(out.begin(), out.end(), 0));
@@ -374,7 +374,7 @@ bool Source::View::save() {
     return false;
   if(Config::get().source.cleanup_whitespace_characters)
     cleanup_whitespace_characters();
-  
+
   if(format_style) {
     if(Config::get().source.format_style_on_save)
       format_style(true);
@@ -382,7 +382,7 @@ bool Source::View::save() {
       format_style(false);
     hide_tooltips();
   }
-  
+
   std::ofstream output(file_path.string(), std::ofstream::binary);
   if(output) {
     auto start_iter=get_buffer()->begin();
@@ -418,15 +418,15 @@ bool Source::View::save() {
 void Source::View::configure() {
   SpellCheckView::configure();
   DiffView::configure();
-  
+
   if(Config::get().source.style.size()>0) {
     auto scheme = StyleSchemeManager::get_default()->get_scheme(Config::get().source.style);
     if(scheme)
       get_source_buffer()->set_style_scheme(scheme);
   }
-  
+
   set_draw_spaces(parse_show_whitespace_characters(Config::get().source.show_whitespace_characters));
-  
+
   if(Config::get().source.wrap_lines)
     set_wrap_mode(Gtk::WrapMode::WRAP_CHAR);
   else
@@ -441,7 +441,7 @@ void Source::View::configure() {
     gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE);
   property_show_right_margin() = Config::get().source.show_right_margin;
   property_right_margin_position() = Config::get().source.right_margin_position;
-  
+
   //Create tags for diagnostic warnings and errors:
   auto scheme = get_source_buffer()->get_style_scheme();
   auto tag_table=get_buffer()->get_tag_table();
@@ -456,7 +456,7 @@ void Source::View::configure() {
     }
     else if(style->property_background_set())
       warning_property=style->property_background().get_value();
-  
+
     diagnostic_tag_underline->property_underline()=Pango::Underline::UNDERLINE_ERROR;
     auto tag_class=G_OBJECT_GET_CLASS(diagnostic_tag_underline->gobj()); //For older GTK+ 3 versions:
     auto param_spec=g_object_class_find_property(tag_class, "underline-rgba");
@@ -475,12 +475,12 @@ void Source::View::configure() {
     }
     else if(style->property_background_set())
       error_property=style->property_background().get_value();
-    
+
     diagnostic_tag_underline->property_underline()=Pango::Underline::UNDERLINE_ERROR;
     diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(error_property));
   }
   //TODO: clear tag_class and param_spec?
-  
+
   if(Config::get().menu.keys["source_show_completion"].empty()) {
     get_completion()->unblock_interactive();
     interactive_completion=true;
@@ -498,11 +498,11 @@ void Source::View::setup_tooltip_and_dialog_events() {
   diagnostic_tooltips.on_motion=[this] {
     delayed_tooltips_connection.disconnect();
   };
-  
+
   get_buffer()->signal_changed().connect([this] {
     hide_tooltips();
   });
-  
+
   signal_motion_notify_event().connect([this](GdkEventMotion* event) {
     if(on_motion_last_x!=event->x || on_motion_last_y!=event->y) {
       delayed_tooltips_connection.disconnect();
@@ -530,11 +530,11 @@ void Source::View::setup_tooltip_and_dialog_events() {
     on_motion_last_y=event->y;
     return false;
   });
-  
+
   get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark) {
     if(get_buffer()->get_has_selection() && mark->get_name()=="selection_bound")
       delayed_tooltips_connection.disconnect();
-    
+
     if(mark->get_name()=="insert") {
       hide_tooltips();
       delayed_tooltips_connection=Glib::signal_timeout().connect([this]() {
@@ -552,12 +552,12 @@ void Source::View::setup_tooltip_and_dialog_events() {
         }
         return false;
       }, 500);
-      
+
       if(SelectionDialog::get())
         SelectionDialog::get()->hide();
       if(CompletionDialog::get())
         CompletionDialog::get()->hide();
-      
+
       if(update_status_location)
         update_status_location(this);
     }
@@ -568,12 +568,12 @@ void Source::View::setup_tooltip_and_dialog_events() {
     hide_dialogs();
     return false;
   });
-  
+
   signal_focus_out_event().connect([this](GdkEventFocus* event) {
     hide_tooltips();
     return false;
   });
-  
+
   signal_leave_notify_event().connect([this](GdkEventCrossing*) {
     delayed_tooltips_connection.disconnect();
     return false;
@@ -607,9 +607,9 @@ void Source::View::setup_format_style(bool is_generic_view) {
         else
           return;
       }
-      
+
       command+=" --stdin-filepath "+this->file_path.string()+" --print-width 120 --config-precedence prefer-file";
-      
+
       if(get_buffer()->get_has_selection()) { // Cannot be used together with --cursor-offset
         Gtk::TextIter start, end;
         get_buffer()->get_selection_bounds(start, end);
@@ -618,11 +618,11 @@ void Source::View::setup_format_style(bool is_generic_view) {
       }
       else
         command+=" --cursor-offset "+std::to_string(get_buffer()->get_insert()->get_iter().get_offset());
-      
+
       size_t num_warnings=0, num_errors=0, num_fix_its=0;
       if(is_generic_view)
         clear_diagnostic_tooltips();
-      
+
       std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream, stderr_stream;
       auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, command, this->file_path.parent_path(), &stderr_stream);
       if(exit_status==0) {
@@ -655,7 +655,7 @@ void Source::View::setup_format_style(bool is_generic_view) {
             end.forward_char();
             if(start==end)
                 start.forward_char();
-            
+
             add_diagnostic_tooltip(start, end, sm[1].str(), true);
           }
           catch(...) {}
@@ -671,15 +671,15 @@ void Source::View::setup_format_style(bool is_generic_view) {
   else if(is_bracket_language) {
     format_style=[this](bool continue_without_style_file) {
       static auto clang_format_command = filesystem::get_executable("clang-format").string();
-      
+
       auto command=clang_format_command+" -output-replacements-xml -assume-filename="+filesystem::escape_argument(this->file_path.string());
-      
+
       if(get_buffer()->get_has_selection()) {
         Gtk::TextIter start, end;
         get_buffer()->get_selection_bounds(start, end);
         command+=" -lines="+std::to_string(start.get_line()+1)+':'+std::to_string(end.get_line()+1);
       }
-      
+
       bool use_style_file=false;
       auto style_file_search_path=this->file_path.parent_path();
       while(true) {
@@ -691,7 +691,7 @@ void Source::View::setup_format_style(bool is_generic_view) {
           break;
         style_file_search_path=style_file_search_path.parent_path();
       }
-      
+
       if(use_style_file)
         command+=" -style=file";
       else {
@@ -714,13 +714,13 @@ void Source::View::setup_format_style(bool is_generic_view) {
           command+=", "+Config::get().source.clang_format_style;
         command+="}\"";
       }
-      
+
       std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream;
-      
+
       auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, command, this->file_path.parent_path());
       if(exit_status==0) {
         // The following code is complex due to clang-format returning offsets in byte offsets instead of char offsets
-        
+
         // Create bytes_in_lines cache to significantly speed up the processing of finding iterators from byte offsets
         std::vector<size_t> bytes_in_lines;
         auto line_count=get_buffer()->get_line_count();
@@ -728,7 +728,7 @@ void Source::View::setup_format_style(bool is_generic_view) {
           auto iter=get_buffer()->get_iter_at_line(line_nr);
           bytes_in_lines.emplace_back(iter.get_bytes_in_line());
         }
-        
+
         get_buffer()->begin_user_action();
         try {
           boost::property_tree::ptree pt;
@@ -739,7 +739,7 @@ void Source::View::setup_format_style(bool is_generic_view) {
               auto offset=it->second.get<size_t>("<xmlattr>.offset");
               auto length=it->second.get<size_t>("<xmlattr>.length");
               auto replacement_str=it->second.get<std::string>("");
-              
+
               size_t bytes=0;
               for(size_t c=0;c<bytes_in_lines.size();++c) {
                 auto previous_bytes=bytes;
@@ -747,7 +747,7 @@ void Source::View::setup_format_style(bool is_generic_view) {
                 if(offset<bytes || (c==bytes_in_lines.size()-1 && offset==bytes)) {
                   std::pair<size_t, size_t> line_index(c, offset-previous_bytes);
                   auto start=get_buffer()->get_iter_at_line_index(line_index.first, line_index.second);
-                  
+
                   // Use left gravity insert to avoid moving cursor from end of line
                   bool left_gravity_insert=false;
                   if(get_buffer()->get_insert()->get_iter()==start) {
@@ -759,7 +759,7 @@ void Source::View::setup_format_style(bool is_generic_view) {
                       }
                     } while(iter.forward_char());
                   }
-                  
+
                   if(length>0) {
                     auto offset_end=offset+length;
                     size_t bytes=0;
@@ -811,22 +811,22 @@ void Source::View::setup_format_style(bool is_generic_view) {
       }
       if(!has_style_file && !continue_without_style_file)
         return;
-      
+
       auto special_character=[](Gtk::TextIter iter) {
         if(*iter=='*' || *iter=='#' || *iter=='<' || *iter=='>' || *iter==' ' || *iter=='=' || *iter=='`' || *iter=='-')
           return true;
-        // Tests if a line starts with for instance: 2. 
+        // Tests if a line starts with for instance: 2.
         if(*iter>='0' && *iter<='9' && iter.forward_char() &&
            *iter=='.' && iter.forward_char() &&
            *iter==' ')
           return true;
         return false;
       };
-      
+
       get_buffer()->begin_user_action();
       disable_spellcheck=true;
       cleanup_whitespace_characters();
-      
+
       auto iter=get_buffer()->begin();
       size_t last_space_offset=-1;
       bool headline=false;
@@ -919,11 +919,11 @@ void Source::View::search_occurrences_updated(GtkWidget* widget, GParamSpec* pro
 Source::View::~View() {
   g_clear_object(&search_context);
   g_clear_object(&search_settings);
-  
+
   delayed_tooltips_connection.disconnect();
   delayed_tag_similar_symbols_connection.disconnect();
   renderer_activate_connection.disconnect();
-  
+
   non_deleted_views.erase(this);
   views.erase(this);
 }
@@ -984,7 +984,7 @@ void Source::View::replace_forward(const std::string &replacement) {
 #else
     gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), nullptr);
 #endif
-    
+
     Glib::ustring replacement_ustring=replacement;
     get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset), get_buffer()->get_iter_at_offset(offset+replacement_ustring.size()));
     scroll_to(get_buffer()->get_insert());
@@ -1026,9 +1026,9 @@ void Source::View::paste() {
     ~Guard() { value = false; }
   };
   Guard guard{multiple_cursors_use};
-  
+
   std::string text=Gtk::Clipboard::get()->wait_for_text();
-  
+
   //Replace carriage returns (which leads to crash) with newlines
   for(size_t c=0;c<text.size();c++) {
     if(text[c]=='\r') {
@@ -1038,7 +1038,7 @@ void Source::View::paste() {
         text.replace(c, 1, "\n");
     }
   }
-  
+
   //Exception for when pasted text is only whitespaces
   bool only_whitespaces=true;
   for(auto &chr: text) {
@@ -1053,7 +1053,7 @@ void Source::View::paste() {
     scroll_to_cursor_delayed(this, false, false);
     return;
   }
-  
+
   get_buffer()->begin_user_action();
   if(get_buffer()->get_has_selection()) {
     Gtk::TextIter start, end;
@@ -1133,7 +1133,7 @@ void Source::View::paste() {
       if(!(first_paste_line && !first_paste_line_has_tabs) && line_tabs<paste_line_tabs) {
         tabs=line_tabs;
       }
-      
+
       if(first_paste_line) {
         if(first_paste_line_has_tabs)
           get_buffer()->insert_at_cursor(text.substr(start_line+tabs, end_line-start_line-tabs));
@@ -1164,9 +1164,9 @@ void Source::View::hide_tooltips() {
 
 void Source::View::add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, std::string spelling, bool error) {
   diagnostic_offsets.emplace(start.get_offset());
-  
+
   std::string severity_tag_name = error ? "def:error" : "def:warning";
-  
+
   auto create_tooltip_buffer=[this, spelling=std::move(spelling), error, severity_tag_name]() {
     auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
     tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), error ? "Error" : "Warning", severity_tag_name);
@@ -1174,9 +1174,9 @@ void Source::View::add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk:
     return tooltip_buffer;
   };
   diagnostic_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start), get_buffer()->create_mark(end));
-  
+
   get_buffer()->apply_tag_by_name(severity_tag_name+"_underline", start, end);
-  
+
   auto iter=get_buffer()->get_insert()->get_iter();
   if(iter.ends_line()) {
     auto next_iter=iter;
@@ -1204,7 +1204,7 @@ bool Source::View::find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk:
   long para_count=0;
   long square_count=0;
   long curly_count=0;
-  
+
   do {
     if(*iter=='(' && is_code_iter(iter))
       para_count++;
@@ -1218,10 +1218,10 @@ bool Source::View::find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk:
       curly_count++;
     else if(*iter=='}' && is_code_iter(iter))
       curly_count--;
-    
+
     if(curly_count>0)
       break;
-    
+
     if(para_count>0 || square_count>0) {
       found_iter=iter;
       return true;
@@ -1233,21 +1233,21 @@ bool Source::View::find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk:
 Gtk::TextIter Source::View::find_start_of_sentence(Gtk::TextIter iter) {
   if(iter.starts_line())
     return iter;
-  
+
   bool stream_operator_test=false;
   bool colon_test=false;
-  
+
   if(*iter==';')
     stream_operator_test=true;
   if(*iter=='{') {
     iter.backward_char();
     colon_test=true;
   }
-  
+
   int para_count=0;
   int square_count=0;
   long curly_count=0;
-  
+
   do {
     if(*iter=='(' && is_code_iter(iter))
       para_count++;
@@ -1261,10 +1261,10 @@ Gtk::TextIter Source::View::find_start_of_sentence(Gtk::TextIter iter) {
       curly_count++;
     else if(*iter=='}' && is_code_iter(iter))
       curly_count--;
-    
+
     if(curly_count>0)
       break;
-    
+
     if(iter.starts_line() && para_count==0 && square_count==0) {
       bool stream_operator_found=false;
       bool colon_found=false;
@@ -1302,13 +1302,13 @@ Gtk::TextIter Source::View::find_start_of_sentence(Gtk::TextIter iter) {
       }
     }
   } while(iter.backward_char());
-  
+
   return iter;
 }
 
 bool Source::View::find_open_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
   long count=0;
-  
+
   do {
     if(*iter=='{') {
       if(count==0 && is_code_iter(iter)) {
@@ -1325,7 +1325,7 @@ bool Source::View::find_open_curly_bracket_backward(Gtk::TextIter iter, Gtk::Tex
 
 bool Source::View::find_close_curly_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter) {
   long count=0;
-  
+
   do {
     if(*iter=='}' && is_code_iter(iter)) {
       if(count==0) {
@@ -1350,7 +1350,7 @@ long Source::View::symbol_count(Gtk::TextIter iter, unsigned int positive_char,
   bool check_if_next_iter_is_code_iter=false;
   if(positive_char=='\'' || negative_char=='\'' || positive_char=='"' || negative_char=='"')
     check_if_next_iter_is_code_iter=true;
-  
+
   Gtk::TextIter previous_iter;
   do {
     if(*iter==positive_char && is_code_iter(iter))
@@ -1369,16 +1369,16 @@ long Source::View::symbol_count(Gtk::TextIter iter, unsigned int positive_char,
       else if(*iter==negative_char && is_code_iter(next_iter))
         symbol_count--;
     }
-    
+
     if(break_on_curly && curly_count>0)
       break;
   } while(iter.backward_char());
-  
+
   iter=iter_stored;
   if(!iter.forward_char()) {
     return symbol_count;
   }
-  
+
   curly_count=0;
   do {
     if(*iter==positive_char && is_code_iter(iter))
@@ -1397,11 +1397,11 @@ long Source::View::symbol_count(Gtk::TextIter iter, unsigned int positive_char,
       else if(*iter==negative_char && is_code_iter(next_iter))
         symbol_count--;
     }
-    
+
     if(break_on_curly && curly_count<0)
       break;
   } while(iter.forward_char());
-  
+
   return symbol_count;
 }
 
@@ -1409,10 +1409,10 @@ bool Source::View::is_templated_function(Gtk::TextIter iter, Gtk::TextIter &pare
   auto iter_stored=iter;
   long bracket_count=0;
   long curly_count=0;
-  
+
   if(!(iter.backward_char() && *iter=='>' && *iter_stored=='('))
     return false;
-  
+
   do {
     if(*iter=='<' && is_code_iter(iter))
       bracket_count++;
@@ -1422,17 +1422,17 @@ bool Source::View::is_templated_function(Gtk::TextIter iter, Gtk::TextIter &pare
       curly_count++;
     else if(*iter=='}' && is_code_iter(iter))
       curly_count--;
-    
+
     if(bracket_count==0)
       break;
-    
+
     if(curly_count>0)
       break;
   } while(iter.backward_char());
-  
+
   if(bracket_count!=0)
     return false;
-  
+
   iter=iter_stored;
   bracket_count=0;
   curly_count=0;
@@ -1445,23 +1445,23 @@ bool Source::View::is_templated_function(Gtk::TextIter iter, Gtk::TextIter &pare
       curly_count++;
     else if(*iter=='}' && is_code_iter(iter))
       curly_count--;
-    
+
     if(bracket_count==0) {
       parenthesis_end_iter=iter;
       return true;
     }
-    
+
     if(curly_count<0)
       return false;
   } while(iter.forward_char());
-  
+
   return false;
 }
 
 std::string Source::View::get_token(Gtk::TextIter iter) {
   auto start=iter;
   auto end=iter;
-  
+
   while((*iter>='A' && *iter<='Z') || (*iter>='a' && *iter<='z') || (*iter>='0' && *iter<='9') || *iter=='_') {
     start=iter;
     if(!iter.backward_char())
@@ -1471,7 +1471,7 @@ std::string Source::View::get_token(Gtk::TextIter iter) {
     if(!end.forward_char())
       break;
   }
-  
+
   return get_buffer()->get_text(start, end);
 }
 
@@ -1502,7 +1502,7 @@ bool Source::View::on_key_press_event(GdkEventKey* key) {
     ~Guard() { value = false; }
   };
   Guard guard{multiple_cursors_use};
-  
+
   if(SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
     if(SelectionDialog::get()->on_key_press(key))
       return true;
@@ -1511,14 +1511,14 @@ bool Source::View::on_key_press_event(GdkEventKey* key) {
     if(CompletionDialog::get()->on_key_press(key))
       return true;
   }
-  
+
   if(last_keyval<GDK_KEY_Shift_L || last_keyval>GDK_KEY_Hyper_R)
     previous_non_modifier_keyval=last_keyval;
   last_keyval=key->keyval;
-  
+
   if(Config::get().source.enable_multiple_cursors && on_key_press_event_multiple_cursors(key))
     return true;
-  
+
   //Move cursor one paragraph down
   if((key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down) && (key->state&GDK_CONTROL_MASK)>0) {
     auto selection_start_iter=get_buffer()->get_selection_bound()->get_iter();
@@ -1586,7 +1586,7 @@ bool Source::View::on_key_press_event(GdkEventKey* key) {
   }
 
   get_buffer()->begin_user_action();
-  
+
   // Shift+enter: go to end of line and enter
   if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && (key->state&GDK_SHIFT_MASK)>0) {
     auto iter=get_buffer()->get_insert()->get_iter();
@@ -1595,7 +1595,7 @@ bool Source::View::on_key_press_event(GdkEventKey* key) {
       get_buffer()->place_cursor(iter);
     }
   }
-  
+
   if(Config::get().source.smart_brackets && on_key_press_event_smart_brackets(key)) {
     get_buffer()->end_user_action();
     return true;
@@ -1604,7 +1604,7 @@ bool Source::View::on_key_press_event(GdkEventKey* key) {
     get_buffer()->end_user_action();
     return true;
   }
-  
+
   if(is_bracket_language && on_key_press_event_bracket_language(key)) {
     get_buffer()->end_user_action();
     return true;
@@ -1626,10 +1626,10 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
   //Indent as in next or previous line
   if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && !get_buffer()->get_has_selection() && !iter.starts_line()) {
     cleanup_whitespace_characters_on_return(iter);
-    
+
     iter=get_buffer()->get_insert()->get_iter();
     auto tabs=get_line_before(get_tabs_end_iter(iter));
-    
+
     auto previous_iter=iter;
     if(previous_iter.backward_char() && *previous_iter==':' && language && language->get_id()=="python") // Python indenting after :
       tabs+=tab;
@@ -1665,7 +1665,7 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
       while(next_line_iter.starts_line() && next_line_iter.forward_char()) {}
       auto next_line_tabs_end_iter=get_tabs_end_iter(next_line_iter);
       auto next_line_tabs=get_line_before(next_line_tabs_end_iter);
-      
+
       std::string tabs;
       if(previous_line_tabs.size()<next_line_tabs.size())
         tabs=previous_line_tabs;
@@ -1676,7 +1676,7 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
         return true;
       }
     }
-    
+
     Gtk::TextIter selection_start, selection_end;
     get_buffer()->get_selection_bounds(selection_start, selection_end);
     auto selection_end_mark=get_buffer()->create_mark(selection_end);
@@ -1696,18 +1696,18 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
     get_buffer()->get_selection_bounds(selection_start, selection_end);
     int line_start=selection_start.get_line();
     int line_end=selection_end.get_line();
-    
+
     unsigned indent_left_steps=tab_size;
     std::vector<bool> ignore_line;
     for(int line_nr=line_start;line_nr<=line_end;line_nr++) {
       auto line_it = get_buffer()->get_iter_at_line(line_nr);
-      if(!get_buffer()->get_has_selection() || line_it!=selection_end) {        
+      if(!get_buffer()->get_has_selection() || line_it!=selection_end) {
         auto tabs_end_iter=get_tabs_end_iter(line_nr);
         if(tabs_end_iter.starts_line() && tabs_end_iter.ends_line())
           ignore_line.push_back(true);
         else {
           auto line_tabs=get_line_before(tabs_end_iter);
-          
+
           if(line_tabs.size()>0) {
             indent_left_steps=std::min(indent_left_steps, static_cast<unsigned>(line_tabs.size()));
             ignore_line.push_back(false);
@@ -1717,7 +1717,7 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
         }
       }
     }
-    
+
     for(int line_nr=line_start;line_nr<=line_end;line_nr++) {
       Gtk::TextIter line_it = get_buffer()->get_iter_at_line(line_nr);
       Gtk::TextIter line_plus_it=line_it;
@@ -1811,11 +1811,11 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
     }
     get_buffer()->insert_at_cursor(Glib::ustring(1, unicode));
     scroll_to(get_buffer()->get_insert());
-    
+
     //Trick to make the cursor visible right after insertion:
     set_cursor_visible(false);
     set_cursor_visible();
-    
+
     return true;
   }
 
@@ -1832,14 +1832,14 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
 
   if(get_buffer()->get_has_selection())
     return false;
-  
+
   if(!is_code_iter(iter)) {
     // Add * at start of line in comment blocks
     if(key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) {
       if(!iter.starts_line() && (!string_tag || (!iter.has_tag(string_tag) && !iter.ends_tag(string_tag)))) {
         cleanup_whitespace_characters_on_return(iter);
         iter=get_buffer()->get_insert()->get_iter();
-        
+
         auto start_iter=get_tabs_end_iter(iter.get_line());
         auto end_iter=start_iter;
         end_iter.forward_chars(2);
@@ -1851,7 +1851,7 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
             if(start_of_sentence[0]=='/')
               insert_str+=' ';
             insert_str+="* ";
-            
+
             get_buffer()->insert_at_cursor(insert_str);
             return true;
           }
@@ -1863,7 +1863,7 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
     else
       return false;
   }
-  
+
   // get iter for if expressions below, which is moved backwards past any comment
   auto get_condition_iter=[this](const Gtk::TextIter &iter) {
     auto condition_iter=iter;
@@ -1880,12 +1880,12 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
           condition_iter.backward_char()) {}
     return condition_iter;
   };
-  
+
   //Indent depending on if/else/etc and brackets
   if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && !iter.starts_line()) {
     cleanup_whitespace_characters_on_return(iter);
     iter=get_buffer()->get_insert()->get_iter();
-    
+
     auto condition_iter=get_condition_iter(iter);
     auto start_iter=condition_iter;
     if(*start_iter=='{')
@@ -1899,7 +1899,7 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
     else
       start_iter=get_tabs_end_iter(get_buffer()->get_iter_at_line(find_start_of_sentence(condition_iter).get_line()));
     auto tabs=get_line_before(start_iter);
-    
+
     /*
      * Change tabs after ending comment block with an extra space (as in this case)
      */
@@ -1914,7 +1914,7 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
         return true;
       }
     }
-    
+
     if(*condition_iter=='{' && is_code_iter(condition_iter)) {
       Gtk::TextIter found_iter;
       // Check if an '}' is needed
@@ -1929,7 +1929,7 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
       // special case for functions and classes with no indentation after: namespace {
       if(tabs.empty() && has_right_curly_bracket)
         has_right_curly_bracket=symbol_count(iter, '{', '}')!=1;
-      
+
       if(*get_buffer()->get_insert()->get_iter()=='}') {
         get_buffer()->insert_at_cursor("\n"+tabs+tab+"\n"+tabs);
         auto insert_it = get_buffer()->get_insert()->get_iter();
@@ -1972,7 +1972,7 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
                 --para_count;
               else if(*it=='(' && is_code_iter(it))
                 ++para_count;
-              
+
               if(square_outside_para_found && square_count==0 && para_count==0) {
                 add_semicolon=true;
                 break;
@@ -2005,7 +2005,7 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
         return true;
       }
     }
-    
+
     //Indent multiline expressions
     if(open_non_curly_bracket_iter_found) {
       auto tabs_end_iter=get_tabs_end_iter(open_non_curly_bracket_iter);
@@ -2141,14 +2141,14 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
       }
     }
   }
-  
+
   return false;
 }
 
 bool Source::View::on_key_press_event_smart_brackets(GdkEventKey *key) {
   if(get_buffer()->get_has_selection())
     return false;
-  
+
   auto iter=get_buffer()->get_insert()->get_iter();
   auto previous_iter=iter;
   previous_iter.backward_char();
@@ -2189,7 +2189,7 @@ bool Source::View::on_key_press_event_smart_brackets(GdkEventKey *key) {
       }
     }
   }
-  
+
   return false;
 }
 
@@ -2271,19 +2271,19 @@ bool Source::View::on_key_press_event_smart_inserts(GdkEventKey *key) {
     }
     return false;
   }
-  
+
   auto iter=get_buffer()->get_insert()->get_iter();
   auto previous_iter=iter;
   previous_iter.backward_char();
   auto next_iter=iter;
   next_iter.forward_char();
-  
+
   auto allow_insertion=[](const Gtk::TextIter &iter) {
     if(iter.ends_line() || *iter==' ' || *iter=='\t' || *iter==';' || *iter==')' || *iter==']' || *iter=='[' || *iter=='{' || *iter=='}')
       return true;
     return false;
   };
-  
+
   // Move right when clicking ' before a ' or when clicking " before a "
   if(((key->keyval==GDK_KEY_apostrophe && *iter=='\'') ||
       (key->keyval==GDK_KEY_quotedbl && *iter=='\"')) && is_code_iter(next_iter)) {
@@ -2314,7 +2314,7 @@ bool Source::View::on_key_press_event_smart_inserts(GdkEventKey *key) {
       return true;
     }
   }
-  
+
   if(is_code_iter(iter)) {
     // Insert ()
     if(key->keyval==GDK_KEY_parenleft && allow_insertion(iter)) {
@@ -2405,7 +2405,7 @@ bool Source::View::on_key_press_event_smart_inserts(GdkEventKey *key) {
       }
     }
   }
-  
+
   return false;
 }
 
@@ -2420,7 +2420,7 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
           break;
         }
       }
-      
+
       if(mark->get_name()=="insert") {
         if(multiple_cursors_use) {
           multiple_cursors_use=false;
@@ -2438,7 +2438,7 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
         multiple_cursors_last_insert=get_buffer()->create_mark(mark->get_iter(), false);
       }
     });
-    
+
     // TODO: this handler should run after signal_insert
     get_buffer()->signal_insert().connect([this](const Gtk::TextBuffer::iterator &iter, const Glib::ustring &text, int bytes) {
       if(multiple_cursors_use) {
@@ -2452,7 +2452,7 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
         multiple_cursors_use=true;
       }
     });
-    
+
     get_buffer()->signal_erase().connect([this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
       if(multiple_cursors_use) {
         auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset();
@@ -2460,7 +2460,7 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
         multiple_cursors_erase_forward_length=iter_end.get_offset()-insert_offset;
       }
     }, false);
-    
+
     get_buffer()->signal_erase().connect([this](const Gtk::TextBuffer::iterator &iter_start, const Gtk::TextBuffer::iterator &iter_end) {
       if(multiple_cursors_use) {
         multiple_cursors_use=false;
@@ -2475,8 +2475,8 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
       }
     });
   }
-  
-  
+
+
   if(key->keyval==GDK_KEY_Escape && !multiple_cursors_extra_cursors.empty()) {
     for(auto &extra_cursor: multiple_cursors_extra_cursors) {
       extra_cursor.first->set_visible(false);
@@ -2485,10 +2485,10 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
     multiple_cursors_extra_cursors.clear();
     return true;
   }
-  
+
   unsigned create_cursor_mask=GDK_MOD1_MASK;
   unsigned move_last_created_cursor_mask=GDK_SHIFT_MASK|GDK_MOD1_MASK;
-  
+
   // Move last created cursor
   if((key->keyval==GDK_KEY_Left || key->keyval==GDK_KEY_KP_Left) && (key->state&move_last_created_cursor_mask)==move_last_created_cursor_mask) {
     if(multiple_cursors_extra_cursors.empty())
@@ -2538,7 +2538,7 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
     }
     return true;
   }
-  
+
   // Create extra cursor
   if((key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up) && (key->state&create_cursor_mask)==create_cursor_mask) {
     auto insert_iter=get_buffer()->get_insert()->get_iter();
@@ -2574,7 +2574,7 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
     }
     return true;
   }
-  
+
   // Move cursors left/right
   if((key->keyval==GDK_KEY_Left || key->keyval==GDK_KEY_KP_Left) && (key->state&GDK_CONTROL_MASK)>0) {
     multiple_cursors_use=false;
@@ -2608,7 +2608,7 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
       get_buffer()->move_mark_by_name("selection_bound", iter);
     return true;
   }
-  
+
   // Move cursors up/down
   if((key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up)) {
     multiple_cursors_use=false;
@@ -2640,7 +2640,7 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
     }
     return false;
   }
-  
+
   // Smart Home-key, start of line
   if((key->keyval==GDK_KEY_Home || key->keyval==GDK_KEY_KP_Home) && (key->state&GDK_CONTROL_MASK)==0) {
     for(auto &extra_cursor: multiple_cursors_extra_cursors)
@@ -2655,7 +2655,7 @@ bool Source::View::on_key_press_event_multiple_cursors(GdkEventKey *key) {
     multiple_cursors_use=false;
     return false;
   }
-  
+
   return false;
 }
 
@@ -2692,7 +2692,7 @@ bool Source::View::on_button_press_event(GdkEventButton *event) {
       get_iter_at_location(iter, x, y);
       if(iter)
         get_buffer()->place_cursor(iter);
-      
+
       Menu::get().actions["source_goto_declaration_or_implementation"]->activate();
       return true;
     }
@@ -2896,19 +2896,19 @@ std::pair<char, unsigned> Source::View::find_tab_char_and_size() {
 Source::GenericView::GenericView(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language) : BaseView(file_path, language), View(file_path, language, true) {
   configure();
   spellcheck_all=true;
-  
+
   if(language)
     get_source_buffer()->set_language(language);
-  
+
   auto completion=get_completion();
   completion->property_show_headers()=false;
   completion->property_show_icons()=false;
   completion->property_accelerators()=0;
-  
+
   auto completion_words=Gsv::CompletionWords::create("", Glib::RefPtr<Gdk::Pixbuf>());
   completion_words->register_provider(get_buffer());
   completion->add_provider(completion_words);
-  
+
   if(language) {
     auto language_manager=LanguageManager::get_default();
     auto search_paths=language_manager->get_search_path();
@@ -2966,7 +2966,7 @@ void Source::GenericView::parse_language_file(Glib::RefPtr<CompletionBuffer> &co
     try {
       parse_language_file(completion_buffer, has_context_class, node.second);
     }
-    catch(const std::exception &e) {        
+    catch(const std::exception &e) {
     }
   }
 }
diff --git a/src/source.h b/src/source.h
index 16a23f8c..a8805fc8 100644
--- a/src/source.h
+++ b/src/source.h
@@ -20,29 +20,29 @@ namespace Source {
   public:
     static Glib::RefPtr<Gsv::StyleSchemeManager> get_default();
   };
-  
+
   Glib::RefPtr<Gsv::Language> guess_language(const boost::filesystem::path &file_path);
-  
+
   class Offset {
   public:
     Offset() = default;
     Offset(unsigned line, unsigned index, boost::filesystem::path file_path_=""): line(line), index(index), file_path(std::move(file_path_)) {}
     operator bool() { return !file_path.empty(); }
     bool operator==(const Offset &o) {return (line==o.line && index==o.index);}
-    
+
     unsigned line;
     unsigned index;
     boost::filesystem::path file_path;
   };
-  
+
   class FixIt {
   public:
     enum class Type {INSERT, REPLACE, ERASE};
-    
+
     FixIt(std::string source_, std::pair<Offset, Offset> offsets_);
-    
+
     std::string string(const Glib::RefPtr<Gtk::TextBuffer> &buffer);
-    
+
     Type type;
     std::string source;
     std::pair<Offset, Offset> offsets;
@@ -52,14 +52,14 @@ namespace Source {
   public:
     static std::unordered_set<View*> non_deleted_views;
     static std::unordered_set<View*> views;
-    
+
     View(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language, bool is_generic_view=false);
     ~View() override;
-    
+
     bool save() override;
-    
+
     void configure() override;
-    
+
     void search_highlight(const std::string &text, bool case_sensitive, bool regex);
     std::function<void(int number)> update_search_occurrences;
     void search_forward();
@@ -67,9 +67,9 @@ namespace Source {
     void replace_forward(const std::string &replacement);
     void replace_backward(const std::string &replacement);
     void replace_all(const std::string &replacement);
-    
+
     void paste();
-    
+
     std::function<void()> non_interactive_completion;
     std::function<void(bool)> format_style;
     std::function<Offset()> get_declaration_location;
@@ -87,13 +87,13 @@ namespace Source {
     std::function<void()> toggle_comments;
     std::function<std::tuple<Source::Offset, std::string, size_t>()> get_documentation_template;
     std::function<void(int)> toggle_breakpoint;
-    
+
     void hide_tooltips() override;
     void hide_dialogs() override;
-    
+
     void set_tab_char_and_size(char tab_char, unsigned tab_size);
     std::pair<char, unsigned> get_tab_char_and_size() {return {tab_char, tab_size};}
-    
+
     bool soft_reparse_needed=false;
     bool full_reparse_needed=false;
     virtual void soft_reparse(bool delayed=false) {soft_reparse_needed=false;}
@@ -110,7 +110,7 @@ namespace Source {
     virtual void show_type_tooltips(const Gdk::Rectangle &rectangle) {}
     gdouble on_motion_last_x=0.0;
     gdouble on_motion_last_y=0.0;
-    
+
     /// Usually returns at start of line, but not always
     Gtk::TextIter find_start_of_sentence(Gtk::TextIter iter);
     bool find_open_non_curly_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
@@ -118,11 +118,11 @@ namespace Source {
     bool find_close_curly_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
     long symbol_count(Gtk::TextIter iter, unsigned int positive_char, unsigned int negative_char);
     bool is_templated_function(Gtk::TextIter iter, Gtk::TextIter &parenthesis_end_iter);
-    
+
     std::string get_token(Gtk::TextIter iter);
-    
+
     void cleanup_whitespace_characters_on_return(const Gtk::TextIter &iter);
-    
+
     bool is_bracket_language=false;
     bool on_key_press_event(GdkEventKey* key) override;
     bool on_key_press_event_basic(GdkEventKey* key);
@@ -131,28 +131,28 @@ namespace Source {
     bool on_key_press_event_smart_inserts(GdkEventKey* key);
     bool on_button_press_event(GdkEventButton *event) override;
     bool on_motion_notify_event(GdkEventMotion *motion_event) override;
-    
+
     std::pair<char, unsigned> find_tab_char_and_size();
     unsigned tab_size;
     char tab_char;
     std::string tab;
-    
+
     bool interactive_completion=true;
-    
+
     guint previous_non_modifier_keyval=0;
   private:
     void setup_tooltip_and_dialog_events();
     void setup_format_style(bool is_generic_view);
-    
+
     void cleanup_whitespace_characters();
     Gsv::DrawSpacesFlags parse_show_whitespace_characters(const std::string &text);
-    
+
     GtkSourceSearchContext *search_context;
     GtkSourceSearchSettings *search_settings;
     static void search_occurrences_updated(GtkWidget* widget, GParamSpec* property, gpointer data);
-    
+
     sigc::connection renderer_activate_connection;
-    
+
     bool multiple_cursors_signals_set=false;
     bool multiple_cursors_use=false;
     std::vector<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, int>> multiple_cursors_extra_cursors;
@@ -161,7 +161,7 @@ namespace Source {
     int multiple_cursors_erase_forward_length;
     bool on_key_press_event_multiple_cursors(GdkEventKey* key);
   };
-  
+
   class GenericView : public View {
   private:
     class CompletionBuffer : public Gtk::TextBuffer {
@@ -170,7 +170,7 @@ namespace Source {
     };
   public:
     GenericView(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language);
-    
+
     void parse_language_file(Glib::RefPtr<CompletionBuffer> &completion_buffer, bool &has_context_class, const boost::property_tree::ptree &pt);
   };
 }
diff --git a/src/source_base.cc b/src/source_base.cc
index 25c293ba..eb40bfb8 100644
--- a/src/source_base.cc
+++ b/src/source_base.cc
@@ -8,13 +8,13 @@
 Source::BaseView::BaseView(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language): Gsv::View(), file_path(file_path), language(language), status_diagnostics(0, 0, 0) {
   load(true);
   get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0));
-  
+
   signal_focus_in_event().connect([this](GdkEventFocus *event) {
     if(this->last_write_time!=static_cast<std::time_t>(-1))
       check_last_write_time();
     return false;
   });
-  
+
   monitor_file();
 }
 
@@ -28,11 +28,11 @@ bool Source::BaseView::load(bool not_undoable_action) {
   last_write_time=boost::filesystem::last_write_time(file_path, ec);
   if(ec)
     last_write_time=static_cast<std::time_t>(-1);
-  
+
   disable_spellcheck=true;
   if(not_undoable_action)
     get_source_buffer()->begin_not_undoable_action();
-  
+
   class Guard {
   public:
     Source::BaseView *view;
@@ -44,14 +44,14 @@ bool Source::BaseView::load(bool not_undoable_action) {
     }
   };
   Guard guard{this, not_undoable_action};
-  
+
   if(language) {
     std::ifstream input(file_path.string(), std::ofstream::binary);
     if(input) {
       std::stringstream ss;
       ss << input.rdbuf();
       Glib::ustring ustr=ss.str();
-      
+
       bool valid=true;
       Glib::ustring::iterator iter;
       while(!ustr.validate(iter)) {
@@ -60,10 +60,10 @@ bool Source::BaseView::load(bool not_undoable_action) {
         ustr.replace(iter, next_char_iter, "?");
         valid=false;
       }
-      
+
       if(!valid)
         Terminal::get().print("Warning: "+file_path.string()+" is not a valid UTF-8 file. Saving might corrupt the file.\n");
-      
+
       if(get_buffer()->size()==0)
         get_buffer()->insert_at_cursor(ustr);
       else
@@ -78,7 +78,7 @@ bool Source::BaseView::load(bool not_undoable_action) {
       std::stringstream ss;
       ss << input.rdbuf();
       Glib::ustring ustr=ss.str();
-      
+
       if(ustr.validate()) {
         if(get_buffer()->size()==0)
           get_buffer()->insert_at_cursor(ustr);
@@ -93,14 +93,14 @@ bool Source::BaseView::load(bool not_undoable_action) {
     else
       return false;
   }
-  
+
   get_buffer()->set_modified(false);
   return true;
 }
 
 void Source::BaseView::replace_text(const std::string &new_text) {
   get_buffer()->begin_user_action();
-  
+
   if(get_buffer()->size()==0) {
     get_buffer()->insert_at_cursor(new_text);
     get_buffer()->end_user_action();
@@ -111,13 +111,13 @@ void Source::BaseView::replace_text(const std::string &new_text) {
     get_buffer()->end_user_action();
     return;
   }
-  
+
   auto iter=get_buffer()->get_insert()->get_iter();
   int cursor_line_nr=iter.get_line();
   int cursor_line_offset=iter.ends_line() ? std::numeric_limits<int>::max() : iter.get_line_offset();
-  
+
   std::vector<std::pair<const char*, const char*>> new_lines;
-  
+
   const char* line_start=new_text.c_str();
   for(const char &chr: new_text) {
     if(chr=='\n') {
@@ -127,17 +127,17 @@ void Source::BaseView::replace_text(const std::string &new_text) {
   }
   if(new_text.empty() || new_text.back()!='\n')
     new_lines.emplace_back(line_start, &new_text[new_text.size()]);
-  
+
   try {
     auto hunks = Git::Repository::Diff::get_hunks(get_buffer()->get_text().raw(), new_text);
-    
+
     for(auto it=hunks.rbegin();it!=hunks.rend();++it) {
       bool place_cursor=false;
       Gtk::TextIter start;
       if(it->old_lines.second!=0) {
         start=get_buffer()->get_iter_at_line(it->old_lines.first-1);
         auto end=get_buffer()->get_iter_at_line(it->old_lines.first-1+it->old_lines.second);
-        
+
         if(cursor_line_nr>=start.get_line() && cursor_line_nr<end.get_line()) {
           if(it->new_lines.second!=0) {
             place_cursor = true;
@@ -145,7 +145,7 @@ void Source::BaseView::replace_text(const std::string &new_text) {
             cursor_line_nr+=static_cast<int>(0.5+(static_cast<float>(line_diff)/it->old_lines.second)*it->new_lines.second)-line_diff;
           }
         }
-        
+
         get_buffer()->erase(start, end);
         start=get_buffer()->get_iter_at_line(it->old_lines.first-1);
       }
@@ -161,13 +161,13 @@ void Source::BaseView::replace_text(const std::string &new_text) {
   catch(...) {
     Terminal::get().print("Error: Could not replace text in buffer\n", true);
   }
-  
+
   get_buffer()->end_user_action();
 }
 
 void Source::BaseView::rename(const boost::filesystem::path &path) {
   file_path=path;
-  
+
   if(update_status_file_path)
     update_status_file_path(this);
   if(update_tab_label)
@@ -215,7 +215,7 @@ void Source::BaseView::monitor_file() {
 void Source::BaseView::check_last_write_time(std::time_t last_write_time_) {
   if(this->last_write_time==static_cast<std::time_t>(-1))
     return;
-  
+
   if(Config::get().source.auto_reload_changed_files && !get_buffer()->get_modified()) {
     boost::system::error_code ec;
     auto last_write_time=last_write_time_!=static_cast<std::time_t>(-1) ? last_write_time_ : boost::filesystem::last_write_time(file_path, ec);
@@ -306,10 +306,10 @@ void Source::BaseView::place_cursor_at_line_index(int line, int index) {
 Gtk::TextIter Source::BaseView::get_smart_home_iter(const Gtk::TextIter &iter) {
   auto start_line_iter=get_buffer()->get_iter_at_line(iter.get_line());
   auto start_sentence_iter=start_line_iter;
-  while(!start_sentence_iter.ends_line() && 
+  while(!start_sentence_iter.ends_line() &&
         (*start_sentence_iter==' ' || *start_sentence_iter=='\t') &&
         start_sentence_iter.forward_char()) {}
-  
+
   if(iter>start_sentence_iter || iter==start_line_iter)
     return start_sentence_iter;
   else
@@ -319,12 +319,12 @@ Gtk::TextIter Source::BaseView::get_smart_home_iter(const Gtk::TextIter &iter) {
 Gtk::TextIter Source::BaseView::get_smart_end_iter(const Gtk::TextIter &iter) {
   auto end_line_iter=get_iter_at_line_end(iter.get_line());
   auto end_sentence_iter=end_line_iter;
-  while(!end_sentence_iter.starts_line() && 
+  while(!end_sentence_iter.starts_line() &&
         (*end_sentence_iter==' ' || *end_sentence_iter=='\t' || end_sentence_iter.ends_line()) &&
         end_sentence_iter.backward_char()) {}
   if(!end_sentence_iter.ends_line() && *end_sentence_iter!=' ' && *end_sentence_iter!='\t')
     end_sentence_iter.forward_char();
-  
+
   if(iter==end_line_iter)
     return end_sentence_iter;
   else
diff --git a/src/source_base.h b/src/source_base.h
index 3307f4b6..ae3085dd 100644
--- a/src/source_base.h
+++ b/src/source_base.h
@@ -11,55 +11,55 @@ namespace Source {
     BaseView(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language);
     ~BaseView() override;
     boost::filesystem::path file_path;
-    
+
     Glib::RefPtr<Gsv::Language> language;
-    
+
     bool load(bool not_undoable_action=false);
     /// Set new text more optimally and without unnecessary scrolling
     void replace_text(const std::string &new_text);
     virtual void rename(const boost::filesystem::path &path);
     virtual bool save() = 0;
-    
+
     Glib::RefPtr<Gio::FileMonitor> monitor;
     sigc::connection monitor_changed_connection;
     sigc::connection delayed_monitor_changed_connection;
-    
+
     virtual void configure() = 0;
     virtual void hide_tooltips() = 0;
     virtual void hide_dialogs() = 0;
-    
+
     std::function<void(BaseView* view, bool center, bool show_tooltips)> scroll_to_cursor_delayed=[](BaseView* view, bool center, bool show_tooltips) {};
-    
+
     /// Safely returns iter given line and an offset using either byte index or character offset. Defaults to using byte index.
     virtual Gtk::TextIter get_iter_at_line_pos(int line, int pos);
     /// Safely returns iter given line and character offset
     Gtk::TextIter get_iter_at_line_offset(int line, int offset);
     /// Safely returns iter given line and byte index
     Gtk::TextIter get_iter_at_line_index(int line, int index);
-    
+
     Gtk::TextIter get_iter_at_line_end(int line_nr);
     Gtk::TextIter get_iter_for_dialog();
-    
+
     /// Safely places cursor at line using get_iter_at_line_pos.
     void place_cursor_at_line_pos(int line, int pos);
     /// Safely places cursor at line offset
     void place_cursor_at_line_offset(int line, int offset);
     /// Safely places cursor at line index
     void place_cursor_at_line_index(int line, int index);
-    
+
   protected:
     std::time_t last_write_time;
     void monitor_file();
     void check_last_write_time(std::time_t last_write_time_=static_cast<std::time_t>(-1));
-    
+
     /// Move iter to line start. Depending on iter position, before or after indentation.
-    /// Works with wrapped lines. 
+    /// Works with wrapped lines.
     Gtk::TextIter get_smart_home_iter(const Gtk::TextIter &iter);
     /// Move iter to line end. Depending on iter position, before or after indentation.
-    /// Works with wrapped lines. 
+    /// Works with wrapped lines.
     /// Note that smart end goes FIRST to end of line to avoid hiding empty chars after expressions.
     Gtk::TextIter get_smart_end_iter(const Gtk::TextIter &iter);
-    
+
     std::string get_line(const Gtk::TextIter &iter);
     std::string get_line(const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark);
     std::string get_line(int line_nr);
@@ -71,7 +71,7 @@ namespace Source {
     Gtk::TextIter get_tabs_end_iter(const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark);
     Gtk::TextIter get_tabs_end_iter(int line_nr);
     Gtk::TextIter get_tabs_end_iter();
-    
+
     std::set<int> diagnostic_offsets;
     void place_cursor_at_next_diagnostic();
   public:
@@ -84,7 +84,7 @@ namespace Source {
     std::string status_state;
     std::function<void(BaseView *view)> update_status_branch;
     std::string status_branch;
-    
+
     bool disable_spellcheck=false;
   };
 }
diff --git a/src/source_clang.cc b/src/source_clang.cc
index b3e14388..06585cdf 100644
--- a/src/source_clang.cc
+++ b/src/source_clang.cc
@@ -19,7 +19,7 @@ clangmm::Index Source::ClangViewParse::clang_index(0, 0);
 Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language):
     BaseView(file_path, language), Source::View(file_path, language) {
   Usages::Clang::erase_cache(file_path);
-  
+
   auto tag_table=get_buffer()->get_tag_table();
   for (auto &item : clang_types()) {
     auto tag=tag_table->lookup(item.second);
@@ -28,16 +28,16 @@ Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path,
     else
       syntax_tags.emplace(item.first, tag);
   }
-  
+
   if(get_buffer()->size()==0 && (language->get_id()=="chdr" || language->get_id()=="cpphdr")) {
     disable_spellcheck=true;
     get_buffer()->insert_at_cursor("#pragma once\n");
     disable_spellcheck=false;
     Info::get().print("Added \"#pragma once\" to empty C/C++ header file");
   }
-  
+
   parse_initialize();
-  
+
   get_buffer()->signal_changed().connect([this]() {
     soft_reparse(true);
   });
@@ -46,7 +46,7 @@ Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path,
 bool Source::ClangViewParse::save() {
   if(!Source::View::save())
      return false;
-  
+
   if(language->get_id()=="chdr" || language->get_id()=="cpphdr") {
     for(auto &view: views) {
       if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
@@ -60,7 +60,7 @@ bool Source::ClangViewParse::save() {
 
 void Source::ClangViewParse::configure() {
   Source::View::configure();
-  
+
   auto scheme = get_source_buffer()->get_style_scheme();
   auto tag_table=get_buffer()->get_tag_table();
   for (auto &item : clang_types()) {
@@ -90,7 +90,7 @@ void Source::ClangViewParse::parse_initialize() {
     parse_thread.join();
   parse_state=ParseState::PROCESSING;
   parse_process_state=ParseProcessState::STARTING;
-  
+
   auto buffer=get_buffer()->get_text();
   //Remove includes for first parse for initial syntax highlighting
   std::size_t pos=0;
@@ -107,7 +107,7 @@ void Source::ClangViewParse::parse_initialize() {
   auto &buffer_raw=const_cast<std::string&>(buffer.raw());
   if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr"))
     clangmm::remove_include_guard(buffer_raw);
-  
+
   auto build=Project::Build::create(file_path);
   if(build->get_project_path().empty())
     Info::get().print(file_path.filename().string()+": could not find a supported build system");
@@ -120,7 +120,7 @@ void Source::ClangViewParse::parse_initialize() {
   for(auto &token: *clang_tokens)
     clang_tokens_offsets.emplace_back(token.get_source_range().get_offsets());
   update_syntax();
-  
+
   status_state="parsing...";
   if(update_status_state)
     update_status_state(this);
@@ -244,10 +244,10 @@ void Source::ClangViewParse::update_syntax() {
       buffer->apply_tag(syntax_tag_it->second, begin_iter, end_iter);
     }
   };
-  
+
   for(auto &pair: syntax_tags)
     buffer->remove_tag(pair.second, buffer->begin(), buffer->end());
-  
+
   for(size_t c=0;c<clang_tokens->size();++c) {
     auto &token=(*clang_tokens)[c];
     auto &token_offsets=clang_tokens_offsets[c];
@@ -277,7 +277,7 @@ void Source::ClangViewParse::update_diagnostics() {
   size_t num_errors=0;
   size_t num_fix_its=0;
   for(auto &diagnostic: clang_diagnostics) {
-    if(diagnostic.path==file_path.string()) {      
+    if(diagnostic.path==file_path.string()) {
       int line=diagnostic.offsets.first.line-1;
       if(line<0 || line>=get_buffer()->get_line_count())
         line=get_buffer()->get_line_count()-1;
@@ -290,7 +290,7 @@ void Source::ClangViewParse::update_diagnostics() {
           start.backward_char();
       }
       diagnostic_offsets.emplace(start.get_offset());
-      
+
       line=diagnostic.offsets.second.line-1;
       if(line<0 || line>=get_buffer()->get_line_count())
         line=get_buffer()->get_line_count()-1;
@@ -298,7 +298,7 @@ void Source::ClangViewParse::update_diagnostics() {
       index=diagnostic.offsets.second.index-1;
       if(index>=0 && index<end.get_line_index())
         end=get_buffer()->get_iter_at_line_index(line, index);
-      
+
       bool error=false;
       std::string severity_tag_name;
       if(diagnostic.severity<=clangmm::Diagnostic::Severity::Warning) {
@@ -310,7 +310,7 @@ void Source::ClangViewParse::update_diagnostics() {
         num_errors++;
         error=true;
       }
-      
+
       std::string fix_its_string;
       unsigned fix_its_count=0;
       for(auto &fix_it: diagnostic.fix_its) {
@@ -320,24 +320,24 @@ void Source::ClangViewParse::update_diagnostics() {
         offsets.first.index=clang_offsets.first.index-1;
         offsets.second.line=clang_offsets.second.line-1;
         offsets.second.index=clang_offsets.second.index-1;
-        
+
         fix_its.emplace_back(fix_it.source, offsets);
-        
+
         if(fix_its_string.size()>0)
           fix_its_string+='\n';
         fix_its_string+=fix_its.back().string(get_buffer());
         fix_its_count++;
         num_fix_its++;
       }
-      
+
       if(fix_its_count==1)
         fix_its_string.insert(0, "Fix-it:\n");
       else if(fix_its_count>1)
         fix_its_string.insert(0, "Fix-its:\n");
-      
+
       if(!fix_its_string.empty())
         diagnostic.spelling+="\n\n"+fix_its_string;
-      
+
       add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
     }
   }
@@ -357,7 +357,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
     get_iter_location(iter, iter_rectangle);
     if(iter.ends_line() && location_x>iter_rectangle.get_x())
       return;
-    
+
     auto line=static_cast<unsigned>(iter.get_line());
     auto index=static_cast<unsigned>(iter.get_line_index());
     type_tooltips.clear();
@@ -377,13 +377,13 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
               auto brief_comment=token.get_cursor().get_brief_comments();
               if(brief_comment!="")
                 tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+brief_comment);
-  
+
 #ifdef JUCI_ENABLE_DEBUG
               if(Debug::LLDB::get().is_stopped()) {
                 auto referenced=token.get_cursor().get_referenced();
                 auto location=referenced.get_source_location();
                 Glib::ustring value_type="Value";
-                
+
                 auto iter=start;
                 while((*iter>='a' && *iter<='z') || (*iter>='A' && *iter<='Z') || (*iter>='0' && *iter<='9') || *iter=='_' || *iter=='.') {
                   start=iter;
@@ -399,7 +399,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
                   }
                 }
                 auto spelling=get_buffer()->get_text(start, end).raw();
-                
+
                 Glib::ustring debug_value;
                 auto cursor_kind=referenced.get_kind();
                 if(cursor_kind!=clangmm::Cursor::Kind::FunctionDecl && cursor_kind!=clangmm::Cursor::Kind::CXXMethod &&
@@ -426,10 +426,10 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
                 }
               }
 #endif
-              
+
               return tooltip_buffer;
             };
-            
+
             type_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start), get_buffer()->create_mark(end));
             type_tooltips.show();
             return;
@@ -448,29 +448,29 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa
       return;
     autocomplete.run();
   };
-  
+
   autocomplete.is_processing=[this] {
     return parse_state==ParseState::PROCESSING;
   };
-  
+
   autocomplete.reparse=[this] {
     selected_completion_string=nullptr;
     code_complete_results=nullptr;
     soft_reparse(true);
   };
-  
+
   autocomplete.cancel_reparse=[this] {
     delayed_reparse_connection.disconnect();
   };
-  
+
   autocomplete.get_parse_lock=[this]() {
     return std::make_unique<std::lock_guard<std::mutex>>(parse_mutex);
   };
-  
+
   autocomplete.stop_parse=[this]() {
     parse_process_state=ParseProcessState::IDLE;
   };
-  
+
   // Activate argument completions
   get_buffer()->signal_changed().connect([this] {
     if(!interactive_completion)
@@ -514,10 +514,10 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa
   autocomplete.is_continue_key=[](guint keyval) {
     if((keyval>='0' && keyval<='9') || (keyval>='a' && keyval<='z') || (keyval>='A' && keyval<='Z') || keyval=='_')
       return true;
-    
+
     return false;
   };
-  
+
   autocomplete.is_restart_key=[this](guint keyval) {
     auto iter=get_buffer()->get_insert()->get_iter();
     iter.backward_chars(2);
@@ -525,15 +525,15 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa
       return true;
     return false;
   };
-  
+
   autocomplete.run_check=[this]() {
     auto iter=get_buffer()->get_insert()->get_iter();
     iter.backward_char();
     if(!is_code_iter(iter))
       return false;
-    
+
     show_arguments=false;
-    
+
     std::string line=" "+get_line_before();
     const static std::regex dot_or_arrow(R"(^.*[a-zA-Z0-9_\)\]\>](\.|->)([a-zA-Z0-9_]*)$)");
     const static std::regex colon_colon(R"(^.*::([a-zA-Z0-9_]*)$)");
@@ -579,29 +579,29 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa
       autocomplete.prefix=get_buffer()->get_text(iter, end_iter);
       return true;
     }
-    
+
     return false;
   };
-  
+
   autocomplete.before_add_rows=[this] {
     status_state="autocomplete...";
     if(update_status_state)
       update_status_state(this);
   };
-  
+
   autocomplete.after_add_rows=[this] {
     status_state="";
     if(update_status_state)
       update_status_state(this);
   };
-  
+
   autocomplete.on_add_rows_error=[this] {
     Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true);
     selected_completion_string=nullptr;
     code_complete_results=nullptr;
     full_reparse();
   };
-  
+
   autocomplete.add_rows=[this](std::string &buffer, int line_number, int column) {
     if(this->language && (this->language->get_id()=="chdr" || this->language->get_id()=="cpphdr"))
       clangmm::remove_include_guard(buffer);
@@ -611,14 +611,14 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa
       parse_state.compare_exchange_strong(expected, ParseState::RESTARTING);
       return;
     }
-    
+
     if(autocomplete.state==Autocomplete::State::STARTING) {
       std::string prefix_copy;
       {
         std::lock_guard<std::mutex> lock(autocomplete.prefix_mutex);
         prefix_copy=autocomplete.prefix;
       }
-      
+
       completion_strings.clear();
       for (unsigned i = 0; i < code_complete_results->size(); ++i) {
         auto result=code_complete_results->get(i);
@@ -684,20 +684,20 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa
       }
     }
   };
-  
+
   autocomplete.on_show = [this] {
     hide_tooltips();
   };
-  
+
   autocomplete.on_hide = [this] {
     selected_completion_string=nullptr;
     code_complete_results=nullptr;
   };
-  
+
   autocomplete.on_changed = [this](unsigned int index, const std::string &text) {
     selected_completion_string=completion_strings[index];
   };
-  
+
   autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
     std::string row;
     auto pos=text.find("  →  ");
@@ -767,7 +767,7 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa
           }
         }
       }
-      
+
       if(start_pos!=std::string::npos && end_pos!=std::string::npos) {
         int start_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+start_pos;
         int end_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+end_pos;
@@ -785,7 +785,7 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa
       }
     }
   };
-  
+
   autocomplete.get_tooltip = [this](unsigned int index) {
     return clangmm::to_string(clang_getCompletionBriefComment(completion_strings[index]));
   };
@@ -820,7 +820,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
     BaseView(file_path, language), Source::ClangViewParse(file_path, language) {
   similar_identifiers_tag=get_buffer()->create_tag();
   similar_identifiers_tag->property_weight()=Pango::WEIGHT_ULTRAHEAVY;
-  
+
   get_buffer()->signal_changed().connect([this]() {
     if(last_tagged_identifier) {
       for(auto &mark: similar_identifiers_marks) {
@@ -832,7 +832,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
       last_tagged_identifier=Identifier();
     }
   });
-  
+
   get_token_spelling=[this]() {
     if(!parsed) {
       Info::get().print("Buffer is parsing");
@@ -848,7 +848,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
     }
     return identifier.spelling;
   };
-  
+
   rename_similar_tokens=[this](const std::string &text) {
     if(!parsed) {
       Info::get().print("Buffer is parsing");
@@ -857,7 +857,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
     auto identifier=get_identifier();
     if(identifier) {
       wait_parsing();
-      
+
       std::vector<clangmm::TranslationUnit*> translation_units;
       translation_units.emplace_back(clang_tu.get());
       for(auto &view: views) {
@@ -866,10 +866,10 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
             translation_units.emplace_back(clang_view->clang_tu.get());
         }
       }
-      
+
       auto build=Project::Build::create(this->file_path);
       auto usages=Usages::Clang::get_usages(build->get_project_path(), build->get_default_path(), build->get_debug_path(), identifier.spelling, identifier.cursor, translation_units);
-      
+
       std::vector<Source::View*> renamed_views;
       std::vector<Usages::Clang::Usages*> usages_renamed;
       for(auto &usage: usages) {
@@ -932,7 +932,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
             Terminal::get().print("Error: could not write to file "+usage.path.string()+'\n', true);
         }
       }
-      
+
       if(!usages_renamed.empty()) {
         Terminal::get().print("Renamed ");
         Terminal::get().print(identifier.spelling, true);
@@ -961,12 +961,12 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
           ++line_c;
         }
       }
-      
+
       for(auto &view: renamed_views)
         view->soft_reparse_needed=false;
     }
   };
-  
+
   get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark){
     if(mark->get_name()=="insert") {
       delayed_tag_similar_symbols_connection.disconnect();
@@ -977,7 +977,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
       }, 100);
     }
   });
-    
+
   auto declaration_location=[this]() {
     auto identifier=get_identifier();
     if(identifier) {
@@ -998,7 +998,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
           std::string sm_str;
         };
         ClientData client_data{this->file_path, std::string(), get_buffer()->get_insert()->get_iter().get_line(), sm[1].str()};
-        
+
         // Attempt to find the 100% correct include file first
         clang_getInclusions(clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) {
           auto client_data=static_cast<ClientData*>(client_data_);
@@ -1009,10 +1009,10 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
               client_data->found_include=clangmm::to_string(clang_getFileName(included_file));
           }
         }, &client_data);
-        
+
         if(!client_data.found_include.empty())
           return Offset(0, 0, client_data.found_include);
-        
+
         // Find a matching include file if no include was found previously
         clang_getInclusions(clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) {
           auto client_data=static_cast<ClientData*>(client_data_);
@@ -1031,14 +1031,14 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
             }
           }
         }, &client_data);
-        
+
         if(!client_data.found_include.empty())
           return Offset(0, 0, client_data.found_include);
       }
     }
     return Offset();
   };
-  
+
   get_declaration_location=[this, declaration_location](){
     if(!parsed) {
       if(selected_completion_string) {
@@ -1049,14 +1049,14 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
           if(CompletionDialog::get())
             CompletionDialog::get()->hide();
           auto offset=Offset(source_location_offset.line-1, source_location_offset.index-1, source_location.get_path());
-          
+
           // Workaround for bug in ArchLinux's clang_getFileName()
           // TODO: remove the workaround when this is fixed
           auto include_path=filesystem::get_normal_path(offset.file_path);
           boost::system::error_code ec;
           if(!boost::filesystem::exists(include_path, ec))
             offset.file_path="/usr/include"/include_path;
-          
+
           return offset;
         }
         else {
@@ -1064,24 +1064,24 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
           return Offset();
         }
       }
-      
+
       Info::get().print("Buffer is parsing");
       return Offset();
     }
     auto offset=declaration_location();
     if(!offset)
       Info::get().print("No declaration found");
-    
+
     // Workaround for bug in ArchLinux's clang_getFileName()
     // TODO: remove the workaround when this is fixed
     auto include_path=filesystem::get_normal_path(offset.file_path);
     boost::system::error_code ec;
     if(!boost::filesystem::exists(include_path, ec))
       offset.file_path="/usr/include"/include_path;
-    
+
     return offset;
   };
-  
+
   get_type_declaration_location=[this](){
     if(!parsed) {
       Info::get().print("Buffer is parsing");
@@ -1096,14 +1096,14 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
         if(!path.empty()) {
           auto source_location_offset=source_location.get_offset();
           auto offset=Offset(source_location_offset.line-1, source_location_offset.index-1, path);
-          
+
           // Workaround for bug in ArchLinux's clang_getFileName()
           // TODO: remove the workaround when this is fixed
           auto include_path=filesystem::get_normal_path(offset.file_path);
           boost::system::error_code ec;
           if(!boost::filesystem::exists(include_path, ec))
             offset.file_path="/usr/include"/include_path;
-          
+
           return offset;
         }
       }
@@ -1111,12 +1111,12 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
     Info::get().print("No type declaration found");
     return Offset();
   };
-  
+
   auto implementation_locations=[this](const Identifier &identifier) {
     std::vector<Offset> offsets;
     if(identifier) {
       wait_parsing();
-      
+
       //First, look for a definition cursor that is equal
       auto identifier_usr=identifier.cursor.get_usr();
       for(auto &view: views) {
@@ -1146,7 +1146,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
       }
       if(!offsets.empty())
         return offsets;
-      
+
       //If no implementation was found, try using clang_getCursorDefinition
       auto definition=identifier.cursor.get_definition();
       if(definition) {
@@ -1159,7 +1159,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
         offsets.emplace_back(offset);
         return offsets;
       }
-      
+
       //If no implementation was found, use declaration if it is a function template
       auto canonical=identifier.cursor.get_canonical();
       auto cursor=clang_tu->get_cursor(canonical.get_source_location());
@@ -1173,7 +1173,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
         offsets.emplace_back(offset);
         return offsets;
       }
-      
+
       //If no implementation was found, try using Ctags
       auto name=identifier.cursor.get_spelling();
       auto parent=identifier.cursor.get_semantic_parent();
@@ -1196,7 +1196,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
     }
     return offsets;
   };
-  
+
   get_implementation_locations=[this, implementation_locations](){
     if(!parsed) {
       if(selected_completion_string) {
@@ -1209,7 +1209,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
           }
           if(CompletionDialog::get())
             CompletionDialog::get()->hide();
-          
+
           // Workaround for bug in ArchLinux's clang_getFileName()
           // TODO: remove the workaround when this is fixed
           for(auto &offset: offsets) {
@@ -1218,7 +1218,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
             if(!boost::filesystem::exists(include_path, ec))
               offset.file_path="/usr/include"/include_path;
           }
-          
+
           return offsets;
         }
         else {
@@ -1226,14 +1226,14 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
           return std::vector<Offset>();
         }
       }
-      
+
       Info::get().print("Buffer is parsing");
       return std::vector<Offset>();
     }
     auto offsets=implementation_locations(get_identifier());
     if(offsets.empty())
       Info::get().print("No implementation found");
-    
+
     // Workaround for bug in ArchLinux's clang_getFileName()
     // TODO: remove the workaround when this is fixed
     for(auto &offset: offsets) {
@@ -1242,18 +1242,18 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
       if(!boost::filesystem::exists(include_path, ec))
         offset.file_path="/usr/include"/include_path;
     }
-    
+
     return offsets;
   };
-  
+
   get_declaration_or_implementation_locations=[this, declaration_location, implementation_locations]() {
     if(!parsed) {
       Info::get().print("Buffer is parsing");
       return std::vector<Offset>();
     }
-    
+
     std::vector<Offset> offsets;
-    
+
     bool is_implementation=false;
     auto iter=get_buffer()->get_insert()->get_iter();
     auto line=static_cast<unsigned>(iter.get_line());
@@ -1286,10 +1286,10 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
           offsets.emplace_back(offset);
       }
     }
-    
+
     if(offsets.empty())
       Info::get().print("No declaration or implementation found");
-    
+
     // Workaround for bug in ArchLinux's clang_getFileName()
     // TODO: remove the workaround when this is fixed
     for(auto &offset: offsets) {
@@ -1298,10 +1298,10 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
       if(!boost::filesystem::exists(include_path, ec))
         offset.file_path="/usr/include"/include_path;
     }
-    
+
     return offsets;
   };
-  
+
   get_usages=[this]() {
     std::vector<std::pair<Offset, std::string> > usages;
     if(!parsed) {
@@ -1311,7 +1311,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
     auto identifier=get_identifier();
     if(identifier) {
       wait_parsing();
-      
+
       auto embolden_token=[](std::string &line, unsigned token_start_pos, unsigned token_end_pos) {
         //markup token as bold
         size_t pos=0;
@@ -1329,14 +1329,14 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
         }
         line.insert(token_end_pos, "</b>");
         line.insert(token_start_pos, "<b>");
-        
+
         size_t start_pos=0;
         while(start_pos<line.size() && (line[start_pos]==' ' || line[start_pos]=='\t'))
           ++start_pos;
         if(start_pos>0)
           line.erase(0, start_pos);
       };
-      
+
       std::vector<clangmm::TranslationUnit*> translation_units;
       translation_units.emplace_back(clang_tu.get());
       for(auto &view: views) {
@@ -1345,7 +1345,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
             translation_units.emplace_back(clang_view->clang_tu.get());
         }
       }
-      
+
       auto build=Project::Build::create(this->file_path);
       auto usages_clang=Usages::Clang::get_usages(build->get_project_path(), build->get_default_path(), build->get_debug_path(), {identifier.spelling}, {identifier.cursor}, translation_units);
       for(auto &usage: usages_clang) {
@@ -1356,12 +1356,12 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
         }
       }
     }
-    
+
     if(usages.empty())
       Info::get().print("No symbol found at current cursor location");
     return usages;
   };
-  
+
   get_method=[this] {
     if(!parsed) {
       Info::get().print("Buffer is parsing");
@@ -1392,7 +1392,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
                 if(kind==clangmm::Cursor::Kind::FunctionDecl || kind==clangmm::Cursor::Kind::CXXMethod) {
                   auto start_offset=cursor.get_source_range().get_start().get_offset();
                   auto end_offset=token_offsets.first;
-                  
+
                   // To accurately get result type with needed namespace and class/struct names:
                   int angle_brackets=0;
                   for(size_t c=0;c<clang_tokens->size();++c) {
@@ -1402,7 +1402,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
                        (token_offsets.first.line>start_offset.line && token_offsets.second.line<end_offset.line) ||
                        (token_offsets.first.line!=start_offset.line && token_offsets.second.line==end_offset.line && token_offsets.second.index<=end_offset.index) ||
                        (token_offsets.first.line==start_offset.line && token_offsets.second.line==end_offset.line &&
-                        token_offsets.first.index>=start_offset.index && token_offsets.second.index<=end_offset.index)) {                     
+                        token_offsets.first.index>=start_offset.index && token_offsets.second.index<=end_offset.index)) {
                       auto token_spelling=token.get_spelling();
                       if(token.get_kind()==clangmm::Token::Kind::Identifier) {
                         if(c==0 || (*clang_tokens)[c-1].get_spelling()!="::") {
@@ -1433,10 +1433,10 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
                       }
                     }
                   }
-                  
+
                   if(!result.empty() && result.back()!='*' && result.back()!='&' && result.back()!=' ')
                     result+=' ';
-                  
+
                   if(clang_CXXMethod_isConst(cursor.cx_cursor))
                     specifier+=" const";
 
@@ -1446,7 +1446,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
                     specifier+=" noexcept";
 #endif
                 }
-                
+
                 auto name=cursor.get_spelling();
                 auto parent=cursor.get_semantic_parent();
                 std::vector<std::string> semantic_parents;
@@ -1458,7 +1458,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
                   }
                   parent=parent.get_semantic_parent();
                 }
-                
+
                 std::string arguments;
                 for(auto &argument_cursor: cursor.get_arguments()) {
                   auto argument_type=argument_cursor.get_type().get_spelling();
@@ -1485,7 +1485,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
     Info::get().print("No method found at current cursor location");
     return std::string();
   };
-  
+
   get_methods=[this](){
     std::vector<std::pair<Offset, std::string> > methods;
     if(!parsed) {
@@ -1504,7 +1504,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
           if(offset==last_offset)
             continue;
           last_offset=offset;
-          
+
           std::string method;
           if(kind!=clangmm::Cursor::Kind::Constructor && kind!=clangmm::Cursor::Kind::Destructor) {
             method+=cursor.get_type().get_result().get_spelling();
@@ -1514,14 +1514,14 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
             method+=" ";
           }
           method+=cursor.get_display_name();
-          
+
           std::string prefix;
           auto parent=cursor.get_semantic_parent();
           while(parent && parent.get_kind()!=clangmm::Cursor::Kind::TranslationUnit) {
             prefix.insert(0, parent.get_display_name()+(prefix.empty()?"":"::"));
             parent=parent.get_semantic_parent();
           }
-          
+
           method=Glib::Markup::escape_text(method);
           //Add bold method token
           size_t token_end_pos=method.find('(');
@@ -1532,25 +1532,25 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
             --token_start_pos;
           method.insert(token_end_pos, "</b>");
           method.insert(token_start_pos, "<b>");
-          
+
           if(!prefix.empty())
             prefix+=':';
           prefix+=std::to_string(offset.line)+": ";
           prefix=Glib::Markup::escape_text(prefix);
-          
+
           methods.emplace_back(Offset(offset.line-1, offset.index-1), prefix+method);
         }
       }
     }
     if(methods.empty())
       Info::get().print("No methods found in current buffer");
-    
+
     return methods;
   };
-  
+
   get_token_data=[this]() -> std::vector<std::string> {
     clangmm::Cursor cursor;
-    
+
     std::vector<std::string> data;
     if(!parsed) {
       if(selected_completion_string) {
@@ -1565,16 +1565,16 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
         return data;
       }
     }
-    
+
     if(!cursor) {
       auto identifier=get_identifier();
       if(identifier)
         cursor=identifier.cursor.get_canonical();
     }
-    
+
     if(cursor) {
       data.emplace_back("clang");
-      
+
       std::string symbol;
       clangmm::Cursor last_cursor;
       auto it=data.end();
@@ -1590,21 +1590,21 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
         last_cursor=cursor;
         cursor=cursor.get_semantic_parent();
       } while(cursor.get_kind()!=clangmm::Cursor::Kind::TranslationUnit);
-      
+
       if(last_cursor.get_kind()!=clangmm::Cursor::Kind::Namespace)
         data.emplace(++data.begin(), "");
-      
+
       auto url=Documentation::CppReference::get_url(symbol);
       if(!url.empty())
         return {url};
     }
-    
+
     if(data.empty())
       Info::get().print("No symbol found at current cursor location");
-    
+
     return data;
   };
-  
+
   goto_next_diagnostic=[this]() {
     if(!parsed) {
       Info::get().print("Buffer is parsing");
@@ -1612,7 +1612,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
     }
     place_cursor_at_next_diagnostic();
   };
-  
+
   get_fix_its=[this]() {
     if(!parsed) {
       Info::get().print("Buffer is parsing");
@@ -1622,7 +1622,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
       Info::get().print("No fix-its found in current buffer");
     return fix_its;
   };
-  
+
   get_documentation_template=[this]() {
     if(!parsed) {
       Info::get().print("Buffer is parsing");
@@ -1643,22 +1643,22 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
       auto first_line=tabs+"/**\n";
       auto second_line=tabs+" * \n";
       auto iter_offset=first_line.size()+second_line.size()-1;
-      
+
       std::string param_lines;
       for(int c=0;c<clang_Cursor_getNumArguments(cursor.cx_cursor);++c)
         param_lines+=tabs+" * @param "+clangmm::Cursor(clang_Cursor_getArgument(cursor.cx_cursor, c)).get_spelling()+'\n';
-      
+
       std::string return_line;
       auto return_spelling=cursor.get_type().get_result().get_spelling();
       if(!return_spelling.empty() && return_spelling!="void")
         return_line+=tabs+" * @return\n";
-      
+
       auto documentation=first_line+second_line;
       if(!param_lines.empty() || !return_line.empty())
         documentation+=tabs+" *\n";
-      
+
       documentation+=param_lines+return_line+tabs+" */\n";
-      
+
       return std::tuple<Source::Offset, std::string, size_t>(source_offset, documentation, iter_offset);
     }
     else {
@@ -1733,7 +1733,7 @@ void Source::ClangViewRefactor::tag_similar_identifiers(const Identifier &identi
         auto start_iter=get_buffer()->get_iter_at_line_index(offset.first.line-1, offset.first.index-1);
         auto end_iter=get_buffer()->get_iter_at_line_index(offset.second.line-1, offset.second.index-1);
         get_buffer()->apply_tag(similar_identifiers_tag, start_iter, end_iter);
-        similar_identifiers_marks.emplace_back(get_buffer()->create_mark(start_iter), get_buffer()->create_mark(end_iter)); 
+        similar_identifiers_marks.emplace_back(get_buffer()->create_mark(start_iter), get_buffer()->create_mark(end_iter));
       }
       last_tagged_identifier=identifier;
     }
@@ -1756,7 +1756,7 @@ Source::ClangView::ClangView(const boost::filesystem::path &file_path, const Gli
     get_source_buffer()->set_highlight_syntax(true);
     get_source_buffer()->set_language(language);
   }
-  
+
   do_delete_object.connect([this]() {
     if(delete_thread.joinable())
       delete_thread.join();
@@ -1802,7 +1802,7 @@ void Source::ClangView::full_reparse() {
 
 void Source::ClangView::async_delete() {
   delayed_show_arguments_connection.disconnect();
-  
+
   views.erase(this);
   std::set<boost::filesystem::path> project_paths_in_use;
   for(auto &view: views) {
@@ -1814,23 +1814,23 @@ void Source::ClangView::async_delete() {
   }
   Usages::Clang::erase_unused_caches(project_paths_in_use);
   Usages::Clang::cache_in_progress();
-  
+
   if(!get_buffer()->get_modified()) {
     if(full_reparse_needed)
       full_reparse();
     else if(soft_reparse_needed)
       soft_reparse();
   }
-  
+
   auto before_parse_time=std::time(nullptr);
   delete_thread=std::thread([this, before_parse_time, project_paths_in_use=std::move(project_paths_in_use)] {
     while(!parsed)
       std::this_thread::sleep_for(std::chrono::milliseconds(10));
-    
+
     delayed_reparse_connection.disconnect();
     parse_state=ParseState::STOP;
     dispatcher.disconnect();
-    
+
     if(get_buffer()->get_modified()) {
       std::ifstream stream(file_path.string(), std::ios::binary);
       if(stream) {
@@ -1844,12 +1844,12 @@ void Source::ClangView::async_delete() {
       else
         clang_tokens=nullptr;
     }
-    
+
     if(clang_tokens) {
       auto build=Project::Build::create(file_path);
       Usages::Clang::cache(build->get_project_path(), build->get_default_path(), file_path, before_parse_time, project_paths_in_use, clang_tu.get(), clang_tokens.get());
     }
-    
+
     if(full_reparse_thread.joinable())
       full_reparse_thread.join();
     if(parse_thread.joinable())
diff --git a/src/source_clang.h b/src/source_clang.h
index 3aca95e7..8f1d26b4 100644
--- a/src/source_clang.h
+++ b/src/source_clang.h
@@ -14,13 +14,13 @@ namespace Source {
   protected:
     enum class ParseState {PROCESSING, RESTARTING, STOP};
     enum class ParseProcessState {IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING};
-    
+
   public:
     ClangViewParse(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language);
-    
+
     bool save() override;
     void configure() override;
-    
+
     void soft_reparse(bool delayed=false) override;
   protected:
     Dispatcher dispatcher;
@@ -29,30 +29,30 @@ namespace Source {
     std::unique_ptr<clangmm::Tokens> clang_tokens;
     std::vector<std::pair<clangmm::Offset, clangmm::Offset>> clang_tokens_offsets;
     sigc::connection delayed_reparse_connection;
-    
+
     void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
-    
+
     std::vector<FixIt> fix_its;
-    
+
     std::thread parse_thread;
     std::mutex parse_mutex;
     std::atomic<ParseState> parse_state;
     std::atomic<ParseProcessState> parse_process_state;
-    
+
     CXCompletionString selected_completion_string=nullptr;
   private:
     Glib::ustring parse_thread_buffer;
-    
+
     static const std::unordered_map<int, std::string> &clang_types();
     void update_syntax();
     std::map<int, Glib::RefPtr<Gtk::TextTag>> syntax_tags;
 
     void update_diagnostics();
     std::vector<clangmm::Diagnostic> clang_diagnostics;
-    
+
     static clangmm::Index clang_index;
   };
-    
+
   class ClangViewAutocomplete : public virtual ClangViewParse {
   public:
     ClangViewAutocomplete(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language);
@@ -73,7 +73,7 @@ namespace Source {
       Identifier(std::string spelling_, const clangmm::Cursor &cursor)
           : kind(cursor.get_kind()), spelling(std::move(spelling_)), usr_extended(cursor.get_usr_extended()), cursor(cursor) {}
       Identifier() : kind(static_cast<clangmm::Cursor::Kind>(0)) {}
-      
+
       operator bool() const { return static_cast<int>(kind)!=0; }
       bool operator==(const Identifier &rhs) const { return spelling==rhs.spelling && usr_extended==rhs.usr_extended; }
       bool operator!=(const Identifier &rhs) const { return !(*this==rhs); }
@@ -88,20 +88,20 @@ namespace Source {
   private:
     Identifier get_identifier();
     void wait_parsing();
-    
+
     std::list<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > similar_identifiers_marks;
     void tag_similar_identifiers(const Identifier &identifier);
     Glib::RefPtr<Gtk::TextTag> similar_identifiers_tag;
     Identifier last_tagged_identifier;
   };
-  
+
   class ClangView : public ClangViewAutocomplete, public ClangViewRefactor {
   public:
     ClangView(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language);
-    
+
     void full_reparse() override;
     void async_delete();
-    
+
   private:
     Glib::Dispatcher do_delete_object;
     std::thread delete_thread;
diff --git a/src/source_diff.cc b/src/source_diff.cc
index df4df206..9d0ea809 100644
--- a/src/source_diff.cc
+++ b/src/source_diff.cc
@@ -39,7 +39,7 @@ Source::DiffView::DiffView(const boost::filesystem::path &file_path, const Glib:
   canonical_file_path=boost::filesystem::canonical(file_path, ec);
   if(ec)
     canonical_file_path=file_path;
-  
+
   renderer->tag_added=get_buffer()->create_tag("git_added");
   renderer->tag_modified=get_buffer()->create_tag("git_modified");
   renderer->tag_removed=get_buffer()->create_tag("git_removed");
@@ -56,7 +56,7 @@ Source::DiffView::~DiffView() {
     monitor_changed_connection.disconnect();
     delayed_buffer_changed_connection.disconnect();
     delayed_monitor_changed_connection.disconnect();
-    
+
     parse_stop=true;
     if(parse_thread.joinable())
       parse_thread.join();
@@ -75,30 +75,30 @@ void Source::DiffView::configure() {
     monitor_changed_connection.disconnect();
     delayed_buffer_changed_connection.disconnect();
     delayed_monitor_changed_connection.disconnect();
-    
+
     parse_stop=true;
     if(parse_thread.joinable())
       parse_thread.join();
     repository=nullptr;
     diff=nullptr;
-    
+
     return;
   }
   else
     return;
-  
+
   try {
     repository=Git::get_repository(this->file_path.parent_path());
   }
   catch(const std::exception &) {
     return;
   }
-  
+
   get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->insert(renderer.get(), -40);
   parse_state=ParseState::STARTING;
   parse_stop=false;
   monitor_changed=false;
-  
+
   buffer_insert_connection=get_buffer()->signal_insert().connect([this](const Gtk::TextBuffer::iterator &iter ,const Glib::ustring &text, int) {
     //Do not perform git diff if no newline is added and line is already marked as added
     if(!iter.starts_line() && iter.has_tag(renderer->tag_added)) {
@@ -127,12 +127,12 @@ void Source::DiffView::configure() {
       return false;
     }, 250);
   }, false);
-  
+
   buffer_erase_connection=get_buffer()->signal_erase().connect([this](const Gtk::TextBuffer::iterator &start_iter, const Gtk::TextBuffer::iterator &end_iter) {
     //Do not perform git diff if start_iter and end_iter is at the same line in addition to the line is tagged added
     if(start_iter.get_line()==end_iter.get_line() && start_iter.has_tag(renderer->tag_added))
       return;
-    
+
     parse_state=ParseState::IDLE;
     delayed_buffer_changed_connection.disconnect();
     delayed_buffer_changed_connection=Glib::signal_timeout().connect([this]() {
@@ -140,7 +140,7 @@ void Source::DiffView::configure() {
       return false;
     }, 250);
   }, false);
-  
+
   monitor_changed_connection=repository->monitor->signal_changed().connect([this](const Glib::RefPtr<Gio::File> &file,
                                                                                   const Glib::RefPtr<Gio::File>&,
                                                                                   Gio::FileMonitorEvent monitor_event) {
@@ -155,7 +155,7 @@ void Source::DiffView::configure() {
       }, 500);
     }
   });
-  
+
   parse_thread=std::thread([this]() {
     std::string status_branch;
     try {
@@ -170,7 +170,7 @@ void Source::DiffView::configure() {
       if(update_status_branch)
         update_status_branch(this);
     });
-    
+
     try {
       while(true) {
         while(!parse_stop && parse_state!=ParseState::STARTING && parse_state!=ParseState::PROCESSING)
@@ -255,7 +255,7 @@ void Source::DiffView::configure() {
 
 void Source::DiffView::rename(const boost::filesystem::path &path) {
   Source::BaseView::rename(path);
-  
+
   std::lock_guard<std::mutex> lock(canonical_file_path_mutex);
   boost::system::error_code ec;
   canonical_file_path=boost::filesystem::canonical(path, ec);
@@ -326,7 +326,7 @@ void Source::DiffView::update_lines() {
   get_buffer()->remove_tag(renderer->tag_removed, get_buffer()->begin(), get_buffer()->end());
   get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
   get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
-  
+
   for(auto &added: lines.added) {
     auto start_iter=get_buffer()->get_iter_at_line(added.first);
     auto end_iter=get_iter_at_line_end(added.second-1);
@@ -360,6 +360,6 @@ void Source::DiffView::update_lines() {
     }
     get_buffer()->apply_tag(renderer->tag_removed, removed_start, removed_end);
   }
-  
+
   renderer->queue_draw();
 }
diff --git a/src/source_diff.h b/src/source_diff.h
index c1465634..4b53e2a5 100644
--- a/src/source_diff.h
+++ b/src/source_diff.h
@@ -12,17 +12,17 @@
 namespace Source {
   class DiffView : virtual public Source::BaseView {
     enum class ParseState {IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING};
-    
+
     class Renderer : public Gsv::GutterRenderer {
     public:
       Renderer();
-      
+
       Glib::RefPtr<Gtk::TextTag> tag_added;
       Glib::RefPtr<Gtk::TextTag> tag_modified;
       Glib::RefPtr<Gtk::TextTag> tag_removed;
       Glib::RefPtr<Gtk::TextTag> tag_removed_below;
       Glib::RefPtr<Gtk::TextTag> tag_removed_above;
-      
+
     protected:
       void draw_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area,
                       const Gdk::Rectangle &cell_area, Gtk::TextIter &start, Gtk::TextIter &end,
@@ -31,26 +31,26 @@ namespace Source {
   public:
     DiffView(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language);
     ~DiffView() override;
-    
+
     void configure() override;
-    
+
     void rename(const boost::filesystem::path &path) override;
-    
+
     void git_goto_next_diff();
     std::string git_get_diff_details();
-    
+
     /// Use canonical path to follow symbolic links
     boost::filesystem::path canonical_file_path;
   private:
     std::mutex canonical_file_path_mutex;
-    
+
     std::unique_ptr<Renderer> renderer;
     Dispatcher dispatcher;
-    
+
     std::shared_ptr<Git::Repository> repository;
     std::unique_ptr<Git::Repository::Diff> diff;
     std::unique_ptr<Git::Repository::Diff> get_diff();
-    
+
     std::thread parse_thread;
     std::atomic<ParseState> parse_state;
     std::mutex parse_mutex;
@@ -62,7 +62,7 @@ namespace Source {
     sigc::connection delayed_buffer_changed_connection;
     sigc::connection delayed_monitor_changed_connection;
     std::atomic<bool> monitor_changed;
-    
+
     Git::Repository::Diff::Lines lines;
     void update_lines();
   };
diff --git a/src/source_language_protocol.cc b/src/source_language_protocol.cc
index f6f5de98..5075c0c6 100644
--- a/src/source_language_protocol.cc
+++ b/src/source_language_protocol.cc
@@ -31,9 +31,9 @@ std::shared_ptr<LanguageProtocol::Client> LanguageProtocol::Client::get(const bo
     root_uri=build->get_project_path().string();
   else
     root_uri=file_path.parent_path().string();
-  
+
   auto cache_id=root_uri+'|'+language_id;
-  
+
   static std::unordered_map<std::string, std::weak_ptr<Client>> cache;
   static std::mutex mutex;
   std::lock_guard<std::mutex> lock(mutex);
@@ -59,11 +59,11 @@ LanguageProtocol::Client::~Client() {
     result_processed.set_value();
   });
   result_processed.get_future().get();
-  
+
   std::unique_lock<std::mutex> lock(timeout_threads_mutex);
   for(auto &thread: timeout_threads)
     thread.join();
-  
+
   int exit_status=-1;
   for(size_t c=0;c<20;++c) {
     std::this_thread::sleep_for(std::chrono::milliseconds(500));
@@ -81,12 +81,12 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::Lang
     std::unique_lock<std::mutex> lock(views_mutex);
     views.emplace(view);
   }
-  
+
   std::lock_guard<std::mutex> lock(initialize_mutex);
-  
+
   if(initialized)
     return capabilities;
-  
+
   std::promise<void> result_processed;
   write_request(nullptr, "initialize", "\"processId\":"+std::to_string(process->get_id())+R"(,"rootUri":"file://)"+root_uri+R"(","capabilities":{"workspace":{"didChangeConfiguration":{"dynamicRegistration":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"dynamicRegistration":true},"executeCommand":{"dynamicRegistration":true}},"textDocument":{"synchronization":{"dynamicRegistration":true,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":true,"completionItem":{"snippetSupport":true}},"hover":{"dynamicRegistration":true},"signatureHelp":{"dynamicRegistration":true},"definition":{"dynamicRegistration":true},"references":{"dynamicRegistration":true},"documentHighlight":{"dynamicRegistration":true},"documentSymbol":{"dynamicRegistration":true},"codeAction":{"dynamicRegistration":true},"codeLens":{"dynamicRegistration":true},"formatting":{"dynamicRegistration":true},"rangeFormatting":{"dynamicRegistration":true},"onTypeFormatting":{"dynamicRegistration":true},"rename":{"dynamicRegistration":true},"documentLink":{"dynamicRegistration":true}}},"initializationOptions":{"omitInitBuild":true},"trace":"off")", [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
     if(!error) {
@@ -103,7 +103,7 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::Lang
         capabilities.document_range_formatting=capabilities_pt->second.get<bool>("documentRangeFormattingProvider", false);
         capabilities.rename=capabilities_pt->second.get<bool>("renameProvider", false);
       }
-      
+
       write_notification("initialized", "");
       if(language_id=="rust")
         write_notification("workspace/didChangeConfiguration", R"("settings":{"rust":{"sysroot":null,"target":null,"rustflags":null,"clear_env_rust_log":true,"build_lib":null,"build_bin":null,"cfg_test":false,"unstable_features":false,"wait_to_build":500,"show_warnings":true,"goto_def_racer_fallback":false,"use_crate_blacklist":true,"build_on_save":false,"workspace_mode":true,"analyze_package":null,"features":[],"all_features":false,"no_default_features":false}})");
@@ -111,7 +111,7 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::Lang
     result_processed.set_value();
   });
   result_processed.get_future().get();
-  
+
   initialized=true;
   return capabilities;
 }
@@ -153,7 +153,7 @@ void LanguageProtocol::Client::parse_server_message() {
       }
     }
   }
-  
+
   if(header_read) {
     server_message_stream.seekg(0, std::ios::end);
     size_t read_size=server_message_stream.tellg();
@@ -167,16 +167,16 @@ void LanguageProtocol::Client::parse_server_message() {
           server_message_stream.put(' ');
         }
       }
-      
+
       server_message_stream.seekg(server_message_content_pos, std::ios::beg);
       boost::property_tree::ptree pt;
       boost::property_tree::read_json(server_message_stream, pt);
-      
+
       if(output_messages_and_errors) {
         std::cout << "language server: ";
         boost::property_tree::write_json(std::cout, pt);
       }
-      
+
       auto message_id=pt.get<size_t>("id", 0);
       auto result_it=pt.find("result");
       auto error_it=pt.find("error");
@@ -220,11 +220,11 @@ void LanguageProtocol::Client::parse_server_message() {
           }
         }
       }
-      
+
       server_message_stream=std::stringstream();
       header_read=false;
       server_message_size=static_cast<size_t>(-1);
-      
+
       tmp.seekg(0, std::ios::end);
       if(tmp.tellg()>0) {
         tmp.seekg(0, std::ios::beg);
@@ -239,7 +239,7 @@ void LanguageProtocol::Client::write_request(Source::LanguageProtocolView *view,
   std::unique_lock<std::mutex> lock(read_write_mutex);
   if(function) {
     handlers.emplace(message_id, std::make_pair(view, std::move(function)));
-    
+
     auto message_id=this->message_id;
     std::unique_lock<std::mutex> lock(timeout_threads_mutex);
     timeout_threads.emplace_back([this, message_id] {
@@ -322,14 +322,14 @@ Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path
   configure();
   get_source_buffer()->set_language(language);
   get_source_buffer()->set_highlight_syntax(true);
-  
+
   similar_symbol_tag=get_buffer()->create_tag();
   similar_symbol_tag->property_weight()=Pango::WEIGHT_ULTRAHEAVY;
-  
+
   status_state="initializing...";
   if(update_status_state)
     update_status_state(this);
-  
+
   if(language_id=="javascript") {
     boost::filesystem::path project_path;
     auto build=Project::Build::create(file_path);
@@ -344,24 +344,24 @@ Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path
       }
     }
   }
-  
+
   initialize_thread=std::thread([this] {
     auto capabilities=client->initialize(this);
-    
+
     if(!flow_coverage_executable.empty())
       add_flow_coverage_tooltips(true);
-    
+
     dispatcher.post([this, capabilities] {
       this->capabilities=capabilities;
-      
+
       std::string text=get_buffer()->get_text();
       escape_text(text);
       client->write_notification("textDocument/didOpen", R"("textDocument":{"uri":")"+uri+R"(","languageId":")"+language_id+R"(","version":)"+std::to_string(document_version++)+R"(,"text":")"+text+"\"}");
-      
+
       setup_autocomplete();
       setup_navigation_and_refactoring();
       Menu::get().toggle_menu_items();
-      
+
       if(status_state=="initializing...") {
         status_state="";
         if(update_status_state)
@@ -369,11 +369,11 @@ Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path
       }
     });
   });
-  
+
   get_buffer()->signal_changed().connect([this] {
     get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(), get_buffer()->end());
   });
-  
+
   get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
     if(mark->get_name() == "insert") {
       delayed_tag_similar_symbols_connection.disconnect();
@@ -419,24 +419,24 @@ Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path
 Source::LanguageProtocolView::~LanguageProtocolView() {
   if(initialize_thread.joinable())
     initialize_thread.join();
-  
+
   autocomplete.state=Autocomplete::State::IDLE;
   if(autocomplete.thread.joinable())
     autocomplete.thread.join();
-  
+
   client->write_notification("textDocument/didClose", R"("textDocument":{"uri":")"+uri+"\"}");
   client->close(this);
-  
+
   client=nullptr;
 }
 
 bool Source::LanguageProtocolView::save() {
   if(!Source::View::save())
     return false;
-  
+
   if(!flow_coverage_executable.empty())
     add_flow_coverage_tooltips(false);
-  
+
   return true;
 }
 
@@ -447,7 +447,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
         bool has_style_file=false;
         auto style_file_search_path=this->file_path.parent_path();
         auto style_file='.'+language_id+"-format";
-        
+
         while(true) {
           if(boost::filesystem::exists(style_file_search_path/style_file)) {
             has_style_file=true;
@@ -457,11 +457,11 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
             break;
           style_file_search_path=style_file_search_path.parent_path();
         }
-        
+
         if(!has_style_file && !continue_without_style_file)
           return;
       }
-      
+
       class Replace {
       public:
         Offset start, end;
@@ -469,7 +469,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
       };
       std::vector<Replace> replaces;
       std::promise<void> result_processed;
-      
+
       std::string method;
       std::string params;
       std::string options("\"tabSize\":"+std::to_string(tab_size)+",\"insertSpaces\":"+(tab_char==' '?"true":"false"));
@@ -483,7 +483,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
         method="textDocument/formatting";
         params=R"("textDocument":{"uri":")"+uri+R"("},"options":{)"+options+"}";
       }
-      
+
       client->write_request(this, method, params, [&replaces, &result_processed](const boost::property_tree::ptree &result, bool error) {
         if(!error) {
           for(auto it=result.begin();it!=result.end();++it) {
@@ -506,7 +506,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
         result_processed.set_value();
       });
       result_processed.get_future().get();
-      
+
       auto end_iter=get_buffer()->end();
       if(replaces.size()==1 &&
          replaces[0].start.line==0 && replaces[0].start.index==0 &&
@@ -529,7 +529,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
       }
     };
   }
-  
+
   if(capabilities.definition) {
     get_declaration_location=[this]() {
       auto offset=get_declaration(get_buffer()->get_insert()->get_iter());
@@ -545,7 +545,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
       return offsets;
     };
   }
-  
+
   if(capabilities.references) {
     get_usages=[this] {
       auto iter=get_buffer()->get_insert()->get_iter();
@@ -579,12 +579,12 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
         result_processed.set_value();
       });
       result_processed.get_future().get();
-      
+
       auto embolden_token=[](std::string &line_, unsigned token_start_pos, unsigned token_end_pos) {
         Glib::ustring line=line_;
         if(token_start_pos>=line.size() || token_end_pos>=line.size())
           return;
-    
+
         //markup token as bold
         size_t pos=0;
         while((pos=line.find('&', pos))!=Glib::ustring::npos) {
@@ -601,16 +601,16 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
         }
         line.insert(token_end_pos, "</b>");
         line.insert(token_start_pos, "<b>");
-        
+
         size_t start_pos=0;
         while(start_pos<line.size() && (line[start_pos]==' ' || line[start_pos]=='\t'))
           ++start_pos;
         if(start_pos>0)
           line.erase(0, start_pos);
-        
+
         line_=line.raw();
       };
-      
+
       std::map<boost::filesystem::path, std::vector<std::string>> file_lines;
       auto c=static_cast<size_t>(-1);
       for(auto &usage: usages) {
@@ -651,36 +651,36 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
               it=pair.first;
             }
           }
-          
+
           if(usage.first.line<it->second.size()) {
             usage.second=it->second[usage.first.line];
             embolden_token(usage.second, usage.first.index, end_offsets[c].index);
           }
         }
       }
-      
+
       if(usages.empty())
         Info::get().print("No symbol found at current cursor location");
-      
+
       return usages;
     };
   }
-  
+
   get_token_spelling=[this]() -> std::string {
     auto start=get_buffer()->get_insert()->get_iter();
     auto end=start;
     auto previous=start;
     while(previous.backward_char() && ((*previous>='A' && *previous<='Z') || (*previous>='a' && *previous<='z') || (*previous>='0' && *previous<='9') || *previous=='_') && start.backward_char()) {}
     while(((*end>='A' && *end<='Z') || (*end>='a' && *end<='z') || (*end>='0' && *end<='9') || *end=='_') && end.forward_char()) {}
-    
+
     if(start==end) {
       Info::get().print("No valid symbol found at current cursor location");
       return "";
     }
-    
+
     return get_buffer()->get_text(start, end);
   };
-  
+
   if(capabilities.rename) {
     rename_similar_tokens=[this](const std::string &text) {
       class Usages {
@@ -689,11 +689,11 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
         std::unique_ptr<std::string> new_text;
         std::vector<std::pair<Offset, Offset>> offsets;
       };
-      
+
       auto previous_text=get_token_spelling();
       if(previous_text.empty())
         return;
-      
+
       auto iter=get_buffer()->get_insert()->get_iter();
       std::vector<Usages> usages;
       std::promise<void> result_processed;
@@ -770,7 +770,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
         result_processed.set_value();
       });
       result_processed.get_future().get();
-      
+
       std::vector<Usages*> usages_renamed;
       for(auto &usage: usages) {
         auto view_it=views.end();
@@ -843,7 +843,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
             Terminal::get().print("Error: could not write to file "+usage.path.string()+'\n', true);
         }
       }
-      
+
       if(!usages_renamed.empty()) {
         Terminal::get().print("Renamed ");
         Terminal::get().print(previous_text, true);
@@ -853,7 +853,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
       }
     };
   }
-  
+
   goto_next_diagnostic=[this]() {
     place_cursor_at_next_diagnostic();
   };
@@ -899,14 +899,14 @@ void Source::LanguageProtocolView::update_diagnostics(std::vector<LanguageProtoc
       if(diagnostic.uri==uri) {
         auto start=get_iter_at_line_pos(diagnostic.offsets.first.line, diagnostic.offsets.first.index);
         auto end=get_iter_at_line_pos(diagnostic.offsets.second.line, diagnostic.offsets.second.index);
-        
+
         if(start==end) {
           if(!end.is_end())
             end.forward_char();
           else
             start.forward_char();
         }
-        
+
         bool error=false;
         std::string severity_tag_name;
         if(diagnostic.severity>=2) {
@@ -918,14 +918,14 @@ void Source::LanguageProtocolView::update_diagnostics(std::vector<LanguageProtoc
           num_errors++;
           error=true;
         }
-        
+
         add_diagnostic_tooltip(start, end, diagnostic.spelling, error);
       }
     }
-    
+
     for(auto &mark: flow_coverage_marks)
       add_diagnostic_tooltip(mark.first->get_iter(), mark.second->get_iter(), flow_coverage_message, false);
-    
+
     status_diagnostics=std::make_tuple(num_warnings+num_flow_coverage_warnings, num_errors, num_fix_its);
     if(update_status_diagnostics)
       update_status_diagnostics(this);
@@ -939,7 +939,7 @@ Gtk::TextIter Source::LanguageProtocolView::get_iter_at_line_pos(int line, int p
 void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rectangle) {
   if(!capabilities.hover)
     return;
-  
+
   Gtk::TextIter iter;
   int location_x, location_y;
   window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x, location_y);
@@ -949,9 +949,9 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect
   get_iter_location(iter, iter_rectangle);
   if(iter.ends_line() && location_x > iter_rectangle.get_x())
     return;
-  
+
   auto offset=iter.get_offset();
-  
+
   static int request_count=0;
   request_count++;
   auto current_request=request_count;
@@ -989,18 +989,18 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect
           auto create_tooltip_buffer=[this, offset, content]() {
             auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
             tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), *content);
-            
+
 #ifdef JUCI_ENABLE_DEBUG
             if(language_id=="rust" && capabilities.definition) {
               if(Debug::LLDB::get().is_stopped()) {
                 Glib::ustring value_type="Value";
-                
+
                 auto start=get_buffer()->get_iter_at_offset(offset);
                 auto end=start;
                 auto previous=start;
                 while(previous.backward_char() && ((*previous>='A' && *previous<='Z') || (*previous>='a' && *previous<='z') || (*previous>='0' && *previous<='9') || *previous=='_') && start.backward_char()) {}
                 while(((*end>='A' && *end<='Z') || (*end>='a' && *end<='z') || (*end>='0' && *end<='9') || *end=='_') && end.forward_char()) {}
-                
+
                 auto offset=get_declaration(start);
                 Glib::ustring debug_value=Debug::LLDB::get().get_value(get_buffer()->get_text(start, end), offset.file_path, offset.line+1, offset.index+1);
                 if(debug_value.empty()) {
@@ -1022,10 +1022,10 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect
               }
             }
 #endif
-            
+
             return tooltip_buffer;
           };
-          
+
           auto start=get_buffer()->get_iter_at_offset(offset);
           auto end=start;
           auto previous=start;
@@ -1042,14 +1042,14 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect
 void Source::LanguageProtocolView::tag_similar_symbols() {
   if(!capabilities.document_highlight && !capabilities.references)
     return;
-  
+
   auto iter=get_buffer()->get_insert()->get_iter();
   std::string method;
   if(capabilities.document_highlight)
     method="textDocument/documentHighlight";
   else
     method="textDocument/references";
-  
+
   static int request_count=0;
   request_count++;
   auto current_request=request_count;
@@ -1113,25 +1113,25 @@ Source::Offset Source::LanguageProtocolView::get_declaration(const Gtk::TextIter
 void Source::LanguageProtocolView::setup_autocomplete() {
   if(!capabilities.completion)
     return;
-  
+
   non_interactive_completion=[this] {
     if(CompletionDialog::get() && CompletionDialog::get()->is_visible())
       return;
     autocomplete.run();
   };
-  
+
   autocomplete.reparse=[this] {
     autocomplete_comment.clear();
     autocomplete_insert.clear();
   };
-  
+
   autocomplete.is_continue_key=[](guint keyval) {
     if((keyval>='0' && keyval<='9') || (keyval>='a' && keyval<='z') || (keyval>='A' && keyval<='Z') || keyval=='_')
       return true;
-    
+
     return false;
   };
-  
+
   autocomplete.is_restart_key=[this](guint keyval) {
     auto iter=get_buffer()->get_insert()->get_iter();
     iter.backward_chars(2);
@@ -1139,13 +1139,13 @@ void Source::LanguageProtocolView::setup_autocomplete() {
       return true;
     return false;
   };
-  
+
   autocomplete.run_check=[this]() {
     auto iter=get_buffer()->get_insert()->get_iter();
     iter.backward_char();
     if(!is_code_iter(iter))
       return false;
-    
+
     std::string line=" "+get_line_before();
     const static std::regex dot_or_arrow(R"(^.*[a-zA-Z0-9_\)\]\>"'](\.)([a-zA-Z0-9_]*)$)");
     const static std::regex colon_colon(R"(^.*::([a-zA-Z0-9_]*)$)");
@@ -1185,27 +1185,27 @@ void Source::LanguageProtocolView::setup_autocomplete() {
       autocomplete.prefix=get_buffer()->get_text(iter, end_iter);
       return true;
     }
-    
+
     return false;
   };
-  
+
   autocomplete.before_add_rows=[this] {
     status_state="autocomplete...";
     if(update_status_state)
       update_status_state(this);
   };
-  
+
   autocomplete.after_add_rows=[this] {
     status_state="";
     if(update_status_state)
       update_status_state(this);
   };
-  
+
   autocomplete.on_add_rows_error=[this] {
     autocomplete_comment.clear();
     autocomplete_insert.clear();
   };
-  
+
   autocomplete.add_rows=[this](std::string &buffer, int line_number, int column) {
     if(autocomplete.state==Autocomplete::State::STARTING) {
       autocomplete_comment.clear();
@@ -1269,7 +1269,7 @@ void Source::LanguageProtocolView::setup_autocomplete() {
       result_processed.get_future().get();
     }
   };
-  
+
   signal_key_press_event().connect([this](GdkEventKey *event) {
     if((event->keyval==GDK_KEY_Tab || event->keyval==GDK_KEY_ISO_Left_Tab) && (event->state&GDK_SHIFT_MASK)==0) {
       if(!autocomplete_marks.empty()) {
@@ -1289,7 +1289,7 @@ void Source::LanguageProtocolView::setup_autocomplete() {
     }
     return false;
   }, false);
-  
+
   get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator &iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
     if(mark->get_name() == "insert") {
       if(!autocomplete_keep_marks) {
@@ -1301,7 +1301,7 @@ void Source::LanguageProtocolView::setup_autocomplete() {
       }
     }
   });
-  
+
   autocomplete.on_show = [this] {
     for(auto &pair: autocomplete_marks) {
       get_buffer()->delete_mark(pair.first);
@@ -1310,17 +1310,17 @@ void Source::LanguageProtocolView::setup_autocomplete() {
     autocomplete_marks.clear();
     hide_tooltips();
   };
-  
+
   autocomplete.on_hide = [this] {
     autocomplete_comment.clear();
     autocomplete_insert.clear();
   };
-  
+
   autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
     get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
     if(hide_window) {
       Glib::ustring insert=autocomplete_insert[index];
-      
+
       // Do not insert function/template parameters if they already exist
       auto iter=get_buffer()->get_insert()->get_iter();
       if(*iter=='(' || *iter=='<') {
@@ -1329,7 +1329,7 @@ void Source::LanguageProtocolView::setup_autocomplete() {
           insert=insert.substr(0, bracket_pos);
         }
       }
-      
+
       // Find and add position marks that one can move to using tab-key
       size_t pos1=0;
       std::vector<std::pair<size_t, size_t>> mark_offsets;
@@ -1371,7 +1371,7 @@ void Source::LanguageProtocolView::setup_autocomplete() {
     else
       get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), text);
   };
-  
+
   autocomplete.get_tooltip = [this](unsigned int index) {
     return autocomplete_comment[index];
   };
@@ -1389,7 +1389,7 @@ void Source::LanguageProtocolView::add_flow_coverage_tooltips(bool called_in_thr
       get_buffer()->delete_mark(mark.second);
     }
     flow_coverage_marks.clear();
-    
+
     if(exit_status==0) {
       boost::property_tree::ptree pt;
       try {
@@ -1400,10 +1400,10 @@ void Source::LanguageProtocolView::add_flow_coverage_tooltips(bool called_in_thr
           auto start=get_iter_at_line_offset(start_pt.get<int>("line")-1, start_pt.get<int>("column")-1);
           auto end_pt=it->second.get_child("end");
           auto end=get_iter_at_line_offset(end_pt.get<int>("line")-1, end_pt.get<int>("column"));
-          
+
           add_diagnostic_tooltip(start, end, flow_coverage_message, false);
           ++num_flow_coverage_warnings;
-          
+
           flow_coverage_marks.emplace_back(get_buffer()->create_mark(start), get_buffer()->create_mark(end));
         }
       }
diff --git a/src/source_language_protocol.h b/src/source_language_protocol.h
index 0c647bc2..02878a7b 100644
--- a/src/source_language_protocol.h
+++ b/src/source_language_protocol.h
@@ -48,7 +48,7 @@ namespace LanguageProtocol {
 
     std::unordered_set<Source::LanguageProtocolView *> views;
     std::mutex views_mutex;
-    
+
     std::mutex initialize_mutex;
 
     std::unique_ptr<TinyProcessLib::Process> process;
@@ -73,7 +73,7 @@ namespace LanguageProtocol {
     bool initialized = false;
     Capabilities initialize(Source::LanguageProtocolView *view);
     void close(Source::LanguageProtocolView *view);
-    
+
     void parse_server_message();
     void write_request(Source::LanguageProtocolView *view, const std::string &method, const std::string &params, std::function<void(const boost::property_tree::ptree &, bool)> &&function = nullptr);
     void write_notification(const std::string &method, const std::string &params);
@@ -87,11 +87,11 @@ namespace Source {
     LanguageProtocolView(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language, std::string language_id_);
     ~LanguageProtocolView() override;
     std::string uri;
-    
+
     bool save() override;
 
     void update_diagnostics(std::vector<LanguageProtocol::Diagnostic> &&diagnostics);
-    
+
     Gtk::TextIter get_iter_at_line_pos(int line, int pos) override;
 
   protected:
@@ -100,22 +100,22 @@ namespace Source {
   private:
     std::string language_id;
     LanguageProtocol::Capabilities capabilities;
-    
+
     std::shared_ptr<LanguageProtocol::Client> client;
 
     size_t document_version = 1;
 
     std::thread initialize_thread;
     Dispatcher dispatcher;
-    
+
     void setup_navigation_and_refactoring();
 
     void escape_text(std::string &text);
     void unescape_text(std::string &text);
-    
+
     Glib::RefPtr<Gtk::TextTag> similar_symbol_tag;
     void tag_similar_symbols();
-    
+
     Offset get_declaration(const Gtk::TextIter &iter);
 
     Autocomplete autocomplete;
@@ -124,7 +124,7 @@ namespace Source {
     std::vector<std::string> autocomplete_insert;
     std::list<std::pair<Glib::RefPtr<Gtk::TextBuffer::Mark>, Glib::RefPtr<Gtk::TextBuffer::Mark>>> autocomplete_marks;
     bool autocomplete_keep_marks = false;
-    
+
     boost::filesystem::path flow_coverage_executable;
     std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark>>> flow_coverage_marks;
     const std::string flow_coverage_message="Not covered by Flow";
diff --git a/src/source_spellcheck.cc b/src/source_spellcheck.cc
index fea72487..99cf942e 100644
--- a/src/source_spellcheck.cc
+++ b/src/source_spellcheck.cc
@@ -12,32 +12,32 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
   spellcheck_checker=nullptr;
   spellcheck_error_tag=get_buffer()->create_tag("spellcheck_error");
   spellcheck_error_tag->property_underline()=Pango::Underline::UNDERLINE_ERROR;
-  
+
   signal_key_press_event().connect([](GdkEventKey *event) {
     if(SelectionDialog::get() && SelectionDialog::get()->is_visible()) {
       if(SelectionDialog::get()->on_key_press(event))
         return true;
     }
-    
+
     return false;
   }, false);
-  
+
   //The following signal is added in case SpellCheckView is not subclassed
   signal_key_press_event().connect([this](GdkEventKey *event) {
     last_keyval=event->keyval;
     return false;
   });
-  
+
   get_buffer()->signal_changed().connect([this]() {
     if(spellcheck_checker==nullptr)
       return;
-    
+
     delayed_spellcheck_suggestions_connection.disconnect();
-    
+
     auto iter=get_buffer()->get_insert()->get_iter();
     if(!is_word_iter(iter) && !iter.starts_line())
       iter.backward_char();
-    
+
     if(disable_spellcheck) {
       if(is_word_iter(iter)) {
         auto word=get_word(iter);
@@ -45,7 +45,7 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
       }
       return;
     }
-    
+
     if(!is_code_iter(iter)) {
       if(last_keyval==GDK_KEY_Return || last_keyval==GDK_KEY_KP_Enter) {
         auto previous_line_iter=iter;
@@ -91,7 +91,7 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
         while(iter!=get_buffer()->end()) {
           if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
             iter=get_buffer()->end();
-          
+
           spell_check=!spell_check;
           if(!spell_check)
             begin_no_spellcheck_iter=iter;
@@ -100,7 +100,7 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
         }
         return false;
       }
-      
+
       bool spell_check=get_source_buffer()->iter_has_context_class(iter, "string") || get_source_buffer()->iter_has_context_class(iter, "comment");
       if(!spell_check)
         begin_no_spellcheck_iter=iter;
@@ -111,7 +111,7 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
           iter1=get_buffer()->end();
         if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
           iter2=get_buffer()->end();
-        
+
         if(iter2<iter1)
           iter=iter2;
         else
@@ -125,15 +125,15 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
       return false;
     }, 1000);
   });
-  
+
   // In case of for instance text paste or undo/redo
   get_buffer()->signal_insert().connect([this](const Gtk::TextIter &start_iter, const Glib::ustring &inserted_string, int) {
     if(spellcheck_checker==nullptr)
       return;
-    
+
     if(!disable_spellcheck)
       return;
-    
+
     auto iter=start_iter;
     if(!is_word_iter(iter) && !iter.starts_line())
       iter.backward_char();
@@ -142,11 +142,11 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
       get_buffer()->remove_tag(spellcheck_error_tag, word.first, word.second);
     }
   }, false);
-  
+
   get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iter, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark) {
     if(spellcheck_checker==nullptr)
       return;
-    
+
     if(mark->get_name()=="insert") {
       if(SelectionDialog::get())
         SelectionDialog::get()->hide();
@@ -180,24 +180,24 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
       }, 500);
     }
   });
-  
+
   get_buffer()->signal_mark_set().connect([](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark) {
     if(mark->get_name()=="insert") {
       if(SelectionDialog::get())
         SelectionDialog::get()->hide();
     }
   });
-  
+
   signal_focus_out_event().connect([this](GdkEventFocus* event) {
     delayed_spellcheck_suggestions_connection.disconnect();
     return false;
   });
-  
+
   signal_leave_notify_event().connect([this](GdkEventCrossing*) {
     delayed_spellcheck_suggestions_connection.disconnect();
     return false;
   });
-  
+
   signal_tag_added_connection=get_buffer()->get_tag_table()->signal_tag_added().connect([this](const Glib::RefPtr<Gtk::TextTag> &tag) {
     if(tag->property_name()=="gtksourceview:context-classes:comment")
       comment_tag=tag;
@@ -219,10 +219,10 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
 Source::SpellCheckView::~SpellCheckView() {
   delayed_spellcheck_suggestions_connection.disconnect();
   delayed_spellcheck_error_clear.disconnect();
-  
+
   if(spellcheck_checker!=nullptr)
     delete_aspell_speller(spellcheck_checker);
-  
+
   signal_tag_added_connection.disconnect();
   signal_tag_removed_connection.disconnect();
 }
@@ -257,7 +257,7 @@ void Source::SpellCheckView::spellcheck(const Gtk::TextIter& start, const Gtk::T
     if(is_word_iter(iter)) {
       auto word=get_word(iter);
       spellcheck_word(word.first, word.second);
-      iter=word.second; 
+      iter=word.second;
     }
     iter.forward_char();
   }
@@ -273,7 +273,7 @@ void Source::SpellCheckView::spellcheck() {
     while(iter!=get_buffer()->end()) {
       if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check"))
         iter=get_buffer()->end();
-      
+
       spell_check=!spell_check;
       if(spell_check)
         begin_spellcheck_iter=iter;
@@ -292,7 +292,7 @@ void Source::SpellCheckView::spellcheck() {
         iter1=get_buffer()->end();
       if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment"))
         iter2=get_buffer()->end();
-      
+
       if(iter2<iter1)
         iter=iter2;
       else
@@ -447,7 +447,7 @@ bool Source::SpellCheckView::is_word_iter(const Gtk::TextIter& iter) {
 std::pair<Gtk::TextIter, Gtk::TextIter> Source::SpellCheckView::get_word(Gtk::TextIter iter) {
   auto start=iter;
   auto end=iter;
-  
+
   while(is_word_iter(iter)) {
     start=iter;
     if(!iter.backward_char())
@@ -457,7 +457,7 @@ std::pair<Gtk::TextIter, Gtk::TextIter> Source::SpellCheckView::get_word(Gtk::Te
     if(!end.forward_char())
       break;
   }
-  
+
   return {start, end};
 }
 
@@ -470,7 +470,7 @@ void Source::SpellCheckView::spellcheck_word(Gtk::TextIter start, Gtk::TextIter
       end.backward_char();
     }
   }
-  
+
   auto word=get_buffer()->get_text(start, end);
   if(word.size()>0) {
     auto correct = aspell_speller_check(spellcheck_checker, word.data(), word.bytes());
@@ -483,16 +483,16 @@ void Source::SpellCheckView::spellcheck_word(Gtk::TextIter start, Gtk::TextIter
 
 std::vector<std::string> Source::SpellCheckView::get_spellcheck_suggestions(const Gtk::TextIter& start, const Gtk::TextIter& end) {
   auto word_with_error=get_buffer()->get_text(start, end);
-  
+
   const AspellWordList *suggestions = aspell_speller_suggest(spellcheck_checker, word_with_error.data(), word_with_error.bytes());
   AspellStringEnumeration *elements = aspell_word_list_elements(suggestions);
-  
+
   std::vector<std::string> words;
   const char *word;
   while ((word = aspell_string_enumeration_next(elements))!= nullptr) {
     words.emplace_back(word);
   }
   delete_aspell_string_enumeration(elements);
-  
+
   return words;
 }
diff --git a/src/source_spellcheck.h b/src/source_spellcheck.h
index eb8e9493..a9b491dd 100644
--- a/src/source_spellcheck.h
+++ b/src/source_spellcheck.h
@@ -7,28 +7,28 @@ namespace Source {
   public:
     SpellCheckView(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language);
     ~SpellCheckView() override;
-    
+
     void configure() override;
     void hide_dialogs() override;
-    
+
     void spellcheck();
     void remove_spellcheck_errors();
     void goto_next_spellcheck_error();
-    
+
   protected:
     bool is_code_iter(const Gtk::TextIter &iter);
     bool spellcheck_all=false;
     guint last_keyval=0;
-    
+
     Glib::RefPtr<Gtk::TextTag> comment_tag;
     Glib::RefPtr<Gtk::TextTag> string_tag;
     Glib::RefPtr<Gtk::TextTag> no_spell_check_tag;
   private:
     Glib::RefPtr<Gtk::TextTag> spellcheck_error_tag;
-    
+
     sigc::connection signal_tag_added_connection;
     sigc::connection signal_tag_removed_connection;
-    
+
     static AspellConfig* spellcheck_config;
     AspellCanHaveError *spellcheck_possible_err;
     AspellSpeller *spellcheck_checker;
@@ -38,7 +38,7 @@ namespace Source {
     std::vector<std::string> get_spellcheck_suggestions(const Gtk::TextIter& start, const Gtk::TextIter& end);
     sigc::connection delayed_spellcheck_suggestions_connection;
     sigc::connection delayed_spellcheck_error_clear;
-    
+
     void spellcheck(const Gtk::TextIter& start, const Gtk::TextIter& end);
   };
 }
diff --git a/src/terminal.cc b/src/terminal.cc
index 3d885fb4..d018e9bf 100644
--- a/src/terminal.cc
+++ b/src/terminal.cc
@@ -10,18 +10,18 @@
 
 Terminal::Terminal() {
   set_editable(false);
-  
+
   bold_tag=get_buffer()->create_tag();
   bold_tag->property_weight()=Pango::WEIGHT_ULTRAHEAVY;
-  
+
   link_tag=get_buffer()->create_tag();
   link_tag->property_underline()=Pango::Underline::UNDERLINE_SINGLE;
-  
+
   link_mouse_cursor=Gdk::Cursor::create(Gdk::CursorType::HAND1);
   default_mouse_cursor=Gdk::Cursor::create(Gdk::CursorType::XTERM);
 }
 
-int Terminal::process(const std::string &command, const boost::filesystem::path &path, bool use_pipes) {  
+int Terminal::process(const std::string &command, const boost::filesystem::path &path, bool use_pipes) {
   std::unique_ptr<TinyProcessLib::Process> process;
   if(use_pipes)
     process=std::make_unique<TinyProcessLib::Process>(command, path.string(), [this](const char* bytes, size_t n) {
@@ -31,12 +31,12 @@ int Terminal::process(const std::string &command, const boost::filesystem::path
     });
   else
     process=std::make_unique<TinyProcessLib::Process>(command, path.string());
-    
+
   if(process->get_id()<=0) {
     async_print("Error: failed to run command: " + command + "\n", true);
     return -1;
   }
-  
+
   return process->get_exit_status();
 }
 
@@ -56,12 +56,12 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c
     else
       async_print(std::string(bytes, n), true);
   }, true);
-  
+
   if(process.get_id()<=0) {
     async_print("Error: failed to run command: " + command + "\n", true);
     return -1;
   }
-  
+
   char buffer[131072];
   for(;;) {
     stdin_stream.readsome(buffer, 131072);
@@ -73,7 +73,7 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c
     }
   }
   process.close_stdin();
-  
+
   return process.get_exit_status();
 }
 
@@ -100,9 +100,9 @@ void Terminal::async_process(const std::string &command, const boost::filesystem
       processes.emplace_back(process);
       processes_lock.unlock();
     }
-      
+
     auto exit_status=process->get_exit_status();
-    
+
     processes_lock.lock();
     for(auto it=processes.begin();it!=processes.end();it++) {
       if((*it)->get_id()==pid) {
@@ -112,7 +112,7 @@ void Terminal::async_process(const std::string &command, const boost::filesystem
     }
     stdin_buffer.clear();
     processes_lock.unlock();
-      
+
     if(callback)
       callback(exit_status);
   });
@@ -142,7 +142,7 @@ bool Terminal::on_motion_notify_event(GdkEventMotion *event) {
     get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(link_mouse_cursor);
   else
     get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->set_cursor(default_mouse_cursor);
-  
+
   // Workaround for drag-and-drop crash on MacOS
   // TODO 2018: check if this bug has been fixed
 #ifdef __APPLE__
@@ -159,7 +159,7 @@ bool Terminal::on_motion_notify_event(GdkEventMotion *event) {
 #else
   return Gtk::TextView::on_motion_notify_event(event);
 #endif
-  
+
   return Gtk::TextView::on_motion_notify_event(event);
 }
 
@@ -260,14 +260,14 @@ size_t Terminal::print(const std::string &message, bool bold){
 #else
   Glib::ustring umessage=message;
 #endif
-  
+
   Glib::ustring::iterator iter;
   while(!umessage.validate(iter)) {
     auto next_char_iter=iter;
     next_char_iter++;
     umessage.replace(iter, next_char_iter, "?");
   }
-  
+
   auto start_mark=get_buffer()->create_mark(get_buffer()->get_iter_at_line(get_buffer()->end().get_line()));
   if(bold)
     get_buffer()->insert_with_tag(get_buffer()->end(), umessage, bold_tag);
@@ -276,15 +276,15 @@ size_t Terminal::print(const std::string &message, bool bold){
   auto start_iter=start_mark->get_iter();
   get_buffer()->delete_mark(start_mark);
   auto end_iter=get_buffer()->get_insert()->get_iter();
-  
+
   apply_link_tags(start_iter, end_iter);
-  
+
   if(get_buffer()->get_line_count()>Config::get().terminal.history_size) {
     int lines=get_buffer()->get_line_count()-Config::get().terminal.history_size;
     get_buffer()->erase(get_buffer()->begin(), get_buffer()->get_iter_at_line(lines));
     deleted_lines+=static_cast<size_t>(lines);
   }
-  
+
   return static_cast<size_t>(get_buffer()->end().get_line())+deleted_lines;
 }
 
@@ -298,7 +298,7 @@ void Terminal::async_print(size_t line_nr, const std::string &message) {
   dispatcher.post([this, line_nr, message] {
     if(line_nr<deleted_lines)
       return;
-    
+
     Glib::ustring umessage=message;
     Glib::ustring::iterator iter;
     while(!umessage.validate(iter)) {
@@ -306,7 +306,7 @@ void Terminal::async_print(size_t line_nr, const std::string &message) {
       next_char_iter++;
       umessage.replace(iter, next_char_iter, "?");
     }
-    
+
     auto end_line_iter=get_buffer()->get_iter_at_line(static_cast<int>(line_nr-deleted_lines));
     while(!end_line_iter.ends_line() && end_line_iter.forward_char()) {}
     get_buffer()->insert(end_line_iter, umessage);
@@ -315,7 +315,7 @@ void Terminal::async_print(size_t line_nr, const std::string &message) {
 
 void Terminal::configure() {
   link_tag->property_foreground_rgba()=get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_LINK);
-  
+
   if(Config::get().terminal.font.size()>0) {
     override_font(Pango::FontDescription(Config::get().terminal.font));
   }
@@ -352,7 +352,7 @@ bool Terminal::on_button_press_event(GdkEventButton* button_event) {
         boost::filesystem::path path=std::get<2>(link);
         std::string line=std::get<3>(link);
         std::string index=std::get<4>(link);
-        
+
         if(!path.empty() && *path.begin()=="~") { // boost::filesystem does not recognize ~
           boost::filesystem::path corrected_path;
           corrected_path=filesystem::get_home_path();
@@ -364,7 +364,7 @@ bool Terminal::on_button_press_event(GdkEventButton* button_event) {
             path=corrected_path;
           }
         }
-        
+
         if(path.is_relative()) {
           if(Project::current) {
             auto absolute_path=Project::current->build->get_default_path()/path;
diff --git a/src/terminal.h b/src/terminal.h
index 53a4df4f..9ce767df 100644
--- a/src/terminal.h
+++ b/src/terminal.h
@@ -15,19 +15,19 @@ class Terminal : public Gtk::TextView {
     static Terminal singleton;
     return singleton;
   }
-  
+
   int process(const std::string &command, const boost::filesystem::path &path="", bool use_pipes=true);
   int process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path="", std::ostream *stderr_stream=nullptr);
   void async_process(const std::string &command, const boost::filesystem::path &path="", const std::function<void(int exit_status)> &callback=nullptr, bool quiet=false);
   void kill_last_async_process(bool force=false);
   void kill_async_processes(bool force=false);
-  
+
   size_t print(const std::string &message, bool bold=false);
   void async_print(const std::string &message, bool bold=false);
   void async_print(size_t line_nr, const std::string &message);
-  
+
   void configure();
-  
+
   void clear();
 protected:
   bool on_motion_notify_event (GdkEventMotion* motion_event) override;
@@ -40,7 +40,7 @@ class Terminal : public Gtk::TextView {
   Glib::RefPtr<Gdk::Cursor> link_mouse_cursor;
   Glib::RefPtr<Gdk::Cursor> default_mouse_cursor;
   size_t deleted_lines=0;
-  
+
   std::tuple<size_t, size_t, std::string, std::string, std::string> find_link(const std::string &line);
   void apply_link_tags(const Gtk::TextIter &start_iter, const Gtk::TextIter &end_iter);
 
diff --git a/src/tooltips.cc b/src/tooltips.cc
index 841016cb..6f588024 100644
--- a/src/tooltips.cc
+++ b/src/tooltips.cc
@@ -37,30 +37,30 @@ void Tooltip::update() {
 
 void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion) {
   Tooltips::shown_tooltips.emplace(this);
-  
+
   if(!window) {
     //init window
     window=std::make_unique<Gtk::Window>(Gtk::WindowType::WINDOW_POPUP);
-    
+
     auto g_application=g_application_get_default();
     auto gio_application=Glib::wrap(g_application, true);
     auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
     window->set_transient_for(*application->get_active_window());
-    
+
     window->set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_TOOLTIP);
-    
+
     window->set_events(Gdk::POINTER_MOTION_MASK);
     window->property_decorated()=false;
     window->set_accept_focus(false);
     window->set_skip_taskbar_hint(true);
     window->set_default_size(0, 0);
-    
+
     window->signal_motion_notify_event().connect([on_motion](GdkEventMotion *event) {
       if(on_motion)
         on_motion();
       return false;
     });
-    
+
     window->get_style_context()->add_class("juci_tooltip_window");
     auto visual = window->get_screen()->get_rgba_visual();
     if(visual)
@@ -72,11 +72,11 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
 
     text_buffer=create_tooltip_buffer();
     wrap_lines();
-    
+
     auto tooltip_text_view=Gtk::manage(new Gtk::TextView(text_buffer));
     tooltip_text_view->get_style_context()->add_class("juci_tooltip_text_view");
     tooltip_text_view->set_editable(false);
-    
+
 #if GTK_VERSION_GE(3, 20)
     box->add(*tooltip_text_view);
 #else
@@ -90,7 +90,7 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
     layout->get_pixel_size(size.first, size.second);
     size.first+=6; // 2xpadding
     size.second+=8; // 2xpadding + 2
-    
+
     window->signal_realize().connect([this] {
       if(!text_view) {
         auto &dialog=SelectionDialog::get();
@@ -107,7 +107,7 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
       window->move(rectangle.get_x(), rectangle.get_y());
     });
   }
-  
+
   int root_x=0, root_y=0;
   if(text_view) {
     //Adjust if tooltip is left of text_view
@@ -116,7 +116,7 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
     int visible_x, visible_y;
     text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(), visible_rect.get_y(), visible_x, visible_y);
     auto activation_rectangle_x=std::max(activation_rectangle.get_x(), visible_x);
-    
+
     text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle_x, activation_rectangle.get_y(), root_x, root_y);
     root_x-=3; // -1xpadding
     if(root_y<size.second)
@@ -126,7 +126,7 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
   rectangle.set_y(std::max(0, root_y-size.second));
   rectangle.set_width(size.first);
   rectangle.set_height(size.second);
-  
+
   if(!disregard_drawn) {
     if(Tooltips::drawn_tooltips_rectangle.get_width()!=0) {
       if(rectangle.intersects(Tooltips::drawn_tooltips_rectangle)) {
@@ -141,7 +141,7 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
     else
       Tooltips::drawn_tooltips_rectangle=rectangle;
   }
-  
+
   if(window->get_realized())
     window->move(rectangle.get_x(), rectangle.get_y());
   window->show_all();
@@ -180,9 +180,9 @@ void Tooltip::hide(const std::pair<int, int> &last_mouse_pos, const std::pair<in
 void Tooltip::wrap_lines() {
   if(!text_buffer)
     return;
-  
+
   auto iter=text_buffer->begin();
-  
+
   while(iter) {
     auto last_space=text_buffer->end();
     bool end=false;
@@ -212,7 +212,7 @@ void Tooltip::wrap_lines() {
         last_space.forward_char();
         text_buffer->erase(last_space_p, last_space);
         text_buffer->insert(mark->get_iter(), "\n");
-        
+
         iter=mark->get_iter();
         iter.forward_char();
 
diff --git a/src/tooltips.h b/src/tooltips.h
index 26f88965..fc43ee72 100644
--- a/src/tooltips.h
+++ b/src/tooltips.h
@@ -10,25 +10,25 @@ class Tooltip {
   Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer_, Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark_, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark_);
   Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer_) : Tooltip(std::move(create_tooltip_buffer_), nullptr, Glib::RefPtr<Gtk::TextBuffer::Mark>(), Glib::RefPtr<Gtk::TextBuffer::Mark>()) {}
   ~Tooltip();
-  
+
   void update();
   void show(bool disregard_drawn=false, const std::function<void()> &on_motion=nullptr);
   void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
-  
+
   Gdk::Rectangle activation_rectangle;
   Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
   Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
-  
+
   Glib::RefPtr<Gtk::TextBuffer> text_buffer;
 private:
   std::unique_ptr<Gtk::Window> window;
   void wrap_lines();
-  
+
   std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer;
   Gtk::TextView *text_view;
   std::pair<int, int> size;
   Gdk::Rectangle rectangle;
-  
+
   bool shown=false;
 };
 
@@ -37,19 +37,19 @@ class Tooltips {
   static std::set<Tooltip*> shown_tooltips;
   static Gdk::Rectangle drawn_tooltips_rectangle;
   static void init() {drawn_tooltips_rectangle=Gdk::Rectangle();}
-  
+
   void show(const Gdk::Rectangle& rectangle, bool disregard_drawn=false);
   void show(bool disregard_drawn=false);
   void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
   void clear() {tooltip_list.clear();};
-  
+
   template<typename... Ts>
   void emplace_back(Ts&&... params) {
     tooltip_list.emplace_back(std::forward<Ts>(params)...);
   }
-  
+
   std::function<void()> on_motion;
-  
+
 private:
   std::list<Tooltip> tooltip_list;
 };
diff --git a/src/usages_clang.cc b/src/usages_clang.cc
index fd50f372..ac1a007a 100644
--- a/src/usages_clang.cc
+++ b/src/usages_clang.cc
@@ -660,7 +660,7 @@ std::pair<Usages::Clang::PathSet, Usages::Clang::PathSet> Usages::Clang::find_po
         auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
         if((path_all_includes.find(path) != path_all_includes.end() || path_with_spelling == path)) {
           potential_paths.emplace(path_with_spelling);
-  
+
           for(auto &include : path_all_includes)
             all_includes.emplace(include);
         }
@@ -670,7 +670,7 @@ std::pair<Usages::Clang::PathSet, Usages::Clang::PathSet> Usages::Clang::find_po
       if(first) {
         for(auto &path_with_spelling : paths_with_spelling) {
           potential_paths.emplace(path_with_spelling);
-    
+
           auto path_all_includes = get_all_includes(path_with_spelling, paths_includes);
           for(auto &include : path_all_includes)
             all_includes.emplace(include);
diff --git a/src/window.cc b/src/window.cc
index 83f4a889..9e0fb579 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -13,10 +13,10 @@
 
 Window::Window() {
   Gsv::init();
-  
+
   set_title("juCi++");
   set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK|Gdk::LEAVE_NOTIFY_MASK);
-  
+
   auto provider = Gtk::CssProvider::create();
   auto screen = get_screen();
   std::string border_radius_style;
@@ -35,14 +35,14 @@ Window::Window() {
     .juci_tooltip_box {)"+border_radius_style+R"(padding: 3px;}
   )");
   get_style_context()->add_provider_for_screen(screen, provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-  
+
   set_menu_actions();
   configure();
   Menu::get().toggle_menu_items();
-  
+
   Menu::get().right_click_line_menu->attach_to_widget(*this);
   Menu::get().right_click_selected_menu->attach_to_widget(*this);
-  
+
   EntryBox::get().signal_hide().connect([]() {
     if(auto view=Notebook::get().get_current_view())
       view->grab_focus();
@@ -57,16 +57,16 @@ Window::Window() {
     }
 
     Menu::get().toggle_menu_items();
-    
+
     Directories::get().select(view->file_path);
-    
+
     if(view->full_reparse_needed)
       view->full_reparse();
     else if(view->soft_reparse_needed)
       view->soft_reparse();
-    
+
     Notebook::get().update_status(view);
-    
+
 #ifdef JUCI_ENABLE_DEBUG
     if(Project::debugging)
       Project::debug_update_stop();
@@ -89,11 +89,11 @@ Window::Window() {
       Notebook::get().update_status(view);
     else {
       Notebook::get().clear_status();
-      
+
       Menu::get().toggle_menu_items();
     }
   };
-  
+
   signal_focus_out_event().connect([](GdkEventFocus *event) {
     if(auto view=Notebook::get().get_current_view()) {
       view->hide_tooltips();
@@ -101,7 +101,7 @@ Window::Window() {
     }
     return false;
   });
-  
+
   signal_hide().connect([]{
     while(!Source::View::non_deleted_views.empty()) {
       while(Gtk::Main::events_pending())
@@ -110,21 +110,21 @@ Window::Window() {
     // TODO 2022 (after Debian Stretch LTS has ended, see issue #354): remove:
     Project::current=nullptr;
   });
-  
+
   Gtk::Settings::get_default()->connect_property_changed("gtk-theme-name", [] {
     Directories::get().update();
     if(auto view=Notebook::get().get_current_view())
       Notebook::get().update_status(view);
   });
-  
+
   about.signal_response().connect([this](int d){
     about.hide();
   });
-  
+
   about.set_logo_icon_name("juci");
   about.set_version(Config::get().window.version);
   about.set_authors({"(in order of appearance)",
-                     "Ted Johan Kristoffersen", 
+                     "Ted Johan Kristoffersen",
                      "Jørgen Lien Sellæg",
                      "Geir Morten Larsen",
                      "Ole Christian Eidheim"});
@@ -148,7 +148,7 @@ void Window::configure() {
     css_provider_theme=Gtk::CssProvider::get_named(Config::get().window.theme_name, Config::get().window.theme_variant);
   //TODO: add check if theme exists, or else write error to terminal
   Gtk::StyleContext::add_provider_for_screen(screen, css_provider_theme, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
-  
+
   auto style_scheme_manager=Source::StyleSchemeManager::get_default();
   if(css_provider_tooltips)
     Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_tooltips);
@@ -173,7 +173,7 @@ void Window::configure() {
                                         ".juci_tooltip_text_view *:not(:selected) {color: "+foreground_value+";background-color: "+background_value+";}");
 #endif
   get_style_context()->add_provider_for_screen(screen, css_provider_tooltips, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-  
+
   Menu::get().set_keys();
   Terminal::get().configure();
   Directories::get().update();
@@ -183,7 +183,7 @@ void Window::configure() {
 
 void Window::set_menu_actions() {
   auto &menu = Menu::get();
-  
+
   menu.add_action("about", [this]() {
     about.show();
     about.present();
@@ -194,7 +194,7 @@ void Window::set_menu_actions() {
   menu.add_action("quit", [this]() {
     close();
   });
-  
+
   menu.add_action("file_new_file", []() {
     boost::filesystem::path path = Dialog::new_file(Notebook::get().get_current_folder());
     if(path!="") {
@@ -295,7 +295,7 @@ void Window::set_menu_actions() {
         Terminal::get().print("Error: Could not create project "+project_path.string()+"\n", true);
     }
   });
-  
+
   menu.add_action("file_open_file", []() {
     auto folder_path=Notebook::get().get_current_folder();
     if(auto view=Notebook::get().get_current_view()) {
@@ -311,7 +311,7 @@ void Window::set_menu_actions() {
     if (path!="" && boost::filesystem::exists(path))
       Directories::get().open(path);
   });
-  
+
   menu.add_action("file_reload_file", []() {
     if(auto view=Notebook::get().get_current_view()) {
       if(boost::filesystem::exists(view->file_path)) {
@@ -326,12 +326,12 @@ void Window::set_menu_actions() {
         Terminal::get().print("Error: "+view->file_path.string()+" does not exist\n", true);
         return;
       }
-      
+
       if(view->load())
         view->full_reparse();
     }
   });
-  
+
   menu.add_action("file_save", [this]() {
     if(auto view=Notebook::get().get_current_view()) {
       if(Notebook::get().save_current()) {
@@ -363,15 +363,15 @@ void Window::set_menu_actions() {
       }
     }
   });
-  
+
   menu.add_action("file_print", [this]() {
     if(auto view=Notebook::get().get_current_view()) {
       auto print_operation=Gtk::PrintOperation::create();
       auto print_compositor=Gsv::PrintCompositor::create(*view);
-      
+
       print_operation->set_job_name(view->file_path.filename().string());
       print_compositor->set_wrap_mode(Gtk::WrapMode::WRAP_WORD_CHAR);
-      
+
       print_operation->signal_begin_print().connect([print_operation, print_compositor](const Glib::RefPtr<Gtk::PrintContext>& print_context) {
         while(!print_compositor->paginate(print_context));
         print_operation->set_n_pages(print_compositor->get_n_pages());
@@ -379,11 +379,11 @@ void Window::set_menu_actions() {
       print_operation->signal_draw_page().connect([print_compositor](const Glib::RefPtr<Gtk::PrintContext>& print_context, int page_nr) {
         print_compositor->draw_page(print_context, page_nr);
       });
-      
+
       print_operation->run(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG, *this);
     }
   });
-  
+
   menu.add_action("edit_undo", []() {
     if(auto view=Notebook::get().get_current_view()) {
       auto undo_manager = view->get_source_buffer()->get_undo_manager();
@@ -408,7 +408,7 @@ void Window::set_menu_actions() {
       }
     }
   });
-  
+
   menu.add_action("edit_cut", [this]() {
     // Return if a shown tooltip has selected text
     for(auto tooltip: Tooltips::shown_tooltips) {
@@ -416,7 +416,7 @@ void Window::set_menu_actions() {
       if(buffer && buffer->get_has_selection())
         return;
     }
-    
+
     auto widget=get_focus();
     if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
       entry->cut_clipboard();
@@ -452,7 +452,7 @@ void Window::set_menu_actions() {
         return;
       }
     }
-    
+
     auto widget=get_focus();
     if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
       entry->copy_clipboard();
@@ -487,11 +487,11 @@ void Window::set_menu_actions() {
         view->get_buffer()->paste_clipboard(Gtk::Clipboard::get());
     }
   });
-  
+
   menu.add_action("edit_find", [this]() {
     search_and_replace_entry();
   });
-  
+
   menu.add_action("source_spellcheck", []() {
     if(auto view=Notebook::get().get_current_view()) {
       view->remove_spellcheck_errors();
@@ -506,7 +506,7 @@ void Window::set_menu_actions() {
     if(auto view=Notebook::get().get_current_view())
       view->goto_next_spellcheck_error();
   });
-  
+
   menu.add_action("source_git_next_diff", []() {
     if(auto view=Notebook::get().get_current_view())
       view->git_goto_next_diff();
@@ -533,7 +533,7 @@ void Window::set_menu_actions() {
       }
     }
   });
-  
+
   menu.add_action("source_indentation_set_buffer_tab", [this]() {
     set_tab_entry();
   });
@@ -546,7 +546,7 @@ void Window::set_menu_actions() {
       view->hide_tooltips();
     }
   });
-  
+
   menu.add_action("source_goto_line", [this]() {
     goto_line_entry();
   });
@@ -559,7 +559,7 @@ void Window::set_menu_actions() {
       return;
     if(Notebook::get().current_cursor_location==static_cast<size_t>(-1))
       Notebook::get().current_cursor_location=Notebook::get().cursor_locations.size()-1;
-    
+
     auto cursor_location=&Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
     // Move to current position if current position's view is not current view
     // (in case one is looking at a new file but has not yet placed the cursor within the file)
@@ -570,7 +570,7 @@ void Window::set_menu_actions() {
         return;
       if(Notebook::get().current_cursor_location==0)
         return;
-      
+
       --Notebook::get().current_cursor_location;
       cursor_location=&Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
       if(Notebook::get().get_current_view()!=cursor_location->view)
@@ -587,7 +587,7 @@ void Window::set_menu_actions() {
       Notebook::get().current_cursor_location=Notebook::get().cursor_locations.size()-1;
     if(Notebook::get().current_cursor_location==Notebook::get().cursor_locations.size()-1)
       return;
-    
+
     ++Notebook::get().current_cursor_location;
     auto &cursor_location=Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location);
     if(Notebook::get().get_current_view()!=cursor_location.view)
@@ -596,7 +596,7 @@ void Window::set_menu_actions() {
     cursor_location.view->get_buffer()->place_cursor(cursor_location.mark->get_iter());
     cursor_location.view->scroll_to_cursor_delayed(cursor_location.view, true, false);
   });
-  
+
   menu.add_action("source_show_completion", [] {
     if(auto view=Notebook::get().get_current_view()) {
       if(view->non_interactive_completion)
@@ -605,12 +605,12 @@ void Window::set_menu_actions() {
         g_signal_emit_by_name(view->gobj(), "show-completion");
     }
   });
-  
+
   menu.add_action("source_find_symbol", []() {
     auto project=Project::create();
     project->show_symbols();
   });
-  
+
   menu.add_action("source_find_file", []() {
     auto view = Notebook::get().get_current_view();
 
@@ -635,18 +635,18 @@ void Window::set_menu_actions() {
       default_path = build->get_default_path();
       debug_path = build->get_debug_path();
     }
-  
+
     if(view) {
       auto dialog_iter=view->get_iter_for_dialog();
       SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
     }
     else
       SelectionDialog::create(true, true);
-    
+
     std::unordered_set<std::string> buffer_paths;
     for(auto view: Notebook::get().get_views())
       buffer_paths.emplace(view->file_path.string());
-    
+
     std::vector<boost::filesystem::path> paths;
     // populate with all files in search_path
     for (boost::filesystem::recursive_directory_iterator iter(search_path), end; iter != end; iter++) {
@@ -657,7 +657,7 @@ void Window::set_menu_actions() {
           iter.no_push();
         continue;
       }
-        
+
       // remove project base path
       auto row_str = filesystem::get_relative_path(path, search_path).string();
       if(buffer_paths.count(path.string()))
@@ -665,12 +665,12 @@ void Window::set_menu_actions() {
       paths.emplace_back(path);
       SelectionDialog::get()->add_row(row_str);
     }
-    
+
     if(paths.empty()) {
       Info::get().print("No files found in current project");
       return;
     }
-  
+
     SelectionDialog::get()->on_select=[paths=std::move(paths)](unsigned int index, const std::string &text, bool hide_window) {
       if(index>=paths.size())
         return;
@@ -678,13 +678,13 @@ void Window::set_menu_actions() {
       if (auto view=Notebook::get().get_current_view())
         view->hide_tooltips();
     };
-  
+
     if(view)
       view->hide_tooltips();
     SelectionDialog::get()->show();
-  
+
   });
-  
+
   menu.add_action("source_comments_toggle", []() {
     if(auto view=Notebook::get().get_current_view()) {
       if(view->toggle_comments) {
@@ -738,7 +738,7 @@ void Window::set_menu_actions() {
                 query=documentation_search->second.queries.find("@empty");
               if(query==documentation_search->second.queries.end())
                 query=documentation_search->second.queries.find("@any");
-              
+
               if(query!=documentation_search->second.queries.end())
                 url=query->second+token_query;
             }
@@ -760,7 +760,7 @@ void Window::set_menu_actions() {
       }
     }
   });
-  
+
   menu.add_action("source_goto_declaration", []() {
     if(auto view=Notebook::get().get_current_view()) {
       if(view->get_declaration_location) {
@@ -815,7 +815,7 @@ void Window::set_menu_actions() {
         rows.emplace_back(location);
         SelectionDialog::get()->add_row(row);
       }
-      
+
       if(rows.size()==0)
         return;
       else if(rows.size()==1) {
@@ -867,7 +867,7 @@ void Window::set_menu_actions() {
           auto dialog_iter=view->get_iter_for_dialog();
           SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
           std::vector<Source::Offset> rows;
-          
+
           auto iter=view->get_buffer()->get_insert()->get_iter();
           for(auto &usage: usages) {
             std::string row;
@@ -880,14 +880,14 @@ void Window::set_menu_actions() {
             row+=std::to_string(usage.first.line+1)+": "+usage.second;
             rows.emplace_back(usage.first);
             SelectionDialog::get()->add_row(row);
-            
+
             //Set dialog cursor to the last row if the textview cursor is at the same line
             if(current_page &&
                iter.get_line()==static_cast<int>(usage.first.line) && iter.get_line_index()>=static_cast<int>(usage.first.index)) {
               SelectionDialog::get()->set_cursor_at_last_row();
             }
           }
-          
+
           if(rows.size()==0)
             return;
           SelectionDialog::get()->on_select=[rows=std::move(rows)](unsigned int index, const std::string &text, bool hide_window) {
@@ -942,7 +942,7 @@ void Window::set_menu_actions() {
   });
   menu.add_action("source_implement_method", []() {
     const static std::string button_text="Insert Method Implementation";
-    
+
     if(auto view=Notebook::get().get_current_view()) {
       if(view->get_method) {
         auto iter=view->get_buffer()->get_insert()->get_iter();
@@ -954,7 +954,7 @@ void Window::set_menu_actions() {
         auto method=view->get_method();
         if(method.empty())
           return;
-        
+
         EntryBox::get().clear();
         EntryBox::get().labels.emplace_back();
         EntryBox::get().labels.back().set_text(method);
@@ -968,7 +968,7 @@ void Window::set_menu_actions() {
       }
     }
   });
-  
+
   menu.add_action("source_goto_next_diagnostic", []() {
     if(auto view=Notebook::get().get_current_view()) {
       if(view->goto_next_diagnostic) {
@@ -1010,13 +1010,13 @@ void Window::set_menu_actions() {
       }
     }
   });
-  
+
   menu.add_action("project_set_run_arguments", []() {
     auto project=Project::create();
     auto run_arguments=project->get_run_arguments();
     if(run_arguments.second.empty())
       return;
-    
+
     EntryBox::get().clear();
     EntryBox::get().labels.emplace_back();
     auto label_it=EntryBox::get().labels.begin();
@@ -1040,12 +1040,12 @@ void Window::set_menu_actions() {
       Info::get().print("Compile or debug in progress");
       return;
     }
-    
+
     Project::current=Project::create();
-    
+
     if(Config::get().project.save_on_compile_or_run)
       Project::save_files(Project::current->build->get_project_path());
-    
+
     Project::current->compile_and_run();
   });
   menu.add_action("project_compile", []() {
@@ -1053,12 +1053,12 @@ void Window::set_menu_actions() {
       Info::get().print("Compile or debug in progress");
       return;
     }
-            
+
     Project::current=Project::create();
-    
+
     if(Config::get().project.save_on_compile_or_run)
       Project::save_files(Project::current->build->get_project_path());
-    
+
     Project::current->compile();
   });
   menu.add_action("project_recreate_build", []() {
@@ -1066,12 +1066,12 @@ void Window::set_menu_actions() {
       Info::get().print("Compile or debug in progress");
       return;
     }
-    
+
     Project::current=Project::create();
 
     Project::current->recreate_build();
   });
-  
+
   menu.add_action("project_run_command", [this]() {
     EntryBox::get().clear();
     EntryBox::get().labels.emplace_back();
@@ -1085,7 +1085,7 @@ void Window::set_menu_actions() {
         last_run_command=content;
         auto run_path=Notebook::get().get_current_folder();
         Terminal::get().async_print("Running: "+content+'\n');
-  
+
         Terminal::get().async_process(content, run_path, [content](int exit_status){
           Terminal::get().async_print(content+" returned: "+std::to_string(exit_status)+'\n');
         });
@@ -1099,21 +1099,21 @@ void Window::set_menu_actions() {
     });
     EntryBox::get().show();
   });
-  
+
   menu.add_action("project_kill_last_running", []() {
     Terminal::get().kill_last_async_process();
   });
   menu.add_action("project_force_kill_last_running", []() {
     Terminal::get().kill_last_async_process(true);
   });
-  
+
 #ifdef JUCI_ENABLE_DEBUG
   menu.add_action("debug_set_run_arguments", []() {
     auto project=Project::create();
     auto run_arguments=project->debug_get_run_arguments();
     if(run_arguments.second.empty())
       return;
-    
+
     EntryBox::get().clear();
     EntryBox::get().labels.emplace_back();
     auto label_it=EntryBox::get().labels.begin();
@@ -1127,7 +1127,7 @@ void Window::set_menu_actions() {
     }, 50);
     auto entry_it=EntryBox::get().entries.begin();
     entry_it->set_placeholder_text("Debug: Set Run Arguments");
-    
+
     if(auto options=project->debug_get_options()) {
       EntryBox::get().buttons.emplace_back("", [options]() {
         options->show_all();
@@ -1137,7 +1137,7 @@ void Window::set_menu_actions() {
       EntryBox::get().buttons.back().set_tooltip_text("Additional Options");
       options->set_relative_to(EntryBox::get().buttons.back());
     }
-    
+
     EntryBox::get().buttons.emplace_back("Debug: set run arguments", [entry_it](){
       entry_it->activate();
     });
@@ -1152,12 +1152,12 @@ void Window::set_menu_actions() {
       Project::current->debug_continue();
       return;
     }
-        
+
     Project::current=Project::create();
-    
+
     if(Config::get().project.save_on_compile_or_run)
       Project::save_files(Project::current->build->get_project_path());
-    
+
     Project::current->debug_start();
   });
   menu.add_action("debug_stop", []() {
@@ -1224,10 +1224,10 @@ void Window::set_menu_actions() {
       }
     }
   });
-  
+
   Project::debug_update_status("");
 #endif
-  
+
   menu.add_action("window_next_tab", []() {
     Notebook::get().next();
   });
@@ -1253,11 +1253,11 @@ void Window::set_menu_actions() {
   menu.add_action("window_clear_terminal", [] {
     Terminal::get().clear();
   });
-  
+
   menu.toggle_menu_items=[] {
     auto &menu = Menu::get();
     auto view=Notebook::get().get_current_view();
-    
+
     menu.actions["file_reload_file"]->set_enabled(view);
     menu.actions["source_spellcheck"]->set_enabled(view);
     menu.actions["source_spellcheck_clear"]->set_enabled(view);
@@ -1267,7 +1267,7 @@ void Window::set_menu_actions() {
     menu.actions["source_indentation_set_buffer_tab"]->set_enabled(view);
     menu.actions["source_goto_line"]->set_enabled(view);
     menu.actions["source_center_cursor"]->set_enabled(view);
-    
+
     menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && view->format_style);
     menu.actions["source_comments_toggle"]->set_enabled(view && view->toggle_comments);
     menu.actions["source_comments_add_documentation"]->set_enabled(view && view->get_documentation_template);
@@ -1291,27 +1291,27 @@ void Window::set_menu_actions() {
 void Window::add_widgets() {
   auto directories_scrolled_window=Gtk::manage(new Gtk::ScrolledWindow());
   directories_scrolled_window->add(Directories::get());
-  
+
   auto notebook_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
   notebook_vbox->pack_start(Notebook::get());
   notebook_vbox->pack_end(EntryBox::get(), Gtk::PACK_SHRINK);
-  
+
   auto terminal_scrolled_window=Gtk::manage(new Gtk::ScrolledWindow());
   terminal_scrolled_window->add(Terminal::get());
-  
+
   int width, height;
   get_default_size(width, height);
-  
+
   auto notebook_and_terminal_vpaned=Gtk::manage(new Gtk::Paned(Gtk::Orientation::ORIENTATION_VERTICAL));
   notebook_and_terminal_vpaned->set_position(static_cast<int>(0.75*height));
   notebook_and_terminal_vpaned->pack1(*notebook_vbox, Gtk::SHRINK);
   notebook_and_terminal_vpaned->pack2(*terminal_scrolled_window, Gtk::SHRINK);
-  
+
   auto hpaned=Gtk::manage(new Gtk::Paned());
   hpaned->set_position(static_cast<int>(0.2*width));
   hpaned->pack1(*directories_scrolled_window, Gtk::SHRINK);
   hpaned->pack2(*notebook_and_terminal_vpaned, Gtk::SHRINK);
-  
+
   auto status_hbox=Gtk::manage(new Gtk::Box());
   status_hbox->set_homogeneous(true);
   status_hbox->pack_start(*Gtk::manage(new Gtk::Box()));
@@ -1321,7 +1321,7 @@ void Window::add_widgets() {
   status_right_overlay->add(*status_right_hbox);
   status_right_overlay->add_overlay(Notebook::get().status_diagnostics);
   status_hbox->pack_end(*status_right_overlay);
-  
+
   auto status_overlay=Gtk::manage(new Gtk::Overlay());
   status_overlay->add(*status_hbox);
   auto status_file_info_hbox=Gtk::manage(new Gtk::Box);
@@ -1330,11 +1330,11 @@ void Window::add_widgets() {
   status_file_info_hbox->pack_start(Notebook::get().status_location, Gtk::PACK_SHRINK);
   status_overlay->add_overlay(*status_file_info_hbox);
   status_overlay->add_overlay(Project::debug_status_label());
-  
+
   auto vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
   vbox->pack_start(*hpaned);
   vbox->pack_start(*status_overlay, Gtk::PACK_SHRINK);
-  
+
   auto overlay_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL));
   auto overlay_hbox=Gtk::manage(new Gtk::Box());
   overlay_vbox->set_hexpand(false);
@@ -1343,23 +1343,23 @@ void Window::add_widgets() {
   overlay_hbox->set_hexpand(false);
   overlay_hbox->set_halign(Gtk::Align::ALIGN_END);
   overlay_hbox->pack_end(*overlay_vbox, Gtk::PACK_SHRINK, 20);
-  
+
   auto overlay=Gtk::manage(new Gtk::Overlay());
   overlay->add(*vbox);
   overlay->add_overlay(*overlay_hbox);
   overlay->set_overlay_pass_through(*overlay_hbox, true);
   add(*overlay);
-  
+
   show_all_children();
   Info::get().hide();
-  
+
   //Scroll to end of terminal whenever info is printed
   Terminal::get().signal_size_allocate().connect([terminal_scrolled_window](Gtk::Allocation& allocation){
     auto adjustment=terminal_scrolled_window->get_vadjustment();
     adjustment->set_value(adjustment->get_upper()-adjustment->get_page_size());
     Terminal::get().queue_draw();
   });
-  
+
   EntryBox::get().signal_show().connect([hpaned, notebook_and_terminal_vpaned, notebook_vbox](){
     hpaned->set_focus_chain({notebook_and_terminal_vpaned});
     notebook_and_terminal_vpaned->set_focus_chain({notebook_vbox});
@@ -1413,7 +1413,7 @@ bool Window::on_key_press_event(GdkEventKey *event) {
 
 bool Window::on_delete_event(GdkEventAny *event) {
   save_session();
-  
+
   for(size_t c=Notebook::get().size()-1;c!=static_cast<size_t>(-1);--c) {
     if(!Notebook::get().close(c))
       return true;
@@ -1487,7 +1487,7 @@ void Window::search_and_replace_entry() {
   replace_entry_it->signal_changed().connect([this, replace_entry_it](){
     last_replace=replace_entry_it->get_text();
   });
-  
+
   EntryBox::get().buttons.emplace_back("↑", [](){
     if(auto view=Notebook::get().get_current_view())
         view->search_backward();
@@ -1509,7 +1509,7 @@ void Window::search_and_replace_entry() {
       view->replace_all(replace_entry_it->get_text());
   });
   EntryBox::get().buttons.back().set_tooltip_text("Replace All");
-  
+
   EntryBox::get().toggle_buttons.emplace_back("Aa");
   EntryBox::get().toggle_buttons.back().set_tooltip_text("Match Case");
   EntryBox::get().toggle_buttons.back().set_active(case_sensitive_search);
@@ -1541,25 +1541,25 @@ void Window::set_tab_entry() {
   EntryBox::get().clear();
   if(auto view=Notebook::get().get_current_view()) {
     auto tab_char_and_size=view->get_tab_char_and_size();
-    
+
     EntryBox::get().labels.emplace_back();
     auto label_it=EntryBox::get().labels.begin();
-    
+
     EntryBox::get().entries.emplace_back(std::to_string(tab_char_and_size.second));
     auto entry_tab_size_it=EntryBox::get().entries.begin();
     entry_tab_size_it->set_placeholder_text("Tab size");
-    
+
     char tab_char=tab_char_and_size.first;
     std::string tab_char_string;
     if(tab_char==' ')
       tab_char_string="space";
     else if(tab_char=='\t')
       tab_char_string="tab";
-      
+
     EntryBox::get().entries.emplace_back(tab_char_string);
     auto entry_tab_char_it=EntryBox::get().entries.rbegin();
     entry_tab_char_it->set_placeholder_text("Tab char");
-    
+
     const auto activate_function=[entry_tab_char_it, entry_tab_size_it, label_it](const std::string& content){
       if(auto view=Notebook::get().get_current_view()) {
         char tab_char=0;
@@ -1584,14 +1584,14 @@ void Window::set_tab_entry() {
         }
       }
     };
-    
+
     entry_tab_char_it->on_activate=activate_function;
     entry_tab_size_it->on_activate=activate_function;
-    
+
     EntryBox::get().buttons.emplace_back("Set tab in current buffer", [entry_tab_char_it](){
       entry_tab_char_it->activate();
     });
-    
+
     EntryBox::get().show();
   }
 }
@@ -1605,7 +1605,7 @@ void Window::goto_line_entry() {
           view->place_cursor_at_line_index(stoi(content)-1, 0);
           view->scroll_to_cursor_delayed(view, true, false);
         }
-        catch(const std::exception &e) {}  
+        catch(const std::exception &e) {}
         EntryBox::get().hide();
       }
     });
@@ -1648,7 +1648,7 @@ void Window::save_session() {
   try {
     boost::property_tree::ptree root_pt;
     root_pt.put("folder", Directories::get().path.string());
-    
+
     boost::property_tree::ptree files_pt;
     for(auto &notebook_view: Notebook::get().get_notebook_views()) {
       boost::property_tree::ptree file_pt;
@@ -1660,7 +1660,7 @@ void Window::save_session() {
       files_pt.push_back(std::make_pair("", file_pt));
     }
     root_pt.add_child("files", files_pt);
-    
+
     boost::property_tree::ptree current_file_pt;
     if(auto view=Notebook::get().get_current_view()) {
       current_file_pt.put("path", view->file_path.string());
@@ -1672,7 +1672,7 @@ void Window::save_session() {
     if(auto view=Notebook::get().get_current_view())
       current_path=view->file_path.string();
     root_pt.put("current_file", current_path);
-    
+
     boost::property_tree::ptree run_arguments_pt;
     for(auto &run_argument: Project::run_arguments) {
       if(run_argument.second.empty())
@@ -1686,7 +1686,7 @@ void Window::save_session() {
       }
     }
     root_pt.add_child("run_arguments", run_arguments_pt);
-    
+
     boost::property_tree::ptree debug_run_arguments_pt;
     for(auto &debug_run_argument: Project::debug_run_arguments) {
       if(debug_run_argument.second.arguments.empty() && !debug_run_argument.second.remote_enabled && debug_run_argument.second.remote_host_port.empty())
@@ -1702,14 +1702,14 @@ void Window::save_session() {
       }
     }
     root_pt.add_child("debug_run_arguments", debug_run_arguments_pt);
-    
+
     int width, height;
     get_size(width, height);
     boost::property_tree::ptree window_pt;
     window_pt.put("width", width);
     window_pt.put("height", height);
     root_pt.add_child("window", window_pt);
-    
+
     boost::property_tree::write_json((Config::get().home_juci_path/"last_session.json").string(), root_pt);
   }
   catch(...) {}
@@ -1723,7 +1723,7 @@ void Window::load_session(std::vector<boost::filesystem::path> &directories, std
       auto folder=root_pt.get<std::string>("folder");
       if(!folder.empty() && boost::filesystem::exists(folder) && boost::filesystem::is_directory(folder))
         directories.emplace_back(folder);
-      
+
       for(auto &file_pt: root_pt.get_child("files")) {
         auto file=file_pt.second.get<std::string>("path");
         auto notebook=file_pt.second.get<size_t>("notebook");
@@ -1734,17 +1734,17 @@ void Window::load_session(std::vector<boost::filesystem::path> &directories, std
           file_offsets.emplace_back(line, line_offset);
         }
       }
-     
+
       current_file=root_pt.get<std::string>("current_file");
     }
-    
+
     for(auto &run_argument: root_pt.get_child(("run_arguments"))) {
       auto path=run_argument.second.get<std::string>("path");
       boost::system::error_code ec;
       if(boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec))
         Project::run_arguments.emplace(path, run_argument.second.get<std::string>("arguments"));
     }
-    
+
     for(auto &debug_run_argument: root_pt.get_child(("debug_run_arguments"))) {
       auto path=debug_run_argument.second.get<std::string>("path");
       boost::system::error_code ec;
@@ -1753,7 +1753,7 @@ void Window::load_session(std::vector<boost::filesystem::path> &directories, std
                                                                               debug_run_argument.second.get<bool>("remote_enabled"),
                                                                               debug_run_argument.second.get<std::string>("remote_host_port")});
     }
-    
+
     auto window_pt=root_pt.get_child("window");
     set_default_size(window_pt.get<int>("width"), window_pt.get<int>("height"));
   }

From 0cae94776692f1301f2bd222de066e553d5864de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BA=88=E9=A1=BA=20=E5=88=98?= <yshliu0321@icloud.com>
Date: Fri, 25 May 2018 15:08:52 +0800
Subject: [PATCH 11/12] Refactoring

---
 3rd_party/json.h                       | 8838 ++++++++++++++++++++++++
 {src/rapidxml => 3rd_party}/rapidxml.h |    0
 CMakeLists.txt                         |    1 +
 src/CMakeLists.txt                     |  106 +-
 src/cmake.cc                           |  107 +-
 src/cmake.h                            |   15 -
 src/compile_commands.cc                |  110 +-
 src/compile_commands.h                 |    4 +-
 src/makefile_base.cc                   |   66 +-
 src/makefile_base.h                    |   32 +-
 src/meson.cc                           |   68 +-
 src/meson.h                            |   16 -
 src/project_build.cc                   |   64 +-
 src/project_build.h                    |   15 +-
 14 files changed, 9088 insertions(+), 354 deletions(-)
 create mode 100644 3rd_party/json.h
 rename {src/rapidxml => 3rd_party}/rapidxml.h (100%)
 delete mode 100644 src/cmake.h
 delete mode 100644 src/meson.h

diff --git a/3rd_party/json.h b/3rd_party/json.h
new file mode 100644
index 00000000..b631877e
--- /dev/null
+++ b/3rd_party/json.h
@@ -0,0 +1,8838 @@
+/*
+    __ _____ _____ _____
+ __|  |   __|     |   | |  JSON for Modern C++
+|  |  |__   |  |  | | | |  version 3.1.2
+|_____|_____|_____|_|___|  https://github.com/nlohmann/json
+
+Licensed under the MIT License <http://opensource.org/licenses/MIT>.
+Copyright (c) 2013-2018 Niels Lohmann <http://nlohmann.me>.
+
+Permission is hereby  granted, free of charge, to any  person obtaining a copy
+of this software and associated  documentation files (the "Software"), to deal
+in the Software  without restriction, including without  limitation the rights
+to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
+copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
+IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
+FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
+AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
+LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#pragma once
+
+#define NLOHMANN_JSON_VERSION_MAJOR 3
+#define NLOHMANN_JSON_VERSION_MINOR 1
+#define NLOHMANN_JSON_VERSION_PATCH 2
+
+#include <algorithm>
+#include <cassert>
+#include <ciso646>
+#include <cstddef>
+#include <functional>
+#include <initializer_list>
+#include <iosfwd>
+#include <iterator>
+#include <numeric>
+#include <string>
+#include <utility>
+
+#ifndef NLOHMANN_JSON_FWD_HPP
+#define NLOHMANN_JSON_FWD_HPP
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <vector>
+
+namespace nlohmann {
+template<typename = void, typename = void>
+struct adl_serializer;
+
+template<template<typename U, typename V, typename... Args> class ObjectType =
+std::map,
+    template<typename U, typename... Args> class ArrayType = std::vector,
+    class StringType = std::string, class BooleanType = bool,
+    class NumberIntegerType = std::int64_t,
+    class NumberUnsignedType = std::uint64_t,
+    class NumberFloatType = double,
+    template<typename U> class AllocatorType = std::allocator,
+    template<typename T, typename SFINAE = void> class JSONSerializer =
+    adl_serializer>
+class basic_json;
+
+template<typename BasicJsonType>
+class json_pointer;
+
+using json = basic_json<>;
+}
+
+#endif
+
+#if defined(__clang__)
+#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
+        #error "unsupported Clang version"
+    #endif
+#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
+#if (__GNUC__ * 10000+__GNUC_MINOR__ * 100+__GNUC_PATCHLEVEL__) < 40900
+#error "unsupported GCC version"
+#endif
+#endif
+
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
+#if defined(__clang__)
+#pragma GCC diagnostic push
+    #pragma GCC diagnostic ignored "-Wdocumentation"
+#endif
+
+#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
+#define JSON_THROW(exception) throw exception
+#define JSON_TRY try
+#define JSON_CATCH(exception) catch(exception)
+#else
+#define JSON_THROW(exception) std::abort()
+    #define JSON_TRY if(true)
+    #define JSON_CATCH(exception) if(false)
+#endif
+
+#if defined(JSON_THROW_USER)
+
+#undef JSON_THROW
+#define JSON_THROW JSON_THROW_USER
+#endif
+#if defined(JSON_TRY_USER)
+
+#undef JSON_TRY
+#define JSON_TRY JSON_TRY_USER
+#endif
+#if defined(JSON_CATCH_USER)
+
+#undef JSON_CATCH
+#define JSON_CATCH JSON_CATCH_USER
+#endif
+
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+#define JSON_LIKELY(x)      __builtin_expect(!!(x), 1)
+#define JSON_UNLIKELY(x)    __builtin_expect(!!(x), 0)
+#else
+#define JSON_LIKELY(x)      x
+#define JSON_UNLIKELY(x)    x
+#endif
+
+#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1)
+
+#define JSON_HAS_CPP_17
+#define JSON_HAS_CPP_14
+#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
+#define JSON_HAS_CPP_14
+#endif
+
+#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
+    template<template<typename, typename, typename...> class ObjectType,   \
+             template<typename, typename...> class ArrayType,              \
+             class StringType, class BooleanType, class NumberIntegerType, \
+             class NumberUnsignedType, class NumberFloatType,              \
+             template<typename> class AllocatorType,                       \
+             template<typename, typename = void> class JSONSerializer>
+
+#define NLOHMANN_BASIC_JSON_TPL                                            \
+    basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
+    NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
+    AllocatorType, JSONSerializer>
+
+#define NLOHMANN_JSON_HAS_HELPER(type)                                        \
+    template<typename T> struct has_##type {                                  \
+    private:                                                                  \
+        template<typename U, typename = typename U::type>                     \
+        static int detect(U &&);                                              \
+        static void detect(...);                                              \
+    public:                                                                   \
+        static constexpr bool value =                                         \
+                std::is_integral<decltype(detect(std::declval<T>()))>::value; \
+    }
+
+#include <limits>
+#include <type_traits>
+
+namespace nlohmann {
+namespace detail {
+template<typename>
+struct is_basic_json : std::false_type {
+};
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+struct is_basic_json<NLOHMANN_BASIC_JSON_TPL > : std::true_type {
+};
+
+template<bool B, typename T = void>
+using enable_if_t = typename std::enable_if<B, T>::type;
+
+template<typename T>
+using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+
+template<std::size_t... Ints>
+struct index_sequence {
+  using type = index_sequence;
+  using value_type = std::size_t;
+
+  static constexpr std::size_t size() noexcept {
+    return sizeof...(Ints);
+  }
+};
+
+template<class Sequence1, class Sequence2>
+struct merge_and_renumber;
+
+template<std::size_t... I1, std::size_t... I2>
+struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
+    : index_sequence<I1..., (sizeof...(I1)+I2)...> {
+};
+
+template<std::size_t N>
+struct make_index_sequence
+    : merge_and_renumber<typename make_index_sequence<N / 2>::type,
+        typename make_index_sequence<N-N / 2>::type> {
+};
+
+template<>
+struct make_index_sequence<0> : index_sequence<> {
+};
+template<>
+struct make_index_sequence<1> : index_sequence<0> {
+};
+
+template<typename... Ts>
+using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
+
+template<class...>
+struct conjunction : std::true_type {
+};
+template<class B1>
+struct conjunction<B1> : B1 {
+};
+template<class B1, class... Bn>
+struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {
+};
+
+template<class B>
+struct negation : std::integral_constant<bool, not B::value> {
+};
+
+template<unsigned N>
+struct priority_tag : priority_tag<N-1> {
+};
+template<>
+struct priority_tag<0> {
+};
+
+template<typename T, typename = void>
+struct is_complete_type : std::false_type {
+};
+
+template<typename T>
+struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {
+};
+
+NLOHMANN_JSON_HAS_HELPER(mapped_type);
+
+NLOHMANN_JSON_HAS_HELPER(key_type);
+
+NLOHMANN_JSON_HAS_HELPER(value_type);
+
+NLOHMANN_JSON_HAS_HELPER(iterator);
+
+template<bool B, class RealType, class CompatibleObjectType>
+struct is_compatible_object_type_impl : std::false_type {
+};
+
+template<class RealType, class CompatibleObjectType>
+struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType> {
+  static constexpr auto value =
+      std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
+      std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
+};
+
+template<class BasicJsonType, class CompatibleObjectType>
+struct is_compatible_object_type {
+  static auto constexpr value = is_compatible_object_type_impl<
+      conjunction<negation<std::is_same<void, CompatibleObjectType>>,
+          has_mapped_type<CompatibleObjectType>,
+          has_key_type<CompatibleObjectType>>::value,
+      typename BasicJsonType::object_t, CompatibleObjectType>::value;
+};
+
+template<typename BasicJsonType, typename T>
+struct is_basic_json_nested_type {
+  static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
+                                std::is_same<T, typename BasicJsonType::const_iterator>::value or
+                                std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
+                                std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
+};
+
+template<class BasicJsonType, class CompatibleArrayType>
+struct is_compatible_array_type {
+  static auto constexpr value =
+      conjunction<negation<std::is_same<void, CompatibleArrayType>>,
+          negation<is_compatible_object_type<
+              BasicJsonType, CompatibleArrayType>>,
+          negation<std::is_constructible<typename BasicJsonType::string_t,
+              CompatibleArrayType>>,
+          negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
+          has_value_type<CompatibleArrayType>,
+          has_iterator<CompatibleArrayType>>::value;
+};
+
+template<bool, typename, typename>
+struct is_compatible_integer_type_impl : std::false_type {
+};
+
+template<typename RealIntegerType, typename CompatibleNumberIntegerType>
+struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType> {
+  using RealLimits = std::numeric_limits<RealIntegerType>;
+  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
+
+  static constexpr auto value =
+      std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
+      CompatibleLimits::is_integer and
+      RealLimits::is_signed == CompatibleLimits::is_signed;
+};
+
+template<typename RealIntegerType, typename CompatibleNumberIntegerType>
+struct is_compatible_integer_type {
+  static constexpr auto value =
+      is_compatible_integer_type_impl<
+          std::is_integral<CompatibleNumberIntegerType>::value and
+          not std::is_same<bool, CompatibleNumberIntegerType>::value,
+          RealIntegerType, CompatibleNumberIntegerType>::value;
+};
+
+template<typename BasicJsonType, typename T>
+struct has_from_json {
+private:
+  template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
+      std::declval<BasicJsonType>(), std::declval<T &>()))>::value>>
+  static int detect(U &&);
+
+  static void detect(...);
+
+public:
+  static constexpr bool value = std::is_integral<decltype(
+  detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
+};
+
+template<typename BasicJsonType, typename T>
+struct has_non_default_from_json {
+private:
+  template<
+      typename U,
+      typename = enable_if_t<std::is_same<
+          T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
+  static int detect(U &&);
+
+  static void detect(...);
+
+public:
+  static constexpr bool value = std::is_integral<decltype(detect(
+      std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
+};
+
+template<typename BasicJsonType, typename T>
+struct has_to_json {
+private:
+  template<typename U, typename = decltype(uncvref_t<U>::to_json(
+      std::declval<BasicJsonType &>(), std::declval<T>()))>
+  static int detect(U &&);
+
+  static void detect(...);
+
+public:
+  static constexpr bool value = std::is_integral<decltype(detect(
+      std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
+};
+
+template<typename BasicJsonType, typename CompatibleCompleteType>
+struct is_compatible_complete_type {
+  static constexpr bool value =
+      not std::is_base_of<std::istream, CompatibleCompleteType>::value and
+      not is_basic_json<CompatibleCompleteType>::value and
+      not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value and
+      has_to_json<BasicJsonType, CompatibleCompleteType>::value;
+};
+
+template<typename BasicJsonType, typename CompatibleType>
+struct is_compatible_type
+    : conjunction<is_complete_type<CompatibleType>,
+        is_compatible_complete_type<BasicJsonType, CompatibleType>> {
+};
+
+template<typename T>
+struct static_const {
+  static constexpr T value{};
+};
+
+template<typename T>
+constexpr T static_const<T>::value;
+}
+}
+
+#include <exception>
+#include <stdexcept>
+
+namespace nlohmann {
+namespace detail {
+class exception : public std::exception {
+public:
+  const char *what() const noexcept override {
+    return m.what();
+  }
+
+  const int id;
+
+protected:
+  exception(int id_, const char *what_arg) : id(id_), m(what_arg) {}
+
+  static std::string name(const std::string &ename, int id_) {
+    return "[json.exception."+ename+"."+std::to_string(id_)+"] ";
+  }
+
+private:
+  std::runtime_error m;
+};
+
+class parse_error : public exception {
+public:
+  static parse_error create(int id_, std::size_t byte_, const std::string &what_arg) {
+    std::string w = exception::name("parse_error", id_)+"parse error"+
+                    (byte_ != 0 ? (" at "+std::to_string(byte_)) : "")+
+                    ": "+what_arg;
+    return parse_error(id_, byte_, w.c_str());
+  }
+
+  const std::size_t byte;
+
+private:
+  parse_error(int id_, std::size_t byte_, const char *what_arg)
+      : exception(id_, what_arg), byte(byte_) {}
+};
+
+class invalid_iterator : public exception {
+public:
+  static invalid_iterator create(int id_, const std::string &what_arg) {
+    std::string w = exception::name("invalid_iterator", id_)+what_arg;
+    return invalid_iterator(id_, w.c_str());
+  }
+
+private:
+  invalid_iterator(int id_, const char *what_arg)
+      : exception(id_, what_arg) {}
+};
+
+class type_error : public exception {
+public:
+  static type_error create(int id_, const std::string &what_arg) {
+    std::string w = exception::name("type_error", id_)+what_arg;
+    return type_error(id_, w.c_str());
+  }
+
+private:
+  type_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
+};
+
+class out_of_range : public exception {
+public:
+  static out_of_range create(int id_, const std::string &what_arg) {
+    std::string w = exception::name("out_of_range", id_)+what_arg;
+    return out_of_range(id_, w.c_str());
+  }
+
+private:
+  out_of_range(int id_, const char *what_arg) : exception(id_, what_arg) {}
+};
+
+class other_error : public exception {
+public:
+  static other_error create(int id_, const std::string &what_arg) {
+    std::string w = exception::name("other_error", id_)+what_arg;
+    return other_error(id_, w.c_str());
+  }
+
+private:
+  other_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
+};
+}
+}
+
+#include <array>
+
+namespace nlohmann {
+namespace detail {
+enum class value_t : std::uint8_t {
+  null,
+  object,
+  array,
+  string,
+  boolean,
+  number_integer,
+  number_unsigned,
+  number_float,
+  discarded
+};
+
+inline bool operator<(const value_t lhs, const value_t rhs) noexcept {
+  static constexpr std::array<std::uint8_t, 8> order = {{
+                                                            0, 3, 4, 5,
+                                                            1, 2, 2, 2
+                                                        }
+  };
+
+  const auto l_index = static_cast<std::size_t>(lhs);
+  const auto r_index = static_cast<std::size_t>(rhs);
+  return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
+}
+}
+}
+
+#include <forward_list>
+#include <tuple>
+#include <valarray>
+
+namespace nlohmann {
+namespace detail {
+template<typename BasicJsonType, typename ArithmeticType,
+    enable_if_t<std::is_arithmetic<ArithmeticType>::value and
+                not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
+        int> = 0>
+void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val) {
+  switch(static_cast<value_t>(j)) {
+    case value_t::number_unsigned: {
+      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
+      break;
+    }
+    case value_t::number_integer: {
+      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
+      break;
+    }
+    case value_t::number_float: {
+      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
+      break;
+    }
+
+    default:
+      JSON_THROW(type_error::create(302, "type must be number, but is "+std::string(j.type_name())));
+  }
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b) {
+  if(JSON_UNLIKELY(not j.is_boolean())) {
+    JSON_THROW(type_error::create(302, "type must be boolean, but is "+std::string(j.type_name())));
+  }
+  b = *j.template get_ptr<const typename BasicJsonType::boolean_t *>();
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType &j, typename BasicJsonType::string_t &s) {
+  if(JSON_UNLIKELY(not j.is_string())) {
+    JSON_THROW(type_error::create(302, "type must be string, but is "+std::string(j.type_name())));
+  }
+  s = *j.template get_ptr<const typename BasicJsonType::string_t *>();
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType &j, typename BasicJsonType::number_float_t &val) {
+  get_arithmetic_value(j, val);
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType &j, typename BasicJsonType::number_unsigned_t &val) {
+  get_arithmetic_value(j, val);
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType &j, typename BasicJsonType::number_integer_t &val) {
+  get_arithmetic_value(j, val);
+}
+
+template<typename BasicJsonType, typename EnumType,
+    enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+void from_json(const BasicJsonType &j, EnumType &e) {
+  typename std::underlying_type<EnumType>::type val;
+  get_arithmetic_value(j, val);
+  e = static_cast<EnumType>(val);
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType &j, typename BasicJsonType::array_t &arr) {
+  if(JSON_UNLIKELY(not j.is_array())) {
+    JSON_THROW(type_error::create(302, "type must be array, but is "+std::string(j.type_name())));
+  }
+  arr = *j.template get_ptr<const typename BasicJsonType::array_t *>();
+}
+
+template<typename BasicJsonType, typename T, typename Allocator,
+    enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
+void from_json(const BasicJsonType &j, std::forward_list<T, Allocator> &l) {
+  if(JSON_UNLIKELY(not j.is_array())) {
+    JSON_THROW(type_error::create(302, "type must be array, but is "+std::string(j.type_name())));
+  }
+  std::transform(j.rbegin(), j.rend(),
+                 std::front_inserter(l), [](const BasicJsonType &i) {
+        return i.template get<T>();
+      });
+}
+
+template<typename BasicJsonType, typename T,
+    enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
+void from_json(const BasicJsonType &j, std::valarray<T> &l) {
+  if(JSON_UNLIKELY(not j.is_array())) {
+    JSON_THROW(type_error::create(302, "type must be array, but is "+std::string(j.type_name())));
+  }
+  l.resize(j.size());
+  std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
+}
+
+template<typename BasicJsonType, typename CompatibleArrayType>
+void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag<0>) {
+  using std::end;
+
+  std::transform(j.begin(), j.end(),
+                 std::inserter(arr, end(arr)), [](const BasicJsonType &i) {
+        return i.template get<typename CompatibleArrayType::value_type>();
+      });
+}
+
+template<typename BasicJsonType, typename CompatibleArrayType>
+auto from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag<1>)
+-> decltype(
+arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
+    void()) {
+  using std::end;
+
+  arr.reserve(j.size());
+  std::transform(j.begin(), j.end(),
+                 std::inserter(arr, end(arr)), [](const BasicJsonType &i) {
+        return i.template get<typename CompatibleArrayType::value_type>();
+      });
+}
+
+template<typename BasicJsonType, typename T, std::size_t N>
+void from_json_array_impl(const BasicJsonType &j, std::array<T, N> &arr, priority_tag<2>) {
+  for(std::size_t i = 0; i < N; ++i) {
+    arr[i] = j.at(i).template get<T>();
+  }
+}
+
+template<
+    typename BasicJsonType, typename CompatibleArrayType,
+    enable_if_t<
+        is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
+        not std::is_same<typename BasicJsonType::array_t,
+            CompatibleArrayType>::value and
+        std::is_constructible<
+            BasicJsonType, typename CompatibleArrayType::value_type>::value,
+        int> = 0>
+void from_json(const BasicJsonType &j, CompatibleArrayType &arr) {
+  if(JSON_UNLIKELY(not j.is_array())) {
+    JSON_THROW(type_error::create(302, "type must be array, but is "+
+                                       std::string(j.type_name())));
+  }
+
+  from_json_array_impl(j, arr, priority_tag<2>{});
+}
+
+template<typename BasicJsonType, typename CompatibleObjectType,
+    enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
+void from_json(const BasicJsonType &j, CompatibleObjectType &obj) {
+  if(JSON_UNLIKELY(not j.is_object())) {
+    JSON_THROW(type_error::create(302, "type must be object, but is "+std::string(j.type_name())));
+  }
+
+  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t *>();
+  using value_type = typename CompatibleObjectType::value_type;
+  std::transform(
+      inner_object->begin(), inner_object->end(),
+      std::inserter(obj, obj.begin()),
+      [](typename BasicJsonType::object_t::value_type const &p) {
+        return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
+      });
+}
+
+template<typename BasicJsonType, typename ArithmeticType,
+    enable_if_t<
+        std::is_arithmetic<ArithmeticType>::value and
+        not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
+        not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
+        not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
+        not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
+        int> = 0>
+void from_json(const BasicJsonType &j, ArithmeticType &val) {
+  switch(static_cast<value_t>(j)) {
+    case value_t::number_unsigned: {
+      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
+      break;
+    }
+    case value_t::number_integer: {
+      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
+      break;
+    }
+    case value_t::number_float: {
+      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
+      break;
+    }
+    case value_t::boolean: {
+      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t *>());
+      break;
+    }
+
+    default:
+      JSON_THROW(type_error::create(302, "type must be number, but is "+std::string(j.type_name())));
+  }
+}
+
+template<typename BasicJsonType, typename A1, typename A2>
+void from_json(const BasicJsonType &j, std::pair<A1, A2> &p) {
+  p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
+}
+
+template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence<Idx...>) {
+  t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
+}
+
+template<typename BasicJsonType, typename... Args>
+void from_json(const BasicJsonType &j, std::tuple<Args...> &t) {
+  from_json_tuple_impl(j, t, index_sequence_for<Args...>{});
+}
+
+struct from_json_fn {
+private:
+  template<typename BasicJsonType, typename T>
+  auto call(const BasicJsonType &j, T &val, priority_tag<1>) const
+  noexcept(noexcept(from_json(j, val)))
+  -> decltype(from_json(j, val), void()) {
+    return from_json(j, val);
+  }
+
+  template<typename BasicJsonType, typename T>
+  void call(const BasicJsonType &, T &, priority_tag<0>) const noexcept {
+    static_assert(sizeof(BasicJsonType) == 0,
+                  "could not find from_json() method in T's namespace");
+#ifdef _MSC_VER
+
+    using decayed = uncvref_t<T>;
+        static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
+                      "forcing MSVC stacktrace to show which T we're talking about.");
+#endif
+  }
+
+public:
+  template<typename BasicJsonType, typename T>
+  void operator()(const BasicJsonType &j, T &val) const
+  noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1>{}))) {
+    return call(j, val, priority_tag<1>{});
+  }
+};
+}
+
+namespace {
+constexpr const auto &from_json = detail::static_const<detail::from_json_fn>::value;
+}
+}
+
+namespace nlohmann {
+namespace detail {
+template<value_t>
+struct external_constructor;
+
+template<>
+struct external_constructor<value_t::boolean> {
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept {
+    j.m_type = value_t::boolean;
+    j.m_value = b;
+    j.assert_invariant();
+  }
+};
+
+template<>
+struct external_constructor<value_t::string> {
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s) {
+    j.m_type = value_t::string;
+    j.m_value = s;
+    j.assert_invariant();
+  }
+
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s) {
+    j.m_type = value_t::string;
+    j.m_value = std::move(s);
+    j.assert_invariant();
+  }
+};
+
+template<>
+struct external_constructor<value_t::number_float> {
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept {
+    j.m_type = value_t::number_float;
+    j.m_value = val;
+    j.assert_invariant();
+  }
+};
+
+template<>
+struct external_constructor<value_t::number_unsigned> {
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept {
+    j.m_type = value_t::number_unsigned;
+    j.m_value = val;
+    j.assert_invariant();
+  }
+};
+
+template<>
+struct external_constructor<value_t::number_integer> {
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept {
+    j.m_type = value_t::number_integer;
+    j.m_value = val;
+    j.assert_invariant();
+  }
+};
+
+template<>
+struct external_constructor<value_t::array> {
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr) {
+    j.m_type = value_t::array;
+    j.m_value = arr;
+    j.assert_invariant();
+  }
+
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr) {
+    j.m_type = value_t::array;
+    j.m_value = std::move(arr);
+    j.assert_invariant();
+  }
+
+  template<typename BasicJsonType, typename CompatibleArrayType,
+      enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
+          int> = 0>
+  static void construct(BasicJsonType &j, const CompatibleArrayType &arr) {
+    using std::begin;
+    using std::end;
+    j.m_type = value_t::array;
+    j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
+    j.assert_invariant();
+  }
+
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, const std::vector<bool> &arr) {
+    j.m_type = value_t::array;
+    j.m_value = value_t::array;
+    j.m_value.array->reserve(arr.size());
+    for(const bool x : arr) {
+      j.m_value.array->push_back(x);
+    }
+    j.assert_invariant();
+  }
+
+  template<typename BasicJsonType, typename T,
+      enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+  static void construct(BasicJsonType &j, const std::valarray<T> &arr) {
+    j.m_type = value_t::array;
+    j.m_value = value_t::array;
+    j.m_value.array->resize(arr.size());
+    std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
+    j.assert_invariant();
+  }
+};
+
+template<>
+struct external_constructor<value_t::object> {
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj) {
+    j.m_type = value_t::object;
+    j.m_value = obj;
+    j.assert_invariant();
+  }
+
+  template<typename BasicJsonType>
+  static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj) {
+    j.m_type = value_t::object;
+    j.m_value = std::move(obj);
+    j.assert_invariant();
+  }
+
+  template<typename BasicJsonType, typename CompatibleObjectType,
+      enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
+  static void construct(BasicJsonType &j, const CompatibleObjectType &obj) {
+    using std::begin;
+    using std::end;
+
+    j.m_type = value_t::object;
+    j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
+    j.assert_invariant();
+  }
+};
+
+template<typename BasicJsonType, typename T,
+    enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
+void to_json(BasicJsonType &j, T b) noexcept {
+  external_constructor<value_t::boolean>::construct(j, b);
+}
+
+template<typename BasicJsonType, typename CompatibleString,
+    enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
+void to_json(BasicJsonType &j, const CompatibleString &s) {
+  external_constructor<value_t::string>::construct(j, s);
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType &j, typename BasicJsonType::string_t &&s) {
+  external_constructor<value_t::string>::construct(j, std::move(s));
+}
+
+template<typename BasicJsonType, typename FloatType,
+    enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
+void to_json(BasicJsonType &j, FloatType val) noexcept {
+  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
+}
+
+template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
+    enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
+void to_json(BasicJsonType &j, CompatibleNumberUnsignedType val) noexcept {
+  external_constructor<value_t::number_unsigned>::construct(j,
+                                                            static_cast<typename BasicJsonType::number_unsigned_t>(val));
+}
+
+template<typename BasicJsonType, typename CompatibleNumberIntegerType,
+    enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
+void to_json(BasicJsonType &j, CompatibleNumberIntegerType val) noexcept {
+  external_constructor<value_t::number_integer>::construct(j,
+                                                           static_cast<typename BasicJsonType::number_integer_t>(val));
+}
+
+template<typename BasicJsonType, typename EnumType,
+    enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+void to_json(BasicJsonType &j, EnumType e) noexcept {
+  using underlying_type = typename std::underlying_type<EnumType>::type;
+  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType &j, const std::vector<bool> &e) {
+  external_constructor<value_t::array>::construct(j, e);
+}
+
+template<typename BasicJsonType, typename CompatibleArrayType,
+    enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
+                std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
+        int> = 0>
+void to_json(BasicJsonType &j, const CompatibleArrayType &arr) {
+  external_constructor<value_t::array>::construct(j, arr);
+}
+
+template<typename BasicJsonType, typename T,
+    enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+void to_json(BasicJsonType &j, std::valarray<T> arr) {
+  external_constructor<value_t::array>::construct(j, std::move(arr));
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType &j, typename BasicJsonType::array_t &&arr) {
+  external_constructor<value_t::array>::construct(j, std::move(arr));
+}
+
+template<typename BasicJsonType, typename CompatibleObjectType,
+    enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
+void to_json(BasicJsonType &j, const CompatibleObjectType &obj) {
+  external_constructor<value_t::object>::construct(j, obj);
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType &j, typename BasicJsonType::object_t &&obj) {
+  external_constructor<value_t::object>::construct(j, std::move(obj));
+}
+
+template<typename BasicJsonType, typename T, std::size_t N,
+    enable_if_t<not std::is_constructible<typename BasicJsonType::string_t, T (&)[N]>::value, int> = 0>
+void to_json(BasicJsonType &j, T (&arr)[N]) {
+  external_constructor<value_t::array>::construct(j, arr);
+}
+
+template<typename BasicJsonType, typename... Args>
+void to_json(BasicJsonType &j, const std::pair<Args...> &p) {
+  j = {p.first, p.second};
+}
+
+template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence<Idx...>) {
+  j = {std::get<Idx>(t)...};
+}
+
+template<typename BasicJsonType, typename... Args>
+void to_json(BasicJsonType &j, const std::tuple<Args...> &t) {
+  to_json_tuple_impl(j, t, index_sequence_for<Args...>{});
+}
+
+struct to_json_fn {
+private:
+  template<typename BasicJsonType, typename T>
+  auto call(BasicJsonType &j, T &&val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
+  -> decltype(to_json(j, std::forward<T>(val)), void()) {
+    return to_json(j, std::forward<T>(val));
+  }
+
+  template<typename BasicJsonType, typename T>
+  void call(BasicJsonType &, T &&, priority_tag<0>) const noexcept {
+    static_assert(sizeof(BasicJsonType) == 0,
+                  "could not find to_json() method in T's namespace");
+
+#ifdef _MSC_VER
+
+    using decayed = uncvref_t<T>;
+        static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
+                      "forcing MSVC stacktrace to show which T we're talking about.");
+#endif
+  }
+
+public:
+  template<typename BasicJsonType, typename T>
+  void operator()(BasicJsonType &j, T &&val) const
+  noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1>{}))) {
+    return call(j, std::forward<T>(val), priority_tag<1>{});
+  }
+};
+}
+
+namespace {
+constexpr const auto &to_json = detail::static_const<detail::to_json_fn>::value;
+}
+}
+
+#include <cstring>
+#include <ios>
+#include <istream>
+
+namespace nlohmann {
+namespace detail {
+struct input_adapter_protocol {
+  virtual std::char_traits<char>::int_type get_character() = 0;
+
+  virtual void unget_character() = 0;
+
+  virtual ~input_adapter_protocol() = default;
+};
+
+using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
+
+class input_stream_adapter : public input_adapter_protocol {
+public:
+  ~input_stream_adapter() override {
+    is.clear();
+  }
+
+  explicit input_stream_adapter(std::istream &i)
+      : is(i), sb(*i.rdbuf()) {
+    std::char_traits<char>::int_type c;
+    if((c = get_character()) == 0xEF) {
+      if((c = get_character()) == 0xBB) {
+        if((c = get_character()) == 0xBF) {
+          return;
+        } else if(c != std::char_traits<char>::eof()) {
+          is.unget();
+        }
+        is.putback('\xBB');
+      } else if(c != std::char_traits<char>::eof()) {
+        is.unget();
+      }
+      is.putback('\xEF');
+    } else if(c != std::char_traits<char>::eof()) {
+      is.unget();
+    }
+  }
+
+  input_stream_adapter(const input_stream_adapter &) = delete;
+
+  input_stream_adapter &operator=(input_stream_adapter &) = delete;
+
+  std::char_traits<char>::int_type get_character() override {
+    return sb.sbumpc();
+  }
+
+  void unget_character() override {
+    sb.sungetc();
+  }
+
+private:
+  std::istream &is;
+  std::streambuf &sb;
+};
+
+class input_buffer_adapter : public input_adapter_protocol {
+public:
+  input_buffer_adapter(const char *b, const std::size_t l)
+      : cursor(b), limit(b+l), start(b) {
+    if(l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF') {
+      cursor += 3;
+    }
+  }
+
+  input_buffer_adapter(const input_buffer_adapter &) = delete;
+
+  input_buffer_adapter &operator=(input_buffer_adapter &) = delete;
+
+  std::char_traits<char>::int_type get_character() noexcept override {
+    if(JSON_LIKELY(cursor < limit)) {
+      return std::char_traits<char>::to_int_type(*(cursor++));
+    }
+
+    return std::char_traits<char>::eof();
+  }
+
+  void unget_character() noexcept override {
+    if(JSON_LIKELY(cursor > start)) {
+      --cursor;
+    }
+  }
+
+private:
+  const char *cursor;
+
+  const char *limit;
+
+  const char *start;
+};
+
+class input_adapter {
+public:
+  input_adapter(std::istream &i)
+      : ia(std::make_shared<input_stream_adapter>(i)) {}
+
+  input_adapter(std::istream &&i)
+      : ia(std::make_shared<input_stream_adapter>(i)) {}
+
+  template<typename CharT,
+      typename std::enable_if<
+          std::is_pointer<CharT>::value and
+          std::is_integral<typename std::remove_pointer<CharT>::type>::value and
+          sizeof(typename std::remove_pointer<CharT>::type) == 1,
+          int>::type = 0>
+  input_adapter(CharT b, std::size_t l)
+      : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char *>(b), l)) {}
+
+  template<typename CharT,
+      typename std::enable_if<
+          std::is_pointer<CharT>::value and
+          std::is_integral<typename std::remove_pointer<CharT>::type>::value and
+          sizeof(typename std::remove_pointer<CharT>::type) == 1,
+          int>::type = 0>
+  input_adapter(CharT b)
+      : input_adapter(reinterpret_cast<const char *>(b),
+                      std::strlen(reinterpret_cast<const char *>(b))) {}
+
+  template<class IteratorType,
+      typename std::enable_if<
+          std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
+          int>::type = 0>
+  input_adapter(IteratorType first, IteratorType last) {
+    assert(std::accumulate(
+        first, last, std::pair<bool, int>(true, 0),
+        [&first](std::pair<bool, int> res, decltype(*first) val) {
+          res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
+          return res;
+        }).first);
+
+    static_assert(
+        sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
+        "each element in the iterator range must have the size of 1 byte");
+
+    const auto len = static_cast<size_t>(std::distance(first, last));
+    if(JSON_LIKELY(len > 0)) {
+      ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char *>(&(*first)), len);
+    } else {
+      ia = std::make_shared<input_buffer_adapter>(nullptr, len);
+    }
+  }
+
+  template<class T, std::size_t N>
+  input_adapter(T (&array)[N])
+      : input_adapter(std::begin(array), std::end(array)) {}
+
+  template<class ContiguousContainer, typename
+  std::enable_if<not std::is_pointer<ContiguousContainer>::value and
+                 std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(
+                     std::declval<ContiguousContainer const>()))>::iterator_category>::value,
+      int>::type = 0>
+  input_adapter(const ContiguousContainer &c)
+      : input_adapter(std::begin(c), std::end(c)) {}
+
+  operator input_adapter_t() {
+    return ia;
+  }
+
+private:
+  input_adapter_t ia = nullptr;
+};
+}
+}
+
+#include <clocale>
+#include <cstdlib>
+#include <iomanip>
+#include <sstream>
+
+namespace nlohmann {
+namespace detail {
+template<typename BasicJsonType>
+class lexer {
+  using number_integer_t = typename BasicJsonType::number_integer_t;
+  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+  using number_float_t = typename BasicJsonType::number_float_t;
+  using string_t = typename BasicJsonType::string_t;
+
+public:
+  enum class token_type {
+    uninitialized,
+    literal_true,
+    literal_false,
+    literal_null,
+    value_string,
+    value_unsigned,
+    value_integer,
+    value_float,
+    begin_array,
+    begin_object,
+    end_array,
+    end_object,
+    name_separator,
+    value_separator,
+    parse_error,
+    end_of_input,
+    literal_or_value
+  };
+
+  static const char *token_type_name(const token_type t) noexcept {
+    switch(t) {
+      case token_type::uninitialized:
+        return "<uninitialized>";
+      case token_type::literal_true:
+        return "true literal";
+      case token_type::literal_false:
+        return "false literal";
+      case token_type::literal_null:
+        return "null literal";
+      case token_type::value_string:
+        return "string literal";
+      case lexer::token_type::value_unsigned:
+      case lexer::token_type::value_integer:
+      case lexer::token_type::value_float:
+        return "number literal";
+      case token_type::begin_array:
+        return "'['";
+      case token_type::begin_object:
+        return "'{'";
+      case token_type::end_array:
+        return "']'";
+      case token_type::end_object:
+        return "'}'";
+      case token_type::name_separator:
+        return "':'";
+      case token_type::value_separator:
+        return "','";
+      case token_type::parse_error:
+        return "<parse error>";
+      case token_type::end_of_input:
+        return "end of input";
+      case token_type::literal_or_value:
+        return "'[', '{', or a literal";
+      default:
+        return "unknown token";
+    }
+  }
+
+  explicit lexer(detail::input_adapter_t adapter)
+      : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
+
+  lexer(const lexer &) = delete;
+
+  lexer &operator=(lexer &) = delete;
+
+private:
+  static char get_decimal_point() noexcept {
+    const auto loc = localeconv();
+    assert(loc != nullptr);
+    return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
+  }
+
+  int get_codepoint() {
+    assert(current == 'u');
+    int codepoint = 0;
+
+    const auto factors = {12, 8, 4, 0};
+    for(const auto factor : factors) {
+      get();
+
+      if(current >= '0' and current <= '9') {
+        codepoint += ((current-0x30) << factor);
+      } else if(current >= 'A' and current <= 'F') {
+        codepoint += ((current-0x37) << factor);
+      } else if(current >= 'a' and current <= 'f') {
+        codepoint += ((current-0x57) << factor);
+      } else {
+        return -1;
+      }
+    }
+
+    assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
+    return codepoint;
+  }
+
+  bool next_byte_in_range(std::initializer_list<int> ranges) {
+    assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
+    add(current);
+
+    for(auto range = ranges.begin(); range != ranges.end(); ++range) {
+      get();
+      if(JSON_LIKELY(*range <= current and current <= *(++range))) {
+        add(current);
+      } else {
+        error_message = "invalid string: ill-formed UTF-8 byte";
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  token_type scan_string() {
+    reset();
+
+    assert(current == '\"');
+
+    while(true) {
+      switch(get()) {
+        case std::char_traits<char>::eof(): {
+          error_message = "invalid string: missing closing quote";
+          return token_type::parse_error;
+        }
+
+        case '\"': {
+          return token_type::value_string;
+        }
+
+        case '\\': {
+          switch(get()) {
+            case '\"':
+              add('\"');
+              break;
+
+            case '\\':
+              add('\\');
+              break;
+
+            case '/':
+              add('/');
+              break;
+
+            case 'b':
+              add('\b');
+              break;
+
+            case 'f':
+              add('\f');
+              break;
+
+            case 'n':
+              add('\n');
+              break;
+
+            case 'r':
+              add('\r');
+              break;
+
+            case 't':
+              add('\t');
+              break;
+
+            case 'u': {
+              const int codepoint1 = get_codepoint();
+              int codepoint = codepoint1;
+
+              if(JSON_UNLIKELY(codepoint1 == -1)) {
+                error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+                return token_type::parse_error;
+              }
+
+              if(0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) {
+                if(JSON_LIKELY(get() == '\\' and get() == 'u')) {
+                  const int codepoint2 = get_codepoint();
+
+                  if(JSON_UNLIKELY(codepoint2 == -1)) {
+                    error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+                    return token_type::parse_error;
+                  }
+
+                  if(JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) {
+                    codepoint =
+
+                        (codepoint1 << 10)
+
+                        +codepoint2
+
+                        -0x35FDC00;
+                  } else {
+                    error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
+                    return token_type::parse_error;
+                  }
+                } else {
+                  error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
+                  return token_type::parse_error;
+                }
+              } else {
+                if(JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) {
+                  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
+                  return token_type::parse_error;
+                }
+              }
+
+              assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
+
+              if(codepoint < 0x80) {
+                add(codepoint);
+              } else if(codepoint <= 0x7FF) {
+                add(0xC0 | (codepoint >> 6));
+                add(0x80 | (codepoint & 0x3F));
+              } else if(codepoint <= 0xFFFF) {
+                add(0xE0 | (codepoint >> 12));
+                add(0x80 | ((codepoint >> 6) & 0x3F));
+                add(0x80 | (codepoint & 0x3F));
+              } else {
+                add(0xF0 | (codepoint >> 18));
+                add(0x80 | ((codepoint >> 12) & 0x3F));
+                add(0x80 | ((codepoint >> 6) & 0x3F));
+                add(0x80 | (codepoint & 0x3F));
+              }
+
+              break;
+            }
+
+            default:
+              error_message = "invalid string: forbidden character after backslash";
+              return token_type::parse_error;
+          }
+
+          break;
+        }
+
+        case 0x00:
+        case 0x01:
+        case 0x02:
+        case 0x03:
+        case 0x04:
+        case 0x05:
+        case 0x06:
+        case 0x07:
+        case 0x08:
+        case 0x09:
+        case 0x0A:
+        case 0x0B:
+        case 0x0C:
+        case 0x0D:
+        case 0x0E:
+        case 0x0F:
+        case 0x10:
+        case 0x11:
+        case 0x12:
+        case 0x13:
+        case 0x14:
+        case 0x15:
+        case 0x16:
+        case 0x17:
+        case 0x18:
+        case 0x19:
+        case 0x1A:
+        case 0x1B:
+        case 0x1C:
+        case 0x1D:
+        case 0x1E:
+        case 0x1F: {
+          error_message = "invalid string: control character must be escaped";
+          return token_type::parse_error;
+        }
+
+        case 0x20:
+        case 0x21:
+        case 0x23:
+        case 0x24:
+        case 0x25:
+        case 0x26:
+        case 0x27:
+        case 0x28:
+        case 0x29:
+        case 0x2A:
+        case 0x2B:
+        case 0x2C:
+        case 0x2D:
+        case 0x2E:
+        case 0x2F:
+        case 0x30:
+        case 0x31:
+        case 0x32:
+        case 0x33:
+        case 0x34:
+        case 0x35:
+        case 0x36:
+        case 0x37:
+        case 0x38:
+        case 0x39:
+        case 0x3A:
+        case 0x3B:
+        case 0x3C:
+        case 0x3D:
+        case 0x3E:
+        case 0x3F:
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+        case 0x48:
+        case 0x49:
+        case 0x4A:
+        case 0x4B:
+        case 0x4C:
+        case 0x4D:
+        case 0x4E:
+        case 0x4F:
+        case 0x50:
+        case 0x51:
+        case 0x52:
+        case 0x53:
+        case 0x54:
+        case 0x55:
+        case 0x56:
+        case 0x57:
+        case 0x58:
+        case 0x59:
+        case 0x5A:
+        case 0x5B:
+        case 0x5D:
+        case 0x5E:
+        case 0x5F:
+        case 0x60:
+        case 0x61:
+        case 0x62:
+        case 0x63:
+        case 0x64:
+        case 0x65:
+        case 0x66:
+        case 0x67:
+        case 0x68:
+        case 0x69:
+        case 0x6A:
+        case 0x6B:
+        case 0x6C:
+        case 0x6D:
+        case 0x6E:
+        case 0x6F:
+        case 0x70:
+        case 0x71:
+        case 0x72:
+        case 0x73:
+        case 0x74:
+        case 0x75:
+        case 0x76:
+        case 0x77:
+        case 0x78:
+        case 0x79:
+        case 0x7A:
+        case 0x7B:
+        case 0x7C:
+        case 0x7D:
+        case 0x7E:
+        case 0x7F: {
+          add(current);
+          break;
+        }
+
+        case 0xC2:
+        case 0xC3:
+        case 0xC4:
+        case 0xC5:
+        case 0xC6:
+        case 0xC7:
+        case 0xC8:
+        case 0xC9:
+        case 0xCA:
+        case 0xCB:
+        case 0xCC:
+        case 0xCD:
+        case 0xCE:
+        case 0xCF:
+        case 0xD0:
+        case 0xD1:
+        case 0xD2:
+        case 0xD3:
+        case 0xD4:
+        case 0xD5:
+        case 0xD6:
+        case 0xD7:
+        case 0xD8:
+        case 0xD9:
+        case 0xDA:
+        case 0xDB:
+        case 0xDC:
+        case 0xDD:
+        case 0xDE:
+        case 0xDF: {
+          if(JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF}))) {
+            return token_type::parse_error;
+          }
+          break;
+        }
+
+        case 0xE0: {
+          if(JSON_UNLIKELY(not(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) {
+            return token_type::parse_error;
+          }
+          break;
+        }
+
+        case 0xE1:
+        case 0xE2:
+        case 0xE3:
+        case 0xE4:
+        case 0xE5:
+        case 0xE6:
+        case 0xE7:
+        case 0xE8:
+        case 0xE9:
+        case 0xEA:
+        case 0xEB:
+        case 0xEC:
+        case 0xEE:
+        case 0xEF: {
+          if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) {
+            return token_type::parse_error;
+          }
+          break;
+        }
+
+        case 0xED: {
+          if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) {
+            return token_type::parse_error;
+          }
+          break;
+        }
+
+        case 0xF0: {
+          if(JSON_UNLIKELY(not(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
+            return token_type::parse_error;
+          }
+          break;
+        }
+
+        case 0xF1:
+        case 0xF2:
+        case 0xF3: {
+          if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
+            return token_type::parse_error;
+          }
+          break;
+        }
+
+        case 0xF4: {
+          if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) {
+            return token_type::parse_error;
+          }
+          break;
+        }
+
+        default: {
+          error_message = "invalid string: ill-formed UTF-8 byte";
+          return token_type::parse_error;
+        }
+      }
+    }
+  }
+
+  static void strtof(float &f, const char *str, char **endptr) noexcept {
+    f = std::strtof(str, endptr);
+  }
+
+  static void strtof(double &f, const char *str, char **endptr) noexcept {
+    f = std::strtod(str, endptr);
+  }
+
+  static void strtof(long double &f, const char *str, char **endptr) noexcept {
+    f = std::strtold(str, endptr);
+  }
+
+  token_type scan_number() {
+    reset();
+
+    token_type number_type = token_type::value_unsigned;
+
+    switch(current) {
+      case '-': {
+        add(current);
+        goto scan_number_minus;
+      }
+
+      case '0': {
+        add(current);
+        goto scan_number_zero;
+      }
+
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9': {
+        add(current);
+        goto scan_number_any1;
+      }
+
+      default: {
+        assert(false);
+      }
+    }
+
+    scan_number_minus:
+
+    number_type = token_type::value_integer;
+    switch(get()) {
+      case '0': {
+        add(current);
+        goto scan_number_zero;
+      }
+
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9': {
+        add(current);
+        goto scan_number_any1;
+      }
+
+      default: {
+        error_message = "invalid number; expected digit after '-'";
+        return token_type::parse_error;
+      }
+    }
+
+    scan_number_zero:
+
+    switch(get()) {
+      case '.': {
+        add(decimal_point_char);
+        goto scan_number_decimal1;
+      }
+
+      case 'e':
+      case 'E': {
+        add(current);
+        goto scan_number_exponent;
+      }
+
+      default:
+        goto scan_number_done;
+    }
+
+    scan_number_any1:
+
+    switch(get()) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9': {
+        add(current);
+        goto scan_number_any1;
+      }
+
+      case '.': {
+        add(decimal_point_char);
+        goto scan_number_decimal1;
+      }
+
+      case 'e':
+      case 'E': {
+        add(current);
+        goto scan_number_exponent;
+      }
+
+      default:
+        goto scan_number_done;
+    }
+
+    scan_number_decimal1:
+
+    number_type = token_type::value_float;
+    switch(get()) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9': {
+        add(current);
+        goto scan_number_decimal2;
+      }
+
+      default: {
+        error_message = "invalid number; expected digit after '.'";
+        return token_type::parse_error;
+      }
+    }
+
+    scan_number_decimal2:
+
+    switch(get()) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9': {
+        add(current);
+        goto scan_number_decimal2;
+      }
+
+      case 'e':
+      case 'E': {
+        add(current);
+        goto scan_number_exponent;
+      }
+
+      default:
+        goto scan_number_done;
+    }
+
+    scan_number_exponent:
+
+    number_type = token_type::value_float;
+    switch(get()) {
+      case '+':
+      case '-': {
+        add(current);
+        goto scan_number_sign;
+      }
+
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9': {
+        add(current);
+        goto scan_number_any2;
+      }
+
+      default: {
+        error_message =
+            "invalid number; expected '+', '-', or digit after exponent";
+        return token_type::parse_error;
+      }
+    }
+
+    scan_number_sign:
+
+    switch(get()) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9': {
+        add(current);
+        goto scan_number_any2;
+      }
+
+      default: {
+        error_message = "invalid number; expected digit after exponent sign";
+        return token_type::parse_error;
+      }
+    }
+
+    scan_number_any2:
+
+    switch(get()) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9': {
+        add(current);
+        goto scan_number_any2;
+      }
+
+      default:
+        goto scan_number_done;
+    }
+
+    scan_number_done:
+
+    unget();
+
+    char *endptr = nullptr;
+    errno = 0;
+
+    if(number_type == token_type::value_unsigned) {
+      const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
+
+      assert(endptr == token_buffer.data()+token_buffer.size());
+
+      if(errno == 0) {
+        value_unsigned = static_cast<number_unsigned_t>(x);
+        if(value_unsigned == x) {
+          return token_type::value_unsigned;
+        }
+      }
+    } else if(number_type == token_type::value_integer) {
+      const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
+
+      assert(endptr == token_buffer.data()+token_buffer.size());
+
+      if(errno == 0) {
+        value_integer = static_cast<number_integer_t>(x);
+        if(value_integer == x) {
+          return token_type::value_integer;
+        }
+      }
+    }
+
+    strtof(value_float, token_buffer.data(), &endptr);
+
+    assert(endptr == token_buffer.data()+token_buffer.size());
+
+    return token_type::value_float;
+  }
+
+  token_type scan_literal(const char *literal_text, const std::size_t length,
+                          token_type return_type) {
+    assert(current == literal_text[0]);
+    for(std::size_t i = 1; i < length; ++i) {
+      if(JSON_UNLIKELY(get() != literal_text[i])) {
+        error_message = "invalid literal";
+        return token_type::parse_error;
+      }
+    }
+    return return_type;
+  }
+
+  void reset() noexcept {
+    token_buffer.clear();
+    token_string.clear();
+    token_string.push_back(std::char_traits<char>::to_char_type(current));
+  }
+
+  std::char_traits<char>::int_type get() {
+    ++chars_read;
+    current = ia->get_character();
+    if(JSON_LIKELY(current != std::char_traits<char>::eof())) {
+      token_string.push_back(std::char_traits<char>::to_char_type(current));
+    }
+    return current;
+  }
+
+  void unget() {
+    --chars_read;
+    if(JSON_LIKELY(current != std::char_traits<char>::eof())) {
+      ia->unget_character();
+      assert(token_string.size() != 0);
+      token_string.pop_back();
+    }
+  }
+
+  void add(int c) {
+    token_buffer.push_back(std::char_traits<char>::to_char_type(c));
+  }
+
+public:
+  constexpr number_integer_t get_number_integer() const noexcept {
+    return value_integer;
+  }
+
+  constexpr number_unsigned_t get_number_unsigned() const noexcept {
+    return value_unsigned;
+  }
+
+  constexpr number_float_t get_number_float() const noexcept {
+    return value_float;
+  }
+
+  string_t &&move_string() {
+    return std::move(token_buffer);
+  }
+
+  constexpr std::size_t get_position() const noexcept {
+    return chars_read;
+  }
+
+  std::string get_token_string() const {
+    std::string result;
+    for(const auto c : token_string) {
+      if('\x00' <= c and c <= '\x1F') {
+        std::stringstream ss;
+        ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
+           << std::hex << static_cast<int>(c) << ">";
+        result += ss.str();
+      } else {
+        result.push_back(c);
+      }
+    }
+
+    return result;
+  }
+
+  constexpr const char *get_error_message() const noexcept {
+    return error_message;
+  }
+
+  token_type scan() {
+    do {
+      get();
+    } while(current == ' ' or current == '\t' or current == '\n' or current == '\r');
+
+    switch(current) {
+      case '[':
+        return token_type::begin_array;
+      case ']':
+        return token_type::end_array;
+      case '{':
+        return token_type::begin_object;
+      case '}':
+        return token_type::end_object;
+      case ':':
+        return token_type::name_separator;
+      case ',':
+        return token_type::value_separator;
+
+      case 't':
+        return scan_literal("true", 4, token_type::literal_true);
+      case 'f':
+        return scan_literal("false", 5, token_type::literal_false);
+      case 'n':
+        return scan_literal("null", 4, token_type::literal_null);
+
+      case '\"':
+        return scan_string();
+
+      case '-':
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        return scan_number();
+
+      case '\0':
+      case std::char_traits<char>::eof():
+        return token_type::end_of_input;
+
+      default:
+        error_message = "invalid literal";
+        return token_type::parse_error;
+    }
+  }
+
+private:
+  detail::input_adapter_t ia = nullptr;
+
+  std::char_traits<char>::int_type current = std::char_traits<char>::eof();
+
+  std::size_t chars_read = 0;
+
+  std::vector<char> token_string{};
+
+  string_t token_buffer{};
+
+  const char *error_message = "";
+
+  number_integer_t value_integer = 0;
+  number_unsigned_t value_unsigned = 0;
+  number_float_t value_float = 0;
+
+  const char decimal_point_char = '.';
+};
+}
+}
+
+#include <cmath>
+
+namespace nlohmann {
+namespace detail {
+template<typename BasicJsonType>
+class parser {
+  using number_integer_t = typename BasicJsonType::number_integer_t;
+  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+  using number_float_t = typename BasicJsonType::number_float_t;
+  using string_t = typename BasicJsonType::string_t;
+  using lexer_t = lexer<BasicJsonType>;
+  using token_type = typename lexer_t::token_type;
+
+public:
+  enum class parse_event_t : uint8_t {
+    object_start,
+
+    object_end,
+
+    array_start,
+
+    array_end,
+
+    key,
+
+    value
+  };
+
+  using parser_callback_t =
+  std::function<bool(int depth, parse_event_t event, BasicJsonType &parsed)>;
+
+  explicit parser(detail::input_adapter_t adapter,
+                  const parser_callback_t cb = nullptr,
+                  const bool allow_exceptions_ = true)
+      : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_) {}
+
+  void parse(const bool strict, BasicJsonType &result) {
+    get_token();
+
+    parse_internal(true, result);
+    result.assert_invariant();
+
+    if(strict) {
+      get_token();
+      expect(token_type::end_of_input);
+    }
+
+    if(errored) {
+      result = value_t::discarded;
+      return;
+    }
+
+    if(result.is_discarded()) {
+      result = nullptr;
+    }
+  }
+
+  bool accept(const bool strict = true) {
+    get_token();
+
+    if(not accept_internal()) {
+      return false;
+    }
+
+    return not strict or (get_token() == token_type::end_of_input);
+  }
+
+private:
+  void parse_internal(bool keep, BasicJsonType &result) {
+    assert(not errored);
+
+    if(not result.is_discarded()) {
+      result.m_value.destroy(result.m_type);
+      result.m_type = value_t::discarded;
+    }
+
+    switch(last_token) {
+      case token_type::begin_object: {
+        if(keep) {
+          if(callback) {
+            keep = callback(depth++, parse_event_t::object_start, result);
+          }
+
+          if(not callback or keep) {
+            result.m_type = value_t::object;
+            result.m_value = value_t::object;
+          }
+        }
+
+        get_token();
+
+        if(last_token == token_type::end_object) {
+          if(keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
+            result.m_value.destroy(result.m_type);
+            result.m_type = value_t::discarded;
+          }
+          break;
+        }
+
+        string_t key;
+        BasicJsonType value;
+        while(true) {
+          if(not expect(token_type::value_string)) {
+            return;
+          }
+          key = m_lexer.move_string();
+
+          bool keep_tag = false;
+          if(keep) {
+            if(callback) {
+              BasicJsonType k(key);
+              keep_tag = callback(depth, parse_event_t::key, k);
+            } else {
+              keep_tag = true;
+            }
+          }
+
+          get_token();
+          if(not expect(token_type::name_separator)) {
+            return;
+          }
+
+          get_token();
+          value.m_value.destroy(value.m_type);
+          value.m_type = value_t::discarded;
+          parse_internal(keep, value);
+
+          if(JSON_UNLIKELY(errored)) {
+            return;
+          }
+
+          if(keep and keep_tag and not value.is_discarded()) {
+            result.m_value.object->emplace(std::move(key), std::move(value));
+          }
+
+          get_token();
+          if(last_token == token_type::value_separator) {
+            get_token();
+            continue;
+          }
+
+          if(not expect(token_type::end_object)) {
+            return;
+          }
+          break;
+        }
+
+        if(keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
+          result.m_value.destroy(result.m_type);
+          result.m_type = value_t::discarded;
+        }
+        break;
+      }
+
+      case token_type::begin_array: {
+        if(keep) {
+          if(callback) {
+            keep = callback(depth++, parse_event_t::array_start, result);
+          }
+
+          if(not callback or keep) {
+            result.m_type = value_t::array;
+            result.m_value = value_t::array;
+          }
+        }
+
+        get_token();
+
+        if(last_token == token_type::end_array) {
+          if(callback and not callback(--depth, parse_event_t::array_end, result)) {
+            result.m_value.destroy(result.m_type);
+            result.m_type = value_t::discarded;
+          }
+          break;
+        }
+
+        BasicJsonType value;
+        while(true) {
+          value.m_value.destroy(value.m_type);
+          value.m_type = value_t::discarded;
+          parse_internal(keep, value);
+
+          if(JSON_UNLIKELY(errored)) {
+            return;
+          }
+
+          if(keep and not value.is_discarded()) {
+            result.m_value.array->push_back(std::move(value));
+          }
+
+          get_token();
+          if(last_token == token_type::value_separator) {
+            get_token();
+            continue;
+          }
+
+          if(not expect(token_type::end_array)) {
+            return;
+          }
+          break;
+        }
+
+        if(keep and callback and not callback(--depth, parse_event_t::array_end, result)) {
+          result.m_value.destroy(result.m_type);
+          result.m_type = value_t::discarded;
+        }
+        break;
+      }
+
+      case token_type::literal_null: {
+        result.m_type = value_t::null;
+        break;
+      }
+
+      case token_type::value_string: {
+        result.m_type = value_t::string;
+        result.m_value = m_lexer.move_string();
+        break;
+      }
+
+      case token_type::literal_true: {
+        result.m_type = value_t::boolean;
+        result.m_value = true;
+        break;
+      }
+
+      case token_type::literal_false: {
+        result.m_type = value_t::boolean;
+        result.m_value = false;
+        break;
+      }
+
+      case token_type::value_unsigned: {
+        result.m_type = value_t::number_unsigned;
+        result.m_value = m_lexer.get_number_unsigned();
+        break;
+      }
+
+      case token_type::value_integer: {
+        result.m_type = value_t::number_integer;
+        result.m_value = m_lexer.get_number_integer();
+        break;
+      }
+
+      case token_type::value_float: {
+        result.m_type = value_t::number_float;
+        result.m_value = m_lexer.get_number_float();
+
+        if(JSON_UNLIKELY(not std::isfinite(result.m_value.number_float))) {
+          if(allow_exceptions) {
+            JSON_THROW(out_of_range::create(406, "number overflow parsing '"+
+                                                 m_lexer.get_token_string()+"'"));
+          }
+          expect(token_type::uninitialized);
+        }
+        break;
+      }
+
+      case token_type::parse_error: {
+        if(not expect(token_type::uninitialized)) {
+          return;
+        }
+        break;
+      }
+
+      default: {
+        if(not expect(token_type::literal_or_value)) {
+          return;
+        }
+        break;
+      }
+    }
+
+    if(keep and callback and not callback(depth, parse_event_t::value, result)) {
+      result.m_value.destroy(result.m_type);
+      result.m_type = value_t::discarded;
+    }
+  }
+
+  bool accept_internal() {
+    switch(last_token) {
+      case token_type::begin_object: {
+        get_token();
+
+        if(last_token == token_type::end_object) {
+          return true;
+        }
+
+        while(true) {
+          if(last_token != token_type::value_string) {
+            return false;
+          }
+
+          get_token();
+          if(last_token != token_type::name_separator) {
+            return false;
+          }
+
+          get_token();
+          if(not accept_internal()) {
+            return false;
+          }
+
+          get_token();
+          if(last_token == token_type::value_separator) {
+            get_token();
+            continue;
+          }
+
+          return (last_token == token_type::end_object);
+        }
+      }
+
+      case token_type::begin_array: {
+        get_token();
+
+        if(last_token == token_type::end_array) {
+          return true;
+        }
+
+        while(true) {
+          if(not accept_internal()) {
+            return false;
+          }
+
+          get_token();
+          if(last_token == token_type::value_separator) {
+            get_token();
+            continue;
+          }
+
+          return (last_token == token_type::end_array);
+        }
+      }
+
+      case token_type::value_float: {
+        return std::isfinite(m_lexer.get_number_float());
+      }
+
+      case token_type::literal_false:
+      case token_type::literal_null:
+      case token_type::literal_true:
+      case token_type::value_integer:
+      case token_type::value_string:
+      case token_type::value_unsigned:
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
+  token_type get_token() {
+    return (last_token = m_lexer.scan());
+  }
+
+  bool expect(token_type t) {
+    if(JSON_UNLIKELY(t != last_token)) {
+      errored = true;
+      expected = t;
+      if(allow_exceptions) {
+        throw_exception();
+      } else {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  [[noreturn]] void throw_exception() const {
+    std::string error_msg = "syntax error - ";
+    if(last_token == token_type::parse_error) {
+      error_msg += std::string(m_lexer.get_error_message())+"; last read: '"+
+                   m_lexer.get_token_string()+"'";
+    } else {
+      error_msg += "unexpected "+std::string(lexer_t::token_type_name(last_token));
+    }
+
+    if(expected != token_type::uninitialized) {
+      error_msg += "; expected "+std::string(lexer_t::token_type_name(expected));
+    }
+
+    JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
+  }
+
+private:
+  int depth = 0;
+
+  const parser_callback_t callback = nullptr;
+
+  token_type last_token = token_type::uninitialized;
+
+  lexer_t m_lexer;
+
+  bool errored = false;
+
+  token_type expected = token_type::uninitialized;
+
+  const bool allow_exceptions = true;
+};
+}
+}
+
+namespace nlohmann {
+namespace detail {
+class primitive_iterator_t {
+private:
+  using difference_type = std::ptrdiff_t;
+  static constexpr difference_type begin_value = 0;
+  static constexpr difference_type end_value = begin_value+1;
+
+  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
+
+public:
+  constexpr difference_type get_value() const noexcept {
+    return m_it;
+  }
+
+  void set_begin() noexcept {
+    m_it = begin_value;
+  }
+
+  void set_end() noexcept {
+    m_it = end_value;
+  }
+
+  constexpr bool is_begin() const noexcept {
+    return m_it == begin_value;
+  }
+
+  constexpr bool is_end() const noexcept {
+    return m_it == end_value;
+  }
+
+  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
+    return lhs.m_it == rhs.m_it;
+  }
+
+  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
+    return lhs.m_it < rhs.m_it;
+  }
+
+  primitive_iterator_t operator+(difference_type n) noexcept {
+    auto result = *this;
+    result += n;
+    return result;
+  }
+
+  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
+    return lhs.m_it-rhs.m_it;
+  }
+
+  primitive_iterator_t &operator++() noexcept {
+    ++m_it;
+    return *this;
+  }
+
+  primitive_iterator_t const operator++(int) noexcept {
+    auto result = *this;
+    m_it++;
+    return result;
+  }
+
+  primitive_iterator_t &operator--() noexcept {
+    --m_it;
+    return *this;
+  }
+
+  primitive_iterator_t const operator--(int) noexcept {
+    auto result = *this;
+    m_it--;
+    return result;
+  }
+
+  primitive_iterator_t &operator+=(difference_type n) noexcept {
+    m_it += n;
+    return *this;
+  }
+
+  primitive_iterator_t &operator-=(difference_type n) noexcept {
+    m_it -= n;
+    return *this;
+  }
+};
+}
+}
+
+namespace nlohmann {
+namespace detail {
+template<typename BasicJsonType>
+struct internal_iterator {
+  typename BasicJsonType::object_t::iterator object_iterator{};
+
+  typename BasicJsonType::array_t::iterator array_iterator{};
+
+  primitive_iterator_t primitive_iterator{};
+};
+}
+}
+
+namespace nlohmann {
+namespace detail {
+template<typename IteratorType>
+class iteration_proxy;
+
+template<typename BasicJsonType>
+class iter_impl {
+  friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
+  friend BasicJsonType;
+  friend iteration_proxy<iter_impl>;
+
+  using object_t = typename BasicJsonType::object_t;
+  using array_t = typename BasicJsonType::array_t;
+
+  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
+                "iter_impl only accepts (const) basic_json");
+
+public:
+  using iterator_category = std::bidirectional_iterator_tag;
+
+  using value_type = typename BasicJsonType::value_type;
+
+  using difference_type = typename BasicJsonType::difference_type;
+
+  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
+      typename BasicJsonType::const_pointer,
+      typename BasicJsonType::pointer>::type;
+
+  using reference =
+  typename std::conditional<std::is_const<BasicJsonType>::value,
+      typename BasicJsonType::const_reference,
+      typename BasicJsonType::reference>::type;
+
+  iter_impl() = default;
+
+  explicit iter_impl(pointer object) noexcept : m_object(object) {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object: {
+        m_it.object_iterator = typename object_t::iterator();
+        break;
+      }
+
+      case value_t::array: {
+        m_it.array_iterator = typename array_t::iterator();
+        break;
+      }
+
+      default: {
+        m_it.primitive_iterator = primitive_iterator_t();
+        break;
+      }
+    }
+  }
+
+  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept
+      : m_object(other.m_object), m_it(other.m_it) {}
+
+  iter_impl &operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept {
+    m_object = other.m_object;
+    m_it = other.m_it;
+    return *this;
+  }
+
+private:
+  void set_begin() noexcept {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object: {
+        m_it.object_iterator = m_object->m_value.object->begin();
+        break;
+      }
+
+      case value_t::array: {
+        m_it.array_iterator = m_object->m_value.array->begin();
+        break;
+      }
+
+      case value_t::null: {
+        m_it.primitive_iterator.set_end();
+        break;
+      }
+
+      default: {
+        m_it.primitive_iterator.set_begin();
+        break;
+      }
+    }
+  }
+
+  void set_end() noexcept {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object: {
+        m_it.object_iterator = m_object->m_value.object->end();
+        break;
+      }
+
+      case value_t::array: {
+        m_it.array_iterator = m_object->m_value.array->end();
+        break;
+      }
+
+      default: {
+        m_it.primitive_iterator.set_end();
+        break;
+      }
+    }
+  }
+
+public:
+  reference operator*() const {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object: {
+        assert(m_it.object_iterator != m_object->m_value.object->end());
+        return m_it.object_iterator->second;
+      }
+
+      case value_t::array: {
+        assert(m_it.array_iterator != m_object->m_value.array->end());
+        return *m_it.array_iterator;
+      }
+
+      case value_t::null:
+        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+
+      default: {
+        if(JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
+          return *m_object;
+        }
+
+        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+      }
+    }
+  }
+
+  pointer operator->() const {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object: {
+        assert(m_it.object_iterator != m_object->m_value.object->end());
+        return &(m_it.object_iterator->second);
+      }
+
+      case value_t::array: {
+        assert(m_it.array_iterator != m_object->m_value.array->end());
+        return &*m_it.array_iterator;
+      }
+
+      default: {
+        if(JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
+          return m_object;
+        }
+
+        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+      }
+    }
+  }
+
+  iter_impl const operator++(int) {
+    auto result = *this;
+    ++(*this);
+    return result;
+  }
+
+  iter_impl &operator++() {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object: {
+        std::advance(m_it.object_iterator, 1);
+        break;
+      }
+
+      case value_t::array: {
+        std::advance(m_it.array_iterator, 1);
+        break;
+      }
+
+      default: {
+        ++m_it.primitive_iterator;
+        break;
+      }
+    }
+
+    return *this;
+  }
+
+  iter_impl const operator--(int) {
+    auto result = *this;
+    --(*this);
+    return result;
+  }
+
+  iter_impl &operator--() {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object: {
+        std::advance(m_it.object_iterator, -1);
+        break;
+      }
+
+      case value_t::array: {
+        std::advance(m_it.array_iterator, -1);
+        break;
+      }
+
+      default: {
+        --m_it.primitive_iterator;
+        break;
+      }
+    }
+
+    return *this;
+  }
+
+  bool operator==(const iter_impl &other) const {
+    if(JSON_UNLIKELY(m_object != other.m_object)) {
+      JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+    }
+
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object:
+        return (m_it.object_iterator == other.m_it.object_iterator);
+
+      case value_t::array:
+        return (m_it.array_iterator == other.m_it.array_iterator);
+
+      default:
+        return (m_it.primitive_iterator == other.m_it.primitive_iterator);
+    }
+  }
+
+  bool operator!=(const iter_impl &other) const {
+    return not operator==(other);
+  }
+
+  bool operator<(const iter_impl &other) const {
+    if(JSON_UNLIKELY(m_object != other.m_object)) {
+      JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+    }
+
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object:
+        JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
+
+      case value_t::array:
+        return (m_it.array_iterator < other.m_it.array_iterator);
+
+      default:
+        return (m_it.primitive_iterator < other.m_it.primitive_iterator);
+    }
+  }
+
+  bool operator<=(const iter_impl &other) const {
+    return not other.operator<(*this);
+  }
+
+  bool operator>(const iter_impl &other) const {
+    return not operator<=(other);
+  }
+
+  bool operator>=(const iter_impl &other) const {
+    return not operator<(other);
+  }
+
+  iter_impl &operator+=(difference_type i) {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object:
+        JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+
+      case value_t::array: {
+        std::advance(m_it.array_iterator, i);
+        break;
+      }
+
+      default: {
+        m_it.primitive_iterator += i;
+        break;
+      }
+    }
+
+    return *this;
+  }
+
+  iter_impl &operator-=(difference_type i) {
+    return operator+=(-i);
+  }
+
+  iter_impl operator+(difference_type i) const {
+    auto result = *this;
+    result += i;
+    return result;
+  }
+
+  friend iter_impl operator+(difference_type i, const iter_impl &it) {
+    auto result = it;
+    result += i;
+    return result;
+  }
+
+  iter_impl operator-(difference_type i) const {
+    auto result = *this;
+    result -= i;
+    return result;
+  }
+
+  difference_type operator-(const iter_impl &other) const {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object:
+        JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+
+      case value_t::array:
+        return m_it.array_iterator-other.m_it.array_iterator;
+
+      default:
+        return m_it.primitive_iterator-other.m_it.primitive_iterator;
+    }
+  }
+
+  reference operator[](difference_type n) const {
+    assert(m_object != nullptr);
+
+    switch(m_object->m_type) {
+      case value_t::object:
+        JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
+
+      case value_t::array:
+        return *std::next(m_it.array_iterator, n);
+
+      case value_t::null:
+        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+
+      default: {
+        if(JSON_LIKELY(m_it.primitive_iterator.get_value() == -n)) {
+          return *m_object;
+        }
+
+        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+      }
+    }
+  }
+
+  typename object_t::key_type key() const {
+    assert(m_object != nullptr);
+
+    if(JSON_LIKELY(m_object->is_object())) {
+      return m_it.object_iterator->first;
+    }
+
+    JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
+  }
+
+  reference value() const {
+    return operator*();
+  }
+
+private:
+  pointer m_object = nullptr;
+
+  internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
+};
+}
+}
+
+namespace nlohmann {
+namespace detail {
+template<typename IteratorType>
+class iteration_proxy {
+private:
+  class iteration_proxy_internal {
+  private:
+    IteratorType anchor;
+
+    std::size_t array_index = 0;
+
+  public:
+    explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
+
+    iteration_proxy_internal &operator*() {
+      return *this;
+    }
+
+    iteration_proxy_internal &operator++() {
+      ++anchor;
+      ++array_index;
+
+      return *this;
+    }
+
+    bool operator!=(const iteration_proxy_internal &o) const noexcept {
+      return anchor != o.anchor;
+    }
+
+    std::string key() const {
+      assert(anchor.m_object != nullptr);
+
+      switch(anchor.m_object->type()) {
+        case value_t::array:
+          return std::to_string(array_index);
+
+        case value_t::object:
+          return anchor.key();
+
+        default:
+          return "";
+      }
+    }
+
+    typename IteratorType::reference value() const {
+      return anchor.value();
+    }
+  };
+
+  typename IteratorType::reference container;
+
+public:
+  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
+      : container(cont) {}
+
+  iteration_proxy_internal begin() noexcept {
+    return iteration_proxy_internal(container.begin());
+  }
+
+  iteration_proxy_internal end() noexcept {
+    return iteration_proxy_internal(container.end());
+  }
+};
+}
+}
+
+namespace nlohmann {
+namespace detail {
+template<typename Base>
+class json_reverse_iterator : public std::reverse_iterator<Base> {
+public:
+  using difference_type = std::ptrdiff_t;
+
+  using base_iterator = std::reverse_iterator<Base>;
+
+  using reference = typename Base::reference;
+
+  json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
+      : base_iterator(it) {}
+
+  json_reverse_iterator(const base_iterator &it) noexcept : base_iterator(it) {}
+
+  json_reverse_iterator const operator++(int) {
+    return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
+  }
+
+  json_reverse_iterator &operator++() {
+    return static_cast<json_reverse_iterator &>(base_iterator::operator++());
+  }
+
+  json_reverse_iterator const operator--(int) {
+    return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
+  }
+
+  json_reverse_iterator &operator--() {
+    return static_cast<json_reverse_iterator &>(base_iterator::operator--());
+  }
+
+  json_reverse_iterator &operator+=(difference_type i) {
+    return static_cast<json_reverse_iterator &>(base_iterator::operator+=(i));
+  }
+
+  json_reverse_iterator operator+(difference_type i) const {
+    return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
+  }
+
+  json_reverse_iterator operator-(difference_type i) const {
+    return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
+  }
+
+  difference_type operator-(const json_reverse_iterator &other) const {
+    return base_iterator(*this)-base_iterator(other);
+  }
+
+  reference operator[](difference_type n) const {
+    return *(this->operator+(n));
+  }
+
+  auto key() const -> decltype(std::declval<Base>().key()) {
+    auto it = --this->base();
+    return it.key();
+  }
+
+  reference value() const {
+    auto it = --this->base();
+    return it.operator*();
+  }
+};
+}
+}
+
+#include <ostream>
+
+namespace nlohmann {
+namespace detail {
+template<typename CharType>
+struct output_adapter_protocol {
+  virtual void write_character(CharType c) = 0;
+
+  virtual void write_characters(const CharType *s, std::size_t length) = 0;
+
+  virtual ~output_adapter_protocol() = default;
+};
+
+template<typename CharType>
+using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
+
+template<typename CharType>
+class output_vector_adapter : public output_adapter_protocol<CharType> {
+public:
+  explicit output_vector_adapter(std::vector<CharType> &vec) : v(vec) {}
+
+  void write_character(CharType c) override {
+    v.push_back(c);
+  }
+
+  void write_characters(const CharType *s, std::size_t length) override {
+    std::copy(s, s+length, std::back_inserter(v));
+  }
+
+private:
+  std::vector<CharType> &v;
+};
+
+template<typename CharType>
+class output_stream_adapter : public output_adapter_protocol<CharType> {
+public:
+  explicit output_stream_adapter(std::basic_ostream<CharType> &s) : stream(s) {}
+
+  void write_character(CharType c) override {
+    stream.put(c);
+  }
+
+  void write_characters(const CharType *s, std::size_t length) override {
+    stream.write(s, static_cast<std::streamsize>(length));
+  }
+
+private:
+  std::basic_ostream<CharType> &stream;
+};
+
+template<typename CharType, typename StringType = std::basic_string<CharType>>
+class output_string_adapter : public output_adapter_protocol<CharType> {
+public:
+  explicit output_string_adapter(StringType &s) : str(s) {}
+
+  void write_character(CharType c) override {
+    str.push_back(c);
+  }
+
+  void write_characters(const CharType *s, std::size_t length) override {
+    str.append(s, length);
+  }
+
+private:
+  StringType &str;
+};
+
+template<typename CharType, typename StringType = std::basic_string<CharType>>
+class output_adapter {
+public:
+  output_adapter(std::vector<CharType> &vec)
+      : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
+
+  output_adapter(std::basic_ostream<CharType> &s)
+      : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
+
+  output_adapter(StringType &s)
+      : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
+
+  operator output_adapter_t<CharType>() {
+    return oa;
+  }
+
+private:
+  output_adapter_t<CharType> oa = nullptr;
+};
+}
+}
+
+namespace nlohmann {
+namespace detail {
+template<typename BasicJsonType>
+class binary_reader {
+  using number_integer_t = typename BasicJsonType::number_integer_t;
+  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+  using string_t = typename BasicJsonType::string_t;
+
+public:
+  explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter)) {
+    assert(ia);
+  }
+
+  BasicJsonType parse_cbor(const bool strict) {
+    const auto res = parse_cbor_internal();
+    if(strict) {
+      get();
+      expect_eof();
+    }
+    return res;
+  }
+
+  BasicJsonType parse_msgpack(const bool strict) {
+    const auto res = parse_msgpack_internal();
+    if(strict) {
+      get();
+      expect_eof();
+    }
+    return res;
+  }
+
+  BasicJsonType parse_ubjson(const bool strict) {
+    const auto res = parse_ubjson_internal();
+    if(strict) {
+      get_ignore_noop();
+      expect_eof();
+    }
+    return res;
+  }
+
+  static constexpr bool little_endianess(int num = 1) noexcept {
+    return (*reinterpret_cast<char *>(&num) == 1);
+  }
+
+private:
+  BasicJsonType parse_cbor_internal(const bool get_char = true) {
+    switch(get_char ? get() : current) {
+      case std::char_traits<char>::eof():
+        JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
+
+      case 0x00:
+      case 0x01:
+      case 0x02:
+      case 0x03:
+      case 0x04:
+      case 0x05:
+      case 0x06:
+      case 0x07:
+      case 0x08:
+      case 0x09:
+      case 0x0A:
+      case 0x0B:
+      case 0x0C:
+      case 0x0D:
+      case 0x0E:
+      case 0x0F:
+      case 0x10:
+      case 0x11:
+      case 0x12:
+      case 0x13:
+      case 0x14:
+      case 0x15:
+      case 0x16:
+      case 0x17:
+        return static_cast<number_unsigned_t>(current);
+
+      case 0x18:
+        return get_number<uint8_t>();
+
+      case 0x19:
+        return get_number<uint16_t>();
+
+      case 0x1A:
+        return get_number<uint32_t>();
+
+      case 0x1B:
+        return get_number<uint64_t>();
+
+      case 0x20:
+      case 0x21:
+      case 0x22:
+      case 0x23:
+      case 0x24:
+      case 0x25:
+      case 0x26:
+      case 0x27:
+      case 0x28:
+      case 0x29:
+      case 0x2A:
+      case 0x2B:
+      case 0x2C:
+      case 0x2D:
+      case 0x2E:
+      case 0x2F:
+      case 0x30:
+      case 0x31:
+      case 0x32:
+      case 0x33:
+      case 0x34:
+      case 0x35:
+      case 0x36:
+      case 0x37:
+        return static_cast<int8_t>(0x20-1-current);
+
+      case 0x38: {
+        return static_cast<number_integer_t>(-1)-get_number<uint8_t>();
+      }
+
+      case 0x39: {
+        return static_cast<number_integer_t>(-1)-get_number<uint16_t>();
+      }
+
+      case 0x3A: {
+        return static_cast<number_integer_t>(-1)-get_number<uint32_t>();
+      }
+
+      case 0x3B: {
+        return static_cast<number_integer_t>(-1)-
+               static_cast<number_integer_t>(get_number<uint64_t>());
+      }
+
+      case 0x60:
+      case 0x61:
+      case 0x62:
+      case 0x63:
+      case 0x64:
+      case 0x65:
+      case 0x66:
+      case 0x67:
+      case 0x68:
+      case 0x69:
+      case 0x6A:
+      case 0x6B:
+      case 0x6C:
+      case 0x6D:
+      case 0x6E:
+      case 0x6F:
+      case 0x70:
+      case 0x71:
+      case 0x72:
+      case 0x73:
+      case 0x74:
+      case 0x75:
+      case 0x76:
+      case 0x77:
+      case 0x78:
+      case 0x79:
+      case 0x7A:
+      case 0x7B:
+      case 0x7F: {
+        return get_cbor_string();
+      }
+
+      case 0x80:
+      case 0x81:
+      case 0x82:
+      case 0x83:
+      case 0x84:
+      case 0x85:
+      case 0x86:
+      case 0x87:
+      case 0x88:
+      case 0x89:
+      case 0x8A:
+      case 0x8B:
+      case 0x8C:
+      case 0x8D:
+      case 0x8E:
+      case 0x8F:
+      case 0x90:
+      case 0x91:
+      case 0x92:
+      case 0x93:
+      case 0x94:
+      case 0x95:
+      case 0x96:
+      case 0x97: {
+        return get_cbor_array(current & 0x1F);
+      }
+
+      case 0x98: {
+        return get_cbor_array(get_number<uint8_t>());
+      }
+
+      case 0x99: {
+        return get_cbor_array(get_number<uint16_t>());
+      }
+
+      case 0x9A: {
+        return get_cbor_array(get_number<uint32_t>());
+      }
+
+      case 0x9B: {
+        return get_cbor_array(get_number<uint64_t>());
+      }
+
+      case 0x9F: {
+        BasicJsonType result = value_t::array;
+        while(get() != 0xFF) {
+          result.push_back(parse_cbor_internal(false));
+        }
+        return result;
+      }
+
+      case 0xA0:
+      case 0xA1:
+      case 0xA2:
+      case 0xA3:
+      case 0xA4:
+      case 0xA5:
+      case 0xA6:
+      case 0xA7:
+      case 0xA8:
+      case 0xA9:
+      case 0xAA:
+      case 0xAB:
+      case 0xAC:
+      case 0xAD:
+      case 0xAE:
+      case 0xAF:
+      case 0xB0:
+      case 0xB1:
+      case 0xB2:
+      case 0xB3:
+      case 0xB4:
+      case 0xB5:
+      case 0xB6:
+      case 0xB7: {
+        return get_cbor_object(current & 0x1F);
+      }
+
+      case 0xB8: {
+        return get_cbor_object(get_number<uint8_t>());
+      }
+
+      case 0xB9: {
+        return get_cbor_object(get_number<uint16_t>());
+      }
+
+      case 0xBA: {
+        return get_cbor_object(get_number<uint32_t>());
+      }
+
+      case 0xBB: {
+        return get_cbor_object(get_number<uint64_t>());
+      }
+
+      case 0xBF: {
+        BasicJsonType result = value_t::object;
+        while(get() != 0xFF) {
+          auto key = get_cbor_string();
+          result[key] = parse_cbor_internal();
+        }
+        return result;
+      }
+
+      case 0xF4: {
+        return false;
+      }
+
+      case 0xF5: {
+        return true;
+      }
+
+      case 0xF6: {
+        return value_t::null;
+      }
+
+      case 0xF9: {
+        const int byte1 = get();
+        unexpect_eof();
+        const int byte2 = get();
+        unexpect_eof();
+
+        const int half = (byte1 << 8)+byte2;
+        const int exp = (half >> 10) & 0x1F;
+        const int mant = half & 0x3FF;
+        double val;
+        if(exp == 0) {
+          val = std::ldexp(mant, -24);
+        } else if(exp != 31) {
+          val = std::ldexp(mant+1024, exp-25);
+        } else {
+          val = (mant == 0) ? std::numeric_limits<double>::infinity()
+                            : std::numeric_limits<double>::quiet_NaN();
+        }
+        return (half & 0x8000) != 0 ? -val : val;
+      }
+
+      case 0xFA: {
+        return get_number<float>();
+      }
+
+      case 0xFB: {
+        return get_number<double>();
+      }
+
+      default: {
+        std::stringstream ss;
+        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
+        JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x"+ss.str()));
+      }
+    }
+  }
+
+  BasicJsonType parse_msgpack_internal() {
+    switch(get()) {
+      case std::char_traits<char>::eof():
+        JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
+
+      case 0x00:
+      case 0x01:
+      case 0x02:
+      case 0x03:
+      case 0x04:
+      case 0x05:
+      case 0x06:
+      case 0x07:
+      case 0x08:
+      case 0x09:
+      case 0x0A:
+      case 0x0B:
+      case 0x0C:
+      case 0x0D:
+      case 0x0E:
+      case 0x0F:
+      case 0x10:
+      case 0x11:
+      case 0x12:
+      case 0x13:
+      case 0x14:
+      case 0x15:
+      case 0x16:
+      case 0x17:
+      case 0x18:
+      case 0x19:
+      case 0x1A:
+      case 0x1B:
+      case 0x1C:
+      case 0x1D:
+      case 0x1E:
+      case 0x1F:
+      case 0x20:
+      case 0x21:
+      case 0x22:
+      case 0x23:
+      case 0x24:
+      case 0x25:
+      case 0x26:
+      case 0x27:
+      case 0x28:
+      case 0x29:
+      case 0x2A:
+      case 0x2B:
+      case 0x2C:
+      case 0x2D:
+      case 0x2E:
+      case 0x2F:
+      case 0x30:
+      case 0x31:
+      case 0x32:
+      case 0x33:
+      case 0x34:
+      case 0x35:
+      case 0x36:
+      case 0x37:
+      case 0x38:
+      case 0x39:
+      case 0x3A:
+      case 0x3B:
+      case 0x3C:
+      case 0x3D:
+      case 0x3E:
+      case 0x3F:
+      case 0x40:
+      case 0x41:
+      case 0x42:
+      case 0x43:
+      case 0x44:
+      case 0x45:
+      case 0x46:
+      case 0x47:
+      case 0x48:
+      case 0x49:
+      case 0x4A:
+      case 0x4B:
+      case 0x4C:
+      case 0x4D:
+      case 0x4E:
+      case 0x4F:
+      case 0x50:
+      case 0x51:
+      case 0x52:
+      case 0x53:
+      case 0x54:
+      case 0x55:
+      case 0x56:
+      case 0x57:
+      case 0x58:
+      case 0x59:
+      case 0x5A:
+      case 0x5B:
+      case 0x5C:
+      case 0x5D:
+      case 0x5E:
+      case 0x5F:
+      case 0x60:
+      case 0x61:
+      case 0x62:
+      case 0x63:
+      case 0x64:
+      case 0x65:
+      case 0x66:
+      case 0x67:
+      case 0x68:
+      case 0x69:
+      case 0x6A:
+      case 0x6B:
+      case 0x6C:
+      case 0x6D:
+      case 0x6E:
+      case 0x6F:
+      case 0x70:
+      case 0x71:
+      case 0x72:
+      case 0x73:
+      case 0x74:
+      case 0x75:
+      case 0x76:
+      case 0x77:
+      case 0x78:
+      case 0x79:
+      case 0x7A:
+      case 0x7B:
+      case 0x7C:
+      case 0x7D:
+      case 0x7E:
+      case 0x7F:
+        return static_cast<number_unsigned_t>(current);
+
+      case 0x80:
+      case 0x81:
+      case 0x82:
+      case 0x83:
+      case 0x84:
+      case 0x85:
+      case 0x86:
+      case 0x87:
+      case 0x88:
+      case 0x89:
+      case 0x8A:
+      case 0x8B:
+      case 0x8C:
+      case 0x8D:
+      case 0x8E:
+      case 0x8F: {
+        return get_msgpack_object(current & 0x0F);
+      }
+
+      case 0x90:
+      case 0x91:
+      case 0x92:
+      case 0x93:
+      case 0x94:
+      case 0x95:
+      case 0x96:
+      case 0x97:
+      case 0x98:
+      case 0x99:
+      case 0x9A:
+      case 0x9B:
+      case 0x9C:
+      case 0x9D:
+      case 0x9E:
+      case 0x9F: {
+        return get_msgpack_array(current & 0x0F);
+      }
+
+      case 0xA0:
+      case 0xA1:
+      case 0xA2:
+      case 0xA3:
+      case 0xA4:
+      case 0xA5:
+      case 0xA6:
+      case 0xA7:
+      case 0xA8:
+      case 0xA9:
+      case 0xAA:
+      case 0xAB:
+      case 0xAC:
+      case 0xAD:
+      case 0xAE:
+      case 0xAF:
+      case 0xB0:
+      case 0xB1:
+      case 0xB2:
+      case 0xB3:
+      case 0xB4:
+      case 0xB5:
+      case 0xB6:
+      case 0xB7:
+      case 0xB8:
+      case 0xB9:
+      case 0xBA:
+      case 0xBB:
+      case 0xBC:
+      case 0xBD:
+      case 0xBE:
+      case 0xBF:
+        return get_msgpack_string();
+
+      case 0xC0:
+        return value_t::null;
+
+      case 0xC2:
+        return false;
+
+      case 0xC3:
+        return true;
+
+      case 0xCA:
+        return get_number<float>();
+
+      case 0xCB:
+        return get_number<double>();
+
+      case 0xCC:
+        return get_number<uint8_t>();
+
+      case 0xCD:
+        return get_number<uint16_t>();
+
+      case 0xCE:
+        return get_number<uint32_t>();
+
+      case 0xCF:
+        return get_number<uint64_t>();
+
+      case 0xD0:
+        return get_number<int8_t>();
+
+      case 0xD1:
+        return get_number<int16_t>();
+
+      case 0xD2:
+        return get_number<int32_t>();
+
+      case 0xD3:
+        return get_number<int64_t>();
+
+      case 0xD9:
+      case 0xDA:
+      case 0xDB:
+        return get_msgpack_string();
+
+      case 0xDC: {
+        return get_msgpack_array(get_number<uint16_t>());
+      }
+
+      case 0xDD: {
+        return get_msgpack_array(get_number<uint32_t>());
+      }
+
+      case 0xDE: {
+        return get_msgpack_object(get_number<uint16_t>());
+      }
+
+      case 0xDF: {
+        return get_msgpack_object(get_number<uint32_t>());
+      }
+
+      case 0xE0:
+      case 0xE1:
+      case 0xE2:
+      case 0xE3:
+      case 0xE4:
+      case 0xE5:
+      case 0xE6:
+      case 0xE7:
+      case 0xE8:
+      case 0xE9:
+      case 0xEA:
+      case 0xEB:
+      case 0xEC:
+      case 0xED:
+      case 0xEE:
+      case 0xEF:
+      case 0xF0:
+      case 0xF1:
+      case 0xF2:
+      case 0xF3:
+      case 0xF4:
+      case 0xF5:
+      case 0xF6:
+      case 0xF7:
+      case 0xF8:
+      case 0xF9:
+      case 0xFA:
+      case 0xFB:
+      case 0xFC:
+      case 0xFD:
+      case 0xFE:
+      case 0xFF:
+        return static_cast<int8_t>(current);
+
+      default: {
+        std::stringstream ss;
+        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
+        JSON_THROW(parse_error::create(112, chars_read,
+                                       "error reading MessagePack; last byte: 0x"+ss.str()));
+      }
+    }
+  }
+
+  BasicJsonType parse_ubjson_internal(const bool get_char = true) {
+    return get_ubjson_value(get_char ? get_ignore_noop() : current);
+  }
+
+  int get() {
+    ++chars_read;
+    return (current = ia->get_character());
+  }
+
+  int get_ignore_noop() {
+    do {
+      get();
+    } while(current == 'N');
+
+    return current;
+  }
+
+  template<typename NumberType>
+  NumberType get_number() {
+    std::array<uint8_t, sizeof(NumberType)> vec;
+    for(std::size_t i = 0; i < sizeof(NumberType); ++i) {
+      get();
+      unexpect_eof();
+
+      if(is_little_endian) {
+        vec[sizeof(NumberType)-i-1] = static_cast<uint8_t>(current);
+      } else {
+        vec[i] = static_cast<uint8_t>(current);
+      }
+    }
+
+    NumberType result;
+    std::memcpy(&result, vec.data(), sizeof(NumberType));
+    return result;
+  }
+
+  template<typename NumberType>
+  string_t get_string(const NumberType len) {
+    string_t result;
+    std::generate_n(std::back_inserter(result), len, [this]() {
+      get();
+      unexpect_eof();
+      return static_cast<char>(current);
+    });
+    return result;
+  }
+
+  string_t get_cbor_string() {
+    unexpect_eof();
+
+    switch(current) {
+      case 0x60:
+      case 0x61:
+      case 0x62:
+      case 0x63:
+      case 0x64:
+      case 0x65:
+      case 0x66:
+      case 0x67:
+      case 0x68:
+      case 0x69:
+      case 0x6A:
+      case 0x6B:
+      case 0x6C:
+      case 0x6D:
+      case 0x6E:
+      case 0x6F:
+      case 0x70:
+      case 0x71:
+      case 0x72:
+      case 0x73:
+      case 0x74:
+      case 0x75:
+      case 0x76:
+      case 0x77: {
+        return get_string(current & 0x1F);
+      }
+
+      case 0x78: {
+        return get_string(get_number<uint8_t>());
+      }
+
+      case 0x79: {
+        return get_string(get_number<uint16_t>());
+      }
+
+      case 0x7A: {
+        return get_string(get_number<uint32_t>());
+      }
+
+      case 0x7B: {
+        return get_string(get_number<uint64_t>());
+      }
+
+      case 0x7F: {
+        string_t result;
+        while(get() != 0xFF) {
+          result.append(get_cbor_string());
+        }
+        return result;
+      }
+
+      default: {
+        std::stringstream ss;
+        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
+        JSON_THROW(parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x"+ss.str()));
+      }
+    }
+  }
+
+  template<typename NumberType>
+  BasicJsonType get_cbor_array(const NumberType len) {
+    BasicJsonType result = value_t::array;
+    std::generate_n(std::back_inserter(*result.m_value.array), len, [this]() {
+      return parse_cbor_internal();
+    });
+    return result;
+  }
+
+  template<typename NumberType>
+  BasicJsonType get_cbor_object(const NumberType len) {
+    BasicJsonType result = value_t::object;
+    std::generate_n(std::inserter(*result.m_value.object,
+                                  result.m_value.object->end()),
+                    len, [this]() {
+          get();
+          auto key = get_cbor_string();
+          auto val = parse_cbor_internal();
+          return std::make_pair(std::move(key), std::move(val));
+        });
+    return result;
+  }
+
+  string_t get_msgpack_string() {
+    unexpect_eof();
+
+    switch(current) {
+      case 0xA0:
+      case 0xA1:
+      case 0xA2:
+      case 0xA3:
+      case 0xA4:
+      case 0xA5:
+      case 0xA6:
+      case 0xA7:
+      case 0xA8:
+      case 0xA9:
+      case 0xAA:
+      case 0xAB:
+      case 0xAC:
+      case 0xAD:
+      case 0xAE:
+      case 0xAF:
+      case 0xB0:
+      case 0xB1:
+      case 0xB2:
+      case 0xB3:
+      case 0xB4:
+      case 0xB5:
+      case 0xB6:
+      case 0xB7:
+      case 0xB8:
+      case 0xB9:
+      case 0xBA:
+      case 0xBB:
+      case 0xBC:
+      case 0xBD:
+      case 0xBE:
+      case 0xBF: {
+        return get_string(current & 0x1F);
+      }
+
+      case 0xD9: {
+        return get_string(get_number<uint8_t>());
+      }
+
+      case 0xDA: {
+        return get_string(get_number<uint16_t>());
+      }
+
+      case 0xDB: {
+        return get_string(get_number<uint32_t>());
+      }
+
+      default: {
+        std::stringstream ss;
+        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
+        JSON_THROW(parse_error::create(113, chars_read,
+                                       "expected a MessagePack string; last byte: 0x"+ss.str()));
+      }
+    }
+  }
+
+  template<typename NumberType>
+  BasicJsonType get_msgpack_array(const NumberType len) {
+    BasicJsonType result = value_t::array;
+    std::generate_n(std::back_inserter(*result.m_value.array), len, [this]() {
+      return parse_msgpack_internal();
+    });
+    return result;
+  }
+
+  template<typename NumberType>
+  BasicJsonType get_msgpack_object(const NumberType len) {
+    BasicJsonType result = value_t::object;
+    std::generate_n(std::inserter(*result.m_value.object,
+                                  result.m_value.object->end()),
+                    len, [this]() {
+          get();
+          auto key = get_msgpack_string();
+          auto val = parse_msgpack_internal();
+          return std::make_pair(std::move(key), std::move(val));
+        });
+    return result;
+  }
+
+  string_t get_ubjson_string(const bool get_char = true) {
+    if(get_char) {
+      get();
+    }
+
+    unexpect_eof();
+
+    switch(current) {
+      case 'U':
+        return get_string(get_number<uint8_t>());
+      case 'i':
+        return get_string(get_number<int8_t>());
+      case 'I':
+        return get_string(get_number<int16_t>());
+      case 'l':
+        return get_string(get_number<int32_t>());
+      case 'L':
+        return get_string(get_number<int64_t>());
+      default:
+        std::stringstream ss;
+        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
+        JSON_THROW(parse_error::create(113, chars_read,
+                                       "expected a UBJSON string; last byte: 0x"+ss.str()));
+    }
+  }
+
+  std::pair<std::size_t, int> get_ubjson_size_type() {
+    std::size_t sz = string_t::npos;
+    int tc = 0;
+
+    get_ignore_noop();
+
+    if(current == '$') {
+      tc = get();
+      unexpect_eof();
+
+      get_ignore_noop();
+      if(current != '#') {
+        std::stringstream ss;
+        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
+        JSON_THROW(parse_error::create(112, chars_read,
+                                       "expected '#' after UBJSON type information; last byte: 0x"+ss.str()));
+      }
+      sz = parse_ubjson_internal();
+    } else if(current == '#') {
+      sz = parse_ubjson_internal();
+    }
+
+    return std::make_pair(sz, tc);
+  }
+
+  BasicJsonType get_ubjson_value(const int prefix) {
+    switch(prefix) {
+      case std::char_traits<char>::eof():
+        JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
+
+      case 'T':
+        return true;
+      case 'F':
+        return false;
+
+      case 'Z':
+        return nullptr;
+
+      case 'U':
+        return get_number<uint8_t>();
+      case 'i':
+        return get_number<int8_t>();
+      case 'I':
+        return get_number<int16_t>();
+      case 'l':
+        return get_number<int32_t>();
+      case 'L':
+        return get_number<int64_t>();
+      case 'd':
+        return get_number<float>();
+      case 'D':
+        return get_number<double>();
+
+      case 'C': {
+        get();
+        unexpect_eof();
+        if(JSON_UNLIKELY(current > 127)) {
+          std::stringstream ss;
+          ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
+          JSON_THROW(parse_error::create(113, chars_read,
+                                         "byte after 'C' must be in range 0x00..0x7F; last byte: 0x"+ss.str()));
+        }
+        return string_t(1, static_cast<char>(current));
+      }
+
+      case 'S':
+        return get_ubjson_string();
+
+      case '[':
+        return get_ubjson_array();
+
+      case '{':
+        return get_ubjson_object();
+
+      default:
+        std::stringstream ss;
+        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
+        JSON_THROW(parse_error::create(112, chars_read,
+                                       "error reading UBJSON; last byte: 0x"+ss.str()));
+    }
+  }
+
+  BasicJsonType get_ubjson_array() {
+    BasicJsonType result = value_t::array;
+    const auto size_and_type = get_ubjson_size_type();
+
+    if(size_and_type.first != string_t::npos) {
+      if(JSON_UNLIKELY(size_and_type.first > result.max_size())) {
+        JSON_THROW(out_of_range::create(408,
+                                        "excessive array size: "+std::to_string(size_and_type.first)));
+      }
+
+      if(size_and_type.second != 0) {
+        if(size_and_type.second != 'N') {
+          std::generate_n(std::back_inserter(*result.m_value.array),
+                          size_and_type.first, [this, size_and_type]() {
+                return get_ubjson_value(size_and_type.second);
+              });
+        }
+      } else {
+        std::generate_n(std::back_inserter(*result.m_value.array),
+                        size_and_type.first, [this]() {
+              return parse_ubjson_internal();
+            });
+      }
+    } else {
+      while(current != ']') {
+        result.push_back(parse_ubjson_internal(false));
+        get_ignore_noop();
+      }
+    }
+
+    return result;
+  }
+
+  BasicJsonType get_ubjson_object() {
+    BasicJsonType result = value_t::object;
+    const auto size_and_type = get_ubjson_size_type();
+
+    if(size_and_type.first != string_t::npos) {
+      if(JSON_UNLIKELY(size_and_type.first > result.max_size())) {
+        JSON_THROW(out_of_range::create(408,
+                                        "excessive object size: "+std::to_string(size_and_type.first)));
+      }
+
+      if(size_and_type.second != 0) {
+        std::generate_n(std::inserter(*result.m_value.object,
+                                      result.m_value.object->end()),
+                        size_and_type.first, [this, size_and_type]() {
+              auto key = get_ubjson_string();
+              auto val = get_ubjson_value(size_and_type.second);
+              return std::make_pair(std::move(key), std::move(val));
+            });
+      } else {
+        std::generate_n(std::inserter(*result.m_value.object,
+                                      result.m_value.object->end()),
+                        size_and_type.first, [this]() {
+              auto key = get_ubjson_string();
+              auto val = parse_ubjson_internal();
+              return std::make_pair(std::move(key), std::move(val));
+            });
+      }
+    } else {
+      while(current != '}') {
+        auto key = get_ubjson_string(false);
+        result[std::move(key)] = parse_ubjson_internal();
+        get_ignore_noop();
+      }
+    }
+
+    return result;
+  }
+
+  void expect_eof() const {
+    if(JSON_UNLIKELY(current != std::char_traits<char>::eof())) {
+      JSON_THROW(parse_error::create(110, chars_read, "expected end of input"));
+    }
+  }
+
+  void unexpect_eof() const {
+    if(JSON_UNLIKELY(current == std::char_traits<char>::eof())) {
+      JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
+    }
+  }
+
+private:
+  input_adapter_t ia = nullptr;
+
+  int current = std::char_traits<char>::eof();
+
+  std::size_t chars_read = 0;
+
+  const bool is_little_endian = little_endianess();
+};
+}
+}
+
+namespace nlohmann {
+namespace detail {
+template<typename BasicJsonType, typename CharType>
+class binary_writer {
+public:
+  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter) {
+    assert(oa);
+  }
+
+  void write_cbor(const BasicJsonType &j) {
+    switch(j.type()) {
+      case value_t::null: {
+        oa->write_character(static_cast<CharType>(0xF6));
+        break;
+      }
+
+      case value_t::boolean: {
+        oa->write_character(j.m_value.boolean
+                            ? static_cast<CharType>(0xF5)
+                            : static_cast<CharType>(0xF4));
+        break;
+      }
+
+      case value_t::number_integer: {
+        if(j.m_value.number_integer >= 0) {
+          if(j.m_value.number_integer <= 0x17) {
+            write_number(static_cast<uint8_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0x18));
+            write_number(static_cast<uint8_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0x19));
+            write_number(static_cast<uint16_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0x1A));
+            write_number(static_cast<uint32_t>(j.m_value.number_integer));
+          } else {
+            oa->write_character(static_cast<CharType>(0x1B));
+            write_number(static_cast<uint64_t>(j.m_value.number_integer));
+          }
+        } else {
+          const auto positive_number = -1-j.m_value.number_integer;
+          if(j.m_value.number_integer >= -24) {
+            write_number(static_cast<uint8_t>(0x20+positive_number));
+          } else if(positive_number <= (std::numeric_limits<uint8_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0x38));
+            write_number(static_cast<uint8_t>(positive_number));
+          } else if(positive_number <= (std::numeric_limits<uint16_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0x39));
+            write_number(static_cast<uint16_t>(positive_number));
+          } else if(positive_number <= (std::numeric_limits<uint32_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0x3A));
+            write_number(static_cast<uint32_t>(positive_number));
+          } else {
+            oa->write_character(static_cast<CharType>(0x3B));
+            write_number(static_cast<uint64_t>(positive_number));
+          }
+        }
+        break;
+      }
+
+      case value_t::number_unsigned: {
+        if(j.m_value.number_unsigned <= 0x17) {
+          write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x18));
+          write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x19));
+          write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x1A));
+          write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
+        } else {
+          oa->write_character(static_cast<CharType>(0x1B));
+          write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
+        }
+        break;
+      }
+
+      case value_t::number_float: {
+        oa->write_character(static_cast<CharType>(0xFB));
+        write_number(j.m_value.number_float);
+        break;
+      }
+
+      case value_t::string: {
+        const auto N = j.m_value.string->size();
+        if(N <= 0x17) {
+          write_number(static_cast<uint8_t>(0x60+N));
+        } else if(N <= (std::numeric_limits<uint8_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x78));
+          write_number(static_cast<uint8_t>(N));
+        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x79));
+          write_number(static_cast<uint16_t>(N));
+        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x7A));
+          write_number(static_cast<uint32_t>(N));
+        } else if(N <= (std::numeric_limits<uint64_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x7B));
+          write_number(static_cast<uint64_t>(N));
+        }
+
+        oa->write_characters(
+            reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
+            j.m_value.string->size());
+        break;
+      }
+
+      case value_t::array: {
+        const auto N = j.m_value.array->size();
+        if(N <= 0x17) {
+          write_number(static_cast<uint8_t>(0x80+N));
+        } else if(N <= (std::numeric_limits<uint8_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x98));
+          write_number(static_cast<uint8_t>(N));
+        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x99));
+          write_number(static_cast<uint16_t>(N));
+        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x9A));
+          write_number(static_cast<uint32_t>(N));
+        } else if(N <= (std::numeric_limits<uint64_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0x9B));
+          write_number(static_cast<uint64_t>(N));
+        }
+
+        for(const auto &el : *j.m_value.array) {
+          write_cbor(el);
+        }
+        break;
+      }
+
+      case value_t::object: {
+        const auto N = j.m_value.object->size();
+        if(N <= 0x17) {
+          write_number(static_cast<uint8_t>(0xA0+N));
+        } else if(N <= (std::numeric_limits<uint8_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xB8));
+          write_number(static_cast<uint8_t>(N));
+        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xB9));
+          write_number(static_cast<uint16_t>(N));
+        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xBA));
+          write_number(static_cast<uint32_t>(N));
+        } else if(N <= (std::numeric_limits<uint64_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xBB));
+          write_number(static_cast<uint64_t>(N));
+        }
+
+        for(const auto &el : *j.m_value.object) {
+          write_cbor(el.first);
+          write_cbor(el.second);
+        }
+        break;
+      }
+
+      default:
+        break;
+    }
+  }
+
+  void write_msgpack(const BasicJsonType &j) {
+    switch(j.type()) {
+      case value_t::null: {
+        oa->write_character(static_cast<CharType>(0xC0));
+        break;
+      }
+
+      case value_t::boolean: {
+        oa->write_character(j.m_value.boolean
+                            ? static_cast<CharType>(0xC3)
+                            : static_cast<CharType>(0xC2));
+        break;
+      }
+
+      case value_t::number_integer: {
+        if(j.m_value.number_integer >= 0) {
+          if(j.m_value.number_unsigned < 128) {
+            write_number(static_cast<uint8_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0xCC));
+            write_number(static_cast<uint8_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0xCD));
+            write_number(static_cast<uint16_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0xCE));
+            write_number(static_cast<uint32_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0xCF));
+            write_number(static_cast<uint64_t>(j.m_value.number_integer));
+          }
+        } else {
+          if(j.m_value.number_integer >= -32) {
+            write_number(static_cast<int8_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_integer >= (std::numeric_limits<int8_t>::min) () and
+                    j.m_value.number_integer <= (std::numeric_limits<int8_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0xD0));
+            write_number(static_cast<int8_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_integer >= (std::numeric_limits<int16_t>::min) () and
+                    j.m_value.number_integer <= (std::numeric_limits<int16_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0xD1));
+            write_number(static_cast<int16_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_integer >= (std::numeric_limits<int32_t>::min) () and
+                    j.m_value.number_integer <= (std::numeric_limits<int32_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0xD2));
+            write_number(static_cast<int32_t>(j.m_value.number_integer));
+          } else if(j.m_value.number_integer >= (std::numeric_limits<int64_t>::min) () and
+                    j.m_value.number_integer <= (std::numeric_limits<int64_t>::max) ()) {
+            oa->write_character(static_cast<CharType>(0xD3));
+            write_number(static_cast<int64_t>(j.m_value.number_integer));
+          }
+        }
+        break;
+      }
+
+      case value_t::number_unsigned: {
+        if(j.m_value.number_unsigned < 128) {
+          write_number(static_cast<uint8_t>(j.m_value.number_integer));
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xCC));
+          write_number(static_cast<uint8_t>(j.m_value.number_integer));
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xCD));
+          write_number(static_cast<uint16_t>(j.m_value.number_integer));
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xCE));
+          write_number(static_cast<uint32_t>(j.m_value.number_integer));
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xCF));
+          write_number(static_cast<uint64_t>(j.m_value.number_integer));
+        }
+        break;
+      }
+
+      case value_t::number_float: {
+        oa->write_character(static_cast<CharType>(0xCB));
+        write_number(j.m_value.number_float);
+        break;
+      }
+
+      case value_t::string: {
+        const auto N = j.m_value.string->size();
+        if(N <= 31) {
+          write_number(static_cast<uint8_t>(0xA0 | N));
+        } else if(N <= (std::numeric_limits<uint8_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xD9));
+          write_number(static_cast<uint8_t>(N));
+        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xDA));
+          write_number(static_cast<uint16_t>(N));
+        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xDB));
+          write_number(static_cast<uint32_t>(N));
+        }
+
+        oa->write_characters(
+            reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
+            j.m_value.string->size());
+        break;
+      }
+
+      case value_t::array: {
+        const auto N = j.m_value.array->size();
+        if(N <= 15) {
+          write_number(static_cast<uint8_t>(0x90 | N));
+        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xDC));
+          write_number(static_cast<uint16_t>(N));
+        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xDD));
+          write_number(static_cast<uint32_t>(N));
+        }
+
+        for(const auto &el : *j.m_value.array) {
+          write_msgpack(el);
+        }
+        break;
+      }
+
+      case value_t::object: {
+        const auto N = j.m_value.object->size();
+        if(N <= 15) {
+          write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
+        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xDE));
+          write_number(static_cast<uint16_t>(N));
+        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
+          oa->write_character(static_cast<CharType>(0xDF));
+          write_number(static_cast<uint32_t>(N));
+        }
+
+        for(const auto &el : *j.m_value.object) {
+          write_msgpack(el.first);
+          write_msgpack(el.second);
+        }
+        break;
+      }
+
+      default:
+        break;
+    }
+  }
+
+  void write_ubjson(const BasicJsonType &j, const bool use_count,
+                    const bool use_type, const bool add_prefix = true) {
+    switch(j.type()) {
+      case value_t::null: {
+        if(add_prefix) {
+          oa->write_character(static_cast<CharType>('Z'));
+        }
+        break;
+      }
+
+      case value_t::boolean: {
+        if(add_prefix)
+          oa->write_character(j.m_value.boolean
+                              ? static_cast<CharType>('T')
+                              : static_cast<CharType>('F'));
+        break;
+      }
+
+      case value_t::number_integer: {
+        write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
+        break;
+      }
+
+      case value_t::number_unsigned: {
+        write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
+        break;
+      }
+
+      case value_t::number_float: {
+        write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
+        break;
+      }
+
+      case value_t::string: {
+        if(add_prefix) {
+          oa->write_character(static_cast<CharType>('S'));
+        }
+        write_number_with_ubjson_prefix(j.m_value.string->size(), true);
+        oa->write_characters(
+            reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
+            j.m_value.string->size());
+        break;
+      }
+
+      case value_t::array: {
+        if(add_prefix) {
+          oa->write_character(static_cast<CharType>('['));
+        }
+
+        bool prefix_required = true;
+        if(use_type and not j.m_value.array->empty()) {
+          assert(use_count);
+          const char first_prefix = ubjson_prefix(j.front());
+          const bool same_prefix = std::all_of(j.begin()+1, j.end(),
+                                               [this, first_prefix](const BasicJsonType &v) {
+                                                 return ubjson_prefix(v) == first_prefix;
+                                               });
+
+          if(same_prefix) {
+            prefix_required = false;
+            oa->write_character(static_cast<CharType>('$'));
+            oa->write_character(static_cast<CharType>(first_prefix));
+          }
+        }
+
+        if(use_count) {
+          oa->write_character(static_cast<CharType>('#'));
+          write_number_with_ubjson_prefix(j.m_value.array->size(), true);
+        }
+
+        for(const auto &el : *j.m_value.array) {
+          write_ubjson(el, use_count, use_type, prefix_required);
+        }
+
+        if(not use_count) {
+          oa->write_character(static_cast<CharType>(']'));
+        }
+
+        break;
+      }
+
+      case value_t::object: {
+        if(add_prefix) {
+          oa->write_character(static_cast<CharType>('{'));
+        }
+
+        bool prefix_required = true;
+        if(use_type and not j.m_value.object->empty()) {
+          assert(use_count);
+          const char first_prefix = ubjson_prefix(j.front());
+          const bool same_prefix = std::all_of(j.begin(), j.end(),
+                                               [this, first_prefix](const BasicJsonType &v) {
+                                                 return ubjson_prefix(v) == first_prefix;
+                                               });
+
+          if(same_prefix) {
+            prefix_required = false;
+            oa->write_character(static_cast<CharType>('$'));
+            oa->write_character(static_cast<CharType>(first_prefix));
+          }
+        }
+
+        if(use_count) {
+          oa->write_character(static_cast<CharType>('#'));
+          write_number_with_ubjson_prefix(j.m_value.object->size(), true);
+        }
+
+        for(const auto &el : *j.m_value.object) {
+          write_number_with_ubjson_prefix(el.first.size(), true);
+          oa->write_characters(
+              reinterpret_cast<const CharType *>(el.first.c_str()),
+              el.first.size());
+          write_ubjson(el.second, use_count, use_type, prefix_required);
+        }
+
+        if(not use_count) {
+          oa->write_character(static_cast<CharType>('}'));
+        }
+
+        break;
+      }
+
+      default:
+        break;
+    }
+  }
+
+private:
+  template<typename NumberType>
+  void write_number(const NumberType n) {
+    std::array<CharType, sizeof(NumberType)> vec;
+    std::memcpy(vec.data(), &n, sizeof(NumberType));
+
+    if(is_little_endian) {
+      std::reverse(vec.begin(), vec.end());
+    }
+
+    oa->write_characters(vec.data(), sizeof(NumberType));
+  }
+
+  template<typename NumberType, typename std::enable_if<
+      std::is_floating_point<NumberType>::value, int>::type = 0>
+  void write_number_with_ubjson_prefix(const NumberType n,
+                                       const bool add_prefix) {
+    if(add_prefix) {
+      oa->write_character(static_cast<CharType>('D'));
+    }
+    write_number(n);
+  }
+
+  template<typename NumberType, typename std::enable_if<
+      std::is_unsigned<NumberType>::value, int>::type = 0>
+  void write_number_with_ubjson_prefix(const NumberType n,
+                                       const bool add_prefix) {
+    if(n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max) ())) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('i'));
+      }
+      write_number(static_cast<uint8_t>(n));
+    } else if(n <= (std::numeric_limits<uint8_t>::max) ()) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('U'));
+      }
+      write_number(static_cast<uint8_t>(n));
+    } else if(n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max) ())) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('I'));
+      }
+      write_number(static_cast<int16_t>(n));
+    } else if(n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max) ())) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('l'));
+      }
+      write_number(static_cast<int32_t>(n));
+    } else if(n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max) ())) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('L'));
+      }
+      write_number(static_cast<int64_t>(n));
+    } else {
+      JSON_THROW(out_of_range::create(407, "number overflow serializing "+std::to_string(n)));
+    }
+  }
+
+  template<typename NumberType, typename std::enable_if<
+      std::is_signed<NumberType>::value and
+      not std::is_floating_point<NumberType>::value, int>::type = 0>
+  void write_number_with_ubjson_prefix(const NumberType n,
+                                       const bool add_prefix) {
+    if((std::numeric_limits<int8_t>::min) () <= n and n <= (std::numeric_limits<int8_t>::max) ()) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('i'));
+      }
+      write_number(static_cast<int8_t>(n));
+    } else if(static_cast<int64_t>((std::numeric_limits<uint8_t>::min) ()) <= n and
+              n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max) ())) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('U'));
+      }
+      write_number(static_cast<uint8_t>(n));
+    } else if((std::numeric_limits<int16_t>::min) () <= n and n <= (std::numeric_limits<int16_t>::max) ()) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('I'));
+      }
+      write_number(static_cast<int16_t>(n));
+    } else if((std::numeric_limits<int32_t>::min) () <= n and n <= (std::numeric_limits<int32_t>::max) ()) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('l'));
+      }
+      write_number(static_cast<int32_t>(n));
+    } else if((std::numeric_limits<int64_t>::min) () <= n and n <= (std::numeric_limits<int64_t>::max) ()) {
+      if(add_prefix) {
+        oa->write_character(static_cast<CharType>('L'));
+      }
+      write_number(static_cast<int64_t>(n));
+    } else {
+      JSON_THROW(out_of_range::create(407, "number overflow serializing "+std::to_string(n)));
+    }
+
+  }
+
+  char ubjson_prefix(const BasicJsonType &j) const noexcept {
+    switch(j.type()) {
+      case value_t::null:
+        return 'Z';
+
+      case value_t::boolean:
+        return j.m_value.boolean ? 'T' : 'F';
+
+      case value_t::number_integer: {
+        if((std::numeric_limits<int8_t>::min) () <= j.m_value.number_integer and
+           j.m_value.number_integer <= (std::numeric_limits<int8_t>::max) ()) {
+          return 'i';
+        } else if((std::numeric_limits<uint8_t>::min) () <= j.m_value.number_integer and
+                  j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max) ()) {
+          return 'U';
+        } else if((std::numeric_limits<int16_t>::min) () <= j.m_value.number_integer and
+                  j.m_value.number_integer <= (std::numeric_limits<int16_t>::max) ()) {
+          return 'I';
+        } else if((std::numeric_limits<int32_t>::min) () <= j.m_value.number_integer and
+                  j.m_value.number_integer <= (std::numeric_limits<int32_t>::max) ()) {
+          return 'l';
+        } else {
+          return 'L';
+        }
+      }
+
+      case value_t::number_unsigned: {
+        if(j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max) ()) {
+          return 'i';
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max) ()) {
+          return 'U';
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max) ()) {
+          return 'I';
+        } else if(j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max) ()) {
+          return 'l';
+        } else {
+          return 'L';
+        }
+      }
+
+      case value_t::number_float:
+        return 'D';
+
+      case value_t::string:
+        return 'S';
+
+      case value_t::array:
+        return '[';
+
+      case value_t::object:
+        return '{';
+
+      default:
+        return 'N';
+    }
+  }
+
+private:
+  const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
+
+  output_adapter_t<CharType> oa = nullptr;
+};
+}
+}
+
+#include <cstdio>
+
+namespace nlohmann {
+namespace detail {
+namespace dtoa_impl {
+template<typename Target, typename Source>
+Target reinterpret_bits(const Source source) {
+  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
+
+  Target target;
+  std::memcpy(&target, &source, sizeof(Source));
+  return target;
+}
+
+struct diyfp {
+  static constexpr int kPrecision = 64;
+
+  uint64_t f;
+  int e;
+
+  constexpr diyfp() noexcept : f(0), e(0) {}
+
+  constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
+
+  static diyfp sub(const diyfp &x, const diyfp &y) noexcept {
+    assert(x.e == y.e);
+    assert(x.f >= y.f);
+
+    return diyfp(x.f-y.f, x.e);
+  }
+
+  static diyfp mul(const diyfp &x, const diyfp &y) noexcept {
+    static_assert(kPrecision == 64, "internal error");
+
+    //
+
+    //
+
+    //
+
+    //
+
+    //
+
+    const uint64_t u_lo = x.f & 0xFFFFFFFF;
+    const uint64_t u_hi = x.f >> 32;
+    const uint64_t v_lo = y.f & 0xFFFFFFFF;
+    const uint64_t v_hi = y.f >> 32;
+
+    const uint64_t p0 = u_lo * v_lo;
+    const uint64_t p1 = u_lo * v_hi;
+    const uint64_t p2 = u_hi * v_lo;
+    const uint64_t p3 = u_hi * v_hi;
+
+    const uint64_t p0_hi = p0 >> 32;
+    const uint64_t p1_lo = p1 & 0xFFFFFFFF;
+    const uint64_t p1_hi = p1 >> 32;
+    const uint64_t p2_lo = p2 & 0xFFFFFFFF;
+    const uint64_t p2_hi = p2 >> 32;
+
+    uint64_t Q = p0_hi+p1_lo+p2_lo;
+
+    //
+
+    //
+
+    Q += uint64_t{1} << (64-32-1);
+
+    const uint64_t h = p3+p2_hi+p1_hi+(Q >> 32);
+
+    return diyfp(h, x.e+y.e+64);
+  }
+
+  static diyfp normalize(diyfp x) noexcept {
+    assert(x.f != 0);
+
+    while((x.f >> 63) == 0) {
+      x.f <<= 1;
+      x.e--;
+    }
+
+    return x;
+  }
+
+  static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept {
+    const int delta = x.e-target_exponent;
+
+    assert(delta >= 0);
+    assert(((x.f << delta) >> delta) == x.f);
+
+    return diyfp(x.f << delta, target_exponent);
+  }
+};
+
+struct boundaries {
+  diyfp w;
+  diyfp minus;
+  diyfp plus;
+};
+
+template<typename FloatType>
+boundaries compute_boundaries(FloatType value) {
+  assert(std::isfinite(value));
+  assert(value > 0);
+
+  //
+
+  static_assert(std::numeric_limits<FloatType>::is_iec559,
+                "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
+
+  constexpr int kPrecision = std::numeric_limits<FloatType>::digits;
+  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent-1+(kPrecision-1);
+  constexpr int kMinExp = 1-kBias;
+  constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision-1);
+
+  using bits_type = typename std::conditional<kPrecision == 24, uint32_t, uint64_t>::type;
+
+  const uint64_t bits = reinterpret_bits<bits_type>(value);
+  const uint64_t E = bits >> (kPrecision-1);
+  const uint64_t F = bits & (kHiddenBit-1);
+
+  const bool is_denormal = (E == 0);
+  const diyfp v = is_denormal
+                  ? diyfp(F, kMinExp)
+                  : diyfp(F+kHiddenBit, static_cast<int>(E)-kBias);
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  const bool lower_boundary_is_closer = (F == 0 and E > 1);
+  const diyfp m_plus = diyfp(2 * v.f+1, v.e-1);
+  const diyfp m_minus = lower_boundary_is_closer
+                        ? diyfp(4 * v.f-1, v.e-2)
+                        : diyfp(2 * v.f-1, v.e-1);
+
+  const diyfp w_plus = diyfp::normalize(m_plus);
+
+  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
+
+  return {diyfp::normalize(v), w_minus, w_plus};
+}
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+//
+
+constexpr int kAlpha = -60;
+constexpr int kGamma = -32;
+
+struct cached_power {
+  uint64_t f;
+  int e;
+  int k;
+};
+
+inline cached_power get_cached_power_for_binary_exponent(int e) {
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  constexpr int kCachedPowersSize = 79;
+  constexpr int kCachedPowersMinDecExp = -300;
+  constexpr int kCachedPowersDecStep = 8;
+
+  static constexpr cached_power kCachedPowers[] =
+      {
+          {0xAB70FE17C79AC6CA, -1060, -300},
+          {0xFF77B1FCBEBCDC4F, -1034, -292},
+          {0xBE5691EF416BD60C, -1007, -284},
+          {0x8DD01FAD907FFC3C, -980,  -276},
+          {0xD3515C2831559A83, -954,  -268},
+          {0x9D71AC8FADA6C9B5, -927,  -260},
+          {0xEA9C227723EE8BCB, -901,  -252},
+          {0xAECC49914078536D, -874,  -244},
+          {0x823C12795DB6CE57, -847,  -236},
+          {0xC21094364DFB5637, -821,  -228},
+          {0x9096EA6F3848984F, -794,  -220},
+          {0xD77485CB25823AC7, -768,  -212},
+          {0xA086CFCD97BF97F4, -741,  -204},
+          {0xEF340A98172AACE5, -715,  -196},
+          {0xB23867FB2A35B28E, -688,  -188},
+          {0x84C8D4DFD2C63F3B, -661,  -180},
+          {0xC5DD44271AD3CDBA, -635,  -172},
+          {0x936B9FCEBB25C996, -608,  -164},
+          {0xDBAC6C247D62A584, -582,  -156},
+          {0xA3AB66580D5FDAF6, -555,  -148},
+          {0xF3E2F893DEC3F126, -529,  -140},
+          {0xB5B5ADA8AAFF80B8, -502,  -132},
+          {0x87625F056C7C4A8B, -475,  -124},
+          {0xC9BCFF6034C13053, -449,  -116},
+          {0x964E858C91BA2655, -422,  -108},
+          {0xDFF9772470297EBD, -396,  -100},
+          {0xA6DFBD9FB8E5B88F, -369,  -92},
+          {0xF8A95FCF88747D94, -343,  -84},
+          {0xB94470938FA89BCF, -316,  -76},
+          {0x8A08F0F8BF0F156B, -289,  -68},
+          {0xCDB02555653131B6, -263,  -60},
+          {0x993FE2C6D07B7FAC, -236,  -52},
+          {0xE45C10C42A2B3B06, -210,  -44},
+          {0xAA242499697392D3, -183,  -36},
+          {0xFD87B5F28300CA0E, -157,  -28},
+          {0xBCE5086492111AEB, -130,  -20},
+          {0x8CBCCC096F5088CC, -103,  -12},
+          {0xD1B71758E219652C, -77,   -4},
+          {0x9C40000000000000, -50,   4},
+          {0xE8D4A51000000000, -24,   12},
+          {0xAD78EBC5AC620000, 3,     20},
+          {0x813F3978F8940984, 30,    28},
+          {0xC097CE7BC90715B3, 56,    36},
+          {0x8F7E32CE7BEA5C70, 83,    44},
+          {0xD5D238A4ABE98068, 109,   52},
+          {0x9F4F2726179A2245, 136,   60},
+          {0xED63A231D4C4FB27, 162,   68},
+          {0xB0DE65388CC8ADA8, 189,   76},
+          {0x83C7088E1AAB65DB, 216,   84},
+          {0xC45D1DF942711D9A, 242,   92},
+          {0x924D692CA61BE758, 269,   100},
+          {0xDA01EE641A708DEA, 295,   108},
+          {0xA26DA3999AEF774A, 322,   116},
+          {0xF209787BB47D6B85, 348,   124},
+          {0xB454E4A179DD1877, 375,   132},
+          {0x865B86925B9BC5C2, 402,   140},
+          {0xC83553C5C8965D3D, 428,   148},
+          {0x952AB45CFA97A0B3, 455,   156},
+          {0xDE469FBD99A05FE3, 481,   164},
+          {0xA59BC234DB398C25, 508,   172},
+          {0xF6C69A72A3989F5C, 534,   180},
+          {0xB7DCBF5354E9BECE, 561,   188},
+          {0x88FCF317F22241E2, 588,   196},
+          {0xCC20CE9BD35C78A5, 614,   204},
+          {0x98165AF37B2153DF, 641,   212},
+          {0xE2A0B5DC971F303A, 667,   220},
+          {0xA8D9D1535CE3B396, 694,   228},
+          {0xFB9B7CD9A4A7443C, 720,   236},
+          {0xBB764C4CA7A44410, 747,   244},
+          {0x8BAB8EEFB6409C1A, 774,   252},
+          {0xD01FEF10A657842C, 800,   260},
+          {0x9B10A4E5E9913129, 827,   268},
+          {0xE7109BFBA19C0C9D, 853,   276},
+          {0xAC2820D9623BF429, 880,   284},
+          {0x80444B5E7AA7CF85, 907,   292},
+          {0xBF21E44003ACDD2D, 933,   300},
+          {0x8E679C2F5E44FF8F, 960,   308},
+          {0xD433179D9C8CB841, 986,   316},
+          {0x9E19DB92B4E31BA9, 1013,  324},
+      };
+
+  assert(e >= -1500);
+  assert(e <= 1500);
+  const int f = kAlpha-e-1;
+  const int k = (f * 78913) / (1 << 18)+(f > 0);
+
+  const int index = (-kCachedPowersMinDecExp+k+(kCachedPowersDecStep-1)) / kCachedPowersDecStep;
+  assert(index >= 0);
+  assert(index < kCachedPowersSize);
+  static_cast<void>(kCachedPowersSize);
+
+  const cached_power cached = kCachedPowers[index];
+  assert(kAlpha <= cached.e+e+64);
+  assert(kGamma >= cached.e+e+64);
+
+  return cached;
+}
+
+inline int find_largest_pow10(const uint32_t n, uint32_t &pow10) {
+  if(n >= 1000000000) {
+    pow10 = 1000000000;
+    return 10;
+  } else if(n >= 100000000) {
+    pow10 = 100000000;
+    return 9;
+  } else if(n >= 10000000) {
+    pow10 = 10000000;
+    return 8;
+  } else if(n >= 1000000) {
+    pow10 = 1000000;
+    return 7;
+  } else if(n >= 100000) {
+    pow10 = 100000;
+    return 6;
+  } else if(n >= 10000) {
+    pow10 = 10000;
+    return 5;
+  } else if(n >= 1000) {
+    pow10 = 1000;
+    return 4;
+  } else if(n >= 100) {
+    pow10 = 100;
+    return 3;
+  } else if(n >= 10) {
+    pow10 = 10;
+    return 2;
+  } else {
+    pow10 = 1;
+    return 1;
+  }
+}
+
+inline void grisu2_round(char *buf, int len, uint64_t dist, uint64_t delta,
+                         uint64_t rest, uint64_t ten_k) {
+  assert(len >= 1);
+  assert(dist <= delta);
+  assert(rest <= delta);
+  assert(ten_k > 0);
+
+  //
+
+  //
+
+  while(rest < dist
+        and delta-rest >= ten_k
+        and (rest+ten_k < dist or dist-rest > rest+ten_k-dist)) {
+    assert(buf[len-1] != '0');
+    buf[len-1]--;
+    rest += ten_k;
+  }
+}
+
+inline void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent,
+                             diyfp M_minus, diyfp w, diyfp M_plus) {
+  static_assert(kAlpha >= -60, "internal error");
+  static_assert(kGamma <= -32, "internal error");
+
+  //
+
+  //
+
+  assert(M_plus.e >= kAlpha);
+  assert(M_plus.e <= kGamma);
+
+  uint64_t delta = diyfp::sub(M_plus, M_minus).f;
+  uint64_t dist = diyfp::sub(M_plus, w).f;
+
+  //
+
+  const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
+
+  uint32_t p1 = static_cast<uint32_t>(M_plus.f >> -one.e);
+  uint64_t p2 = M_plus.f & (one.f-1);
+
+  //
+
+  assert(p1 > 0);
+
+  uint32_t pow10;
+  const int k = find_largest_pow10(p1, pow10);
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  int n = k;
+  while(n > 0) {
+    //
+    const uint32_t d = p1 / pow10;
+    const uint32_t r = p1 % pow10;
+    //
+
+    //
+    assert(d <= 9);
+    buffer[length++] = static_cast<char>('0'+d);
+    //
+
+    //
+    p1 = r;
+    n--;
+    //
+
+    //
+
+    //
+
+    //
+
+    const uint64_t rest = (uint64_t{p1} << -one.e)+p2;
+    if(rest <= delta) {
+      decimal_exponent += n;
+
+      //
+
+      //
+
+      //
+      const uint64_t ten_n = uint64_t{pow10} << -one.e;
+      grisu2_round(buffer, length, dist, delta, rest, ten_n);
+
+      return;
+    }
+
+    pow10 /= 10;
+    //
+
+  }
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  assert(p2 > delta);
+
+  int m = 0;
+  for(;;) {
+    //
+    assert(p2 <= UINT64_MAX / 10);
+    p2 *= 10;
+    const uint64_t d = p2 >> -one.e;
+    const uint64_t r = p2 & (one.f-1);
+    //
+
+    //
+    assert(d <= 9);
+    buffer[length++] = static_cast<char>('0'+d);
+    //
+
+    //
+    p2 = r;
+    m++;
+    //
+
+    //
+
+    delta *= 10;
+    dist *= 10;
+    if(p2 <= delta) {
+      break;
+    }
+  }
+
+  decimal_exponent -= m;
+
+  //
+
+  //
+  const uint64_t ten_m = one.f;
+  grisu2_round(buffer, length, dist, delta, p2, ten_m);
+
+  //
+
+  //
+
+  //
+
+}
+
+inline void grisu2(char *buf, int &len, int &decimal_exponent,
+                   diyfp m_minus, diyfp v, diyfp m_plus) {
+  assert(m_plus.e == m_minus.e);
+  assert(m_plus.e == v.e);
+
+  //
+
+  //
+
+  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
+
+  const diyfp c_minus_k(cached.f, cached.e);
+
+  const diyfp w = diyfp::mul(v, c_minus_k);
+  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
+  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  //
+
+  const diyfp M_minus(w_minus.f+1, w_minus.e);
+  const diyfp M_plus(w_plus.f-1, w_plus.e);
+
+  decimal_exponent = -cached.k;
+
+  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
+}
+
+template<typename FloatType>
+void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value) {
+  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits+3,
+                "internal error: not enough precision");
+
+  assert(std::isfinite(value));
+  assert(value > 0);
+
+  //
+
+  //
+
+#if 0
+  const boundaries w = compute_boundaries(static_cast<double>(value));
+#else
+  const boundaries w = compute_boundaries(value);
+#endif
+
+  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
+}
+
+inline char *append_exponent(char *buf, int e) {
+  assert(e > -1000);
+  assert(e < 1000);
+
+  if(e < 0) {
+    e = -e;
+    *buf++ = '-';
+  } else {
+    *buf++ = '+';
+  }
+
+  uint32_t k = static_cast<uint32_t>(e);
+  if(k < 10) {
+    *buf++ = '0';
+    *buf++ = static_cast<char>('0'+k);
+  } else if(k < 100) {
+    *buf++ = static_cast<char>('0'+k / 10);
+    k %= 10;
+    *buf++ = static_cast<char>('0'+k);
+  } else {
+    *buf++ = static_cast<char>('0'+k / 100);
+    k %= 100;
+    *buf++ = static_cast<char>('0'+k / 10);
+    k %= 10;
+    *buf++ = static_cast<char>('0'+k);
+  }
+
+  return buf;
+}
+
+inline char *format_buffer(char *buf, int len, int decimal_exponent,
+                           int min_exp, int max_exp) {
+  assert(min_exp < 0);
+  assert(max_exp > 0);
+
+  const int k = len;
+  const int n = len+decimal_exponent;
+
+  if(k <= n and n <= max_exp) {
+    std::memset(buf+k, '0', static_cast<size_t>(n-k));
+
+    buf[n+0] = '.';
+    buf[n+1] = '0';
+    return buf+(n+2);
+  }
+
+  if(0 < n and n <= max_exp) {
+    assert(k > n);
+
+    std::memmove(buf+(n+1), buf+n, static_cast<size_t>(k-n));
+    buf[n] = '.';
+    return buf+(k+1);
+  }
+
+  if(min_exp < n and n <= 0) {
+    std::memmove(buf+(2+ -n), buf, static_cast<size_t>(k));
+    buf[0] = '0';
+    buf[1] = '.';
+    std::memset(buf+2, '0', static_cast<size_t>(-n));
+    return buf+(2+(-n)+k);
+  }
+
+  if(k == 1) {
+    buf += 1;
+  } else {
+    std::memmove(buf+2, buf+1, static_cast<size_t>(k-1));
+    buf[1] = '.';
+    buf += 1+k;
+  }
+
+  *buf++ = 'e';
+  return append_exponent(buf, n-1);
+}
+
+}
+
+template<typename FloatType>
+char *to_chars(char *first, char *last, FloatType value) {
+  static_cast<void>(last);
+  assert(std::isfinite(value));
+
+  if(std::signbit(value)) {
+    value = -value;
+    *first++ = '-';
+  }
+
+  if(value == 0) {
+    *first++ = '0';
+
+    *first++ = '.';
+    *first++ = '0';
+    return first;
+  }
+
+  assert(last-first >= std::numeric_limits<FloatType>::max_digits10);
+
+  int len = 0;
+  int decimal_exponent = 0;
+  dtoa_impl::grisu2(first, len, decimal_exponent, value);
+
+  assert(len <= std::numeric_limits<FloatType>::max_digits10);
+
+  constexpr int kMinExp = -4;
+
+  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
+
+  assert(last-first >= kMaxExp+2);
+  assert(last-first >= 2+(-kMinExp-1)+std::numeric_limits<FloatType>::max_digits10);
+  assert(last-first >= std::numeric_limits<FloatType>::max_digits10+6);
+
+  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
+}
+
+}
+}
+
+namespace nlohmann {
+namespace detail {
+template<typename BasicJsonType>
+class serializer {
+  using string_t = typename BasicJsonType::string_t;
+  using number_float_t = typename BasicJsonType::number_float_t;
+  using number_integer_t = typename BasicJsonType::number_integer_t;
+  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+  static constexpr uint8_t UTF8_ACCEPT = 0;
+  static constexpr uint8_t UTF8_REJECT = 1;
+
+public:
+  serializer(output_adapter_t<char> s, const char ichar)
+      : o(std::move(s)), loc(std::localeconv()),
+        thousands_sep(loc->thousands_sep == nullptr ? '\0' : *(loc->thousands_sep)),
+        decimal_point(loc->decimal_point == nullptr ? '\0' : *(loc->decimal_point)),
+        indent_char(ichar), indent_string(512, indent_char) {}
+
+  serializer(const serializer &) = delete;
+
+  serializer &operator=(const serializer &) = delete;
+
+  void dump(const BasicJsonType &val, const bool pretty_print,
+            const bool ensure_ascii,
+            const unsigned int indent_step,
+            const unsigned int current_indent = 0) {
+    switch(val.m_type) {
+      case value_t::object: {
+        if(val.m_value.object->empty()) {
+          o->write_characters("{}", 2);
+          return;
+        }
+
+        if(pretty_print) {
+          o->write_characters("{\n", 2);
+
+          const auto new_indent = current_indent+indent_step;
+          if(JSON_UNLIKELY(indent_string.size() < new_indent)) {
+            indent_string.resize(indent_string.size() * 2, ' ');
+          }
+
+          auto i = val.m_value.object->cbegin();
+          for(std::size_t cnt = 0; cnt < val.m_value.object->size()-1; ++cnt, ++i) {
+            o->write_characters(indent_string.c_str(), new_indent);
+            o->write_character('\"');
+            dump_escaped(i->first, ensure_ascii);
+            o->write_characters("\": ", 3);
+            dump(i->second, true, ensure_ascii, indent_step, new_indent);
+            o->write_characters(",\n", 2);
+          }
+
+          assert(i != val.m_value.object->cend());
+          assert(std::next(i) == val.m_value.object->cend());
+          o->write_characters(indent_string.c_str(), new_indent);
+          o->write_character('\"');
+          dump_escaped(i->first, ensure_ascii);
+          o->write_characters("\": ", 3);
+          dump(i->second, true, ensure_ascii, indent_step, new_indent);
+
+          o->write_character('\n');
+          o->write_characters(indent_string.c_str(), current_indent);
+          o->write_character('}');
+        } else {
+          o->write_character('{');
+
+          auto i = val.m_value.object->cbegin();
+          for(std::size_t cnt = 0; cnt < val.m_value.object->size()-1; ++cnt, ++i) {
+            o->write_character('\"');
+            dump_escaped(i->first, ensure_ascii);
+            o->write_characters("\":", 2);
+            dump(i->second, false, ensure_ascii, indent_step, current_indent);
+            o->write_character(',');
+          }
+
+          assert(i != val.m_value.object->cend());
+          assert(std::next(i) == val.m_value.object->cend());
+          o->write_character('\"');
+          dump_escaped(i->first, ensure_ascii);
+          o->write_characters("\":", 2);
+          dump(i->second, false, ensure_ascii, indent_step, current_indent);
+
+          o->write_character('}');
+        }
+
+        return;
+      }
+
+      case value_t::array: {
+        if(val.m_value.array->empty()) {
+          o->write_characters("[]", 2);
+          return;
+        }
+
+        if(pretty_print) {
+          o->write_characters("[\n", 2);
+
+          const auto new_indent = current_indent+indent_step;
+          if(JSON_UNLIKELY(indent_string.size() < new_indent)) {
+            indent_string.resize(indent_string.size() * 2, ' ');
+          }
+
+          for(auto i = val.m_value.array->cbegin();
+              i != val.m_value.array->cend()-1; ++i) {
+            o->write_characters(indent_string.c_str(), new_indent);
+            dump(*i, true, ensure_ascii, indent_step, new_indent);
+            o->write_characters(",\n", 2);
+          }
+
+          assert(not val.m_value.array->empty());
+          o->write_characters(indent_string.c_str(), new_indent);
+          dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
+
+          o->write_character('\n');
+          o->write_characters(indent_string.c_str(), current_indent);
+          o->write_character(']');
+        } else {
+          o->write_character('[');
+
+          for(auto i = val.m_value.array->cbegin();
+              i != val.m_value.array->cend()-1; ++i) {
+            dump(*i, false, ensure_ascii, indent_step, current_indent);
+            o->write_character(',');
+          }
+
+          assert(not val.m_value.array->empty());
+          dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
+
+          o->write_character(']');
+        }
+
+        return;
+      }
+
+      case value_t::string: {
+        o->write_character('\"');
+        dump_escaped(*val.m_value.string, ensure_ascii);
+        o->write_character('\"');
+        return;
+      }
+
+      case value_t::boolean: {
+        if(val.m_value.boolean) {
+          o->write_characters("true", 4);
+        } else {
+          o->write_characters("false", 5);
+        }
+        return;
+      }
+
+      case value_t::number_integer: {
+        dump_integer(val.m_value.number_integer);
+        return;
+      }
+
+      case value_t::number_unsigned: {
+        dump_integer(val.m_value.number_unsigned);
+        return;
+      }
+
+      case value_t::number_float: {
+        dump_float(val.m_value.number_float);
+        return;
+      }
+
+      case value_t::discarded: {
+        o->write_characters("<discarded>", 11);
+        return;
+      }
+
+      case value_t::null: {
+        o->write_characters("null", 4);
+        return;
+      }
+    }
+  }
+
+private:
+  void dump_escaped(const string_t &s, const bool ensure_ascii) {
+    uint32_t codepoint;
+    uint8_t state = UTF8_ACCEPT;
+    std::size_t bytes = 0;
+
+    for(std::size_t i = 0; i < s.size(); ++i) {
+      const auto byte = static_cast<uint8_t>(s[i]);
+
+      switch(decode(state, codepoint, byte)) {
+        case UTF8_ACCEPT: {
+          switch(codepoint) {
+            case 0x08: {
+              string_buffer[bytes++] = '\\';
+              string_buffer[bytes++] = 'b';
+              break;
+            }
+
+            case 0x09: {
+              string_buffer[bytes++] = '\\';
+              string_buffer[bytes++] = 't';
+              break;
+            }
+
+            case 0x0A: {
+              string_buffer[bytes++] = '\\';
+              string_buffer[bytes++] = 'n';
+              break;
+            }
+
+            case 0x0C: {
+              string_buffer[bytes++] = '\\';
+              string_buffer[bytes++] = 'f';
+              break;
+            }
+
+            case 0x0D: {
+              string_buffer[bytes++] = '\\';
+              string_buffer[bytes++] = 'r';
+              break;
+            }
+
+            case 0x22: {
+              string_buffer[bytes++] = '\\';
+              string_buffer[bytes++] = '\"';
+              break;
+            }
+
+            case 0x5C: {
+              string_buffer[bytes++] = '\\';
+              string_buffer[bytes++] = '\\';
+              break;
+            }
+
+            default: {
+              if((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F))) {
+                if(codepoint <= 0xFFFF) {
+                  std::snprintf(string_buffer.data()+bytes, 7, "\\u%04x",
+                                static_cast<uint16_t>(codepoint));
+                  bytes += 6;
+                } else {
+                  std::snprintf(string_buffer.data()+bytes, 13, "\\u%04x\\u%04x",
+                                static_cast<uint16_t>(0xD7C0+(codepoint >> 10)),
+                                static_cast<uint16_t>(0xDC00+(codepoint & 0x3FF)));
+                  bytes += 12;
+                }
+              } else {
+                string_buffer[bytes++] = s[i];
+              }
+              break;
+            }
+          }
+
+          if(string_buffer.size()-bytes < 13) {
+            o->write_characters(string_buffer.data(), bytes);
+            bytes = 0;
+          }
+          break;
+        }
+
+        case UTF8_REJECT: {
+          std::stringstream ss;
+          ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(byte);
+          JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index "+std::to_string(i)+": 0x"+ss.str()));
+        }
+
+        default: {
+          if(not ensure_ascii) {
+            string_buffer[bytes++] = s[i];
+          }
+          break;
+        }
+      }
+    }
+
+    if(JSON_LIKELY(state == UTF8_ACCEPT)) {
+      if(bytes > 0) {
+        o->write_characters(string_buffer.data(), bytes);
+      }
+    } else {
+      std::stringstream ss;
+      ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex
+         << static_cast<int>(static_cast<uint8_t>(s.back()));
+      JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x"+ss.str()));
+    }
+  }
+
+  template<typename NumberType, detail::enable_if_t<
+      std::is_same<NumberType, number_unsigned_t>::value or
+      std::is_same<NumberType, number_integer_t>::value,
+      int> = 0>
+  void dump_integer(NumberType x) {
+    if(x == 0) {
+      o->write_character('0');
+      return;
+    }
+
+    const bool is_negative = (x <= 0) and (x != 0);
+    std::size_t i = 0;
+
+    while(x != 0) {
+      assert(i < number_buffer.size()-1);
+
+      const auto digit = std::labs(static_cast<long>(x % 10));
+      number_buffer[i++] = static_cast<char>('0'+digit);
+      x /= 10;
+    }
+
+    if(is_negative) {
+      assert(i < number_buffer.size()-2);
+      number_buffer[i++] = '-';
+    }
+
+    std::reverse(number_buffer.begin(), number_buffer.begin()+i);
+    o->write_characters(number_buffer.data(), i);
+  }
+
+  void dump_float(number_float_t x) {
+    if(not std::isfinite(x)) {
+      o->write_characters("null", 4);
+      return;
+    }
+
+    //
+
+    static constexpr bool is_ieee_single_or_double
+        = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and
+           std::numeric_limits<number_float_t>::max_exponent == 128) or
+          (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and
+           std::numeric_limits<number_float_t>::max_exponent == 1024);
+
+    dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
+  }
+
+  void dump_float(number_float_t x, std::true_type) {
+    char *begin = number_buffer.data();
+    char *end = ::nlohmann::detail::to_chars(begin, begin+number_buffer.size(), x);
+
+    o->write_characters(begin, static_cast<size_t>(end-begin));
+  }
+
+  void dump_float(number_float_t x, std::false_type) {
+    static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
+
+    std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
+
+    assert(len > 0);
+
+    assert(static_cast<std::size_t>(len) < number_buffer.size());
+
+    if(thousands_sep != '\0') {
+      const auto end = std::remove(number_buffer.begin(),
+                                   number_buffer.begin()+len, thousands_sep);
+      std::fill(end, number_buffer.end(), '\0');
+      assert((end-number_buffer.begin()) <= len);
+      len = (end-number_buffer.begin());
+    }
+
+    if(decimal_point != '\0' and decimal_point != '.') {
+      const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
+      if(dec_pos != number_buffer.end()) {
+        *dec_pos = '.';
+      }
+    }
+
+    o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
+
+    const bool value_is_int_like =
+        std::none_of(number_buffer.begin(), number_buffer.begin()+len+1,
+                     [](char c) {
+                       return (c == '.' or c == 'e');
+                     });
+
+    if(value_is_int_like) {
+      o->write_characters(".0", 2);
+    }
+  }
+
+  static uint8_t decode(uint8_t &state, uint32_t &codep, const uint8_t byte) noexcept {
+    static const std::array<uint8_t, 400> utf8d =
+        {
+            {
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+                8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
+                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
+                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
+                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1,
+                1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+                1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1,
+                1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+            }
+        };
+
+    const uint8_t type = utf8d[byte];
+
+    codep = (state != UTF8_ACCEPT)
+            ? (byte & 0x3fu) | (codep << 6)
+            : static_cast<uint32_t>(0xff >> type) & (byte);
+
+    state = utf8d[256u+state * 16u+type];
+    return state;
+  }
+
+private:
+  output_adapter_t<char> o = nullptr;
+
+  std::array<char, 64> number_buffer{{}};
+
+  const std::lconv *loc = nullptr;
+
+  const char thousands_sep = '\0';
+
+  const char decimal_point = '\0';
+
+  std::array<char, 512> string_buffer{{}};
+
+  const char indent_char;
+
+  string_t indent_string;
+};
+}
+}
+
+namespace nlohmann {
+namespace detail {
+template<typename BasicJsonType>
+class json_ref {
+public:
+  using value_type = BasicJsonType;
+
+  json_ref(value_type &&value)
+      : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true) {}
+
+  json_ref(const value_type &value)
+      : value_ref(const_cast<value_type *>(&value)), is_rvalue(false) {}
+
+  json_ref(std::initializer_list<json_ref> init)
+      : owned_value(init), value_ref(&owned_value), is_rvalue(true) {}
+
+  template<class... Args>
+  json_ref(Args &&... args)
+      : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true) {}
+
+  json_ref(json_ref &&) = default;
+
+  json_ref(const json_ref &) = delete;
+
+  json_ref &operator=(const json_ref &) = delete;
+
+  value_type moved_or_copied() const {
+    if(is_rvalue) {
+      return std::move(*value_ref);
+    }
+    return *value_ref;
+  }
+
+  value_type const &operator*() const {
+    return *static_cast<value_type const *>(value_ref);
+  }
+
+  value_type const *operator->() const {
+    return static_cast<value_type const *>(value_ref);
+  }
+
+private:
+  mutable value_type owned_value = nullptr;
+  value_type *value_ref = nullptr;
+  const bool is_rvalue;
+};
+}
+}
+
+namespace nlohmann {
+template<typename BasicJsonType>
+class json_pointer {
+  NLOHMANN_BASIC_JSON_TPL_DECLARATION
+  friend
+  class basic_json;
+
+public:
+  explicit json_pointer(const std::string &s = "")
+      : reference_tokens(split(s)) {}
+
+  std::string to_string() const noexcept {
+    return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
+                           std::string{},
+                           [](const std::string &a, const std::string &b) {
+                             return a+"/"+escape(b);
+                           });
+  }
+
+  operator std::string() const {
+    return to_string();
+  }
+
+  static int array_index(const std::string &s) {
+    std::size_t processed_chars = 0;
+    const int res = std::stoi(s, &processed_chars);
+
+    if(JSON_UNLIKELY(processed_chars != s.size())) {
+      JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+s+"'"));
+    }
+
+    return res;
+  }
+
+private:
+  std::string pop_back() {
+    if(JSON_UNLIKELY(is_root())) {
+      JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+    }
+
+    auto last = reference_tokens.back();
+    reference_tokens.pop_back();
+    return last;
+  }
+
+  bool is_root() const {
+    return reference_tokens.empty();
+  }
+
+  json_pointer top() const {
+    if(JSON_UNLIKELY(is_root())) {
+      JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+    }
+
+    json_pointer result = *this;
+    result.reference_tokens = {reference_tokens[0]};
+    return result;
+  }
+
+  BasicJsonType &get_and_create(BasicJsonType &j) const {
+    using size_type = typename BasicJsonType::size_type;
+    auto result = &j;
+
+    for(const auto &reference_token : reference_tokens) {
+      switch(result->m_type) {
+        case detail::value_t::null: {
+          if(reference_token == "0") {
+            result = &result->operator[](0);
+          } else {
+            result = &result->operator[](reference_token);
+          }
+          break;
+        }
+
+        case detail::value_t::object: {
+          result = &result->operator[](reference_token);
+          break;
+        }
+
+        case detail::value_t::array: {
+          JSON_TRY {
+            result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
+          }
+          JSON_CATCH(std::invalid_argument &) {
+            JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+          }
+          break;
+        }
+
+        default:
+          JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
+      }
+    }
+
+    return *result;
+  }
+
+  BasicJsonType &get_unchecked(BasicJsonType *ptr) const {
+    using size_type = typename BasicJsonType::size_type;
+    for(const auto &reference_token : reference_tokens) {
+      if(ptr->m_type == detail::value_t::null) {
+        const bool nums =
+            std::all_of(reference_token.begin(), reference_token.end(),
+                        [](const char x) {
+                          return (x >= '0' and x <= '9');
+                        });
+
+        *ptr = (nums or reference_token == "-")
+               ? detail::value_t::array
+               : detail::value_t::object;
+      }
+
+      switch(ptr->m_type) {
+        case detail::value_t::object: {
+          ptr = &ptr->operator[](reference_token);
+          break;
+        }
+
+        case detail::value_t::array: {
+          if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
+            JSON_THROW(detail::parse_error::create(106, 0,
+                                                   "array index '"+reference_token+
+                                                   "' must not begin with '0'"));
+          }
+
+          if(reference_token == "-") {
+            ptr = &ptr->operator[](ptr->m_value.array->size());
+          } else {
+            JSON_TRY {
+              ptr = &ptr->operator[](
+                  static_cast<size_type>(array_index(reference_token)));
+            }
+            JSON_CATCH(std::invalid_argument &) {
+              JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+            }
+          }
+          break;
+        }
+
+        default:
+          JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
+      }
+    }
+
+    return *ptr;
+  }
+
+  BasicJsonType &get_checked(BasicJsonType *ptr) const {
+    using size_type = typename BasicJsonType::size_type;
+    for(const auto &reference_token : reference_tokens) {
+      switch(ptr->m_type) {
+        case detail::value_t::object: {
+          ptr = &ptr->at(reference_token);
+          break;
+        }
+
+        case detail::value_t::array: {
+          if(JSON_UNLIKELY(reference_token == "-")) {
+            JSON_THROW(detail::out_of_range::create(402,
+                                                    "array index '-' ("+std::to_string(ptr->m_value.array->size())+
+                                                    ") is out of range"));
+          }
+
+          if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
+            JSON_THROW(detail::parse_error::create(106, 0,
+                                                   "array index '"+reference_token+
+                                                   "' must not begin with '0'"));
+          }
+
+          JSON_TRY {
+            ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
+          }
+          JSON_CATCH(std::invalid_argument &) {
+            JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+          }
+          break;
+        }
+
+        default:
+          JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
+      }
+    }
+
+    return *ptr;
+  }
+
+  const BasicJsonType &get_unchecked(const BasicJsonType *ptr) const {
+    using size_type = typename BasicJsonType::size_type;
+    for(const auto &reference_token : reference_tokens) {
+      switch(ptr->m_type) {
+        case detail::value_t::object: {
+          ptr = &ptr->operator[](reference_token);
+          break;
+        }
+
+        case detail::value_t::array: {
+          if(JSON_UNLIKELY(reference_token == "-")) {
+            JSON_THROW(detail::out_of_range::create(402,
+                                                    "array index '-' ("+std::to_string(ptr->m_value.array->size())+
+                                                    ") is out of range"));
+          }
+
+          if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
+            JSON_THROW(detail::parse_error::create(106, 0,
+                                                   "array index '"+reference_token+
+                                                   "' must not begin with '0'"));
+          }
+
+          JSON_TRY {
+            ptr = &ptr->operator[](
+                static_cast<size_type>(array_index(reference_token)));
+          }
+          JSON_CATCH(std::invalid_argument &) {
+            JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+          }
+          break;
+        }
+
+        default:
+          JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
+      }
+    }
+
+    return *ptr;
+  }
+
+  const BasicJsonType &get_checked(const BasicJsonType *ptr) const {
+    using size_type = typename BasicJsonType::size_type;
+    for(const auto &reference_token : reference_tokens) {
+      switch(ptr->m_type) {
+        case detail::value_t::object: {
+          ptr = &ptr->at(reference_token);
+          break;
+        }
+
+        case detail::value_t::array: {
+          if(JSON_UNLIKELY(reference_token == "-")) {
+            JSON_THROW(detail::out_of_range::create(402,
+                                                    "array index '-' ("+std::to_string(ptr->m_value.array->size())+
+                                                    ") is out of range"));
+          }
+
+          if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
+            JSON_THROW(detail::parse_error::create(106, 0,
+                                                   "array index '"+reference_token+
+                                                   "' must not begin with '0'"));
+          }
+
+          JSON_TRY {
+            ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
+          }
+          JSON_CATCH(std::invalid_argument &) {
+            JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+          }
+          break;
+        }
+
+        default:
+          JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
+      }
+    }
+
+    return *ptr;
+  }
+
+  static std::vector<std::string> split(const std::string &reference_string) {
+    std::vector<std::string> result;
+
+    if(reference_string.empty()) {
+      return result;
+    }
+
+    if(JSON_UNLIKELY(reference_string[0] != '/')) {
+      JSON_THROW(detail::parse_error::create(107, 1,
+                                             "JSON pointer must be empty or begin with '/' - was: '"+
+                                             reference_string+"'"));
+    }
+
+    for(
+
+        std::size_t slash = reference_string.find_first_of('/', 1),
+
+            start = 1;
+
+        start != 0;
+
+        start = slash+1,
+
+            slash = reference_string.find_first_of('/', start)) {
+      auto reference_token = reference_string.substr(start, slash-start);
+
+      for(std::size_t pos = reference_token.find_first_of('~');
+          pos != std::string::npos;
+          pos = reference_token.find_first_of('~', pos+1)) {
+        assert(reference_token[pos] == '~');
+
+        if(JSON_UNLIKELY(pos == reference_token.size()-1 or
+                         (reference_token[pos+1] != '0' and
+                          reference_token[pos+1] != '1'))) {
+          JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
+        }
+      }
+
+      unescape(reference_token);
+      result.push_back(reference_token);
+    }
+
+    return result;
+  }
+
+  static void replace_substring(std::string &s, const std::string &f,
+                                const std::string &t) {
+    assert(not f.empty());
+    for(auto pos = s.find(f);
+        pos != std::string::npos;
+        s.replace(pos, f.size(), t),
+            pos = s.find(f, pos+t.size())) {}
+  }
+
+  static std::string escape(std::string s) {
+    replace_substring(s, "~", "~0");
+    replace_substring(s, "/", "~1");
+    return s;
+  }
+
+  static void unescape(std::string &s) {
+    replace_substring(s, "~1", "/");
+    replace_substring(s, "~0", "~");
+  }
+
+  static void flatten(const std::string &reference_string,
+                      const BasicJsonType &value,
+                      BasicJsonType &result) {
+    switch(value.m_type) {
+      case detail::value_t::array: {
+        if(value.m_value.array->empty()) {
+          result[reference_string] = nullptr;
+        } else {
+          for(std::size_t i = 0; i < value.m_value.array->size(); ++i) {
+            flatten(reference_string+"/"+std::to_string(i),
+                    value.m_value.array->operator[](i), result);
+          }
+        }
+        break;
+      }
+
+      case detail::value_t::object: {
+        if(value.m_value.object->empty()) {
+          result[reference_string] = nullptr;
+        } else {
+          for(const auto &element : *value.m_value.object) {
+            flatten(reference_string+"/"+escape(element.first), element.second, result);
+          }
+        }
+        break;
+      }
+
+      default: {
+        result[reference_string] = value;
+        break;
+      }
+    }
+  }
+
+  static BasicJsonType
+  unflatten(const BasicJsonType &value) {
+    if(JSON_UNLIKELY(not value.is_object())) {
+      JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
+    }
+
+    BasicJsonType result;
+
+    for(const auto &element : *value.m_value.object) {
+      if(JSON_UNLIKELY(not element.second.is_primitive())) {
+        JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
+      }
+
+      json_pointer(element.first).get_and_create(result) = element.second;
+    }
+
+    return result;
+  }
+
+  friend bool operator==(json_pointer const &lhs,
+                         json_pointer const &rhs) noexcept {
+    return (lhs.reference_tokens == rhs.reference_tokens);
+  }
+
+  friend bool operator!=(json_pointer const &lhs,
+                         json_pointer const &rhs) noexcept {
+    return not(lhs == rhs);
+  }
+
+  std::vector<std::string> reference_tokens;
+};
+}
+
+namespace nlohmann {
+template<typename, typename>
+struct adl_serializer {
+  template<typename BasicJsonType, typename ValueType>
+  static void from_json(BasicJsonType &&j, ValueType &val) noexcept(
+  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val))) {
+    ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
+  }
+
+  template<typename BasicJsonType, typename ValueType>
+  static void to_json(BasicJsonType &j, ValueType &&val) noexcept(
+  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val)))) {
+    ::nlohmann::to_json(j, std::forward<ValueType>(val));
+  }
+};
+}
+
+namespace nlohmann {
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+class basic_json {
+private:
+  template<detail::value_t> friend
+  struct detail::external_constructor;
+  friend ::nlohmann::json_pointer<basic_json>;
+  friend ::nlohmann::detail::parser<basic_json>;
+  friend ::nlohmann::detail::serializer<basic_json>;
+
+  template<typename BasicJsonType>
+  friend
+  class ::nlohmann::detail::iter_impl;
+
+  template<typename BasicJsonType, typename CharType>
+  friend
+  class ::nlohmann::detail::binary_writer;
+
+  template<typename BasicJsonType>
+  friend
+  class ::nlohmann::detail::binary_reader;
+
+  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
+
+  using lexer = ::nlohmann::detail::lexer<basic_json>;
+  using parser = ::nlohmann::detail::parser<basic_json>;
+
+  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
+  template<typename BasicJsonType>
+  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
+  template<typename BasicJsonType>
+  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
+  template<typename Iterator>
+  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
+  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
+
+  template<typename CharType>
+  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
+
+  using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
+  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
+
+  using serializer = ::nlohmann::detail::serializer<basic_json>;
+
+public:
+  using value_t = detail::value_t;
+
+  using json_pointer = ::nlohmann::json_pointer<basic_json>;
+  template<typename T, typename SFINAE>
+  using json_serializer = JSONSerializer<T, SFINAE>;
+
+  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
+
+  using exception = detail::exception;
+
+  using parse_error = detail::parse_error;
+
+  using invalid_iterator = detail::invalid_iterator;
+
+  using type_error = detail::type_error;
+
+  using out_of_range = detail::out_of_range;
+
+  using other_error = detail::other_error;
+
+  using value_type = basic_json;
+
+  using reference = value_type &;
+
+  using const_reference = const value_type &;
+
+  using difference_type = std::ptrdiff_t;
+
+  using size_type = std::size_t;
+
+  using allocator_type = AllocatorType<basic_json>;
+
+  using pointer = typename std::allocator_traits<allocator_type>::pointer;
+
+  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
+
+  using iterator = iter_impl<basic_json>;
+
+  using const_iterator = iter_impl<const basic_json>;
+
+  using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
+
+  using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
+
+  static allocator_type get_allocator() {
+    return allocator_type();
+  }
+
+  static basic_json meta() {
+    basic_json result;
+
+    result["copyright"] = "(C) 2013-2017 Niels Lohmann";
+    result["name"] = "JSON for Modern C++";
+    result["version"]["string"] =
+        std::to_string(NLOHMANN_JSON_VERSION_MAJOR)+"."+
+        std::to_string(NLOHMANN_JSON_VERSION_MINOR)+"."+
+        std::to_string(NLOHMANN_JSON_VERSION_PATCH);
+    result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
+    result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
+    result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
+
+#ifdef _WIN32
+    result["platform"] = "win32";
+#elif defined __linux__
+    result["platform"] = "linux";
+#elif defined __APPLE__
+        result["platform"] = "apple";
+#elif defined __unix__
+        result["platform"] = "unix";
+#else
+        result["platform"] = "unknown";
+#endif
+
+#if defined(__ICC) || defined(__INTEL_COMPILER)
+    result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
+#elif defined(__clang__)
+    result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
+#elif defined(__GNUC__) || defined(__GNUG__)
+    result["compiler"] = {{"family",  "gcc"},
+                          {"version", std::to_string(__GNUC__)+"."+std::to_string(__GNUC_MINOR__)+"."+
+                                      std::to_string(__GNUC_PATCHLEVEL__)}};
+#elif defined(__HP_cc) || defined(__HP_aCC)
+    result["compiler"] = "hp"
+#elif defined(__IBMCPP__)
+        result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
+#elif defined(_MSC_VER)
+        result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
+#elif defined(__PGI)
+        result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
+#elif defined(__SUNPRO_CC)
+        result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
+#else
+        result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
+#endif
+
+#ifdef __cplusplus
+    result["compiler"]["c++"] = std::to_string(__cplusplus);
+#else
+    result["compiler"]["c++"] = "unknown";
+#endif
+    return result;
+  }
+
+#if defined(JSON_HAS_CPP_14)
+
+  using object_comparator_t = std::less<>;
+#else
+  using object_comparator_t = std::less<StringType>;
+#endif
+
+  using object_t = ObjectType<StringType,
+      basic_json,
+      object_comparator_t,
+      AllocatorType<std::pair<const StringType,
+          basic_json>>>;
+
+  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
+
+  using string_t = StringType;
+
+  using boolean_t = BooleanType;
+
+  using number_integer_t = NumberIntegerType;
+
+  using number_unsigned_t = NumberUnsignedType;
+
+  using number_float_t = NumberFloatType;
+
+private:
+  template<typename T, typename... Args>
+  static T *create(Args &&... args) {
+    AllocatorType<T> alloc;
+    using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
+
+    auto deleter = [&](T *object) {
+      AllocatorTraits::deallocate(alloc, object, 1);
+    };
+    std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
+    AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
+    assert(object != nullptr);
+    return object.release();
+  }
+
+  union json_value {
+    object_t *object;
+
+    array_t *array;
+
+    string_t *string;
+
+    boolean_t boolean;
+
+    number_integer_t number_integer;
+
+    number_unsigned_t number_unsigned;
+
+    number_float_t number_float;
+
+    json_value() = default;
+
+    json_value(boolean_t v) noexcept : boolean(v) {}
+
+    json_value(number_integer_t v) noexcept : number_integer(v) {}
+
+    json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
+
+    json_value(number_float_t v) noexcept : number_float(v) {}
+
+    json_value(value_t t) {
+      switch(t) {
+        case value_t::object: {
+          object = create<object_t>();
+          break;
+        }
+
+        case value_t::array: {
+          array = create<array_t>();
+          break;
+        }
+
+        case value_t::string: {
+          string = create<string_t>("");
+          break;
+        }
+
+        case value_t::boolean: {
+          boolean = boolean_t(false);
+          break;
+        }
+
+        case value_t::number_integer: {
+          number_integer = number_integer_t(0);
+          break;
+        }
+
+        case value_t::number_unsigned: {
+          number_unsigned = number_unsigned_t(0);
+          break;
+        }
+
+        case value_t::number_float: {
+          number_float = number_float_t(0.0);
+          break;
+        }
+
+        case value_t::null: {
+          object = nullptr;
+          break;
+        }
+
+        default: {
+          object = nullptr;
+          if(JSON_UNLIKELY(t == value_t::null)) {
+            JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2"));
+          }
+          break;
+        }
+      }
+    }
+
+    json_value(const string_t &value) {
+      string = create<string_t>(value);
+    }
+
+    json_value(string_t &&value) {
+      string = create<string_t>(std::move(value));
+    }
+
+    json_value(const object_t &value) {
+      object = create<object_t>(value);
+    }
+
+    json_value(object_t &&value) {
+      object = create<object_t>(std::move(value));
+    }
+
+    json_value(const array_t &value) {
+      array = create<array_t>(value);
+    }
+
+    json_value(array_t &&value) {
+      array = create<array_t>(std::move(value));
+    }
+
+    void destroy(value_t t) noexcept {
+      switch(t) {
+        case value_t::object: {
+          AllocatorType<object_t> alloc;
+          std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
+          std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
+          break;
+        }
+
+        case value_t::array: {
+          AllocatorType<array_t> alloc;
+          std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
+          std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
+          break;
+        }
+
+        case value_t::string: {
+          AllocatorType<string_t> alloc;
+          std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
+          std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
+          break;
+        }
+
+        default: {
+          break;
+        }
+      }
+    }
+  };
+
+  void assert_invariant() const noexcept {
+    assert(m_type != value_t::object or m_value.object != nullptr);
+    assert(m_type != value_t::array or m_value.array != nullptr);
+    assert(m_type != value_t::string or m_value.string != nullptr);
+  }
+
+public:
+  using parse_event_t = typename parser::parse_event_t;
+
+  using parser_callback_t = typename parser::parser_callback_t;
+
+  basic_json(const value_t v)
+      : m_type(v), m_value(v) {
+    assert_invariant();
+  }
+
+  basic_json(std::nullptr_t = nullptr) noexcept
+      : basic_json(value_t::null) {
+    assert_invariant();
+  }
+
+  template<typename CompatibleType,
+      typename U = detail::uncvref_t<CompatibleType>,
+      detail::enable_if_t<
+          detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
+  basic_json(CompatibleType &&val) noexcept(noexcept(
+      JSONSerializer<U>::to_json(std::declval<basic_json_t &>(),
+                                 std::forward<CompatibleType>(val)))) {
+    JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
+    assert_invariant();
+  }
+
+  template<typename BasicJsonType,
+      detail::enable_if_t<
+          detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
+  basic_json(const BasicJsonType &val) {
+    using other_boolean_t = typename BasicJsonType::boolean_t;
+    using other_number_float_t = typename BasicJsonType::number_float_t;
+    using other_number_integer_t = typename BasicJsonType::number_integer_t;
+    using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using other_string_t = typename BasicJsonType::string_t;
+    using other_object_t = typename BasicJsonType::object_t;
+    using other_array_t = typename BasicJsonType::array_t;
+
+    switch(val.type()) {
+      case value_t::boolean:
+        JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
+        break;
+      case value_t::number_float:
+        JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
+        break;
+      case value_t::number_integer:
+        JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
+        break;
+      case value_t::number_unsigned:
+        JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
+        break;
+      case value_t::string:
+        JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t &>());
+        break;
+      case value_t::object:
+        JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t &>());
+        break;
+      case value_t::array:
+        JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t &>());
+        break;
+      case value_t::null:
+        *this = nullptr;
+        break;
+      case value_t::discarded:
+        m_type = value_t::discarded;
+        break;
+    }
+    assert_invariant();
+  }
+
+  basic_json(initializer_list_t init,
+             bool type_deduction = true,
+             value_t manual_type = value_t::array) {
+    bool is_an_object = std::all_of(init.begin(), init.end(),
+                                    [](const detail::json_ref<basic_json> &element_ref) {
+                                      return (element_ref->is_array() and element_ref->size() == 2 and
+                                              (*element_ref)[0].is_string());
+                                    });
+
+    if(not type_deduction) {
+      if(manual_type == value_t::array) {
+        is_an_object = false;
+      }
+
+      if(JSON_UNLIKELY(manual_type == value_t::object and not is_an_object)) {
+        JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
+      }
+    }
+
+    if(is_an_object) {
+      m_type = value_t::object;
+      m_value = value_t::object;
+
+      std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json> &element_ref) {
+        auto element = element_ref.moved_or_copied();
+        m_value.object->emplace(
+            std::move(*((*element.m_value.array)[0].m_value.string)),
+            std::move((*element.m_value.array)[1]));
+      });
+    } else {
+      m_type = value_t::array;
+      m_value.array = create<array_t>(init.begin(), init.end());
+    }
+
+    assert_invariant();
+  }
+
+  static basic_json array(initializer_list_t init = {}) {
+    return basic_json(init, false, value_t::array);
+  }
+
+  static basic_json object(initializer_list_t init = {}) {
+    return basic_json(init, false, value_t::object);
+  }
+
+  basic_json(size_type cnt, const basic_json &val)
+      : m_type(value_t::array) {
+    m_value.array = create<array_t>(cnt, val);
+    assert_invariant();
+  }
+
+  template<class InputIT, typename std::enable_if<
+      std::is_same<InputIT, typename basic_json_t::iterator>::value or
+      std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
+  basic_json(InputIT first, InputIT last) {
+    assert(first.m_object != nullptr);
+    assert(last.m_object != nullptr);
+
+    if(JSON_UNLIKELY(first.m_object != last.m_object)) {
+      JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
+    }
+
+    m_type = first.m_object->m_type;
+
+    switch(m_type) {
+      case value_t::boolean:
+      case value_t::number_float:
+      case value_t::number_integer:
+      case value_t::number_unsigned:
+      case value_t::string: {
+        if(JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
+                         or not last.m_it.primitive_iterator.is_end())) {
+          JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+        }
+        break;
+      }
+
+      default:
+        break;
+    }
+
+    switch(m_type) {
+      case value_t::number_integer: {
+        m_value.number_integer = first.m_object->m_value.number_integer;
+        break;
+      }
+
+      case value_t::number_unsigned: {
+        m_value.number_unsigned = first.m_object->m_value.number_unsigned;
+        break;
+      }
+
+      case value_t::number_float: {
+        m_value.number_float = first.m_object->m_value.number_float;
+        break;
+      }
+
+      case value_t::boolean: {
+        m_value.boolean = first.m_object->m_value.boolean;
+        break;
+      }
+
+      case value_t::string: {
+        m_value = *first.m_object->m_value.string;
+        break;
+      }
+
+      case value_t::object: {
+        m_value.object = create<object_t>(first.m_it.object_iterator,
+                                          last.m_it.object_iterator);
+        break;
+      }
+
+      case value_t::array: {
+        m_value.array = create<array_t>(first.m_it.array_iterator,
+                                        last.m_it.array_iterator);
+        break;
+      }
+
+      default:
+        JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from "+
+                                                 std::string(first.m_object->type_name())));
+    }
+
+    assert_invariant();
+  }
+
+  basic_json(const detail::json_ref<basic_json> &ref)
+      : basic_json(ref.moved_or_copied()) {}
+
+  basic_json(const basic_json &other)
+      : m_type(other.m_type) {
+    other.assert_invariant();
+
+    switch(m_type) {
+      case value_t::object: {
+        m_value = *other.m_value.object;
+        break;
+      }
+
+      case value_t::array: {
+        m_value = *other.m_value.array;
+        break;
+      }
+
+      case value_t::string: {
+        m_value = *other.m_value.string;
+        break;
+      }
+
+      case value_t::boolean: {
+        m_value = other.m_value.boolean;
+        break;
+      }
+
+      case value_t::number_integer: {
+        m_value = other.m_value.number_integer;
+        break;
+      }
+
+      case value_t::number_unsigned: {
+        m_value = other.m_value.number_unsigned;
+        break;
+      }
+
+      case value_t::number_float: {
+        m_value = other.m_value.number_float;
+        break;
+      }
+
+      default:
+        break;
+    }
+
+    assert_invariant();
+  }
+
+  basic_json(basic_json &&other) noexcept
+      : m_type(std::move(other.m_type)),
+        m_value(std::move(other.m_value)) {
+    other.assert_invariant();
+
+    other.m_type = value_t::null;
+    other.m_value = {};
+
+    assert_invariant();
+  }
+
+  reference &operator=(basic_json other) noexcept(
+  std::is_nothrow_move_constructible<value_t>::value and
+  std::is_nothrow_move_assignable<value_t>::value and
+  std::is_nothrow_move_constructible<json_value>::value and
+  std::is_nothrow_move_assignable<json_value>::value
+  ) {
+    other.assert_invariant();
+
+    using std::swap;
+    swap(m_type, other.m_type);
+    swap(m_value, other.m_value);
+
+    assert_invariant();
+    return *this;
+  }
+
+  ~basic_json() noexcept {
+    assert_invariant();
+    m_value.destroy(m_type);
+  }
+
+public:
+  string_t dump(const int indent = -1, const char indent_char = ' ',
+                const bool ensure_ascii = false) const {
+    string_t result;
+    serializer s(detail::output_adapter<char, string_t>(result), indent_char);
+
+    if(indent >= 0) {
+      s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
+    } else {
+      s.dump(*this, false, ensure_ascii, 0);
+    }
+
+    return result;
+  }
+
+  constexpr value_t type() const noexcept {
+    return m_type;
+  }
+
+  constexpr bool is_primitive() const noexcept {
+    return is_null() or is_string() or is_boolean() or is_number();
+  }
+
+  constexpr bool is_structured() const noexcept {
+    return is_array() or is_object();
+  }
+
+  constexpr bool is_null() const noexcept {
+    return (m_type == value_t::null);
+  }
+
+  constexpr bool is_boolean() const noexcept {
+    return (m_type == value_t::boolean);
+  }
+
+  constexpr bool is_number() const noexcept {
+    return is_number_integer() or is_number_float();
+  }
+
+  constexpr bool is_number_integer() const noexcept {
+    return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
+  }
+
+  constexpr bool is_number_unsigned() const noexcept {
+    return (m_type == value_t::number_unsigned);
+  }
+
+  constexpr bool is_number_float() const noexcept {
+    return (m_type == value_t::number_float);
+  }
+
+  constexpr bool is_object() const noexcept {
+    return (m_type == value_t::object);
+  }
+
+  constexpr bool is_array() const noexcept {
+    return (m_type == value_t::array);
+  }
+
+  constexpr bool is_string() const noexcept {
+    return (m_type == value_t::string);
+  }
+
+  constexpr bool is_discarded() const noexcept {
+    return (m_type == value_t::discarded);
+  }
+
+  constexpr operator value_t() const noexcept {
+    return m_type;
+  }
+
+private:
+  boolean_t get_impl(boolean_t *) const {
+    if(JSON_LIKELY(is_boolean())) {
+      return m_value.boolean;
+    }
+
+    JSON_THROW(type_error::create(302, "type must be boolean, but is "+std::string(type_name())));
+  }
+
+  object_t *get_impl_ptr(object_t *) noexcept {
+    return is_object() ? m_value.object : nullptr;
+  }
+
+  constexpr const object_t *get_impl_ptr(const object_t *) const noexcept {
+    return is_object() ? m_value.object : nullptr;
+  }
+
+  array_t *get_impl_ptr(array_t *) noexcept {
+    return is_array() ? m_value.array : nullptr;
+  }
+
+  constexpr const array_t *get_impl_ptr(const array_t *) const noexcept {
+    return is_array() ? m_value.array : nullptr;
+  }
+
+  string_t *get_impl_ptr(string_t *) noexcept {
+    return is_string() ? m_value.string : nullptr;
+  }
+
+  constexpr const string_t *get_impl_ptr(const string_t *) const noexcept {
+    return is_string() ? m_value.string : nullptr;
+  }
+
+  boolean_t *get_impl_ptr(boolean_t *) noexcept {
+    return is_boolean() ? &m_value.boolean : nullptr;
+  }
+
+  constexpr const boolean_t *get_impl_ptr(const boolean_t *) const noexcept {
+    return is_boolean() ? &m_value.boolean : nullptr;
+  }
+
+  number_integer_t *get_impl_ptr(number_integer_t *) noexcept {
+    return is_number_integer() ? &m_value.number_integer : nullptr;
+  }
+
+  constexpr const number_integer_t *get_impl_ptr(const number_integer_t *) const noexcept {
+    return is_number_integer() ? &m_value.number_integer : nullptr;
+  }
+
+  number_unsigned_t *get_impl_ptr(number_unsigned_t *) noexcept {
+    return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
+  }
+
+  constexpr const number_unsigned_t *get_impl_ptr(const number_unsigned_t *) const noexcept {
+    return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
+  }
+
+  number_float_t *get_impl_ptr(number_float_t *) noexcept {
+    return is_number_float() ? &m_value.number_float : nullptr;
+  }
+
+  constexpr const number_float_t *get_impl_ptr(const number_float_t *) const noexcept {
+    return is_number_float() ? &m_value.number_float : nullptr;
+  }
+
+  template<typename ReferenceType, typename ThisType>
+  static ReferenceType get_ref_impl(ThisType &obj) {
+    auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
+
+    if(JSON_LIKELY(ptr != nullptr)) {
+      return *ptr;
+    }
+
+    JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is "+
+                                       std::string(obj.type_name())));
+  }
+
+public:
+  template<typename BasicJsonType, detail::enable_if_t<
+      std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
+      int> = 0>
+  basic_json get() const {
+    return *this;
+  }
+
+  template<typename BasicJsonType, detail::enable_if_t<
+      not std::is_same<BasicJsonType, basic_json>::value and
+      detail::is_basic_json<BasicJsonType>::value, int> = 0>
+  BasicJsonType get() const {
+    return *this;
+  }
+
+  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
+      detail::enable_if_t<
+          not detail::is_basic_json<ValueType>::value and
+          detail::has_from_json<basic_json_t, ValueType>::value and
+          not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
+          int> = 0>
+  ValueType get() const noexcept(noexcept(
+      JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t &>(), std::declval<ValueType &>()))) {
+    static_assert(not std::is_reference<ValueTypeCV>::value,
+                  "get() cannot be used with reference types, you might want to use get_ref()");
+    static_assert(std::is_default_constructible<ValueType>::value,
+                  "types must be DefaultConstructible when used with get()");
+
+    ValueType ret;
+    JSONSerializer<ValueType>::from_json(*this, ret);
+    return ret;
+  }
+
+  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
+      detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
+                          detail::has_non_default_from_json<basic_json_t, ValueType>::value,
+          int> = 0>
+  ValueType get() const noexcept(noexcept(
+      JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t &>()))) {
+    static_assert(not std::is_reference<ValueTypeCV>::value,
+                  "get() cannot be used with reference types, you might want to use get_ref()");
+    return JSONSerializer<ValueTypeCV>::from_json(*this);
+  }
+
+  template<typename PointerType, typename std::enable_if<
+      std::is_pointer<PointerType>::value, int>::type = 0>
+  PointerType get() noexcept {
+    return get_ptr<PointerType>();
+  }
+
+  template<typename PointerType, typename std::enable_if<
+      std::is_pointer<PointerType>::value, int>::type = 0>
+  constexpr const PointerType get() const noexcept {
+    return get_ptr<PointerType>();
+  }
+
+  template<typename PointerType, typename std::enable_if<
+      std::is_pointer<PointerType>::value, int>::type = 0>
+  PointerType get_ptr() noexcept {
+    using pointee_t = typename std::remove_const<typename
+    std::remove_pointer<typename
+    std::remove_const<PointerType>::type>::type>::type;
+
+    static_assert(
+        std::is_same<object_t, pointee_t>::value
+        or std::is_same<array_t, pointee_t>::value
+        or std::is_same<string_t, pointee_t>::value
+        or std::is_same<boolean_t, pointee_t>::value
+        or std::is_same<number_integer_t, pointee_t>::value
+        or std::is_same<number_unsigned_t, pointee_t>::value
+        or std::is_same<number_float_t, pointee_t>::value, "incompatible pointer type");
+
+    return get_impl_ptr(static_cast<PointerType>(nullptr));
+  }
+
+  template<typename PointerType, typename std::enable_if<
+      std::is_pointer<PointerType>::value and
+      std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
+  constexpr const PointerType get_ptr() const noexcept {
+    using pointee_t = typename std::remove_const<typename
+    std::remove_pointer<typename
+    std::remove_const<PointerType>::type>::type>::type;
+
+    static_assert(
+        std::is_same<object_t, pointee_t>::value
+        or std::is_same<array_t, pointee_t>::value
+        or std::is_same<string_t, pointee_t>::value
+        or std::is_same<boolean_t, pointee_t>::value
+        or std::is_same<number_integer_t, pointee_t>::value
+        or std::is_same<number_unsigned_t, pointee_t>::value
+        or std::is_same<number_float_t, pointee_t>::value, "incompatible pointer type");
+
+    return get_impl_ptr(static_cast<PointerType>(nullptr));
+  }
+
+  template<typename ReferenceType, typename std::enable_if<
+      std::is_reference<ReferenceType>::value, int>::type = 0>
+  ReferenceType get_ref() {
+    return get_ref_impl<ReferenceType>(*this);
+  }
+
+  template<typename ReferenceType, typename std::enable_if<
+      std::is_reference<ReferenceType>::value and
+      std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
+  ReferenceType get_ref() const {
+    return get_ref_impl<ReferenceType>(*this);
+  }
+
+  template<typename ValueType, typename std::enable_if<
+      not std::is_pointer<ValueType>::value and
+      not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
+      not std::is_same<ValueType, typename string_t::value_type>::value and
+      not detail::is_basic_json<ValueType>::value
+      #ifndef _MSC_VER
+      and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
+#endif
+#if defined(JSON_HAS_CPP_17)
+      and not std::is_same<ValueType, typename std::string_view>::value
+#endif
+      , int>::type = 0>
+  operator ValueType() const {
+    return get<ValueType>();
+  }
+
+  reference at(size_type idx) {
+    if(JSON_LIKELY(is_array())) {
+      JSON_TRY {
+        return m_value.array->at(idx);
+      }
+      JSON_CATCH (std::out_of_range &) {
+        JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+      }
+    } else {
+      JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
+    }
+  }
+
+  const_reference at(size_type idx) const {
+    if(JSON_LIKELY(is_array())) {
+      JSON_TRY {
+        return m_value.array->at(idx);
+      }
+      JSON_CATCH (std::out_of_range &) {
+        JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+      }
+    } else {
+      JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
+    }
+  }
+
+  reference at(const typename object_t::key_type &key) {
+    if(JSON_LIKELY(is_object())) {
+      JSON_TRY {
+        return m_value.object->at(key);
+      }
+      JSON_CATCH (std::out_of_range &) {
+        JSON_THROW(out_of_range::create(403, "key '"+key+"' not found"));
+      }
+    } else {
+      JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
+    }
+  }
+
+  const_reference at(const typename object_t::key_type &key) const {
+    if(JSON_LIKELY(is_object())) {
+      JSON_TRY {
+        return m_value.object->at(key);
+      }
+      JSON_CATCH (std::out_of_range &) {
+        JSON_THROW(out_of_range::create(403, "key '"+key+"' not found"));
+      }
+    } else {
+      JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
+    }
+  }
+
+  reference operator[](size_type idx) {
+    if(is_null()) {
+      m_type = value_t::array;
+      m_value.array = create<array_t>();
+      assert_invariant();
+    }
+
+    if(JSON_LIKELY(is_array())) {
+      if(idx >= m_value.array->size()) {
+        m_value.array->insert(m_value.array->end(),
+                              idx-m_value.array->size()+1,
+                              basic_json());
+      }
+
+      return m_value.array->operator[](idx);
+    }
+
+    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
+  }
+
+  const_reference operator[](size_type idx) const {
+    if(JSON_LIKELY(is_array())) {
+      return m_value.array->operator[](idx);
+    }
+
+    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
+  }
+
+  reference operator[](const typename object_t::key_type &key) {
+    if(is_null()) {
+      m_type = value_t::object;
+      m_value.object = create<object_t>();
+      assert_invariant();
+    }
+
+    if(JSON_LIKELY(is_object())) {
+      return m_value.object->operator[](key);
+    }
+
+    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
+  }
+
+  const_reference operator[](const typename object_t::key_type &key) const {
+    if(JSON_LIKELY(is_object())) {
+      assert(m_value.object->find(key) != m_value.object->end());
+      return m_value.object->find(key)->second;
+    }
+
+    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
+  }
+
+  template<typename T>
+  reference operator[](T *key) {
+    if(is_null()) {
+      m_type = value_t::object;
+      m_value = value_t::object;
+      assert_invariant();
+    }
+
+    if(JSON_LIKELY(is_object())) {
+      return m_value.object->operator[](key);
+    }
+
+    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
+  }
+
+  template<typename T>
+  const_reference operator[](T *key) const {
+    if(JSON_LIKELY(is_object())) {
+      assert(m_value.object->find(key) != m_value.object->end());
+      return m_value.object->find(key)->second;
+    }
+
+    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
+  }
+
+  template<class ValueType, typename std::enable_if<
+      std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
+  ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const {
+    if(JSON_LIKELY(is_object())) {
+      const auto it = find(key);
+      if(it != end()) {
+        return *it;
+      }
+
+      return default_value;
+    }
+
+    JSON_THROW(type_error::create(306, "cannot use value() with "+std::string(type_name())));
+  }
+
+  string_t value(const typename object_t::key_type &key, const char *default_value) const {
+    return value(key, string_t(default_value));
+  }
+
+  template<class ValueType, typename std::enable_if<
+      std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
+  ValueType value(const json_pointer &ptr, const ValueType &default_value) const {
+    if(JSON_LIKELY(is_object())) {
+      JSON_TRY {
+        return ptr.get_checked(this);
+      }
+      JSON_CATCH (out_of_range &) {
+        return default_value;
+      }
+    }
+
+    JSON_THROW(type_error::create(306, "cannot use value() with "+std::string(type_name())));
+  }
+
+  string_t value(const json_pointer &ptr, const char *default_value) const {
+    return value(ptr, string_t(default_value));
+  }
+
+  reference front() {
+    return *begin();
+  }
+
+  const_reference front() const {
+    return *cbegin();
+  }
+
+  reference back() {
+    auto tmp = end();
+    --tmp;
+    return *tmp;
+  }
+
+  const_reference back() const {
+    auto tmp = cend();
+    --tmp;
+    return *tmp;
+  }
+
+  template<class IteratorType, typename std::enable_if<
+      std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+      std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+  = 0>
+  IteratorType erase(IteratorType pos) {
+    if(JSON_UNLIKELY(this != pos.m_object)) {
+      JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+    }
+
+    IteratorType result = end();
+
+    switch(m_type) {
+      case value_t::boolean:
+      case value_t::number_float:
+      case value_t::number_integer:
+      case value_t::number_unsigned:
+      case value_t::string: {
+        if(JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin())) {
+          JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
+        }
+
+        if(is_string()) {
+          AllocatorType<string_t> alloc;
+          std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
+          std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
+          m_value.string = nullptr;
+        }
+
+        m_type = value_t::null;
+        assert_invariant();
+        break;
+      }
+
+      case value_t::object: {
+        result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
+        break;
+      }
+
+      case value_t::array: {
+        result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
+        break;
+      }
+
+      default:
+        JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
+    }
+
+    return result;
+  }
+
+  template<class IteratorType, typename std::enable_if<
+      std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+      std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+  = 0>
+  IteratorType erase(IteratorType first, IteratorType last) {
+    if(JSON_UNLIKELY(this != first.m_object or this != last.m_object)) {
+      JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
+    }
+
+    IteratorType result = end();
+
+    switch(m_type) {
+      case value_t::boolean:
+      case value_t::number_float:
+      case value_t::number_integer:
+      case value_t::number_unsigned:
+      case value_t::string: {
+        if(JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
+                       or not last.m_it.primitive_iterator.is_end())) {
+          JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+        }
+
+        if(is_string()) {
+          AllocatorType<string_t> alloc;
+          std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
+          std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
+          m_value.string = nullptr;
+        }
+
+        m_type = value_t::null;
+        assert_invariant();
+        break;
+      }
+
+      case value_t::object: {
+        result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
+                                                            last.m_it.object_iterator);
+        break;
+      }
+
+      case value_t::array: {
+        result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
+                                                          last.m_it.array_iterator);
+        break;
+      }
+
+      default:
+        JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
+    }
+
+    return result;
+  }
+
+  size_type erase(const typename object_t::key_type &key) {
+    if(JSON_LIKELY(is_object())) {
+      return m_value.object->erase(key);
+    }
+
+    JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
+  }
+
+  void erase(const size_type idx) {
+    if(JSON_LIKELY(is_array())) {
+      if(JSON_UNLIKELY(idx >= size())) {
+        JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+      }
+
+      m_value.array->erase(m_value.array->begin()+static_cast<difference_type>(idx));
+    } else {
+      JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
+    }
+  }
+
+  template<typename KeyT>
+  iterator find(KeyT &&key) {
+    auto result = end();
+
+    if(is_object()) {
+      result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
+    }
+
+    return result;
+  }
+
+  template<typename KeyT>
+  const_iterator find(KeyT &&key) const {
+    auto result = cend();
+
+    if(is_object()) {
+      result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
+    }
+
+    return result;
+  }
+
+  template<typename KeyT>
+  size_type count(KeyT &&key) const {
+    return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
+  }
+
+  iterator begin() noexcept {
+    iterator result(this);
+    result.set_begin();
+    return result;
+  }
+
+  const_iterator begin() const noexcept {
+    return cbegin();
+  }
+
+  const_iterator cbegin() const noexcept {
+    const_iterator result(this);
+    result.set_begin();
+    return result;
+  }
+
+  iterator end() noexcept {
+    iterator result(this);
+    result.set_end();
+    return result;
+  }
+
+  const_iterator end() const noexcept {
+    return cend();
+  }
+
+  const_iterator cend() const noexcept {
+    const_iterator result(this);
+    result.set_end();
+    return result;
+  }
+
+  reverse_iterator rbegin() noexcept {
+    return reverse_iterator(end());
+  }
+
+  const_reverse_iterator rbegin() const noexcept {
+    return crbegin();
+  }
+
+  reverse_iterator rend() noexcept {
+    return reverse_iterator(begin());
+  }
+
+  const_reverse_iterator rend() const noexcept {
+    return crend();
+  }
+
+  const_reverse_iterator crbegin() const noexcept {
+    return const_reverse_iterator(cend());
+  }
+
+  const_reverse_iterator crend() const noexcept {
+    return const_reverse_iterator(cbegin());
+  }
+
+public:
+  iteration_proxy<iterator> items() noexcept {
+    return iteration_proxy<iterator>(*this);
+  }
+
+  iteration_proxy<const_iterator> items() const noexcept {
+    return iteration_proxy<const_iterator>(*this);
+  }
+
+  bool empty() const noexcept {
+    switch(m_type) {
+      case value_t::null: {
+        return true;
+      }
+
+      case value_t::array: {
+        return m_value.array->empty();
+      }
+
+      case value_t::object: {
+        return m_value.object->empty();
+      }
+
+      default: {
+        return false;
+      }
+    }
+  }
+
+  size_type size() const noexcept {
+    switch(m_type) {
+      case value_t::null: {
+        return 0;
+      }
+
+      case value_t::array: {
+        return m_value.array->size();
+      }
+
+      case value_t::object: {
+        return m_value.object->size();
+      }
+
+      default: {
+        return 1;
+      }
+    }
+  }
+
+  size_type max_size() const noexcept {
+    switch(m_type) {
+      case value_t::array: {
+        return m_value.array->max_size();
+      }
+
+      case value_t::object: {
+        return m_value.object->max_size();
+      }
+
+      default: {
+        return size();
+      }
+    }
+  }
+
+  void clear() noexcept {
+    switch(m_type) {
+      case value_t::number_integer: {
+        m_value.number_integer = 0;
+        break;
+      }
+
+      case value_t::number_unsigned: {
+        m_value.number_unsigned = 0;
+        break;
+      }
+
+      case value_t::number_float: {
+        m_value.number_float = 0.0;
+        break;
+      }
+
+      case value_t::boolean: {
+        m_value.boolean = false;
+        break;
+      }
+
+      case value_t::string: {
+        m_value.string->clear();
+        break;
+      }
+
+      case value_t::array: {
+        m_value.array->clear();
+        break;
+      }
+
+      case value_t::object: {
+        m_value.object->clear();
+        break;
+      }
+
+      default:
+        break;
+    }
+  }
+
+  void push_back(basic_json &&val) {
+    if(JSON_UNLIKELY(not(is_null() or is_array()))) {
+      JSON_THROW(type_error::create(308, "cannot use push_back() with "+std::string(type_name())));
+    }
+
+    if(is_null()) {
+      m_type = value_t::array;
+      m_value = value_t::array;
+      assert_invariant();
+    }
+
+    m_value.array->push_back(std::move(val));
+
+    val.m_type = value_t::null;
+  }
+
+  reference operator+=(basic_json &&val) {
+    push_back(std::move(val));
+    return *this;
+  }
+
+  void push_back(const basic_json &val) {
+    if(JSON_UNLIKELY(not(is_null() or is_array()))) {
+      JSON_THROW(type_error::create(308, "cannot use push_back() with "+std::string(type_name())));
+    }
+
+    if(is_null()) {
+      m_type = value_t::array;
+      m_value = value_t::array;
+      assert_invariant();
+    }
+
+    m_value.array->push_back(val);
+  }
+
+  reference operator+=(const basic_json &val) {
+    push_back(val);
+    return *this;
+  }
+
+  void push_back(const typename object_t::value_type &val) {
+    if(JSON_UNLIKELY(not(is_null() or is_object()))) {
+      JSON_THROW(type_error::create(308, "cannot use push_back() with "+std::string(type_name())));
+    }
+
+    if(is_null()) {
+      m_type = value_t::object;
+      m_value = value_t::object;
+      assert_invariant();
+    }
+
+    m_value.object->insert(val);
+  }
+
+  reference operator+=(const typename object_t::value_type &val) {
+    push_back(val);
+    return *this;
+  }
+
+  void push_back(initializer_list_t init) {
+    if(is_object() and init.size() == 2 and (*init.begin())->is_string()) {
+      basic_json &&key = init.begin()->moved_or_copied();
+      push_back(typename object_t::value_type(
+          std::move(key.get_ref<string_t &>()), (init.begin()+1)->moved_or_copied()));
+    } else {
+      push_back(basic_json(init));
+    }
+  }
+
+  reference operator+=(initializer_list_t init) {
+    push_back(init);
+    return *this;
+  }
+
+  template<class... Args>
+  void emplace_back(Args &&... args) {
+    if(JSON_UNLIKELY(not(is_null() or is_array()))) {
+      JSON_THROW(type_error::create(311, "cannot use emplace_back() with "+std::string(type_name())));
+    }
+
+    if(is_null()) {
+      m_type = value_t::array;
+      m_value = value_t::array;
+      assert_invariant();
+    }
+
+    m_value.array->emplace_back(std::forward<Args>(args)...);
+  }
+
+  template<class... Args>
+  std::pair<iterator, bool> emplace(Args &&... args) {
+    if(JSON_UNLIKELY(not(is_null() or is_object()))) {
+      JSON_THROW(type_error::create(311, "cannot use emplace() with "+std::string(type_name())));
+    }
+
+    if(is_null()) {
+      m_type = value_t::object;
+      m_value = value_t::object;
+      assert_invariant();
+    }
+
+    auto res = m_value.object->emplace(std::forward<Args>(args)...);
+
+    auto it = begin();
+    it.m_it.object_iterator = res.first;
+
+    return {it, res.second};
+  }
+
+  iterator insert(const_iterator pos, const basic_json &val) {
+    if(JSON_LIKELY(is_array())) {
+      if(JSON_UNLIKELY(pos.m_object != this)) {
+        JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+      }
+
+      iterator result(this);
+      result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
+      return result;
+    }
+
+    JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
+  }
+
+  iterator insert(const_iterator pos, basic_json &&val) {
+    return insert(pos, val);
+  }
+
+  iterator insert(const_iterator pos, size_type cnt, const basic_json &val) {
+    if(JSON_LIKELY(is_array())) {
+      if(JSON_UNLIKELY(pos.m_object != this)) {
+        JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+      }
+
+      iterator result(this);
+      result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
+      return result;
+    }
+
+    JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
+  }
+
+  iterator insert(const_iterator pos, const_iterator first, const_iterator last) {
+    if(JSON_UNLIKELY(not is_array())) {
+      JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
+    }
+
+    if(JSON_UNLIKELY(pos.m_object != this)) {
+      JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+    }
+
+    if(JSON_UNLIKELY(first.m_object != last.m_object)) {
+      JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+    }
+
+    if(JSON_UNLIKELY(first.m_object == this)) {
+      JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
+    }
+
+    iterator result(this);
+    result.m_it.array_iterator = m_value.array->insert(
+        pos.m_it.array_iterator,
+        first.m_it.array_iterator,
+        last.m_it.array_iterator);
+    return result;
+  }
+
+  iterator insert(const_iterator pos, initializer_list_t ilist) {
+    if(JSON_UNLIKELY(not is_array())) {
+      JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
+    }
+
+    if(JSON_UNLIKELY(pos.m_object != this)) {
+      JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+    }
+
+    iterator result(this);
+    result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
+    return result;
+  }
+
+  void insert(const_iterator first, const_iterator last) {
+    if(JSON_UNLIKELY(not is_object())) {
+      JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
+    }
+
+    if(JSON_UNLIKELY(first.m_object != last.m_object)) {
+      JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+    }
+
+    if(JSON_UNLIKELY(not first.m_object->is_object())) {
+      JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+    }
+
+    m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
+  }
+
+  void update(const_reference j) {
+    if(is_null()) {
+      m_type = value_t::object;
+      m_value.object = create<object_t>();
+      assert_invariant();
+    }
+
+    if(JSON_UNLIKELY(not is_object())) {
+      JSON_THROW(type_error::create(312, "cannot use update() with "+std::string(type_name())));
+    }
+    if(JSON_UNLIKELY(not j.is_object())) {
+      JSON_THROW(type_error::create(312, "cannot use update() with "+std::string(j.type_name())));
+    }
+
+    for(auto it = j.cbegin(); it != j.cend(); ++it) {
+      m_value.object->operator[](it.key()) = it.value();
+    }
+  }
+
+  void update(const_iterator first, const_iterator last) {
+    if(is_null()) {
+      m_type = value_t::object;
+      m_value.object = create<object_t>();
+      assert_invariant();
+    }
+
+    if(JSON_UNLIKELY(not is_object())) {
+      JSON_THROW(type_error::create(312, "cannot use update() with "+std::string(type_name())));
+    }
+
+    if(JSON_UNLIKELY(first.m_object != last.m_object)) {
+      JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+    }
+
+    if(JSON_UNLIKELY(not first.m_object->is_object()
+                     or not last.m_object->is_object())) {
+      JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+    }
+
+    for(auto it = first; it != last; ++it) {
+      m_value.object->operator[](it.key()) = it.value();
+    }
+  }
+
+  void swap(reference other) noexcept(
+  std::is_nothrow_move_constructible<value_t>::value and
+  std::is_nothrow_move_assignable<value_t>::value and
+  std::is_nothrow_move_constructible<json_value>::value and
+  std::is_nothrow_move_assignable<json_value>::value
+  ) {
+    std::swap(m_type, other.m_type);
+    std::swap(m_value, other.m_value);
+    assert_invariant();
+  }
+
+  void swap(array_t &other) {
+    if(JSON_LIKELY(is_array())) {
+      std::swap(*(m_value.array), other);
+    } else {
+      JSON_THROW(type_error::create(310, "cannot use swap() with "+std::string(type_name())));
+    }
+  }
+
+  void swap(object_t &other) {
+    if(JSON_LIKELY(is_object())) {
+      std::swap(*(m_value.object), other);
+    } else {
+      JSON_THROW(type_error::create(310, "cannot use swap() with "+std::string(type_name())));
+    }
+  }
+
+  void swap(string_t &other) {
+    if(JSON_LIKELY(is_string())) {
+      std::swap(*(m_value.string), other);
+    } else {
+      JSON_THROW(type_error::create(310, "cannot use swap() with "+std::string(type_name())));
+    }
+  }
+
+public:
+  friend bool operator==(const_reference lhs, const_reference rhs) noexcept {
+    const auto lhs_type = lhs.type();
+    const auto rhs_type = rhs.type();
+
+    if(lhs_type == rhs_type) {
+      switch(lhs_type) {
+        case value_t::array:
+          return (*lhs.m_value.array == *rhs.m_value.array);
+
+        case value_t::object:
+          return (*lhs.m_value.object == *rhs.m_value.object);
+
+        case value_t::null:
+          return true;
+
+        case value_t::string:
+          return (*lhs.m_value.string == *rhs.m_value.string);
+
+        case value_t::boolean:
+          return (lhs.m_value.boolean == rhs.m_value.boolean);
+
+        case value_t::number_integer:
+          return (lhs.m_value.number_integer == rhs.m_value.number_integer);
+
+        case value_t::number_unsigned:
+          return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
+
+        case value_t::number_float:
+          return (lhs.m_value.number_float == rhs.m_value.number_float);
+
+        default:
+          return false;
+      }
+    } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
+      return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
+    } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
+      return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
+    } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
+      return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
+    } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
+      return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
+    } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
+      return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
+    } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
+      return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
+    }
+
+    return false;
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept {
+    return (lhs == basic_json(rhs));
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept {
+    return (basic_json(lhs) == rhs);
+  }
+
+  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept {
+    return not(lhs == rhs);
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept {
+    return (lhs != basic_json(rhs));
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept {
+    return (basic_json(lhs) != rhs);
+  }
+
+  friend bool operator<(const_reference lhs, const_reference rhs) noexcept {
+    const auto lhs_type = lhs.type();
+    const auto rhs_type = rhs.type();
+
+    if(lhs_type == rhs_type) {
+      switch(lhs_type) {
+        case value_t::array:
+          return (*lhs.m_value.array) < (*rhs.m_value.array);
+
+        case value_t::object:
+          return *lhs.m_value.object < *rhs.m_value.object;
+
+        case value_t::null:
+          return false;
+
+        case value_t::string:
+          return *lhs.m_value.string < *rhs.m_value.string;
+
+        case value_t::boolean:
+          return lhs.m_value.boolean < rhs.m_value.boolean;
+
+        case value_t::number_integer:
+          return lhs.m_value.number_integer < rhs.m_value.number_integer;
+
+        case value_t::number_unsigned:
+          return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
+
+        case value_t::number_float:
+          return lhs.m_value.number_float < rhs.m_value.number_float;
+
+        default:
+          return false;
+      }
+    } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
+      return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
+    } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
+      return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
+    } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
+      return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
+    } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
+      return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
+    } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
+      return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
+    } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
+      return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
+    }
+
+    return operator<(lhs_type, rhs_type);
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept {
+    return (lhs < basic_json(rhs));
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept {
+    return (basic_json(lhs) < rhs);
+  }
+
+  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept {
+    return not(rhs < lhs);
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept {
+    return (lhs <= basic_json(rhs));
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept {
+    return (basic_json(lhs) <= rhs);
+  }
+
+  friend bool operator>(const_reference lhs, const_reference rhs) noexcept {
+    return not(lhs <= rhs);
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept {
+    return (lhs > basic_json(rhs));
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept {
+    return (basic_json(lhs) > rhs);
+  }
+
+  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept {
+    return not(lhs < rhs);
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept {
+    return (lhs >= basic_json(rhs));
+  }
+
+  template<typename ScalarType, typename std::enable_if<
+      std::is_scalar<ScalarType>::value, int>::type = 0>
+  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept {
+    return (basic_json(lhs) >= rhs);
+  }
+
+  friend std::ostream &operator<<(std::ostream &o, const basic_json &j) {
+    const bool pretty_print = (o.width() > 0);
+    const auto indentation = (pretty_print ? o.width() : 0);
+
+    o.width(0);
+
+    serializer s(detail::output_adapter<char>(o), o.fill());
+    s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
+    return o;
+  }
+
+  static basic_json parse(detail::input_adapter i,
+                          const parser_callback_t cb = nullptr,
+                          const bool allow_exceptions = true) {
+    basic_json result;
+    parser(i, cb, allow_exceptions).parse(true, result);
+    return result;
+  }
+
+  static basic_json parse(detail::input_adapter &i,
+                          const parser_callback_t cb = nullptr,
+                          const bool allow_exceptions = true) {
+    basic_json result;
+    parser(i, cb, allow_exceptions).parse(true, result);
+    return result;
+  }
+
+  static bool accept(detail::input_adapter i) {
+    return parser(i).accept(true);
+  }
+
+  static bool accept(detail::input_adapter &i) {
+    return parser(i).accept(true);
+  }
+
+  template<class IteratorType, typename std::enable_if<
+      std::is_base_of<
+          std::random_access_iterator_tag,
+          typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
+  static basic_json parse(IteratorType first, IteratorType last,
+                          const parser_callback_t cb = nullptr,
+                          const bool allow_exceptions = true) {
+    basic_json result;
+    parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
+    return result;
+  }
+
+  template<class IteratorType, typename std::enable_if<
+      std::is_base_of<
+          std::random_access_iterator_tag,
+          typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
+  static bool accept(IteratorType first, IteratorType last) {
+    return parser(detail::input_adapter(first, last)).accept(true);
+  }
+
+  friend std::istream &operator>>(std::istream &i, basic_json &j) {
+    parser(detail::input_adapter(i)).parse(false, j);
+    return i;
+  }
+
+  const char *type_name() const noexcept {
+    {
+      switch(m_type) {
+        case value_t::null:
+          return "null";
+        case value_t::object:
+          return "object";
+        case value_t::array:
+          return "array";
+        case value_t::string:
+          return "string";
+        case value_t::boolean:
+          return "boolean";
+        case value_t::discarded:
+          return "discarded";
+        default:
+          return "number";
+      }
+    }
+  }
+
+private:
+  value_t m_type = value_t::null;
+
+  json_value m_value = {};
+
+public:
+  static std::vector<uint8_t> to_cbor(const basic_json &j) {
+    std::vector<uint8_t> result;
+    to_cbor(j, result);
+    return result;
+  }
+
+  static void to_cbor(const basic_json &j, detail::output_adapter<uint8_t> o) {
+    binary_writer<uint8_t>(o).write_cbor(j);
+  }
+
+  static void to_cbor(const basic_json &j, detail::output_adapter<char> o) {
+    binary_writer<char>(o).write_cbor(j);
+  }
+
+  static std::vector<uint8_t> to_msgpack(const basic_json &j) {
+    std::vector<uint8_t> result;
+    to_msgpack(j, result);
+    return result;
+  }
+
+  static void to_msgpack(const basic_json &j, detail::output_adapter<uint8_t> o) {
+    binary_writer<uint8_t>(o).write_msgpack(j);
+  }
+
+  static void to_msgpack(const basic_json &j, detail::output_adapter<char> o) {
+    binary_writer<char>(o).write_msgpack(j);
+  }
+
+  static std::vector<uint8_t> to_ubjson(const basic_json &j,
+                                        const bool use_size = false,
+                                        const bool use_type = false) {
+    std::vector<uint8_t> result;
+    to_ubjson(j, result, use_size, use_type);
+    return result;
+  }
+
+  static void to_ubjson(const basic_json &j, detail::output_adapter<uint8_t> o,
+                        const bool use_size = false, const bool use_type = false) {
+    binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
+  }
+
+  static void to_ubjson(const basic_json &j, detail::output_adapter<char> o,
+                        const bool use_size = false, const bool use_type = false) {
+    binary_writer<char>(o).write_ubjson(j, use_size, use_type);
+  }
+
+  static basic_json from_cbor(detail::input_adapter i,
+                              const bool strict = true) {
+    return binary_reader(i).parse_cbor(strict);
+  }
+
+  template<typename A1, typename A2,
+      detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+  static basic_json from_cbor(A1 &&a1, A2 &&a2, const bool strict = true) {
+    return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
+  }
+
+  static basic_json from_msgpack(detail::input_adapter i,
+                                 const bool strict = true) {
+    return binary_reader(i).parse_msgpack(strict);
+  }
+
+  template<typename A1, typename A2,
+      detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+  static basic_json from_msgpack(A1 &&a1, A2 &&a2, const bool strict = true) {
+    return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
+  }
+
+  static basic_json from_ubjson(detail::input_adapter i,
+                                const bool strict = true) {
+    return binary_reader(i).parse_ubjson(strict);
+  }
+
+  template<typename A1, typename A2,
+      detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+  static basic_json from_ubjson(A1 &&a1, A2 &&a2, const bool strict = true) {
+    return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_ubjson(strict);
+  }
+
+  reference operator[](const json_pointer &ptr) {
+    return ptr.get_unchecked(this);
+  }
+
+  const_reference operator[](const json_pointer &ptr) const {
+    return ptr.get_unchecked(this);
+  }
+
+  reference at(const json_pointer &ptr) {
+    return ptr.get_checked(this);
+  }
+
+  const_reference at(const json_pointer &ptr) const {
+    return ptr.get_checked(this);
+  }
+
+  basic_json flatten() const {
+    basic_json result(value_t::object);
+    json_pointer::flatten("", *this, result);
+    return result;
+  }
+
+  basic_json unflatten() const {
+    return json_pointer::unflatten(*this);
+  }
+
+  basic_json patch(const basic_json &json_patch) const {
+    basic_json result = *this;
+
+    enum class patch_operations {
+      add, remove, replace, move, copy, test, invalid
+    };
+
+    const auto get_op = [](const std::string &op) {
+      if(op == "add") {
+        return patch_operations::add;
+      }
+      if(op == "remove") {
+        return patch_operations::remove;
+      }
+      if(op == "replace") {
+        return patch_operations::replace;
+      }
+      if(op == "move") {
+        return patch_operations::move;
+      }
+      if(op == "copy") {
+        return patch_operations::copy;
+      }
+      if(op == "test") {
+        return patch_operations::test;
+      }
+
+      return patch_operations::invalid;
+    };
+
+    const auto operation_add = [&result](json_pointer &ptr, basic_json val) {
+      if(ptr.is_root()) {
+        result = val;
+      } else {
+        json_pointer top_pointer = ptr.top();
+        if(top_pointer != ptr) {
+          result.at(top_pointer);
+        }
+
+        const auto last_path = ptr.pop_back();
+        basic_json &parent = result[ptr];
+
+        switch(parent.m_type) {
+          case value_t::null:
+          case value_t::object: {
+            parent[last_path] = val;
+            break;
+          }
+
+          case value_t::array: {
+            if(last_path == "-") {
+              parent.push_back(val);
+            } else {
+              const auto idx = json_pointer::array_index(last_path);
+              if(JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size())) {
+                JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+              } else {
+                parent.insert(parent.begin()+static_cast<difference_type>(idx), val);
+              }
+            }
+            break;
+          }
+
+          default: {
+            assert(false);
+          }
+        }
+      }
+    };
+
+    const auto operation_remove = [&result](json_pointer &ptr) {
+      const auto last_path = ptr.pop_back();
+      basic_json &parent = result.at(ptr);
+
+      if(parent.is_object()) {
+        auto it = parent.find(last_path);
+        if(JSON_LIKELY(it != parent.end())) {
+          parent.erase(it);
+        } else {
+          JSON_THROW(out_of_range::create(403, "key '"+last_path+"' not found"));
+        }
+      } else if(parent.is_array()) {
+        parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
+      }
+    };
+
+    if(JSON_UNLIKELY(not json_patch.is_array())) {
+      JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
+    }
+
+    for(const auto &val : json_patch) {
+      const auto get_value = [&val](const std::string &op,
+                                    const std::string &member,
+                                    bool string_type) -> basic_json & {
+        auto it = val.m_value.object->find(member);
+
+        const auto error_msg = (op == "op") ? "operation" : "operation '"+op+"'";
+
+        if(JSON_UNLIKELY(it == val.m_value.object->end())) {
+          JSON_THROW(parse_error::create(105, 0, error_msg+" must have member '"+member+"'"));
+        }
+
+        if(JSON_UNLIKELY(string_type and not it->second.is_string())) {
+          JSON_THROW(parse_error::create(105, 0, error_msg+" must have string member '"+member+"'"));
+        }
+
+        return it->second;
+      };
+
+      if(JSON_UNLIKELY(not val.is_object())) {
+        JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
+      }
+
+      const std::string op = get_value("op", "op", true);
+      const std::string path = get_value(op, "path", true);
+      json_pointer ptr(path);
+
+      switch(get_op(op)) {
+        case patch_operations::add: {
+          operation_add(ptr, get_value("add", "value", false));
+          break;
+        }
+
+        case patch_operations::remove: {
+          operation_remove(ptr);
+          break;
+        }
+
+        case patch_operations::replace: {
+          result.at(ptr) = get_value("replace", "value", false);
+          break;
+        }
+
+        case patch_operations::move: {
+          const std::string from_path = get_value("move", "from", true);
+          json_pointer from_ptr(from_path);
+
+          basic_json v = result.at(from_ptr);
+
+          operation_remove(from_ptr);
+          operation_add(ptr, v);
+          break;
+        }
+
+        case patch_operations::copy: {
+          const std::string from_path = get_value("copy", "from", true);
+          const json_pointer from_ptr(from_path);
+
+          basic_json v = result.at(from_ptr);
+
+          operation_add(ptr, v);
+          break;
+        }
+
+        case patch_operations::test: {
+          bool success = false;
+          JSON_TRY {
+            success = (result.at(ptr) == get_value("test", "value", false));
+          }
+          JSON_CATCH (out_of_range &) {
+          }
+
+          if(JSON_UNLIKELY(not success)) {
+            JSON_THROW(other_error::create(501, "unsuccessful: "+val.dump()));
+          }
+
+          break;
+        }
+
+        case patch_operations::invalid: {
+          JSON_THROW(parse_error::create(105, 0, "operation value '"+op+"' is invalid"));
+        }
+      }
+    }
+
+    return result;
+  }
+
+  static basic_json diff(const basic_json &source, const basic_json &target,
+                         const std::string &path = "") {
+    basic_json result(value_t::array);
+
+    if(source == target) {
+      return result;
+    }
+
+    if(source.type() != target.type()) {
+      result.push_back(
+          {
+              {"op",    "replace"},
+              {"path",  path},
+              {"value", target}
+          });
+    } else {
+      switch(source.type()) {
+        case value_t::array: {
+          std::size_t i = 0;
+          while(i < source.size() and i < target.size()) {
+            auto temp_diff = diff(source[i], target[i], path+"/"+std::to_string(i));
+            result.insert(result.end(), temp_diff.begin(), temp_diff.end());
+            ++i;
+          }
+
+          const auto end_index = static_cast<difference_type>(result.size());
+          while(i < source.size()) {
+            result.insert(result.begin()+end_index, object(
+                {
+                    {"op",   "remove"},
+                    {"path", path+"/"+std::to_string(i)}
+                }));
+            ++i;
+          }
+
+          while(i < target.size()) {
+            result.push_back(
+                {
+                    {"op",    "add"},
+                    {"path",  path+"/"+std::to_string(i)},
+                    {"value", target[i]}
+                });
+            ++i;
+          }
+
+          break;
+        }
+
+        case value_t::object: {
+          for(auto it = source.cbegin(); it != source.cend(); ++it) {
+            const auto key = json_pointer::escape(it.key());
+
+            if(target.find(it.key()) != target.end()) {
+              auto temp_diff = diff(it.value(), target[it.key()], path+"/"+key);
+              result.insert(result.end(), temp_diff.begin(), temp_diff.end());
+            } else {
+              result.push_back(object(
+                  {
+                      {"op",   "remove"},
+                      {"path", path+"/"+key}
+                  }));
+            }
+          }
+
+          for(auto it = target.cbegin(); it != target.cend(); ++it) {
+            if(source.find(it.key()) == source.end()) {
+              const auto key = json_pointer::escape(it.key());
+              result.push_back(
+                  {
+                      {"op",    "add"},
+                      {"path",  path+"/"+key},
+                      {"value", it.value()}
+                  });
+            }
+          }
+
+          break;
+        }
+
+        default: {
+          result.push_back(
+              {
+                  {"op",    "replace"},
+                  {"path",  path},
+                  {"value", target}
+              });
+          break;
+        }
+      }
+    }
+
+    return result;
+  }
+
+  void merge_patch(const basic_json &patch) {
+    if(patch.is_object()) {
+      if(not is_object()) {
+        *this = object();
+      }
+      for(auto it = patch.begin(); it != patch.end(); ++it) {
+        if(it.value().is_null()) {
+          erase(it.key());
+        } else {
+          operator[](it.key()).merge_patch(it.value());
+        }
+      }
+    } else {
+      *this = patch;
+    }
+  }
+
+};
+}
+
+namespace std {
+template<>
+inline void swap(nlohmann::json &j1,
+                 nlohmann::json &j2) noexcept(
+is_nothrow_move_constructible<nlohmann::json>::value and
+is_nothrow_move_assignable<nlohmann::json>::value
+) {
+  j1.swap(j2);
+}
+
+template<>
+struct hash<nlohmann::json> {
+  std::size_t operator()(const nlohmann::json &j) const {
+    const auto &h = hash<nlohmann::json::string_t>();
+    return h(j.dump());
+  }
+};
+
+template<>
+struct less<::nlohmann::detail::value_t> {
+  bool operator()(nlohmann::detail::value_t lhs,
+                  nlohmann::detail::value_t rhs) const noexcept {
+    return nlohmann::detail::operator<(lhs, rhs);
+  }
+};
+
+}
+
+inline nlohmann::json operator "" _json(const char *s, std::size_t n) {
+  return nlohmann::json::parse(s, s+n);
+}
+
+inline nlohmann::json::json_pointer operator "" _json_pointer(const char *s, std::size_t n) {
+  return nlohmann::json::json_pointer(std::string(s, n));
+}
+
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+#pragma GCC diagnostic pop
+#endif
+#if defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+#undef JSON_CATCH
+#undef JSON_THROW
+#undef JSON_TRY
+#undef JSON_LIKELY
+#undef JSON_UNLIKELY
+#undef JSON_HAS_CPP_14
+#undef JSON_HAS_CPP_17
+#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
+#undef NLOHMANN_BASIC_JSON_TPL
+#undef NLOHMANN_JSON_HAS_HELPER
diff --git a/src/rapidxml/rapidxml.h b/3rd_party/rapidxml.h
similarity index 100%
rename from src/rapidxml/rapidxml.h
rename to 3rd_party/rapidxml.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 74cd0602..437b9b4d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -78,6 +78,7 @@ include_directories(
   ${LIBCLANG_INCLUDE_DIRS}
   ${ASPELL_INCLUDE_DIR}
   ${LIBGIT2_INCLUDE_DIRS}
+  3rd_party
 )
 
 add_subdirectory("src")
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b84b87e9..c2bd858c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,64 +3,64 @@
 file(GLOB JUCI_SRC_BUILDSYSTEMS cmake.h cmake.cc meson.h meson.cc makefile_base.h makefile_base.cc)
 
 set(JUCI_SHARED_FILES
-        ${JUCI_SRC_BUILDSYSTEMS}
-        autocomplete.cc
-        compile_commands.cc
-        ctags.cc
-        dispatcher.cc
-        documentation_cppreference.cc
-        filesystem.cc
-        git.cc
-        menu.cc
-        project_build.cc
-        source.cc
-        source_base.cc
-        source_clang.cc
-        source_diff.cc
-        source_language_protocol.cc
-        source_spellcheck.cc
-        terminal.cc
-        usages_clang.cc
-        )
+    ${JUCI_SRC_BUILDSYSTEMS}
+    autocomplete.cc
+    compile_commands.cc
+    ctags.cc
+    dispatcher.cc
+    documentation_cppreference.cc
+    filesystem.cc
+    git.cc
+    menu.cc
+    project_build.cc
+    source.cc
+    source_base.cc
+    source_clang.cc
+    source_diff.cc
+    source_language_protocol.cc
+    source_spellcheck.cc
+    terminal.cc
+    usages_clang.cc
+    )
 if (LIBLLDB_FOUND)
-    list(APPEND JUCI_SHARED_FILES debug_lldb.cc)
+  list(APPEND JUCI_SHARED_FILES debug_lldb.cc)
 endif ()
 add_library(juci_shared STATIC ${JUCI_SHARED_FILES})
 target_link_libraries(juci_shared
-        ${GTKMM_LIBRARIES}
-        ${GTKSVMM_LIBRARIES}
-        ${Boost_LIBRARIES}
-        ${LIBLLDB_LIBRARIES}
-        ${ASPELL_LIBRARIES}
-        ${LIBGIT2_LIBRARIES}
-        clangmm
-        tiny-process-library
-        )
+    ${GTKMM_LIBRARIES}
+    ${GTKSVMM_LIBRARIES}
+    ${Boost_LIBRARIES}
+    ${LIBLLDB_LIBRARIES}
+    ${ASPELL_LIBRARIES}
+    ${LIBGIT2_LIBRARIES}
+    clangmm
+    tiny-process-library
+    )
 
 add_executable(juci
-        config.cc
-        dialogs.cc
-        dialogs_unix.cc
-        directories.cc
-        entrybox.cc
-        info.cc
-        juci.cc
-        notebook.cc
-        project.cc
-        selection_dialog.cc
-        tooltips.cc
-        window.cc
-        )
+    config.cc
+    dialogs.cc
+    dialogs_unix.cc
+    directories.cc
+    entrybox.cc
+    info.cc
+    juci.cc
+    notebook.cc
+    project.cc
+    selection_dialog.cc
+    tooltips.cc
+    window.cc
+    )
 target_link_libraries(juci juci_shared)
 
 install(TARGETS juci RUNTIME DESTINATION bin)
 if (${CMAKE_SYSTEM_NAME} MATCHES Linux|.*BSD|DragonFly)
-    install(FILES "${CMAKE_SOURCE_DIR}/share/juci.desktop"
-            DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
-    install(FILES "${CMAKE_SOURCE_DIR}/share/juci.svg"
-            DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps")
+  install(FILES "${CMAKE_SOURCE_DIR}/share/juci.desktop"
+      DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
+  install(FILES "${CMAKE_SOURCE_DIR}/share/juci.svg"
+      DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps")
 elseif (APPLE)
-    install(CODE "execute_process(COMMAND /usr/bin/python ${CMAKE_SOURCE_DIR}/share/set_icon_macos.py ${CMAKE_SOURCE_DIR}/share/juci.png ${CMAKE_INSTALL_PREFIX}/bin/juci)")
+  install(CODE "execute_process(COMMAND /usr/bin/python ${CMAKE_SOURCE_DIR}/share/set_icon_macos.py ${CMAKE_SOURCE_DIR}/share/juci.png ${CMAKE_INSTALL_PREFIX}/bin/juci)")
 endif ()
 
 # add a target to generate API documentation with Doxygen
@@ -68,10 +68,10 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules/")
 find_package(Plantuml)
 find_package(Doxygen)
 if (DOXYGEN_FOUND)
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
-    add_custom_target(doc
-            ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
-            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-            COMMENT "Generating API documentation with Doxygen to ${CMAKE_CURRENT_BINARY_DIR}" VERBATIM
-            )
+  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
+  add_custom_target(doc
+      ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
+      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+      COMMENT "Generating API documentation with Doxygen to ${CMAKE_CURRENT_BINARY_DIR}" VERBATIM
+      )
 endif (DOXYGEN_FOUND)
diff --git a/src/cmake.cc b/src/cmake.cc
index 118c3488..252f2586 100644
--- a/src/cmake.cc
+++ b/src/cmake.cc
@@ -1,57 +1,32 @@
-#include "cmake.h"
+#include "project_build.h"
+#include "makefile_base.h"
 #include "filesystem.h"
-#include "dialogs.h"
 #include "config.h"
-#include "terminal.h"
-#include "compile_commands.h"
-#include "rapidxml/rapidxml.h"
+#include "rapidxml.h"
 
 namespace {
-  enum class Configuration {
-    Debug, Release
-  };
-
-  class CMakeProjectUpdater {
+  class CMakeProjectUpdater : public MakefileProjectUpdater {
   public:
-    CMakeProjectUpdater(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path) :
-        m_ref_project_path(project_path), m_ref_build_path(build_path) {}
+    using MakefileProjectUpdater::MakefileProjectUpdater;
 
-    CMakeProjectUpdater &set_configuration(Configuration conf) noexcept {
-      m_configuration = conf;
-      return *this;
+  private:
+    std::string get_extra_arguments() const {
+      return m_configuration == Configuration::Debug ? " -DCMAKE_BUILD_TYPE=Debug" : " -DCMAKE_BUILD_TYPE=Release";
     }
 
-    void do_update(bool force) {
-      check_arguments();
-      boost::filesystem::create_directory(m_ref_build_path);
-      if(!force && boost::filesystem::exists(m_ref_build_path / "CMakeCache.txt")) return;
-      auto compile_commands_path = m_ref_build_path / "compile_commands.json";
-      Dialog::Message message("Creating/updating build");
-      auto exit_status = Terminal::get().process(Config::get().project.cmake.command+' '+
-                                                 filesystem::escape_argument(m_ref_project_path.string())+
-                                                 " -DCMAKE_EXPORT_COMPILE_COMMANDS=ON"+get_extra_arguments(),
-                                                 m_ref_build_path);
-      if(exit_status == EXIT_SUCCESS)
-#ifdef _WIN32
-        applyMsys2Patch(compile_commands_path);
-#endif
-      message.hide();
+    std::string get_updater_arguments() const override {
+      return Config::get().project.cmake.command+' '+ filesystem::escape_argument(m_ref_project_path.string()) +
+             " -DCMAKE_EXPORT_COMPILE_COMMANDS=ON"+ get_extra_arguments();
     }
 
-  private:
-    void check_arguments() {
-      if(m_ref_project_path.empty() || m_ref_build_path.empty())
-        throw std::runtime_error("Arguments Incomplete");
-      if(!boost::filesystem::exists(m_ref_project_path / "CMakeLists.txt"))
-        throw std::runtime_error("CMake Project Not Found");
-    }
+    const char *get_project_name() const noexcept override { return "CMakeLists.txt"; };
 
-    std::string get_extra_arguments() const {
-      return m_configuration == Configuration::Debug ? " -DCMAKE_BUILD_TYPE=Debug" : " -DCMAKE_BUILD_TYPE=Release";
-    }
+    const char *get_cache_identifier_name() const noexcept override { return "CMakeCache.txt"; }
 
-    //Temporary fix to MSYS2's libclang
-    void applyMsys2Patch(const boost::filesystem::path &compile_commands_path) const {
+    void on_success() override {
+      //Temporary fix to MSYS2's libclang
+#ifdef _WIN32
+      auto compile_commands_path = m_ref_build_path / "compile_commands.json";
       auto compile_commands_file = filesystem::read(compile_commands_path);
       const std::array<const std::string, 2> drives = {"-I", "-isystem"};
       for(const auto &target: drives) {
@@ -65,37 +40,21 @@ namespace {
         }
       }
       filesystem::write(compile_commands_path, compile_commands_file);
+#endif
     }
-
-    Configuration m_configuration;
-    const boost::filesystem::path &m_ref_project_path;
-    const boost::filesystem::path &m_ref_build_path;
   };
 }
 
-CMake::CMake(const boost::filesystem::path &path) : MakefileBase(path, "CMakeLists.txt") {}
+Project::CMakeBuild::CMakeBuild(const boost::filesystem::path &path) : Build(path, "CMakeLists.txt") {}
 
-bool CMake::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
-  try {
-    CMakeProjectUpdater(get_project_path(), default_build_path).set_configuration(Configuration::Release).do_update(
-        force);
-  }
-  catch(std::exception &e) {
-    Terminal::get().print("Configuration For: "+get_project_path().string()+" Failed With: "+e.what()+'\n');
-    return false;
-  }
-  return true;
+bool Project::CMakeBuild::update_default(bool force) {
+  return CMakeProjectUpdater(get_project_path(), get_default_path()).
+      do_update(MakefileProjectUpdater::Configuration::Release, force);
 }
 
-bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-  try {
-    CMakeProjectUpdater(get_project_path(), debug_build_path).set_configuration(Configuration::Debug).do_update(force);
-  }
-  catch(std::exception &e) {
-    Terminal::get().print("Configuration For: "+get_project_path().string()+" Failed With: "+e.what()+'\n');
-    return false;
-  }
-  return true;
+bool Project::CMakeBuild::update_debug(bool force) {
+  return CMakeProjectUpdater(get_project_path(), get_debug_path()).
+      do_update(MakefileProjectUpdater::Configuration::Debug, force);
 }
 
 namespace {
@@ -114,15 +73,8 @@ namespace {
       return "";
     }
 
-    static std::string file_reader(const boost::filesystem::path &build_path) {
-      std::stringstream ss;
-      std::ifstream inf(build_path.string());
-      ss << inf.rdbuf();
-      return ss.str();
-    }
-
     void parse_project(const boost::filesystem::path &build_path) {
-      const auto project_file = file_reader(find_project_file(build_path));
+      const auto project_file = filesystem::read(find_project_file(build_path));
       document.parse<0>(const_cast<char *>(project_file.c_str()));
     }
 
@@ -162,9 +114,10 @@ namespace {
 
 }
 
-boost::filesystem::path
-CMake::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &) {
-  GetExecutableHelper helper(build_path);
+boost::filesystem::path Project::CMakeBuild::get_executable(const boost::filesystem::path &) {
+  GetExecutableHelper helper(get_default_path());
   auto &exec = helper.get_executables();
   return exec.empty() ? "" : exec[0];
 }
+
+std::string Project::CMakeBuild::get_compile_command() { return Config::get().project.cmake.compile_command; }
diff --git a/src/cmake.h b/src/cmake.h
deleted file mode 100644
index 1fa22ce9..00000000
--- a/src/cmake.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "makefile_base.h"
-
-class CMake : public MakefileBase {
-public:
-  explicit CMake(const boost::filesystem::path &path);
-
-  bool update_default_build(const boost::filesystem::path &default_build_path, bool force) override;
-
-  bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) override;
-
-  boost::filesystem::path
-  get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
-};
diff --git a/src/compile_commands.cc b/src/compile_commands.cc
index 07c3d221..412f1338 100644
--- a/src/compile_commands.cc
+++ b/src/compile_commands.cc
@@ -1,7 +1,8 @@
 #include "compile_commands.h"
 #include "clangmm.h"
-#include <boost/property_tree/json_parser.hpp>
+#include <fstream>
 #include <regex>
+#include <json.h>
 
 std::vector<std::string> CompileCommands::Command::parameter_values(const std::string &parameter_name) const {
   std::vector<std::string> parameter_values;
@@ -21,65 +22,68 @@ std::vector<std::string> CompileCommands::Command::parameter_values(const std::s
 
 CompileCommands::CompileCommands(const boost::filesystem::path &build_path) {
   try {
-    boost::property_tree::ptree root_pt;
-    boost::property_tree::json_parser::read_json((build_path/"compile_commands.json").string(), root_pt);
-
-    auto commands_pt=root_pt.get_child("");
-    for(auto &command: commands_pt) {
-      boost::filesystem::path directory=command.second.get<std::string>("directory");
-      auto parameters_str=command.second.get<std::string>("command");
-      boost::filesystem::path file=command.second.get<std::string>("file");
-
-      std::vector<std::string> parameters;
-      bool backslash=false;
-      bool single_quote=false;
-      bool double_quote=false;
-      size_t parameter_start_pos=std::string::npos;
-      size_t parameter_size=0;
-      auto add_parameter=[&parameters, &parameters_str, &parameter_start_pos, &parameter_size] {
-        auto parameter=parameters_str.substr(parameter_start_pos, parameter_size);
-        // Remove escaping
-        for(size_t c=0;c<parameter.size()-1;++c) {
-          if(parameter[c]=='\\')
-            parameter.replace(c, 2, std::string()+parameter[c+1]);
-        }
-        parameters.emplace_back(parameter);
-      };
-      for(size_t c=0;c<parameters_str.size();++c) {
-        if(backslash)
-          backslash=false;
-        else if(parameters_str[c]=='\\')
-          backslash=true;
-        else if((parameters_str[c]==' ' || parameters_str[c]=='\t') && !backslash && !single_quote && !double_quote) {
-          if(parameter_start_pos!=std::string::npos) {
-            add_parameter();
-            parameter_start_pos=std::string::npos;
-            parameter_size=0;
-          }
-          continue;
-        }
-        else if(parameters_str[c]=='\'' && !backslash && !double_quote) {
-          single_quote=!single_quote;
-          continue;
-        }
-        else if(parameters_str[c]=='\"' && !backslash && !single_quote) {
-          double_quote=!double_quote;
-          continue;
-        }
+    std::ifstream commands_file((build_path/"compile_commands.json").string());
+    nlohmann::json commands_pt;
+    commands_file >> commands_pt;
 
-        if(parameter_start_pos==std::string::npos)
-          parameter_start_pos=c;
-        ++parameter_size;
-      }
-      if(parameter_start_pos!=std::string::npos)
-        add_parameter();
+    for(auto& command: commands_pt) {
+      boost::filesystem::path directory=command["directory"].get<std::string>();
+      boost::filesystem::path file=command["file"].get<std::string>();
 
-      commands.emplace_back(Command{directory, parameters, boost::filesystem::absolute(file, build_path)});
+      commands.emplace_back(
+          Command{directory, parse_command(command["command"]), boost::filesystem::absolute(file, build_path)});
     }
   }
   catch(...) {}
 }
 
+std::vector<std::string> CompileCommands::parse_command(const std::string& parameters_str) const {
+  std::vector<std::string> parameters;
+  bool backslash=false;
+  bool single_quote=false;
+  bool double_quote=false;
+  size_t parameter_start_pos= std::string::npos;
+  size_t parameter_size=0;
+  auto add_parameter=[&parameters, &parameters_str, &parameter_start_pos, &parameter_size] {
+    auto parameter=parameters_str.substr(parameter_start_pos, parameter_size);
+    // Remove escaping
+    for(size_t c=0;c<parameter.size()-1;++c) {
+      if(parameter[c]=='\\')
+        parameter.replace(c, 2, std::string()+parameter[c+1]);
+    }
+    parameters.emplace_back(parameter);
+  };
+  for(size_t c=0;c<parameters_str.size();++c) {
+    if(backslash)
+      backslash=false;
+    else if(parameters_str[c]=='\\')
+      backslash=true;
+    else if((parameters_str[c] == ' ' || parameters_str[c] == '\t') && !single_quote && !double_quote) {
+      if(parameter_start_pos != std::string::npos) {
+        add_parameter();
+        parameter_start_pos= std::string::npos;
+        parameter_size=0;
+      }
+      continue;
+    }
+    else if(parameters_str[c] == '\'' && !double_quote) {
+      single_quote=!single_quote;
+      continue;
+    }
+    else if(parameters_str[c] == '\"' && !single_quote) {
+      double_quote=!double_quote;
+      continue;
+    }
+
+    if(parameter_start_pos == std::string::npos)
+      parameter_start_pos=c;
+    ++parameter_size;
+  }
+  if(parameter_start_pos != std::string::npos)
+    add_parameter();
+  return parameters;
+}
+
 std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
   std::string default_std_argument="-std=c++1y";
 
diff --git a/src/compile_commands.h b/src/compile_commands.h
index c7bb0f4a..b18a1cbc 100644
--- a/src/compile_commands.h
+++ b/src/compile_commands.h
@@ -15,11 +15,13 @@ class CompileCommands {
     std::vector<std::string> parameter_values(const std::string &parameter_name) const;
   };
 
-  CompileCommands(const boost::filesystem::path &build_path);
+  explicit CompileCommands(const boost::filesystem::path &build_path);
 
   std::vector<Command> commands;
 
   /// Return arguments for the given file using libclangmm
   static std::vector<std::string>
   get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path);
+
+  std::vector<std::string> parse_command(const std::string& parameters_str) const;
 };
diff --git a/src/makefile_base.cc b/src/makefile_base.cc
index a73a76b4..5a6d232b 100644
--- a/src/makefile_base.cc
+++ b/src/makefile_base.cc
@@ -1,49 +1,37 @@
-#include <regex>
-#include "meson.h"
 #include "makefile_base.h"
 #include "terminal.h"
-#include "filesystem.h"
+#include "dialogs.h"
 
-bool MakefileBase::create_build_directory(const boost::filesystem::path &build_path) {
-  if (!boost::filesystem::exists(build_path)) {
-    boost::system::error_code ec;
-    boost::filesystem::create_directories(build_path, ec);
-    if (ec) {
-      Terminal::get().print("Error: could not create " + build_path.string() + ": " + ec.message() + "\n",
-                            true);
-      return false;
+MakefileProjectUpdater::MakefileProjectUpdater(const boost::filesystem::path &project_path,
+                                               const boost::filesystem::path &build_path) :
+    m_configuration(Configuration::Release), m_ref_project_path(project_path), m_ref_build_path(build_path) {}
+
+bool MakefileProjectUpdater::do_update(Configuration conf, bool force) noexcept {
+  m_configuration = conf;
+  try {
+    check_arguments();
+    boost::filesystem::create_directory(m_ref_build_path);
+    if(force || !is_generated()) {
+      Dialog::Message message("Creating/updating build");
+      if(Terminal::get().process(get_updater_arguments(), m_ref_build_path) == EXIT_SUCCESS)
+        on_success();
+      message.hide();
     }
   }
+  catch(std::exception &e) {
+    Terminal::get().print("Configuration For: "+m_ref_project_path.string()+" Failed With: "+e.what()+'\n');
+    return false;
+  }
   return true;
 }
 
-namespace {
-  bool find_project_impl(const boost::filesystem::path &file_path) {
-    for (auto &line: filesystem::read_lines(file_path)) {
-      const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
-      std::smatch sm;
-      if (std::regex_match(line, sm, project_regex))
-        return true;
-    }
-    return false;
-  }
+bool MakefileProjectUpdater::is_generated() const { return exists(m_ref_build_path / get_cache_identifier_name()); }
 
-  boost::filesystem::path find_project(const boost::filesystem::path &path, const std::string &filename) {
-    auto search_path = is_directory(path) ? path : path.parent_path();
-    while (true) {
-      auto search_file = search_path / filename;
-      if (exists(search_file)) {
-        if (find_project_impl(search_file)) {
-          return search_path;
-        }
-      }
-      if (search_path == search_path.root_directory())
-        break;
-      search_path = search_path.parent_path();
-    }
-    return "";
-  }
-}
+void MakefileProjectUpdater::on_success() {}
 
-MakefileBase::MakefileBase(const boost::filesystem::path &path, const std::string &filename) : project_path(
-    find_project(path, filename)) {}
+void MakefileProjectUpdater::check_arguments() const {
+  if(m_ref_project_path.empty() || m_ref_build_path.empty())
+    throw std::runtime_error("Arguments Incomplete");
+  if(!boost::filesystem::exists(m_ref_project_path / get_project_name()))
+    throw std::runtime_error("Project Not Found");
+}
diff --git a/src/makefile_base.h b/src/makefile_base.h
index d2493ab6..d6283280 100644
--- a/src/makefile_base.h
+++ b/src/makefile_base.h
@@ -2,24 +2,24 @@
 
 #include <boost/filesystem.hpp>
 
-class MakefileBase {
+class MakefileProjectUpdater {
 public:
-  MakefileBase(const boost::filesystem::path &path, const std::string &filename);
+  enum class Configuration {
+    Debug, Release
+  };
 
-  virtual ~MakefileBase() = default;
-
-  auto &get_project_path() const { return project_path; }
-
-  virtual bool update_default_build(const boost::filesystem::path &default_build_path, bool force) = 0;
-
-  virtual bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) = 0;
-
-  virtual boost::filesystem::path
-  get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) = 0;
+  MakefileProjectUpdater(const boost::filesystem::path &project_path, const boost::filesystem::path &build_path);
+  bool do_update(Configuration conf, bool force) noexcept;
 
 protected:
-  static bool create_build_directory(const boost::filesystem::path &build_path);
-
-private:
-  const boost::filesystem::path project_path;
+  virtual std::string get_updater_arguments() const = 0;
+  virtual const char* get_project_name() const noexcept = 0;
+  virtual const char* get_cache_identifier_name() const noexcept = 0;
+  virtual void on_success();
+  void check_arguments() const;
+  bool is_generated() const;
+
+  Configuration m_configuration;
+  const boost::filesystem::path &m_ref_project_path;
+  const boost::filesystem::path &m_ref_build_path;
 };
diff --git a/src/meson.cc b/src/meson.cc
index 30485f12..2dff9f7b 100644
--- a/src/meson.cc
+++ b/src/meson.cc
@@ -1,56 +1,44 @@
-#include "meson.h"
+#include "project_build.h"
+#include "makefile_base.h"
 #include "filesystem.h"
 #include "compile_commands.h"
-#include <regex>
-#include "terminal.h"
-#include "dialogs.h"
 #include "config.h"
 
-Meson::Meson(const boost::filesystem::path &path) : MakefileBase(path, "meson.build") {}
+namespace {
+  class MesonProjectUpdater : public MakefileProjectUpdater {
+  public:
+    using MakefileProjectUpdater::MakefileProjectUpdater;
 
-bool Meson::update_default_build(const boost::filesystem::path &default_build_path, bool force) {
-  if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") ||
-      default_build_path.empty())
-    return false;
+  private:
+    std::string get_extra_arguments() const {
+      return m_configuration == Configuration::Debug ? "--buildtype debug " : "";
+    }
 
-  if (!create_build_directory(default_build_path)) return false;
+    std::string get_updater_arguments() const override {
+      return Config::get().project.meson.command+' '+(is_generated()?"--internal regenerate ":"")+
+             get_extra_arguments()+filesystem::escape_argument(m_ref_project_path.string());
+    }
 
-  auto compile_commands_path = default_build_path / "compile_commands.json";
-  bool compile_commands_exists = boost::filesystem::exists(compile_commands_path);
-  if (!force && compile_commands_exists)
-    return true;
+    const char *get_project_name() const noexcept override { return "meson.build"; };
 
-  Dialog::Message message("Creating/updating default build");
-  auto exit_status = Terminal::get().process(
-      Config::get().project.meson.command + ' ' + (compile_commands_exists ? "--internal regenerate " : "") +
-      filesystem::escape_argument(get_project_path().string()), default_build_path);
-  message.hide();
-  if (exit_status == EXIT_SUCCESS)
-    return true;
-  return false;
+    const char *get_cache_identifier_name() const noexcept override { return "compile_commands.json"; }
+  };
 }
 
-bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) {
-  if (get_project_path().empty() || !boost::filesystem::exists(get_project_path() / "meson.build") ||
-      debug_build_path.empty())
-    return false;
-
-  if (!create_build_directory(debug_build_path)) return false;
+Project::MesonBuild::MesonBuild(const boost::filesystem::path &path) : Build(path, "meson.build") {}
 
-  bool compile_commands_exists=boost::filesystem::exists(debug_build_path/"compile_commands.json");
-  if(!force && compile_commands_exists)
-    return true;
+bool Project::MesonBuild::update_default(bool force) {
+  return MesonProjectUpdater(get_project_path(), get_default_path()).
+      do_update(MakefileProjectUpdater::Configuration::Release, force);
+}
 
-  Dialog::Message message("Creating/updating debug build");
-  auto exit_status=Terminal::get().process(Config::get().project.meson.command+' '+(compile_commands_exists?"--internal regenerate ":"")+
-                                           "--buildtype debug "+filesystem::escape_argument(get_project_path().string()), debug_build_path);
-  message.hide();
-  if(exit_status==EXIT_SUCCESS)
-    return true;
-  return false;
+bool Project::MesonBuild::update_debug(bool force) {
+  return MesonProjectUpdater(get_project_path(), get_debug_path()).
+      do_update(MakefileProjectUpdater::Configuration::Debug, force);
 }
 
-boost::filesystem::path Meson::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) {
+boost::filesystem::path Project::MesonBuild::get_executable(const boost::filesystem::path &file_path) {
+  auto build_path = get_default_path();
   CompileCommands compile_commands(build_path);
 
   size_t best_match_size=-1;
@@ -80,3 +68,5 @@ boost::filesystem::path Meson::get_executable(const boost::filesystem::path &bui
 
   return best_match_executable;
 }
+
+std::string Project::MesonBuild::get_compile_command() { return Config::get().project.meson.compile_command; }
diff --git a/src/meson.h b/src/meson.h
deleted file mode 100644
index 43c5b1c4..00000000
--- a/src/meson.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include "makefile_base.h"
-
-class Meson : public MakefileBase {
-public:
-  Meson(const boost::filesystem::path &path);
-
-  bool update_default_build(const boost::filesystem::path &default_build_path, bool force) override;
-
-  bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force) override;
-
-  boost::filesystem::path
-  get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) override;
-
-};
diff --git a/src/project_build.cc b/src/project_build.cc
index 3398086a..58939de6 100644
--- a/src/project_build.cc
+++ b/src/project_build.cc
@@ -1,6 +1,7 @@
 #include "project_build.h"
 #include "config.h"
 #include "filesystem.h"
+#include <regex>
 
 std::unique_ptr<Project::Build> Project::Build::create(const boost::filesystem::path &path) {
   auto search_path = boost::filesystem::is_directory(path) ? path : path.parent_path();
@@ -81,42 +82,33 @@ boost::filesystem::path Project::Build::get_debug_path() {
   return filesystem::get_normal_path(debug_build_path);
 }
 
-Project::CMakeBuild::CMakeBuild(const boost::filesystem::path &path) : Project::Build(), cmake(path) {
-  project_path = cmake.get_project_path();
-}
-
-bool Project::CMakeBuild::update_default(bool force) {
-  return cmake.update_default_build(get_default_path(), force);
-}
-
-bool Project::CMakeBuild::update_debug(bool force) {
-  return cmake.update_debug_build(get_debug_path(), force);
-}
-
-std::string Project::CMakeBuild::get_compile_command() {
-  return Config::get().project.cmake.compile_command;
-}
-
-boost::filesystem::path Project::CMakeBuild::get_executable(const boost::filesystem::path &path) {
-  return cmake.get_executable(get_default_path(), path).string();
-}
-
-Project::MesonBuild::MesonBuild(const boost::filesystem::path &path) : Project::Build(), meson(path) {
-  project_path = meson.get_project_path();
-}
-
-bool Project::MesonBuild::update_default(bool force) {
-  return meson.update_default_build(get_default_path(), force);
-}
-
-bool Project::MesonBuild::update_debug(bool force) {
-  return meson.update_debug_build(get_debug_path(), force);
-}
+namespace {
+  bool find_project_impl(const boost::filesystem::path &file_path) {
+    for (auto &line: filesystem::read_lines(file_path)) {
+      const static std::regex project_regex("^ *project *\\(.*\\r?$", std::regex::icase);
+      std::smatch sm;
+      if (std::regex_match(line, sm, project_regex))
+        return true;
+    }
+    return false;
+  }
 
-std::string Project::MesonBuild::get_compile_command() {
-  return Config::get().project.meson.compile_command;
+  boost::filesystem::path find_project(const boost::filesystem::path &path, const std::string &filename) {
+    auto search_path = is_directory(path) ? path : path.parent_path();
+    while (true) {
+      auto search_file = search_path / filename;
+      if (exists(search_file)) {
+        if (find_project_impl(search_file)) {
+          return search_path;
+        }
+      }
+      if (search_path == search_path.root_directory())
+        break;
+      search_path = search_path.parent_path();
+    }
+    return "";
+  }
 }
 
-boost::filesystem::path Project::MesonBuild::get_executable(const boost::filesystem::path &path) {
-  return meson.get_executable(get_default_path(), path);
-}
+Project::Build::Build(const boost::filesystem::path &path, const std::string &filename) :
+    project_path(find_project(path, filename)) {}
diff --git a/src/project_build.h b/src/project_build.h
index 43c23d6d..245914bb 100644
--- a/src/project_build.h
+++ b/src/project_build.h
@@ -1,12 +1,12 @@
 #pragma once
 #include <boost/filesystem.hpp>
-#include "cmake.h"
-#include "meson.h"
 
 namespace Project {
   class Build {
   public:
-    virtual ~Build() {}
+    Build() = default;
+    explicit Build(const boost::filesystem::path &path, const std::string &filename);
+    virtual ~Build() = default;
 
     virtual boost::filesystem::path get_default_path();
     virtual bool update_default(bool force=false) {return false;}
@@ -24,12 +24,10 @@ namespace Project {
     boost::filesystem::path project_path;
   };
 
-
   class CMakeBuild : public Build {
-    ::CMake cmake;
   public:
-    CMakeBuild(const boost::filesystem::path &path);
-
+    explicit CMakeBuild(const boost::filesystem::path &path);
+    
     bool update_default(bool force) override;
 
     bool update_debug(bool force) override;
@@ -40,9 +38,8 @@ namespace Project {
   };
 
   class MesonBuild : public Build {
-    Meson meson;
   public:
-    MesonBuild(const boost::filesystem::path &path);
+    explicit MesonBuild(const boost::filesystem::path &path);
 
     bool update_default(bool force) override;
 

From 5ad82df509ba49f8631279f56751dc901f82cc1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BA=88=E9=A1=BA=20=E5=88=98?= <yshliu0321@icloud.com>
Date: Sat, 26 May 2018 11:31:18 +0800
Subject: [PATCH 12/12] Minoring Code

---
 3rd_party/json.h | 12438 +++++++++++++++++++--------------------------
 src/cmake.cc     |     1 +
 src/config.cc    |   309 +-
 src/config.h     |    21 -
 src/window.cc    |     1 +
 5 files changed, 5415 insertions(+), 7355 deletions(-)

diff --git a/3rd_party/json.h b/3rd_party/json.h
index b631877e..00537155 100644
--- a/3rd_party/json.h
+++ b/3rd_party/json.h
@@ -53,37 +53,37 @@ SOFTWARE.
 #include <vector>
 
 namespace nlohmann {
-template<typename = void, typename = void>
-struct adl_serializer;
-
-template<template<typename U, typename V, typename... Args> class ObjectType =
-std::map,
-    template<typename U, typename... Args> class ArrayType = std::vector,
-    class StringType = std::string, class BooleanType = bool,
-    class NumberIntegerType = std::int64_t,
-    class NumberUnsignedType = std::uint64_t,
-    class NumberFloatType = double,
-    template<typename U> class AllocatorType = std::allocator,
-    template<typename T, typename SFINAE = void> class JSONSerializer =
-    adl_serializer>
-class basic_json;
-
-template<typename BasicJsonType>
-class json_pointer;
-
-using json = basic_json<>;
+  template<typename = void, typename = void>
+  struct adl_serializer;
+
+  template<template<typename U, typename V, typename... Args> class ObjectType =
+  std::map,
+      template<typename U, typename... Args> class ArrayType = std::vector,
+      class StringType = std::string, class BooleanType = bool,
+      class NumberIntegerType = std::int64_t,
+      class NumberUnsignedType = std::uint64_t,
+      class NumberFloatType = double,
+      template<typename U> class AllocatorType = std::allocator,
+      template<typename T, typename SFINAE = void> class JSONSerializer =
+      adl_serializer>
+  class basic_json;
+
+  template<typename BasicJsonType>
+  class json_pointer;
+
+  using json = basic_json<>;
 }
 
 #endif
 
 #if defined(__clang__)
-#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
-        #error "unsupported Clang version"
-    #endif
+  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
+    #error "unsupported Clang version"
+  #endif
 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
-#if (__GNUC__ * 10000+__GNUC_MINOR__ * 100+__GNUC_PATCHLEVEL__) < 40900
-#error "unsupported GCC version"
-#endif
+  #if (__GNUC__ * 10000+__GNUC_MINOR__ * 100+__GNUC_PATCHLEVEL__) < 40900
+    #error "unsupported GCC version"
+  #endif
 #endif
 
 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
@@ -166,6410 +166,4560 @@ using json = basic_json<>;
 #include <type_traits>
 
 namespace nlohmann {
-namespace detail {
-template<typename>
-struct is_basic_json : std::false_type {
-};
+  namespace detail {
+    template<typename>
+    struct is_basic_json : std::false_type {
+    };
 
-NLOHMANN_BASIC_JSON_TPL_DECLARATION
-struct is_basic_json<NLOHMANN_BASIC_JSON_TPL > : std::true_type {
-};
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    struct is_basic_json<NLOHMANN_BASIC_JSON_TPL > : std::true_type {
+    };
 
-template<bool B, typename T = void>
-using enable_if_t = typename std::enable_if<B, T>::type;
+    template<bool B, typename T = void>
+    using enable_if_t = typename std::enable_if<B, T>::type;
 
-template<typename T>
-using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+    template<typename T>
+    using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
 
-template<std::size_t... Ints>
-struct index_sequence {
-  using type = index_sequence;
-  using value_type = std::size_t;
+    template<std::size_t... Ints>
+    struct index_sequence {
+      using type = index_sequence;
+      using value_type = std::size_t;
 
-  static constexpr std::size_t size() noexcept {
-    return sizeof...(Ints);
-  }
-};
-
-template<class Sequence1, class Sequence2>
-struct merge_and_renumber;
-
-template<std::size_t... I1, std::size_t... I2>
-struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
-    : index_sequence<I1..., (sizeof...(I1)+I2)...> {
-};
-
-template<std::size_t N>
-struct make_index_sequence
-    : merge_and_renumber<typename make_index_sequence<N / 2>::type,
-        typename make_index_sequence<N-N / 2>::type> {
-};
-
-template<>
-struct make_index_sequence<0> : index_sequence<> {
-};
-template<>
-struct make_index_sequence<1> : index_sequence<0> {
-};
-
-template<typename... Ts>
-using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
-
-template<class...>
-struct conjunction : std::true_type {
-};
-template<class B1>
-struct conjunction<B1> : B1 {
-};
-template<class B1, class... Bn>
-struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {
-};
-
-template<class B>
-struct negation : std::integral_constant<bool, not B::value> {
-};
-
-template<unsigned N>
-struct priority_tag : priority_tag<N-1> {
-};
-template<>
-struct priority_tag<0> {
-};
-
-template<typename T, typename = void>
-struct is_complete_type : std::false_type {
-};
-
-template<typename T>
-struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {
-};
-
-NLOHMANN_JSON_HAS_HELPER(mapped_type);
-
-NLOHMANN_JSON_HAS_HELPER(key_type);
-
-NLOHMANN_JSON_HAS_HELPER(value_type);
-
-NLOHMANN_JSON_HAS_HELPER(iterator);
-
-template<bool B, class RealType, class CompatibleObjectType>
-struct is_compatible_object_type_impl : std::false_type {
-};
-
-template<class RealType, class CompatibleObjectType>
-struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType> {
-  static constexpr auto value =
-      std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
-      std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
-};
-
-template<class BasicJsonType, class CompatibleObjectType>
-struct is_compatible_object_type {
-  static auto constexpr value = is_compatible_object_type_impl<
-      conjunction<negation<std::is_same<void, CompatibleObjectType>>,
-          has_mapped_type<CompatibleObjectType>,
-          has_key_type<CompatibleObjectType>>::value,
-      typename BasicJsonType::object_t, CompatibleObjectType>::value;
-};
-
-template<typename BasicJsonType, typename T>
-struct is_basic_json_nested_type {
-  static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
-                                std::is_same<T, typename BasicJsonType::const_iterator>::value or
-                                std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
-                                std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
-};
-
-template<class BasicJsonType, class CompatibleArrayType>
-struct is_compatible_array_type {
-  static auto constexpr value =
-      conjunction<negation<std::is_same<void, CompatibleArrayType>>,
-          negation<is_compatible_object_type<
-              BasicJsonType, CompatibleArrayType>>,
-          negation<std::is_constructible<typename BasicJsonType::string_t,
-              CompatibleArrayType>>,
-          negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
-          has_value_type<CompatibleArrayType>,
-          has_iterator<CompatibleArrayType>>::value;
-};
-
-template<bool, typename, typename>
-struct is_compatible_integer_type_impl : std::false_type {
-};
-
-template<typename RealIntegerType, typename CompatibleNumberIntegerType>
-struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType> {
-  using RealLimits = std::numeric_limits<RealIntegerType>;
-  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
-
-  static constexpr auto value =
-      std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
-      CompatibleLimits::is_integer and
-      RealLimits::is_signed == CompatibleLimits::is_signed;
-};
-
-template<typename RealIntegerType, typename CompatibleNumberIntegerType>
-struct is_compatible_integer_type {
-  static constexpr auto value =
-      is_compatible_integer_type_impl<
-          std::is_integral<CompatibleNumberIntegerType>::value and
-          not std::is_same<bool, CompatibleNumberIntegerType>::value,
-          RealIntegerType, CompatibleNumberIntegerType>::value;
-};
-
-template<typename BasicJsonType, typename T>
-struct has_from_json {
-private:
-  template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
-      std::declval<BasicJsonType>(), std::declval<T &>()))>::value>>
-  static int detect(U &&);
-
-  static void detect(...);
-
-public:
-  static constexpr bool value = std::is_integral<decltype(
-  detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
-};
-
-template<typename BasicJsonType, typename T>
-struct has_non_default_from_json {
-private:
-  template<
-      typename U,
-      typename = enable_if_t<std::is_same<
-          T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
-  static int detect(U &&);
-
-  static void detect(...);
-
-public:
-  static constexpr bool value = std::is_integral<decltype(detect(
-      std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
-};
-
-template<typename BasicJsonType, typename T>
-struct has_to_json {
-private:
-  template<typename U, typename = decltype(uncvref_t<U>::to_json(
-      std::declval<BasicJsonType &>(), std::declval<T>()))>
-  static int detect(U &&);
-
-  static void detect(...);
-
-public:
-  static constexpr bool value = std::is_integral<decltype(detect(
-      std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
-};
-
-template<typename BasicJsonType, typename CompatibleCompleteType>
-struct is_compatible_complete_type {
-  static constexpr bool value =
-      not std::is_base_of<std::istream, CompatibleCompleteType>::value and
-      not is_basic_json<CompatibleCompleteType>::value and
-      not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value and
-      has_to_json<BasicJsonType, CompatibleCompleteType>::value;
-};
-
-template<typename BasicJsonType, typename CompatibleType>
-struct is_compatible_type
-    : conjunction<is_complete_type<CompatibleType>,
-        is_compatible_complete_type<BasicJsonType, CompatibleType>> {
-};
-
-template<typename T>
-struct static_const {
-  static constexpr T value{};
-};
-
-template<typename T>
-constexpr T static_const<T>::value;
-}
-}
+      static constexpr std::size_t size() noexcept {
+        return sizeof...(Ints);
+      }
+    };
 
-#include <exception>
-#include <stdexcept>
+    template<class Sequence1, class Sequence2>
+    struct merge_and_renumber;
 
-namespace nlohmann {
-namespace detail {
-class exception : public std::exception {
-public:
-  const char *what() const noexcept override {
-    return m.what();
-  }
+    template<std::size_t... I1, std::size_t... I2>
+    struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
+        : index_sequence<I1..., (sizeof...(I1)+I2)...> {
+    };
 
-  const int id;
+    template<std::size_t N>
+    struct make_index_sequence
+        : merge_and_renumber<typename make_index_sequence<N / 2>::type,
+            typename make_index_sequence<N-N / 2>::type> {
+    };
 
-protected:
-  exception(int id_, const char *what_arg) : id(id_), m(what_arg) {}
+    template<>
+    struct make_index_sequence<0> : index_sequence<> {
+    };
+    template<>
+    struct make_index_sequence<1> : index_sequence<0> {
+    };
 
-  static std::string name(const std::string &ename, int id_) {
-    return "[json.exception."+ename+"."+std::to_string(id_)+"] ";
-  }
+    template<typename... Ts>
+    using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
 
-private:
-  std::runtime_error m;
-};
-
-class parse_error : public exception {
-public:
-  static parse_error create(int id_, std::size_t byte_, const std::string &what_arg) {
-    std::string w = exception::name("parse_error", id_)+"parse error"+
-                    (byte_ != 0 ? (" at "+std::to_string(byte_)) : "")+
-                    ": "+what_arg;
-    return parse_error(id_, byte_, w.c_str());
-  }
+    template<class...>
+    struct conjunction : std::true_type {
+    };
+    template<class B1>
+    struct conjunction<B1> : B1 {
+    };
+    template<class B1, class... Bn>
+    struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {
+    };
 
-  const std::size_t byte;
+    template<class B>
+    struct negation : std::integral_constant<bool, not B::value> {
+    };
 
-private:
-  parse_error(int id_, std::size_t byte_, const char *what_arg)
-      : exception(id_, what_arg), byte(byte_) {}
-};
+    template<unsigned N>
+    struct priority_tag : priority_tag<N-1> {
+    };
+    template<>
+    struct priority_tag<0> {
+    };
 
-class invalid_iterator : public exception {
-public:
-  static invalid_iterator create(int id_, const std::string &what_arg) {
-    std::string w = exception::name("invalid_iterator", id_)+what_arg;
-    return invalid_iterator(id_, w.c_str());
-  }
+    template<typename T, typename = void>
+    struct is_complete_type : std::false_type {
+    };
 
-private:
-  invalid_iterator(int id_, const char *what_arg)
-      : exception(id_, what_arg) {}
-};
+    template<typename T>
+    struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {
+    };
 
-class type_error : public exception {
-public:
-  static type_error create(int id_, const std::string &what_arg) {
-    std::string w = exception::name("type_error", id_)+what_arg;
-    return type_error(id_, w.c_str());
-  }
+    NLOHMANN_JSON_HAS_HELPER(mapped_type);
 
-private:
-  type_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
-};
+    NLOHMANN_JSON_HAS_HELPER(key_type);
 
-class out_of_range : public exception {
-public:
-  static out_of_range create(int id_, const std::string &what_arg) {
-    std::string w = exception::name("out_of_range", id_)+what_arg;
-    return out_of_range(id_, w.c_str());
-  }
+    NLOHMANN_JSON_HAS_HELPER(value_type);
 
-private:
-  out_of_range(int id_, const char *what_arg) : exception(id_, what_arg) {}
-};
+    NLOHMANN_JSON_HAS_HELPER(iterator);
 
-class other_error : public exception {
-public:
-  static other_error create(int id_, const std::string &what_arg) {
-    std::string w = exception::name("other_error", id_)+what_arg;
-    return other_error(id_, w.c_str());
-  }
+    template<bool B, class RealType, class CompatibleObjectType>
+    struct is_compatible_object_type_impl : std::false_type {
+    };
 
-private:
-  other_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
-};
-}
-}
+    template<class RealType, class CompatibleObjectType>
+    struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType> {
+      static constexpr auto value =
+          std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
+          std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
+    };
 
-#include <array>
+    template<class BasicJsonType, class CompatibleObjectType>
+    struct is_compatible_object_type {
+      static auto constexpr value = is_compatible_object_type_impl<
+          conjunction<negation<std::is_same<void, CompatibleObjectType>>,
+              has_mapped_type<CompatibleObjectType>,
+              has_key_type<CompatibleObjectType>>::value,
+          typename BasicJsonType::object_t, CompatibleObjectType>::value;
+    };
 
-namespace nlohmann {
-namespace detail {
-enum class value_t : std::uint8_t {
-  null,
-  object,
-  array,
-  string,
-  boolean,
-  number_integer,
-  number_unsigned,
-  number_float,
-  discarded
-};
-
-inline bool operator<(const value_t lhs, const value_t rhs) noexcept {
-  static constexpr std::array<std::uint8_t, 8> order = {{
-                                                            0, 3, 4, 5,
-                                                            1, 2, 2, 2
-                                                        }
-  };
+    template<typename BasicJsonType, typename T>
+    struct is_basic_json_nested_type {
+      static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
+                                    std::is_same<T, typename BasicJsonType::const_iterator>::value or
+                                    std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
+                                    std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
+    };
 
-  const auto l_index = static_cast<std::size_t>(lhs);
-  const auto r_index = static_cast<std::size_t>(rhs);
-  return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
-}
-}
-}
+    template<class BasicJsonType, class CompatibleArrayType>
+    struct is_compatible_array_type {
+      static auto constexpr value =
+          conjunction<negation<std::is_same<void, CompatibleArrayType>>,
+              negation<is_compatible_object_type<
+                  BasicJsonType, CompatibleArrayType>>,
+              negation<std::is_constructible<typename BasicJsonType::string_t,
+                  CompatibleArrayType>>,
+              negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
+              has_value_type<CompatibleArrayType>,
+              has_iterator<CompatibleArrayType>>::value;
+    };
 
-#include <forward_list>
-#include <tuple>
-#include <valarray>
+    template<bool, typename, typename>
+    struct is_compatible_integer_type_impl : std::false_type {
+    };
 
-namespace nlohmann {
-namespace detail {
-template<typename BasicJsonType, typename ArithmeticType,
-    enable_if_t<std::is_arithmetic<ArithmeticType>::value and
-                not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
-        int> = 0>
-void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val) {
-  switch(static_cast<value_t>(j)) {
-    case value_t::number_unsigned: {
-      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
-      break;
-    }
-    case value_t::number_integer: {
-      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
-      break;
-    }
-    case value_t::number_float: {
-      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
-      break;
-    }
+    template<typename RealIntegerType, typename CompatibleNumberIntegerType>
+    struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType> {
+      using RealLimits = std::numeric_limits<RealIntegerType>;
+      using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
 
-    default:
-      JSON_THROW(type_error::create(302, "type must be number, but is "+std::string(j.type_name())));
-  }
-}
+      static constexpr auto value =
+          std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
+          CompatibleLimits::is_integer and
+          RealLimits::is_signed == CompatibleLimits::is_signed;
+    };
 
-template<typename BasicJsonType>
-void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b) {
-  if(JSON_UNLIKELY(not j.is_boolean())) {
-    JSON_THROW(type_error::create(302, "type must be boolean, but is "+std::string(j.type_name())));
-  }
-  b = *j.template get_ptr<const typename BasicJsonType::boolean_t *>();
-}
+    template<typename RealIntegerType, typename CompatibleNumberIntegerType>
+    struct is_compatible_integer_type {
+      static constexpr auto value =
+          is_compatible_integer_type_impl<
+              std::is_integral<CompatibleNumberIntegerType>::value and
+              not std::is_same<bool, CompatibleNumberIntegerType>::value,
+              RealIntegerType, CompatibleNumberIntegerType>::value;
+    };
 
-template<typename BasicJsonType>
-void from_json(const BasicJsonType &j, typename BasicJsonType::string_t &s) {
-  if(JSON_UNLIKELY(not j.is_string())) {
-    JSON_THROW(type_error::create(302, "type must be string, but is "+std::string(j.type_name())));
-  }
-  s = *j.template get_ptr<const typename BasicJsonType::string_t *>();
-}
+    template<typename BasicJsonType, typename T>
+    struct has_from_json {
+    private:
+      template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
+          std::declval<BasicJsonType>(), std::declval<T &>()))>::value>>
+      static int detect(U &&);
 
-template<typename BasicJsonType>
-void from_json(const BasicJsonType &j, typename BasicJsonType::number_float_t &val) {
-  get_arithmetic_value(j, val);
-}
+      static void detect(...);
 
-template<typename BasicJsonType>
-void from_json(const BasicJsonType &j, typename BasicJsonType::number_unsigned_t &val) {
-  get_arithmetic_value(j, val);
-}
+    public:
+      static constexpr bool value = std::is_integral<decltype(
+      detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
+    };
 
-template<typename BasicJsonType>
-void from_json(const BasicJsonType &j, typename BasicJsonType::number_integer_t &val) {
-  get_arithmetic_value(j, val);
-}
+    template<typename BasicJsonType, typename T>
+    struct has_non_default_from_json {
+    private:
+      template<
+          typename U,
+          typename = enable_if_t<std::is_same<
+              T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
+      static int detect(U &&);
 
-template<typename BasicJsonType, typename EnumType,
-    enable_if_t<std::is_enum<EnumType>::value, int> = 0>
-void from_json(const BasicJsonType &j, EnumType &e) {
-  typename std::underlying_type<EnumType>::type val;
-  get_arithmetic_value(j, val);
-  e = static_cast<EnumType>(val);
-}
+      static void detect(...);
 
-template<typename BasicJsonType>
-void from_json(const BasicJsonType &j, typename BasicJsonType::array_t &arr) {
-  if(JSON_UNLIKELY(not j.is_array())) {
-    JSON_THROW(type_error::create(302, "type must be array, but is "+std::string(j.type_name())));
-  }
-  arr = *j.template get_ptr<const typename BasicJsonType::array_t *>();
-}
+    public:
+      static constexpr bool value = std::is_integral<decltype(detect(
+          std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
+    };
 
-template<typename BasicJsonType, typename T, typename Allocator,
-    enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
-void from_json(const BasicJsonType &j, std::forward_list<T, Allocator> &l) {
-  if(JSON_UNLIKELY(not j.is_array())) {
-    JSON_THROW(type_error::create(302, "type must be array, but is "+std::string(j.type_name())));
-  }
-  std::transform(j.rbegin(), j.rend(),
-                 std::front_inserter(l), [](const BasicJsonType &i) {
-        return i.template get<T>();
-      });
-}
+    template<typename BasicJsonType, typename T>
+    struct has_to_json {
+    private:
+      template<typename U, typename = decltype(uncvref_t<U>::to_json(
+          std::declval<BasicJsonType &>(), std::declval<T>()))>
+      static int detect(U &&);
 
-template<typename BasicJsonType, typename T,
-    enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
-void from_json(const BasicJsonType &j, std::valarray<T> &l) {
-  if(JSON_UNLIKELY(not j.is_array())) {
-    JSON_THROW(type_error::create(302, "type must be array, but is "+std::string(j.type_name())));
-  }
-  l.resize(j.size());
-  std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
-}
+      static void detect(...);
 
-template<typename BasicJsonType, typename CompatibleArrayType>
-void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag<0>) {
-  using std::end;
+    public:
+      static constexpr bool value = std::is_integral<decltype(detect(
+          std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
+    };
 
-  std::transform(j.begin(), j.end(),
-                 std::inserter(arr, end(arr)), [](const BasicJsonType &i) {
-        return i.template get<typename CompatibleArrayType::value_type>();
-      });
-}
+    template<typename BasicJsonType, typename CompatibleCompleteType>
+    struct is_compatible_complete_type {
+      static constexpr bool value =
+          not std::is_base_of<std::istream, CompatibleCompleteType>::value and
+          not is_basic_json<CompatibleCompleteType>::value and
+          not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value and
+          has_to_json<BasicJsonType, CompatibleCompleteType>::value;
+    };
 
-template<typename BasicJsonType, typename CompatibleArrayType>
-auto from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag<1>)
--> decltype(
-arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
-    void()) {
-  using std::end;
-
-  arr.reserve(j.size());
-  std::transform(j.begin(), j.end(),
-                 std::inserter(arr, end(arr)), [](const BasicJsonType &i) {
-        return i.template get<typename CompatibleArrayType::value_type>();
-      });
-}
+    template<typename BasicJsonType, typename CompatibleType>
+    struct is_compatible_type
+        : conjunction<is_complete_type<CompatibleType>,
+            is_compatible_complete_type<BasicJsonType, CompatibleType>> {
+    };
 
-template<typename BasicJsonType, typename T, std::size_t N>
-void from_json_array_impl(const BasicJsonType &j, std::array<T, N> &arr, priority_tag<2>) {
-  for(std::size_t i = 0; i < N; ++i) {
-    arr[i] = j.at(i).template get<T>();
-  }
-}
+    template<typename T>
+    struct static_const {
+      static constexpr T value{};
+    };
 
-template<
-    typename BasicJsonType, typename CompatibleArrayType,
-    enable_if_t<
-        is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
-        not std::is_same<typename BasicJsonType::array_t,
-            CompatibleArrayType>::value and
-        std::is_constructible<
-            BasicJsonType, typename CompatibleArrayType::value_type>::value,
-        int> = 0>
-void from_json(const BasicJsonType &j, CompatibleArrayType &arr) {
-  if(JSON_UNLIKELY(not j.is_array())) {
-    JSON_THROW(type_error::create(302, "type must be array, but is "+
-                                       std::string(j.type_name())));
+    template<typename T>
+    constexpr T static_const<T>::value;
   }
-
-  from_json_array_impl(j, arr, priority_tag<2>{});
 }
 
-template<typename BasicJsonType, typename CompatibleObjectType,
-    enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
-void from_json(const BasicJsonType &j, CompatibleObjectType &obj) {
-  if(JSON_UNLIKELY(not j.is_object())) {
-    JSON_THROW(type_error::create(302, "type must be object, but is "+std::string(j.type_name())));
-  }
+#include <exception>
+#include <stdexcept>
 
-  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t *>();
-  using value_type = typename CompatibleObjectType::value_type;
-  std::transform(
-      inner_object->begin(), inner_object->end(),
-      std::inserter(obj, obj.begin()),
-      [](typename BasicJsonType::object_t::value_type const &p) {
-        return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
-      });
-}
+namespace nlohmann {
+  namespace detail {
+    class exception : public std::exception {
+    public:
+      const char *what() const noexcept override {
+        return m.what();
+      }
 
-template<typename BasicJsonType, typename ArithmeticType,
-    enable_if_t<
-        std::is_arithmetic<ArithmeticType>::value and
-        not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
-        not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
-        not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
-        not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
-        int> = 0>
-void from_json(const BasicJsonType &j, ArithmeticType &val) {
-  switch(static_cast<value_t>(j)) {
-    case value_t::number_unsigned: {
-      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
-      break;
-    }
-    case value_t::number_integer: {
-      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
-      break;
-    }
-    case value_t::number_float: {
-      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
-      break;
-    }
-    case value_t::boolean: {
-      val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t *>());
-      break;
-    }
+      const int id;
 
-    default:
-      JSON_THROW(type_error::create(302, "type must be number, but is "+std::string(j.type_name())));
-  }
-}
+    protected:
+      exception(int id_, const char *what_arg) : id(id_), m(what_arg) {}
 
-template<typename BasicJsonType, typename A1, typename A2>
-void from_json(const BasicJsonType &j, std::pair<A1, A2> &p) {
-  p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
-}
+      static std::string name(const std::string &ename, int id_) {
+        return "[json.exception."+ename+"."+std::to_string(id_)+"] ";
+      }
 
-template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
-void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence<Idx...>) {
-  t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
-}
+    private:
+      std::runtime_error m;
+    };
 
-template<typename BasicJsonType, typename... Args>
-void from_json(const BasicJsonType &j, std::tuple<Args...> &t) {
-  from_json_tuple_impl(j, t, index_sequence_for<Args...>{});
-}
+    class parse_error : public exception {
+    public:
+      static parse_error create(int id_, std::size_t byte_, const std::string &what_arg) {
+        std::string w = exception::name("parse_error", id_)+"parse error"+
+                        (byte_ != 0 ? (" at "+std::to_string(byte_)) : "")+
+                        ": "+what_arg;
+        return parse_error(id_, byte_, w.c_str());
+      }
 
-struct from_json_fn {
-private:
-  template<typename BasicJsonType, typename T>
-  auto call(const BasicJsonType &j, T &val, priority_tag<1>) const
-  noexcept(noexcept(from_json(j, val)))
-  -> decltype(from_json(j, val), void()) {
-    return from_json(j, val);
-  }
+      const std::size_t byte;
 
-  template<typename BasicJsonType, typename T>
-  void call(const BasicJsonType &, T &, priority_tag<0>) const noexcept {
-    static_assert(sizeof(BasicJsonType) == 0,
-                  "could not find from_json() method in T's namespace");
-#ifdef _MSC_VER
+    private:
+      parse_error(int id_, std::size_t byte_, const char *what_arg)
+          : exception(id_, what_arg), byte(byte_) {}
+    };
 
-    using decayed = uncvref_t<T>;
-        static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
-                      "forcing MSVC stacktrace to show which T we're talking about.");
-#endif
-  }
+    class invalid_iterator : public exception {
+    public:
+      static invalid_iterator create(int id_, const std::string &what_arg) {
+        std::string w = exception::name("invalid_iterator", id_)+what_arg;
+        return invalid_iterator(id_, w.c_str());
+      }
 
-public:
-  template<typename BasicJsonType, typename T>
-  void operator()(const BasicJsonType &j, T &val) const
-  noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1>{}))) {
-    return call(j, val, priority_tag<1>{});
-  }
-};
-}
+    private:
+      invalid_iterator(int id_, const char *what_arg)
+          : exception(id_, what_arg) {}
+    };
 
-namespace {
-constexpr const auto &from_json = detail::static_const<detail::from_json_fn>::value;
-}
-}
+    class type_error : public exception {
+    public:
+      static type_error create(int id_, const std::string &what_arg) {
+        std::string w = exception::name("type_error", id_)+what_arg;
+        return type_error(id_, w.c_str());
+      }
 
-namespace nlohmann {
-namespace detail {
-template<value_t>
-struct external_constructor;
+    private:
+      type_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
+    };
 
-template<>
-struct external_constructor<value_t::boolean> {
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept {
-    j.m_type = value_t::boolean;
-    j.m_value = b;
-    j.assert_invariant();
-  }
-};
+    class out_of_range : public exception {
+    public:
+      static out_of_range create(int id_, const std::string &what_arg) {
+        std::string w = exception::name("out_of_range", id_)+what_arg;
+        return out_of_range(id_, w.c_str());
+      }
 
-template<>
-struct external_constructor<value_t::string> {
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s) {
-    j.m_type = value_t::string;
-    j.m_value = s;
-    j.assert_invariant();
-  }
+    private:
+      out_of_range(int id_, const char *what_arg) : exception(id_, what_arg) {}
+    };
 
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s) {
-    j.m_type = value_t::string;
-    j.m_value = std::move(s);
-    j.assert_invariant();
-  }
-};
+    class other_error : public exception {
+    public:
+      static other_error create(int id_, const std::string &what_arg) {
+        std::string w = exception::name("other_error", id_)+what_arg;
+        return other_error(id_, w.c_str());
+      }
 
-template<>
-struct external_constructor<value_t::number_float> {
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept {
-    j.m_type = value_t::number_float;
-    j.m_value = val;
-    j.assert_invariant();
+    private:
+      other_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
+    };
   }
-};
+}
 
-template<>
-struct external_constructor<value_t::number_unsigned> {
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept {
-    j.m_type = value_t::number_unsigned;
-    j.m_value = val;
-    j.assert_invariant();
-  }
-};
+#include <array>
 
-template<>
-struct external_constructor<value_t::number_integer> {
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept {
-    j.m_type = value_t::number_integer;
-    j.m_value = val;
-    j.assert_invariant();
-  }
-};
+namespace nlohmann {
+  namespace detail {
+    enum class value_t : std::uint8_t {
+      null,
+      object,
+      array,
+      string,
+      boolean,
+      number_integer,
+      number_unsigned,
+      number_float,
+      discarded
+    };
 
-template<>
-struct external_constructor<value_t::array> {
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr) {
-    j.m_type = value_t::array;
-    j.m_value = arr;
-    j.assert_invariant();
-  }
+    inline bool operator<(const value_t lhs, const value_t rhs) noexcept {
+      static constexpr std::array<std::uint8_t, 8> order = {{
+                                                                0, 3, 4, 5,
+                                                                1, 2, 2, 2
+                                                            }
+      };
 
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr) {
-    j.m_type = value_t::array;
-    j.m_value = std::move(arr);
-    j.assert_invariant();
+      const auto l_index = static_cast<std::size_t>(lhs);
+      const auto r_index = static_cast<std::size_t>(rhs);
+      return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
+    }
   }
+}
 
-  template<typename BasicJsonType, typename CompatibleArrayType,
-      enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
-          int> = 0>
-  static void construct(BasicJsonType &j, const CompatibleArrayType &arr) {
-    using std::begin;
-    using std::end;
-    j.m_type = value_t::array;
-    j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
-    j.assert_invariant();
-  }
+#include <forward_list>
+#include <tuple>
+#include <valarray>
 
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, const std::vector<bool> &arr) {
-    j.m_type = value_t::array;
-    j.m_value = value_t::array;
-    j.m_value.array->reserve(arr.size());
-    for(const bool x : arr) {
-      j.m_value.array->push_back(x);
-    }
-    j.assert_invariant();
-  }
+namespace nlohmann {
+  namespace detail {
+    template<typename BasicJsonType, typename ArithmeticType,
+        enable_if_t<std::is_arithmetic<ArithmeticType>::value and
+                    not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
+            int> = 0>
+    void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val) {
+      switch(static_cast<value_t>(j)) {
+        case value_t::number_unsigned: {
+          val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
+          break;
+        }
+        case value_t::number_integer: {
+          val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
+          break;
+        }
+        case value_t::number_float: {
+          val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
+          break;
+        }
 
-  template<typename BasicJsonType, typename T,
-      enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
-  static void construct(BasicJsonType &j, const std::valarray<T> &arr) {
-    j.m_type = value_t::array;
-    j.m_value = value_t::array;
-    j.m_value.array->resize(arr.size());
-    std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
-    j.assert_invariant();
-  }
-};
+        default:
+          JSON_THROW(type_error::create(302, "type must be number, but is "+std::string(j.type_name())));
+      }
+    }
 
-template<>
-struct external_constructor<value_t::object> {
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj) {
-    j.m_type = value_t::object;
-    j.m_value = obj;
-    j.assert_invariant();
-  }
+    template<typename BasicJsonType>
+    void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b) {
+      if(JSON_UNLIKELY(not j.is_boolean())) {
+        JSON_THROW(type_error::create(302, "type must be boolean, but is "+std::string(j.type_name())));
+      }
+      b = *j.template get_ptr<const typename BasicJsonType::boolean_t *>();
+    }
 
-  template<typename BasicJsonType>
-  static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj) {
-    j.m_type = value_t::object;
-    j.m_value = std::move(obj);
-    j.assert_invariant();
-  }
+    template<typename BasicJsonType>
+    void from_json(const BasicJsonType &j, typename BasicJsonType::string_t &s) {
+      if(JSON_UNLIKELY(not j.is_string())) {
+        JSON_THROW(type_error::create(302, "type must be string, but is "+std::string(j.type_name())));
+      }
+      s = *j.template get_ptr<const typename BasicJsonType::string_t *>();
+    }
 
-  template<typename BasicJsonType, typename CompatibleObjectType,
-      enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
-  static void construct(BasicJsonType &j, const CompatibleObjectType &obj) {
-    using std::begin;
-    using std::end;
+    template<typename BasicJsonType>
+    void from_json(const BasicJsonType &j, typename BasicJsonType::number_float_t &val) {
+      get_arithmetic_value(j, val);
+    }
 
-    j.m_type = value_t::object;
-    j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
-    j.assert_invariant();
-  }
-};
+    template<typename BasicJsonType>
+    void from_json(const BasicJsonType &j, typename BasicJsonType::number_unsigned_t &val) {
+      get_arithmetic_value(j, val);
+    }
 
-template<typename BasicJsonType, typename T,
-    enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
-void to_json(BasicJsonType &j, T b) noexcept {
-  external_constructor<value_t::boolean>::construct(j, b);
-}
+    template<typename BasicJsonType>
+    void from_json(const BasicJsonType &j, typename BasicJsonType::number_integer_t &val) {
+      get_arithmetic_value(j, val);
+    }
 
-template<typename BasicJsonType, typename CompatibleString,
-    enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
-void to_json(BasicJsonType &j, const CompatibleString &s) {
-  external_constructor<value_t::string>::construct(j, s);
-}
+    template<typename BasicJsonType, typename EnumType,
+        enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+    void from_json(const BasicJsonType &j, EnumType &e) {
+      typename std::underlying_type<EnumType>::type val;
+      get_arithmetic_value(j, val);
+      e = static_cast<EnumType>(val);
+    }
 
-template<typename BasicJsonType>
-void to_json(BasicJsonType &j, typename BasicJsonType::string_t &&s) {
-  external_constructor<value_t::string>::construct(j, std::move(s));
-}
+    template<typename BasicJsonType>
+    void from_json(const BasicJsonType &j, typename BasicJsonType::array_t &arr) {
+      if(JSON_UNLIKELY(not j.is_array())) {
+        JSON_THROW(type_error::create(302, "type must be array, but is "+std::string(j.type_name())));
+      }
+      arr = *j.template get_ptr<const typename BasicJsonType::array_t *>();
+    }
 
-template<typename BasicJsonType, typename FloatType,
-    enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
-void to_json(BasicJsonType &j, FloatType val) noexcept {
-  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
-}
+    template<typename BasicJsonType, typename T, typename Allocator,
+        enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
+    void from_json(const BasicJsonType &j, std::forward_list<T, Allocator> &l) {
+      if(JSON_UNLIKELY(not j.is_array())) {
+        JSON_THROW(type_error::create(302, "type must be array, but is "+std::string(j.type_name())));
+      }
+      std::transform(j.rbegin(), j.rend(),
+                     std::front_inserter(l), [](const BasicJsonType &i) {
+            return i.template get<T>();
+          });
+    }
 
-template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
-    enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
-void to_json(BasicJsonType &j, CompatibleNumberUnsignedType val) noexcept {
-  external_constructor<value_t::number_unsigned>::construct(j,
-                                                            static_cast<typename BasicJsonType::number_unsigned_t>(val));
-}
+    template<typename BasicJsonType, typename T,
+        enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
+    void from_json(const BasicJsonType &j, std::valarray<T> &l) {
+      if(JSON_UNLIKELY(not j.is_array())) {
+        JSON_THROW(type_error::create(302, "type must be array, but is "+std::string(j.type_name())));
+      }
+      l.resize(j.size());
+      std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
+    }
 
-template<typename BasicJsonType, typename CompatibleNumberIntegerType,
-    enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
-void to_json(BasicJsonType &j, CompatibleNumberIntegerType val) noexcept {
-  external_constructor<value_t::number_integer>::construct(j,
-                                                           static_cast<typename BasicJsonType::number_integer_t>(val));
-}
+    template<typename BasicJsonType, typename CompatibleArrayType>
+    void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag<0>) {
+      using std::end;
 
-template<typename BasicJsonType, typename EnumType,
-    enable_if_t<std::is_enum<EnumType>::value, int> = 0>
-void to_json(BasicJsonType &j, EnumType e) noexcept {
-  using underlying_type = typename std::underlying_type<EnumType>::type;
-  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
-}
+      std::transform(j.begin(), j.end(),
+                     std::inserter(arr, end(arr)), [](const BasicJsonType &i) {
+            return i.template get<typename CompatibleArrayType::value_type>();
+          });
+    }
 
-template<typename BasicJsonType>
-void to_json(BasicJsonType &j, const std::vector<bool> &e) {
-  external_constructor<value_t::array>::construct(j, e);
-}
+    template<typename BasicJsonType, typename CompatibleArrayType>
+    auto from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag<1>)
+    -> decltype(
+    arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
+        void()) {
+      using std::end;
 
-template<typename BasicJsonType, typename CompatibleArrayType,
-    enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
-                std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
-        int> = 0>
-void to_json(BasicJsonType &j, const CompatibleArrayType &arr) {
-  external_constructor<value_t::array>::construct(j, arr);
-}
+      arr.reserve(j.size());
+      std::transform(j.begin(), j.end(),
+                     std::inserter(arr, end(arr)), [](const BasicJsonType &i) {
+            return i.template get<typename CompatibleArrayType::value_type>();
+          });
+    }
 
-template<typename BasicJsonType, typename T,
-    enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
-void to_json(BasicJsonType &j, std::valarray<T> arr) {
-  external_constructor<value_t::array>::construct(j, std::move(arr));
-}
+    template<typename BasicJsonType, typename T, std::size_t N>
+    void from_json_array_impl(const BasicJsonType &j, std::array<T, N> &arr, priority_tag<2>) {
+      for(std::size_t i = 0; i < N; ++i) {
+        arr[i] = j.at(i).template get<T>();
+      }
+    }
 
-template<typename BasicJsonType>
-void to_json(BasicJsonType &j, typename BasicJsonType::array_t &&arr) {
-  external_constructor<value_t::array>::construct(j, std::move(arr));
-}
+    template<
+        typename BasicJsonType, typename CompatibleArrayType,
+        enable_if_t<
+            is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
+            not std::is_same<typename BasicJsonType::array_t,
+                CompatibleArrayType>::value and
+            std::is_constructible<
+                BasicJsonType, typename CompatibleArrayType::value_type>::value,
+            int> = 0>
+    void from_json(const BasicJsonType &j, CompatibleArrayType &arr) {
+      if(JSON_UNLIKELY(not j.is_array())) {
+        JSON_THROW(type_error::create(302, "type must be array, but is "+
+                                           std::string(j.type_name())));
+      }
 
-template<typename BasicJsonType, typename CompatibleObjectType,
-    enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
-void to_json(BasicJsonType &j, const CompatibleObjectType &obj) {
-  external_constructor<value_t::object>::construct(j, obj);
-}
+      from_json_array_impl(j, arr, priority_tag<2>{});
+    }
 
-template<typename BasicJsonType>
-void to_json(BasicJsonType &j, typename BasicJsonType::object_t &&obj) {
-  external_constructor<value_t::object>::construct(j, std::move(obj));
-}
+    template<typename BasicJsonType, typename CompatibleObjectType,
+        enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
+    void from_json(const BasicJsonType &j, CompatibleObjectType &obj) {
+      if(JSON_UNLIKELY(not j.is_object())) {
+        JSON_THROW(type_error::create(302, "type must be object, but is "+std::string(j.type_name())));
+      }
 
-template<typename BasicJsonType, typename T, std::size_t N,
-    enable_if_t<not std::is_constructible<typename BasicJsonType::string_t, T (&)[N]>::value, int> = 0>
-void to_json(BasicJsonType &j, T (&arr)[N]) {
-  external_constructor<value_t::array>::construct(j, arr);
-}
+      auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t *>();
+      using value_type = typename CompatibleObjectType::value_type;
+      std::transform(
+          inner_object->begin(), inner_object->end(),
+          std::inserter(obj, obj.begin()),
+          [](typename BasicJsonType::object_t::value_type const &p) {
+            return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
+          });
+    }
 
-template<typename BasicJsonType, typename... Args>
-void to_json(BasicJsonType &j, const std::pair<Args...> &p) {
-  j = {p.first, p.second};
-}
+    template<typename BasicJsonType, typename ArithmeticType,
+        enable_if_t<
+            std::is_arithmetic<ArithmeticType>::value and
+            not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
+            not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
+            not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
+            not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
+            int> = 0>
+    void from_json(const BasicJsonType &j, ArithmeticType &val) {
+      switch(static_cast<value_t>(j)) {
+        case value_t::number_unsigned: {
+          val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
+          break;
+        }
+        case value_t::number_integer: {
+          val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
+          break;
+        }
+        case value_t::number_float: {
+          val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
+          break;
+        }
+        case value_t::boolean: {
+          val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t *>());
+          break;
+        }
 
-template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
-void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence<Idx...>) {
-  j = {std::get<Idx>(t)...};
-}
+        default:
+          JSON_THROW(type_error::create(302, "type must be number, but is "+std::string(j.type_name())));
+      }
+    }
 
-template<typename BasicJsonType, typename... Args>
-void to_json(BasicJsonType &j, const std::tuple<Args...> &t) {
-  to_json_tuple_impl(j, t, index_sequence_for<Args...>{});
-}
+    template<typename BasicJsonType, typename A1, typename A2>
+    void from_json(const BasicJsonType &j, std::pair<A1, A2> &p) {
+      p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
+    }
 
-struct to_json_fn {
-private:
-  template<typename BasicJsonType, typename T>
-  auto call(BasicJsonType &j, T &&val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
-  -> decltype(to_json(j, std::forward<T>(val)), void()) {
-    return to_json(j, std::forward<T>(val));
-  }
+    template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+    void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence<Idx...>) {
+      t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
+    }
+
+    template<typename BasicJsonType, typename... Args>
+    void from_json(const BasicJsonType &j, std::tuple<Args...> &t) {
+      from_json_tuple_impl(j, t, index_sequence_for<Args...>{});
+    }
 
-  template<typename BasicJsonType, typename T>
-  void call(BasicJsonType &, T &&, priority_tag<0>) const noexcept {
-    static_assert(sizeof(BasicJsonType) == 0,
-                  "could not find to_json() method in T's namespace");
+    struct from_json_fn {
+    private:
+      template<typename BasicJsonType, typename T>
+      auto call(const BasicJsonType &j, T &val, priority_tag<1>) const
+      noexcept(noexcept(from_json(j, val)))
+      -> decltype(from_json(j, val), void()) {
+        return from_json(j, val);
+      }
 
+      template<typename BasicJsonType, typename T>
+      void call(const BasicJsonType &, T &, priority_tag<0>) const noexcept {
+        static_assert(sizeof(BasicJsonType) == 0,
+                      "could not find from_json() method in T's namespace");
 #ifdef _MSC_VER
 
-    using decayed = uncvref_t<T>;
+        using decayed = uncvref_t<T>;
         static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
                       "forcing MSVC stacktrace to show which T we're talking about.");
 #endif
-  }
+      }
 
-public:
-  template<typename BasicJsonType, typename T>
-  void operator()(BasicJsonType &j, T &&val) const
-  noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1>{}))) {
-    return call(j, std::forward<T>(val), priority_tag<1>{});
+    public:
+      template<typename BasicJsonType, typename T>
+      void operator()(const BasicJsonType &j, T &val) const
+      noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1>{}))) {
+        return call(j, val, priority_tag<1>{});
+      }
+    };
   }
-};
-}
 
-namespace {
-constexpr const auto &to_json = detail::static_const<detail::to_json_fn>::value;
-}
+  namespace {
+    constexpr const auto &from_json = detail::static_const<detail::from_json_fn>::value;
+  }
 }
 
-#include <cstring>
-#include <ios>
-#include <istream>
-
 namespace nlohmann {
-namespace detail {
-struct input_adapter_protocol {
-  virtual std::char_traits<char>::int_type get_character() = 0;
+  namespace detail {
+    template<value_t>
+    struct external_constructor;
+
+    template<>
+    struct external_constructor<value_t::boolean> {
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept {
+        j.m_type = value_t::boolean;
+        j.m_value = b;
+        j.assert_invariant();
+      }
+    };
 
-  virtual void unget_character() = 0;
+    template<>
+    struct external_constructor<value_t::string> {
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s) {
+        j.m_type = value_t::string;
+        j.m_value = s;
+        j.assert_invariant();
+      }
 
-  virtual ~input_adapter_protocol() = default;
-};
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s) {
+        j.m_type = value_t::string;
+        j.m_value = std::move(s);
+        j.assert_invariant();
+      }
+    };
 
-using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
+    template<>
+    struct external_constructor<value_t::number_float> {
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept {
+        j.m_type = value_t::number_float;
+        j.m_value = val;
+        j.assert_invariant();
+      }
+    };
 
-class input_stream_adapter : public input_adapter_protocol {
-public:
-  ~input_stream_adapter() override {
-    is.clear();
-  }
+    template<>
+    struct external_constructor<value_t::number_unsigned> {
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept {
+        j.m_type = value_t::number_unsigned;
+        j.m_value = val;
+        j.assert_invariant();
+      }
+    };
 
-  explicit input_stream_adapter(std::istream &i)
-      : is(i), sb(*i.rdbuf()) {
-    std::char_traits<char>::int_type c;
-    if((c = get_character()) == 0xEF) {
-      if((c = get_character()) == 0xBB) {
-        if((c = get_character()) == 0xBF) {
-          return;
-        } else if(c != std::char_traits<char>::eof()) {
-          is.unget();
+    template<>
+    struct external_constructor<value_t::number_integer> {
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept {
+        j.m_type = value_t::number_integer;
+        j.m_value = val;
+        j.assert_invariant();
+      }
+    };
+
+    template<>
+    struct external_constructor<value_t::array> {
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr) {
+        j.m_type = value_t::array;
+        j.m_value = arr;
+        j.assert_invariant();
+      }
+
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr) {
+        j.m_type = value_t::array;
+        j.m_value = std::move(arr);
+        j.assert_invariant();
+      }
+
+      template<typename BasicJsonType, typename CompatibleArrayType,
+          enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
+              int> = 0>
+      static void construct(BasicJsonType &j, const CompatibleArrayType &arr) {
+        using std::begin;
+        using std::end;
+        j.m_type = value_t::array;
+        j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
+        j.assert_invariant();
+      }
+
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, const std::vector<bool> &arr) {
+        j.m_type = value_t::array;
+        j.m_value = value_t::array;
+        j.m_value.array->reserve(arr.size());
+        for(const bool x : arr) {
+          j.m_value.array->push_back(x);
         }
-        is.putback('\xBB');
-      } else if(c != std::char_traits<char>::eof()) {
-        is.unget();
+        j.assert_invariant();
       }
-      is.putback('\xEF');
-    } else if(c != std::char_traits<char>::eof()) {
-      is.unget();
-    }
-  }
 
-  input_stream_adapter(const input_stream_adapter &) = delete;
+      template<typename BasicJsonType, typename T,
+          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+      static void construct(BasicJsonType &j, const std::valarray<T> &arr) {
+        j.m_type = value_t::array;
+        j.m_value = value_t::array;
+        j.m_value.array->resize(arr.size());
+        std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
+        j.assert_invariant();
+      }
+    };
 
-  input_stream_adapter &operator=(input_stream_adapter &) = delete;
+    template<>
+    struct external_constructor<value_t::object> {
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj) {
+        j.m_type = value_t::object;
+        j.m_value = obj;
+        j.assert_invariant();
+      }
 
-  std::char_traits<char>::int_type get_character() override {
-    return sb.sbumpc();
-  }
+      template<typename BasicJsonType>
+      static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj) {
+        j.m_type = value_t::object;
+        j.m_value = std::move(obj);
+        j.assert_invariant();
+      }
 
-  void unget_character() override {
-    sb.sungetc();
-  }
+      template<typename BasicJsonType, typename CompatibleObjectType,
+          enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
+      static void construct(BasicJsonType &j, const CompatibleObjectType &obj) {
+        using std::begin;
+        using std::end;
 
-private:
-  std::istream &is;
-  std::streambuf &sb;
-};
+        j.m_type = value_t::object;
+        j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
+        j.assert_invariant();
+      }
+    };
 
-class input_buffer_adapter : public input_adapter_protocol {
-public:
-  input_buffer_adapter(const char *b, const std::size_t l)
-      : cursor(b), limit(b+l), start(b) {
-    if(l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF') {
-      cursor += 3;
+    template<typename BasicJsonType, typename T,
+        enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
+    void to_json(BasicJsonType &j, T b) noexcept {
+      external_constructor<value_t::boolean>::construct(j, b);
     }
-  }
-
-  input_buffer_adapter(const input_buffer_adapter &) = delete;
 
-  input_buffer_adapter &operator=(input_buffer_adapter &) = delete;
-
-  std::char_traits<char>::int_type get_character() noexcept override {
-    if(JSON_LIKELY(cursor < limit)) {
-      return std::char_traits<char>::to_int_type(*(cursor++));
+    template<typename BasicJsonType, typename CompatibleString,
+        enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
+    void to_json(BasicJsonType &j, const CompatibleString &s) {
+      external_constructor<value_t::string>::construct(j, s);
     }
 
-    return std::char_traits<char>::eof();
-  }
-
-  void unget_character() noexcept override {
-    if(JSON_LIKELY(cursor > start)) {
-      --cursor;
+    template<typename BasicJsonType>
+    void to_json(BasicJsonType &j, typename BasicJsonType::string_t &&s) {
+      external_constructor<value_t::string>::construct(j, std::move(s));
     }
-  }
-
-private:
-  const char *cursor;
-
-  const char *limit;
-
-  const char *start;
-};
-
-class input_adapter {
-public:
-  input_adapter(std::istream &i)
-      : ia(std::make_shared<input_stream_adapter>(i)) {}
-
-  input_adapter(std::istream &&i)
-      : ia(std::make_shared<input_stream_adapter>(i)) {}
-
-  template<typename CharT,
-      typename std::enable_if<
-          std::is_pointer<CharT>::value and
-          std::is_integral<typename std::remove_pointer<CharT>::type>::value and
-          sizeof(typename std::remove_pointer<CharT>::type) == 1,
-          int>::type = 0>
-  input_adapter(CharT b, std::size_t l)
-      : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char *>(b), l)) {}
-
-  template<typename CharT,
-      typename std::enable_if<
-          std::is_pointer<CharT>::value and
-          std::is_integral<typename std::remove_pointer<CharT>::type>::value and
-          sizeof(typename std::remove_pointer<CharT>::type) == 1,
-          int>::type = 0>
-  input_adapter(CharT b)
-      : input_adapter(reinterpret_cast<const char *>(b),
-                      std::strlen(reinterpret_cast<const char *>(b))) {}
 
-  template<class IteratorType,
-      typename std::enable_if<
-          std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
-          int>::type = 0>
-  input_adapter(IteratorType first, IteratorType last) {
-    assert(std::accumulate(
-        first, last, std::pair<bool, int>(true, 0),
-        [&first](std::pair<bool, int> res, decltype(*first) val) {
-          res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
-          return res;
-        }).first);
-
-    static_assert(
-        sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
-        "each element in the iterator range must have the size of 1 byte");
-
-    const auto len = static_cast<size_t>(std::distance(first, last));
-    if(JSON_LIKELY(len > 0)) {
-      ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char *>(&(*first)), len);
-    } else {
-      ia = std::make_shared<input_buffer_adapter>(nullptr, len);
+    template<typename BasicJsonType, typename FloatType,
+        enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
+    void to_json(BasicJsonType &j, FloatType val) noexcept {
+      external_constructor<value_t::number_float>::construct(j,
+                                                             static_cast<typename BasicJsonType::number_float_t>(val));
     }
-  }
-
-  template<class T, std::size_t N>
-  input_adapter(T (&array)[N])
-      : input_adapter(std::begin(array), std::end(array)) {}
-
-  template<class ContiguousContainer, typename
-  std::enable_if<not std::is_pointer<ContiguousContainer>::value and
-                 std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(
-                     std::declval<ContiguousContainer const>()))>::iterator_category>::value,
-      int>::type = 0>
-  input_adapter(const ContiguousContainer &c)
-      : input_adapter(std::begin(c), std::end(c)) {}
-
-  operator input_adapter_t() {
-    return ia;
-  }
-
-private:
-  input_adapter_t ia = nullptr;
-};
-}
-}
-
-#include <clocale>
-#include <cstdlib>
-#include <iomanip>
-#include <sstream>
-
-namespace nlohmann {
-namespace detail {
-template<typename BasicJsonType>
-class lexer {
-  using number_integer_t = typename BasicJsonType::number_integer_t;
-  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
-  using number_float_t = typename BasicJsonType::number_float_t;
-  using string_t = typename BasicJsonType::string_t;
-
-public:
-  enum class token_type {
-    uninitialized,
-    literal_true,
-    literal_false,
-    literal_null,
-    value_string,
-    value_unsigned,
-    value_integer,
-    value_float,
-    begin_array,
-    begin_object,
-    end_array,
-    end_object,
-    name_separator,
-    value_separator,
-    parse_error,
-    end_of_input,
-    literal_or_value
-  };
 
-  static const char *token_type_name(const token_type t) noexcept {
-    switch(t) {
-      case token_type::uninitialized:
-        return "<uninitialized>";
-      case token_type::literal_true:
-        return "true literal";
-      case token_type::literal_false:
-        return "false literal";
-      case token_type::literal_null:
-        return "null literal";
-      case token_type::value_string:
-        return "string literal";
-      case lexer::token_type::value_unsigned:
-      case lexer::token_type::value_integer:
-      case lexer::token_type::value_float:
-        return "number literal";
-      case token_type::begin_array:
-        return "'['";
-      case token_type::begin_object:
-        return "'{'";
-      case token_type::end_array:
-        return "']'";
-      case token_type::end_object:
-        return "'}'";
-      case token_type::name_separator:
-        return "':'";
-      case token_type::value_separator:
-        return "','";
-      case token_type::parse_error:
-        return "<parse error>";
-      case token_type::end_of_input:
-        return "end of input";
-      case token_type::literal_or_value:
-        return "'[', '{', or a literal";
-      default:
-        return "unknown token";
+    template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
+        enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
+    void to_json(BasicJsonType &j, CompatibleNumberUnsignedType val) noexcept {
+      external_constructor<value_t::number_unsigned>::construct(j,
+                                                                static_cast<typename BasicJsonType::number_unsigned_t>(val));
     }
-  }
-
-  explicit lexer(detail::input_adapter_t adapter)
-      : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
-
-  lexer(const lexer &) = delete;
-
-  lexer &operator=(lexer &) = delete;
-
-private:
-  static char get_decimal_point() noexcept {
-    const auto loc = localeconv();
-    assert(loc != nullptr);
-    return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
-  }
-
-  int get_codepoint() {
-    assert(current == 'u');
-    int codepoint = 0;
 
-    const auto factors = {12, 8, 4, 0};
-    for(const auto factor : factors) {
-      get();
-
-      if(current >= '0' and current <= '9') {
-        codepoint += ((current-0x30) << factor);
-      } else if(current >= 'A' and current <= 'F') {
-        codepoint += ((current-0x37) << factor);
-      } else if(current >= 'a' and current <= 'f') {
-        codepoint += ((current-0x57) << factor);
-      } else {
-        return -1;
-      }
+    template<typename BasicJsonType, typename CompatibleNumberIntegerType,
+        enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
+    void to_json(BasicJsonType &j, CompatibleNumberIntegerType val) noexcept {
+      external_constructor<value_t::number_integer>::construct(j,
+                                                               static_cast<typename BasicJsonType::number_integer_t>(val));
     }
 
-    assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
-    return codepoint;
-  }
-
-  bool next_byte_in_range(std::initializer_list<int> ranges) {
-    assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
-    add(current);
-
-    for(auto range = ranges.begin(); range != ranges.end(); ++range) {
-      get();
-      if(JSON_LIKELY(*range <= current and current <= *(++range))) {
-        add(current);
-      } else {
-        error_message = "invalid string: ill-formed UTF-8 byte";
-        return false;
-      }
+    template<typename BasicJsonType, typename EnumType,
+        enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+    void to_json(BasicJsonType &j, EnumType e) noexcept {
+      using underlying_type = typename std::underlying_type<EnumType>::type;
+      external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
     }
 
-    return true;
-  }
-
-  token_type scan_string() {
-    reset();
-
-    assert(current == '\"');
-
-    while(true) {
-      switch(get()) {
-        case std::char_traits<char>::eof(): {
-          error_message = "invalid string: missing closing quote";
-          return token_type::parse_error;
-        }
-
-        case '\"': {
-          return token_type::value_string;
-        }
-
-        case '\\': {
-          switch(get()) {
-            case '\"':
-              add('\"');
-              break;
-
-            case '\\':
-              add('\\');
-              break;
-
-            case '/':
-              add('/');
-              break;
-
-            case 'b':
-              add('\b');
-              break;
-
-            case 'f':
-              add('\f');
-              break;
-
-            case 'n':
-              add('\n');
-              break;
-
-            case 'r':
-              add('\r');
-              break;
-
-            case 't':
-              add('\t');
-              break;
-
-            case 'u': {
-              const int codepoint1 = get_codepoint();
-              int codepoint = codepoint1;
-
-              if(JSON_UNLIKELY(codepoint1 == -1)) {
-                error_message = "invalid string: '\\u' must be followed by 4 hex digits";
-                return token_type::parse_error;
-              }
-
-              if(0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) {
-                if(JSON_LIKELY(get() == '\\' and get() == 'u')) {
-                  const int codepoint2 = get_codepoint();
-
-                  if(JSON_UNLIKELY(codepoint2 == -1)) {
-                    error_message = "invalid string: '\\u' must be followed by 4 hex digits";
-                    return token_type::parse_error;
-                  }
-
-                  if(JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) {
-                    codepoint =
-
-                        (codepoint1 << 10)
-
-                        +codepoint2
-
-                        -0x35FDC00;
-                  } else {
-                    error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
-                    return token_type::parse_error;
-                  }
-                } else {
-                  error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
-                  return token_type::parse_error;
-                }
-              } else {
-                if(JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) {
-                  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
-                  return token_type::parse_error;
-                }
-              }
-
-              assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
-
-              if(codepoint < 0x80) {
-                add(codepoint);
-              } else if(codepoint <= 0x7FF) {
-                add(0xC0 | (codepoint >> 6));
-                add(0x80 | (codepoint & 0x3F));
-              } else if(codepoint <= 0xFFFF) {
-                add(0xE0 | (codepoint >> 12));
-                add(0x80 | ((codepoint >> 6) & 0x3F));
-                add(0x80 | (codepoint & 0x3F));
-              } else {
-                add(0xF0 | (codepoint >> 18));
-                add(0x80 | ((codepoint >> 12) & 0x3F));
-                add(0x80 | ((codepoint >> 6) & 0x3F));
-                add(0x80 | (codepoint & 0x3F));
-              }
-
-              break;
-            }
-
-            default:
-              error_message = "invalid string: forbidden character after backslash";
-              return token_type::parse_error;
-          }
-
-          break;
-        }
-
-        case 0x00:
-        case 0x01:
-        case 0x02:
-        case 0x03:
-        case 0x04:
-        case 0x05:
-        case 0x06:
-        case 0x07:
-        case 0x08:
-        case 0x09:
-        case 0x0A:
-        case 0x0B:
-        case 0x0C:
-        case 0x0D:
-        case 0x0E:
-        case 0x0F:
-        case 0x10:
-        case 0x11:
-        case 0x12:
-        case 0x13:
-        case 0x14:
-        case 0x15:
-        case 0x16:
-        case 0x17:
-        case 0x18:
-        case 0x19:
-        case 0x1A:
-        case 0x1B:
-        case 0x1C:
-        case 0x1D:
-        case 0x1E:
-        case 0x1F: {
-          error_message = "invalid string: control character must be escaped";
-          return token_type::parse_error;
-        }
-
-        case 0x20:
-        case 0x21:
-        case 0x23:
-        case 0x24:
-        case 0x25:
-        case 0x26:
-        case 0x27:
-        case 0x28:
-        case 0x29:
-        case 0x2A:
-        case 0x2B:
-        case 0x2C:
-        case 0x2D:
-        case 0x2E:
-        case 0x2F:
-        case 0x30:
-        case 0x31:
-        case 0x32:
-        case 0x33:
-        case 0x34:
-        case 0x35:
-        case 0x36:
-        case 0x37:
-        case 0x38:
-        case 0x39:
-        case 0x3A:
-        case 0x3B:
-        case 0x3C:
-        case 0x3D:
-        case 0x3E:
-        case 0x3F:
-        case 0x40:
-        case 0x41:
-        case 0x42:
-        case 0x43:
-        case 0x44:
-        case 0x45:
-        case 0x46:
-        case 0x47:
-        case 0x48:
-        case 0x49:
-        case 0x4A:
-        case 0x4B:
-        case 0x4C:
-        case 0x4D:
-        case 0x4E:
-        case 0x4F:
-        case 0x50:
-        case 0x51:
-        case 0x52:
-        case 0x53:
-        case 0x54:
-        case 0x55:
-        case 0x56:
-        case 0x57:
-        case 0x58:
-        case 0x59:
-        case 0x5A:
-        case 0x5B:
-        case 0x5D:
-        case 0x5E:
-        case 0x5F:
-        case 0x60:
-        case 0x61:
-        case 0x62:
-        case 0x63:
-        case 0x64:
-        case 0x65:
-        case 0x66:
-        case 0x67:
-        case 0x68:
-        case 0x69:
-        case 0x6A:
-        case 0x6B:
-        case 0x6C:
-        case 0x6D:
-        case 0x6E:
-        case 0x6F:
-        case 0x70:
-        case 0x71:
-        case 0x72:
-        case 0x73:
-        case 0x74:
-        case 0x75:
-        case 0x76:
-        case 0x77:
-        case 0x78:
-        case 0x79:
-        case 0x7A:
-        case 0x7B:
-        case 0x7C:
-        case 0x7D:
-        case 0x7E:
-        case 0x7F: {
-          add(current);
-          break;
-        }
-
-        case 0xC2:
-        case 0xC3:
-        case 0xC4:
-        case 0xC5:
-        case 0xC6:
-        case 0xC7:
-        case 0xC8:
-        case 0xC9:
-        case 0xCA:
-        case 0xCB:
-        case 0xCC:
-        case 0xCD:
-        case 0xCE:
-        case 0xCF:
-        case 0xD0:
-        case 0xD1:
-        case 0xD2:
-        case 0xD3:
-        case 0xD4:
-        case 0xD5:
-        case 0xD6:
-        case 0xD7:
-        case 0xD8:
-        case 0xD9:
-        case 0xDA:
-        case 0xDB:
-        case 0xDC:
-        case 0xDD:
-        case 0xDE:
-        case 0xDF: {
-          if(JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF}))) {
-            return token_type::parse_error;
-          }
-          break;
-        }
-
-        case 0xE0: {
-          if(JSON_UNLIKELY(not(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) {
-            return token_type::parse_error;
-          }
-          break;
-        }
-
-        case 0xE1:
-        case 0xE2:
-        case 0xE3:
-        case 0xE4:
-        case 0xE5:
-        case 0xE6:
-        case 0xE7:
-        case 0xE8:
-        case 0xE9:
-        case 0xEA:
-        case 0xEB:
-        case 0xEC:
-        case 0xEE:
-        case 0xEF: {
-          if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) {
-            return token_type::parse_error;
-          }
-          break;
-        }
-
-        case 0xED: {
-          if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) {
-            return token_type::parse_error;
-          }
-          break;
-        }
-
-        case 0xF0: {
-          if(JSON_UNLIKELY(not(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
-            return token_type::parse_error;
-          }
-          break;
-        }
-
-        case 0xF1:
-        case 0xF2:
-        case 0xF3: {
-          if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
-            return token_type::parse_error;
-          }
-          break;
-        }
-
-        case 0xF4: {
-          if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) {
-            return token_type::parse_error;
-          }
-          break;
-        }
-
-        default: {
-          error_message = "invalid string: ill-formed UTF-8 byte";
-          return token_type::parse_error;
-        }
-      }
+    template<typename BasicJsonType>
+    void to_json(BasicJsonType &j, const std::vector<bool> &e) {
+      external_constructor<value_t::array>::construct(j, e);
     }
-  }
 
-  static void strtof(float &f, const char *str, char **endptr) noexcept {
-    f = std::strtof(str, endptr);
-  }
-
-  static void strtof(double &f, const char *str, char **endptr) noexcept {
-    f = std::strtod(str, endptr);
-  }
-
-  static void strtof(long double &f, const char *str, char **endptr) noexcept {
-    f = std::strtold(str, endptr);
-  }
-
-  token_type scan_number() {
-    reset();
-
-    token_type number_type = token_type::value_unsigned;
+    template<typename BasicJsonType, typename CompatibleArrayType,
+        enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
+                    std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
+            int> = 0>
+    void to_json(BasicJsonType &j, const CompatibleArrayType &arr) {
+      external_constructor<value_t::array>::construct(j, arr);
+    }
 
-    switch(current) {
-      case '-': {
-        add(current);
-        goto scan_number_minus;
-      }
+    template<typename BasicJsonType, typename T,
+        enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+    void to_json(BasicJsonType &j, std::valarray<T> arr) {
+      external_constructor<value_t::array>::construct(j, std::move(arr));
+    }
 
-      case '0': {
-        add(current);
-        goto scan_number_zero;
-      }
-
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9': {
-        add(current);
-        goto scan_number_any1;
-      }
+    template<typename BasicJsonType>
+    void to_json(BasicJsonType &j, typename BasicJsonType::array_t &&arr) {
+      external_constructor<value_t::array>::construct(j, std::move(arr));
+    }
 
-      default: {
-        assert(false);
-      }
+    template<typename BasicJsonType, typename CompatibleObjectType,
+        enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
+    void to_json(BasicJsonType &j, const CompatibleObjectType &obj) {
+      external_constructor<value_t::object>::construct(j, obj);
     }
 
-    scan_number_minus:
+    template<typename BasicJsonType>
+    void to_json(BasicJsonType &j, typename BasicJsonType::object_t &&obj) {
+      external_constructor<value_t::object>::construct(j, std::move(obj));
+    }
 
-    number_type = token_type::value_integer;
-    switch(get()) {
-      case '0': {
-        add(current);
-        goto scan_number_zero;
-      }
-
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9': {
-        add(current);
-        goto scan_number_any1;
-      }
+    template<typename BasicJsonType, typename T, std::size_t N,
+        enable_if_t<not std::is_constructible<typename BasicJsonType::string_t, T (&)[N]>::value, int> = 0>
+    void to_json(BasicJsonType &j, T (&arr)[N]) {
+      external_constructor<value_t::array>::construct(j, arr);
+    }
 
-      default: {
-        error_message = "invalid number; expected digit after '-'";
-        return token_type::parse_error;
-      }
+    template<typename BasicJsonType, typename... Args>
+    void to_json(BasicJsonType &j, const std::pair<Args...> &p) {
+      j = {p.first, p.second};
     }
 
-    scan_number_zero:
+    template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+    void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence<Idx...>) {
+      j = {std::get<Idx>(t)...};
+    }
 
-    switch(get()) {
-      case '.': {
-        add(decimal_point_char);
-        goto scan_number_decimal1;
-      }
+    template<typename BasicJsonType, typename... Args>
+    void to_json(BasicJsonType &j, const std::tuple<Args...> &t) {
+      to_json_tuple_impl(j, t, index_sequence_for<Args...>{});
+    }
 
-      case 'e':
-      case 'E': {
-        add(current);
-        goto scan_number_exponent;
+    struct to_json_fn {
+    private:
+      template<typename BasicJsonType, typename T>
+      auto call(BasicJsonType &j, T &&val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
+      -> decltype(to_json(j, std::forward<T>(val)), void()) {
+        return to_json(j, std::forward<T>(val));
       }
 
-      default:
-        goto scan_number_done;
-    }
-
-    scan_number_any1:
+      template<typename BasicJsonType, typename T>
+      void call(BasicJsonType &, T &&, priority_tag<0>) const noexcept {
+        static_assert(sizeof(BasicJsonType) == 0,
+                      "could not find to_json() method in T's namespace");
 
-    switch(get()) {
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9': {
-        add(current);
-        goto scan_number_any1;
-      }
+#ifdef _MSC_VER
 
-      case '.': {
-        add(decimal_point_char);
-        goto scan_number_decimal1;
+        using decayed = uncvref_t<T>;
+        static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
+                      "forcing MSVC stacktrace to show which T we're talking about.");
+#endif
       }
 
-      case 'e':
-      case 'E': {
-        add(current);
-        goto scan_number_exponent;
+    public:
+      template<typename BasicJsonType, typename T>
+      void operator()(BasicJsonType &j, T &&val) const
+      noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1>{}))) {
+        return call(j, std::forward<T>(val), priority_tag<1>{});
       }
+    };
+  }
 
-      default:
-        goto scan_number_done;
-    }
+  namespace {
+    constexpr const auto &to_json = detail::static_const<detail::to_json_fn>::value;
+  }
+}
 
-    scan_number_decimal1:
+#include <cstring>
+#include <ios>
+#include <istream>
 
-    number_type = token_type::value_float;
-    switch(get()) {
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9': {
-        add(current);
-        goto scan_number_decimal2;
-      }
+namespace nlohmann {
+  namespace detail {
+    struct input_adapter_protocol {
+      virtual std::char_traits<char>::int_type get_character() = 0;
 
-      default: {
-        error_message = "invalid number; expected digit after '.'";
-        return token_type::parse_error;
-      }
-    }
+      virtual void unget_character() = 0;
 
-    scan_number_decimal2:
+      virtual ~input_adapter_protocol() = default;
+    };
 
-    switch(get()) {
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9': {
-        add(current);
-        goto scan_number_decimal2;
-      }
+    using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
 
-      case 'e':
-      case 'E': {
-        add(current);
-        goto scan_number_exponent;
+    class input_stream_adapter : public input_adapter_protocol {
+    public:
+      ~input_stream_adapter() override {
+        is.clear();
       }
 
-      default:
-        goto scan_number_done;
-    }
-
-    scan_number_exponent:
-
-    number_type = token_type::value_float;
-    switch(get()) {
-      case '+':
-      case '-': {
-        add(current);
-        goto scan_number_sign;
-      }
-
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9': {
-        add(current);
-        goto scan_number_any2;
+      explicit input_stream_adapter(std::istream &i)
+          : is(i), sb(*i.rdbuf()) {
+        std::char_traits<char>::int_type c;
+        if((c = get_character()) == 0xEF) {
+          if((c = get_character()) == 0xBB) {
+            if((c = get_character()) == 0xBF) {
+              return;
+            } else if(c != std::char_traits<char>::eof()) {
+              is.unget();
+            }
+            is.putback('\xBB');
+          } else if(c != std::char_traits<char>::eof()) {
+            is.unget();
+          }
+          is.putback('\xEF');
+        } else if(c != std::char_traits<char>::eof()) {
+          is.unget();
+        }
       }
 
-      default: {
-        error_message =
-            "invalid number; expected '+', '-', or digit after exponent";
-        return token_type::parse_error;
-      }
-    }
+      input_stream_adapter(const input_stream_adapter &) = delete;
 
-    scan_number_sign:
+      input_stream_adapter &operator=(input_stream_adapter &) = delete;
 
-    switch(get()) {
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9': {
-        add(current);
-        goto scan_number_any2;
+      std::char_traits<char>::int_type get_character() override {
+        return sb.sbumpc();
       }
 
-      default: {
-        error_message = "invalid number; expected digit after exponent sign";
-        return token_type::parse_error;
+      void unget_character() override {
+        sb.sungetc();
       }
-    }
 
-    scan_number_any2:
+    private:
+      std::istream &is;
+      std::streambuf &sb;
+    };
 
-    switch(get()) {
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9': {
-        add(current);
-        goto scan_number_any2;
+    class input_buffer_adapter : public input_adapter_protocol {
+    public:
+      input_buffer_adapter(const char *b, const std::size_t l)
+          : cursor(b), limit(b+l), start(b) {
+        if(l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF') {
+          cursor += 3;
+        }
       }
 
-      default:
-        goto scan_number_done;
-    }
-
-    scan_number_done:
-
-    unget();
+      input_buffer_adapter(const input_buffer_adapter &) = delete;
 
-    char *endptr = nullptr;
-    errno = 0;
+      input_buffer_adapter &operator=(input_buffer_adapter &) = delete;
 
-    if(number_type == token_type::value_unsigned) {
-      const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
-
-      assert(endptr == token_buffer.data()+token_buffer.size());
-
-      if(errno == 0) {
-        value_unsigned = static_cast<number_unsigned_t>(x);
-        if(value_unsigned == x) {
-          return token_type::value_unsigned;
+      std::char_traits<char>::int_type get_character() noexcept override {
+        if(JSON_LIKELY(cursor < limit)) {
+          return std::char_traits<char>::to_int_type(*(cursor++));
         }
-      }
-    } else if(number_type == token_type::value_integer) {
-      const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
 
-      assert(endptr == token_buffer.data()+token_buffer.size());
+        return std::char_traits<char>::eof();
+      }
 
-      if(errno == 0) {
-        value_integer = static_cast<number_integer_t>(x);
-        if(value_integer == x) {
-          return token_type::value_integer;
+      void unget_character() noexcept override {
+        if(JSON_LIKELY(cursor > start)) {
+          --cursor;
         }
       }
-    }
 
-    strtof(value_float, token_buffer.data(), &endptr);
+    private:
+      const char *cursor;
 
-    assert(endptr == token_buffer.data()+token_buffer.size());
+      const char *limit;
 
-    return token_type::value_float;
-  }
+      const char *start;
+    };
 
-  token_type scan_literal(const char *literal_text, const std::size_t length,
-                          token_type return_type) {
-    assert(current == literal_text[0]);
-    for(std::size_t i = 1; i < length; ++i) {
-      if(JSON_UNLIKELY(get() != literal_text[i])) {
-        error_message = "invalid literal";
-        return token_type::parse_error;
+    class input_adapter {
+    public:
+      input_adapter(std::istream &i)
+          : ia(std::make_shared<input_stream_adapter>(i)) {}
+
+      input_adapter(std::istream &&i)
+          : ia(std::make_shared<input_stream_adapter>(i)) {}
+
+      template<typename CharT,
+          typename std::enable_if<
+              std::is_pointer<CharT>::value and
+              std::is_integral<typename std::remove_pointer<CharT>::type>::value and
+              sizeof(typename std::remove_pointer<CharT>::type) == 1,
+              int>::type = 0>
+      input_adapter(CharT b, std::size_t l)
+          : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char *>(b), l)) {}
+
+      template<typename CharT,
+          typename std::enable_if<
+              std::is_pointer<CharT>::value and
+              std::is_integral<typename std::remove_pointer<CharT>::type>::value and
+              sizeof(typename std::remove_pointer<CharT>::type) == 1,
+              int>::type = 0>
+      input_adapter(CharT b)
+          : input_adapter(reinterpret_cast<const char *>(b),
+                          std::strlen(reinterpret_cast<const char *>(b))) {}
+
+      template<class IteratorType,
+          typename std::enable_if<
+              std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
+              int>::type = 0>
+      input_adapter(IteratorType first, IteratorType last) {
+        assert(std::accumulate(
+            first, last, std::pair<bool, int>(true, 0),
+            [&first](std::pair<bool, int> res, decltype(*first) val) {
+              res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
+              return res;
+            }).first);
+
+        static_assert(
+            sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
+            "each element in the iterator range must have the size of 1 byte");
+
+        const auto len = static_cast<size_t>(std::distance(first, last));
+        if(JSON_LIKELY(len > 0)) {
+          ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char *>(&(*first)), len);
+        } else {
+          ia = std::make_shared<input_buffer_adapter>(nullptr, len);
+        }
       }
-    }
-    return return_type;
-  }
-
-  void reset() noexcept {
-    token_buffer.clear();
-    token_string.clear();
-    token_string.push_back(std::char_traits<char>::to_char_type(current));
-  }
-
-  std::char_traits<char>::int_type get() {
-    ++chars_read;
-    current = ia->get_character();
-    if(JSON_LIKELY(current != std::char_traits<char>::eof())) {
-      token_string.push_back(std::char_traits<char>::to_char_type(current));
-    }
-    return current;
-  }
 
-  void unget() {
-    --chars_read;
-    if(JSON_LIKELY(current != std::char_traits<char>::eof())) {
-      ia->unget_character();
-      assert(token_string.size() != 0);
-      token_string.pop_back();
-    }
-  }
-
-  void add(int c) {
-    token_buffer.push_back(std::char_traits<char>::to_char_type(c));
-  }
-
-public:
-  constexpr number_integer_t get_number_integer() const noexcept {
-    return value_integer;
-  }
-
-  constexpr number_unsigned_t get_number_unsigned() const noexcept {
-    return value_unsigned;
-  }
+      template<class T, std::size_t N>
+      input_adapter(T (&array)[N])
+          : input_adapter(std::begin(array), std::end(array)) {}
 
-  constexpr number_float_t get_number_float() const noexcept {
-    return value_float;
-  }
-
-  string_t &&move_string() {
-    return std::move(token_buffer);
-  }
-
-  constexpr std::size_t get_position() const noexcept {
-    return chars_read;
-  }
+      template<class ContiguousContainer, typename
+      std::enable_if<not std::is_pointer<ContiguousContainer>::value and
+                     std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(
+                         std::declval<ContiguousContainer const>()))>::iterator_category>::value,
+          int>::type = 0>
+      input_adapter(const ContiguousContainer &c)
+          : input_adapter(std::begin(c), std::end(c)) {}
 
-  std::string get_token_string() const {
-    std::string result;
-    for(const auto c : token_string) {
-      if('\x00' <= c and c <= '\x1F') {
-        std::stringstream ss;
-        ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
-           << std::hex << static_cast<int>(c) << ">";
-        result += ss.str();
-      } else {
-        result.push_back(c);
+      operator input_adapter_t() {
+        return ia;
       }
-    }
 
-    return result;
-  }
-
-  constexpr const char *get_error_message() const noexcept {
-    return error_message;
-  }
-
-  token_type scan() {
-    do {
-      get();
-    } while(current == ' ' or current == '\t' or current == '\n' or current == '\r');
-
-    switch(current) {
-      case '[':
-        return token_type::begin_array;
-      case ']':
-        return token_type::end_array;
-      case '{':
-        return token_type::begin_object;
-      case '}':
-        return token_type::end_object;
-      case ':':
-        return token_type::name_separator;
-      case ',':
-        return token_type::value_separator;
-
-      case 't':
-        return scan_literal("true", 4, token_type::literal_true);
-      case 'f':
-        return scan_literal("false", 5, token_type::literal_false);
-      case 'n':
-        return scan_literal("null", 4, token_type::literal_null);
-
-      case '\"':
-        return scan_string();
-
-      case '-':
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9':
-        return scan_number();
-
-      case '\0':
-      case std::char_traits<char>::eof():
-        return token_type::end_of_input;
-
-      default:
-        error_message = "invalid literal";
-        return token_type::parse_error;
-    }
+    private:
+      input_adapter_t ia = nullptr;
+    };
   }
-
-private:
-  detail::input_adapter_t ia = nullptr;
-
-  std::char_traits<char>::int_type current = std::char_traits<char>::eof();
-
-  std::size_t chars_read = 0;
-
-  std::vector<char> token_string{};
-
-  string_t token_buffer{};
-
-  const char *error_message = "";
-
-  number_integer_t value_integer = 0;
-  number_unsigned_t value_unsigned = 0;
-  number_float_t value_float = 0;
-
-  const char decimal_point_char = '.';
-};
-}
 }
 
-#include <cmath>
+#include <clocale>
+#include <cstdlib>
+#include <iomanip>
+#include <sstream>
 
 namespace nlohmann {
-namespace detail {
-template<typename BasicJsonType>
-class parser {
-  using number_integer_t = typename BasicJsonType::number_integer_t;
-  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
-  using number_float_t = typename BasicJsonType::number_float_t;
-  using string_t = typename BasicJsonType::string_t;
-  using lexer_t = lexer<BasicJsonType>;
-  using token_type = typename lexer_t::token_type;
-
-public:
-  enum class parse_event_t : uint8_t {
-    object_start,
-
-    object_end,
-
-    array_start,
-
-    array_end,
-
-    key,
-
-    value
-  };
-
-  using parser_callback_t =
-  std::function<bool(int depth, parse_event_t event, BasicJsonType &parsed)>;
-
-  explicit parser(detail::input_adapter_t adapter,
-                  const parser_callback_t cb = nullptr,
-                  const bool allow_exceptions_ = true)
-      : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_) {}
-
-  void parse(const bool strict, BasicJsonType &result) {
-    get_token();
-
-    parse_internal(true, result);
-    result.assert_invariant();
-
-    if(strict) {
-      get_token();
-      expect(token_type::end_of_input);
-    }
-
-    if(errored) {
-      result = value_t::discarded;
-      return;
-    }
-
-    if(result.is_discarded()) {
-      result = nullptr;
-    }
-  }
-
-  bool accept(const bool strict = true) {
-    get_token();
-
-    if(not accept_internal()) {
-      return false;
-    }
-
-    return not strict or (get_token() == token_type::end_of_input);
-  }
-
-private:
-  void parse_internal(bool keep, BasicJsonType &result) {
-    assert(not errored);
-
-    if(not result.is_discarded()) {
-      result.m_value.destroy(result.m_type);
-      result.m_type = value_t::discarded;
-    }
-
-    switch(last_token) {
-      case token_type::begin_object: {
-        if(keep) {
-          if(callback) {
-            keep = callback(depth++, parse_event_t::object_start, result);
-          }
-
-          if(not callback or keep) {
-            result.m_type = value_t::object;
-            result.m_value = value_t::object;
-          }
-        }
-
-        get_token();
+  namespace detail {
+    template<typename BasicJsonType>
+    class lexer {
+      using number_integer_t = typename BasicJsonType::number_integer_t;
+      using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+      using number_float_t = typename BasicJsonType::number_float_t;
+      using string_t = typename BasicJsonType::string_t;
+
+    public:
+      enum class token_type {
+        uninitialized,
+        literal_true,
+        literal_false,
+        literal_null,
+        value_string,
+        value_unsigned,
+        value_integer,
+        value_float,
+        begin_array,
+        begin_object,
+        end_array,
+        end_object,
+        name_separator,
+        value_separator,
+        parse_error,
+        end_of_input,
+        literal_or_value
+      };
 
-        if(last_token == token_type::end_object) {
-          if(keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
-            result.m_value.destroy(result.m_type);
-            result.m_type = value_t::discarded;
-          }
-          break;
+      static const char *token_type_name(const token_type t) noexcept {
+        switch(t) {
+          case token_type::uninitialized:
+            return "<uninitialized>";
+          case token_type::literal_true:
+            return "true literal";
+          case token_type::literal_false:
+            return "false literal";
+          case token_type::literal_null:
+            return "null literal";
+          case token_type::value_string:
+            return "string literal";
+          case lexer::token_type::value_unsigned:
+          case lexer::token_type::value_integer:
+          case lexer::token_type::value_float:
+            return "number literal";
+          case token_type::begin_array:
+            return "'['";
+          case token_type::begin_object:
+            return "'{'";
+          case token_type::end_array:
+            return "']'";
+          case token_type::end_object:
+            return "'}'";
+          case token_type::name_separator:
+            return "':'";
+          case token_type::value_separator:
+            return "','";
+          case token_type::parse_error:
+            return "<parse error>";
+          case token_type::end_of_input:
+            return "end of input";
+          case token_type::literal_or_value:
+            return "'[', '{', or a literal";
+          default:
+            return "unknown token";
         }
+      }
 
-        string_t key;
-        BasicJsonType value;
-        while(true) {
-          if(not expect(token_type::value_string)) {
-            return;
-          }
-          key = m_lexer.move_string();
-
-          bool keep_tag = false;
-          if(keep) {
-            if(callback) {
-              BasicJsonType k(key);
-              keep_tag = callback(depth, parse_event_t::key, k);
-            } else {
-              keep_tag = true;
-            }
-          }
-
-          get_token();
-          if(not expect(token_type::name_separator)) {
-            return;
-          }
-
-          get_token();
-          value.m_value.destroy(value.m_type);
-          value.m_type = value_t::discarded;
-          parse_internal(keep, value);
-
-          if(JSON_UNLIKELY(errored)) {
-            return;
-          }
-
-          if(keep and keep_tag and not value.is_discarded()) {
-            result.m_value.object->emplace(std::move(key), std::move(value));
-          }
+      explicit lexer(detail::input_adapter_t adapter)
+          : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
 
-          get_token();
-          if(last_token == token_type::value_separator) {
-            get_token();
-            continue;
-          }
+      lexer(const lexer &) = delete;
 
-          if(not expect(token_type::end_object)) {
-            return;
-          }
-          break;
-        }
+      lexer &operator=(lexer &) = delete;
 
-        if(keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
-          result.m_value.destroy(result.m_type);
-          result.m_type = value_t::discarded;
-        }
-        break;
+    private:
+      static char get_decimal_point() noexcept {
+        const auto loc = localeconv();
+        assert(loc != nullptr);
+        return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
       }
 
-      case token_type::begin_array: {
-        if(keep) {
-          if(callback) {
-            keep = callback(depth++, parse_event_t::array_start, result);
-          }
-
-          if(not callback or keep) {
-            result.m_type = value_t::array;
-            result.m_value = value_t::array;
-          }
-        }
+      int get_codepoint() {
+        assert(current == 'u');
+        int codepoint = 0;
 
-        get_token();
+        const auto factors = {12, 8, 4, 0};
+        for(const auto factor : factors) {
+          get();
 
-        if(last_token == token_type::end_array) {
-          if(callback and not callback(--depth, parse_event_t::array_end, result)) {
-            result.m_value.destroy(result.m_type);
-            result.m_type = value_t::discarded;
+          if(current >= '0' and current <= '9') {
+            codepoint += ((current-0x30) << factor);
+          } else if(current >= 'A' and current <= 'F') {
+            codepoint += ((current-0x37) << factor);
+          } else if(current >= 'a' and current <= 'f') {
+            codepoint += ((current-0x57) << factor);
+          } else {
+            return -1;
           }
-          break;
         }
 
-        BasicJsonType value;
-        while(true) {
-          value.m_value.destroy(value.m_type);
-          value.m_type = value_t::discarded;
-          parse_internal(keep, value);
-
-          if(JSON_UNLIKELY(errored)) {
-            return;
-          }
-
-          if(keep and not value.is_discarded()) {
-            result.m_value.array->push_back(std::move(value));
-          }
+        assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
+        return codepoint;
+      }
 
-          get_token();
-          if(last_token == token_type::value_separator) {
-            get_token();
-            continue;
-          }
+      bool next_byte_in_range(std::initializer_list<int> ranges) {
+        assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
+        add(current);
 
-          if(not expect(token_type::end_array)) {
-            return;
+        for(auto range = ranges.begin(); range != ranges.end(); ++range) {
+          get();
+          if(JSON_LIKELY(*range <= current and current <= *(++range))) {
+            add(current);
+          } else {
+            error_message = "invalid string: ill-formed UTF-8 byte";
+            return false;
           }
-          break;
-        }
-
-        if(keep and callback and not callback(--depth, parse_event_t::array_end, result)) {
-          result.m_value.destroy(result.m_type);
-          result.m_type = value_t::discarded;
         }
-        break;
-      }
-
-      case token_type::literal_null: {
-        result.m_type = value_t::null;
-        break;
-      }
-
-      case token_type::value_string: {
-        result.m_type = value_t::string;
-        result.m_value = m_lexer.move_string();
-        break;
-      }
-
-      case token_type::literal_true: {
-        result.m_type = value_t::boolean;
-        result.m_value = true;
-        break;
-      }
-
-      case token_type::literal_false: {
-        result.m_type = value_t::boolean;
-        result.m_value = false;
-        break;
-      }
-
-      case token_type::value_unsigned: {
-        result.m_type = value_t::number_unsigned;
-        result.m_value = m_lexer.get_number_unsigned();
-        break;
-      }
 
-      case token_type::value_integer: {
-        result.m_type = value_t::number_integer;
-        result.m_value = m_lexer.get_number_integer();
-        break;
+        return true;
       }
 
-      case token_type::value_float: {
-        result.m_type = value_t::number_float;
-        result.m_value = m_lexer.get_number_float();
+      token_type scan_string() {
+        reset();
 
-        if(JSON_UNLIKELY(not std::isfinite(result.m_value.number_float))) {
-          if(allow_exceptions) {
-            JSON_THROW(out_of_range::create(406, "number overflow parsing '"+
-                                                 m_lexer.get_token_string()+"'"));
-          }
-          expect(token_type::uninitialized);
-        }
-        break;
-      }
+        assert(current == '\"');
 
-      case token_type::parse_error: {
-        if(not expect(token_type::uninitialized)) {
-          return;
-        }
-        break;
-      }
+        while(true) {
+          switch(get()) {
+            case std::char_traits<char>::eof(): {
+              error_message = "invalid string: missing closing quote";
+              return token_type::parse_error;
+            }
 
-      default: {
-        if(not expect(token_type::literal_or_value)) {
-          return;
-        }
-        break;
-      }
-    }
+            case '\"': {
+              return token_type::value_string;
+            }
 
-    if(keep and callback and not callback(depth, parse_event_t::value, result)) {
-      result.m_value.destroy(result.m_type);
-      result.m_type = value_t::discarded;
-    }
-  }
+            case '\\': {
+              switch(get()) {
+                case '\"':
+                  add('\"');
+                  break;
 
-  bool accept_internal() {
-    switch(last_token) {
-      case token_type::begin_object: {
-        get_token();
+                case '\\':
+                  add('\\');
+                  break;
 
-        if(last_token == token_type::end_object) {
-          return true;
-        }
+                case '/':
+                  add('/');
+                  break;
 
-        while(true) {
-          if(last_token != token_type::value_string) {
-            return false;
-          }
+                case 'b':
+                  add('\b');
+                  break;
 
-          get_token();
-          if(last_token != token_type::name_separator) {
-            return false;
-          }
+                case 'f':
+                  add('\f');
+                  break;
 
-          get_token();
-          if(not accept_internal()) {
-            return false;
-          }
+                case 'n':
+                  add('\n');
+                  break;
 
-          get_token();
-          if(last_token == token_type::value_separator) {
-            get_token();
-            continue;
-          }
+                case 'r':
+                  add('\r');
+                  break;
 
-          return (last_token == token_type::end_object);
-        }
-      }
+                case 't':
+                  add('\t');
+                  break;
 
-      case token_type::begin_array: {
-        get_token();
+                case 'u': {
+                  const int codepoint1 = get_codepoint();
+                  int codepoint = codepoint1;
 
-        if(last_token == token_type::end_array) {
-          return true;
-        }
+                  if(JSON_UNLIKELY(codepoint1 == -1)) {
+                    error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+                    return token_type::parse_error;
+                  }
 
-        while(true) {
-          if(not accept_internal()) {
-            return false;
-          }
+                  if(0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) {
+                    if(JSON_LIKELY(get() == '\\' and get() == 'u')) {
+                      const int codepoint2 = get_codepoint();
 
-          get_token();
-          if(last_token == token_type::value_separator) {
-            get_token();
-            continue;
-          }
+                      if(JSON_UNLIKELY(codepoint2 == -1)) {
+                        error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+                        return token_type::parse_error;
+                      }
 
-          return (last_token == token_type::end_array);
-        }
-      }
+                      if(JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) {
+                        codepoint =
 
-      case token_type::value_float: {
-        return std::isfinite(m_lexer.get_number_float());
-      }
+                            (codepoint1 << 10)
 
-      case token_type::literal_false:
-      case token_type::literal_null:
-      case token_type::literal_true:
-      case token_type::value_integer:
-      case token_type::value_string:
-      case token_type::value_unsigned:
-        return true;
+                            +codepoint2
 
-      default:
-        return false;
-    }
-  }
+                            -0x35FDC00;
+                      } else {
+                        error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
+                        return token_type::parse_error;
+                      }
+                    } else {
+                      error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
+                      return token_type::parse_error;
+                    }
+                  } else {
+                    if(JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) {
+                      error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
+                      return token_type::parse_error;
+                    }
+                  }
 
-  token_type get_token() {
-    return (last_token = m_lexer.scan());
-  }
+                  assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
+
+                  if(codepoint < 0x80) {
+                    add(codepoint);
+                  } else if(codepoint <= 0x7FF) {
+                    add(0xC0 | (codepoint >> 6));
+                    add(0x80 | (codepoint & 0x3F));
+                  } else if(codepoint <= 0xFFFF) {
+                    add(0xE0 | (codepoint >> 12));
+                    add(0x80 | ((codepoint >> 6) & 0x3F));
+                    add(0x80 | (codepoint & 0x3F));
+                  } else {
+                    add(0xF0 | (codepoint >> 18));
+                    add(0x80 | ((codepoint >> 12) & 0x3F));
+                    add(0x80 | ((codepoint >> 6) & 0x3F));
+                    add(0x80 | (codepoint & 0x3F));
+                  }
 
-  bool expect(token_type t) {
-    if(JSON_UNLIKELY(t != last_token)) {
-      errored = true;
-      expected = t;
-      if(allow_exceptions) {
-        throw_exception();
-      } else {
-        return false;
-      }
-    }
+                  break;
+                }
 
-    return true;
-  }
+                default:
+                  error_message = "invalid string: forbidden character after backslash";
+                  return token_type::parse_error;
+              }
 
-  [[noreturn]] void throw_exception() const {
-    std::string error_msg = "syntax error - ";
-    if(last_token == token_type::parse_error) {
-      error_msg += std::string(m_lexer.get_error_message())+"; last read: '"+
-                   m_lexer.get_token_string()+"'";
-    } else {
-      error_msg += "unexpected "+std::string(lexer_t::token_type_name(last_token));
-    }
+              break;
+            }
 
-    if(expected != token_type::uninitialized) {
-      error_msg += "; expected "+std::string(lexer_t::token_type_name(expected));
-    }
+            case 0x00:
+            case 0x01:
+            case 0x02:
+            case 0x03:
+            case 0x04:
+            case 0x05:
+            case 0x06:
+            case 0x07:
+            case 0x08:
+            case 0x09:
+            case 0x0A:
+            case 0x0B:
+            case 0x0C:
+            case 0x0D:
+            case 0x0E:
+            case 0x0F:
+            case 0x10:
+            case 0x11:
+            case 0x12:
+            case 0x13:
+            case 0x14:
+            case 0x15:
+            case 0x16:
+            case 0x17:
+            case 0x18:
+            case 0x19:
+            case 0x1A:
+            case 0x1B:
+            case 0x1C:
+            case 0x1D:
+            case 0x1E:
+            case 0x1F: {
+              error_message = "invalid string: control character must be escaped";
+              return token_type::parse_error;
+            }
 
-    JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
-  }
+            case 0x20:
+            case 0x21:
+            case 0x23:
+            case 0x24:
+            case 0x25:
+            case 0x26:
+            case 0x27:
+            case 0x28:
+            case 0x29:
+            case 0x2A:
+            case 0x2B:
+            case 0x2C:
+            case 0x2D:
+            case 0x2E:
+            case 0x2F:
+            case 0x30:
+            case 0x31:
+            case 0x32:
+            case 0x33:
+            case 0x34:
+            case 0x35:
+            case 0x36:
+            case 0x37:
+            case 0x38:
+            case 0x39:
+            case 0x3A:
+            case 0x3B:
+            case 0x3C:
+            case 0x3D:
+            case 0x3E:
+            case 0x3F:
+            case 0x40:
+            case 0x41:
+            case 0x42:
+            case 0x43:
+            case 0x44:
+            case 0x45:
+            case 0x46:
+            case 0x47:
+            case 0x48:
+            case 0x49:
+            case 0x4A:
+            case 0x4B:
+            case 0x4C:
+            case 0x4D:
+            case 0x4E:
+            case 0x4F:
+            case 0x50:
+            case 0x51:
+            case 0x52:
+            case 0x53:
+            case 0x54:
+            case 0x55:
+            case 0x56:
+            case 0x57:
+            case 0x58:
+            case 0x59:
+            case 0x5A:
+            case 0x5B:
+            case 0x5D:
+            case 0x5E:
+            case 0x5F:
+            case 0x60:
+            case 0x61:
+            case 0x62:
+            case 0x63:
+            case 0x64:
+            case 0x65:
+            case 0x66:
+            case 0x67:
+            case 0x68:
+            case 0x69:
+            case 0x6A:
+            case 0x6B:
+            case 0x6C:
+            case 0x6D:
+            case 0x6E:
+            case 0x6F:
+            case 0x70:
+            case 0x71:
+            case 0x72:
+            case 0x73:
+            case 0x74:
+            case 0x75:
+            case 0x76:
+            case 0x77:
+            case 0x78:
+            case 0x79:
+            case 0x7A:
+            case 0x7B:
+            case 0x7C:
+            case 0x7D:
+            case 0x7E:
+            case 0x7F: {
+              add(current);
+              break;
+            }
 
-private:
-  int depth = 0;
+            case 0xC2:
+            case 0xC3:
+            case 0xC4:
+            case 0xC5:
+            case 0xC6:
+            case 0xC7:
+            case 0xC8:
+            case 0xC9:
+            case 0xCA:
+            case 0xCB:
+            case 0xCC:
+            case 0xCD:
+            case 0xCE:
+            case 0xCF:
+            case 0xD0:
+            case 0xD1:
+            case 0xD2:
+            case 0xD3:
+            case 0xD4:
+            case 0xD5:
+            case 0xD6:
+            case 0xD7:
+            case 0xD8:
+            case 0xD9:
+            case 0xDA:
+            case 0xDB:
+            case 0xDC:
+            case 0xDD:
+            case 0xDE:
+            case 0xDF: {
+              if(JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF}))) {
+                return token_type::parse_error;
+              }
+              break;
+            }
 
-  const parser_callback_t callback = nullptr;
+            case 0xE0: {
+              if(JSON_UNLIKELY(not(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) {
+                return token_type::parse_error;
+              }
+              break;
+            }
 
-  token_type last_token = token_type::uninitialized;
+            case 0xE1:
+            case 0xE2:
+            case 0xE3:
+            case 0xE4:
+            case 0xE5:
+            case 0xE6:
+            case 0xE7:
+            case 0xE8:
+            case 0xE9:
+            case 0xEA:
+            case 0xEB:
+            case 0xEC:
+            case 0xEE:
+            case 0xEF: {
+              if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) {
+                return token_type::parse_error;
+              }
+              break;
+            }
 
-  lexer_t m_lexer;
+            case 0xED: {
+              if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) {
+                return token_type::parse_error;
+              }
+              break;
+            }
 
-  bool errored = false;
+            case 0xF0: {
+              if(JSON_UNLIKELY(not(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
+                return token_type::parse_error;
+              }
+              break;
+            }
 
-  token_type expected = token_type::uninitialized;
+            case 0xF1:
+            case 0xF2:
+            case 0xF3: {
+              if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
+                return token_type::parse_error;
+              }
+              break;
+            }
 
-  const bool allow_exceptions = true;
-};
-}
-}
+            case 0xF4: {
+              if(JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) {
+                return token_type::parse_error;
+              }
+              break;
+            }
 
-namespace nlohmann {
-namespace detail {
-class primitive_iterator_t {
-private:
-  using difference_type = std::ptrdiff_t;
-  static constexpr difference_type begin_value = 0;
-  static constexpr difference_type end_value = begin_value+1;
-
-  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
-
-public:
-  constexpr difference_type get_value() const noexcept {
-    return m_it;
-  }
+            default: {
+              error_message = "invalid string: ill-formed UTF-8 byte";
+              return token_type::parse_error;
+            }
+          }
+        }
+      }
 
-  void set_begin() noexcept {
-    m_it = begin_value;
-  }
+      static void strtof(float &f, const char *str, char **endptr) noexcept {
+        f = std::strtof(str, endptr);
+      }
 
-  void set_end() noexcept {
-    m_it = end_value;
-  }
+      static void strtof(double &f, const char *str, char **endptr) noexcept {
+        f = std::strtod(str, endptr);
+      }
 
-  constexpr bool is_begin() const noexcept {
-    return m_it == begin_value;
-  }
+      static void strtof(long double &f, const char *str, char **endptr) noexcept {
+        f = std::strtold(str, endptr);
+      }
 
-  constexpr bool is_end() const noexcept {
-    return m_it == end_value;
-  }
+      token_type scan_number() {
+        reset();
 
-  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
-    return lhs.m_it == rhs.m_it;
-  }
+        token_type number_type = token_type::value_unsigned;
 
-  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
-    return lhs.m_it < rhs.m_it;
-  }
+        switch(current) {
+          case '-': {
+            add(current);
+            goto scan_number_minus;
+          }
 
-  primitive_iterator_t operator+(difference_type n) noexcept {
-    auto result = *this;
-    result += n;
-    return result;
-  }
+          case '0': {
+            add(current);
+            goto scan_number_zero;
+          }
 
-  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
-    return lhs.m_it-rhs.m_it;
-  }
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9': {
+            add(current);
+            goto scan_number_any1;
+          }
 
-  primitive_iterator_t &operator++() noexcept {
-    ++m_it;
-    return *this;
-  }
+          default: {
+            assert(false);
+          }
+        }
 
-  primitive_iterator_t const operator++(int) noexcept {
-    auto result = *this;
-    m_it++;
-    return result;
-  }
+        scan_number_minus:
 
-  primitive_iterator_t &operator--() noexcept {
-    --m_it;
-    return *this;
-  }
+        number_type = token_type::value_integer;
+        switch(get()) {
+          case '0': {
+            add(current);
+            goto scan_number_zero;
+          }
 
-  primitive_iterator_t const operator--(int) noexcept {
-    auto result = *this;
-    m_it--;
-    return result;
-  }
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9': {
+            add(current);
+            goto scan_number_any1;
+          }
 
-  primitive_iterator_t &operator+=(difference_type n) noexcept {
-    m_it += n;
-    return *this;
-  }
+          default: {
+            error_message = "invalid number; expected digit after '-'";
+            return token_type::parse_error;
+          }
+        }
 
-  primitive_iterator_t &operator-=(difference_type n) noexcept {
-    m_it -= n;
-    return *this;
-  }
-};
-}
-}
+        scan_number_zero:
 
-namespace nlohmann {
-namespace detail {
-template<typename BasicJsonType>
-struct internal_iterator {
-  typename BasicJsonType::object_t::iterator object_iterator{};
+        switch(get()) {
+          case '.': {
+            add(decimal_point_char);
+            goto scan_number_decimal1;
+          }
 
-  typename BasicJsonType::array_t::iterator array_iterator{};
+          case 'e':
+          case 'E': {
+            add(current);
+            goto scan_number_exponent;
+          }
 
-  primitive_iterator_t primitive_iterator{};
-};
-}
-}
+          default:
+            goto scan_number_done;
+        }
 
-namespace nlohmann {
-namespace detail {
-template<typename IteratorType>
-class iteration_proxy;
+        scan_number_any1:
+
+        switch(get()) {
+          case '0':
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9': {
+            add(current);
+            goto scan_number_any1;
+          }
 
-template<typename BasicJsonType>
-class iter_impl {
-  friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
-  friend BasicJsonType;
-  friend iteration_proxy<iter_impl>;
+          case '.': {
+            add(decimal_point_char);
+            goto scan_number_decimal1;
+          }
 
-  using object_t = typename BasicJsonType::object_t;
-  using array_t = typename BasicJsonType::array_t;
+          case 'e':
+          case 'E': {
+            add(current);
+            goto scan_number_exponent;
+          }
 
-  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
-                "iter_impl only accepts (const) basic_json");
+          default:
+            goto scan_number_done;
+        }
 
-public:
-  using iterator_category = std::bidirectional_iterator_tag;
+        scan_number_decimal1:
+
+        number_type = token_type::value_float;
+        switch(get()) {
+          case '0':
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9': {
+            add(current);
+            goto scan_number_decimal2;
+          }
 
-  using value_type = typename BasicJsonType::value_type;
+          default: {
+            error_message = "invalid number; expected digit after '.'";
+            return token_type::parse_error;
+          }
+        }
 
-  using difference_type = typename BasicJsonType::difference_type;
+        scan_number_decimal2:
+
+        switch(get()) {
+          case '0':
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9': {
+            add(current);
+            goto scan_number_decimal2;
+          }
 
-  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
-      typename BasicJsonType::const_pointer,
-      typename BasicJsonType::pointer>::type;
+          case 'e':
+          case 'E': {
+            add(current);
+            goto scan_number_exponent;
+          }
 
-  using reference =
-  typename std::conditional<std::is_const<BasicJsonType>::value,
-      typename BasicJsonType::const_reference,
-      typename BasicJsonType::reference>::type;
+          default:
+            goto scan_number_done;
+        }
 
-  iter_impl() = default;
+        scan_number_exponent:
 
-  explicit iter_impl(pointer object) noexcept : m_object(object) {
-    assert(m_object != nullptr);
+        number_type = token_type::value_float;
+        switch(get()) {
+          case '+':
+          case '-': {
+            add(current);
+            goto scan_number_sign;
+          }
 
-    switch(m_object->m_type) {
-      case value_t::object: {
-        m_it.object_iterator = typename object_t::iterator();
-        break;
-      }
+          case '0':
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9': {
+            add(current);
+            goto scan_number_any2;
+          }
 
-      case value_t::array: {
-        m_it.array_iterator = typename array_t::iterator();
-        break;
-      }
+          default: {
+            error_message =
+                "invalid number; expected '+', '-', or digit after exponent";
+            return token_type::parse_error;
+          }
+        }
 
-      default: {
-        m_it.primitive_iterator = primitive_iterator_t();
-        break;
-      }
-    }
-  }
+        scan_number_sign:
+
+        switch(get()) {
+          case '0':
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9': {
+            add(current);
+            goto scan_number_any2;
+          }
 
-  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept
-      : m_object(other.m_object), m_it(other.m_it) {}
+          default: {
+            error_message = "invalid number; expected digit after exponent sign";
+            return token_type::parse_error;
+          }
+        }
 
-  iter_impl &operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept {
-    m_object = other.m_object;
-    m_it = other.m_it;
-    return *this;
-  }
+        scan_number_any2:
+
+        switch(get()) {
+          case '0':
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9': {
+            add(current);
+            goto scan_number_any2;
+          }
 
-private:
-  void set_begin() noexcept {
-    assert(m_object != nullptr);
+          default:
+            goto scan_number_done;
+        }
 
-    switch(m_object->m_type) {
-      case value_t::object: {
-        m_it.object_iterator = m_object->m_value.object->begin();
-        break;
-      }
+        scan_number_done:
 
-      case value_t::array: {
-        m_it.array_iterator = m_object->m_value.array->begin();
-        break;
-      }
+        unget();
 
-      case value_t::null: {
-        m_it.primitive_iterator.set_end();
-        break;
-      }
+        char *endptr = nullptr;
+        errno = 0;
 
-      default: {
-        m_it.primitive_iterator.set_begin();
-        break;
-      }
-    }
-  }
+        if(number_type == token_type::value_unsigned) {
+          const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
 
-  void set_end() noexcept {
-    assert(m_object != nullptr);
+          assert(endptr == token_buffer.data()+token_buffer.size());
 
-    switch(m_object->m_type) {
-      case value_t::object: {
-        m_it.object_iterator = m_object->m_value.object->end();
-        break;
-      }
+          if(errno == 0) {
+            value_unsigned = static_cast<number_unsigned_t>(x);
+            if(value_unsigned == x) {
+              return token_type::value_unsigned;
+            }
+          }
+        } else if(number_type == token_type::value_integer) {
+          const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
 
-      case value_t::array: {
-        m_it.array_iterator = m_object->m_value.array->end();
-        break;
-      }
+          assert(endptr == token_buffer.data()+token_buffer.size());
 
-      default: {
-        m_it.primitive_iterator.set_end();
-        break;
-      }
-    }
-  }
+          if(errno == 0) {
+            value_integer = static_cast<number_integer_t>(x);
+            if(value_integer == x) {
+              return token_type::value_integer;
+            }
+          }
+        }
 
-public:
-  reference operator*() const {
-    assert(m_object != nullptr);
+        strtof(value_float, token_buffer.data(), &endptr);
 
-    switch(m_object->m_type) {
-      case value_t::object: {
-        assert(m_it.object_iterator != m_object->m_value.object->end());
-        return m_it.object_iterator->second;
-      }
+        assert(endptr == token_buffer.data()+token_buffer.size());
 
-      case value_t::array: {
-        assert(m_it.array_iterator != m_object->m_value.array->end());
-        return *m_it.array_iterator;
+        return token_type::value_float;
       }
 
-      case value_t::null:
-        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
-
-      default: {
-        if(JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
-          return *m_object;
+      token_type scan_literal(const char *literal_text, const std::size_t length,
+                              token_type return_type) {
+        assert(current == literal_text[0]);
+        for(std::size_t i = 1; i < length; ++i) {
+          if(JSON_UNLIKELY(get() != literal_text[i])) {
+            error_message = "invalid literal";
+            return token_type::parse_error;
+          }
         }
-
-        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+        return return_type;
       }
-    }
-  }
-
-  pointer operator->() const {
-    assert(m_object != nullptr);
 
-    switch(m_object->m_type) {
-      case value_t::object: {
-        assert(m_it.object_iterator != m_object->m_value.object->end());
-        return &(m_it.object_iterator->second);
+      void reset() noexcept {
+        token_buffer.clear();
+        token_string.clear();
+        token_string.push_back(std::char_traits<char>::to_char_type(current));
       }
 
-      case value_t::array: {
-        assert(m_it.array_iterator != m_object->m_value.array->end());
-        return &*m_it.array_iterator;
+      std::char_traits<char>::int_type get() {
+        ++chars_read;
+        current = ia->get_character();
+        if(JSON_LIKELY(current != std::char_traits<char>::eof())) {
+          token_string.push_back(std::char_traits<char>::to_char_type(current));
+        }
+        return current;
       }
 
-      default: {
-        if(JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
-          return m_object;
+      void unget() {
+        --chars_read;
+        if(JSON_LIKELY(current != std::char_traits<char>::eof())) {
+          ia->unget_character();
+          assert(token_string.size() != 0);
+          token_string.pop_back();
         }
-
-        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
       }
-    }
-  }
 
-  iter_impl const operator++(int) {
-    auto result = *this;
-    ++(*this);
-    return result;
-  }
-
-  iter_impl &operator++() {
-    assert(m_object != nullptr);
-
-    switch(m_object->m_type) {
-      case value_t::object: {
-        std::advance(m_it.object_iterator, 1);
-        break;
+      void add(int c) {
+        token_buffer.push_back(std::char_traits<char>::to_char_type(c));
       }
 
-      case value_t::array: {
-        std::advance(m_it.array_iterator, 1);
-        break;
+    public:
+      constexpr number_integer_t get_number_integer() const noexcept {
+        return value_integer;
       }
 
-      default: {
-        ++m_it.primitive_iterator;
-        break;
+      constexpr number_unsigned_t get_number_unsigned() const noexcept {
+        return value_unsigned;
       }
-    }
-
-    return *this;
-  }
-
-  iter_impl const operator--(int) {
-    auto result = *this;
-    --(*this);
-    return result;
-  }
 
-  iter_impl &operator--() {
-    assert(m_object != nullptr);
-
-    switch(m_object->m_type) {
-      case value_t::object: {
-        std::advance(m_it.object_iterator, -1);
-        break;
+      constexpr number_float_t get_number_float() const noexcept {
+        return value_float;
       }
 
-      case value_t::array: {
-        std::advance(m_it.array_iterator, -1);
-        break;
+      string_t &&move_string() {
+        return std::move(token_buffer);
       }
 
-      default: {
-        --m_it.primitive_iterator;
-        break;
+      constexpr std::size_t get_position() const noexcept {
+        return chars_read;
       }
-    }
-
-    return *this;
-  }
-
-  bool operator==(const iter_impl &other) const {
-    if(JSON_UNLIKELY(m_object != other.m_object)) {
-      JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
-    }
-
-    assert(m_object != nullptr);
-
-    switch(m_object->m_type) {
-      case value_t::object:
-        return (m_it.object_iterator == other.m_it.object_iterator);
-
-      case value_t::array:
-        return (m_it.array_iterator == other.m_it.array_iterator);
-
-      default:
-        return (m_it.primitive_iterator == other.m_it.primitive_iterator);
-    }
-  }
-
-  bool operator!=(const iter_impl &other) const {
-    return not operator==(other);
-  }
-
-  bool operator<(const iter_impl &other) const {
-    if(JSON_UNLIKELY(m_object != other.m_object)) {
-      JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
-    }
-
-    assert(m_object != nullptr);
-
-    switch(m_object->m_type) {
-      case value_t::object:
-        JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
-
-      case value_t::array:
-        return (m_it.array_iterator < other.m_it.array_iterator);
-
-      default:
-        return (m_it.primitive_iterator < other.m_it.primitive_iterator);
-    }
-  }
-
-  bool operator<=(const iter_impl &other) const {
-    return not other.operator<(*this);
-  }
 
-  bool operator>(const iter_impl &other) const {
-    return not operator<=(other);
-  }
-
-  bool operator>=(const iter_impl &other) const {
-    return not operator<(other);
-  }
-
-  iter_impl &operator+=(difference_type i) {
-    assert(m_object != nullptr);
-
-    switch(m_object->m_type) {
-      case value_t::object:
-        JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+      std::string get_token_string() const {
+        std::string result;
+        for(const auto c : token_string) {
+          if('\x00' <= c and c <= '\x1F') {
+            std::stringstream ss;
+            ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
+               << std::hex << static_cast<int>(c) << ">";
+            result += ss.str();
+          } else {
+            result.push_back(c);
+          }
+        }
 
-      case value_t::array: {
-        std::advance(m_it.array_iterator, i);
-        break;
+        return result;
       }
 
-      default: {
-        m_it.primitive_iterator += i;
-        break;
+      constexpr const char *get_error_message() const noexcept {
+        return error_message;
       }
-    }
 
-    return *this;
-  }
+      token_type scan() {
+        do {
+          get();
+        } while(current == ' ' or current == '\t' or current == '\n' or current == '\r');
+
+        switch(current) {
+          case '[':
+            return token_type::begin_array;
+          case ']':
+            return token_type::end_array;
+          case '{':
+            return token_type::begin_object;
+          case '}':
+            return token_type::end_object;
+          case ':':
+            return token_type::name_separator;
+          case ',':
+            return token_type::value_separator;
+
+          case 't':
+            return scan_literal("true", 4, token_type::literal_true);
+          case 'f':
+            return scan_literal("false", 5, token_type::literal_false);
+          case 'n':
+            return scan_literal("null", 4, token_type::literal_null);
+
+          case '\"':
+            return scan_string();
+
+          case '-':
+          case '0':
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9':
+            return scan_number();
+
+          case '\0':
+          case std::char_traits<char>::eof():
+            return token_type::end_of_input;
+
+          default:
+            error_message = "invalid literal";
+            return token_type::parse_error;
+        }
+      }
 
-  iter_impl &operator-=(difference_type i) {
-    return operator+=(-i);
-  }
+    private:
+      detail::input_adapter_t ia = nullptr;
 
-  iter_impl operator+(difference_type i) const {
-    auto result = *this;
-    result += i;
-    return result;
-  }
+      std::char_traits<char>::int_type current = std::char_traits<char>::eof();
 
-  friend iter_impl operator+(difference_type i, const iter_impl &it) {
-    auto result = it;
-    result += i;
-    return result;
-  }
+      std::size_t chars_read = 0;
 
-  iter_impl operator-(difference_type i) const {
-    auto result = *this;
-    result -= i;
-    return result;
-  }
+      std::vector<char> token_string{};
 
-  difference_type operator-(const iter_impl &other) const {
-    assert(m_object != nullptr);
+      string_t token_buffer{};
 
-    switch(m_object->m_type) {
-      case value_t::object:
-        JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+      const char *error_message = "";
 
-      case value_t::array:
-        return m_it.array_iterator-other.m_it.array_iterator;
+      number_integer_t value_integer = 0;
+      number_unsigned_t value_unsigned = 0;
+      number_float_t value_float = 0;
 
-      default:
-        return m_it.primitive_iterator-other.m_it.primitive_iterator;
-    }
+      const char decimal_point_char = '.';
+    };
   }
+}
 
-  reference operator[](difference_type n) const {
-    assert(m_object != nullptr);
-
-    switch(m_object->m_type) {
-      case value_t::object:
-        JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
-
-      case value_t::array:
-        return *std::next(m_it.array_iterator, n);
-
-      case value_t::null:
-        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
-
-      default: {
-        if(JSON_LIKELY(m_it.primitive_iterator.get_value() == -n)) {
-          return *m_object;
-        }
-
-        JSON_THROW(invalid_iterator::create(214, "cannot get value"));
-      }
-    }
-  }
+#include <cmath>
 
-  typename object_t::key_type key() const {
-    assert(m_object != nullptr);
+namespace nlohmann {
+  namespace detail {
+    template<typename BasicJsonType>
+    class parser {
+      using number_integer_t = typename BasicJsonType::number_integer_t;
+      using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+      using number_float_t = typename BasicJsonType::number_float_t;
+      using string_t = typename BasicJsonType::string_t;
+      using lexer_t = lexer<BasicJsonType>;
+      using token_type = typename lexer_t::token_type;
 
-    if(JSON_LIKELY(m_object->is_object())) {
-      return m_it.object_iterator->first;
-    }
+    public:
+      enum class parse_event_t : uint8_t {
+        object_start,
 
-    JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
-  }
+        object_end,
 
-  reference value() const {
-    return operator*();
-  }
+        array_start,
 
-private:
-  pointer m_object = nullptr;
+        array_end,
 
-  internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
-};
-}
-}
+        key,
 
-namespace nlohmann {
-namespace detail {
-template<typename IteratorType>
-class iteration_proxy {
-private:
-  class iteration_proxy_internal {
-  private:
-    IteratorType anchor;
+        value
+      };
 
-    std::size_t array_index = 0;
+      using parser_callback_t =
+      std::function<bool(int depth, parse_event_t event, BasicJsonType &parsed)>;
 
-  public:
-    explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
+      explicit parser(detail::input_adapter_t adapter,
+                      const parser_callback_t cb = nullptr,
+                      const bool allow_exceptions_ = true)
+          : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_) {}
 
-    iteration_proxy_internal &operator*() {
-      return *this;
-    }
+      void parse(const bool strict, BasicJsonType &result) {
+        get_token();
 
-    iteration_proxy_internal &operator++() {
-      ++anchor;
-      ++array_index;
+        parse_internal(true, result);
+        result.assert_invariant();
 
-      return *this;
-    }
+        if(strict) {
+          get_token();
+          expect(token_type::end_of_input);
+        }
 
-    bool operator!=(const iteration_proxy_internal &o) const noexcept {
-      return anchor != o.anchor;
-    }
+        if(errored) {
+          result = value_t::discarded;
+          return;
+        }
 
-    std::string key() const {
-      assert(anchor.m_object != nullptr);
+        if(result.is_discarded()) {
+          result = nullptr;
+        }
+      }
 
-      switch(anchor.m_object->type()) {
-        case value_t::array:
-          return std::to_string(array_index);
+      bool accept(const bool strict = true) {
+        get_token();
 
-        case value_t::object:
-          return anchor.key();
+        if(not accept_internal()) {
+          return false;
+        }
 
-        default:
-          return "";
+        return not strict or (get_token() == token_type::end_of_input);
       }
-    }
-
-    typename IteratorType::reference value() const {
-      return anchor.value();
-    }
-  };
 
-  typename IteratorType::reference container;
+    private:
+      void parse_internal(bool keep, BasicJsonType &result) {
+        assert(not errored);
 
-public:
-  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
-      : container(cont) {}
-
-  iteration_proxy_internal begin() noexcept {
-    return iteration_proxy_internal(container.begin());
-  }
+        if(not result.is_discarded()) {
+          result.m_value.destroy(result.m_type);
+          result.m_type = value_t::discarded;
+        }
 
-  iteration_proxy_internal end() noexcept {
-    return iteration_proxy_internal(container.end());
-  }
-};
-}
-}
+        switch(last_token) {
+          case token_type::begin_object: {
+            if(keep) {
+              if(callback) {
+                keep = callback(depth++, parse_event_t::object_start, result);
+              }
 
-namespace nlohmann {
-namespace detail {
-template<typename Base>
-class json_reverse_iterator : public std::reverse_iterator<Base> {
-public:
-  using difference_type = std::ptrdiff_t;
+              if(not callback or keep) {
+                result.m_type = value_t::object;
+                result.m_value = value_t::object;
+              }
+            }
 
-  using base_iterator = std::reverse_iterator<Base>;
+            get_token();
 
-  using reference = typename Base::reference;
+            if(last_token == token_type::end_object) {
+              if(keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
+                result.m_value.destroy(result.m_type);
+                result.m_type = value_t::discarded;
+              }
+              break;
+            }
 
-  json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
-      : base_iterator(it) {}
+            string_t key;
+            BasicJsonType value;
+            while(true) {
+              if(not expect(token_type::value_string)) {
+                return;
+              }
+              key = m_lexer.move_string();
 
-  json_reverse_iterator(const base_iterator &it) noexcept : base_iterator(it) {}
+              bool keep_tag = false;
+              if(keep) {
+                if(callback) {
+                  BasicJsonType k(key);
+                  keep_tag = callback(depth, parse_event_t::key, k);
+                } else {
+                  keep_tag = true;
+                }
+              }
 
-  json_reverse_iterator const operator++(int) {
-    return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
-  }
+              get_token();
+              if(not expect(token_type::name_separator)) {
+                return;
+              }
 
-  json_reverse_iterator &operator++() {
-    return static_cast<json_reverse_iterator &>(base_iterator::operator++());
-  }
+              get_token();
+              value.m_value.destroy(value.m_type);
+              value.m_type = value_t::discarded;
+              parse_internal(keep, value);
 
-  json_reverse_iterator const operator--(int) {
-    return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
-  }
+              if(JSON_UNLIKELY(errored)) {
+                return;
+              }
 
-  json_reverse_iterator &operator--() {
-    return static_cast<json_reverse_iterator &>(base_iterator::operator--());
-  }
+              if(keep and keep_tag and not value.is_discarded()) {
+                result.m_value.object->emplace(std::move(key), std::move(value));
+              }
 
-  json_reverse_iterator &operator+=(difference_type i) {
-    return static_cast<json_reverse_iterator &>(base_iterator::operator+=(i));
-  }
+              get_token();
+              if(last_token == token_type::value_separator) {
+                get_token();
+                continue;
+              }
 
-  json_reverse_iterator operator+(difference_type i) const {
-    return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
-  }
+              if(not expect(token_type::end_object)) {
+                return;
+              }
+              break;
+            }
 
-  json_reverse_iterator operator-(difference_type i) const {
-    return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
-  }
+            if(keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
+              result.m_value.destroy(result.m_type);
+              result.m_type = value_t::discarded;
+            }
+            break;
+          }
 
-  difference_type operator-(const json_reverse_iterator &other) const {
-    return base_iterator(*this)-base_iterator(other);
-  }
+          case token_type::begin_array: {
+            if(keep) {
+              if(callback) {
+                keep = callback(depth++, parse_event_t::array_start, result);
+              }
 
-  reference operator[](difference_type n) const {
-    return *(this->operator+(n));
-  }
+              if(not callback or keep) {
+                result.m_type = value_t::array;
+                result.m_value = value_t::array;
+              }
+            }
 
-  auto key() const -> decltype(std::declval<Base>().key()) {
-    auto it = --this->base();
-    return it.key();
-  }
+            get_token();
 
-  reference value() const {
-    auto it = --this->base();
-    return it.operator*();
-  }
-};
-}
-}
+            if(last_token == token_type::end_array) {
+              if(callback and not callback(--depth, parse_event_t::array_end, result)) {
+                result.m_value.destroy(result.m_type);
+                result.m_type = value_t::discarded;
+              }
+              break;
+            }
 
-#include <ostream>
+            BasicJsonType value;
+            while(true) {
+              value.m_value.destroy(value.m_type);
+              value.m_type = value_t::discarded;
+              parse_internal(keep, value);
 
-namespace nlohmann {
-namespace detail {
-template<typename CharType>
-struct output_adapter_protocol {
-  virtual void write_character(CharType c) = 0;
+              if(JSON_UNLIKELY(errored)) {
+                return;
+              }
 
-  virtual void write_characters(const CharType *s, std::size_t length) = 0;
+              if(keep and not value.is_discarded()) {
+                result.m_value.array->push_back(std::move(value));
+              }
 
-  virtual ~output_adapter_protocol() = default;
-};
+              get_token();
+              if(last_token == token_type::value_separator) {
+                get_token();
+                continue;
+              }
 
-template<typename CharType>
-using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
+              if(not expect(token_type::end_array)) {
+                return;
+              }
+              break;
+            }
 
-template<typename CharType>
-class output_vector_adapter : public output_adapter_protocol<CharType> {
-public:
-  explicit output_vector_adapter(std::vector<CharType> &vec) : v(vec) {}
+            if(keep and callback and not callback(--depth, parse_event_t::array_end, result)) {
+              result.m_value.destroy(result.m_type);
+              result.m_type = value_t::discarded;
+            }
+            break;
+          }
 
-  void write_character(CharType c) override {
-    v.push_back(c);
-  }
+          case token_type::literal_null: {
+            result.m_type = value_t::null;
+            break;
+          }
 
-  void write_characters(const CharType *s, std::size_t length) override {
-    std::copy(s, s+length, std::back_inserter(v));
-  }
+          case token_type::value_string: {
+            result.m_type = value_t::string;
+            result.m_value = m_lexer.move_string();
+            break;
+          }
 
-private:
-  std::vector<CharType> &v;
-};
+          case token_type::literal_true: {
+            result.m_type = value_t::boolean;
+            result.m_value = true;
+            break;
+          }
 
-template<typename CharType>
-class output_stream_adapter : public output_adapter_protocol<CharType> {
-public:
-  explicit output_stream_adapter(std::basic_ostream<CharType> &s) : stream(s) {}
+          case token_type::literal_false: {
+            result.m_type = value_t::boolean;
+            result.m_value = false;
+            break;
+          }
 
-  void write_character(CharType c) override {
-    stream.put(c);
-  }
+          case token_type::value_unsigned: {
+            result.m_type = value_t::number_unsigned;
+            result.m_value = m_lexer.get_number_unsigned();
+            break;
+          }
 
-  void write_characters(const CharType *s, std::size_t length) override {
-    stream.write(s, static_cast<std::streamsize>(length));
-  }
+          case token_type::value_integer: {
+            result.m_type = value_t::number_integer;
+            result.m_value = m_lexer.get_number_integer();
+            break;
+          }
 
-private:
-  std::basic_ostream<CharType> &stream;
-};
+          case token_type::value_float: {
+            result.m_type = value_t::number_float;
+            result.m_value = m_lexer.get_number_float();
 
-template<typename CharType, typename StringType = std::basic_string<CharType>>
-class output_string_adapter : public output_adapter_protocol<CharType> {
-public:
-  explicit output_string_adapter(StringType &s) : str(s) {}
+            if(JSON_UNLIKELY(not std::isfinite(result.m_value.number_float))) {
+              if(allow_exceptions) {
+                JSON_THROW(out_of_range::create(406, "number overflow parsing '"+
+                                                     m_lexer.get_token_string()+"'"));
+              }
+              expect(token_type::uninitialized);
+            }
+            break;
+          }
 
-  void write_character(CharType c) override {
-    str.push_back(c);
-  }
+          case token_type::parse_error: {
+            if(not expect(token_type::uninitialized)) {
+              return;
+            }
+            break;
+          }
 
-  void write_characters(const CharType *s, std::size_t length) override {
-    str.append(s, length);
-  }
+          default: {
+            if(not expect(token_type::literal_or_value)) {
+              return;
+            }
+            break;
+          }
+        }
 
-private:
-  StringType &str;
-};
+        if(keep and callback and not callback(depth, parse_event_t::value, result)) {
+          result.m_value.destroy(result.m_type);
+          result.m_type = value_t::discarded;
+        }
+      }
 
-template<typename CharType, typename StringType = std::basic_string<CharType>>
-class output_adapter {
-public:
-  output_adapter(std::vector<CharType> &vec)
-      : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
+      bool accept_internal() {
+        switch(last_token) {
+          case token_type::begin_object: {
+            get_token();
 
-  output_adapter(std::basic_ostream<CharType> &s)
-      : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
+            if(last_token == token_type::end_object) {
+              return true;
+            }
 
-  output_adapter(StringType &s)
-      : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
+            while(true) {
+              if(last_token != token_type::value_string) {
+                return false;
+              }
 
-  operator output_adapter_t<CharType>() {
-    return oa;
-  }
+              get_token();
+              if(last_token != token_type::name_separator) {
+                return false;
+              }
 
-private:
-  output_adapter_t<CharType> oa = nullptr;
-};
-}
-}
+              get_token();
+              if(not accept_internal()) {
+                return false;
+              }
 
-namespace nlohmann {
-namespace detail {
-template<typename BasicJsonType>
-class binary_reader {
-  using number_integer_t = typename BasicJsonType::number_integer_t;
-  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
-  using string_t = typename BasicJsonType::string_t;
-
-public:
-  explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter)) {
-    assert(ia);
-  }
+              get_token();
+              if(last_token == token_type::value_separator) {
+                get_token();
+                continue;
+              }
 
-  BasicJsonType parse_cbor(const bool strict) {
-    const auto res = parse_cbor_internal();
-    if(strict) {
-      get();
-      expect_eof();
-    }
-    return res;
-  }
+              return (last_token == token_type::end_object);
+            }
+          }
 
-  BasicJsonType parse_msgpack(const bool strict) {
-    const auto res = parse_msgpack_internal();
-    if(strict) {
-      get();
-      expect_eof();
-    }
-    return res;
-  }
+          case token_type::begin_array: {
+            get_token();
 
-  BasicJsonType parse_ubjson(const bool strict) {
-    const auto res = parse_ubjson_internal();
-    if(strict) {
-      get_ignore_noop();
-      expect_eof();
-    }
-    return res;
-  }
+            if(last_token == token_type::end_array) {
+              return true;
+            }
 
-  static constexpr bool little_endianess(int num = 1) noexcept {
-    return (*reinterpret_cast<char *>(&num) == 1);
-  }
+            while(true) {
+              if(not accept_internal()) {
+                return false;
+              }
 
-private:
-  BasicJsonType parse_cbor_internal(const bool get_char = true) {
-    switch(get_char ? get() : current) {
-      case std::char_traits<char>::eof():
-        JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
-
-      case 0x00:
-      case 0x01:
-      case 0x02:
-      case 0x03:
-      case 0x04:
-      case 0x05:
-      case 0x06:
-      case 0x07:
-      case 0x08:
-      case 0x09:
-      case 0x0A:
-      case 0x0B:
-      case 0x0C:
-      case 0x0D:
-      case 0x0E:
-      case 0x0F:
-      case 0x10:
-      case 0x11:
-      case 0x12:
-      case 0x13:
-      case 0x14:
-      case 0x15:
-      case 0x16:
-      case 0x17:
-        return static_cast<number_unsigned_t>(current);
-
-      case 0x18:
-        return get_number<uint8_t>();
-
-      case 0x19:
-        return get_number<uint16_t>();
-
-      case 0x1A:
-        return get_number<uint32_t>();
-
-      case 0x1B:
-        return get_number<uint64_t>();
-
-      case 0x20:
-      case 0x21:
-      case 0x22:
-      case 0x23:
-      case 0x24:
-      case 0x25:
-      case 0x26:
-      case 0x27:
-      case 0x28:
-      case 0x29:
-      case 0x2A:
-      case 0x2B:
-      case 0x2C:
-      case 0x2D:
-      case 0x2E:
-      case 0x2F:
-      case 0x30:
-      case 0x31:
-      case 0x32:
-      case 0x33:
-      case 0x34:
-      case 0x35:
-      case 0x36:
-      case 0x37:
-        return static_cast<int8_t>(0x20-1-current);
-
-      case 0x38: {
-        return static_cast<number_integer_t>(-1)-get_number<uint8_t>();
-      }
-
-      case 0x39: {
-        return static_cast<number_integer_t>(-1)-get_number<uint16_t>();
-      }
-
-      case 0x3A: {
-        return static_cast<number_integer_t>(-1)-get_number<uint32_t>();
-      }
-
-      case 0x3B: {
-        return static_cast<number_integer_t>(-1)-
-               static_cast<number_integer_t>(get_number<uint64_t>());
-      }
-
-      case 0x60:
-      case 0x61:
-      case 0x62:
-      case 0x63:
-      case 0x64:
-      case 0x65:
-      case 0x66:
-      case 0x67:
-      case 0x68:
-      case 0x69:
-      case 0x6A:
-      case 0x6B:
-      case 0x6C:
-      case 0x6D:
-      case 0x6E:
-      case 0x6F:
-      case 0x70:
-      case 0x71:
-      case 0x72:
-      case 0x73:
-      case 0x74:
-      case 0x75:
-      case 0x76:
-      case 0x77:
-      case 0x78:
-      case 0x79:
-      case 0x7A:
-      case 0x7B:
-      case 0x7F: {
-        return get_cbor_string();
-      }
-
-      case 0x80:
-      case 0x81:
-      case 0x82:
-      case 0x83:
-      case 0x84:
-      case 0x85:
-      case 0x86:
-      case 0x87:
-      case 0x88:
-      case 0x89:
-      case 0x8A:
-      case 0x8B:
-      case 0x8C:
-      case 0x8D:
-      case 0x8E:
-      case 0x8F:
-      case 0x90:
-      case 0x91:
-      case 0x92:
-      case 0x93:
-      case 0x94:
-      case 0x95:
-      case 0x96:
-      case 0x97: {
-        return get_cbor_array(current & 0x1F);
-      }
-
-      case 0x98: {
-        return get_cbor_array(get_number<uint8_t>());
-      }
-
-      case 0x99: {
-        return get_cbor_array(get_number<uint16_t>());
-      }
-
-      case 0x9A: {
-        return get_cbor_array(get_number<uint32_t>());
-      }
-
-      case 0x9B: {
-        return get_cbor_array(get_number<uint64_t>());
-      }
-
-      case 0x9F: {
-        BasicJsonType result = value_t::array;
-        while(get() != 0xFF) {
-          result.push_back(parse_cbor_internal(false));
-        }
-        return result;
-      }
+              get_token();
+              if(last_token == token_type::value_separator) {
+                get_token();
+                continue;
+              }
 
-      case 0xA0:
-      case 0xA1:
-      case 0xA2:
-      case 0xA3:
-      case 0xA4:
-      case 0xA5:
-      case 0xA6:
-      case 0xA7:
-      case 0xA8:
-      case 0xA9:
-      case 0xAA:
-      case 0xAB:
-      case 0xAC:
-      case 0xAD:
-      case 0xAE:
-      case 0xAF:
-      case 0xB0:
-      case 0xB1:
-      case 0xB2:
-      case 0xB3:
-      case 0xB4:
-      case 0xB5:
-      case 0xB6:
-      case 0xB7: {
-        return get_cbor_object(current & 0x1F);
-      }
+              return (last_token == token_type::end_array);
+            }
+          }
 
-      case 0xB8: {
-        return get_cbor_object(get_number<uint8_t>());
-      }
+          case token_type::value_float: {
+            return std::isfinite(m_lexer.get_number_float());
+          }
 
-      case 0xB9: {
-        return get_cbor_object(get_number<uint16_t>());
-      }
+          case token_type::literal_false:
+          case token_type::literal_null:
+          case token_type::literal_true:
+          case token_type::value_integer:
+          case token_type::value_string:
+          case token_type::value_unsigned:
+            return true;
 
-      case 0xBA: {
-        return get_cbor_object(get_number<uint32_t>());
+          default:
+            return false;
+        }
       }
 
-      case 0xBB: {
-        return get_cbor_object(get_number<uint64_t>());
+      token_type get_token() {
+        return (last_token = m_lexer.scan());
       }
 
-      case 0xBF: {
-        BasicJsonType result = value_t::object;
-        while(get() != 0xFF) {
-          auto key = get_cbor_string();
-          result[key] = parse_cbor_internal();
+      bool expect(token_type t) {
+        if(JSON_UNLIKELY(t != last_token)) {
+          errored = true;
+          expected = t;
+          if(allow_exceptions) {
+            throw_exception();
+          } else {
+            return false;
+          }
         }
-        return result;
-      }
 
-      case 0xF4: {
-        return false;
-      }
-
-      case 0xF5: {
         return true;
       }
 
-      case 0xF6: {
-        return value_t::null;
-      }
-
-      case 0xF9: {
-        const int byte1 = get();
-        unexpect_eof();
-        const int byte2 = get();
-        unexpect_eof();
-
-        const int half = (byte1 << 8)+byte2;
-        const int exp = (half >> 10) & 0x1F;
-        const int mant = half & 0x3FF;
-        double val;
-        if(exp == 0) {
-          val = std::ldexp(mant, -24);
-        } else if(exp != 31) {
-          val = std::ldexp(mant+1024, exp-25);
+      [[noreturn]] void throw_exception() const {
+        std::string error_msg = "syntax error - ";
+        if(last_token == token_type::parse_error) {
+          error_msg += std::string(m_lexer.get_error_message())+"; last read: '"+
+                       m_lexer.get_token_string()+"'";
         } else {
-          val = (mant == 0) ? std::numeric_limits<double>::infinity()
-                            : std::numeric_limits<double>::quiet_NaN();
+          error_msg += "unexpected "+std::string(lexer_t::token_type_name(last_token));
         }
-        return (half & 0x8000) != 0 ? -val : val;
-      }
-
-      case 0xFA: {
-        return get_number<float>();
-      }
 
-      case 0xFB: {
-        return get_number<double>();
-      }
+        if(expected != token_type::uninitialized) {
+          error_msg += "; expected "+std::string(lexer_t::token_type_name(expected));
+        }
 
-      default: {
-        std::stringstream ss;
-        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
-        JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x"+ss.str()));
+        JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
       }
-    }
-  }
-
-  BasicJsonType parse_msgpack_internal() {
-    switch(get()) {
-      case std::char_traits<char>::eof():
-        JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
-
-      case 0x00:
-      case 0x01:
-      case 0x02:
-      case 0x03:
-      case 0x04:
-      case 0x05:
-      case 0x06:
-      case 0x07:
-      case 0x08:
-      case 0x09:
-      case 0x0A:
-      case 0x0B:
-      case 0x0C:
-      case 0x0D:
-      case 0x0E:
-      case 0x0F:
-      case 0x10:
-      case 0x11:
-      case 0x12:
-      case 0x13:
-      case 0x14:
-      case 0x15:
-      case 0x16:
-      case 0x17:
-      case 0x18:
-      case 0x19:
-      case 0x1A:
-      case 0x1B:
-      case 0x1C:
-      case 0x1D:
-      case 0x1E:
-      case 0x1F:
-      case 0x20:
-      case 0x21:
-      case 0x22:
-      case 0x23:
-      case 0x24:
-      case 0x25:
-      case 0x26:
-      case 0x27:
-      case 0x28:
-      case 0x29:
-      case 0x2A:
-      case 0x2B:
-      case 0x2C:
-      case 0x2D:
-      case 0x2E:
-      case 0x2F:
-      case 0x30:
-      case 0x31:
-      case 0x32:
-      case 0x33:
-      case 0x34:
-      case 0x35:
-      case 0x36:
-      case 0x37:
-      case 0x38:
-      case 0x39:
-      case 0x3A:
-      case 0x3B:
-      case 0x3C:
-      case 0x3D:
-      case 0x3E:
-      case 0x3F:
-      case 0x40:
-      case 0x41:
-      case 0x42:
-      case 0x43:
-      case 0x44:
-      case 0x45:
-      case 0x46:
-      case 0x47:
-      case 0x48:
-      case 0x49:
-      case 0x4A:
-      case 0x4B:
-      case 0x4C:
-      case 0x4D:
-      case 0x4E:
-      case 0x4F:
-      case 0x50:
-      case 0x51:
-      case 0x52:
-      case 0x53:
-      case 0x54:
-      case 0x55:
-      case 0x56:
-      case 0x57:
-      case 0x58:
-      case 0x59:
-      case 0x5A:
-      case 0x5B:
-      case 0x5C:
-      case 0x5D:
-      case 0x5E:
-      case 0x5F:
-      case 0x60:
-      case 0x61:
-      case 0x62:
-      case 0x63:
-      case 0x64:
-      case 0x65:
-      case 0x66:
-      case 0x67:
-      case 0x68:
-      case 0x69:
-      case 0x6A:
-      case 0x6B:
-      case 0x6C:
-      case 0x6D:
-      case 0x6E:
-      case 0x6F:
-      case 0x70:
-      case 0x71:
-      case 0x72:
-      case 0x73:
-      case 0x74:
-      case 0x75:
-      case 0x76:
-      case 0x77:
-      case 0x78:
-      case 0x79:
-      case 0x7A:
-      case 0x7B:
-      case 0x7C:
-      case 0x7D:
-      case 0x7E:
-      case 0x7F:
-        return static_cast<number_unsigned_t>(current);
-
-      case 0x80:
-      case 0x81:
-      case 0x82:
-      case 0x83:
-      case 0x84:
-      case 0x85:
-      case 0x86:
-      case 0x87:
-      case 0x88:
-      case 0x89:
-      case 0x8A:
-      case 0x8B:
-      case 0x8C:
-      case 0x8D:
-      case 0x8E:
-      case 0x8F: {
-        return get_msgpack_object(current & 0x0F);
-      }
-
-      case 0x90:
-      case 0x91:
-      case 0x92:
-      case 0x93:
-      case 0x94:
-      case 0x95:
-      case 0x96:
-      case 0x97:
-      case 0x98:
-      case 0x99:
-      case 0x9A:
-      case 0x9B:
-      case 0x9C:
-      case 0x9D:
-      case 0x9E:
-      case 0x9F: {
-        return get_msgpack_array(current & 0x0F);
-      }
-
-      case 0xA0:
-      case 0xA1:
-      case 0xA2:
-      case 0xA3:
-      case 0xA4:
-      case 0xA5:
-      case 0xA6:
-      case 0xA7:
-      case 0xA8:
-      case 0xA9:
-      case 0xAA:
-      case 0xAB:
-      case 0xAC:
-      case 0xAD:
-      case 0xAE:
-      case 0xAF:
-      case 0xB0:
-      case 0xB1:
-      case 0xB2:
-      case 0xB3:
-      case 0xB4:
-      case 0xB5:
-      case 0xB6:
-      case 0xB7:
-      case 0xB8:
-      case 0xB9:
-      case 0xBA:
-      case 0xBB:
-      case 0xBC:
-      case 0xBD:
-      case 0xBE:
-      case 0xBF:
-        return get_msgpack_string();
-
-      case 0xC0:
-        return value_t::null;
-
-      case 0xC2:
-        return false;
-
-      case 0xC3:
-        return true;
-
-      case 0xCA:
-        return get_number<float>();
-
-      case 0xCB:
-        return get_number<double>();
 
-      case 0xCC:
-        return get_number<uint8_t>();
+    private:
+      int depth = 0;
 
-      case 0xCD:
-        return get_number<uint16_t>();
+      const parser_callback_t callback = nullptr;
 
-      case 0xCE:
-        return get_number<uint32_t>();
+      token_type last_token = token_type::uninitialized;
 
-      case 0xCF:
-        return get_number<uint64_t>();
+      lexer_t m_lexer;
 
-      case 0xD0:
-        return get_number<int8_t>();
+      bool errored = false;
 
-      case 0xD1:
-        return get_number<int16_t>();
+      token_type expected = token_type::uninitialized;
 
-      case 0xD2:
-        return get_number<int32_t>();
+      const bool allow_exceptions = true;
+    };
+  }
+}
 
-      case 0xD3:
-        return get_number<int64_t>();
+namespace nlohmann {
+  namespace detail {
+    class primitive_iterator_t {
+    private:
+      using difference_type = std::ptrdiff_t;
+      static constexpr difference_type begin_value = 0;
+      static constexpr difference_type end_value = begin_value+1;
 
-      case 0xD9:
-      case 0xDA:
-      case 0xDB:
-        return get_msgpack_string();
+      difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
 
-      case 0xDC: {
-        return get_msgpack_array(get_number<uint16_t>());
+    public:
+      constexpr difference_type get_value() const noexcept {
+        return m_it;
       }
 
-      case 0xDD: {
-        return get_msgpack_array(get_number<uint32_t>());
+      void set_begin() noexcept {
+        m_it = begin_value;
       }
 
-      case 0xDE: {
-        return get_msgpack_object(get_number<uint16_t>());
+      void set_end() noexcept {
+        m_it = end_value;
       }
 
-      case 0xDF: {
-        return get_msgpack_object(get_number<uint32_t>());
+      constexpr bool is_begin() const noexcept {
+        return m_it == begin_value;
       }
 
-      case 0xE0:
-      case 0xE1:
-      case 0xE2:
-      case 0xE3:
-      case 0xE4:
-      case 0xE5:
-      case 0xE6:
-      case 0xE7:
-      case 0xE8:
-      case 0xE9:
-      case 0xEA:
-      case 0xEB:
-      case 0xEC:
-      case 0xED:
-      case 0xEE:
-      case 0xEF:
-      case 0xF0:
-      case 0xF1:
-      case 0xF2:
-      case 0xF3:
-      case 0xF4:
-      case 0xF5:
-      case 0xF6:
-      case 0xF7:
-      case 0xF8:
-      case 0xF9:
-      case 0xFA:
-      case 0xFB:
-      case 0xFC:
-      case 0xFD:
-      case 0xFE:
-      case 0xFF:
-        return static_cast<int8_t>(current);
-
-      default: {
-        std::stringstream ss;
-        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
-        JSON_THROW(parse_error::create(112, chars_read,
-                                       "error reading MessagePack; last byte: 0x"+ss.str()));
+      constexpr bool is_end() const noexcept {
+        return m_it == end_value;
       }
-    }
-  }
-
-  BasicJsonType parse_ubjson_internal(const bool get_char = true) {
-    return get_ubjson_value(get_char ? get_ignore_noop() : current);
-  }
-
-  int get() {
-    ++chars_read;
-    return (current = ia->get_character());
-  }
-
-  int get_ignore_noop() {
-    do {
-      get();
-    } while(current == 'N');
 
-    return current;
-  }
-
-  template<typename NumberType>
-  NumberType get_number() {
-    std::array<uint8_t, sizeof(NumberType)> vec;
-    for(std::size_t i = 0; i < sizeof(NumberType); ++i) {
-      get();
-      unexpect_eof();
-
-      if(is_little_endian) {
-        vec[sizeof(NumberType)-i-1] = static_cast<uint8_t>(current);
-      } else {
-        vec[i] = static_cast<uint8_t>(current);
+      friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
+        return lhs.m_it == rhs.m_it;
       }
-    }
-
-    NumberType result;
-    std::memcpy(&result, vec.data(), sizeof(NumberType));
-    return result;
-  }
-
-  template<typename NumberType>
-  string_t get_string(const NumberType len) {
-    string_t result;
-    std::generate_n(std::back_inserter(result), len, [this]() {
-      get();
-      unexpect_eof();
-      return static_cast<char>(current);
-    });
-    return result;
-  }
 
-  string_t get_cbor_string() {
-    unexpect_eof();
+      friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
+        return lhs.m_it < rhs.m_it;
+      }
 
-    switch(current) {
-      case 0x60:
-      case 0x61:
-      case 0x62:
-      case 0x63:
-      case 0x64:
-      case 0x65:
-      case 0x66:
-      case 0x67:
-      case 0x68:
-      case 0x69:
-      case 0x6A:
-      case 0x6B:
-      case 0x6C:
-      case 0x6D:
-      case 0x6E:
-      case 0x6F:
-      case 0x70:
-      case 0x71:
-      case 0x72:
-      case 0x73:
-      case 0x74:
-      case 0x75:
-      case 0x76:
-      case 0x77: {
-        return get_string(current & 0x1F);
+      primitive_iterator_t operator+(difference_type n) noexcept {
+        auto result = *this;
+        result += n;
+        return result;
       }
 
-      case 0x78: {
-        return get_string(get_number<uint8_t>());
+      friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
+        return lhs.m_it-rhs.m_it;
       }
 
-      case 0x79: {
-        return get_string(get_number<uint16_t>());
+      primitive_iterator_t &operator++() noexcept {
+        ++m_it;
+        return *this;
       }
 
-      case 0x7A: {
-        return get_string(get_number<uint32_t>());
+      primitive_iterator_t const operator++(int) noexcept {
+        auto result = *this;
+        m_it++;
+        return result;
       }
 
-      case 0x7B: {
-        return get_string(get_number<uint64_t>());
+      primitive_iterator_t &operator--() noexcept {
+        --m_it;
+        return *this;
       }
 
-      case 0x7F: {
-        string_t result;
-        while(get() != 0xFF) {
-          result.append(get_cbor_string());
-        }
+      primitive_iterator_t const operator--(int) noexcept {
+        auto result = *this;
+        m_it--;
         return result;
       }
 
-      default: {
-        std::stringstream ss;
-        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
-        JSON_THROW(parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x"+ss.str()));
+      primitive_iterator_t &operator+=(difference_type n) noexcept {
+        m_it += n;
+        return *this;
       }
-    }
-  }
-
-  template<typename NumberType>
-  BasicJsonType get_cbor_array(const NumberType len) {
-    BasicJsonType result = value_t::array;
-    std::generate_n(std::back_inserter(*result.m_value.array), len, [this]() {
-      return parse_cbor_internal();
-    });
-    return result;
-  }
-
-  template<typename NumberType>
-  BasicJsonType get_cbor_object(const NumberType len) {
-    BasicJsonType result = value_t::object;
-    std::generate_n(std::inserter(*result.m_value.object,
-                                  result.m_value.object->end()),
-                    len, [this]() {
-          get();
-          auto key = get_cbor_string();
-          auto val = parse_cbor_internal();
-          return std::make_pair(std::move(key), std::move(val));
-        });
-    return result;
-  }
 
-  string_t get_msgpack_string() {
-    unexpect_eof();
-
-    switch(current) {
-      case 0xA0:
-      case 0xA1:
-      case 0xA2:
-      case 0xA3:
-      case 0xA4:
-      case 0xA5:
-      case 0xA6:
-      case 0xA7:
-      case 0xA8:
-      case 0xA9:
-      case 0xAA:
-      case 0xAB:
-      case 0xAC:
-      case 0xAD:
-      case 0xAE:
-      case 0xAF:
-      case 0xB0:
-      case 0xB1:
-      case 0xB2:
-      case 0xB3:
-      case 0xB4:
-      case 0xB5:
-      case 0xB6:
-      case 0xB7:
-      case 0xB8:
-      case 0xB9:
-      case 0xBA:
-      case 0xBB:
-      case 0xBC:
-      case 0xBD:
-      case 0xBE:
-      case 0xBF: {
-        return get_string(current & 0x1F);
-      }
-
-      case 0xD9: {
-        return get_string(get_number<uint8_t>());
-      }
-
-      case 0xDA: {
-        return get_string(get_number<uint16_t>());
-      }
-
-      case 0xDB: {
-        return get_string(get_number<uint32_t>());
-      }
-
-      default: {
-        std::stringstream ss;
-        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
-        JSON_THROW(parse_error::create(113, chars_read,
-                                       "expected a MessagePack string; last byte: 0x"+ss.str()));
+      primitive_iterator_t &operator-=(difference_type n) noexcept {
+        m_it -= n;
+        return *this;
       }
-    }
+    };
   }
+}
 
-  template<typename NumberType>
-  BasicJsonType get_msgpack_array(const NumberType len) {
-    BasicJsonType result = value_t::array;
-    std::generate_n(std::back_inserter(*result.m_value.array), len, [this]() {
-      return parse_msgpack_internal();
-    });
-    return result;
-  }
+namespace nlohmann {
+  namespace detail {
+    template<typename BasicJsonType>
+    struct internal_iterator {
+      typename BasicJsonType::object_t::iterator object_iterator{};
 
-  template<typename NumberType>
-  BasicJsonType get_msgpack_object(const NumberType len) {
-    BasicJsonType result = value_t::object;
-    std::generate_n(std::inserter(*result.m_value.object,
-                                  result.m_value.object->end()),
-                    len, [this]() {
-          get();
-          auto key = get_msgpack_string();
-          auto val = parse_msgpack_internal();
-          return std::make_pair(std::move(key), std::move(val));
-        });
-    return result;
-  }
+      typename BasicJsonType::array_t::iterator array_iterator{};
 
-  string_t get_ubjson_string(const bool get_char = true) {
-    if(get_char) {
-      get();
-    }
-
-    unexpect_eof();
-
-    switch(current) {
-      case 'U':
-        return get_string(get_number<uint8_t>());
-      case 'i':
-        return get_string(get_number<int8_t>());
-      case 'I':
-        return get_string(get_number<int16_t>());
-      case 'l':
-        return get_string(get_number<int32_t>());
-      case 'L':
-        return get_string(get_number<int64_t>());
-      default:
-        std::stringstream ss;
-        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
-        JSON_THROW(parse_error::create(113, chars_read,
-                                       "expected a UBJSON string; last byte: 0x"+ss.str()));
-    }
+      primitive_iterator_t primitive_iterator{};
+    };
   }
+}
 
-  std::pair<std::size_t, int> get_ubjson_size_type() {
-    std::size_t sz = string_t::npos;
-    int tc = 0;
+namespace nlohmann {
+  namespace detail {
+    template<typename IteratorType>
+    class iteration_proxy;
 
-    get_ignore_noop();
+    template<typename BasicJsonType>
+    class iter_impl {
+      friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
+      friend BasicJsonType;
+      friend iteration_proxy<iter_impl>;
 
-    if(current == '$') {
-      tc = get();
-      unexpect_eof();
+      using object_t = typename BasicJsonType::object_t;
+      using array_t = typename BasicJsonType::array_t;
 
-      get_ignore_noop();
-      if(current != '#') {
-        std::stringstream ss;
-        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
-        JSON_THROW(parse_error::create(112, chars_read,
-                                       "expected '#' after UBJSON type information; last byte: 0x"+ss.str()));
-      }
-      sz = parse_ubjson_internal();
-    } else if(current == '#') {
-      sz = parse_ubjson_internal();
-    }
+      static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
+                    "iter_impl only accepts (const) basic_json");
 
-    return std::make_pair(sz, tc);
-  }
+    public:
+      using iterator_category = std::bidirectional_iterator_tag;
 
-  BasicJsonType get_ubjson_value(const int prefix) {
-    switch(prefix) {
-      case std::char_traits<char>::eof():
-        JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
+      using value_type = typename BasicJsonType::value_type;
 
-      case 'T':
-        return true;
-      case 'F':
-        return false;
-
-      case 'Z':
-        return nullptr;
-
-      case 'U':
-        return get_number<uint8_t>();
-      case 'i':
-        return get_number<int8_t>();
-      case 'I':
-        return get_number<int16_t>();
-      case 'l':
-        return get_number<int32_t>();
-      case 'L':
-        return get_number<int64_t>();
-      case 'd':
-        return get_number<float>();
-      case 'D':
-        return get_number<double>();
-
-      case 'C': {
-        get();
-        unexpect_eof();
-        if(JSON_UNLIKELY(current > 127)) {
-          std::stringstream ss;
-          ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
-          JSON_THROW(parse_error::create(113, chars_read,
-                                         "byte after 'C' must be in range 0x00..0x7F; last byte: 0x"+ss.str()));
-        }
-        return string_t(1, static_cast<char>(current));
-      }
+      using difference_type = typename BasicJsonType::difference_type;
 
-      case 'S':
-        return get_ubjson_string();
+      using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
+          typename BasicJsonType::const_pointer,
+          typename BasicJsonType::pointer>::type;
 
-      case '[':
-        return get_ubjson_array();
+      using reference =
+      typename std::conditional<std::is_const<BasicJsonType>::value,
+          typename BasicJsonType::const_reference,
+          typename BasicJsonType::reference>::type;
 
-      case '{':
-        return get_ubjson_object();
+      iter_impl() = default;
 
-      default:
-        std::stringstream ss;
-        ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
-        JSON_THROW(parse_error::create(112, chars_read,
-                                       "error reading UBJSON; last byte: 0x"+ss.str()));
-    }
-  }
+      explicit iter_impl(pointer object) noexcept : m_object(object) {
+        assert(m_object != nullptr);
 
-  BasicJsonType get_ubjson_array() {
-    BasicJsonType result = value_t::array;
-    const auto size_and_type = get_ubjson_size_type();
+        switch(m_object->m_type) {
+          case value_t::object: {
+            m_it.object_iterator = typename object_t::iterator();
+            break;
+          }
 
-    if(size_and_type.first != string_t::npos) {
-      if(JSON_UNLIKELY(size_and_type.first > result.max_size())) {
-        JSON_THROW(out_of_range::create(408,
-                                        "excessive array size: "+std::to_string(size_and_type.first)));
-      }
+          case value_t::array: {
+            m_it.array_iterator = typename array_t::iterator();
+            break;
+          }
 
-      if(size_and_type.second != 0) {
-        if(size_and_type.second != 'N') {
-          std::generate_n(std::back_inserter(*result.m_value.array),
-                          size_and_type.first, [this, size_and_type]() {
-                return get_ubjson_value(size_and_type.second);
-              });
+          default: {
+            m_it.primitive_iterator = primitive_iterator_t();
+            break;
+          }
         }
-      } else {
-        std::generate_n(std::back_inserter(*result.m_value.array),
-                        size_and_type.first, [this]() {
-              return parse_ubjson_internal();
-            });
       }
-    } else {
-      while(current != ']') {
-        result.push_back(parse_ubjson_internal(false));
-        get_ignore_noop();
-      }
-    }
 
-    return result;
-  }
-
-  BasicJsonType get_ubjson_object() {
-    BasicJsonType result = value_t::object;
-    const auto size_and_type = get_ubjson_size_type();
-
-    if(size_and_type.first != string_t::npos) {
-      if(JSON_UNLIKELY(size_and_type.first > result.max_size())) {
-        JSON_THROW(out_of_range::create(408,
-                                        "excessive object size: "+std::to_string(size_and_type.first)));
-      }
+      iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept
+          : m_object(other.m_object), m_it(other.m_it) {}
 
-      if(size_and_type.second != 0) {
-        std::generate_n(std::inserter(*result.m_value.object,
-                                      result.m_value.object->end()),
-                        size_and_type.first, [this, size_and_type]() {
-              auto key = get_ubjson_string();
-              auto val = get_ubjson_value(size_and_type.second);
-              return std::make_pair(std::move(key), std::move(val));
-            });
-      } else {
-        std::generate_n(std::inserter(*result.m_value.object,
-                                      result.m_value.object->end()),
-                        size_and_type.first, [this]() {
-              auto key = get_ubjson_string();
-              auto val = parse_ubjson_internal();
-              return std::make_pair(std::move(key), std::move(val));
-            });
-      }
-    } else {
-      while(current != '}') {
-        auto key = get_ubjson_string(false);
-        result[std::move(key)] = parse_ubjson_internal();
-        get_ignore_noop();
+      iter_impl &operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept {
+        m_object = other.m_object;
+        m_it = other.m_it;
+        return *this;
       }
-    }
-
-    return result;
-  }
 
-  void expect_eof() const {
-    if(JSON_UNLIKELY(current != std::char_traits<char>::eof())) {
-      JSON_THROW(parse_error::create(110, chars_read, "expected end of input"));
-    }
-  }
+    private:
+      void set_begin() noexcept {
+        assert(m_object != nullptr);
 
-  void unexpect_eof() const {
-    if(JSON_UNLIKELY(current == std::char_traits<char>::eof())) {
-      JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
-    }
-  }
+        switch(m_object->m_type) {
+          case value_t::object: {
+            m_it.object_iterator = m_object->m_value.object->begin();
+            break;
+          }
 
-private:
-  input_adapter_t ia = nullptr;
+          case value_t::array: {
+            m_it.array_iterator = m_object->m_value.array->begin();
+            break;
+          }
 
-  int current = std::char_traits<char>::eof();
+          case value_t::null: {
+            m_it.primitive_iterator.set_end();
+            break;
+          }
 
-  std::size_t chars_read = 0;
+          default: {
+            m_it.primitive_iterator.set_begin();
+            break;
+          }
+        }
+      }
 
-  const bool is_little_endian = little_endianess();
-};
-}
-}
+      void set_end() noexcept {
+        assert(m_object != nullptr);
 
-namespace nlohmann {
-namespace detail {
-template<typename BasicJsonType, typename CharType>
-class binary_writer {
-public:
-  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter) {
-    assert(oa);
-  }
+        switch(m_object->m_type) {
+          case value_t::object: {
+            m_it.object_iterator = m_object->m_value.object->end();
+            break;
+          }
 
-  void write_cbor(const BasicJsonType &j) {
-    switch(j.type()) {
-      case value_t::null: {
-        oa->write_character(static_cast<CharType>(0xF6));
-        break;
-      }
-
-      case value_t::boolean: {
-        oa->write_character(j.m_value.boolean
-                            ? static_cast<CharType>(0xF5)
-                            : static_cast<CharType>(0xF4));
-        break;
-      }
-
-      case value_t::number_integer: {
-        if(j.m_value.number_integer >= 0) {
-          if(j.m_value.number_integer <= 0x17) {
-            write_number(static_cast<uint8_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0x18));
-            write_number(static_cast<uint8_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0x19));
-            write_number(static_cast<uint16_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0x1A));
-            write_number(static_cast<uint32_t>(j.m_value.number_integer));
-          } else {
-            oa->write_character(static_cast<CharType>(0x1B));
-            write_number(static_cast<uint64_t>(j.m_value.number_integer));
+          case value_t::array: {
+            m_it.array_iterator = m_object->m_value.array->end();
+            break;
           }
-        } else {
-          const auto positive_number = -1-j.m_value.number_integer;
-          if(j.m_value.number_integer >= -24) {
-            write_number(static_cast<uint8_t>(0x20+positive_number));
-          } else if(positive_number <= (std::numeric_limits<uint8_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0x38));
-            write_number(static_cast<uint8_t>(positive_number));
-          } else if(positive_number <= (std::numeric_limits<uint16_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0x39));
-            write_number(static_cast<uint16_t>(positive_number));
-          } else if(positive_number <= (std::numeric_limits<uint32_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0x3A));
-            write_number(static_cast<uint32_t>(positive_number));
-          } else {
-            oa->write_character(static_cast<CharType>(0x3B));
-            write_number(static_cast<uint64_t>(positive_number));
+
+          default: {
+            m_it.primitive_iterator.set_end();
+            break;
           }
         }
-        break;
       }
 
-      case value_t::number_unsigned: {
-        if(j.m_value.number_unsigned <= 0x17) {
-          write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x18));
-          write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x19));
-          write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x1A));
-          write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
-        } else {
-          oa->write_character(static_cast<CharType>(0x1B));
-          write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
-        }
-        break;
-      }
-
-      case value_t::number_float: {
-        oa->write_character(static_cast<CharType>(0xFB));
-        write_number(j.m_value.number_float);
-        break;
-      }
-
-      case value_t::string: {
-        const auto N = j.m_value.string->size();
-        if(N <= 0x17) {
-          write_number(static_cast<uint8_t>(0x60+N));
-        } else if(N <= (std::numeric_limits<uint8_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x78));
-          write_number(static_cast<uint8_t>(N));
-        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x79));
-          write_number(static_cast<uint16_t>(N));
-        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x7A));
-          write_number(static_cast<uint32_t>(N));
-        } else if(N <= (std::numeric_limits<uint64_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x7B));
-          write_number(static_cast<uint64_t>(N));
-        }
-
-        oa->write_characters(
-            reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
-            j.m_value.string->size());
-        break;
-      }
-
-      case value_t::array: {
-        const auto N = j.m_value.array->size();
-        if(N <= 0x17) {
-          write_number(static_cast<uint8_t>(0x80+N));
-        } else if(N <= (std::numeric_limits<uint8_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x98));
-          write_number(static_cast<uint8_t>(N));
-        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x99));
-          write_number(static_cast<uint16_t>(N));
-        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x9A));
-          write_number(static_cast<uint32_t>(N));
-        } else if(N <= (std::numeric_limits<uint64_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0x9B));
-          write_number(static_cast<uint64_t>(N));
-        }
-
-        for(const auto &el : *j.m_value.array) {
-          write_cbor(el);
-        }
-        break;
-      }
-
-      case value_t::object: {
-        const auto N = j.m_value.object->size();
-        if(N <= 0x17) {
-          write_number(static_cast<uint8_t>(0xA0+N));
-        } else if(N <= (std::numeric_limits<uint8_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xB8));
-          write_number(static_cast<uint8_t>(N));
-        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xB9));
-          write_number(static_cast<uint16_t>(N));
-        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xBA));
-          write_number(static_cast<uint32_t>(N));
-        } else if(N <= (std::numeric_limits<uint64_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xBB));
-          write_number(static_cast<uint64_t>(N));
-        }
-
-        for(const auto &el : *j.m_value.object) {
-          write_cbor(el.first);
-          write_cbor(el.second);
-        }
-        break;
-      }
-
-      default:
-        break;
-    }
-  }
+    public:
+      reference operator*() const {
+        assert(m_object != nullptr);
 
-  void write_msgpack(const BasicJsonType &j) {
-    switch(j.type()) {
-      case value_t::null: {
-        oa->write_character(static_cast<CharType>(0xC0));
-        break;
-      }
-
-      case value_t::boolean: {
-        oa->write_character(j.m_value.boolean
-                            ? static_cast<CharType>(0xC3)
-                            : static_cast<CharType>(0xC2));
-        break;
-      }
-
-      case value_t::number_integer: {
-        if(j.m_value.number_integer >= 0) {
-          if(j.m_value.number_unsigned < 128) {
-            write_number(static_cast<uint8_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0xCC));
-            write_number(static_cast<uint8_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0xCD));
-            write_number(static_cast<uint16_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0xCE));
-            write_number(static_cast<uint32_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0xCF));
-            write_number(static_cast<uint64_t>(j.m_value.number_integer));
+        switch(m_object->m_type) {
+          case value_t::object: {
+            assert(m_it.object_iterator != m_object->m_value.object->end());
+            return m_it.object_iterator->second;
           }
-        } else {
-          if(j.m_value.number_integer >= -32) {
-            write_number(static_cast<int8_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_integer >= (std::numeric_limits<int8_t>::min) () and
-                    j.m_value.number_integer <= (std::numeric_limits<int8_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0xD0));
-            write_number(static_cast<int8_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_integer >= (std::numeric_limits<int16_t>::min) () and
-                    j.m_value.number_integer <= (std::numeric_limits<int16_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0xD1));
-            write_number(static_cast<int16_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_integer >= (std::numeric_limits<int32_t>::min) () and
-                    j.m_value.number_integer <= (std::numeric_limits<int32_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0xD2));
-            write_number(static_cast<int32_t>(j.m_value.number_integer));
-          } else if(j.m_value.number_integer >= (std::numeric_limits<int64_t>::min) () and
-                    j.m_value.number_integer <= (std::numeric_limits<int64_t>::max) ()) {
-            oa->write_character(static_cast<CharType>(0xD3));
-            write_number(static_cast<int64_t>(j.m_value.number_integer));
-          }
-        }
-        break;
-      }
-
-      case value_t::number_unsigned: {
-        if(j.m_value.number_unsigned < 128) {
-          write_number(static_cast<uint8_t>(j.m_value.number_integer));
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xCC));
-          write_number(static_cast<uint8_t>(j.m_value.number_integer));
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xCD));
-          write_number(static_cast<uint16_t>(j.m_value.number_integer));
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xCE));
-          write_number(static_cast<uint32_t>(j.m_value.number_integer));
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xCF));
-          write_number(static_cast<uint64_t>(j.m_value.number_integer));
-        }
-        break;
-      }
-
-      case value_t::number_float: {
-        oa->write_character(static_cast<CharType>(0xCB));
-        write_number(j.m_value.number_float);
-        break;
-      }
-
-      case value_t::string: {
-        const auto N = j.m_value.string->size();
-        if(N <= 31) {
-          write_number(static_cast<uint8_t>(0xA0 | N));
-        } else if(N <= (std::numeric_limits<uint8_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xD9));
-          write_number(static_cast<uint8_t>(N));
-        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xDA));
-          write_number(static_cast<uint16_t>(N));
-        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xDB));
-          write_number(static_cast<uint32_t>(N));
-        }
-
-        oa->write_characters(
-            reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
-            j.m_value.string->size());
-        break;
-      }
-
-      case value_t::array: {
-        const auto N = j.m_value.array->size();
-        if(N <= 15) {
-          write_number(static_cast<uint8_t>(0x90 | N));
-        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xDC));
-          write_number(static_cast<uint16_t>(N));
-        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xDD));
-          write_number(static_cast<uint32_t>(N));
-        }
-
-        for(const auto &el : *j.m_value.array) {
-          write_msgpack(el);
-        }
-        break;
-      }
-
-      case value_t::object: {
-        const auto N = j.m_value.object->size();
-        if(N <= 15) {
-          write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
-        } else if(N <= (std::numeric_limits<uint16_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xDE));
-          write_number(static_cast<uint16_t>(N));
-        } else if(N <= (std::numeric_limits<uint32_t>::max) ()) {
-          oa->write_character(static_cast<CharType>(0xDF));
-          write_number(static_cast<uint32_t>(N));
-        }
-
-        for(const auto &el : *j.m_value.object) {
-          write_msgpack(el.first);
-          write_msgpack(el.second);
-        }
-        break;
-      }
-
-      default:
-        break;
-    }
-  }
 
-  void write_ubjson(const BasicJsonType &j, const bool use_count,
-                    const bool use_type, const bool add_prefix = true) {
-    switch(j.type()) {
-      case value_t::null: {
-        if(add_prefix) {
-          oa->write_character(static_cast<CharType>('Z'));
+          case value_t::array: {
+            assert(m_it.array_iterator != m_object->m_value.array->end());
+            return *m_it.array_iterator;
+          }
+
+          case value_t::null:
+            JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+
+          default: {
+            if(JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
+              return *m_object;
+            }
+
+            JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+          }
         }
-        break;
       }
 
-      case value_t::boolean: {
-        if(add_prefix)
-          oa->write_character(j.m_value.boolean
-                              ? static_cast<CharType>('T')
-                              : static_cast<CharType>('F'));
-        break;
-      }
+      pointer operator->() const {
+        assert(m_object != nullptr);
 
-      case value_t::number_integer: {
-        write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
-        break;
-      }
+        switch(m_object->m_type) {
+          case value_t::object: {
+            assert(m_it.object_iterator != m_object->m_value.object->end());
+            return &(m_it.object_iterator->second);
+          }
 
-      case value_t::number_unsigned: {
-        write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
-        break;
-      }
+          case value_t::array: {
+            assert(m_it.array_iterator != m_object->m_value.array->end());
+            return &*m_it.array_iterator;
+          }
 
-      case value_t::number_float: {
-        write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
-        break;
-      }
+          default: {
+            if(JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
+              return m_object;
+            }
 
-      case value_t::string: {
-        if(add_prefix) {
-          oa->write_character(static_cast<CharType>('S'));
+            JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+          }
         }
-        write_number_with_ubjson_prefix(j.m_value.string->size(), true);
-        oa->write_characters(
-            reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
-            j.m_value.string->size());
-        break;
       }
 
-      case value_t::array: {
-        if(add_prefix) {
-          oa->write_character(static_cast<CharType>('['));
-        }
+      iter_impl const operator++(int) {
+        auto result = *this;
+        ++(*this);
+        return result;
+      }
 
-        bool prefix_required = true;
-        if(use_type and not j.m_value.array->empty()) {
-          assert(use_count);
-          const char first_prefix = ubjson_prefix(j.front());
-          const bool same_prefix = std::all_of(j.begin()+1, j.end(),
-                                               [this, first_prefix](const BasicJsonType &v) {
-                                                 return ubjson_prefix(v) == first_prefix;
-                                               });
+      iter_impl &operator++() {
+        assert(m_object != nullptr);
 
-          if(same_prefix) {
-            prefix_required = false;
-            oa->write_character(static_cast<CharType>('$'));
-            oa->write_character(static_cast<CharType>(first_prefix));
+        switch(m_object->m_type) {
+          case value_t::object: {
+            std::advance(m_it.object_iterator, 1);
+            break;
           }
-        }
 
-        if(use_count) {
-          oa->write_character(static_cast<CharType>('#'));
-          write_number_with_ubjson_prefix(j.m_value.array->size(), true);
-        }
-
-        for(const auto &el : *j.m_value.array) {
-          write_ubjson(el, use_count, use_type, prefix_required);
-        }
+          case value_t::array: {
+            std::advance(m_it.array_iterator, 1);
+            break;
+          }
 
-        if(not use_count) {
-          oa->write_character(static_cast<CharType>(']'));
+          default: {
+            ++m_it.primitive_iterator;
+            break;
+          }
         }
 
-        break;
+        return *this;
       }
 
-      case value_t::object: {
-        if(add_prefix) {
-          oa->write_character(static_cast<CharType>('{'));
-        }
+      iter_impl const operator--(int) {
+        auto result = *this;
+        --(*this);
+        return result;
+      }
 
-        bool prefix_required = true;
-        if(use_type and not j.m_value.object->empty()) {
-          assert(use_count);
-          const char first_prefix = ubjson_prefix(j.front());
-          const bool same_prefix = std::all_of(j.begin(), j.end(),
-                                               [this, first_prefix](const BasicJsonType &v) {
-                                                 return ubjson_prefix(v) == first_prefix;
-                                               });
+      iter_impl &operator--() {
+        assert(m_object != nullptr);
 
-          if(same_prefix) {
-            prefix_required = false;
-            oa->write_character(static_cast<CharType>('$'));
-            oa->write_character(static_cast<CharType>(first_prefix));
+        switch(m_object->m_type) {
+          case value_t::object: {
+            std::advance(m_it.object_iterator, -1);
+            break;
           }
-        }
-
-        if(use_count) {
-          oa->write_character(static_cast<CharType>('#'));
-          write_number_with_ubjson_prefix(j.m_value.object->size(), true);
-        }
 
-        for(const auto &el : *j.m_value.object) {
-          write_number_with_ubjson_prefix(el.first.size(), true);
-          oa->write_characters(
-              reinterpret_cast<const CharType *>(el.first.c_str()),
-              el.first.size());
-          write_ubjson(el.second, use_count, use_type, prefix_required);
-        }
+          case value_t::array: {
+            std::advance(m_it.array_iterator, -1);
+            break;
+          }
 
-        if(not use_count) {
-          oa->write_character(static_cast<CharType>('}'));
+          default: {
+            --m_it.primitive_iterator;
+            break;
+          }
         }
 
-        break;
+        return *this;
       }
 
-      default:
-        break;
-    }
-  }
-
-private:
-  template<typename NumberType>
-  void write_number(const NumberType n) {
-    std::array<CharType, sizeof(NumberType)> vec;
-    std::memcpy(vec.data(), &n, sizeof(NumberType));
-
-    if(is_little_endian) {
-      std::reverse(vec.begin(), vec.end());
-    }
-
-    oa->write_characters(vec.data(), sizeof(NumberType));
-  }
-
-  template<typename NumberType, typename std::enable_if<
-      std::is_floating_point<NumberType>::value, int>::type = 0>
-  void write_number_with_ubjson_prefix(const NumberType n,
-                                       const bool add_prefix) {
-    if(add_prefix) {
-      oa->write_character(static_cast<CharType>('D'));
-    }
-    write_number(n);
-  }
+      bool operator==(const iter_impl &other) const {
+        if(JSON_UNLIKELY(m_object != other.m_object)) {
+          JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+        }
 
-  template<typename NumberType, typename std::enable_if<
-      std::is_unsigned<NumberType>::value, int>::type = 0>
-  void write_number_with_ubjson_prefix(const NumberType n,
-                                       const bool add_prefix) {
-    if(n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max) ())) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('i'));
-      }
-      write_number(static_cast<uint8_t>(n));
-    } else if(n <= (std::numeric_limits<uint8_t>::max) ()) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('U'));
-      }
-      write_number(static_cast<uint8_t>(n));
-    } else if(n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max) ())) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('I'));
-      }
-      write_number(static_cast<int16_t>(n));
-    } else if(n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max) ())) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('l'));
-      }
-      write_number(static_cast<int32_t>(n));
-    } else if(n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max) ())) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('L'));
-      }
-      write_number(static_cast<int64_t>(n));
-    } else {
-      JSON_THROW(out_of_range::create(407, "number overflow serializing "+std::to_string(n)));
-    }
-  }
+        assert(m_object != nullptr);
 
-  template<typename NumberType, typename std::enable_if<
-      std::is_signed<NumberType>::value and
-      not std::is_floating_point<NumberType>::value, int>::type = 0>
-  void write_number_with_ubjson_prefix(const NumberType n,
-                                       const bool add_prefix) {
-    if((std::numeric_limits<int8_t>::min) () <= n and n <= (std::numeric_limits<int8_t>::max) ()) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('i'));
-      }
-      write_number(static_cast<int8_t>(n));
-    } else if(static_cast<int64_t>((std::numeric_limits<uint8_t>::min) ()) <= n and
-              n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max) ())) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('U'));
-      }
-      write_number(static_cast<uint8_t>(n));
-    } else if((std::numeric_limits<int16_t>::min) () <= n and n <= (std::numeric_limits<int16_t>::max) ()) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('I'));
-      }
-      write_number(static_cast<int16_t>(n));
-    } else if((std::numeric_limits<int32_t>::min) () <= n and n <= (std::numeric_limits<int32_t>::max) ()) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('l'));
-      }
-      write_number(static_cast<int32_t>(n));
-    } else if((std::numeric_limits<int64_t>::min) () <= n and n <= (std::numeric_limits<int64_t>::max) ()) {
-      if(add_prefix) {
-        oa->write_character(static_cast<CharType>('L'));
-      }
-      write_number(static_cast<int64_t>(n));
-    } else {
-      JSON_THROW(out_of_range::create(407, "number overflow serializing "+std::to_string(n)));
-    }
+        switch(m_object->m_type) {
+          case value_t::object:
+            return (m_it.object_iterator == other.m_it.object_iterator);
 
-  }
+          case value_t::array:
+            return (m_it.array_iterator == other.m_it.array_iterator);
 
-  char ubjson_prefix(const BasicJsonType &j) const noexcept {
-    switch(j.type()) {
-      case value_t::null:
-        return 'Z';
-
-      case value_t::boolean:
-        return j.m_value.boolean ? 'T' : 'F';
-
-      case value_t::number_integer: {
-        if((std::numeric_limits<int8_t>::min) () <= j.m_value.number_integer and
-           j.m_value.number_integer <= (std::numeric_limits<int8_t>::max) ()) {
-          return 'i';
-        } else if((std::numeric_limits<uint8_t>::min) () <= j.m_value.number_integer and
-                  j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max) ()) {
-          return 'U';
-        } else if((std::numeric_limits<int16_t>::min) () <= j.m_value.number_integer and
-                  j.m_value.number_integer <= (std::numeric_limits<int16_t>::max) ()) {
-          return 'I';
-        } else if((std::numeric_limits<int32_t>::min) () <= j.m_value.number_integer and
-                  j.m_value.number_integer <= (std::numeric_limits<int32_t>::max) ()) {
-          return 'l';
-        } else {
-          return 'L';
+          default:
+            return (m_it.primitive_iterator == other.m_it.primitive_iterator);
         }
       }
 
-      case value_t::number_unsigned: {
-        if(j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max) ()) {
-          return 'i';
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max) ()) {
-          return 'U';
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max) ()) {
-          return 'I';
-        } else if(j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max) ()) {
-          return 'l';
-        } else {
-          return 'L';
-        }
+      bool operator!=(const iter_impl &other) const {
+        return not operator==(other);
       }
 
-      case value_t::number_float:
-        return 'D';
+      bool operator<(const iter_impl &other) const {
+        if(JSON_UNLIKELY(m_object != other.m_object)) {
+          JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+        }
 
-      case value_t::string:
-        return 'S';
+        assert(m_object != nullptr);
 
-      case value_t::array:
-        return '[';
+        switch(m_object->m_type) {
+          case value_t::object:
+            JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
 
-      case value_t::object:
-        return '{';
+          case value_t::array:
+            return (m_it.array_iterator < other.m_it.array_iterator);
 
-      default:
-        return 'N';
-    }
-  }
+          default:
+            return (m_it.primitive_iterator < other.m_it.primitive_iterator);
+        }
+      }
 
-private:
-  const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
+      bool operator<=(const iter_impl &other) const {
+        return not other.operator<(*this);
+      }
 
-  output_adapter_t<CharType> oa = nullptr;
-};
-}
-}
+      bool operator>(const iter_impl &other) const {
+        return not operator<=(other);
+      }
 
-#include <cstdio>
+      bool operator>=(const iter_impl &other) const {
+        return not operator<(other);
+      }
 
-namespace nlohmann {
-namespace detail {
-namespace dtoa_impl {
-template<typename Target, typename Source>
-Target reinterpret_bits(const Source source) {
-  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
-
-  Target target;
-  std::memcpy(&target, &source, sizeof(Source));
-  return target;
-}
+      iter_impl &operator+=(difference_type i) {
+        assert(m_object != nullptr);
 
-struct diyfp {
-  static constexpr int kPrecision = 64;
+        switch(m_object->m_type) {
+          case value_t::object:
+            JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
 
-  uint64_t f;
-  int e;
+          case value_t::array: {
+            std::advance(m_it.array_iterator, i);
+            break;
+          }
 
-  constexpr diyfp() noexcept : f(0), e(0) {}
+          default: {
+            m_it.primitive_iterator += i;
+            break;
+          }
+        }
 
-  constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
+        return *this;
+      }
 
-  static diyfp sub(const diyfp &x, const diyfp &y) noexcept {
-    assert(x.e == y.e);
-    assert(x.f >= y.f);
+      iter_impl &operator-=(difference_type i) {
+        return operator+=(-i);
+      }
 
-    return diyfp(x.f-y.f, x.e);
-  }
+      iter_impl operator+(difference_type i) const {
+        auto result = *this;
+        result += i;
+        return result;
+      }
 
-  static diyfp mul(const diyfp &x, const diyfp &y) noexcept {
-    static_assert(kPrecision == 64, "internal error");
+      friend iter_impl operator+(difference_type i, const iter_impl &it) {
+        auto result = it;
+        result += i;
+        return result;
+      }
 
-    //
+      iter_impl operator-(difference_type i) const {
+        auto result = *this;
+        result -= i;
+        return result;
+      }
 
-    //
+      difference_type operator-(const iter_impl &other) const {
+        assert(m_object != nullptr);
 
-    //
+        switch(m_object->m_type) {
+          case value_t::object:
+            JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
 
-    //
+          case value_t::array:
+            return m_it.array_iterator-other.m_it.array_iterator;
 
-    //
+          default:
+            return m_it.primitive_iterator-other.m_it.primitive_iterator;
+        }
+      }
 
-    const uint64_t u_lo = x.f & 0xFFFFFFFF;
-    const uint64_t u_hi = x.f >> 32;
-    const uint64_t v_lo = y.f & 0xFFFFFFFF;
-    const uint64_t v_hi = y.f >> 32;
+      reference operator[](difference_type n) const {
+        assert(m_object != nullptr);
 
-    const uint64_t p0 = u_lo * v_lo;
-    const uint64_t p1 = u_lo * v_hi;
-    const uint64_t p2 = u_hi * v_lo;
-    const uint64_t p3 = u_hi * v_hi;
+        switch(m_object->m_type) {
+          case value_t::object:
+            JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
 
-    const uint64_t p0_hi = p0 >> 32;
-    const uint64_t p1_lo = p1 & 0xFFFFFFFF;
-    const uint64_t p1_hi = p1 >> 32;
-    const uint64_t p2_lo = p2 & 0xFFFFFFFF;
-    const uint64_t p2_hi = p2 >> 32;
+          case value_t::array:
+            return *std::next(m_it.array_iterator, n);
 
-    uint64_t Q = p0_hi+p1_lo+p2_lo;
+          case value_t::null:
+            JSON_THROW(invalid_iterator::create(214, "cannot get value"));
 
-    //
+          default: {
+            if(JSON_LIKELY(m_it.primitive_iterator.get_value() == -n)) {
+              return *m_object;
+            }
 
-    //
+            JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+          }
+        }
+      }
 
-    Q += uint64_t{1} << (64-32-1);
+      typename object_t::key_type key() const {
+        assert(m_object != nullptr);
 
-    const uint64_t h = p3+p2_hi+p1_hi+(Q >> 32);
+        if(JSON_LIKELY(m_object->is_object())) {
+          return m_it.object_iterator->first;
+        }
 
-    return diyfp(h, x.e+y.e+64);
-  }
+        JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
+      }
 
-  static diyfp normalize(diyfp x) noexcept {
-    assert(x.f != 0);
+      reference value() const {
+        return operator*();
+      }
 
-    while((x.f >> 63) == 0) {
-      x.f <<= 1;
-      x.e--;
-    }
+    private:
+      pointer m_object = nullptr;
 
-    return x;
+      internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
+    };
   }
+}
 
-  static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept {
-    const int delta = x.e-target_exponent;
-
-    assert(delta >= 0);
-    assert(((x.f << delta) >> delta) == x.f);
-
-    return diyfp(x.f << delta, target_exponent);
-  }
-};
+namespace nlohmann {
+  namespace detail {
+    template<typename IteratorType>
+    class iteration_proxy {
+    private:
+      class iteration_proxy_internal {
+      private:
+        IteratorType anchor;
 
-struct boundaries {
-  diyfp w;
-  diyfp minus;
-  diyfp plus;
-};
+        std::size_t array_index = 0;
 
-template<typename FloatType>
-boundaries compute_boundaries(FloatType value) {
-  assert(std::isfinite(value));
-  assert(value > 0);
+      public:
+        explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
 
-  //
+        iteration_proxy_internal &operator*() {
+          return *this;
+        }
 
-  static_assert(std::numeric_limits<FloatType>::is_iec559,
-                "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
+        iteration_proxy_internal &operator++() {
+          ++anchor;
+          ++array_index;
 
-  constexpr int kPrecision = std::numeric_limits<FloatType>::digits;
-  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent-1+(kPrecision-1);
-  constexpr int kMinExp = 1-kBias;
-  constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision-1);
+          return *this;
+        }
 
-  using bits_type = typename std::conditional<kPrecision == 24, uint32_t, uint64_t>::type;
+        bool operator!=(const iteration_proxy_internal &o) const noexcept {
+          return anchor != o.anchor;
+        }
 
-  const uint64_t bits = reinterpret_bits<bits_type>(value);
-  const uint64_t E = bits >> (kPrecision-1);
-  const uint64_t F = bits & (kHiddenBit-1);
+        std::string key() const {
+          assert(anchor.m_object != nullptr);
 
-  const bool is_denormal = (E == 0);
-  const diyfp v = is_denormal
-                  ? diyfp(F, kMinExp)
-                  : diyfp(F+kHiddenBit, static_cast<int>(E)-kBias);
+          switch(anchor.m_object->type()) {
+            case value_t::array:
+              return std::to_string(array_index);
 
-  //
+            case value_t::object:
+              return anchor.key();
 
-  //
+            default:
+              return "";
+          }
+        }
 
-  //
+        typename IteratorType::reference value() const {
+          return anchor.value();
+        }
+      };
 
-  //
+      typename IteratorType::reference container;
 
-  //
+    public:
+      explicit iteration_proxy(typename IteratorType::reference cont) noexcept
+          : container(cont) {}
 
-  //
+      iteration_proxy_internal begin() noexcept {
+        return iteration_proxy_internal(container.begin());
+      }
 
-  const bool lower_boundary_is_closer = (F == 0 and E > 1);
-  const diyfp m_plus = diyfp(2 * v.f+1, v.e-1);
-  const diyfp m_minus = lower_boundary_is_closer
-                        ? diyfp(4 * v.f-1, v.e-2)
-                        : diyfp(2 * v.f-1, v.e-1);
+      iteration_proxy_internal end() noexcept {
+        return iteration_proxy_internal(container.end());
+      }
+    };
+  }
+}
 
-  const diyfp w_plus = diyfp::normalize(m_plus);
+namespace nlohmann {
+  namespace detail {
+    template<typename Base>
+    class json_reverse_iterator : public std::reverse_iterator<Base> {
+    public:
+      using difference_type = std::ptrdiff_t;
 
-  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
+      using base_iterator = std::reverse_iterator<Base>;
 
-  return {diyfp::normalize(v), w_minus, w_plus};
-}
+      using reference = typename Base::reference;
 
-//
+      json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
+          : base_iterator(it) {}
 
-//
+      json_reverse_iterator(const base_iterator &it) noexcept : base_iterator(it) {}
 
-//
+      json_reverse_iterator const operator++(int) {
+        return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
+      }
 
-//
+      json_reverse_iterator &operator++() {
+        return static_cast<json_reverse_iterator &>(base_iterator::operator++());
+      }
 
-//
+      json_reverse_iterator const operator--(int) {
+        return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
+      }
 
-//
+      json_reverse_iterator &operator--() {
+        return static_cast<json_reverse_iterator &>(base_iterator::operator--());
+      }
 
-//
+      json_reverse_iterator &operator+=(difference_type i) {
+        return static_cast<json_reverse_iterator &>(base_iterator::operator+=(i));
+      }
 
-//
+      json_reverse_iterator operator+(difference_type i) const {
+        return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
+      }
 
-//
+      json_reverse_iterator operator-(difference_type i) const {
+        return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
+      }
 
-//
+      difference_type operator-(const json_reverse_iterator &other) const {
+        return base_iterator(*this)-base_iterator(other);
+      }
 
-//
+      reference operator[](difference_type n) const {
+        return *(this->operator+(n));
+      }
 
-//
+      auto key() const -> decltype(std::declval<Base>().key()) {
+        auto it = --this->base();
+        return it.key();
+      }
 
-//
+      reference value() const {
+        auto it = --this->base();
+        return it.operator*();
+      }
+    };
+  }
+}
 
-//
+#include <ostream>
 
-//
+namespace nlohmann {
+  namespace detail {
+    template<typename CharType>
+    struct output_adapter_protocol {
+      virtual void write_character(CharType c) = 0;
 
-//
+      virtual void write_characters(const CharType *s, std::size_t length) = 0;
 
-//
+      virtual ~output_adapter_protocol() = default;
+    };
 
-//
+    template<typename CharType>
+    using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
 
-//
+    template<typename CharType>
+    class output_vector_adapter : public output_adapter_protocol<CharType> {
+    public:
+      explicit output_vector_adapter(std::vector<CharType> &vec) : v(vec) {}
 
-//
+      void write_character(CharType c) override {
+        v.push_back(c);
+      }
 
-constexpr int kAlpha = -60;
-constexpr int kGamma = -32;
+      void write_characters(const CharType *s, std::size_t length) override {
+        std::copy(s, s+length, std::back_inserter(v));
+      }
 
-struct cached_power {
-  uint64_t f;
-  int e;
-  int k;
-};
+    private:
+      std::vector<CharType> &v;
+    };
 
-inline cached_power get_cached_power_for_binary_exponent(int e) {
-  //
+    template<typename CharType>
+    class output_stream_adapter : public output_adapter_protocol<CharType> {
+    public:
+      explicit output_stream_adapter(std::basic_ostream<CharType> &s) : stream(s) {}
 
-  //
+      void write_character(CharType c) override {
+        stream.put(c);
+      }
 
-  //
+      void write_characters(const CharType *s, std::size_t length) override {
+        stream.write(s, static_cast<std::streamsize>(length));
+      }
 
-  //
+    private:
+      std::basic_ostream<CharType> &stream;
+    };
 
-  //
+    template<typename CharType, typename StringType = std::basic_string<CharType>>
+    class output_string_adapter : public output_adapter_protocol<CharType> {
+    public:
+      explicit output_string_adapter(StringType &s) : str(s) {}
 
-  //
+      void write_character(CharType c) override {
+        str.push_back(c);
+      }
 
-  //
+      void write_characters(const CharType *s, std::size_t length) override {
+        str.append(s, length);
+      }
 
-  //
+    private:
+      StringType &str;
+    };
 
-  //
+    template<typename CharType, typename StringType = std::basic_string<CharType>>
+    class output_adapter {
+    public:
+      output_adapter(std::vector<CharType> &vec)
+          : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
 
-  //
+      output_adapter(std::basic_ostream<CharType> &s)
+          : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
 
-  //
+      output_adapter(StringType &s)
+          : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
 
-  //
+      operator output_adapter_t<CharType>() {
+        return oa;
+      }
 
-  //
+    private:
+      output_adapter_t<CharType> oa = nullptr;
+    };
+  }
+}
 
-  constexpr int kCachedPowersSize = 79;
-  constexpr int kCachedPowersMinDecExp = -300;
-  constexpr int kCachedPowersDecStep = 8;
+#include <cstdio>
 
-  static constexpr cached_power kCachedPowers[] =
-      {
-          {0xAB70FE17C79AC6CA, -1060, -300},
-          {0xFF77B1FCBEBCDC4F, -1034, -292},
-          {0xBE5691EF416BD60C, -1007, -284},
-          {0x8DD01FAD907FFC3C, -980,  -276},
-          {0xD3515C2831559A83, -954,  -268},
-          {0x9D71AC8FADA6C9B5, -927,  -260},
-          {0xEA9C227723EE8BCB, -901,  -252},
-          {0xAECC49914078536D, -874,  -244},
-          {0x823C12795DB6CE57, -847,  -236},
-          {0xC21094364DFB5637, -821,  -228},
-          {0x9096EA6F3848984F, -794,  -220},
-          {0xD77485CB25823AC7, -768,  -212},
-          {0xA086CFCD97BF97F4, -741,  -204},
-          {0xEF340A98172AACE5, -715,  -196},
-          {0xB23867FB2A35B28E, -688,  -188},
-          {0x84C8D4DFD2C63F3B, -661,  -180},
-          {0xC5DD44271AD3CDBA, -635,  -172},
-          {0x936B9FCEBB25C996, -608,  -164},
-          {0xDBAC6C247D62A584, -582,  -156},
-          {0xA3AB66580D5FDAF6, -555,  -148},
-          {0xF3E2F893DEC3F126, -529,  -140},
-          {0xB5B5ADA8AAFF80B8, -502,  -132},
-          {0x87625F056C7C4A8B, -475,  -124},
-          {0xC9BCFF6034C13053, -449,  -116},
-          {0x964E858C91BA2655, -422,  -108},
-          {0xDFF9772470297EBD, -396,  -100},
-          {0xA6DFBD9FB8E5B88F, -369,  -92},
-          {0xF8A95FCF88747D94, -343,  -84},
-          {0xB94470938FA89BCF, -316,  -76},
-          {0x8A08F0F8BF0F156B, -289,  -68},
-          {0xCDB02555653131B6, -263,  -60},
-          {0x993FE2C6D07B7FAC, -236,  -52},
-          {0xE45C10C42A2B3B06, -210,  -44},
-          {0xAA242499697392D3, -183,  -36},
-          {0xFD87B5F28300CA0E, -157,  -28},
-          {0xBCE5086492111AEB, -130,  -20},
-          {0x8CBCCC096F5088CC, -103,  -12},
-          {0xD1B71758E219652C, -77,   -4},
-          {0x9C40000000000000, -50,   4},
-          {0xE8D4A51000000000, -24,   12},
-          {0xAD78EBC5AC620000, 3,     20},
-          {0x813F3978F8940984, 30,    28},
-          {0xC097CE7BC90715B3, 56,    36},
-          {0x8F7E32CE7BEA5C70, 83,    44},
-          {0xD5D238A4ABE98068, 109,   52},
-          {0x9F4F2726179A2245, 136,   60},
-          {0xED63A231D4C4FB27, 162,   68},
-          {0xB0DE65388CC8ADA8, 189,   76},
-          {0x83C7088E1AAB65DB, 216,   84},
-          {0xC45D1DF942711D9A, 242,   92},
-          {0x924D692CA61BE758, 269,   100},
-          {0xDA01EE641A708DEA, 295,   108},
-          {0xA26DA3999AEF774A, 322,   116},
-          {0xF209787BB47D6B85, 348,   124},
-          {0xB454E4A179DD1877, 375,   132},
-          {0x865B86925B9BC5C2, 402,   140},
-          {0xC83553C5C8965D3D, 428,   148},
-          {0x952AB45CFA97A0B3, 455,   156},
-          {0xDE469FBD99A05FE3, 481,   164},
-          {0xA59BC234DB398C25, 508,   172},
-          {0xF6C69A72A3989F5C, 534,   180},
-          {0xB7DCBF5354E9BECE, 561,   188},
-          {0x88FCF317F22241E2, 588,   196},
-          {0xCC20CE9BD35C78A5, 614,   204},
-          {0x98165AF37B2153DF, 641,   212},
-          {0xE2A0B5DC971F303A, 667,   220},
-          {0xA8D9D1535CE3B396, 694,   228},
-          {0xFB9B7CD9A4A7443C, 720,   236},
-          {0xBB764C4CA7A44410, 747,   244},
-          {0x8BAB8EEFB6409C1A, 774,   252},
-          {0xD01FEF10A657842C, 800,   260},
-          {0x9B10A4E5E9913129, 827,   268},
-          {0xE7109BFBA19C0C9D, 853,   276},
-          {0xAC2820D9623BF429, 880,   284},
-          {0x80444B5E7AA7CF85, 907,   292},
-          {0xBF21E44003ACDD2D, 933,   300},
-          {0x8E679C2F5E44FF8F, 960,   308},
-          {0xD433179D9C8CB841, 986,   316},
-          {0x9E19DB92B4E31BA9, 1013,  324},
-      };
+namespace nlohmann {
+  namespace detail {
+    namespace dtoa_impl {
+      template<typename Target, typename Source>
+      Target reinterpret_bits(const Source source) {
+        static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
 
-  assert(e >= -1500);
-  assert(e <= 1500);
-  const int f = kAlpha-e-1;
-  const int k = (f * 78913) / (1 << 18)+(f > 0);
+        Target target;
+        std::memcpy(&target, &source, sizeof(Source));
+        return target;
+      }
 
-  const int index = (-kCachedPowersMinDecExp+k+(kCachedPowersDecStep-1)) / kCachedPowersDecStep;
-  assert(index >= 0);
-  assert(index < kCachedPowersSize);
-  static_cast<void>(kCachedPowersSize);
+      struct diyfp {
+        static constexpr int kPrecision = 64;
 
-  const cached_power cached = kCachedPowers[index];
-  assert(kAlpha <= cached.e+e+64);
-  assert(kGamma >= cached.e+e+64);
+        uint64_t f;
+        int e;
 
-  return cached;
-}
+        constexpr diyfp() noexcept : f(0), e(0) {}
 
-inline int find_largest_pow10(const uint32_t n, uint32_t &pow10) {
-  if(n >= 1000000000) {
-    pow10 = 1000000000;
-    return 10;
-  } else if(n >= 100000000) {
-    pow10 = 100000000;
-    return 9;
-  } else if(n >= 10000000) {
-    pow10 = 10000000;
-    return 8;
-  } else if(n >= 1000000) {
-    pow10 = 1000000;
-    return 7;
-  } else if(n >= 100000) {
-    pow10 = 100000;
-    return 6;
-  } else if(n >= 10000) {
-    pow10 = 10000;
-    return 5;
-  } else if(n >= 1000) {
-    pow10 = 1000;
-    return 4;
-  } else if(n >= 100) {
-    pow10 = 100;
-    return 3;
-  } else if(n >= 10) {
-    pow10 = 10;
-    return 2;
-  } else {
-    pow10 = 1;
-    return 1;
-  }
-}
+        constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
 
-inline void grisu2_round(char *buf, int len, uint64_t dist, uint64_t delta,
-                         uint64_t rest, uint64_t ten_k) {
-  assert(len >= 1);
-  assert(dist <= delta);
-  assert(rest <= delta);
-  assert(ten_k > 0);
+        static diyfp sub(const diyfp &x, const diyfp &y) noexcept {
+          assert(x.e == y.e);
+          assert(x.f >= y.f);
 
-  //
+          return diyfp(x.f-y.f, x.e);
+        }
 
-  //
+        static diyfp mul(const diyfp &x, const diyfp &y) noexcept {
+          static_assert(kPrecision == 64, "internal error");
 
-  while(rest < dist
-        and delta-rest >= ten_k
-        and (rest+ten_k < dist or dist-rest > rest+ten_k-dist)) {
-    assert(buf[len-1] != '0');
-    buf[len-1]--;
-    rest += ten_k;
-  }
-}
+          const uint64_t u_lo = x.f & 0xFFFFFFFF;
+          const uint64_t u_hi = x.f >> 32;
+          const uint64_t v_lo = y.f & 0xFFFFFFFF;
+          const uint64_t v_hi = y.f >> 32;
 
-inline void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent,
-                             diyfp M_minus, diyfp w, diyfp M_plus) {
-  static_assert(kAlpha >= -60, "internal error");
-  static_assert(kGamma <= -32, "internal error");
+          const uint64_t p0 = u_lo * v_lo;
+          const uint64_t p1 = u_lo * v_hi;
+          const uint64_t p2 = u_hi * v_lo;
+          const uint64_t p3 = u_hi * v_hi;
 
-  //
+          const uint64_t p0_hi = p0 >> 32;
+          const uint64_t p1_lo = p1 & 0xFFFFFFFF;
+          const uint64_t p1_hi = p1 >> 32;
+          const uint64_t p2_lo = p2 & 0xFFFFFFFF;
+          const uint64_t p2_hi = p2 >> 32;
 
-  //
+          uint64_t Q = p0_hi+p1_lo+p2_lo;
 
-  assert(M_plus.e >= kAlpha);
-  assert(M_plus.e <= kGamma);
+          Q += uint64_t{1} << (64-32-1);
 
-  uint64_t delta = diyfp::sub(M_plus, M_minus).f;
-  uint64_t dist = diyfp::sub(M_plus, w).f;
+          const uint64_t h = p3+p2_hi+p1_hi+(Q >> 32);
 
-  //
+          return diyfp(h, x.e+y.e+64);
+        }
 
-  const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
+        static diyfp normalize(diyfp x) noexcept {
+          assert(x.f != 0);
 
-  uint32_t p1 = static_cast<uint32_t>(M_plus.f >> -one.e);
-  uint64_t p2 = M_plus.f & (one.f-1);
+          while((x.f >> 63) == 0) {
+            x.f <<= 1;
+            x.e--;
+          }
 
-  //
+          return x;
+        }
 
-  assert(p1 > 0);
+        static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept {
+          const int delta = x.e-target_exponent;
 
-  uint32_t pow10;
-  const int k = find_largest_pow10(p1, pow10);
+          assert(delta >= 0);
+          assert(((x.f << delta) >> delta) == x.f);
 
-  //
+          return diyfp(x.f << delta, target_exponent);
+        }
+      };
 
-  //
+      struct boundaries {
+        diyfp w;
+        diyfp minus;
+        diyfp plus;
+      };
 
-  //
+      template<typename FloatType>
+      boundaries compute_boundaries(FloatType value) {
+        assert(std::isfinite(value));
+        assert(value > 0);
 
-  //
+        static_assert(std::numeric_limits<FloatType>::is_iec559,
+                      "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
 
-  //
+        constexpr int kPrecision = std::numeric_limits<FloatType>::digits;
+        constexpr int kBias = std::numeric_limits<FloatType>::max_exponent-1+(kPrecision-1);
+        constexpr int kMinExp = 1-kBias;
+        constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision-1);
 
-  //
+        using bits_type = typename std::conditional<kPrecision == 24, uint32_t, uint64_t>::type;
 
-  int n = k;
-  while(n > 0) {
-    //
-    const uint32_t d = p1 / pow10;
-    const uint32_t r = p1 % pow10;
-    //
+        const uint64_t bits = reinterpret_bits<bits_type>(value);
+        const uint64_t E = bits >> (kPrecision-1);
+        const uint64_t F = bits & (kHiddenBit-1);
 
-    //
-    assert(d <= 9);
-    buffer[length++] = static_cast<char>('0'+d);
-    //
+        const bool is_denormal = (E == 0);
+        const diyfp v = is_denormal
+                        ? diyfp(F, kMinExp)
+                        : diyfp(F+kHiddenBit, static_cast<int>(E)-kBias);
 
-    //
-    p1 = r;
-    n--;
-    //
+        const bool lower_boundary_is_closer = (F == 0 and E > 1);
+        const diyfp m_plus = diyfp(2 * v.f+1, v.e-1);
+        const diyfp m_minus = lower_boundary_is_closer
+                              ? diyfp(4 * v.f-1, v.e-2)
+                              : diyfp(2 * v.f-1, v.e-1);
 
-    //
+        const diyfp w_plus = diyfp::normalize(m_plus);
 
-    //
+        const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
 
-    //
+        return {diyfp::normalize(v), w_minus, w_plus};
+      }
 
-    const uint64_t rest = (uint64_t{p1} << -one.e)+p2;
-    if(rest <= delta) {
-      decimal_exponent += n;
+      constexpr int kAlpha = -60;
+      constexpr int kGamma = -32;
 
-      //
+      struct cached_power {
+        uint64_t f;
+        int e;
+        int k;
+      };
 
-      //
+      inline cached_power get_cached_power_for_binary_exponent(int e) {
+        constexpr int kCachedPowersSize = 79;
+        constexpr int kCachedPowersMinDecExp = -300;
+        constexpr int kCachedPowersDecStep = 8;
 
-      //
-      const uint64_t ten_n = uint64_t{pow10} << -one.e;
-      grisu2_round(buffer, length, dist, delta, rest, ten_n);
+        static constexpr cached_power kCachedPowers[] =
+            {
+                {0xAB70FE17C79AC6CA, -1060, -300},
+                {0xFF77B1FCBEBCDC4F, -1034, -292},
+                {0xBE5691EF416BD60C, -1007, -284},
+                {0x8DD01FAD907FFC3C, -980,  -276},
+                {0xD3515C2831559A83, -954,  -268},
+                {0x9D71AC8FADA6C9B5, -927,  -260},
+                {0xEA9C227723EE8BCB, -901,  -252},
+                {0xAECC49914078536D, -874,  -244},
+                {0x823C12795DB6CE57, -847,  -236},
+                {0xC21094364DFB5637, -821,  -228},
+                {0x9096EA6F3848984F, -794,  -220},
+                {0xD77485CB25823AC7, -768,  -212},
+                {0xA086CFCD97BF97F4, -741,  -204},
+                {0xEF340A98172AACE5, -715,  -196},
+                {0xB23867FB2A35B28E, -688,  -188},
+                {0x84C8D4DFD2C63F3B, -661,  -180},
+                {0xC5DD44271AD3CDBA, -635,  -172},
+                {0x936B9FCEBB25C996, -608,  -164},
+                {0xDBAC6C247D62A584, -582,  -156},
+                {0xA3AB66580D5FDAF6, -555,  -148},
+                {0xF3E2F893DEC3F126, -529,  -140},
+                {0xB5B5ADA8AAFF80B8, -502,  -132},
+                {0x87625F056C7C4A8B, -475,  -124},
+                {0xC9BCFF6034C13053, -449,  -116},
+                {0x964E858C91BA2655, -422,  -108},
+                {0xDFF9772470297EBD, -396,  -100},
+                {0xA6DFBD9FB8E5B88F, -369,  -92},
+                {0xF8A95FCF88747D94, -343,  -84},
+                {0xB94470938FA89BCF, -316,  -76},
+                {0x8A08F0F8BF0F156B, -289,  -68},
+                {0xCDB02555653131B6, -263,  -60},
+                {0x993FE2C6D07B7FAC, -236,  -52},
+                {0xE45C10C42A2B3B06, -210,  -44},
+                {0xAA242499697392D3, -183,  -36},
+                {0xFD87B5F28300CA0E, -157,  -28},
+                {0xBCE5086492111AEB, -130,  -20},
+                {0x8CBCCC096F5088CC, -103,  -12},
+                {0xD1B71758E219652C, -77,   -4},
+                {0x9C40000000000000, -50,   4},
+                {0xE8D4A51000000000, -24,   12},
+                {0xAD78EBC5AC620000, 3,     20},
+                {0x813F3978F8940984, 30,    28},
+                {0xC097CE7BC90715B3, 56,    36},
+                {0x8F7E32CE7BEA5C70, 83,    44},
+                {0xD5D238A4ABE98068, 109,   52},
+                {0x9F4F2726179A2245, 136,   60},
+                {0xED63A231D4C4FB27, 162,   68},
+                {0xB0DE65388CC8ADA8, 189,   76},
+                {0x83C7088E1AAB65DB, 216,   84},
+                {0xC45D1DF942711D9A, 242,   92},
+                {0x924D692CA61BE758, 269,   100},
+                {0xDA01EE641A708DEA, 295,   108},
+                {0xA26DA3999AEF774A, 322,   116},
+                {0xF209787BB47D6B85, 348,   124},
+                {0xB454E4A179DD1877, 375,   132},
+                {0x865B86925B9BC5C2, 402,   140},
+                {0xC83553C5C8965D3D, 428,   148},
+                {0x952AB45CFA97A0B3, 455,   156},
+                {0xDE469FBD99A05FE3, 481,   164},
+                {0xA59BC234DB398C25, 508,   172},
+                {0xF6C69A72A3989F5C, 534,   180},
+                {0xB7DCBF5354E9BECE, 561,   188},
+                {0x88FCF317F22241E2, 588,   196},
+                {0xCC20CE9BD35C78A5, 614,   204},
+                {0x98165AF37B2153DF, 641,   212},
+                {0xE2A0B5DC971F303A, 667,   220},
+                {0xA8D9D1535CE3B396, 694,   228},
+                {0xFB9B7CD9A4A7443C, 720,   236},
+                {0xBB764C4CA7A44410, 747,   244},
+                {0x8BAB8EEFB6409C1A, 774,   252},
+                {0xD01FEF10A657842C, 800,   260},
+                {0x9B10A4E5E9913129, 827,   268},
+                {0xE7109BFBA19C0C9D, 853,   276},
+                {0xAC2820D9623BF429, 880,   284},
+                {0x80444B5E7AA7CF85, 907,   292},
+                {0xBF21E44003ACDD2D, 933,   300},
+                {0x8E679C2F5E44FF8F, 960,   308},
+                {0xD433179D9C8CB841, 986,   316},
+                {0x9E19DB92B4E31BA9, 1013,  324},
+            };
+
+        assert(e >= -1500);
+        assert(e <= 1500);
+        const int f = kAlpha-e-1;
+        const int k = (f * 78913) / (1 << 18)+(f > 0);
+
+        const int index = (-kCachedPowersMinDecExp+k+(kCachedPowersDecStep-1)) / kCachedPowersDecStep;
+        assert(index >= 0);
+        assert(index < kCachedPowersSize);
+        static_cast<void>(kCachedPowersSize);
+
+        const cached_power cached = kCachedPowers[index];
+        assert(kAlpha <= cached.e+e+64);
+        assert(kGamma >= cached.e+e+64);
+
+        return cached;
+      }
+
+      inline int find_largest_pow10(const uint32_t n, uint32_t &pow10) {
+        if(n >= 1000000000) {
+          pow10 = 1000000000;
+          return 10;
+        } else if(n >= 100000000) {
+          pow10 = 100000000;
+          return 9;
+        } else if(n >= 10000000) {
+          pow10 = 10000000;
+          return 8;
+        } else if(n >= 1000000) {
+          pow10 = 1000000;
+          return 7;
+        } else if(n >= 100000) {
+          pow10 = 100000;
+          return 6;
+        } else if(n >= 10000) {
+          pow10 = 10000;
+          return 5;
+        } else if(n >= 1000) {
+          pow10 = 1000;
+          return 4;
+        } else if(n >= 100) {
+          pow10 = 100;
+          return 3;
+        } else if(n >= 10) {
+          pow10 = 10;
+          return 2;
+        } else {
+          pow10 = 1;
+          return 1;
+        }
+      }
 
-      return;
-    }
+      inline void grisu2_round(char *buf, int len, uint64_t dist, uint64_t delta,
+                               uint64_t rest, uint64_t ten_k) {
+        assert(len >= 1);
+        assert(dist <= delta);
+        assert(rest <= delta);
+        assert(ten_k > 0);
 
-    pow10 /= 10;
-    //
+        while(rest < dist
+              and delta-rest >= ten_k
+              and (rest+ten_k < dist or dist-rest > rest+ten_k-dist)) {
+          assert(buf[len-1] != '0');
+          buf[len-1]--;
+          rest += ten_k;
+        }
+      }
 
-  }
+      inline void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent,
+                                   diyfp M_minus, diyfp w, diyfp M_plus) {
+        static_assert(kAlpha >= -60, "internal error");
+        static_assert(kGamma <= -32, "internal error");
 
-  //
+        assert(M_plus.e >= kAlpha);
+        assert(M_plus.e <= kGamma);
 
-  //
+        uint64_t delta = diyfp::sub(M_plus, M_minus).f;
+        uint64_t dist = diyfp::sub(M_plus, w).f;
 
-  //
+        const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
 
-  //
+        uint32_t p1 = static_cast<uint32_t>(M_plus.f >> -one.e);
+        uint64_t p2 = M_plus.f & (one.f-1);
 
-  //
+        assert(p1 > 0);
 
-  //
+        uint32_t pow10;
+        const int k = find_largest_pow10(p1, pow10);
 
-  //
+        int n = k;
+        while(n > 0) {
+          const uint32_t d = p1 / pow10;
+          const uint32_t r = p1 % pow10;
 
-  //
+          assert(d <= 9);
+          buffer[length++] = static_cast<char>('0'+d);
 
-  //
+          p1 = r;
+          n--;
 
-  //
+          const uint64_t rest = (uint64_t{p1} << -one.e)+p2;
+          if(rest <= delta) {
+            decimal_exponent += n;
 
-  //
+            const uint64_t ten_n = uint64_t{pow10} << -one.e;
+            grisu2_round(buffer, length, dist, delta, rest, ten_n);
 
-  //
+            return;
+          }
 
-  //
+          pow10 /= 10;
 
-  //
+        }
 
-  assert(p2 > delta);
+        assert(p2 > delta);
 
-  int m = 0;
-  for(;;) {
-    //
-    assert(p2 <= UINT64_MAX / 10);
-    p2 *= 10;
-    const uint64_t d = p2 >> -one.e;
-    const uint64_t r = p2 & (one.f-1);
-    //
+        int m = 0;
+        for(;;) {
+          assert(p2 <= UINT64_MAX / 10);
+          p2 *= 10;
+          const uint64_t d = p2 >> -one.e;
+          const uint64_t r = p2 & (one.f-1);
 
-    //
-    assert(d <= 9);
-    buffer[length++] = static_cast<char>('0'+d);
-    //
+          assert(d <= 9);
+          buffer[length++] = static_cast<char>('0'+d);
 
-    //
-    p2 = r;
-    m++;
-    //
+          p2 = r;
+          m++;
 
-    //
+          delta *= 10;
+          dist *= 10;
+          if(p2 <= delta) {
+            break;
+          }
+        }
 
-    delta *= 10;
-    dist *= 10;
-    if(p2 <= delta) {
-      break;
-    }
-  }
+        decimal_exponent -= m;
 
-  decimal_exponent -= m;
+        const uint64_t ten_m = one.f;
+        grisu2_round(buffer, length, dist, delta, p2, ten_m);
 
-  //
+      }
 
-  //
-  const uint64_t ten_m = one.f;
-  grisu2_round(buffer, length, dist, delta, p2, ten_m);
+      inline void grisu2(char *buf, int &len, int &decimal_exponent,
+                         diyfp m_minus, diyfp v, diyfp m_plus) {
+        assert(m_plus.e == m_minus.e);
+        assert(m_plus.e == v.e);
 
-  //
+        const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
 
-  //
+        const diyfp c_minus_k(cached.f, cached.e);
 
-  //
+        const diyfp w = diyfp::mul(v, c_minus_k);
+        const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
+        const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
 
-}
+        const diyfp M_minus(w_minus.f+1, w_minus.e);
+        const diyfp M_plus(w_plus.f-1, w_plus.e);
 
-inline void grisu2(char *buf, int &len, int &decimal_exponent,
-                   diyfp m_minus, diyfp v, diyfp m_plus) {
-  assert(m_plus.e == m_minus.e);
-  assert(m_plus.e == v.e);
+        decimal_exponent = -cached.k;
 
-  //
+        grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
+      }
 
-  //
+      template<typename FloatType>
+      void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value) {
+        static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits+3,
+                      "internal error: not enough precision");
 
-  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
+        assert(std::isfinite(value));
+        assert(value > 0);
 
-  const diyfp c_minus_k(cached.f, cached.e);
+#if 0
+        const boundaries w = compute_boundaries(static_cast<double>(value));
+#else
+        const boundaries w = compute_boundaries(value);
+#endif
 
-  const diyfp w = diyfp::mul(v, c_minus_k);
-  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
-  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
+        grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
+      }
 
-  //
+      inline char *append_exponent(char *buf, int e) {
+        assert(e > -1000);
+        assert(e < 1000);
 
-  //
+        if(e < 0) {
+          e = -e;
+          *buf++ = '-';
+        } else {
+          *buf++ = '+';
+        }
 
-  //
+        uint32_t k = static_cast<uint32_t>(e);
+        if(k < 10) {
+          *buf++ = '0';
+          *buf++ = static_cast<char>('0'+k);
+        } else if(k < 100) {
+          *buf++ = static_cast<char>('0'+k / 10);
+          k %= 10;
+          *buf++ = static_cast<char>('0'+k);
+        } else {
+          *buf++ = static_cast<char>('0'+k / 100);
+          k %= 100;
+          *buf++ = static_cast<char>('0'+k / 10);
+          k %= 10;
+          *buf++ = static_cast<char>('0'+k);
+        }
 
-  //
+        return buf;
+      }
 
-  //
+      inline char *format_buffer(char *buf, int len, int decimal_exponent,
+                                 int min_exp, int max_exp) {
+        assert(min_exp < 0);
+        assert(max_exp > 0);
 
-  //
+        const int k = len;
+        const int n = len+decimal_exponent;
 
-  const diyfp M_minus(w_minus.f+1, w_minus.e);
-  const diyfp M_plus(w_plus.f-1, w_plus.e);
+        if(k <= n and n <= max_exp) {
+          std::memset(buf+k, '0', static_cast<size_t>(n-k));
 
-  decimal_exponent = -cached.k;
+          buf[n+0] = '.';
+          buf[n+1] = '0';
+          return buf+(n+2);
+        }
 
-  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
-}
+        if(0 < n and n <= max_exp) {
+          assert(k > n);
 
-template<typename FloatType>
-void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value) {
-  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits+3,
-                "internal error: not enough precision");
+          std::memmove(buf+(n+1), buf+n, static_cast<size_t>(k-n));
+          buf[n] = '.';
+          return buf+(k+1);
+        }
 
-  assert(std::isfinite(value));
-  assert(value > 0);
+        if(min_exp < n and n <= 0) {
+          std::memmove(buf+(2+ -n), buf, static_cast<size_t>(k));
+          buf[0] = '0';
+          buf[1] = '.';
+          std::memset(buf+2, '0', static_cast<size_t>(-n));
+          return buf+(2+(-n)+k);
+        }
 
-  //
+        if(k == 1) {
+          buf += 1;
+        } else {
+          std::memmove(buf+2, buf+1, static_cast<size_t>(k-1));
+          buf[1] = '.';
+          buf += 1+k;
+        }
 
-  //
+        *buf++ = 'e';
+        return append_exponent(buf, n-1);
+      }
 
-#if 0
-  const boundaries w = compute_boundaries(static_cast<double>(value));
-#else
-  const boundaries w = compute_boundaries(value);
-#endif
+    }
 
-  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
-}
+    template<typename FloatType>
+    char *to_chars(char *first, char *last, FloatType value) {
+      static_cast<void>(last);
+      assert(std::isfinite(value));
 
-inline char *append_exponent(char *buf, int e) {
-  assert(e > -1000);
-  assert(e < 1000);
+      if(std::signbit(value)) {
+        value = -value;
+        *first++ = '-';
+      }
 
-  if(e < 0) {
-    e = -e;
-    *buf++ = '-';
-  } else {
-    *buf++ = '+';
-  }
+      if(value == 0) {
+        *first++ = '0';
 
-  uint32_t k = static_cast<uint32_t>(e);
-  if(k < 10) {
-    *buf++ = '0';
-    *buf++ = static_cast<char>('0'+k);
-  } else if(k < 100) {
-    *buf++ = static_cast<char>('0'+k / 10);
-    k %= 10;
-    *buf++ = static_cast<char>('0'+k);
-  } else {
-    *buf++ = static_cast<char>('0'+k / 100);
-    k %= 100;
-    *buf++ = static_cast<char>('0'+k / 10);
-    k %= 10;
-    *buf++ = static_cast<char>('0'+k);
-  }
+        *first++ = '.';
+        *first++ = '0';
+        return first;
+      }
 
-  return buf;
-}
+      assert(last-first >= std::numeric_limits<FloatType>::max_digits10);
 
-inline char *format_buffer(char *buf, int len, int decimal_exponent,
-                           int min_exp, int max_exp) {
-  assert(min_exp < 0);
-  assert(max_exp > 0);
+      int len = 0;
+      int decimal_exponent = 0;
+      dtoa_impl::grisu2(first, len, decimal_exponent, value);
 
-  const int k = len;
-  const int n = len+decimal_exponent;
+      assert(len <= std::numeric_limits<FloatType>::max_digits10);
 
-  if(k <= n and n <= max_exp) {
-    std::memset(buf+k, '0', static_cast<size_t>(n-k));
+      constexpr int kMinExp = -4;
 
-    buf[n+0] = '.';
-    buf[n+1] = '0';
-    return buf+(n+2);
-  }
+      constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
 
-  if(0 < n and n <= max_exp) {
-    assert(k > n);
+      assert(last-first >= kMaxExp+2);
+      assert(last-first >= 2+(-kMinExp-1)+std::numeric_limits<FloatType>::max_digits10);
+      assert(last-first >= std::numeric_limits<FloatType>::max_digits10+6);
 
-    std::memmove(buf+(n+1), buf+n, static_cast<size_t>(k-n));
-    buf[n] = '.';
-    return buf+(k+1);
-  }
+      return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
+    }
 
-  if(min_exp < n and n <= 0) {
-    std::memmove(buf+(2+ -n), buf, static_cast<size_t>(k));
-    buf[0] = '0';
-    buf[1] = '.';
-    std::memset(buf+2, '0', static_cast<size_t>(-n));
-    return buf+(2+(-n)+k);
   }
+}
 
-  if(k == 1) {
-    buf += 1;
-  } else {
-    std::memmove(buf+2, buf+1, static_cast<size_t>(k-1));
-    buf[1] = '.';
-    buf += 1+k;
-  }
+namespace nlohmann {
+  namespace detail {
+    template<typename BasicJsonType>
+    class serializer {
+      using string_t = typename BasicJsonType::string_t;
+      using number_float_t = typename BasicJsonType::number_float_t;
+      using number_integer_t = typename BasicJsonType::number_integer_t;
+      using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+      static constexpr uint8_t UTF8_ACCEPT = 0;
+      static constexpr uint8_t UTF8_REJECT = 1;
+
+    public:
+      serializer(output_adapter_t<char> s, const char ichar)
+          : o(std::move(s)), loc(std::localeconv()),
+            thousands_sep(loc->thousands_sep == nullptr ? '\0' : *(loc->thousands_sep)),
+            decimal_point(loc->decimal_point == nullptr ? '\0' : *(loc->decimal_point)),
+            indent_char(ichar), indent_string(512, indent_char) {}
+
+      serializer(const serializer &) = delete;
+
+      serializer &operator=(const serializer &) = delete;
+
+      void dump(const BasicJsonType &val, const bool pretty_print,
+                const bool ensure_ascii,
+                const unsigned int indent_step,
+                const unsigned int current_indent = 0) {
+        switch(val.m_type) {
+          case value_t::object: {
+            if(val.m_value.object->empty()) {
+              o->write_characters("{}", 2);
+              return;
+            }
 
-  *buf++ = 'e';
-  return append_exponent(buf, n-1);
-}
+            if(pretty_print) {
+              o->write_characters("{\n", 2);
 
-}
+              const auto new_indent = current_indent+indent_step;
+              if(JSON_UNLIKELY(indent_string.size() < new_indent)) {
+                indent_string.resize(indent_string.size() * 2, ' ');
+              }
 
-template<typename FloatType>
-char *to_chars(char *first, char *last, FloatType value) {
-  static_cast<void>(last);
-  assert(std::isfinite(value));
+              auto i = val.m_value.object->cbegin();
+              for(std::size_t cnt = 0; cnt < val.m_value.object->size()-1; ++cnt, ++i) {
+                o->write_characters(indent_string.c_str(), new_indent);
+                o->write_character('\"');
+                dump_escaped(i->first, ensure_ascii);
+                o->write_characters("\": ", 3);
+                dump(i->second, true, ensure_ascii, indent_step, new_indent);
+                o->write_characters(",\n", 2);
+              }
 
-  if(std::signbit(value)) {
-    value = -value;
-    *first++ = '-';
-  }
+              assert(i != val.m_value.object->cend());
+              assert(std::next(i) == val.m_value.object->cend());
+              o->write_characters(indent_string.c_str(), new_indent);
+              o->write_character('\"');
+              dump_escaped(i->first, ensure_ascii);
+              o->write_characters("\": ", 3);
+              dump(i->second, true, ensure_ascii, indent_step, new_indent);
+
+              o->write_character('\n');
+              o->write_characters(indent_string.c_str(), current_indent);
+              o->write_character('}');
+            } else {
+              o->write_character('{');
+
+              auto i = val.m_value.object->cbegin();
+              for(std::size_t cnt = 0; cnt < val.m_value.object->size()-1; ++cnt, ++i) {
+                o->write_character('\"');
+                dump_escaped(i->first, ensure_ascii);
+                o->write_characters("\":", 2);
+                dump(i->second, false, ensure_ascii, indent_step, current_indent);
+                o->write_character(',');
+              }
 
-  if(value == 0) {
-    *first++ = '0';
+              assert(i != val.m_value.object->cend());
+              assert(std::next(i) == val.m_value.object->cend());
+              o->write_character('\"');
+              dump_escaped(i->first, ensure_ascii);
+              o->write_characters("\":", 2);
+              dump(i->second, false, ensure_ascii, indent_step, current_indent);
 
-    *first++ = '.';
-    *first++ = '0';
-    return first;
-  }
+              o->write_character('}');
+            }
 
-  assert(last-first >= std::numeric_limits<FloatType>::max_digits10);
+            return;
+          }
 
-  int len = 0;
-  int decimal_exponent = 0;
-  dtoa_impl::grisu2(first, len, decimal_exponent, value);
+          case value_t::array: {
+            if(val.m_value.array->empty()) {
+              o->write_characters("[]", 2);
+              return;
+            }
 
-  assert(len <= std::numeric_limits<FloatType>::max_digits10);
+            if(pretty_print) {
+              o->write_characters("[\n", 2);
 
-  constexpr int kMinExp = -4;
+              const auto new_indent = current_indent+indent_step;
+              if(JSON_UNLIKELY(indent_string.size() < new_indent)) {
+                indent_string.resize(indent_string.size() * 2, ' ');
+              }
 
-  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
+              for(auto i = val.m_value.array->cbegin();
+                  i != val.m_value.array->cend()-1; ++i) {
+                o->write_characters(indent_string.c_str(), new_indent);
+                dump(*i, true, ensure_ascii, indent_step, new_indent);
+                o->write_characters(",\n", 2);
+              }
 
-  assert(last-first >= kMaxExp+2);
-  assert(last-first >= 2+(-kMinExp-1)+std::numeric_limits<FloatType>::max_digits10);
-  assert(last-first >= std::numeric_limits<FloatType>::max_digits10+6);
+              assert(not val.m_value.array->empty());
+              o->write_characters(indent_string.c_str(), new_indent);
+              dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
 
-  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
-}
+              o->write_character('\n');
+              o->write_characters(indent_string.c_str(), current_indent);
+              o->write_character(']');
+            } else {
+              o->write_character('[');
 
-}
-}
+              for(auto i = val.m_value.array->cbegin();
+                  i != val.m_value.array->cend()-1; ++i) {
+                dump(*i, false, ensure_ascii, indent_step, current_indent);
+                o->write_character(',');
+              }
 
-namespace nlohmann {
-namespace detail {
-template<typename BasicJsonType>
-class serializer {
-  using string_t = typename BasicJsonType::string_t;
-  using number_float_t = typename BasicJsonType::number_float_t;
-  using number_integer_t = typename BasicJsonType::number_integer_t;
-  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
-  static constexpr uint8_t UTF8_ACCEPT = 0;
-  static constexpr uint8_t UTF8_REJECT = 1;
-
-public:
-  serializer(output_adapter_t<char> s, const char ichar)
-      : o(std::move(s)), loc(std::localeconv()),
-        thousands_sep(loc->thousands_sep == nullptr ? '\0' : *(loc->thousands_sep)),
-        decimal_point(loc->decimal_point == nullptr ? '\0' : *(loc->decimal_point)),
-        indent_char(ichar), indent_string(512, indent_char) {}
-
-  serializer(const serializer &) = delete;
-
-  serializer &operator=(const serializer &) = delete;
-
-  void dump(const BasicJsonType &val, const bool pretty_print,
-            const bool ensure_ascii,
-            const unsigned int indent_step,
-            const unsigned int current_indent = 0) {
-    switch(val.m_type) {
-      case value_t::object: {
-        if(val.m_value.object->empty()) {
-          o->write_characters("{}", 2);
-          return;
-        }
+              assert(not val.m_value.array->empty());
+              dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
 
-        if(pretty_print) {
-          o->write_characters("{\n", 2);
+              o->write_character(']');
+            }
 
-          const auto new_indent = current_indent+indent_step;
-          if(JSON_UNLIKELY(indent_string.size() < new_indent)) {
-            indent_string.resize(indent_string.size() * 2, ' ');
+            return;
           }
 
-          auto i = val.m_value.object->cbegin();
-          for(std::size_t cnt = 0; cnt < val.m_value.object->size()-1; ++cnt, ++i) {
-            o->write_characters(indent_string.c_str(), new_indent);
+          case value_t::string: {
             o->write_character('\"');
-            dump_escaped(i->first, ensure_ascii);
-            o->write_characters("\": ", 3);
-            dump(i->second, true, ensure_ascii, indent_step, new_indent);
-            o->write_characters(",\n", 2);
-          }
-
-          assert(i != val.m_value.object->cend());
-          assert(std::next(i) == val.m_value.object->cend());
-          o->write_characters(indent_string.c_str(), new_indent);
-          o->write_character('\"');
-          dump_escaped(i->first, ensure_ascii);
-          o->write_characters("\": ", 3);
-          dump(i->second, true, ensure_ascii, indent_step, new_indent);
-
-          o->write_character('\n');
-          o->write_characters(indent_string.c_str(), current_indent);
-          o->write_character('}');
-        } else {
-          o->write_character('{');
-
-          auto i = val.m_value.object->cbegin();
-          for(std::size_t cnt = 0; cnt < val.m_value.object->size()-1; ++cnt, ++i) {
+            dump_escaped(*val.m_value.string, ensure_ascii);
             o->write_character('\"');
-            dump_escaped(i->first, ensure_ascii);
-            o->write_characters("\":", 2);
-            dump(i->second, false, ensure_ascii, indent_step, current_indent);
-            o->write_character(',');
+            return;
           }
 
-          assert(i != val.m_value.object->cend());
-          assert(std::next(i) == val.m_value.object->cend());
-          o->write_character('\"');
-          dump_escaped(i->first, ensure_ascii);
-          o->write_characters("\":", 2);
-          dump(i->second, false, ensure_ascii, indent_step, current_indent);
-
-          o->write_character('}');
-        }
-
-        return;
-      }
-
-      case value_t::array: {
-        if(val.m_value.array->empty()) {
-          o->write_characters("[]", 2);
-          return;
-        }
-
-        if(pretty_print) {
-          o->write_characters("[\n", 2);
-
-          const auto new_indent = current_indent+indent_step;
-          if(JSON_UNLIKELY(indent_string.size() < new_indent)) {
-            indent_string.resize(indent_string.size() * 2, ' ');
+          case value_t::boolean: {
+            if(val.m_value.boolean) {
+              o->write_characters("true", 4);
+            } else {
+              o->write_characters("false", 5);
+            }
+            return;
           }
 
-          for(auto i = val.m_value.array->cbegin();
-              i != val.m_value.array->cend()-1; ++i) {
-            o->write_characters(indent_string.c_str(), new_indent);
-            dump(*i, true, ensure_ascii, indent_step, new_indent);
-            o->write_characters(",\n", 2);
+          case value_t::number_integer: {
+            dump_integer(val.m_value.number_integer);
+            return;
           }
 
-          assert(not val.m_value.array->empty());
-          o->write_characters(indent_string.c_str(), new_indent);
-          dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
-
-          o->write_character('\n');
-          o->write_characters(indent_string.c_str(), current_indent);
-          o->write_character(']');
-        } else {
-          o->write_character('[');
-
-          for(auto i = val.m_value.array->cbegin();
-              i != val.m_value.array->cend()-1; ++i) {
-            dump(*i, false, ensure_ascii, indent_step, current_indent);
-            o->write_character(',');
+          case value_t::number_unsigned: {
+            dump_integer(val.m_value.number_unsigned);
+            return;
           }
 
-          assert(not val.m_value.array->empty());
-          dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
-
-          o->write_character(']');
-        }
-
-        return;
-      }
+          case value_t::number_float: {
+            dump_float(val.m_value.number_float);
+            return;
+          }
 
-      case value_t::string: {
-        o->write_character('\"');
-        dump_escaped(*val.m_value.string, ensure_ascii);
-        o->write_character('\"');
-        return;
-      }
+          case value_t::discarded: {
+            o->write_characters("<discarded>", 11);
+            return;
+          }
 
-      case value_t::boolean: {
-        if(val.m_value.boolean) {
-          o->write_characters("true", 4);
-        } else {
-          o->write_characters("false", 5);
+          case value_t::null: {
+            o->write_characters("null", 4);
+            return;
+          }
         }
-        return;
       }
 
-      case value_t::number_integer: {
-        dump_integer(val.m_value.number_integer);
-        return;
-      }
-
-      case value_t::number_unsigned: {
-        dump_integer(val.m_value.number_unsigned);
-        return;
-      }
+    private:
+      void dump_escaped(const string_t &s, const bool ensure_ascii) {
+        uint32_t codepoint;
+        uint8_t state = UTF8_ACCEPT;
+        std::size_t bytes = 0;
 
-      case value_t::number_float: {
-        dump_float(val.m_value.number_float);
-        return;
-      }
+        for(std::size_t i = 0; i < s.size(); ++i) {
+          const auto byte = static_cast<uint8_t>(s[i]);
 
-      case value_t::discarded: {
-        o->write_characters("<discarded>", 11);
-        return;
-      }
+          switch(decode(state, codepoint, byte)) {
+            case UTF8_ACCEPT: {
+              switch(codepoint) {
+                case 0x08: {
+                  string_buffer[bytes++] = '\\';
+                  string_buffer[bytes++] = 'b';
+                  break;
+                }
 
-      case value_t::null: {
-        o->write_characters("null", 4);
-        return;
-      }
-    }
-  }
+                case 0x09: {
+                  string_buffer[bytes++] = '\\';
+                  string_buffer[bytes++] = 't';
+                  break;
+                }
 
-private:
-  void dump_escaped(const string_t &s, const bool ensure_ascii) {
-    uint32_t codepoint;
-    uint8_t state = UTF8_ACCEPT;
-    std::size_t bytes = 0;
-
-    for(std::size_t i = 0; i < s.size(); ++i) {
-      const auto byte = static_cast<uint8_t>(s[i]);
-
-      switch(decode(state, codepoint, byte)) {
-        case UTF8_ACCEPT: {
-          switch(codepoint) {
-            case 0x08: {
-              string_buffer[bytes++] = '\\';
-              string_buffer[bytes++] = 'b';
-              break;
-            }
+                case 0x0A: {
+                  string_buffer[bytes++] = '\\';
+                  string_buffer[bytes++] = 'n';
+                  break;
+                }
 
-            case 0x09: {
-              string_buffer[bytes++] = '\\';
-              string_buffer[bytes++] = 't';
-              break;
-            }
+                case 0x0C: {
+                  string_buffer[bytes++] = '\\';
+                  string_buffer[bytes++] = 'f';
+                  break;
+                }
 
-            case 0x0A: {
-              string_buffer[bytes++] = '\\';
-              string_buffer[bytes++] = 'n';
-              break;
-            }
+                case 0x0D: {
+                  string_buffer[bytes++] = '\\';
+                  string_buffer[bytes++] = 'r';
+                  break;
+                }
 
-            case 0x0C: {
-              string_buffer[bytes++] = '\\';
-              string_buffer[bytes++] = 'f';
-              break;
-            }
+                case 0x22: {
+                  string_buffer[bytes++] = '\\';
+                  string_buffer[bytes++] = '\"';
+                  break;
+                }
 
-            case 0x0D: {
-              string_buffer[bytes++] = '\\';
-              string_buffer[bytes++] = 'r';
-              break;
-            }
+                case 0x5C: {
+                  string_buffer[bytes++] = '\\';
+                  string_buffer[bytes++] = '\\';
+                  break;
+                }
+
+                default: {
+                  if((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F))) {
+                    if(codepoint <= 0xFFFF) {
+                      std::snprintf(string_buffer.data()+bytes, 7, "\\u%04x",
+                                    static_cast<uint16_t>(codepoint));
+                      bytes += 6;
+                    } else {
+                      std::snprintf(string_buffer.data()+bytes, 13, "\\u%04x\\u%04x",
+                                    static_cast<uint16_t>(0xD7C0+(codepoint >> 10)),
+                                    static_cast<uint16_t>(0xDC00+(codepoint & 0x3FF)));
+                      bytes += 12;
+                    }
+                  } else {
+                    string_buffer[bytes++] = s[i];
+                  }
+                  break;
+                }
+              }
 
-            case 0x22: {
-              string_buffer[bytes++] = '\\';
-              string_buffer[bytes++] = '\"';
+              if(string_buffer.size()-bytes < 13) {
+                o->write_characters(string_buffer.data(), bytes);
+                bytes = 0;
+              }
               break;
             }
 
-            case 0x5C: {
-              string_buffer[bytes++] = '\\';
-              string_buffer[bytes++] = '\\';
-              break;
+            case UTF8_REJECT: {
+              std::stringstream ss;
+              ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(byte);
+              JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index "+std::to_string(i)+": 0x"+ss.str()));
             }
 
             default: {
-              if((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F))) {
-                if(codepoint <= 0xFFFF) {
-                  std::snprintf(string_buffer.data()+bytes, 7, "\\u%04x",
-                                static_cast<uint16_t>(codepoint));
-                  bytes += 6;
-                } else {
-                  std::snprintf(string_buffer.data()+bytes, 13, "\\u%04x\\u%04x",
-                                static_cast<uint16_t>(0xD7C0+(codepoint >> 10)),
-                                static_cast<uint16_t>(0xDC00+(codepoint & 0x3FF)));
-                  bytes += 12;
-                }
-              } else {
+              if(not ensure_ascii) {
                 string_buffer[bytes++] = s[i];
               }
               break;
             }
           }
+        }
 
-          if(string_buffer.size()-bytes < 13) {
+        if(JSON_LIKELY(state == UTF8_ACCEPT)) {
+          if(bytes > 0) {
             o->write_characters(string_buffer.data(), bytes);
-            bytes = 0;
           }
-          break;
-        }
-
-        case UTF8_REJECT: {
+        } else {
           std::stringstream ss;
-          ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(byte);
-          JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index "+std::to_string(i)+": 0x"+ss.str()));
+          ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex
+             << static_cast<int>(static_cast<uint8_t>(s.back()));
+          JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x"+ss.str()));
         }
+      }
 
-        default: {
-          if(not ensure_ascii) {
-            string_buffer[bytes++] = s[i];
-          }
-          break;
+      template<typename NumberType, detail::enable_if_t<
+          std::is_same<NumberType, number_unsigned_t>::value or
+          std::is_same<NumberType, number_integer_t>::value,
+          int> = 0>
+      void dump_integer(NumberType x) {
+        if(x == 0) {
+          o->write_character('0');
+          return;
         }
-      }
-    }
 
-    if(JSON_LIKELY(state == UTF8_ACCEPT)) {
-      if(bytes > 0) {
-        o->write_characters(string_buffer.data(), bytes);
-      }
-    } else {
-      std::stringstream ss;
-      ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex
-         << static_cast<int>(static_cast<uint8_t>(s.back()));
-      JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x"+ss.str()));
-    }
-  }
+        const bool is_negative = (x <= 0) and (x != 0);
+        std::size_t i = 0;
 
-  template<typename NumberType, detail::enable_if_t<
-      std::is_same<NumberType, number_unsigned_t>::value or
-      std::is_same<NumberType, number_integer_t>::value,
-      int> = 0>
-  void dump_integer(NumberType x) {
-    if(x == 0) {
-      o->write_character('0');
-      return;
-    }
+        while(x != 0) {
+          assert(i < number_buffer.size()-1);
 
-    const bool is_negative = (x <= 0) and (x != 0);
-    std::size_t i = 0;
+          const auto digit = std::labs(static_cast<long>(x % 10));
+          number_buffer[i++] = static_cast<char>('0'+digit);
+          x /= 10;
+        }
 
-    while(x != 0) {
-      assert(i < number_buffer.size()-1);
+        if(is_negative) {
+          assert(i < number_buffer.size()-2);
+          number_buffer[i++] = '-';
+        }
 
-      const auto digit = std::labs(static_cast<long>(x % 10));
-      number_buffer[i++] = static_cast<char>('0'+digit);
-      x /= 10;
-    }
+        std::reverse(number_buffer.begin(), number_buffer.begin()+i);
+        o->write_characters(number_buffer.data(), i);
+      }
 
-    if(is_negative) {
-      assert(i < number_buffer.size()-2);
-      number_buffer[i++] = '-';
-    }
+      void dump_float(number_float_t x) {
+        if(not std::isfinite(x)) {
+          o->write_characters("null", 4);
+          return;
+        }
 
-    std::reverse(number_buffer.begin(), number_buffer.begin()+i);
-    o->write_characters(number_buffer.data(), i);
-  }
+        static constexpr bool is_ieee_single_or_double
+            = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and
+               std::numeric_limits<number_float_t>::max_exponent == 128) or
+              (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and
+               std::numeric_limits<number_float_t>::max_exponent == 1024);
 
-  void dump_float(number_float_t x) {
-    if(not std::isfinite(x)) {
-      o->write_characters("null", 4);
-      return;
-    }
+        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
+      }
 
-    //
+      void dump_float(number_float_t x, std::true_type) {
+        char *begin = number_buffer.data();
+        char *end = ::nlohmann::detail::to_chars(begin, begin+number_buffer.size(), x);
 
-    static constexpr bool is_ieee_single_or_double
-        = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and
-           std::numeric_limits<number_float_t>::max_exponent == 128) or
-          (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and
-           std::numeric_limits<number_float_t>::max_exponent == 1024);
+        o->write_characters(begin, static_cast<size_t>(end-begin));
+      }
 
-    dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
-  }
+      void dump_float(number_float_t x, std::false_type) {
+        static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
 
-  void dump_float(number_float_t x, std::true_type) {
-    char *begin = number_buffer.data();
-    char *end = ::nlohmann::detail::to_chars(begin, begin+number_buffer.size(), x);
+        std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
 
-    o->write_characters(begin, static_cast<size_t>(end-begin));
-  }
+        assert(len > 0);
 
-  void dump_float(number_float_t x, std::false_type) {
-    static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
+        assert(static_cast<std::size_t>(len) < number_buffer.size());
 
-    std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
+        if(thousands_sep != '\0') {
+          const auto end = std::remove(number_buffer.begin(),
+                                       number_buffer.begin()+len, thousands_sep);
+          std::fill(end, number_buffer.end(), '\0');
+          assert((end-number_buffer.begin()) <= len);
+          len = (end-number_buffer.begin());
+        }
 
-    assert(len > 0);
+        if(decimal_point != '\0' and decimal_point != '.') {
+          const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
+          if(dec_pos != number_buffer.end()) {
+            *dec_pos = '.';
+          }
+        }
 
-    assert(static_cast<std::size_t>(len) < number_buffer.size());
+        o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
 
-    if(thousands_sep != '\0') {
-      const auto end = std::remove(number_buffer.begin(),
-                                   number_buffer.begin()+len, thousands_sep);
-      std::fill(end, number_buffer.end(), '\0');
-      assert((end-number_buffer.begin()) <= len);
-      len = (end-number_buffer.begin());
-    }
+        const bool value_is_int_like =
+            std::none_of(number_buffer.begin(), number_buffer.begin()+len+1,
+                         [](char c) {
+                           return (c == '.' or c == 'e');
+                         });
 
-    if(decimal_point != '\0' and decimal_point != '.') {
-      const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
-      if(dec_pos != number_buffer.end()) {
-        *dec_pos = '.';
+        if(value_is_int_like) {
+          o->write_characters(".0", 2);
+        }
       }
-    }
-
-    o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
 
-    const bool value_is_int_like =
-        std::none_of(number_buffer.begin(), number_buffer.begin()+len+1,
-                     [](char c) {
-                       return (c == '.' or c == 'e');
-                     });
-
-    if(value_is_int_like) {
-      o->write_characters(".0", 2);
-    }
-  }
-
-  static uint8_t decode(uint8_t &state, uint32_t &codep, const uint8_t byte) noexcept {
-    static const std::array<uint8_t, 400> utf8d =
-        {
+      static uint8_t decode(uint8_t &state, uint32_t &codep, const uint8_t byte) noexcept {
+        static const std::array<uint8_t, 400> utf8d =
             {
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
-                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-                8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
-                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
-                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
-                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1,
-                1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
-                1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1,
-                1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
-            }
-        };
+                {
+                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+                    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+                    8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+                    0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
+                    0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
+                    0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
+                    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1,
+                    1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+                    1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1,
+                    1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+                }
+            };
 
-    const uint8_t type = utf8d[byte];
+        const uint8_t type = utf8d[byte];
 
-    codep = (state != UTF8_ACCEPT)
-            ? (byte & 0x3fu) | (codep << 6)
-            : static_cast<uint32_t>(0xff >> type) & (byte);
+        codep = (state != UTF8_ACCEPT)
+                ? (byte & 0x3fu) | (codep << 6)
+                : static_cast<uint32_t>(0xff >> type) & (byte);
 
-    state = utf8d[256u+state * 16u+type];
-    return state;
-  }
+        state = utf8d[256u+state * 16u+type];
+        return state;
+      }
 
-private:
-  output_adapter_t<char> o = nullptr;
+    private:
+      output_adapter_t<char> o = nullptr;
 
-  std::array<char, 64> number_buffer{{}};
+      std::array<char, 64> number_buffer{{}};
 
-  const std::lconv *loc = nullptr;
+      const std::lconv *loc = nullptr;
 
-  const char thousands_sep = '\0';
+      const char thousands_sep = '\0';
 
-  const char decimal_point = '\0';
+      const char decimal_point = '\0';
 
-  std::array<char, 512> string_buffer{{}};
+      std::array<char, 512> string_buffer{{}};
 
-  const char indent_char;
+      const char indent_char;
 
-  string_t indent_string;
-};
-}
+      string_t indent_string;
+    };
+  }
 }
 
 namespace nlohmann {
-namespace detail {
-template<typename BasicJsonType>
-class json_ref {
-public:
-  using value_type = BasicJsonType;
+  namespace detail {
+    template<typename BasicJsonType>
+    class json_ref {
+    public:
+      using value_type = BasicJsonType;
 
-  json_ref(value_type &&value)
-      : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true) {}
+      json_ref(value_type &&value)
+          : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true) {}
 
-  json_ref(const value_type &value)
-      : value_ref(const_cast<value_type *>(&value)), is_rvalue(false) {}
+      json_ref(const value_type &value)
+          : value_ref(const_cast<value_type *>(&value)), is_rvalue(false) {}
 
-  json_ref(std::initializer_list<json_ref> init)
-      : owned_value(init), value_ref(&owned_value), is_rvalue(true) {}
+      json_ref(std::initializer_list<json_ref> init)
+          : owned_value(init), value_ref(&owned_value), is_rvalue(true) {}
 
-  template<class... Args>
-  json_ref(Args &&... args)
-      : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true) {}
+      template<class... Args>
+      json_ref(Args &&... args)
+          : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true) {}
 
-  json_ref(json_ref &&) = default;
+      json_ref(json_ref &&) = default;
 
-  json_ref(const json_ref &) = delete;
+      json_ref(const json_ref &) = delete;
 
-  json_ref &operator=(const json_ref &) = delete;
+      json_ref &operator=(const json_ref &) = delete;
 
-  value_type moved_or_copied() const {
-    if(is_rvalue) {
-      return std::move(*value_ref);
-    }
-    return *value_ref;
-  }
+      value_type moved_or_copied() const {
+        if(is_rvalue) {
+          return std::move(*value_ref);
+        }
+        return *value_ref;
+      }
 
-  value_type const &operator*() const {
-    return *static_cast<value_type const *>(value_ref);
-  }
+      value_type const &operator*() const {
+        return *static_cast<value_type const *>(value_ref);
+      }
 
-  value_type const *operator->() const {
-    return static_cast<value_type const *>(value_ref);
-  }
+      value_type const *operator->() const {
+        return static_cast<value_type const *>(value_ref);
+      }
 
-private:
-  mutable value_type owned_value = nullptr;
-  value_type *value_ref = nullptr;
-  const bool is_rvalue;
-};
-}
+    private:
+      mutable value_type owned_value = nullptr;
+      value_type *value_ref = nullptr;
+      const bool is_rvalue;
+    };
+  }
 }
 
 namespace nlohmann {
-template<typename BasicJsonType>
-class json_pointer {
-  NLOHMANN_BASIC_JSON_TPL_DECLARATION
-  friend
-  class basic_json;
+  template<typename BasicJsonType>
+  class json_pointer {
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    friend
+    class basic_json;
 
-public:
-  explicit json_pointer(const std::string &s = "")
-      : reference_tokens(split(s)) {}
+  public:
+    explicit json_pointer(const std::string &s = "")
+        : reference_tokens(split(s)) {}
 
-  std::string to_string() const noexcept {
-    return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
-                           std::string{},
-                           [](const std::string &a, const std::string &b) {
-                             return a+"/"+escape(b);
-                           });
-  }
+    std::string to_string() const noexcept {
+      return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
+                             std::string{},
+                             [](const std::string &a, const std::string &b) {
+                               return a+"/"+escape(b);
+                             });
+    }
 
-  operator std::string() const {
-    return to_string();
-  }
+    operator std::string() const {
+      return to_string();
+    }
 
-  static int array_index(const std::string &s) {
-    std::size_t processed_chars = 0;
-    const int res = std::stoi(s, &processed_chars);
+    static int array_index(const std::string &s) {
+      std::size_t processed_chars = 0;
+      const int res = std::stoi(s, &processed_chars);
 
-    if(JSON_UNLIKELY(processed_chars != s.size())) {
-      JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+s+"'"));
+      if(JSON_UNLIKELY(processed_chars != s.size())) {
+        JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+s+"'"));
+      }
+
+      return res;
     }
 
-    return res;
-  }
+  private:
+    std::string pop_back() {
+      if(JSON_UNLIKELY(is_root())) {
+        JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+      }
 
-private:
-  std::string pop_back() {
-    if(JSON_UNLIKELY(is_root())) {
-      JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+      auto last = reference_tokens.back();
+      reference_tokens.pop_back();
+      return last;
     }
 
-    auto last = reference_tokens.back();
-    reference_tokens.pop_back();
-    return last;
-  }
+    bool is_root() const {
+      return reference_tokens.empty();
+    }
 
-  bool is_root() const {
-    return reference_tokens.empty();
-  }
+    json_pointer top() const {
+      if(JSON_UNLIKELY(is_root())) {
+        JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+      }
 
-  json_pointer top() const {
-    if(JSON_UNLIKELY(is_root())) {
-      JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+      json_pointer result = *this;
+      result.reference_tokens = {reference_tokens[0]};
+      return result;
     }
 
-    json_pointer result = *this;
-    result.reference_tokens = {reference_tokens[0]};
-    return result;
-  }
+    BasicJsonType &get_and_create(BasicJsonType &j) const {
+      using size_type = typename BasicJsonType::size_type;
+      auto result = &j;
 
-  BasicJsonType &get_and_create(BasicJsonType &j) const {
-    using size_type = typename BasicJsonType::size_type;
-    auto result = &j;
+      for(const auto &reference_token : reference_tokens) {
+        switch(result->m_type) {
+          case detail::value_t::null: {
+            if(reference_token == "0") {
+              result = &result->operator[](0);
+            } else {
+              result = &result->operator[](reference_token);
+            }
+            break;
+          }
 
-    for(const auto &reference_token : reference_tokens) {
-      switch(result->m_type) {
-        case detail::value_t::null: {
-          if(reference_token == "0") {
-            result = &result->operator[](0);
-          } else {
+          case detail::value_t::object: {
             result = &result->operator[](reference_token);
+            break;
           }
-          break;
-        }
-
-        case detail::value_t::object: {
-          result = &result->operator[](reference_token);
-          break;
-        }
 
-        case detail::value_t::array: {
-          JSON_TRY {
-            result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
-          }
-          JSON_CATCH(std::invalid_argument &) {
-            JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+          case detail::value_t::array: {
+            JSON_TRY {
+              result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
+            }
+            JSON_CATCH(std::invalid_argument &) {
+              JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+            }
+            break;
           }
-          break;
-        }
 
-        default:
-          JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
+          default:
+            JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
+        }
       }
-    }
 
-    return *result;
-  }
-
-  BasicJsonType &get_unchecked(BasicJsonType *ptr) const {
-    using size_type = typename BasicJsonType::size_type;
-    for(const auto &reference_token : reference_tokens) {
-      if(ptr->m_type == detail::value_t::null) {
-        const bool nums =
-            std::all_of(reference_token.begin(), reference_token.end(),
-                        [](const char x) {
-                          return (x >= '0' and x <= '9');
-                        });
+      return *result;
+    }
 
-        *ptr = (nums or reference_token == "-")
-               ? detail::value_t::array
-               : detail::value_t::object;
-      }
+    BasicJsonType &get_unchecked(BasicJsonType *ptr) const {
+      using size_type = typename BasicJsonType::size_type;
+      for(const auto &reference_token : reference_tokens) {
+        if(ptr->m_type == detail::value_t::null) {
+          const bool nums =
+              std::all_of(reference_token.begin(), reference_token.end(),
+                          [](const char x) {
+                            return (x >= '0' and x <= '9');
+                          });
 
-      switch(ptr->m_type) {
-        case detail::value_t::object: {
-          ptr = &ptr->operator[](reference_token);
-          break;
+          *ptr = (nums or reference_token == "-")
+                 ? detail::value_t::array
+                 : detail::value_t::object;
         }
 
-        case detail::value_t::array: {
-          if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
-            JSON_THROW(detail::parse_error::create(106, 0,
-                                                   "array index '"+reference_token+
-                                                   "' must not begin with '0'"));
+        switch(ptr->m_type) {
+          case detail::value_t::object: {
+            ptr = &ptr->operator[](reference_token);
+            break;
           }
 
-          if(reference_token == "-") {
-            ptr = &ptr->operator[](ptr->m_value.array->size());
-          } else {
-            JSON_TRY {
-              ptr = &ptr->operator[](
-                  static_cast<size_type>(array_index(reference_token)));
+          case detail::value_t::array: {
+            if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
+              JSON_THROW(detail::parse_error::create(106, 0,
+                                                     "array index '"+reference_token+
+                                                     "' must not begin with '0'"));
             }
-            JSON_CATCH(std::invalid_argument &) {
-              JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+
+            if(reference_token == "-") {
+              ptr = &ptr->operator[](ptr->m_value.array->size());
+            } else {
+              JSON_TRY {
+                ptr = &ptr->operator[](
+                    static_cast<size_type>(array_index(reference_token)));
+              }
+              JSON_CATCH(std::invalid_argument &) {
+                JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+              }
             }
+            break;
           }
-          break;
-        }
 
-        default:
-          JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
+          default:
+            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
+        }
       }
+
+      return *ptr;
     }
 
-    return *ptr;
-  }
+    BasicJsonType &get_checked(BasicJsonType *ptr) const {
+      using size_type = typename BasicJsonType::size_type;
+      for(const auto &reference_token : reference_tokens) {
+        switch(ptr->m_type) {
+          case detail::value_t::object: {
+            ptr = &ptr->at(reference_token);
+            break;
+          }
 
-  BasicJsonType &get_checked(BasicJsonType *ptr) const {
-    using size_type = typename BasicJsonType::size_type;
-    for(const auto &reference_token : reference_tokens) {
-      switch(ptr->m_type) {
-        case detail::value_t::object: {
-          ptr = &ptr->at(reference_token);
-          break;
-        }
+          case detail::value_t::array: {
+            if(JSON_UNLIKELY(reference_token == "-")) {
+              JSON_THROW(detail::out_of_range::create(402,
+                                                      "array index '-' ("+std::to_string(ptr->m_value.array->size())+
+                                                      ") is out of range"));
+            }
 
-        case detail::value_t::array: {
-          if(JSON_UNLIKELY(reference_token == "-")) {
-            JSON_THROW(detail::out_of_range::create(402,
-                                                    "array index '-' ("+std::to_string(ptr->m_value.array->size())+
-                                                    ") is out of range"));
-          }
+            if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
+              JSON_THROW(detail::parse_error::create(106, 0,
+                                                     "array index '"+reference_token+
+                                                     "' must not begin with '0'"));
+            }
 
-          if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
-            JSON_THROW(detail::parse_error::create(106, 0,
-                                                   "array index '"+reference_token+
-                                                   "' must not begin with '0'"));
+            JSON_TRY {
+              ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
+            }
+            JSON_CATCH(std::invalid_argument &) {
+              JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+            }
+            break;
           }
 
-          JSON_TRY {
-            ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
-          }
-          JSON_CATCH(std::invalid_argument &) {
-            JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
-          }
-          break;
+          default:
+            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
         }
-
-        default:
-          JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
       }
+
+      return *ptr;
     }
 
-    return *ptr;
-  }
+    const BasicJsonType &get_unchecked(const BasicJsonType *ptr) const {
+      using size_type = typename BasicJsonType::size_type;
+      for(const auto &reference_token : reference_tokens) {
+        switch(ptr->m_type) {
+          case detail::value_t::object: {
+            ptr = &ptr->operator[](reference_token);
+            break;
+          }
 
-  const BasicJsonType &get_unchecked(const BasicJsonType *ptr) const {
-    using size_type = typename BasicJsonType::size_type;
-    for(const auto &reference_token : reference_tokens) {
-      switch(ptr->m_type) {
-        case detail::value_t::object: {
-          ptr = &ptr->operator[](reference_token);
-          break;
-        }
+          case detail::value_t::array: {
+            if(JSON_UNLIKELY(reference_token == "-")) {
+              JSON_THROW(detail::out_of_range::create(402,
+                                                      "array index '-' ("+std::to_string(ptr->m_value.array->size())+
+                                                      ") is out of range"));
+            }
 
-        case detail::value_t::array: {
-          if(JSON_UNLIKELY(reference_token == "-")) {
-            JSON_THROW(detail::out_of_range::create(402,
-                                                    "array index '-' ("+std::to_string(ptr->m_value.array->size())+
-                                                    ") is out of range"));
-          }
+            if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
+              JSON_THROW(detail::parse_error::create(106, 0,
+                                                     "array index '"+reference_token+
+                                                     "' must not begin with '0'"));
+            }
 
-          if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
-            JSON_THROW(detail::parse_error::create(106, 0,
-                                                   "array index '"+reference_token+
-                                                   "' must not begin with '0'"));
+            JSON_TRY {
+              ptr = &ptr->operator[](
+                  static_cast<size_type>(array_index(reference_token)));
+            }
+            JSON_CATCH(std::invalid_argument &) {
+              JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+            }
+            break;
           }
 
-          JSON_TRY {
-            ptr = &ptr->operator[](
-                static_cast<size_type>(array_index(reference_token)));
-          }
-          JSON_CATCH(std::invalid_argument &) {
-            JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
-          }
-          break;
+          default:
+            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
         }
-
-        default:
-          JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
       }
+
+      return *ptr;
     }
 
-    return *ptr;
-  }
+    const BasicJsonType &get_checked(const BasicJsonType *ptr) const {
+      using size_type = typename BasicJsonType::size_type;
+      for(const auto &reference_token : reference_tokens) {
+        switch(ptr->m_type) {
+          case detail::value_t::object: {
+            ptr = &ptr->at(reference_token);
+            break;
+          }
 
-  const BasicJsonType &get_checked(const BasicJsonType *ptr) const {
-    using size_type = typename BasicJsonType::size_type;
-    for(const auto &reference_token : reference_tokens) {
-      switch(ptr->m_type) {
-        case detail::value_t::object: {
-          ptr = &ptr->at(reference_token);
-          break;
-        }
+          case detail::value_t::array: {
+            if(JSON_UNLIKELY(reference_token == "-")) {
+              JSON_THROW(detail::out_of_range::create(402,
+                                                      "array index '-' ("+std::to_string(ptr->m_value.array->size())+
+                                                      ") is out of range"));
+            }
 
-        case detail::value_t::array: {
-          if(JSON_UNLIKELY(reference_token == "-")) {
-            JSON_THROW(detail::out_of_range::create(402,
-                                                    "array index '-' ("+std::to_string(ptr->m_value.array->size())+
-                                                    ") is out of range"));
-          }
+            if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
+              JSON_THROW(detail::parse_error::create(106, 0,
+                                                     "array index '"+reference_token+
+                                                     "' must not begin with '0'"));
+            }
 
-          if(JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
-            JSON_THROW(detail::parse_error::create(106, 0,
-                                                   "array index '"+reference_token+
-                                                   "' must not begin with '0'"));
+            JSON_TRY {
+              ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
+            }
+            JSON_CATCH(std::invalid_argument &) {
+              JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
+            }
+            break;
           }
 
-          JSON_TRY {
-            ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
-          }
-          JSON_CATCH(std::invalid_argument &) {
-            JSON_THROW(detail::parse_error::create(109, 0, "array index '"+reference_token+"' is not a number"));
-          }
-          break;
+          default:
+            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
         }
-
-        default:
-          JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '"+reference_token+"'"));
       }
-    }
 
-    return *ptr;
-  }
+      return *ptr;
+    }
 
-  static std::vector<std::string> split(const std::string &reference_string) {
-    std::vector<std::string> result;
+    static std::vector<std::string> split(const std::string &reference_string) {
+      std::vector<std::string> result;
 
-    if(reference_string.empty()) {
-      return result;
-    }
+      if(reference_string.empty()) {
+        return result;
+      }
 
-    if(JSON_UNLIKELY(reference_string[0] != '/')) {
-      JSON_THROW(detail::parse_error::create(107, 1,
-                                             "JSON pointer must be empty or begin with '/' - was: '"+
-                                             reference_string+"'"));
-    }
+      if(JSON_UNLIKELY(reference_string[0] != '/')) {
+        JSON_THROW(detail::parse_error::create(107, 1,
+                                               "JSON pointer must be empty or begin with '/' - was: '"+
+                                               reference_string+"'"));
+      }
 
-    for(
+      for(
 
-        std::size_t slash = reference_string.find_first_of('/', 1),
+          std::size_t slash = reference_string.find_first_of('/', 1),
 
-            start = 1;
+              start = 1;
 
-        start != 0;
+          start != 0;
 
-        start = slash+1,
+          start = slash+1,
 
-            slash = reference_string.find_first_of('/', start)) {
-      auto reference_token = reference_string.substr(start, slash-start);
+              slash = reference_string.find_first_of('/', start)) {
+        auto reference_token = reference_string.substr(start, slash-start);
 
-      for(std::size_t pos = reference_token.find_first_of('~');
-          pos != std::string::npos;
-          pos = reference_token.find_first_of('~', pos+1)) {
-        assert(reference_token[pos] == '~');
+        for(std::size_t pos = reference_token.find_first_of('~');
+            pos != std::string::npos;
+            pos = reference_token.find_first_of('~', pos+1)) {
+          assert(reference_token[pos] == '~');
 
-        if(JSON_UNLIKELY(pos == reference_token.size()-1 or
-                         (reference_token[pos+1] != '0' and
-                          reference_token[pos+1] != '1'))) {
-          JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
+          if(JSON_UNLIKELY(pos == reference_token.size()-1 or
+                           (reference_token[pos+1] != '0' and
+                            reference_token[pos+1] != '1'))) {
+            JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
+          }
         }
+
+        unescape(reference_token);
+        result.push_back(reference_token);
       }
 
-      unescape(reference_token);
-      result.push_back(reference_token);
+      return result;
     }
 
-    return result;
-  }
-
-  static void replace_substring(std::string &s, const std::string &f,
-                                const std::string &t) {
-    assert(not f.empty());
-    for(auto pos = s.find(f);
-        pos != std::string::npos;
-        s.replace(pos, f.size(), t),
-            pos = s.find(f, pos+t.size())) {}
-  }
+    static void replace_substring(std::string &s, const std::string &f,
+                                  const std::string &t) {
+      assert(not f.empty());
+      for(auto pos = s.find(f);
+          pos != std::string::npos;
+          s.replace(pos, f.size(), t),
+              pos = s.find(f, pos+t.size())) {}
+    }
 
-  static std::string escape(std::string s) {
-    replace_substring(s, "~", "~0");
-    replace_substring(s, "/", "~1");
-    return s;
-  }
+    static std::string escape(std::string s) {
+      replace_substring(s, "~", "~0");
+      replace_substring(s, "/", "~1");
+      return s;
+    }
 
-  static void unescape(std::string &s) {
-    replace_substring(s, "~1", "/");
-    replace_substring(s, "~0", "~");
-  }
+    static void unescape(std::string &s) {
+      replace_substring(s, "~1", "/");
+      replace_substring(s, "~0", "~");
+    }
 
-  static void flatten(const std::string &reference_string,
-                      const BasicJsonType &value,
-                      BasicJsonType &result) {
-    switch(value.m_type) {
-      case detail::value_t::array: {
-        if(value.m_value.array->empty()) {
-          result[reference_string] = nullptr;
-        } else {
-          for(std::size_t i = 0; i < value.m_value.array->size(); ++i) {
-            flatten(reference_string+"/"+std::to_string(i),
-                    value.m_value.array->operator[](i), result);
+    static void flatten(const std::string &reference_string,
+                        const BasicJsonType &value,
+                        BasicJsonType &result) {
+      switch(value.m_type) {
+        case detail::value_t::array: {
+          if(value.m_value.array->empty()) {
+            result[reference_string] = nullptr;
+          } else {
+            for(std::size_t i = 0; i < value.m_value.array->size(); ++i) {
+              flatten(reference_string+"/"+std::to_string(i),
+                      value.m_value.array->operator[](i), result);
+            }
           }
+          break;
         }
-        break;
-      }
 
-      case detail::value_t::object: {
-        if(value.m_value.object->empty()) {
-          result[reference_string] = nullptr;
-        } else {
-          for(const auto &element : *value.m_value.object) {
-            flatten(reference_string+"/"+escape(element.first), element.second, result);
+        case detail::value_t::object: {
+          if(value.m_value.object->empty()) {
+            result[reference_string] = nullptr;
+          } else {
+            for(const auto &element : *value.m_value.object) {
+              flatten(reference_string+"/"+escape(element.first), element.second, result);
+            }
           }
+          break;
+        }
+
+        default: {
+          result[reference_string] = value;
+          break;
         }
-        break;
       }
+    }
 
-      default: {
-        result[reference_string] = value;
-        break;
+    static BasicJsonType
+    unflatten(const BasicJsonType &value) {
+      if(JSON_UNLIKELY(not value.is_object())) {
+        JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
       }
-    }
-  }
 
-  static BasicJsonType
-  unflatten(const BasicJsonType &value) {
-    if(JSON_UNLIKELY(not value.is_object())) {
-      JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
-    }
+      BasicJsonType result;
 
-    BasicJsonType result;
+      for(const auto &element : *value.m_value.object) {
+        if(JSON_UNLIKELY(not element.second.is_primitive())) {
+          JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
+        }
 
-    for(const auto &element : *value.m_value.object) {
-      if(JSON_UNLIKELY(not element.second.is_primitive())) {
-        JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
+        json_pointer(element.first).get_and_create(result) = element.second;
       }
 
-      json_pointer(element.first).get_and_create(result) = element.second;
+      return result;
     }
 
-    return result;
-  }
-
-  friend bool operator==(json_pointer const &lhs,
-                         json_pointer const &rhs) noexcept {
-    return (lhs.reference_tokens == rhs.reference_tokens);
-  }
+    friend bool operator==(json_pointer const &lhs,
+                           json_pointer const &rhs) noexcept {
+      return (lhs.reference_tokens == rhs.reference_tokens);
+    }
 
-  friend bool operator!=(json_pointer const &lhs,
-                         json_pointer const &rhs) noexcept {
-    return not(lhs == rhs);
-  }
+    friend bool operator!=(json_pointer const &lhs,
+                           json_pointer const &rhs) noexcept {
+      return not(lhs == rhs);
+    }
 
-  std::vector<std::string> reference_tokens;
-};
+    std::vector<std::string> reference_tokens;
+  };
 }
 
 namespace nlohmann {
-template<typename, typename>
-struct adl_serializer {
-  template<typename BasicJsonType, typename ValueType>
-  static void from_json(BasicJsonType &&j, ValueType &val) noexcept(
-  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val))) {
-    ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
-  }
+  template<typename, typename>
+  struct adl_serializer {
+    template<typename BasicJsonType, typename ValueType>
+    static void from_json(BasicJsonType &&j, ValueType &val) noexcept(
+    noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val))) {
+      ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
+    }
 
-  template<typename BasicJsonType, typename ValueType>
-  static void to_json(BasicJsonType &j, ValueType &&val) noexcept(
-  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val)))) {
-    ::nlohmann::to_json(j, std::forward<ValueType>(val));
-  }
-};
+    template<typename BasicJsonType, typename ValueType>
+    static void to_json(BasicJsonType &j, ValueType &&val) noexcept(
+    noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val)))) {
+      ::nlohmann::to_json(j, std::forward<ValueType>(val));
+    }
+  };
 }
 
 namespace nlohmann {
-NLOHMANN_BASIC_JSON_TPL_DECLARATION
-class basic_json {
-private:
-  template<detail::value_t> friend
-  struct detail::external_constructor;
-  friend ::nlohmann::json_pointer<basic_json>;
-  friend ::nlohmann::detail::parser<basic_json>;
-  friend ::nlohmann::detail::serializer<basic_json>;
-
-  template<typename BasicJsonType>
-  friend
-  class ::nlohmann::detail::iter_impl;
-
-  template<typename BasicJsonType, typename CharType>
-  friend
-  class ::nlohmann::detail::binary_writer;
-
-  template<typename BasicJsonType>
-  friend
-  class ::nlohmann::detail::binary_reader;
+  NLOHMANN_BASIC_JSON_TPL_DECLARATION
+  class basic_json {
+  private:
+    template<detail::value_t> friend
+    struct detail::external_constructor;
+    friend ::nlohmann::json_pointer<basic_json>;
+    friend ::nlohmann::detail::parser<basic_json>;
+    friend ::nlohmann::detail::serializer<basic_json>;
 
-  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
+    template<typename BasicJsonType>
+    friend
+    class ::nlohmann::detail::iter_impl;
 
-  using lexer = ::nlohmann::detail::lexer<basic_json>;
-  using parser = ::nlohmann::detail::parser<basic_json>;
+    using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
 
-  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
-  template<typename BasicJsonType>
-  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
-  template<typename BasicJsonType>
-  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
-  template<typename Iterator>
-  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
-  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
+    using lexer = ::nlohmann::detail::lexer<basic_json>;
+    using parser = ::nlohmann::detail::parser<basic_json>;
 
-  template<typename CharType>
-  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
+    using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
+    template<typename BasicJsonType>
+    using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
+    template<typename BasicJsonType>
+    using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
+    template<typename Iterator>
+    using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
+    template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
 
-  using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
-  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
+    template<typename CharType>
+    using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
 
-  using serializer = ::nlohmann::detail::serializer<basic_json>;
+    using serializer = ::nlohmann::detail::serializer<basic_json>;
 
-public:
-  using value_t = detail::value_t;
+  public:
+    using value_t = detail::value_t;
 
-  using json_pointer = ::nlohmann::json_pointer<basic_json>;
-  template<typename T, typename SFINAE>
-  using json_serializer = JSONSerializer<T, SFINAE>;
+    using json_pointer = ::nlohmann::json_pointer<basic_json>;
+    template<typename T, typename SFINAE>
+    using json_serializer = JSONSerializer<T, SFINAE>;
 
-  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
+    using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
 
-  using exception = detail::exception;
+    using exception = detail::exception;
 
-  using parse_error = detail::parse_error;
+    using parse_error = detail::parse_error;
 
-  using invalid_iterator = detail::invalid_iterator;
+    using invalid_iterator = detail::invalid_iterator;
 
-  using type_error = detail::type_error;
+    using type_error = detail::type_error;
 
-  using out_of_range = detail::out_of_range;
+    using out_of_range = detail::out_of_range;
 
-  using other_error = detail::other_error;
+    using other_error = detail::other_error;
 
-  using value_type = basic_json;
+    using value_type = basic_json;
 
-  using reference = value_type &;
+    using reference = value_type &;
 
-  using const_reference = const value_type &;
+    using const_reference = const value_type &;
 
-  using difference_type = std::ptrdiff_t;
+    using difference_type = std::ptrdiff_t;
 
-  using size_type = std::size_t;
+    using size_type = std::size_t;
 
-  using allocator_type = AllocatorType<basic_json>;
+    using allocator_type = AllocatorType<basic_json>;
 
-  using pointer = typename std::allocator_traits<allocator_type>::pointer;
+    using pointer = typename std::allocator_traits<allocator_type>::pointer;
 
-  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
+    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
 
-  using iterator = iter_impl<basic_json>;
+    using iterator = iter_impl<basic_json>;
 
-  using const_iterator = iter_impl<const basic_json>;
+    using const_iterator = iter_impl<const basic_json>;
 
-  using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
+    using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
 
-  using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
+    using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
 
-  static allocator_type get_allocator() {
-    return allocator_type();
-  }
+    static allocator_type get_allocator() {
+      return allocator_type();
+    }
 
-  static basic_json meta() {
-    basic_json result;
+    static basic_json meta() {
+      basic_json result;
 
-    result["copyright"] = "(C) 2013-2017 Niels Lohmann";
-    result["name"] = "JSON for Modern C++";
-    result["version"]["string"] =
-        std::to_string(NLOHMANN_JSON_VERSION_MAJOR)+"."+
-        std::to_string(NLOHMANN_JSON_VERSION_MINOR)+"."+
-        std::to_string(NLOHMANN_JSON_VERSION_PATCH);
-    result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
-    result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
-    result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
+      result["copyright"] = "(C) 2013-2017 Niels Lohmann";
+      result["name"] = "JSON for Modern C++";
+      result["version"]["string"] =
+          std::to_string(NLOHMANN_JSON_VERSION_MAJOR)+"."+
+          std::to_string(NLOHMANN_JSON_VERSION_MINOR)+"."+
+          std::to_string(NLOHMANN_JSON_VERSION_PATCH);
+      result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
+      result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
+      result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
 
 #ifdef _WIN32
-    result["platform"] = "win32";
+      result["platform"] = "win32";
 #elif defined __linux__
-    result["platform"] = "linux";
+      result["platform"] = "linux";
 #elif defined __APPLE__
         result["platform"] = "apple";
 #elif defined __unix__
@@ -6579,15 +4729,15 @@ class basic_json {
 #endif
 
 #if defined(__ICC) || defined(__INTEL_COMPILER)
-    result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
+      result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
 #elif defined(__clang__)
-    result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
+      result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
 #elif defined(__GNUC__) || defined(__GNUG__)
-    result["compiler"] = {{"family",  "gcc"},
-                          {"version", std::to_string(__GNUC__)+"."+std::to_string(__GNUC_MINOR__)+"."+
-                                      std::to_string(__GNUC_PATCHLEVEL__)}};
+      result["compiler"] = {{"family",  "gcc"},
+                            {"version", std::to_string(__GNUC__)+"."+std::to_string(__GNUC_MINOR__)+"."+
+                                        std::to_string(__GNUC_PATCHLEVEL__)}};
 #elif defined(__HP_cc) || defined(__HP_aCC)
-    result["compiler"] = "hp"
+      result["compiler"] = "hp"
 #elif defined(__IBMCPP__)
         result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
 #elif defined(_MSC_VER)
@@ -6601,2213 +4751,2135 @@ class basic_json {
 #endif
 
 #ifdef __cplusplus
-    result["compiler"]["c++"] = std::to_string(__cplusplus);
+      result["compiler"]["c++"] = std::to_string(__cplusplus);
 #else
-    result["compiler"]["c++"] = "unknown";
+      result["compiler"]["c++"] = "unknown";
 #endif
-    return result;
-  }
+      return result;
+    }
 
 #if defined(JSON_HAS_CPP_14)
 
-  using object_comparator_t = std::less<>;
+    using object_comparator_t = std::less<>;
 #else
-  using object_comparator_t = std::less<StringType>;
+    using object_comparator_t = std::less<StringType>;
 #endif
 
-  using object_t = ObjectType<StringType,
-      basic_json,
-      object_comparator_t,
-      AllocatorType<std::pair<const StringType,
-          basic_json>>>;
+    using object_t = ObjectType<StringType,
+        basic_json,
+        object_comparator_t,
+        AllocatorType<std::pair<const StringType,
+            basic_json>>>;
 
-  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
+    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
 
-  using string_t = StringType;
+    using string_t = StringType;
 
-  using boolean_t = BooleanType;
+    using boolean_t = BooleanType;
 
-  using number_integer_t = NumberIntegerType;
+    using number_integer_t = NumberIntegerType;
 
-  using number_unsigned_t = NumberUnsignedType;
+    using number_unsigned_t = NumberUnsignedType;
 
-  using number_float_t = NumberFloatType;
+    using number_float_t = NumberFloatType;
 
-private:
-  template<typename T, typename... Args>
-  static T *create(Args &&... args) {
-    AllocatorType<T> alloc;
-    using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
+  private:
+    template<typename T, typename... Args>
+    static T *create(Args &&... args) {
+      AllocatorType<T> alloc;
+      using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
 
-    auto deleter = [&](T *object) {
-      AllocatorTraits::deallocate(alloc, object, 1);
-    };
-    std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
-    AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
-    assert(object != nullptr);
-    return object.release();
-  }
+      auto deleter = [&](T *object) {
+        AllocatorTraits::deallocate(alloc, object, 1);
+      };
+      std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
+      AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
+      assert(object != nullptr);
+      return object.release();
+    }
 
-  union json_value {
-    object_t *object;
+    union json_value {
+      object_t *object;
 
-    array_t *array;
+      array_t *array;
 
-    string_t *string;
+      string_t *string;
 
-    boolean_t boolean;
+      boolean_t boolean;
 
-    number_integer_t number_integer;
+      number_integer_t number_integer;
 
-    number_unsigned_t number_unsigned;
+      number_unsigned_t number_unsigned;
 
-    number_float_t number_float;
+      number_float_t number_float;
 
-    json_value() = default;
+      json_value() = default;
 
-    json_value(boolean_t v) noexcept : boolean(v) {}
+      json_value(boolean_t v) noexcept : boolean(v) {}
 
-    json_value(number_integer_t v) noexcept : number_integer(v) {}
+      json_value(number_integer_t v) noexcept : number_integer(v) {}
 
-    json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
+      json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
 
-    json_value(number_float_t v) noexcept : number_float(v) {}
+      json_value(number_float_t v) noexcept : number_float(v) {}
 
-    json_value(value_t t) {
-      switch(t) {
-        case value_t::object: {
-          object = create<object_t>();
-          break;
-        }
+      json_value(value_t t) {
+        switch(t) {
+          case value_t::object: {
+            object = create<object_t>();
+            break;
+          }
 
-        case value_t::array: {
-          array = create<array_t>();
-          break;
-        }
+          case value_t::array: {
+            array = create<array_t>();
+            break;
+          }
 
-        case value_t::string: {
-          string = create<string_t>("");
-          break;
-        }
+          case value_t::string: {
+            string = create<string_t>("");
+            break;
+          }
 
-        case value_t::boolean: {
-          boolean = boolean_t(false);
-          break;
-        }
+          case value_t::boolean: {
+            boolean = boolean_t(false);
+            break;
+          }
 
-        case value_t::number_integer: {
-          number_integer = number_integer_t(0);
-          break;
-        }
+          case value_t::number_integer: {
+            number_integer = number_integer_t(0);
+            break;
+          }
 
-        case value_t::number_unsigned: {
-          number_unsigned = number_unsigned_t(0);
-          break;
-        }
+          case value_t::number_unsigned: {
+            number_unsigned = number_unsigned_t(0);
+            break;
+          }
 
-        case value_t::number_float: {
-          number_float = number_float_t(0.0);
-          break;
-        }
+          case value_t::number_float: {
+            number_float = number_float_t(0.0);
+            break;
+          }
 
-        case value_t::null: {
-          object = nullptr;
-          break;
-        }
+          case value_t::null: {
+            object = nullptr;
+            break;
+          }
 
-        default: {
-          object = nullptr;
-          if(JSON_UNLIKELY(t == value_t::null)) {
-            JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2"));
+          default: {
+            object = nullptr;
+            if(JSON_UNLIKELY(t == value_t::null)) {
+              JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2"));
+            }
+            break;
           }
-          break;
         }
       }
-    }
 
-    json_value(const string_t &value) {
-      string = create<string_t>(value);
-    }
+      json_value(const string_t &value) {
+        string = create<string_t>(value);
+      }
 
-    json_value(string_t &&value) {
-      string = create<string_t>(std::move(value));
-    }
+      json_value(string_t &&value) {
+        string = create<string_t>(std::move(value));
+      }
 
-    json_value(const object_t &value) {
-      object = create<object_t>(value);
-    }
+      json_value(const object_t &value) {
+        object = create<object_t>(value);
+      }
 
-    json_value(object_t &&value) {
-      object = create<object_t>(std::move(value));
-    }
+      json_value(object_t &&value) {
+        object = create<object_t>(std::move(value));
+      }
 
-    json_value(const array_t &value) {
-      array = create<array_t>(value);
-    }
+      json_value(const array_t &value) {
+        array = create<array_t>(value);
+      }
 
-    json_value(array_t &&value) {
-      array = create<array_t>(std::move(value));
-    }
+      json_value(array_t &&value) {
+        array = create<array_t>(std::move(value));
+      }
 
-    void destroy(value_t t) noexcept {
-      switch(t) {
-        case value_t::object: {
-          AllocatorType<object_t> alloc;
-          std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
-          std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
-          break;
-        }
+      void destroy(value_t t) noexcept {
+        switch(t) {
+          case value_t::object: {
+            AllocatorType<object_t> alloc;
+            std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
+            std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
+            break;
+          }
 
-        case value_t::array: {
-          AllocatorType<array_t> alloc;
-          std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
-          std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
-          break;
-        }
+          case value_t::array: {
+            AllocatorType<array_t> alloc;
+            std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
+            std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
+            break;
+          }
 
-        case value_t::string: {
-          AllocatorType<string_t> alloc;
-          std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
-          std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
-          break;
-        }
+          case value_t::string: {
+            AllocatorType<string_t> alloc;
+            std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
+            std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
+            break;
+          }
 
-        default: {
-          break;
+          default: {
+            break;
+          }
         }
       }
-    }
-  };
-
-  void assert_invariant() const noexcept {
-    assert(m_type != value_t::object or m_value.object != nullptr);
-    assert(m_type != value_t::array or m_value.array != nullptr);
-    assert(m_type != value_t::string or m_value.string != nullptr);
-  }
-
-public:
-  using parse_event_t = typename parser::parse_event_t;
-
-  using parser_callback_t = typename parser::parser_callback_t;
-
-  basic_json(const value_t v)
-      : m_type(v), m_value(v) {
-    assert_invariant();
-  }
-
-  basic_json(std::nullptr_t = nullptr) noexcept
-      : basic_json(value_t::null) {
-    assert_invariant();
-  }
-
-  template<typename CompatibleType,
-      typename U = detail::uncvref_t<CompatibleType>,
-      detail::enable_if_t<
-          detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
-  basic_json(CompatibleType &&val) noexcept(noexcept(
-      JSONSerializer<U>::to_json(std::declval<basic_json_t &>(),
-                                 std::forward<CompatibleType>(val)))) {
-    JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
-    assert_invariant();
-  }
+    };
 
-  template<typename BasicJsonType,
-      detail::enable_if_t<
-          detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
-  basic_json(const BasicJsonType &val) {
-    using other_boolean_t = typename BasicJsonType::boolean_t;
-    using other_number_float_t = typename BasicJsonType::number_float_t;
-    using other_number_integer_t = typename BasicJsonType::number_integer_t;
-    using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
-    using other_string_t = typename BasicJsonType::string_t;
-    using other_object_t = typename BasicJsonType::object_t;
-    using other_array_t = typename BasicJsonType::array_t;
-
-    switch(val.type()) {
-      case value_t::boolean:
-        JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
-        break;
-      case value_t::number_float:
-        JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
-        break;
-      case value_t::number_integer:
-        JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
-        break;
-      case value_t::number_unsigned:
-        JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
-        break;
-      case value_t::string:
-        JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t &>());
-        break;
-      case value_t::object:
-        JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t &>());
-        break;
-      case value_t::array:
-        JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t &>());
-        break;
-      case value_t::null:
-        *this = nullptr;
-        break;
-      case value_t::discarded:
-        m_type = value_t::discarded;
-        break;
-    }
-    assert_invariant();
-  }
+    void assert_invariant() const noexcept {
+      assert(m_type != value_t::object or m_value.object != nullptr);
+      assert(m_type != value_t::array or m_value.array != nullptr);
+      assert(m_type != value_t::string or m_value.string != nullptr);
+    }
 
-  basic_json(initializer_list_t init,
-             bool type_deduction = true,
-             value_t manual_type = value_t::array) {
-    bool is_an_object = std::all_of(init.begin(), init.end(),
-                                    [](const detail::json_ref<basic_json> &element_ref) {
-                                      return (element_ref->is_array() and element_ref->size() == 2 and
-                                              (*element_ref)[0].is_string());
-                                    });
+  public:
+    using parse_event_t = typename parser::parse_event_t;
 
-    if(not type_deduction) {
-      if(manual_type == value_t::array) {
-        is_an_object = false;
-      }
+    using parser_callback_t = typename parser::parser_callback_t;
 
-      if(JSON_UNLIKELY(manual_type == value_t::object and not is_an_object)) {
-        JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
-      }
+    basic_json(const value_t v)
+        : m_type(v), m_value(v) {
+      assert_invariant();
     }
 
-    if(is_an_object) {
-      m_type = value_t::object;
-      m_value = value_t::object;
-
-      std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json> &element_ref) {
-        auto element = element_ref.moved_or_copied();
-        m_value.object->emplace(
-            std::move(*((*element.m_value.array)[0].m_value.string)),
-            std::move((*element.m_value.array)[1]));
-      });
-    } else {
-      m_type = value_t::array;
-      m_value.array = create<array_t>(init.begin(), init.end());
+    basic_json(std::nullptr_t = nullptr) noexcept
+        : basic_json(value_t::null) {
+      assert_invariant();
     }
 
-    assert_invariant();
-  }
-
-  static basic_json array(initializer_list_t init = {}) {
-    return basic_json(init, false, value_t::array);
-  }
-
-  static basic_json object(initializer_list_t init = {}) {
-    return basic_json(init, false, value_t::object);
-  }
-
-  basic_json(size_type cnt, const basic_json &val)
-      : m_type(value_t::array) {
-    m_value.array = create<array_t>(cnt, val);
-    assert_invariant();
-  }
-
-  template<class InputIT, typename std::enable_if<
-      std::is_same<InputIT, typename basic_json_t::iterator>::value or
-      std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
-  basic_json(InputIT first, InputIT last) {
-    assert(first.m_object != nullptr);
-    assert(last.m_object != nullptr);
+    template<typename CompatibleType,
+        typename U = detail::uncvref_t<CompatibleType>,
+        detail::enable_if_t<
+            detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
+    basic_json(CompatibleType &&val) noexcept(noexcept(
+        JSONSerializer<U>::to_json(std::declval<basic_json_t &>(),
+                                   std::forward<CompatibleType>(val)))) {
+      JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
+      assert_invariant();
+    }
 
-    if(JSON_UNLIKELY(first.m_object != last.m_object)) {
-      JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
+    template<typename BasicJsonType,
+        detail::enable_if_t<
+            detail::is_basic_json<BasicJsonType>::value and
+            not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
+    basic_json(const BasicJsonType &val) {
+      using other_boolean_t = typename BasicJsonType::boolean_t;
+      using other_number_float_t = typename BasicJsonType::number_float_t;
+      using other_number_integer_t = typename BasicJsonType::number_integer_t;
+      using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+      using other_string_t = typename BasicJsonType::string_t;
+      using other_object_t = typename BasicJsonType::object_t;
+      using other_array_t = typename BasicJsonType::array_t;
+
+      switch(val.type()) {
+        case value_t::boolean:
+          JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
+          break;
+        case value_t::number_float:
+          JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
+          break;
+        case value_t::number_integer:
+          JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
+          break;
+        case value_t::number_unsigned:
+          JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
+          break;
+        case value_t::string:
+          JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t &>());
+          break;
+        case value_t::object:
+          JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t &>());
+          break;
+        case value_t::array:
+          JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t &>());
+          break;
+        case value_t::null:
+          *this = nullptr;
+          break;
+        case value_t::discarded:
+          m_type = value_t::discarded;
+          break;
+      }
+      assert_invariant();
     }
 
-    m_type = first.m_object->m_type;
+    basic_json(initializer_list_t init,
+               bool type_deduction = true,
+               value_t manual_type = value_t::array) {
+      bool is_an_object = std::all_of(init.begin(), init.end(),
+                                      [](const detail::json_ref<basic_json> &element_ref) {
+                                        return (element_ref->is_array() and element_ref->size() == 2 and
+                                                (*element_ref)[0].is_string());
+                                      });
 
-    switch(m_type) {
-      case value_t::boolean:
-      case value_t::number_float:
-      case value_t::number_integer:
-      case value_t::number_unsigned:
-      case value_t::string: {
-        if(JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
-                         or not last.m_it.primitive_iterator.is_end())) {
-          JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+      if(not type_deduction) {
+        if(manual_type == value_t::array) {
+          is_an_object = false;
+        }
+
+        if(JSON_UNLIKELY(manual_type == value_t::object and not is_an_object)) {
+          JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
         }
-        break;
       }
 
-      default:
-        break;
-    }
+      if(is_an_object) {
+        m_type = value_t::object;
+        m_value = value_t::object;
 
-    switch(m_type) {
-      case value_t::number_integer: {
-        m_value.number_integer = first.m_object->m_value.number_integer;
-        break;
+        std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json> &element_ref) {
+          auto element = element_ref.moved_or_copied();
+          m_value.object->emplace(
+              std::move(*((*element.m_value.array)[0].m_value.string)),
+              std::move((*element.m_value.array)[1]));
+        });
+      } else {
+        m_type = value_t::array;
+        m_value.array = create<array_t>(init.begin(), init.end());
       }
 
-      case value_t::number_unsigned: {
-        m_value.number_unsigned = first.m_object->m_value.number_unsigned;
-        break;
-      }
+      assert_invariant();
+    }
 
-      case value_t::number_float: {
-        m_value.number_float = first.m_object->m_value.number_float;
-        break;
-      }
+    static basic_json array(initializer_list_t init = {}) {
+      return basic_json(init, false, value_t::array);
+    }
 
-      case value_t::boolean: {
-        m_value.boolean = first.m_object->m_value.boolean;
-        break;
-      }
+    static basic_json object(initializer_list_t init = {}) {
+      return basic_json(init, false, value_t::object);
+    }
 
-      case value_t::string: {
-        m_value = *first.m_object->m_value.string;
-        break;
-      }
+    basic_json(size_type cnt, const basic_json &val)
+        : m_type(value_t::array) {
+      m_value.array = create<array_t>(cnt, val);
+      assert_invariant();
+    }
 
-      case value_t::object: {
-        m_value.object = create<object_t>(first.m_it.object_iterator,
-                                          last.m_it.object_iterator);
-        break;
-      }
+    template<class InputIT, typename std::enable_if<
+        std::is_same<InputIT, typename basic_json_t::iterator>::value or
+        std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
+    basic_json(InputIT first, InputIT last) {
+      assert(first.m_object != nullptr);
+      assert(last.m_object != nullptr);
 
-      case value_t::array: {
-        m_value.array = create<array_t>(first.m_it.array_iterator,
-                                        last.m_it.array_iterator);
-        break;
+      if(JSON_UNLIKELY(first.m_object != last.m_object)) {
+        JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
       }
 
-      default:
-        JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from "+
-                                                 std::string(first.m_object->type_name())));
-    }
+      m_type = first.m_object->m_type;
 
-    assert_invariant();
-  }
+      switch(m_type) {
+        case value_t::boolean:
+        case value_t::number_float:
+        case value_t::number_integer:
+        case value_t::number_unsigned:
+        case value_t::string: {
+          if(JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
+                           or not last.m_it.primitive_iterator.is_end())) {
+            JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+          }
+          break;
+        }
 
-  basic_json(const detail::json_ref<basic_json> &ref)
-      : basic_json(ref.moved_or_copied()) {}
+        default:
+          break;
+      }
 
-  basic_json(const basic_json &other)
-      : m_type(other.m_type) {
-    other.assert_invariant();
+      switch(m_type) {
+        case value_t::number_integer: {
+          m_value.number_integer = first.m_object->m_value.number_integer;
+          break;
+        }
 
-    switch(m_type) {
-      case value_t::object: {
-        m_value = *other.m_value.object;
-        break;
-      }
+        case value_t::number_unsigned: {
+          m_value.number_unsigned = first.m_object->m_value.number_unsigned;
+          break;
+        }
 
-      case value_t::array: {
-        m_value = *other.m_value.array;
-        break;
-      }
+        case value_t::number_float: {
+          m_value.number_float = first.m_object->m_value.number_float;
+          break;
+        }
 
-      case value_t::string: {
-        m_value = *other.m_value.string;
-        break;
-      }
+        case value_t::boolean: {
+          m_value.boolean = first.m_object->m_value.boolean;
+          break;
+        }
 
-      case value_t::boolean: {
-        m_value = other.m_value.boolean;
-        break;
-      }
+        case value_t::string: {
+          m_value = *first.m_object->m_value.string;
+          break;
+        }
 
-      case value_t::number_integer: {
-        m_value = other.m_value.number_integer;
-        break;
-      }
+        case value_t::object: {
+          m_value.object = create<object_t>(first.m_it.object_iterator,
+                                            last.m_it.object_iterator);
+          break;
+        }
 
-      case value_t::number_unsigned: {
-        m_value = other.m_value.number_unsigned;
-        break;
-      }
+        case value_t::array: {
+          m_value.array = create<array_t>(first.m_it.array_iterator,
+                                          last.m_it.array_iterator);
+          break;
+        }
 
-      case value_t::number_float: {
-        m_value = other.m_value.number_float;
-        break;
+        default:
+          JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from "+
+                                                   std::string(first.m_object->type_name())));
       }
 
-      default:
-        break;
+      assert_invariant();
     }
 
-    assert_invariant();
-  }
+    basic_json(const detail::json_ref<basic_json> &ref)
+        : basic_json(ref.moved_or_copied()) {}
 
-  basic_json(basic_json &&other) noexcept
-      : m_type(std::move(other.m_type)),
-        m_value(std::move(other.m_value)) {
-    other.assert_invariant();
+    basic_json(const basic_json &other)
+        : m_type(other.m_type) {
+      other.assert_invariant();
 
-    other.m_type = value_t::null;
-    other.m_value = {};
+      switch(m_type) {
+        case value_t::object: {
+          m_value = *other.m_value.object;
+          break;
+        }
 
-    assert_invariant();
-  }
+        case value_t::array: {
+          m_value = *other.m_value.array;
+          break;
+        }
 
-  reference &operator=(basic_json other) noexcept(
-  std::is_nothrow_move_constructible<value_t>::value and
-  std::is_nothrow_move_assignable<value_t>::value and
-  std::is_nothrow_move_constructible<json_value>::value and
-  std::is_nothrow_move_assignable<json_value>::value
-  ) {
-    other.assert_invariant();
+        case value_t::string: {
+          m_value = *other.m_value.string;
+          break;
+        }
+
+        case value_t::boolean: {
+          m_value = other.m_value.boolean;
+          break;
+        }
 
-    using std::swap;
-    swap(m_type, other.m_type);
-    swap(m_value, other.m_value);
+        case value_t::number_integer: {
+          m_value = other.m_value.number_integer;
+          break;
+        }
 
-    assert_invariant();
-    return *this;
-  }
+        case value_t::number_unsigned: {
+          m_value = other.m_value.number_unsigned;
+          break;
+        }
 
-  ~basic_json() noexcept {
-    assert_invariant();
-    m_value.destroy(m_type);
-  }
+        case value_t::number_float: {
+          m_value = other.m_value.number_float;
+          break;
+        }
 
-public:
-  string_t dump(const int indent = -1, const char indent_char = ' ',
-                const bool ensure_ascii = false) const {
-    string_t result;
-    serializer s(detail::output_adapter<char, string_t>(result), indent_char);
+        default:
+          break;
+      }
 
-    if(indent >= 0) {
-      s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
-    } else {
-      s.dump(*this, false, ensure_ascii, 0);
+      assert_invariant();
     }
 
-    return result;
-  }
+    basic_json(basic_json &&other) noexcept
+        : m_type(std::move(other.m_type)),
+          m_value(std::move(other.m_value)) {
+      other.assert_invariant();
 
-  constexpr value_t type() const noexcept {
-    return m_type;
-  }
+      other.m_type = value_t::null;
+      other.m_value = {};
 
-  constexpr bool is_primitive() const noexcept {
-    return is_null() or is_string() or is_boolean() or is_number();
-  }
+      assert_invariant();
+    }
 
-  constexpr bool is_structured() const noexcept {
-    return is_array() or is_object();
-  }
+    reference &operator=(basic_json other) noexcept(
+    std::is_nothrow_move_constructible<value_t>::value and
+    std::is_nothrow_move_assignable<value_t>::value and
+    std::is_nothrow_move_constructible<json_value>::value and
+    std::is_nothrow_move_assignable<json_value>::value
+    ) {
+      other.assert_invariant();
 
-  constexpr bool is_null() const noexcept {
-    return (m_type == value_t::null);
-  }
+      using std::swap;
+      swap(m_type, other.m_type);
+      swap(m_value, other.m_value);
 
-  constexpr bool is_boolean() const noexcept {
-    return (m_type == value_t::boolean);
-  }
+      assert_invariant();
+      return *this;
+    }
 
-  constexpr bool is_number() const noexcept {
-    return is_number_integer() or is_number_float();
-  }
+    ~basic_json() noexcept {
+      assert_invariant();
+      m_value.destroy(m_type);
+    }
 
-  constexpr bool is_number_integer() const noexcept {
-    return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
-  }
+  public:
+    string_t dump(const int indent = -1, const char indent_char = ' ',
+                  const bool ensure_ascii = false) const {
+      string_t result;
+      serializer s(detail::output_adapter<char, string_t>(result), indent_char);
 
-  constexpr bool is_number_unsigned() const noexcept {
-    return (m_type == value_t::number_unsigned);
-  }
+      if(indent >= 0) {
+        s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
+      } else {
+        s.dump(*this, false, ensure_ascii, 0);
+      }
 
-  constexpr bool is_number_float() const noexcept {
-    return (m_type == value_t::number_float);
-  }
+      return result;
+    }
 
-  constexpr bool is_object() const noexcept {
-    return (m_type == value_t::object);
-  }
+    constexpr value_t type() const noexcept {
+      return m_type;
+    }
 
-  constexpr bool is_array() const noexcept {
-    return (m_type == value_t::array);
-  }
+    constexpr bool is_primitive() const noexcept {
+      return is_null() or is_string() or is_boolean() or is_number();
+    }
 
-  constexpr bool is_string() const noexcept {
-    return (m_type == value_t::string);
-  }
+    constexpr bool is_structured() const noexcept {
+      return is_array() or is_object();
+    }
 
-  constexpr bool is_discarded() const noexcept {
-    return (m_type == value_t::discarded);
-  }
+    constexpr bool is_null() const noexcept {
+      return (m_type == value_t::null);
+    }
 
-  constexpr operator value_t() const noexcept {
-    return m_type;
-  }
+    constexpr bool is_boolean() const noexcept {
+      return (m_type == value_t::boolean);
+    }
 
-private:
-  boolean_t get_impl(boolean_t *) const {
-    if(JSON_LIKELY(is_boolean())) {
-      return m_value.boolean;
+    constexpr bool is_number() const noexcept {
+      return is_number_integer() or is_number_float();
     }
 
-    JSON_THROW(type_error::create(302, "type must be boolean, but is "+std::string(type_name())));
-  }
+    constexpr bool is_number_integer() const noexcept {
+      return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
+    }
 
-  object_t *get_impl_ptr(object_t *) noexcept {
-    return is_object() ? m_value.object : nullptr;
-  }
+    constexpr bool is_number_unsigned() const noexcept {
+      return (m_type == value_t::number_unsigned);
+    }
 
-  constexpr const object_t *get_impl_ptr(const object_t *) const noexcept {
-    return is_object() ? m_value.object : nullptr;
-  }
+    constexpr bool is_number_float() const noexcept {
+      return (m_type == value_t::number_float);
+    }
 
-  array_t *get_impl_ptr(array_t *) noexcept {
-    return is_array() ? m_value.array : nullptr;
-  }
+    constexpr bool is_object() const noexcept {
+      return (m_type == value_t::object);
+    }
 
-  constexpr const array_t *get_impl_ptr(const array_t *) const noexcept {
-    return is_array() ? m_value.array : nullptr;
-  }
+    constexpr bool is_array() const noexcept {
+      return (m_type == value_t::array);
+    }
 
-  string_t *get_impl_ptr(string_t *) noexcept {
-    return is_string() ? m_value.string : nullptr;
-  }
+    constexpr bool is_string() const noexcept {
+      return (m_type == value_t::string);
+    }
 
-  constexpr const string_t *get_impl_ptr(const string_t *) const noexcept {
-    return is_string() ? m_value.string : nullptr;
-  }
+    constexpr bool is_discarded() const noexcept {
+      return (m_type == value_t::discarded);
+    }
 
-  boolean_t *get_impl_ptr(boolean_t *) noexcept {
-    return is_boolean() ? &m_value.boolean : nullptr;
-  }
+    constexpr operator value_t() const noexcept {
+      return m_type;
+    }
 
-  constexpr const boolean_t *get_impl_ptr(const boolean_t *) const noexcept {
-    return is_boolean() ? &m_value.boolean : nullptr;
-  }
+  private:
+    boolean_t get_impl(boolean_t *) const {
+      if(JSON_LIKELY(is_boolean())) {
+        return m_value.boolean;
+      }
 
-  number_integer_t *get_impl_ptr(number_integer_t *) noexcept {
-    return is_number_integer() ? &m_value.number_integer : nullptr;
-  }
+      JSON_THROW(type_error::create(302, "type must be boolean, but is "+std::string(type_name())));
+    }
 
-  constexpr const number_integer_t *get_impl_ptr(const number_integer_t *) const noexcept {
-    return is_number_integer() ? &m_value.number_integer : nullptr;
-  }
+    object_t *get_impl_ptr(object_t *) noexcept {
+      return is_object() ? m_value.object : nullptr;
+    }
 
-  number_unsigned_t *get_impl_ptr(number_unsigned_t *) noexcept {
-    return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
-  }
+    constexpr const object_t *get_impl_ptr(const object_t *) const noexcept {
+      return is_object() ? m_value.object : nullptr;
+    }
 
-  constexpr const number_unsigned_t *get_impl_ptr(const number_unsigned_t *) const noexcept {
-    return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
-  }
+    array_t *get_impl_ptr(array_t *) noexcept {
+      return is_array() ? m_value.array : nullptr;
+    }
 
-  number_float_t *get_impl_ptr(number_float_t *) noexcept {
-    return is_number_float() ? &m_value.number_float : nullptr;
-  }
+    constexpr const array_t *get_impl_ptr(const array_t *) const noexcept {
+      return is_array() ? m_value.array : nullptr;
+    }
 
-  constexpr const number_float_t *get_impl_ptr(const number_float_t *) const noexcept {
-    return is_number_float() ? &m_value.number_float : nullptr;
-  }
+    string_t *get_impl_ptr(string_t *) noexcept {
+      return is_string() ? m_value.string : nullptr;
+    }
 
-  template<typename ReferenceType, typename ThisType>
-  static ReferenceType get_ref_impl(ThisType &obj) {
-    auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
+    constexpr const string_t *get_impl_ptr(const string_t *) const noexcept {
+      return is_string() ? m_value.string : nullptr;
+    }
 
-    if(JSON_LIKELY(ptr != nullptr)) {
-      return *ptr;
+    boolean_t *get_impl_ptr(boolean_t *) noexcept {
+      return is_boolean() ? &m_value.boolean : nullptr;
     }
 
-    JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is "+
-                                       std::string(obj.type_name())));
-  }
+    constexpr const boolean_t *get_impl_ptr(const boolean_t *) const noexcept {
+      return is_boolean() ? &m_value.boolean : nullptr;
+    }
 
-public:
-  template<typename BasicJsonType, detail::enable_if_t<
-      std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
-      int> = 0>
-  basic_json get() const {
-    return *this;
-  }
+    number_integer_t *get_impl_ptr(number_integer_t *) noexcept {
+      return is_number_integer() ? &m_value.number_integer : nullptr;
+    }
 
-  template<typename BasicJsonType, detail::enable_if_t<
-      not std::is_same<BasicJsonType, basic_json>::value and
-      detail::is_basic_json<BasicJsonType>::value, int> = 0>
-  BasicJsonType get() const {
-    return *this;
-  }
+    constexpr const number_integer_t *get_impl_ptr(const number_integer_t *) const noexcept {
+      return is_number_integer() ? &m_value.number_integer : nullptr;
+    }
 
-  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
-      detail::enable_if_t<
-          not detail::is_basic_json<ValueType>::value and
-          detail::has_from_json<basic_json_t, ValueType>::value and
-          not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
-          int> = 0>
-  ValueType get() const noexcept(noexcept(
-      JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t &>(), std::declval<ValueType &>()))) {
-    static_assert(not std::is_reference<ValueTypeCV>::value,
-                  "get() cannot be used with reference types, you might want to use get_ref()");
-    static_assert(std::is_default_constructible<ValueType>::value,
-                  "types must be DefaultConstructible when used with get()");
-
-    ValueType ret;
-    JSONSerializer<ValueType>::from_json(*this, ret);
-    return ret;
-  }
+    number_unsigned_t *get_impl_ptr(number_unsigned_t *) noexcept {
+      return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
+    }
 
-  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
-      detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
-                          detail::has_non_default_from_json<basic_json_t, ValueType>::value,
-          int> = 0>
-  ValueType get() const noexcept(noexcept(
-      JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t &>()))) {
-    static_assert(not std::is_reference<ValueTypeCV>::value,
-                  "get() cannot be used with reference types, you might want to use get_ref()");
-    return JSONSerializer<ValueTypeCV>::from_json(*this);
-  }
+    constexpr const number_unsigned_t *get_impl_ptr(const number_unsigned_t *) const noexcept {
+      return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
+    }
 
-  template<typename PointerType, typename std::enable_if<
-      std::is_pointer<PointerType>::value, int>::type = 0>
-  PointerType get() noexcept {
-    return get_ptr<PointerType>();
-  }
+    number_float_t *get_impl_ptr(number_float_t *) noexcept {
+      return is_number_float() ? &m_value.number_float : nullptr;
+    }
 
-  template<typename PointerType, typename std::enable_if<
-      std::is_pointer<PointerType>::value, int>::type = 0>
-  constexpr const PointerType get() const noexcept {
-    return get_ptr<PointerType>();
-  }
+    constexpr const number_float_t *get_impl_ptr(const number_float_t *) const noexcept {
+      return is_number_float() ? &m_value.number_float : nullptr;
+    }
 
-  template<typename PointerType, typename std::enable_if<
-      std::is_pointer<PointerType>::value, int>::type = 0>
-  PointerType get_ptr() noexcept {
-    using pointee_t = typename std::remove_const<typename
-    std::remove_pointer<typename
-    std::remove_const<PointerType>::type>::type>::type;
-
-    static_assert(
-        std::is_same<object_t, pointee_t>::value
-        or std::is_same<array_t, pointee_t>::value
-        or std::is_same<string_t, pointee_t>::value
-        or std::is_same<boolean_t, pointee_t>::value
-        or std::is_same<number_integer_t, pointee_t>::value
-        or std::is_same<number_unsigned_t, pointee_t>::value
-        or std::is_same<number_float_t, pointee_t>::value, "incompatible pointer type");
-
-    return get_impl_ptr(static_cast<PointerType>(nullptr));
-  }
+    template<typename ReferenceType, typename ThisType>
+    static ReferenceType get_ref_impl(ThisType &obj) {
+      auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
 
-  template<typename PointerType, typename std::enable_if<
-      std::is_pointer<PointerType>::value and
-      std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
-  constexpr const PointerType get_ptr() const noexcept {
-    using pointee_t = typename std::remove_const<typename
-    std::remove_pointer<typename
-    std::remove_const<PointerType>::type>::type>::type;
-
-    static_assert(
-        std::is_same<object_t, pointee_t>::value
-        or std::is_same<array_t, pointee_t>::value
-        or std::is_same<string_t, pointee_t>::value
-        or std::is_same<boolean_t, pointee_t>::value
-        or std::is_same<number_integer_t, pointee_t>::value
-        or std::is_same<number_unsigned_t, pointee_t>::value
-        or std::is_same<number_float_t, pointee_t>::value, "incompatible pointer type");
-
-    return get_impl_ptr(static_cast<PointerType>(nullptr));
-  }
+      if(JSON_LIKELY(ptr != nullptr)) {
+        return *ptr;
+      }
 
-  template<typename ReferenceType, typename std::enable_if<
-      std::is_reference<ReferenceType>::value, int>::type = 0>
-  ReferenceType get_ref() {
-    return get_ref_impl<ReferenceType>(*this);
-  }
+      JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is "+
+                                         std::string(obj.type_name())));
+    }
 
-  template<typename ReferenceType, typename std::enable_if<
-      std::is_reference<ReferenceType>::value and
-      std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
-  ReferenceType get_ref() const {
-    return get_ref_impl<ReferenceType>(*this);
-  }
+  public:
+    template<typename BasicJsonType, detail::enable_if_t<
+        std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
+        int> = 0>
+    basic_json get() const {
+      return *this;
+    }
+
+    template<typename BasicJsonType, detail::enable_if_t<
+        not std::is_same<BasicJsonType, basic_json>::value and
+        detail::is_basic_json<BasicJsonType>::value, int> = 0>
+    BasicJsonType get() const {
+      return *this;
+    }
 
-  template<typename ValueType, typename std::enable_if<
-      not std::is_pointer<ValueType>::value and
-      not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
-      not std::is_same<ValueType, typename string_t::value_type>::value and
-      not detail::is_basic_json<ValueType>::value
-      #ifndef _MSC_VER
-      and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
+    template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
+        detail::enable_if_t<
+            not detail::is_basic_json<ValueType>::value and
+            detail::has_from_json<basic_json_t, ValueType>::value and
+            not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
+            int> = 0>
+    ValueType get() const noexcept(noexcept(
+        JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t &>(), std::declval<ValueType &>()))) {
+      static_assert(not std::is_reference<ValueTypeCV>::value,
+                    "get() cannot be used with reference types, you might want to use get_ref()");
+      static_assert(std::is_default_constructible<ValueType>::value,
+                    "types must be DefaultConstructible when used with get()");
+
+      ValueType ret;
+      JSONSerializer<ValueType>::from_json(*this, ret);
+      return ret;
+    }
+
+    template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
+        detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
+                            detail::has_non_default_from_json<basic_json_t, ValueType>::value,
+            int> = 0>
+    ValueType get() const noexcept(noexcept(
+        JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t &>()))) {
+      static_assert(not std::is_reference<ValueTypeCV>::value,
+                    "get() cannot be used with reference types, you might want to use get_ref()");
+      return JSONSerializer<ValueTypeCV>::from_json(*this);
+    }
+
+    template<typename PointerType, typename std::enable_if<
+        std::is_pointer<PointerType>::value, int>::type = 0>
+    PointerType get() noexcept {
+      return get_ptr<PointerType>();
+    }
+
+    template<typename PointerType, typename std::enable_if<
+        std::is_pointer<PointerType>::value, int>::type = 0>
+    constexpr const PointerType get() const noexcept {
+      return get_ptr<PointerType>();
+    }
+
+    template<typename PointerType, typename std::enable_if<
+        std::is_pointer<PointerType>::value, int>::type = 0>
+    PointerType get_ptr() noexcept {
+      using pointee_t = typename std::remove_const<typename
+      std::remove_pointer<typename
+      std::remove_const<PointerType>::type>::type>::type;
+
+      static_assert(
+          std::is_same<object_t, pointee_t>::value
+          or std::is_same<array_t, pointee_t>::value
+          or std::is_same<string_t, pointee_t>::value
+          or std::is_same<boolean_t, pointee_t>::value
+          or std::is_same<number_integer_t, pointee_t>::value
+          or std::is_same<number_unsigned_t, pointee_t>::value
+          or std::is_same<number_float_t, pointee_t>::value, "incompatible pointer type");
+
+      return get_impl_ptr(static_cast<PointerType>(nullptr));
+    }
+
+    template<typename PointerType, typename std::enable_if<
+        std::is_pointer<PointerType>::value and
+        std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
+    constexpr const PointerType get_ptr() const noexcept {
+      using pointee_t = typename std::remove_const<typename
+      std::remove_pointer<typename
+      std::remove_const<PointerType>::type>::type>::type;
+
+      static_assert(
+          std::is_same<object_t, pointee_t>::value
+          or std::is_same<array_t, pointee_t>::value
+          or std::is_same<string_t, pointee_t>::value
+          or std::is_same<boolean_t, pointee_t>::value
+          or std::is_same<number_integer_t, pointee_t>::value
+          or std::is_same<number_unsigned_t, pointee_t>::value
+          or std::is_same<number_float_t, pointee_t>::value, "incompatible pointer type");
+
+      return get_impl_ptr(static_cast<PointerType>(nullptr));
+    }
+
+    template<typename ReferenceType, typename std::enable_if<
+        std::is_reference<ReferenceType>::value, int>::type = 0>
+    ReferenceType get_ref() {
+      return get_ref_impl<ReferenceType>(*this);
+    }
+
+    template<typename ReferenceType, typename std::enable_if<
+        std::is_reference<ReferenceType>::value and
+        std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
+    ReferenceType get_ref() const {
+      return get_ref_impl<ReferenceType>(*this);
+    }
+
+    template<typename ValueType, typename std::enable_if<
+        not std::is_pointer<ValueType>::value and
+        not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
+        not std::is_same<ValueType, typename string_t::value_type>::value and
+        not detail::is_basic_json<ValueType>::value
+        #ifndef _MSC_VER
+        and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
 #endif
 #if defined(JSON_HAS_CPP_17)
-      and not std::is_same<ValueType, typename std::string_view>::value
+        and not std::is_same<ValueType, typename std::string_view>::value
 #endif
-      , int>::type = 0>
-  operator ValueType() const {
-    return get<ValueType>();
-  }
+        , int>::type = 0>
+    operator ValueType() const {
+      return get<ValueType>();
+    }
 
-  reference at(size_type idx) {
-    if(JSON_LIKELY(is_array())) {
-      JSON_TRY {
-        return m_value.array->at(idx);
-      }
-      JSON_CATCH (std::out_of_range &) {
-        JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+    reference at(size_type idx) {
+      if(JSON_LIKELY(is_array())) {
+        JSON_TRY {
+          return m_value.array->at(idx);
+        }
+        JSON_CATCH (std::out_of_range &) {
+          JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+        }
+      } else {
+        JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
       }
-    } else {
-      JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
     }
-  }
 
-  const_reference at(size_type idx) const {
-    if(JSON_LIKELY(is_array())) {
-      JSON_TRY {
-        return m_value.array->at(idx);
-      }
-      JSON_CATCH (std::out_of_range &) {
-        JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+    const_reference at(size_type idx) const {
+      if(JSON_LIKELY(is_array())) {
+        JSON_TRY {
+          return m_value.array->at(idx);
+        }
+        JSON_CATCH (std::out_of_range &) {
+          JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+        }
+      } else {
+        JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
       }
-    } else {
-      JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
     }
-  }
 
-  reference at(const typename object_t::key_type &key) {
-    if(JSON_LIKELY(is_object())) {
-      JSON_TRY {
-        return m_value.object->at(key);
+    reference at(const typename object_t::key_type &key) {
+      if(JSON_LIKELY(is_object())) {
+        JSON_TRY {
+          return m_value.object->at(key);
+        }
+        JSON_CATCH (std::out_of_range &) {
+          JSON_THROW(out_of_range::create(403, "key '"+key+"' not found"));
+        }
+      } else {
+        JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
       }
-      JSON_CATCH (std::out_of_range &) {
-        JSON_THROW(out_of_range::create(403, "key '"+key+"' not found"));
+    }
+
+    const_reference at(const typename object_t::key_type &key) const {
+      if(JSON_LIKELY(is_object())) {
+        JSON_TRY {
+          return m_value.object->at(key);
+        }
+        JSON_CATCH (std::out_of_range &) {
+          JSON_THROW(out_of_range::create(403, "key '"+key+"' not found"));
+        }
+      } else {
+        JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
       }
-    } else {
-      JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
     }
-  }
 
-  const_reference at(const typename object_t::key_type &key) const {
-    if(JSON_LIKELY(is_object())) {
-      JSON_TRY {
-        return m_value.object->at(key);
+    reference operator[](size_type idx) {
+      if(is_null()) {
+        m_type = value_t::array;
+        m_value.array = create<array_t>();
+        assert_invariant();
       }
-      JSON_CATCH (std::out_of_range &) {
-        JSON_THROW(out_of_range::create(403, "key '"+key+"' not found"));
+
+      if(JSON_LIKELY(is_array())) {
+        if(idx >= m_value.array->size()) {
+          m_value.array->insert(m_value.array->end(),
+                                idx-m_value.array->size()+1,
+                                basic_json());
+        }
+
+        return m_value.array->operator[](idx);
       }
-    } else {
-      JSON_THROW(type_error::create(304, "cannot use at() with "+std::string(type_name())));
-    }
-  }
 
-  reference operator[](size_type idx) {
-    if(is_null()) {
-      m_type = value_t::array;
-      m_value.array = create<array_t>();
-      assert_invariant();
+      JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
     }
 
-    if(JSON_LIKELY(is_array())) {
-      if(idx >= m_value.array->size()) {
-        m_value.array->insert(m_value.array->end(),
-                              idx-m_value.array->size()+1,
-                              basic_json());
+    const_reference operator[](size_type idx) const {
+      if(JSON_LIKELY(is_array())) {
+        return m_value.array->operator[](idx);
       }
 
-      return m_value.array->operator[](idx);
+      JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
     }
 
-    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
-  }
+    reference operator[](const typename object_t::key_type &key) {
+      if(is_null()) {
+        m_type = value_t::object;
+        m_value.object = create<object_t>();
+        assert_invariant();
+      }
+
+      if(JSON_LIKELY(is_object())) {
+        return m_value.object->operator[](key);
+      }
 
-  const_reference operator[](size_type idx) const {
-    if(JSON_LIKELY(is_array())) {
-      return m_value.array->operator[](idx);
+      JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
     }
 
-    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
-  }
+    const_reference operator[](const typename object_t::key_type &key) const {
+      if(JSON_LIKELY(is_object())) {
+        assert(m_value.object->find(key) != m_value.object->end());
+        return m_value.object->find(key)->second;
+      }
 
-  reference operator[](const typename object_t::key_type &key) {
-    if(is_null()) {
-      m_type = value_t::object;
-      m_value.object = create<object_t>();
-      assert_invariant();
+      JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
     }
 
-    if(JSON_LIKELY(is_object())) {
-      return m_value.object->operator[](key);
-    }
+    template<typename T>
+    reference operator[](T *key) {
+      if(is_null()) {
+        m_type = value_t::object;
+        m_value = value_t::object;
+        assert_invariant();
+      }
 
-    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
-  }
+      if(JSON_LIKELY(is_object())) {
+        return m_value.object->operator[](key);
+      }
 
-  const_reference operator[](const typename object_t::key_type &key) const {
-    if(JSON_LIKELY(is_object())) {
-      assert(m_value.object->find(key) != m_value.object->end());
-      return m_value.object->find(key)->second;
+      JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
     }
 
-    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
-  }
+    template<typename T>
+    const_reference operator[](T *key) const {
+      if(JSON_LIKELY(is_object())) {
+        assert(m_value.object->find(key) != m_value.object->end());
+        return m_value.object->find(key)->second;
+      }
 
-  template<typename T>
-  reference operator[](T *key) {
-    if(is_null()) {
-      m_type = value_t::object;
-      m_value = value_t::object;
-      assert_invariant();
+      JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
     }
 
-    if(JSON_LIKELY(is_object())) {
-      return m_value.object->operator[](key);
-    }
+    template<class ValueType, typename std::enable_if<
+        std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
+    ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const {
+      if(JSON_LIKELY(is_object())) {
+        const auto it = find(key);
+        if(it != end()) {
+          return *it;
+        }
 
-    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
-  }
+        return default_value;
+      }
 
-  template<typename T>
-  const_reference operator[](T *key) const {
-    if(JSON_LIKELY(is_object())) {
-      assert(m_value.object->find(key) != m_value.object->end());
-      return m_value.object->find(key)->second;
+      JSON_THROW(type_error::create(306, "cannot use value() with "+std::string(type_name())));
     }
 
-    JSON_THROW(type_error::create(305, "cannot use operator[] with "+std::string(type_name())));
-  }
+    string_t value(const typename object_t::key_type &key, const char *default_value) const {
+      return value(key, string_t(default_value));
+    }
 
-  template<class ValueType, typename std::enable_if<
-      std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
-  ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const {
-    if(JSON_LIKELY(is_object())) {
-      const auto it = find(key);
-      if(it != end()) {
-        return *it;
+    template<class ValueType, typename std::enable_if<
+        std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
+    ValueType value(const json_pointer &ptr, const ValueType &default_value) const {
+      if(JSON_LIKELY(is_object())) {
+        JSON_TRY {
+          return ptr.get_checked(this);
+        }
+        JSON_CATCH (out_of_range &) {
+          return default_value;
+        }
       }
 
-      return default_value;
+      JSON_THROW(type_error::create(306, "cannot use value() with "+std::string(type_name())));
     }
 
-    JSON_THROW(type_error::create(306, "cannot use value() with "+std::string(type_name())));
-  }
-
-  string_t value(const typename object_t::key_type &key, const char *default_value) const {
-    return value(key, string_t(default_value));
-  }
+    string_t value(const json_pointer &ptr, const char *default_value) const {
+      return value(ptr, string_t(default_value));
+    }
 
-  template<class ValueType, typename std::enable_if<
-      std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
-  ValueType value(const json_pointer &ptr, const ValueType &default_value) const {
-    if(JSON_LIKELY(is_object())) {
-      JSON_TRY {
-        return ptr.get_checked(this);
-      }
-      JSON_CATCH (out_of_range &) {
-        return default_value;
-      }
+    reference front() {
+      return *begin();
     }
 
-    JSON_THROW(type_error::create(306, "cannot use value() with "+std::string(type_name())));
-  }
+    const_reference front() const {
+      return *cbegin();
+    }
 
-  string_t value(const json_pointer &ptr, const char *default_value) const {
-    return value(ptr, string_t(default_value));
-  }
+    reference back() {
+      auto tmp = end();
+      --tmp;
+      return *tmp;
+    }
 
-  reference front() {
-    return *begin();
-  }
+    const_reference back() const {
+      auto tmp = cend();
+      --tmp;
+      return *tmp;
+    }
 
-  const_reference front() const {
-    return *cbegin();
-  }
+    template<class IteratorType, typename std::enable_if<
+        std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+        std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+    = 0>
+    IteratorType erase(IteratorType pos) {
+      if(JSON_UNLIKELY(this != pos.m_object)) {
+        JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+      }
 
-  reference back() {
-    auto tmp = end();
-    --tmp;
-    return *tmp;
-  }
+      IteratorType result = end();
 
-  const_reference back() const {
-    auto tmp = cend();
-    --tmp;
-    return *tmp;
-  }
+      switch(m_type) {
+        case value_t::boolean:
+        case value_t::number_float:
+        case value_t::number_integer:
+        case value_t::number_unsigned:
+        case value_t::string: {
+          if(JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin())) {
+            JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
+          }
 
-  template<class IteratorType, typename std::enable_if<
-      std::is_same<IteratorType, typename basic_json_t::iterator>::value or
-      std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
-  = 0>
-  IteratorType erase(IteratorType pos) {
-    if(JSON_UNLIKELY(this != pos.m_object)) {
-      JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
-    }
+          if(is_string()) {
+            AllocatorType<string_t> alloc;
+            std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
+            std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
+            m_value.string = nullptr;
+          }
 
-    IteratorType result = end();
+          m_type = value_t::null;
+          assert_invariant();
+          break;
+        }
 
-    switch(m_type) {
-      case value_t::boolean:
-      case value_t::number_float:
-      case value_t::number_integer:
-      case value_t::number_unsigned:
-      case value_t::string: {
-        if(JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin())) {
-          JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
+        case value_t::object: {
+          result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
+          break;
         }
 
-        if(is_string()) {
-          AllocatorType<string_t> alloc;
-          std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
-          std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
-          m_value.string = nullptr;
+        case value_t::array: {
+          result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
+          break;
         }
 
-        m_type = value_t::null;
-        assert_invariant();
-        break;
+        default:
+          JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
       }
 
-      case value_t::object: {
-        result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
-        break;
-      }
+      return result;
+    }
 
-      case value_t::array: {
-        result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
-        break;
+    template<class IteratorType, typename std::enable_if<
+        std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+        std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+    = 0>
+    IteratorType erase(IteratorType first, IteratorType last) {
+      if(JSON_UNLIKELY(this != first.m_object or this != last.m_object)) {
+        JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
       }
 
-      default:
-        JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
-    }
+      IteratorType result = end();
 
-    return result;
-  }
+      switch(m_type) {
+        case value_t::boolean:
+        case value_t::number_float:
+        case value_t::number_integer:
+        case value_t::number_unsigned:
+        case value_t::string: {
+          if(JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
+                         or not last.m_it.primitive_iterator.is_end())) {
+            JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+          }
 
-  template<class IteratorType, typename std::enable_if<
-      std::is_same<IteratorType, typename basic_json_t::iterator>::value or
-      std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
-  = 0>
-  IteratorType erase(IteratorType first, IteratorType last) {
-    if(JSON_UNLIKELY(this != first.m_object or this != last.m_object)) {
-      JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
-    }
+          if(is_string()) {
+            AllocatorType<string_t> alloc;
+            std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
+            std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
+            m_value.string = nullptr;
+          }
 
-    IteratorType result = end();
+          m_type = value_t::null;
+          assert_invariant();
+          break;
+        }
 
-    switch(m_type) {
-      case value_t::boolean:
-      case value_t::number_float:
-      case value_t::number_integer:
-      case value_t::number_unsigned:
-      case value_t::string: {
-        if(JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
-                       or not last.m_it.primitive_iterator.is_end())) {
-          JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+        case value_t::object: {
+          result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
+                                                              last.m_it.object_iterator);
+          break;
         }
 
-        if(is_string()) {
-          AllocatorType<string_t> alloc;
-          std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
-          std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
-          m_value.string = nullptr;
+        case value_t::array: {
+          result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
+                                                            last.m_it.array_iterator);
+          break;
         }
 
-        m_type = value_t::null;
-        assert_invariant();
-        break;
+        default:
+          JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
       }
 
-      case value_t::object: {
-        result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
-                                                            last.m_it.object_iterator);
-        break;
-      }
+      return result;
+    }
 
-      case value_t::array: {
-        result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
-                                                          last.m_it.array_iterator);
-        break;
+    size_type erase(const typename object_t::key_type &key) {
+      if(JSON_LIKELY(is_object())) {
+        return m_value.object->erase(key);
       }
 
-      default:
+      JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
+    }
+
+    void erase(const size_type idx) {
+      if(JSON_LIKELY(is_array())) {
+        if(JSON_UNLIKELY(idx >= size())) {
+          JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+        }
+
+        m_value.array->erase(m_value.array->begin()+static_cast<difference_type>(idx));
+      } else {
         JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
+      }
     }
 
-    return result;
-  }
+    template<typename KeyT>
+    iterator find(KeyT &&key) {
+      auto result = end();
+
+      if(is_object()) {
+        result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
+      }
 
-  size_type erase(const typename object_t::key_type &key) {
-    if(JSON_LIKELY(is_object())) {
-      return m_value.object->erase(key);
+      return result;
     }
 
-    JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
-  }
+    template<typename KeyT>
+    const_iterator find(KeyT &&key) const {
+      auto result = cend();
 
-  void erase(const size_type idx) {
-    if(JSON_LIKELY(is_array())) {
-      if(JSON_UNLIKELY(idx >= size())) {
-        JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+      if(is_object()) {
+        result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
       }
 
-      m_value.array->erase(m_value.array->begin()+static_cast<difference_type>(idx));
-    } else {
-      JSON_THROW(type_error::create(307, "cannot use erase() with "+std::string(type_name())));
+      return result;
     }
-  }
 
-  template<typename KeyT>
-  iterator find(KeyT &&key) {
-    auto result = end();
+    template<typename KeyT>
+    size_type count(KeyT &&key) const {
+      return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
+    }
 
-    if(is_object()) {
-      result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
+    iterator begin() noexcept {
+      iterator result(this);
+      result.set_begin();
+      return result;
     }
 
-    return result;
-  }
+    const_iterator begin() const noexcept {
+      return cbegin();
+    }
+
+    const_iterator cbegin() const noexcept {
+      const_iterator result(this);
+      result.set_begin();
+      return result;
+    }
 
-  template<typename KeyT>
-  const_iterator find(KeyT &&key) const {
-    auto result = cend();
+    iterator end() noexcept {
+      iterator result(this);
+      result.set_end();
+      return result;
+    }
 
-    if(is_object()) {
-      result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
+    const_iterator end() const noexcept {
+      return cend();
     }
 
-    return result;
-  }
+    const_iterator cend() const noexcept {
+      const_iterator result(this);
+      result.set_end();
+      return result;
+    }
 
-  template<typename KeyT>
-  size_type count(KeyT &&key) const {
-    return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
-  }
+    reverse_iterator rbegin() noexcept {
+      return reverse_iterator(end());
+    }
 
-  iterator begin() noexcept {
-    iterator result(this);
-    result.set_begin();
-    return result;
-  }
+    const_reverse_iterator rbegin() const noexcept {
+      return crbegin();
+    }
 
-  const_iterator begin() const noexcept {
-    return cbegin();
-  }
+    reverse_iterator rend() noexcept {
+      return reverse_iterator(begin());
+    }
 
-  const_iterator cbegin() const noexcept {
-    const_iterator result(this);
-    result.set_begin();
-    return result;
-  }
+    const_reverse_iterator rend() const noexcept {
+      return crend();
+    }
 
-  iterator end() noexcept {
-    iterator result(this);
-    result.set_end();
-    return result;
-  }
+    const_reverse_iterator crbegin() const noexcept {
+      return const_reverse_iterator(cend());
+    }
 
-  const_iterator end() const noexcept {
-    return cend();
-  }
+    const_reverse_iterator crend() const noexcept {
+      return const_reverse_iterator(cbegin());
+    }
 
-  const_iterator cend() const noexcept {
-    const_iterator result(this);
-    result.set_end();
-    return result;
-  }
+  public:
+    iteration_proxy<iterator> items() noexcept {
+      return iteration_proxy<iterator>(*this);
+    }
 
-  reverse_iterator rbegin() noexcept {
-    return reverse_iterator(end());
-  }
+    iteration_proxy<const_iterator> items() const noexcept {
+      return iteration_proxy<const_iterator>(*this);
+    }
 
-  const_reverse_iterator rbegin() const noexcept {
-    return crbegin();
-  }
+    bool empty() const noexcept {
+      switch(m_type) {
+        case value_t::null: {
+          return true;
+        }
 
-  reverse_iterator rend() noexcept {
-    return reverse_iterator(begin());
-  }
+        case value_t::array: {
+          return m_value.array->empty();
+        }
 
-  const_reverse_iterator rend() const noexcept {
-    return crend();
-  }
+        case value_t::object: {
+          return m_value.object->empty();
+        }
 
-  const_reverse_iterator crbegin() const noexcept {
-    return const_reverse_iterator(cend());
-  }
+        default: {
+          return false;
+        }
+      }
+    }
 
-  const_reverse_iterator crend() const noexcept {
-    return const_reverse_iterator(cbegin());
-  }
+    size_type size() const noexcept {
+      switch(m_type) {
+        case value_t::null: {
+          return 0;
+        }
 
-public:
-  iteration_proxy<iterator> items() noexcept {
-    return iteration_proxy<iterator>(*this);
-  }
+        case value_t::array: {
+          return m_value.array->size();
+        }
 
-  iteration_proxy<const_iterator> items() const noexcept {
-    return iteration_proxy<const_iterator>(*this);
-  }
+        case value_t::object: {
+          return m_value.object->size();
+        }
 
-  bool empty() const noexcept {
-    switch(m_type) {
-      case value_t::null: {
-        return true;
+        default: {
+          return 1;
+        }
       }
+    }
 
-      case value_t::array: {
-        return m_value.array->empty();
-      }
+    size_type max_size() const noexcept {
+      switch(m_type) {
+        case value_t::array: {
+          return m_value.array->max_size();
+        }
 
-      case value_t::object: {
-        return m_value.object->empty();
-      }
+        case value_t::object: {
+          return m_value.object->max_size();
+        }
 
-      default: {
-        return false;
+        default: {
+          return size();
+        }
       }
     }
-  }
 
-  size_type size() const noexcept {
-    switch(m_type) {
-      case value_t::null: {
-        return 0;
-      }
+    void clear() noexcept {
+      switch(m_type) {
+        case value_t::number_integer: {
+          m_value.number_integer = 0;
+          break;
+        }
 
-      case value_t::array: {
-        return m_value.array->size();
-      }
+        case value_t::number_unsigned: {
+          m_value.number_unsigned = 0;
+          break;
+        }
 
-      case value_t::object: {
-        return m_value.object->size();
-      }
+        case value_t::number_float: {
+          m_value.number_float = 0.0;
+          break;
+        }
 
-      default: {
-        return 1;
-      }
-    }
-  }
+        case value_t::boolean: {
+          m_value.boolean = false;
+          break;
+        }
 
-  size_type max_size() const noexcept {
-    switch(m_type) {
-      case value_t::array: {
-        return m_value.array->max_size();
-      }
+        case value_t::string: {
+          m_value.string->clear();
+          break;
+        }
 
-      case value_t::object: {
-        return m_value.object->max_size();
-      }
+        case value_t::array: {
+          m_value.array->clear();
+          break;
+        }
+
+        case value_t::object: {
+          m_value.object->clear();
+          break;
+        }
 
-      default: {
-        return size();
+        default:
+          break;
       }
     }
-  }
 
-  void clear() noexcept {
-    switch(m_type) {
-      case value_t::number_integer: {
-        m_value.number_integer = 0;
-        break;
+    void push_back(basic_json &&val) {
+      if(JSON_UNLIKELY(not(is_null() or is_array()))) {
+        JSON_THROW(type_error::create(308, "cannot use push_back() with "+std::string(type_name())));
       }
 
-      case value_t::number_unsigned: {
-        m_value.number_unsigned = 0;
-        break;
+      if(is_null()) {
+        m_type = value_t::array;
+        m_value = value_t::array;
+        assert_invariant();
       }
 
-      case value_t::number_float: {
-        m_value.number_float = 0.0;
-        break;
-      }
+      m_value.array->push_back(std::move(val));
 
-      case value_t::boolean: {
-        m_value.boolean = false;
-        break;
-      }
+      val.m_type = value_t::null;
+    }
 
-      case value_t::string: {
-        m_value.string->clear();
-        break;
-      }
+    reference operator+=(basic_json &&val) {
+      push_back(std::move(val));
+      return *this;
+    }
 
-      case value_t::array: {
-        m_value.array->clear();
-        break;
+    void push_back(const basic_json &val) {
+      if(JSON_UNLIKELY(not(is_null() or is_array()))) {
+        JSON_THROW(type_error::create(308, "cannot use push_back() with "+std::string(type_name())));
       }
 
-      case value_t::object: {
-        m_value.object->clear();
-        break;
+      if(is_null()) {
+        m_type = value_t::array;
+        m_value = value_t::array;
+        assert_invariant();
       }
 
-      default:
-        break;
-    }
-  }
-
-  void push_back(basic_json &&val) {
-    if(JSON_UNLIKELY(not(is_null() or is_array()))) {
-      JSON_THROW(type_error::create(308, "cannot use push_back() with "+std::string(type_name())));
+      m_value.array->push_back(val);
     }
 
-    if(is_null()) {
-      m_type = value_t::array;
-      m_value = value_t::array;
-      assert_invariant();
+    reference operator+=(const basic_json &val) {
+      push_back(val);
+      return *this;
     }
 
-    m_value.array->push_back(std::move(val));
+    void push_back(const typename object_t::value_type &val) {
+      if(JSON_UNLIKELY(not(is_null() or is_object()))) {
+        JSON_THROW(type_error::create(308, "cannot use push_back() with "+std::string(type_name())));
+      }
 
-    val.m_type = value_t::null;
-  }
+      if(is_null()) {
+        m_type = value_t::object;
+        m_value = value_t::object;
+        assert_invariant();
+      }
 
-  reference operator+=(basic_json &&val) {
-    push_back(std::move(val));
-    return *this;
-  }
+      m_value.object->insert(val);
+    }
 
-  void push_back(const basic_json &val) {
-    if(JSON_UNLIKELY(not(is_null() or is_array()))) {
-      JSON_THROW(type_error::create(308, "cannot use push_back() with "+std::string(type_name())));
+    reference operator+=(const typename object_t::value_type &val) {
+      push_back(val);
+      return *this;
     }
 
-    if(is_null()) {
-      m_type = value_t::array;
-      m_value = value_t::array;
-      assert_invariant();
+    void push_back(initializer_list_t init) {
+      if(is_object() and init.size() == 2 and (*init.begin())->is_string()) {
+        basic_json &&key = init.begin()->moved_or_copied();
+        push_back(typename object_t::value_type(
+            std::move(key.get_ref<string_t &>()), (init.begin()+1)->moved_or_copied()));
+      } else {
+        push_back(basic_json(init));
+      }
     }
 
-    m_value.array->push_back(val);
-  }
+    reference operator+=(initializer_list_t init) {
+      push_back(init);
+      return *this;
+    }
 
-  reference operator+=(const basic_json &val) {
-    push_back(val);
-    return *this;
-  }
+    template<class... Args>
+    void emplace_back(Args &&... args) {
+      if(JSON_UNLIKELY(not(is_null() or is_array()))) {
+        JSON_THROW(type_error::create(311, "cannot use emplace_back() with "+std::string(type_name())));
+      }
 
-  void push_back(const typename object_t::value_type &val) {
-    if(JSON_UNLIKELY(not(is_null() or is_object()))) {
-      JSON_THROW(type_error::create(308, "cannot use push_back() with "+std::string(type_name())));
-    }
+      if(is_null()) {
+        m_type = value_t::array;
+        m_value = value_t::array;
+        assert_invariant();
+      }
 
-    if(is_null()) {
-      m_type = value_t::object;
-      m_value = value_t::object;
-      assert_invariant();
+      m_value.array->emplace_back(std::forward<Args>(args)...);
     }
 
-    m_value.object->insert(val);
-  }
+    template<class... Args>
+    std::pair<iterator, bool> emplace(Args &&... args) {
+      if(JSON_UNLIKELY(not(is_null() or is_object()))) {
+        JSON_THROW(type_error::create(311, "cannot use emplace() with "+std::string(type_name())));
+      }
 
-  reference operator+=(const typename object_t::value_type &val) {
-    push_back(val);
-    return *this;
-  }
+      if(is_null()) {
+        m_type = value_t::object;
+        m_value = value_t::object;
+        assert_invariant();
+      }
 
-  void push_back(initializer_list_t init) {
-    if(is_object() and init.size() == 2 and (*init.begin())->is_string()) {
-      basic_json &&key = init.begin()->moved_or_copied();
-      push_back(typename object_t::value_type(
-          std::move(key.get_ref<string_t &>()), (init.begin()+1)->moved_or_copied()));
-    } else {
-      push_back(basic_json(init));
-    }
-  }
+      auto res = m_value.object->emplace(std::forward<Args>(args)...);
 
-  reference operator+=(initializer_list_t init) {
-    push_back(init);
-    return *this;
-  }
+      auto it = begin();
+      it.m_it.object_iterator = res.first;
 
-  template<class... Args>
-  void emplace_back(Args &&... args) {
-    if(JSON_UNLIKELY(not(is_null() or is_array()))) {
-      JSON_THROW(type_error::create(311, "cannot use emplace_back() with "+std::string(type_name())));
+      return {it, res.second};
     }
 
-    if(is_null()) {
-      m_type = value_t::array;
-      m_value = value_t::array;
-      assert_invariant();
-    }
+    iterator insert(const_iterator pos, const basic_json &val) {
+      if(JSON_LIKELY(is_array())) {
+        if(JSON_UNLIKELY(pos.m_object != this)) {
+          JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+        }
 
-    m_value.array->emplace_back(std::forward<Args>(args)...);
-  }
+        iterator result(this);
+        result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
+        return result;
+      }
 
-  template<class... Args>
-  std::pair<iterator, bool> emplace(Args &&... args) {
-    if(JSON_UNLIKELY(not(is_null() or is_object()))) {
-      JSON_THROW(type_error::create(311, "cannot use emplace() with "+std::string(type_name())));
+      JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
     }
 
-    if(is_null()) {
-      m_type = value_t::object;
-      m_value = value_t::object;
-      assert_invariant();
+    iterator insert(const_iterator pos, basic_json &&val) {
+      return insert(pos, val);
     }
 
-    auto res = m_value.object->emplace(std::forward<Args>(args)...);
+    iterator insert(const_iterator pos, size_type cnt, const basic_json &val) {
+      if(JSON_LIKELY(is_array())) {
+        if(JSON_UNLIKELY(pos.m_object != this)) {
+          JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+        }
 
-    auto it = begin();
-    it.m_it.object_iterator = res.first;
+        iterator result(this);
+        result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
+        return result;
+      }
 
-    return {it, res.second};
-  }
+      JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
+    }
+
+    iterator insert(const_iterator pos, const_iterator first, const_iterator last) {
+      if(JSON_UNLIKELY(not is_array())) {
+        JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
+      }
 
-  iterator insert(const_iterator pos, const basic_json &val) {
-    if(JSON_LIKELY(is_array())) {
       if(JSON_UNLIKELY(pos.m_object != this)) {
         JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
       }
 
+      if(JSON_UNLIKELY(first.m_object != last.m_object)) {
+        JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+      }
+
+      if(JSON_UNLIKELY(first.m_object == this)) {
+        JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
+      }
+
       iterator result(this);
-      result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
+      result.m_it.array_iterator = m_value.array->insert(
+          pos.m_it.array_iterator,
+          first.m_it.array_iterator,
+          last.m_it.array_iterator);
       return result;
     }
 
-    JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
-  }
-
-  iterator insert(const_iterator pos, basic_json &&val) {
-    return insert(pos, val);
-  }
+    iterator insert(const_iterator pos, initializer_list_t ilist) {
+      if(JSON_UNLIKELY(not is_array())) {
+        JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
+      }
 
-  iterator insert(const_iterator pos, size_type cnt, const basic_json &val) {
-    if(JSON_LIKELY(is_array())) {
       if(JSON_UNLIKELY(pos.m_object != this)) {
         JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
       }
 
       iterator result(this);
-      result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
+      result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
       return result;
     }
 
-    JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
-  }
-
-  iterator insert(const_iterator pos, const_iterator first, const_iterator last) {
-    if(JSON_UNLIKELY(not is_array())) {
-      JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
-    }
-
-    if(JSON_UNLIKELY(pos.m_object != this)) {
-      JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
-    }
-
-    if(JSON_UNLIKELY(first.m_object != last.m_object)) {
-      JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
-    }
-
-    if(JSON_UNLIKELY(first.m_object == this)) {
-      JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
-    }
+    void insert(const_iterator first, const_iterator last) {
+      if(JSON_UNLIKELY(not is_object())) {
+        JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
+      }
 
-    iterator result(this);
-    result.m_it.array_iterator = m_value.array->insert(
-        pos.m_it.array_iterator,
-        first.m_it.array_iterator,
-        last.m_it.array_iterator);
-    return result;
-  }
+      if(JSON_UNLIKELY(first.m_object != last.m_object)) {
+        JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+      }
 
-  iterator insert(const_iterator pos, initializer_list_t ilist) {
-    if(JSON_UNLIKELY(not is_array())) {
-      JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
-    }
+      if(JSON_UNLIKELY(not first.m_object->is_object())) {
+        JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+      }
 
-    if(JSON_UNLIKELY(pos.m_object != this)) {
-      JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+      m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
     }
 
-    iterator result(this);
-    result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
-    return result;
-  }
+    void update(const_reference j) {
+      if(is_null()) {
+        m_type = value_t::object;
+        m_value.object = create<object_t>();
+        assert_invariant();
+      }
 
-  void insert(const_iterator first, const_iterator last) {
-    if(JSON_UNLIKELY(not is_object())) {
-      JSON_THROW(type_error::create(309, "cannot use insert() with "+std::string(type_name())));
-    }
+      if(JSON_UNLIKELY(not is_object())) {
+        JSON_THROW(type_error::create(312, "cannot use update() with "+std::string(type_name())));
+      }
+      if(JSON_UNLIKELY(not j.is_object())) {
+        JSON_THROW(type_error::create(312, "cannot use update() with "+std::string(j.type_name())));
+      }
 
-    if(JSON_UNLIKELY(first.m_object != last.m_object)) {
-      JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+      for(auto it = j.cbegin(); it != j.cend(); ++it) {
+        m_value.object->operator[](it.key()) = it.value();
+      }
     }
 
-    if(JSON_UNLIKELY(not first.m_object->is_object())) {
-      JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
-    }
+    void update(const_iterator first, const_iterator last) {
+      if(is_null()) {
+        m_type = value_t::object;
+        m_value.object = create<object_t>();
+        assert_invariant();
+      }
 
-    m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
-  }
+      if(JSON_UNLIKELY(not is_object())) {
+        JSON_THROW(type_error::create(312, "cannot use update() with "+std::string(type_name())));
+      }
 
-  void update(const_reference j) {
-    if(is_null()) {
-      m_type = value_t::object;
-      m_value.object = create<object_t>();
-      assert_invariant();
-    }
+      if(JSON_UNLIKELY(first.m_object != last.m_object)) {
+        JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+      }
 
-    if(JSON_UNLIKELY(not is_object())) {
-      JSON_THROW(type_error::create(312, "cannot use update() with "+std::string(type_name())));
-    }
-    if(JSON_UNLIKELY(not j.is_object())) {
-      JSON_THROW(type_error::create(312, "cannot use update() with "+std::string(j.type_name())));
-    }
+      if(JSON_UNLIKELY(not first.m_object->is_object()
+                       or not last.m_object->is_object())) {
+        JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+      }
 
-    for(auto it = j.cbegin(); it != j.cend(); ++it) {
-      m_value.object->operator[](it.key()) = it.value();
+      for(auto it = first; it != last; ++it) {
+        m_value.object->operator[](it.key()) = it.value();
+      }
     }
-  }
 
-  void update(const_iterator first, const_iterator last) {
-    if(is_null()) {
-      m_type = value_t::object;
-      m_value.object = create<object_t>();
+    void swap(reference other) noexcept(
+    std::is_nothrow_move_constructible<value_t>::value and
+    std::is_nothrow_move_assignable<value_t>::value and
+    std::is_nothrow_move_constructible<json_value>::value and
+    std::is_nothrow_move_assignable<json_value>::value
+    ) {
+      std::swap(m_type, other.m_type);
+      std::swap(m_value, other.m_value);
       assert_invariant();
     }
 
-    if(JSON_UNLIKELY(not is_object())) {
-      JSON_THROW(type_error::create(312, "cannot use update() with "+std::string(type_name())));
-    }
-
-    if(JSON_UNLIKELY(first.m_object != last.m_object)) {
-      JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
-    }
-
-    if(JSON_UNLIKELY(not first.m_object->is_object()
-                     or not last.m_object->is_object())) {
-      JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
-    }
-
-    for(auto it = first; it != last; ++it) {
-      m_value.object->operator[](it.key()) = it.value();
-    }
-  }
-
-  void swap(reference other) noexcept(
-  std::is_nothrow_move_constructible<value_t>::value and
-  std::is_nothrow_move_assignable<value_t>::value and
-  std::is_nothrow_move_constructible<json_value>::value and
-  std::is_nothrow_move_assignable<json_value>::value
-  ) {
-    std::swap(m_type, other.m_type);
-    std::swap(m_value, other.m_value);
-    assert_invariant();
-  }
-
-  void swap(array_t &other) {
-    if(JSON_LIKELY(is_array())) {
-      std::swap(*(m_value.array), other);
-    } else {
-      JSON_THROW(type_error::create(310, "cannot use swap() with "+std::string(type_name())));
-    }
-  }
-
-  void swap(object_t &other) {
-    if(JSON_LIKELY(is_object())) {
-      std::swap(*(m_value.object), other);
-    } else {
-      JSON_THROW(type_error::create(310, "cannot use swap() with "+std::string(type_name())));
+    void swap(array_t &other) {
+      if(JSON_LIKELY(is_array())) {
+        std::swap(*(m_value.array), other);
+      } else {
+        JSON_THROW(type_error::create(310, "cannot use swap() with "+std::string(type_name())));
+      }
     }
-  }
 
-  void swap(string_t &other) {
-    if(JSON_LIKELY(is_string())) {
-      std::swap(*(m_value.string), other);
-    } else {
-      JSON_THROW(type_error::create(310, "cannot use swap() with "+std::string(type_name())));
+    void swap(object_t &other) {
+      if(JSON_LIKELY(is_object())) {
+        std::swap(*(m_value.object), other);
+      } else {
+        JSON_THROW(type_error::create(310, "cannot use swap() with "+std::string(type_name())));
+      }
     }
-  }
-
-public:
-  friend bool operator==(const_reference lhs, const_reference rhs) noexcept {
-    const auto lhs_type = lhs.type();
-    const auto rhs_type = rhs.type();
-
-    if(lhs_type == rhs_type) {
-      switch(lhs_type) {
-        case value_t::array:
-          return (*lhs.m_value.array == *rhs.m_value.array);
-
-        case value_t::object:
-          return (*lhs.m_value.object == *rhs.m_value.object);
-
-        case value_t::null:
-          return true;
-
-        case value_t::string:
-          return (*lhs.m_value.string == *rhs.m_value.string);
-
-        case value_t::boolean:
-          return (lhs.m_value.boolean == rhs.m_value.boolean);
 
-        case value_t::number_integer:
-          return (lhs.m_value.number_integer == rhs.m_value.number_integer);
-
-        case value_t::number_unsigned:
-          return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
-
-        case value_t::number_float:
-          return (lhs.m_value.number_float == rhs.m_value.number_float);
-
-        default:
-          return false;
+    void swap(string_t &other) {
+      if(JSON_LIKELY(is_string())) {
+        std::swap(*(m_value.string), other);
+      } else {
+        JSON_THROW(type_error::create(310, "cannot use swap() with "+std::string(type_name())));
       }
-    } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
-      return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
-    } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
-      return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
-    } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
-      return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
-    } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
-      return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
-    } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
-      return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
-    } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
-      return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
-    }
-
-    return false;
-  }
-
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept {
-    return (lhs == basic_json(rhs));
-  }
-
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept {
-    return (basic_json(lhs) == rhs);
-  }
-
-  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept {
-    return not(lhs == rhs);
-  }
-
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept {
-    return (lhs != basic_json(rhs));
-  }
-
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept {
-    return (basic_json(lhs) != rhs);
-  }
+    }
 
-  friend bool operator<(const_reference lhs, const_reference rhs) noexcept {
-    const auto lhs_type = lhs.type();
-    const auto rhs_type = rhs.type();
+  public:
+    friend bool operator==(const_reference lhs, const_reference rhs) noexcept {
+      const auto lhs_type = lhs.type();
+      const auto rhs_type = rhs.type();
 
-    if(lhs_type == rhs_type) {
-      switch(lhs_type) {
-        case value_t::array:
-          return (*lhs.m_value.array) < (*rhs.m_value.array);
+      if(lhs_type == rhs_type) {
+        switch(lhs_type) {
+          case value_t::array:
+            return (*lhs.m_value.array == *rhs.m_value.array);
 
-        case value_t::object:
-          return *lhs.m_value.object < *rhs.m_value.object;
+          case value_t::object:
+            return (*lhs.m_value.object == *rhs.m_value.object);
 
-        case value_t::null:
-          return false;
+          case value_t::null:
+            return true;
 
-        case value_t::string:
-          return *lhs.m_value.string < *rhs.m_value.string;
+          case value_t::string:
+            return (*lhs.m_value.string == *rhs.m_value.string);
 
-        case value_t::boolean:
-          return lhs.m_value.boolean < rhs.m_value.boolean;
+          case value_t::boolean:
+            return (lhs.m_value.boolean == rhs.m_value.boolean);
 
-        case value_t::number_integer:
-          return lhs.m_value.number_integer < rhs.m_value.number_integer;
+          case value_t::number_integer:
+            return (lhs.m_value.number_integer == rhs.m_value.number_integer);
 
-        case value_t::number_unsigned:
-          return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
+          case value_t::number_unsigned:
+            return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
 
-        case value_t::number_float:
-          return lhs.m_value.number_float < rhs.m_value.number_float;
+          case value_t::number_float:
+            return (lhs.m_value.number_float == rhs.m_value.number_float);
 
-        default:
-          return false;
+          default:
+            return false;
+        }
+      } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
+        return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
+      } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
+        return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
+      } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
+        return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
+      } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
+        return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
+      } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
+        return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
+      } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
+        return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
       }
-    } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
-      return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
-    } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
-      return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
-    } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
-      return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
-    } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
-      return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
-    } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
-      return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
-    } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
-      return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
-    }
-
-    return operator<(lhs_type, rhs_type);
-  }
 
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept {
-    return (lhs < basic_json(rhs));
-  }
+      return false;
+    }
 
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept {
-    return (basic_json(lhs) < rhs);
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept {
+      return (lhs == basic_json(rhs));
+    }
 
-  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept {
-    return not(rhs < lhs);
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept {
+      return (basic_json(lhs) == rhs);
+    }
 
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept {
-    return (lhs <= basic_json(rhs));
-  }
+    friend bool operator!=(const_reference lhs, const_reference rhs) noexcept {
+      return not(lhs == rhs);
+    }
 
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept {
-    return (basic_json(lhs) <= rhs);
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept {
+      return (lhs != basic_json(rhs));
+    }
 
-  friend bool operator>(const_reference lhs, const_reference rhs) noexcept {
-    return not(lhs <= rhs);
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept {
+      return (basic_json(lhs) != rhs);
+    }
 
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept {
-    return (lhs > basic_json(rhs));
-  }
+    friend bool operator<(const_reference lhs, const_reference rhs) noexcept {
+      const auto lhs_type = lhs.type();
+      const auto rhs_type = rhs.type();
 
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept {
-    return (basic_json(lhs) > rhs);
-  }
+      if(lhs_type == rhs_type) {
+        switch(lhs_type) {
+          case value_t::array:
+            return (*lhs.m_value.array) < (*rhs.m_value.array);
 
-  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept {
-    return not(lhs < rhs);
-  }
+          case value_t::object:
+            return *lhs.m_value.object < *rhs.m_value.object;
 
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept {
-    return (lhs >= basic_json(rhs));
-  }
+          case value_t::null:
+            return false;
 
-  template<typename ScalarType, typename std::enable_if<
-      std::is_scalar<ScalarType>::value, int>::type = 0>
-  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept {
-    return (basic_json(lhs) >= rhs);
-  }
+          case value_t::string:
+            return *lhs.m_value.string < *rhs.m_value.string;
 
-  friend std::ostream &operator<<(std::ostream &o, const basic_json &j) {
-    const bool pretty_print = (o.width() > 0);
-    const auto indentation = (pretty_print ? o.width() : 0);
+          case value_t::boolean:
+            return lhs.m_value.boolean < rhs.m_value.boolean;
 
-    o.width(0);
+          case value_t::number_integer:
+            return lhs.m_value.number_integer < rhs.m_value.number_integer;
 
-    serializer s(detail::output_adapter<char>(o), o.fill());
-    s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
-    return o;
-  }
+          case value_t::number_unsigned:
+            return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
 
-  static basic_json parse(detail::input_adapter i,
-                          const parser_callback_t cb = nullptr,
-                          const bool allow_exceptions = true) {
-    basic_json result;
-    parser(i, cb, allow_exceptions).parse(true, result);
-    return result;
-  }
+          case value_t::number_float:
+            return lhs.m_value.number_float < rhs.m_value.number_float;
 
-  static basic_json parse(detail::input_adapter &i,
-                          const parser_callback_t cb = nullptr,
-                          const bool allow_exceptions = true) {
-    basic_json result;
-    parser(i, cb, allow_exceptions).parse(true, result);
-    return result;
-  }
+          default:
+            return false;
+        }
+      } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
+        return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
+      } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
+        return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
+      } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
+        return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
+      } else if(lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
+        return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
+      } else if(lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
+        return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
+      } else if(lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
+        return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
+      }
 
-  static bool accept(detail::input_adapter i) {
-    return parser(i).accept(true);
-  }
+      return operator<(lhs_type, rhs_type);
+    }
 
-  static bool accept(detail::input_adapter &i) {
-    return parser(i).accept(true);
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept {
+      return (lhs < basic_json(rhs));
+    }
 
-  template<class IteratorType, typename std::enable_if<
-      std::is_base_of<
-          std::random_access_iterator_tag,
-          typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
-  static basic_json parse(IteratorType first, IteratorType last,
-                          const parser_callback_t cb = nullptr,
-                          const bool allow_exceptions = true) {
-    basic_json result;
-    parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
-    return result;
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept {
+      return (basic_json(lhs) < rhs);
+    }
 
-  template<class IteratorType, typename std::enable_if<
-      std::is_base_of<
-          std::random_access_iterator_tag,
-          typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
-  static bool accept(IteratorType first, IteratorType last) {
-    return parser(detail::input_adapter(first, last)).accept(true);
-  }
+    friend bool operator<=(const_reference lhs, const_reference rhs) noexcept {
+      return not(rhs < lhs);
+    }
 
-  friend std::istream &operator>>(std::istream &i, basic_json &j) {
-    parser(detail::input_adapter(i)).parse(false, j);
-    return i;
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept {
+      return (lhs <= basic_json(rhs));
+    }
 
-  const char *type_name() const noexcept {
-    {
-      switch(m_type) {
-        case value_t::null:
-          return "null";
-        case value_t::object:
-          return "object";
-        case value_t::array:
-          return "array";
-        case value_t::string:
-          return "string";
-        case value_t::boolean:
-          return "boolean";
-        case value_t::discarded:
-          return "discarded";
-        default:
-          return "number";
-      }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept {
+      return (basic_json(lhs) <= rhs);
     }
-  }
 
-private:
-  value_t m_type = value_t::null;
+    friend bool operator>(const_reference lhs, const_reference rhs) noexcept {
+      return not(lhs <= rhs);
+    }
 
-  json_value m_value = {};
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept {
+      return (lhs > basic_json(rhs));
+    }
 
-public:
-  static std::vector<uint8_t> to_cbor(const basic_json &j) {
-    std::vector<uint8_t> result;
-    to_cbor(j, result);
-    return result;
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept {
+      return (basic_json(lhs) > rhs);
+    }
 
-  static void to_cbor(const basic_json &j, detail::output_adapter<uint8_t> o) {
-    binary_writer<uint8_t>(o).write_cbor(j);
-  }
+    friend bool operator>=(const_reference lhs, const_reference rhs) noexcept {
+      return not(lhs < rhs);
+    }
 
-  static void to_cbor(const basic_json &j, detail::output_adapter<char> o) {
-    binary_writer<char>(o).write_cbor(j);
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept {
+      return (lhs >= basic_json(rhs));
+    }
 
-  static std::vector<uint8_t> to_msgpack(const basic_json &j) {
-    std::vector<uint8_t> result;
-    to_msgpack(j, result);
-    return result;
-  }
+    template<typename ScalarType, typename std::enable_if<
+        std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept {
+      return (basic_json(lhs) >= rhs);
+    }
 
-  static void to_msgpack(const basic_json &j, detail::output_adapter<uint8_t> o) {
-    binary_writer<uint8_t>(o).write_msgpack(j);
-  }
+    friend std::ostream &operator<<(std::ostream &o, const basic_json &j) {
+      const bool pretty_print = (o.width() > 0);
+      const auto indentation = (pretty_print ? o.width() : 0);
 
-  static void to_msgpack(const basic_json &j, detail::output_adapter<char> o) {
-    binary_writer<char>(o).write_msgpack(j);
-  }
+      o.width(0);
 
-  static std::vector<uint8_t> to_ubjson(const basic_json &j,
-                                        const bool use_size = false,
-                                        const bool use_type = false) {
-    std::vector<uint8_t> result;
-    to_ubjson(j, result, use_size, use_type);
-    return result;
-  }
+      serializer s(detail::output_adapter<char>(o), o.fill());
+      s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
+      return o;
+    }
 
-  static void to_ubjson(const basic_json &j, detail::output_adapter<uint8_t> o,
-                        const bool use_size = false, const bool use_type = false) {
-    binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
-  }
+    static basic_json parse(detail::input_adapter i,
+                            const parser_callback_t cb = nullptr,
+                            const bool allow_exceptions = true) {
+      basic_json result;
+      parser(i, cb, allow_exceptions).parse(true, result);
+      return result;
+    }
 
-  static void to_ubjson(const basic_json &j, detail::output_adapter<char> o,
-                        const bool use_size = false, const bool use_type = false) {
-    binary_writer<char>(o).write_ubjson(j, use_size, use_type);
-  }
+    static basic_json parse(detail::input_adapter &i,
+                            const parser_callback_t cb = nullptr,
+                            const bool allow_exceptions = true) {
+      basic_json result;
+      parser(i, cb, allow_exceptions).parse(true, result);
+      return result;
+    }
 
-  static basic_json from_cbor(detail::input_adapter i,
-                              const bool strict = true) {
-    return binary_reader(i).parse_cbor(strict);
-  }
+    static bool accept(detail::input_adapter i) {
+      return parser(i).accept(true);
+    }
 
-  template<typename A1, typename A2,
-      detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
-  static basic_json from_cbor(A1 &&a1, A2 &&a2, const bool strict = true) {
-    return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
-  }
+    static bool accept(detail::input_adapter &i) {
+      return parser(i).accept(true);
+    }
 
-  static basic_json from_msgpack(detail::input_adapter i,
-                                 const bool strict = true) {
-    return binary_reader(i).parse_msgpack(strict);
-  }
+    template<class IteratorType, typename std::enable_if<
+        std::is_base_of<
+            std::random_access_iterator_tag,
+            typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
+    static basic_json parse(IteratorType first, IteratorType last,
+                            const parser_callback_t cb = nullptr,
+                            const bool allow_exceptions = true) {
+      basic_json result;
+      parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
+      return result;
+    }
 
-  template<typename A1, typename A2,
-      detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
-  static basic_json from_msgpack(A1 &&a1, A2 &&a2, const bool strict = true) {
-    return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
-  }
+    template<class IteratorType, typename std::enable_if<
+        std::is_base_of<
+            std::random_access_iterator_tag,
+            typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
+    static bool accept(IteratorType first, IteratorType last) {
+      return parser(detail::input_adapter(first, last)).accept(true);
+    }
 
-  static basic_json from_ubjson(detail::input_adapter i,
-                                const bool strict = true) {
-    return binary_reader(i).parse_ubjson(strict);
-  }
+    friend std::istream &operator>>(std::istream &i, basic_json &j) {
+      parser(detail::input_adapter(i)).parse(false, j);
+      return i;
+    }
 
-  template<typename A1, typename A2,
-      detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
-  static basic_json from_ubjson(A1 &&a1, A2 &&a2, const bool strict = true) {
-    return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_ubjson(strict);
-  }
+    const char *type_name() const noexcept {
+      {
+        switch(m_type) {
+          case value_t::null:
+            return "null";
+          case value_t::object:
+            return "object";
+          case value_t::array:
+            return "array";
+          case value_t::string:
+            return "string";
+          case value_t::boolean:
+            return "boolean";
+          case value_t::discarded:
+            return "discarded";
+          default:
+            return "number";
+        }
+      }
+    }
 
-  reference operator[](const json_pointer &ptr) {
-    return ptr.get_unchecked(this);
-  }
+  private:
+    value_t m_type = value_t::null;
 
-  const_reference operator[](const json_pointer &ptr) const {
-    return ptr.get_unchecked(this);
-  }
+    json_value m_value = {};
 
-  reference at(const json_pointer &ptr) {
-    return ptr.get_checked(this);
-  }
+  public:
+    reference operator[](const json_pointer &ptr) {
+      return ptr.get_unchecked(this);
+    }
 
-  const_reference at(const json_pointer &ptr) const {
-    return ptr.get_checked(this);
-  }
+    const_reference operator[](const json_pointer &ptr) const {
+      return ptr.get_unchecked(this);
+    }
 
-  basic_json flatten() const {
-    basic_json result(value_t::object);
-    json_pointer::flatten("", *this, result);
-    return result;
-  }
+    reference at(const json_pointer &ptr) {
+      return ptr.get_checked(this);
+    }
 
-  basic_json unflatten() const {
-    return json_pointer::unflatten(*this);
-  }
+    const_reference at(const json_pointer &ptr) const {
+      return ptr.get_checked(this);
+    }
 
-  basic_json patch(const basic_json &json_patch) const {
-    basic_json result = *this;
+    basic_json flatten() const {
+      basic_json result(value_t::object);
+      json_pointer::flatten("", *this, result);
+      return result;
+    }
 
-    enum class patch_operations {
-      add, remove, replace, move, copy, test, invalid
-    };
+    basic_json unflatten() const {
+      return json_pointer::unflatten(*this);
+    }
 
-    const auto get_op = [](const std::string &op) {
-      if(op == "add") {
-        return patch_operations::add;
-      }
-      if(op == "remove") {
-        return patch_operations::remove;
-      }
-      if(op == "replace") {
-        return patch_operations::replace;
-      }
-      if(op == "move") {
-        return patch_operations::move;
-      }
-      if(op == "copy") {
-        return patch_operations::copy;
-      }
-      if(op == "test") {
-        return patch_operations::test;
-      }
+    basic_json patch(const basic_json &json_patch) const {
+      basic_json result = *this;
 
-      return patch_operations::invalid;
-    };
+      enum class patch_operations {
+        add, remove, replace, move, copy, test, invalid
+      };
 
-    const auto operation_add = [&result](json_pointer &ptr, basic_json val) {
-      if(ptr.is_root()) {
-        result = val;
-      } else {
-        json_pointer top_pointer = ptr.top();
-        if(top_pointer != ptr) {
-          result.at(top_pointer);
+      const auto get_op = [](const std::string &op) {
+        if(op == "add") {
+          return patch_operations::add;
+        }
+        if(op == "remove") {
+          return patch_operations::remove;
+        }
+        if(op == "replace") {
+          return patch_operations::replace;
+        }
+        if(op == "move") {
+          return patch_operations::move;
+        }
+        if(op == "copy") {
+          return patch_operations::copy;
+        }
+        if(op == "test") {
+          return patch_operations::test;
         }
 
-        const auto last_path = ptr.pop_back();
-        basic_json &parent = result[ptr];
+        return patch_operations::invalid;
+      };
 
-        switch(parent.m_type) {
-          case value_t::null:
-          case value_t::object: {
-            parent[last_path] = val;
-            break;
+      const auto operation_add = [&result](json_pointer &ptr, basic_json val) {
+        if(ptr.is_root()) {
+          result = val;
+        } else {
+          json_pointer top_pointer = ptr.top();
+          if(top_pointer != ptr) {
+            result.at(top_pointer);
           }
 
-          case value_t::array: {
-            if(last_path == "-") {
-              parent.push_back(val);
-            } else {
-              const auto idx = json_pointer::array_index(last_path);
-              if(JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size())) {
-                JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+          const auto last_path = ptr.pop_back();
+          basic_json &parent = result[ptr];
+
+          switch(parent.m_type) {
+            case value_t::null:
+            case value_t::object: {
+              parent[last_path] = val;
+              break;
+            }
+
+            case value_t::array: {
+              if(last_path == "-") {
+                parent.push_back(val);
               } else {
-                parent.insert(parent.begin()+static_cast<difference_type>(idx), val);
+                const auto idx = json_pointer::array_index(last_path);
+                if(JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size())) {
+                  JSON_THROW(out_of_range::create(401, "array index "+std::to_string(idx)+" is out of range"));
+                } else {
+                  parent.insert(parent.begin()+static_cast<difference_type>(idx), val);
+                }
               }
+              break;
             }
-            break;
-          }
 
-          default: {
-            assert(false);
+            default: {
+              assert(false);
+            }
           }
         }
-      }
-    };
-
-    const auto operation_remove = [&result](json_pointer &ptr) {
-      const auto last_path = ptr.pop_back();
-      basic_json &parent = result.at(ptr);
-
-      if(parent.is_object()) {
-        auto it = parent.find(last_path);
-        if(JSON_LIKELY(it != parent.end())) {
-          parent.erase(it);
-        } else {
-          JSON_THROW(out_of_range::create(403, "key '"+last_path+"' not found"));
-        }
-      } else if(parent.is_array()) {
-        parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
-      }
-    };
-
-    if(JSON_UNLIKELY(not json_patch.is_array())) {
-      JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
-    }
-
-    for(const auto &val : json_patch) {
-      const auto get_value = [&val](const std::string &op,
-                                    const std::string &member,
-                                    bool string_type) -> basic_json & {
-        auto it = val.m_value.object->find(member);
-
-        const auto error_msg = (op == "op") ? "operation" : "operation '"+op+"'";
+      };
 
-        if(JSON_UNLIKELY(it == val.m_value.object->end())) {
-          JSON_THROW(parse_error::create(105, 0, error_msg+" must have member '"+member+"'"));
-        }
+      const auto operation_remove = [&result](json_pointer &ptr) {
+        const auto last_path = ptr.pop_back();
+        basic_json &parent = result.at(ptr);
 
-        if(JSON_UNLIKELY(string_type and not it->second.is_string())) {
-          JSON_THROW(parse_error::create(105, 0, error_msg+" must have string member '"+member+"'"));
+        if(parent.is_object()) {
+          auto it = parent.find(last_path);
+          if(JSON_LIKELY(it != parent.end())) {
+            parent.erase(it);
+          } else {
+            JSON_THROW(out_of_range::create(403, "key '"+last_path+"' not found"));
+          }
+        } else if(parent.is_array()) {
+          parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
         }
-
-        return it->second;
       };
 
-      if(JSON_UNLIKELY(not val.is_object())) {
+      if(JSON_UNLIKELY(not json_patch.is_array())) {
         JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
       }
 
-      const std::string op = get_value("op", "op", true);
-      const std::string path = get_value(op, "path", true);
-      json_pointer ptr(path);
-
-      switch(get_op(op)) {
-        case patch_operations::add: {
-          operation_add(ptr, get_value("add", "value", false));
-          break;
-        }
+      for(const auto &val : json_patch) {
+        const auto get_value = [&val](const std::string &op,
+                                      const std::string &member,
+                                      bool string_type) -> basic_json & {
+          auto it = val.m_value.object->find(member);
 
-        case patch_operations::remove: {
-          operation_remove(ptr);
-          break;
-        }
+          const auto error_msg = (op == "op") ? "operation" : "operation '"+op+"'";
 
-        case patch_operations::replace: {
-          result.at(ptr) = get_value("replace", "value", false);
-          break;
-        }
+          if(JSON_UNLIKELY(it == val.m_value.object->end())) {
+            JSON_THROW(parse_error::create(105, 0, error_msg+" must have member '"+member+"'"));
+          }
 
-        case patch_operations::move: {
-          const std::string from_path = get_value("move", "from", true);
-          json_pointer from_ptr(from_path);
+          if(JSON_UNLIKELY(string_type and not it->second.is_string())) {
+            JSON_THROW(parse_error::create(105, 0, error_msg+" must have string member '"+member+"'"));
+          }
 
-          basic_json v = result.at(from_ptr);
+          return it->second;
+        };
 
-          operation_remove(from_ptr);
-          operation_add(ptr, v);
-          break;
+        if(JSON_UNLIKELY(not val.is_object())) {
+          JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
         }
 
-        case patch_operations::copy: {
-          const std::string from_path = get_value("copy", "from", true);
-          const json_pointer from_ptr(from_path);
+        const std::string op = get_value("op", "op", true);
+        const std::string path = get_value(op, "path", true);
+        json_pointer ptr(path);
 
-          basic_json v = result.at(from_ptr);
-
-          operation_add(ptr, v);
-          break;
-        }
-
-        case patch_operations::test: {
-          bool success = false;
-          JSON_TRY {
-            success = (result.at(ptr) == get_value("test", "value", false));
+        switch(get_op(op)) {
+          case patch_operations::add: {
+            operation_add(ptr, get_value("add", "value", false));
+            break;
           }
-          JSON_CATCH (out_of_range &) {
+
+          case patch_operations::remove: {
+            operation_remove(ptr);
+            break;
           }
 
-          if(JSON_UNLIKELY(not success)) {
-            JSON_THROW(other_error::create(501, "unsuccessful: "+val.dump()));
+          case patch_operations::replace: {
+            result.at(ptr) = get_value("replace", "value", false);
+            break;
           }
 
-          break;
-        }
+          case patch_operations::move: {
+            const std::string from_path = get_value("move", "from", true);
+            json_pointer from_ptr(from_path);
 
-        case patch_operations::invalid: {
-          JSON_THROW(parse_error::create(105, 0, "operation value '"+op+"' is invalid"));
-        }
-      }
-    }
+            basic_json v = result.at(from_ptr);
 
-    return result;
-  }
+            operation_remove(from_ptr);
+            operation_add(ptr, v);
+            break;
+          }
 
-  static basic_json diff(const basic_json &source, const basic_json &target,
-                         const std::string &path = "") {
-    basic_json result(value_t::array);
+          case patch_operations::copy: {
+            const std::string from_path = get_value("copy", "from", true);
+            const json_pointer from_ptr(from_path);
 
-    if(source == target) {
-      return result;
-    }
+            basic_json v = result.at(from_ptr);
 
-    if(source.type() != target.type()) {
-      result.push_back(
-          {
-              {"op",    "replace"},
-              {"path",  path},
-              {"value", target}
-          });
-    } else {
-      switch(source.type()) {
-        case value_t::array: {
-          std::size_t i = 0;
-          while(i < source.size() and i < target.size()) {
-            auto temp_diff = diff(source[i], target[i], path+"/"+std::to_string(i));
-            result.insert(result.end(), temp_diff.begin(), temp_diff.end());
-            ++i;
+            operation_add(ptr, v);
+            break;
           }
 
-          const auto end_index = static_cast<difference_type>(result.size());
-          while(i < source.size()) {
-            result.insert(result.begin()+end_index, object(
-                {
-                    {"op",   "remove"},
-                    {"path", path+"/"+std::to_string(i)}
-                }));
-            ++i;
-          }
+          case patch_operations::test: {
+            bool success = false;
+            JSON_TRY {
+              success = (result.at(ptr) == get_value("test", "value", false));
+            }
+            JSON_CATCH (out_of_range &) {
+            }
 
-          while(i < target.size()) {
-            result.push_back(
-                {
-                    {"op",    "add"},
-                    {"path",  path+"/"+std::to_string(i)},
-                    {"value", target[i]}
-                });
-            ++i;
+            if(JSON_UNLIKELY(not success)) {
+              JSON_THROW(other_error::create(501, "unsuccessful: "+val.dump()));
+            }
+
+            break;
           }
 
-          break;
+          case patch_operations::invalid: {
+            JSON_THROW(parse_error::create(105, 0, "operation value '"+op+"' is invalid"));
+          }
         }
+      }
 
-        case value_t::object: {
-          for(auto it = source.cbegin(); it != source.cend(); ++it) {
-            const auto key = json_pointer::escape(it.key());
+      return result;
+    }
+
+    static basic_json diff(const basic_json &source, const basic_json &target,
+                           const std::string &path = "") {
+      basic_json result(value_t::array);
+
+      if(source == target) {
+        return result;
+      }
 
-            if(target.find(it.key()) != target.end()) {
-              auto temp_diff = diff(it.value(), target[it.key()], path+"/"+key);
+      if(source.type() != target.type()) {
+        result.push_back(
+            {
+                {"op",    "replace"},
+                {"path",  path},
+                {"value", target}
+            });
+      } else {
+        switch(source.type()) {
+          case value_t::array: {
+            std::size_t i = 0;
+            while(i < source.size() and i < target.size()) {
+              auto temp_diff = diff(source[i], target[i], path+"/"+std::to_string(i));
               result.insert(result.end(), temp_diff.begin(), temp_diff.end());
-            } else {
-              result.push_back(object(
+              ++i;
+            }
+
+            const auto end_index = static_cast<difference_type>(result.size());
+            while(i < source.size()) {
+              result.insert(result.begin()+end_index, object(
                   {
                       {"op",   "remove"},
-                      {"path", path+"/"+key}
+                      {"path", path+"/"+std::to_string(i)}
                   }));
+              ++i;
             }
-          }
 
-          for(auto it = target.cbegin(); it != target.cend(); ++it) {
-            if(source.find(it.key()) == source.end()) {
-              const auto key = json_pointer::escape(it.key());
+            while(i < target.size()) {
               result.push_back(
                   {
                       {"op",    "add"},
-                      {"path",  path+"/"+key},
-                      {"value", it.value()}
+                      {"path",  path+"/"+std::to_string(i)},
+                      {"value", target[i]}
                   });
+              ++i;
             }
+
+            break;
           }
 
-          break;
-        }
+          case value_t::object: {
+            for(auto it = source.cbegin(); it != source.cend(); ++it) {
+              const auto key = json_pointer::escape(it.key());
 
-        default: {
-          result.push_back(
-              {
-                  {"op",    "replace"},
-                  {"path",  path},
-                  {"value", target}
-              });
-          break;
+              if(target.find(it.key()) != target.end()) {
+                auto temp_diff = diff(it.value(), target[it.key()], path+"/"+key);
+                result.insert(result.end(), temp_diff.begin(), temp_diff.end());
+              } else {
+                result.push_back(object(
+                    {
+                        {"op",   "remove"},
+                        {"path", path+"/"+key}
+                    }));
+              }
+            }
+
+            for(auto it = target.cbegin(); it != target.cend(); ++it) {
+              if(source.find(it.key()) == source.end()) {
+                const auto key = json_pointer::escape(it.key());
+                result.push_back(
+                    {
+                        {"op",    "add"},
+                        {"path",  path+"/"+key},
+                        {"value", it.value()}
+                    });
+              }
+            }
+
+            break;
+          }
+
+          default: {
+            result.push_back(
+                {
+                    {"op",    "replace"},
+                    {"path",  path},
+                    {"value", target}
+                });
+            break;
+          }
         }
       }
-    }
 
-    return result;
-  }
+      return result;
+    }
 
-  void merge_patch(const basic_json &patch) {
-    if(patch.is_object()) {
-      if(not is_object()) {
-        *this = object();
-      }
-      for(auto it = patch.begin(); it != patch.end(); ++it) {
-        if(it.value().is_null()) {
-          erase(it.key());
-        } else {
-          operator[](it.key()).merge_patch(it.value());
+    void merge_patch(const basic_json &patch) {
+      if(patch.is_object()) {
+        if(not is_object()) {
+          *this = object();
+        }
+        for(auto it = patch.begin(); it != patch.end(); ++it) {
+          if(it.value().is_null()) {
+            erase(it.key());
+          } else {
+            operator[](it.key()).merge_patch(it.value());
+          }
         }
+      } else {
+        *this = patch;
       }
-    } else {
-      *this = patch;
     }
-  }
 
-};
+  };
 }
 
 namespace std {
-template<>
-inline void swap(nlohmann::json &j1,
-                 nlohmann::json &j2) noexcept(
-is_nothrow_move_constructible<nlohmann::json>::value and
-is_nothrow_move_assignable<nlohmann::json>::value
-) {
-  j1.swap(j2);
-}
-
-template<>
-struct hash<nlohmann::json> {
-  std::size_t operator()(const nlohmann::json &j) const {
-    const auto &h = hash<nlohmann::json::string_t>();
-    return h(j.dump());
+  template<>
+  inline void swap(nlohmann::json &j1,
+                   nlohmann::json &j2) noexcept(
+  is_nothrow_move_constructible<nlohmann::json>::value and
+  is_nothrow_move_assignable<nlohmann::json>::value
+  ) {
+    j1.swap(j2);
   }
-};
 
-template<>
-struct less<::nlohmann::detail::value_t> {
-  bool operator()(nlohmann::detail::value_t lhs,
-                  nlohmann::detail::value_t rhs) const noexcept {
-    return nlohmann::detail::operator<(lhs, rhs);
-  }
-};
+  template<>
+  struct hash<nlohmann::json> {
+    std::size_t operator()(const nlohmann::json &j) const {
+      const auto &h = hash<nlohmann::json::string_t>();
+      return h(j.dump());
+    }
+  };
+
+  template<>
+  struct less<::nlohmann::detail::value_t> {
+    bool operator()(nlohmann::detail::value_t lhs,
+                    nlohmann::detail::value_t rhs) const noexcept {
+      return nlohmann::detail::operator<(lhs, rhs);
+    }
+  };
 
 }
 
diff --git a/src/cmake.cc b/src/cmake.cc
index 252f2586..734cf0a1 100644
--- a/src/cmake.cc
+++ b/src/cmake.cc
@@ -1,3 +1,4 @@
+#include <map>
 #include "project_build.h"
 #include "makefile_base.h"
 #include "filesystem.h"
diff --git a/src/config.cc b/src/config.cc
index bc8d2e8d..83c35b3d 100644
--- a/src/config.cc
+++ b/src/config.cc
@@ -1,10 +1,166 @@
 #include "config.h"
-#include <exception>
 #include "files.h"
 #include <iostream>
 #include "filesystem.h"
 #include "terminal.h"
-#include <algorithm>
+#include <boost/property_tree/json_parser.hpp>
+
+namespace {
+  /// Used to dispatch Terminal outputs after juCi++ GUI setup and configuration
+  Dispatcher dispatcher;
+
+  void make_version_dependent_corrections(boost::property_tree::ptree &cfg,
+                                          const boost::property_tree::ptree &default_cfg,
+                                          const std::string &version) {
+    auto &keybindings_cfg = cfg.get_child("keybindings");
+    try {
+      if(version <= "1.2.4") {
+        auto it_file_print = keybindings_cfg.find("print");
+        if(it_file_print != keybindings_cfg.not_found() && it_file_print->second.data() == "<primary>p") {
+          dispatcher.post([] {
+            ::Terminal::get().print("Preference change: keybindings.print set to \"\"\n");
+          });
+          it_file_print->second.data() = "";
+        }
+      }
+    }
+    catch(const std::exception &e) {
+      std::cerr << "Error correcting preferences: " << e.what() << std::endl;
+    }
+  }
+
+  bool add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                         std::string parent_path = "") {
+    if(!parent_path.empty())
+      parent_path += ".";
+    bool unchanged = true;
+    for(auto &node: default_cfg) {
+      auto path = parent_path+node.first;
+      try {
+        cfg.get<std::string>(path);
+      }
+      catch(const std::exception &e) {
+        cfg.add(path, node.second.data());
+        unchanged = false;
+      }
+      unchanged &= add_missing_nodes(cfg, node.second, path);
+    }
+    return unchanged;
+  }
+
+  bool remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
+                               std::string parent_path = "") {
+    if(!parent_path.empty())
+      parent_path += ".";
+    bool unchanged = true;
+    for(auto it = cfg.begin(); it != cfg.end();) {
+      auto path = parent_path+it->first;
+      try {
+        default_cfg.get<std::string>(path);
+        unchanged &= remove_deprecated_nodes(it->second, default_cfg, path);
+        ++it;
+      }
+      catch(const std::exception &e) {
+        it = cfg.erase(it);
+        unchanged = false;
+      }
+    }
+    return unchanged;
+  }
+
+  void update(boost::property_tree::ptree &cfg) {
+    auto &cfgs = Config::get();
+    boost::property_tree::ptree default_cfg;
+    bool cfg_ok = true;
+    if(cfg.get<std::string>("version") != JUCI_VERSION) {
+      std::stringstream ss;
+      ss << default_config_file;
+      boost::property_tree::read_json(ss, default_cfg);
+      cfg_ok = false;
+      auto it_version = cfg.find("version");
+      if(it_version != cfg.not_found()) {
+        make_version_dependent_corrections(cfg, default_cfg, it_version->second.data());
+        it_version->second.data() = JUCI_VERSION;
+      }
+
+      auto style_path = cfgs.home_juci_path / "styles";
+      filesystem::write(style_path / "juci-light.xml", juci_light_style);
+      filesystem::write(style_path / "juci-dark.xml", juci_dark_style);
+      filesystem::write(style_path / "juci-dark-blue.xml", juci_dark_blue_style);
+    } else
+      return;
+    cfg_ok &= add_missing_nodes(cfg, default_cfg);
+    cfg_ok &= remove_deprecated_nodes(cfg, default_cfg);
+    if(!cfg_ok)
+      boost::property_tree::write_json((cfgs.home_juci_path / "config" / "config.json").string(), cfg);
+  }
+
+  void read(const boost::property_tree::ptree &cfg) {
+    auto &cfgs = Config::get();
+    auto keybindings_pt = cfg.get_child("keybindings");
+    for(auto &i : keybindings_pt) {
+      cfgs.menu.keys[i.first] = i.second.get_value<std::string>();
+    }
+
+    auto source_json = cfg.get_child("source");
+    cfgs.source.style = source_json.get<std::string>("style");
+    cfgs.source.font = source_json.get<std::string>("font");
+    cfgs.source.cleanup_whitespace_characters = source_json.get<bool>("cleanup_whitespace_characters");
+    cfgs.source.show_whitespace_characters = source_json.get<std::string>("show_whitespace_characters");
+    cfgs.source.format_style_on_save = source_json.get<bool>("format_style_on_save");
+    cfgs.source.format_style_on_save_if_style_file_found = source_json.get<bool>(
+        "format_style_on_save_if_style_file_found");
+    cfgs.source.smart_brackets = source_json.get<bool>("smart_brackets");
+    cfgs.source.smart_inserts = source_json.get<bool>("smart_inserts");
+    if(cfgs.source.smart_inserts)
+      cfgs.source.smart_brackets = true;
+    cfgs.source.show_map = source_json.get<bool>("show_map");
+    cfgs.source.map_font_size = source_json.get<std::string>("map_font_size");
+    cfgs.source.show_git_diff = source_json.get<bool>("show_git_diff");
+    cfgs.source.show_background_pattern = source_json.get<bool>("show_background_pattern");
+    cfgs.source.show_right_margin = source_json.get<bool>("show_right_margin");
+    cfgs.source.right_margin_position = source_json.get<unsigned>("right_margin_position");
+    cfgs.source.spellcheck_language = source_json.get<std::string>("spellcheck_language");
+    cfgs.source.default_tab_char = source_json.get<char>("default_tab_char");
+    cfgs.source.default_tab_size = source_json.get<unsigned>("default_tab_size");
+    cfgs.source.auto_tab_char_and_size = source_json.get<bool>("auto_tab_char_and_size");
+    cfgs.source.tab_indents_line = source_json.get<bool>("tab_indents_line");
+    cfgs.source.wrap_lines = source_json.get<bool>("wrap_lines");
+    cfgs.source.highlight_current_line = source_json.get<bool>("highlight_current_line");
+    cfgs.source.show_line_numbers = source_json.get<bool>("show_line_numbers");
+    cfgs.source.enable_multiple_cursors = source_json.get<bool>("enable_multiple_cursors");
+    cfgs.source.auto_reload_changed_files = source_json.get<bool>("auto_reload_changed_files");
+    cfgs.source.clang_format_style = source_json.get<std::string>("clang_format_style");
+    cfgs.source.clang_usages_threads = static_cast<unsigned>(source_json.get<int>("clang_usages_threads"));
+    auto pt_doc_search = cfg.get_child("documentation_searches");
+    for(auto &pt_doc_search_lang: pt_doc_search) {
+      cfgs.source.documentation_searches[pt_doc_search_lang.first].separator = pt_doc_search_lang.second.get<std::string>(
+          "separator");
+      auto &queries = cfgs.source.documentation_searches.find(pt_doc_search_lang.first)->second.queries;
+      for(auto &i: pt_doc_search_lang.second.get_child("queries")) {
+        queries[i.first] = i.second.get_value<std::string>();
+      }
+    }
+
+    cfgs.window.theme_name = cfg.get<std::string>("gtk_theme.name");
+    cfgs.window.theme_variant = cfg.get<std::string>("gtk_theme.variant");
+    cfgs.window.version = cfg.get<std::string>("version");
+
+    cfgs.project.default_build_path = cfg.get<std::string>("project.default_build_path");
+    cfgs.project.debug_build_path = cfg.get<std::string>("project.debug_build_path");
+    cfgs.project.cmake.command = cfg.get<std::string>("project.cmake.command");
+    cfgs.project.cmake.compile_command = cfg.get<std::string>("project.cmake.compile_command");
+    cfgs.project.meson.command = cfg.get<std::string>("project.meson.command");
+    cfgs.project.meson.compile_command = cfg.get<std::string>("project.meson.compile_command");
+    cfgs.project.save_on_compile_or_run = cfg.get<bool>("project.save_on_compile_or_run");
+    cfgs.project.clear_terminal_on_compile = cfg.get<bool>("project.clear_terminal_on_compile");
+    cfgs.project.ctags_command = cfg.get<std::string>("project.ctags_command");
+    cfgs.project.python_command = cfg.get<std::string>("project.python_command");
+
+    cfgs.terminal.history_size = cfg.get<int>("terminal.history_size");
+    cfgs.terminal.font = cfg.get<std::string>("terminal.font");
+  }
+}
 
 Config::Config() {
   home_path = filesystem::get_home_path();
@@ -58,152 +214,3 @@ void Config::find_or_create_config_files() {
   if (!boost::filesystem::exists(juci_style_path))
     filesystem::write(juci_style_path, juci_dark_blue_style);
 }
-
-void Config::update(boost::property_tree::ptree &cfg) {
-  boost::property_tree::ptree default_cfg;
-  bool cfg_ok = true;
-  if (cfg.get<std::string>("version") != JUCI_VERSION) {
-    std::stringstream ss;
-    ss << default_config_file;
-    boost::property_tree::read_json(ss, default_cfg);
-    cfg_ok = false;
-    auto it_version = cfg.find("version");
-    if (it_version != cfg.not_found()) {
-      make_version_dependent_corrections(cfg, default_cfg, it_version->second.data());
-      it_version->second.data() = JUCI_VERSION;
-    }
-
-    auto style_path = home_juci_path / "styles";
-    filesystem::write(style_path / "juci-light.xml", juci_light_style);
-    filesystem::write(style_path / "juci-dark.xml", juci_dark_style);
-    filesystem::write(style_path / "juci-dark-blue.xml", juci_dark_blue_style);
-  } else
-    return;
-  cfg_ok &= add_missing_nodes(cfg, default_cfg);
-  cfg_ok &= remove_deprecated_nodes(cfg, default_cfg);
-  if (!cfg_ok)
-    boost::property_tree::write_json((home_juci_path / "config" / "config.json").string(), cfg);
-}
-
-void Config::make_version_dependent_corrections(boost::property_tree::ptree &cfg,
-                                                const boost::property_tree::ptree &default_cfg,
-                                                const std::string &version) {
-  auto &keybindings_cfg = cfg.get_child("keybindings");
-  try {
-    if (version <= "1.2.4") {
-      auto it_file_print = keybindings_cfg.find("print");
-      if (it_file_print != keybindings_cfg.not_found() && it_file_print->second.data() == "<primary>p") {
-        dispatcher.post([] {
-          ::Terminal::get().print("Preference change: keybindings.print set to \"\"\n");
-        });
-        it_file_print->second.data() = "";
-      }
-    }
-  }
-  catch (const std::exception &e) {
-    std::cerr << "Error correcting preferences: " << e.what() << std::endl;
-  }
-}
-
-bool Config::add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
-                               std::string parent_path) {
-  if (parent_path.size() > 0)
-    parent_path += ".";
-  bool unchanged = true;
-  for (auto &node: default_cfg) {
-    auto path = parent_path + node.first;
-    try {
-      cfg.get<std::string>(path);
-    }
-    catch (const std::exception &e) {
-      cfg.add(path, node.second.data());
-      unchanged = false;
-    }
-    unchanged &= add_missing_nodes(cfg, node.second, path);
-  }
-  return unchanged;
-}
-
-bool Config::remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
-                                     std::string parent_path) {
-  if (parent_path.size() > 0)
-    parent_path += ".";
-  bool unchanged = true;
-  for (auto it = cfg.begin(); it != cfg.end();) {
-    auto path = parent_path + it->first;
-    try {
-      default_cfg.get<std::string>(path);
-      unchanged &= remove_deprecated_nodes(it->second, default_cfg, path);
-      ++it;
-    }
-    catch (const std::exception &e) {
-      it = cfg.erase(it);
-      unchanged = false;
-    }
-  }
-  return unchanged;
-}
-
-void Config::read(const boost::property_tree::ptree &cfg) {
-  auto keybindings_pt = cfg.get_child("keybindings");
-  for (auto &i : keybindings_pt) {
-    menu.keys[i.first] = i.second.get_value<std::string>();
-  }
-
-  auto source_json = cfg.get_child("source");
-  source.style = source_json.get<std::string>("style");
-  source.font = source_json.get<std::string>("font");
-  source.cleanup_whitespace_characters = source_json.get<bool>("cleanup_whitespace_characters");
-  source.show_whitespace_characters = source_json.get<std::string>("show_whitespace_characters");
-  source.format_style_on_save = source_json.get<bool>("format_style_on_save");
-  source.format_style_on_save_if_style_file_found = source_json.get<bool>("format_style_on_save_if_style_file_found");
-  source.smart_brackets = source_json.get<bool>("smart_brackets");
-  source.smart_inserts = source_json.get<bool>("smart_inserts");
-  if (source.smart_inserts)
-    source.smart_brackets = true;
-  source.show_map = source_json.get<bool>("show_map");
-  source.map_font_size = source_json.get<std::string>("map_font_size");
-  source.show_git_diff = source_json.get<bool>("show_git_diff");
-  source.show_background_pattern = source_json.get<bool>("show_background_pattern");
-  source.show_right_margin = source_json.get<bool>("show_right_margin");
-  source.right_margin_position = source_json.get<unsigned>("right_margin_position");
-  source.spellcheck_language = source_json.get<std::string>("spellcheck_language");
-  source.default_tab_char = source_json.get<char>("default_tab_char");
-  source.default_tab_size = source_json.get<unsigned>("default_tab_size");
-  source.auto_tab_char_and_size = source_json.get<bool>("auto_tab_char_and_size");
-  source.tab_indents_line = source_json.get<bool>("tab_indents_line");
-  source.wrap_lines = source_json.get<bool>("wrap_lines");
-  source.highlight_current_line = source_json.get<bool>("highlight_current_line");
-  source.show_line_numbers = source_json.get<bool>("show_line_numbers");
-  source.enable_multiple_cursors = source_json.get<bool>("enable_multiple_cursors");
-  source.auto_reload_changed_files = source_json.get<bool>("auto_reload_changed_files");
-  source.clang_format_style = source_json.get<std::string>("clang_format_style");
-  source.clang_usages_threads = static_cast<unsigned>(source_json.get<int>("clang_usages_threads"));
-  auto pt_doc_search = cfg.get_child("documentation_searches");
-  for (auto &pt_doc_search_lang: pt_doc_search) {
-    source.documentation_searches[pt_doc_search_lang.first].separator = pt_doc_search_lang.second.get<std::string>(
-        "separator");
-    auto &queries = source.documentation_searches.find(pt_doc_search_lang.first)->second.queries;
-    for (auto &i: pt_doc_search_lang.second.get_child("queries")) {
-      queries[i.first] = i.second.get_value<std::string>();
-    }
-  }
-
-  window.theme_name = cfg.get<std::string>("gtk_theme.name");
-  window.theme_variant = cfg.get<std::string>("gtk_theme.variant");
-  window.version = cfg.get<std::string>("version");
-
-  project.default_build_path = cfg.get<std::string>("project.default_build_path");
-  project.debug_build_path = cfg.get<std::string>("project.debug_build_path");
-  project.cmake.command = cfg.get<std::string>("project.cmake.command");
-  project.cmake.compile_command = cfg.get<std::string>("project.cmake.compile_command");
-  project.meson.command = cfg.get<std::string>("project.meson.command");
-  project.meson.compile_command = cfg.get<std::string>("project.meson.compile_command");
-  project.save_on_compile_or_run = cfg.get<bool>("project.save_on_compile_or_run");
-  project.clear_terminal_on_compile = cfg.get<bool>("project.clear_terminal_on_compile");
-  project.ctags_command = cfg.get<std::string>("project.ctags_command");
-  project.python_command = cfg.get<std::string>("project.python_command");
-
-  terminal.history_size = cfg.get<int>("terminal.history_size");
-  terminal.font = cfg.get<std::string>("terminal.font");
-}
diff --git a/src/config.h b/src/config.h
index 096374b8..ba56be69 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,12 +1,8 @@
 #pragma once
 
-#include <boost/property_tree/json_parser.hpp>
 #include <boost/filesystem.hpp>
 #include <unordered_map>
 #include <string>
-#include <utility>
-#include <vector>
-#include "dispatcher.h"
 
 class Config {
 public:
@@ -117,22 +113,5 @@ class Config {
   boost::filesystem::path home_juci_path;
 
 private:
-  /// Used to dispatch Terminal outputs after juCi++ GUI setup and configuration
-  Dispatcher dispatcher;
-
   void find_or_create_config_files();
-
-  void update(boost::property_tree::ptree &cfg);
-
-  void
-  make_version_dependent_corrections(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
-                                     const std::string &version);
-
-  bool add_missing_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
-                         std::string parent_path = "");
-
-  bool remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boost::property_tree::ptree &default_cfg,
-                               std::string parent_path = "");
-
-  void read(const boost::property_tree::ptree &cfg);
 };
diff --git a/src/window.cc b/src/window.cc
index 9e0fb579..6a4fa057 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -1,3 +1,4 @@
+#include <boost/property_tree/json_parser.hpp>
 #include "window.h"
 #include "config.h"
 #include "menu.h"