From 3ed9daccf318776598ecdf3f5b59c6e8ee3e873d Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 25 Feb 2016 10:10:25 +0100 Subject: [PATCH 1/9] CMake cleanup --- src/cmake.cc | 19 ++++++++++++------- src/cmake.h | 10 +++++----- src/directories.cc | 14 ++++++++------ src/directories.h | 5 +++-- src/notebook.cc | 22 +++++++++++----------- src/project.cc | 32 +++++++++++++++----------------- src/source_clang.cc | 2 +- 7 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index cff8f1b..c24ffb5 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -7,7 +7,12 @@ std::unordered_set CMake::debug_build_needed; -CMake::CMake(const boost::filesystem::path &path) { +CMake::CMake(const boost::filesystem::path &path, bool find_project_root_path) { + if(!find_project_root_path) { + project_path=path; + return; + } + const auto find_cmake_project=[this](const boost::filesystem::path &cmake_path) { for(auto &line: filesystem::read_lines(cmake_path)) { const boost::regex project_regex("^ *project *\\(.*$"); @@ -35,7 +40,7 @@ CMake::CMake(const boost::filesystem::path &path) { } } -boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::path &project_path) { +boost::filesystem::path CMake::get_default_build_path() { boost::filesystem::path default_build_path=Config::get().project.default_build_path; const std::string path_variable_project_directory_name=""; @@ -55,7 +60,7 @@ boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::p return default_build_path; } -boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::path &project_path) { +boost::filesystem::path CMake::get_debug_build_path() { boost::filesystem::path debug_build_path=Config::get().project.debug_build_path; const std::string path_variable_project_directory_name=""; @@ -86,14 +91,14 @@ boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::pat return debug_build_path; } -bool CMake::create_default_build(const boost::filesystem::path &project_path, bool force) { +bool CMake::create_default_build(bool force) { if(project_path.empty()) return false; if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) return false; - auto default_build_path=get_default_build_path(project_path); + auto default_build_path=get_default_build_path(); if(default_build_path.empty()) return false; if(!boost::filesystem::exists(default_build_path)) { @@ -135,14 +140,14 @@ bool CMake::create_default_build(const boost::filesystem::path &project_path, bo return false; } -bool CMake::create_debug_build(const boost::filesystem::path &project_path) { +bool CMake::create_debug_build() { if(project_path.empty()) return false; if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) return false; - auto debug_build_path=get_debug_build_path(project_path); + auto debug_build_path=get_debug_build_path(); if(debug_build_path.empty()) return false; if(!boost::filesystem::exists(debug_build_path)) { diff --git a/src/cmake.h b/src/cmake.h index bfa463b..dc665b5 100644 --- a/src/cmake.h +++ b/src/cmake.h @@ -7,14 +7,14 @@ class CMake { public: - CMake(const boost::filesystem::path &path); + CMake(const boost::filesystem::path &path, bool find_project_root_path=false); boost::filesystem::path project_path; std::vector paths; - static boost::filesystem::path get_default_build_path(const boost::filesystem::path &project_path); - static boost::filesystem::path get_debug_build_path(const boost::filesystem::path &project_path); - static bool create_default_build(const boost::filesystem::path &project_path, bool force=false); - static bool create_debug_build(const boost::filesystem::path &project_path); + boost::filesystem::path get_default_build_path(); + boost::filesystem::path get_debug_build_path(); + bool create_default_build(bool force=false); + bool create_debug_build(); boost::filesystem::path get_executable(const boost::filesystem::path &file_path); diff --git a/src/directories.cc b/src/directories.cc index be1d779..6b51587 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -3,6 +3,7 @@ #include #include #include "source.h" +#include "cmake.h" #include //TODO: remove using namespace std; //TODO: remove @@ -130,12 +131,13 @@ void Directories::open(const boost::filesystem::path& dir_path) { last_write_times.clear(); update_paths.clear(); update_mutex.unlock(); - - cmake=std::unique_ptr(new CMake(dir_path)); - CMake::create_default_build(cmake->project_path); - auto project=cmake->get_functions_parameters("project"); - if(project.size()>0 && project[0].second.size()>0) { - auto title=project[0].second[0]; + + auto cmake=CMake(dir_path, true); + cmake.create_default_build(); + project_path=cmake.project_path; + auto project_name=cmake.get_functions_parameters("project"); + if(project_name.size()>0 && project_name[0].second.size()>0) { + auto title=project_name[0].second[0]; //TODO: report that set_title does not handle '_' correctly? size_t pos=0; while((pos=title.find('_', pos))!=std::string::npos) { diff --git a/src/directories.h b/src/directories.h index 5e5e374..e91b6c6 100644 --- a/src/directories.h +++ b/src/directories.h @@ -5,11 +5,11 @@ #include #include #include "boost/filesystem.hpp" -#include "cmake.h" #include #include #include #include "dispatcher.h" +#include class Directories : public Gtk::TreeView { public: @@ -40,8 +40,9 @@ public: void select(const boost::filesystem::path &path); std::function on_row_activated; - std::unique_ptr cmake; + boost::filesystem::path current_path; + boost::filesystem::path project_path; private: void add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &row); diff --git a/src/notebook.cc b/src/notebook.cc index f973961..9545c11 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -99,18 +99,18 @@ void Notebook::open(const boost::filesystem::path &file_path) { auto language=Source::guess_language(file_path); boost::filesystem::path project_path; auto &directories=Directories::get(); - if(directories.cmake && directories.cmake->project_path!="" && file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') - project_path=directories.cmake->project_path; + if(!directories.project_path.empty() && file_path.generic_string().substr(0, directories.project_path.generic_string().size()+1)==directories.project_path.generic_string()+'/') + project_path=directories.project_path; else { project_path=file_path.parent_path(); - CMake cmake(project_path); + CMake cmake(project_path, true); if(cmake.project_path!="") { project_path=cmake.project_path; Terminal::get().print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n"); } } if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) { - CMake::create_default_build(project_path); + CMake(project_path).create_default_build(); source_views.emplace_back(new Source::ClangView(file_path, project_path, language)); } else @@ -249,19 +249,19 @@ bool Notebook::save(int page) { boost::filesystem::path project_path; if(view->file_path.filename()=="CMakeLists.txt") { auto &directories=Directories::get(); - if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') { - if(CMake::create_default_build(directories.cmake->project_path, true)) - project_path=directories.cmake->project_path; + if(!directories.project_path.empty() && view->file_path.generic_string().substr(0, directories.project_path.generic_string().size()+1)==directories.project_path.generic_string()+'/') { + if(CMake(directories.project_path).create_default_build(true)) + project_path=directories.project_path; } else { - CMake cmake(view->file_path.parent_path()); - if(CMake::create_default_build(cmake.project_path, true)) + CMake cmake(view->file_path.parent_path(), true); + if(cmake.create_default_build(true)) project_path=cmake.project_path; } if(project_path!="") { - auto debug_project_path=CMake::get_debug_build_path(project_path); + auto debug_project_path=CMake(project_path).get_debug_build_path(); if(!debug_project_path.empty() && boost::filesystem::exists(debug_project_path)) - CMake::create_debug_build(project_path); + CMake(project_path).create_debug_build(); for(auto source_view: source_views) { if(auto source_clang_view=dynamic_cast(source_view)) { if(project_path==source_clang_view->project_path) diff --git a/src/project.cc b/src/project.cc index 0fc11b4..1e1601d 100644 --- a/src/project.cc +++ b/src/project.cc @@ -82,10 +82,10 @@ std::unique_ptr Project::Clang::get_cmake() { path=Directories::get().current_path; if(path.empty()) return nullptr; - auto cmake=std::unique_ptr(new CMake(path)); + auto cmake=std::unique_ptr(new CMake(path, true)); if(cmake->project_path.empty()) return nullptr; - if(!CMake::create_default_build(cmake->project_path)) + if(!cmake->create_default_build()) return nullptr; return cmake; } @@ -96,7 +96,7 @@ std::pair Project::Clang::get_run_arguments() { return {"", ""}; auto project_path=cmake->project_path.string(); - auto run_arguments_it=run_arguments.find(project_path); + auto run_arguments_it=run_arguments.find(cmake->project_path.string()); std::string arguments; if(run_arguments_it!=run_arguments.end()) arguments=run_arguments_it->second; @@ -105,17 +105,16 @@ std::pair Project::Clang::get_run_arguments() { auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(executable!="") { - auto project_path=cmake->project_path; - auto build_path=CMake::get_default_build_path(project_path); + auto build_path=cmake->get_default_build_path(); if(!build_path.empty()) { - size_t pos=executable.find(project_path.string()); + size_t pos=executable.find(project_path); if(pos!=std::string::npos) - executable.replace(pos, project_path.string().size(), build_path.string()); + executable.replace(pos, project_path.size(), build_path.string()); } arguments=filesystem::escape_argument(executable); } else - arguments=filesystem::escape_argument(CMake::get_default_build_path(cmake->project_path)); + arguments=filesystem::escape_argument(cmake->get_default_build_path()); } return {project_path, arguments}; @@ -126,7 +125,7 @@ void Project::Clang::compile() { if(!cmake) return; - auto default_build_path=CMake::get_default_build_path(cmake->project_path); + auto default_build_path=cmake->get_default_build_path(); if(default_build_path.empty()) return; compiling=true; @@ -142,7 +141,7 @@ void Project::Clang::compile_and_run() { return; auto project_path=cmake->project_path; - auto default_build_path=CMake::get_default_build_path(project_path); + auto default_build_path=cmake->get_default_build_path(); if(default_build_path.empty()) return; @@ -194,17 +193,16 @@ std::pair Project::Clang::debug_get_run_arguments() { auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(executable!="") { - auto project_path=cmake->project_path; - auto build_path=CMake::get_debug_build_path(project_path); + auto build_path=cmake->get_debug_build_path(); if(!build_path.empty()) { - size_t pos=executable.find(project_path.string()); + size_t pos=executable.find(project_path); if(pos!=std::string::npos) - executable.replace(pos, project_path.string().size(), build_path.string()); + executable.replace(pos, project_path.size(), build_path.string()); } arguments=filesystem::escape_argument(executable); } else - arguments=filesystem::escape_argument(CMake::get_debug_build_path(cmake->project_path)); + arguments=filesystem::escape_argument(cmake->get_debug_build_path()); } return {project_path, arguments}; @@ -216,10 +214,10 @@ void Project::Clang::debug_start() { return; auto project_path=cmake->project_path; - auto debug_build_path=CMake::get_debug_build_path(project_path); + auto debug_build_path=cmake->get_debug_build_path(); if(debug_build_path.empty()) return; - if(!CMake::create_debug_build(project_path)) + if(!cmake->create_debug_build()) return; auto run_arguments_it=debug_run_arguments.find(project_path.string()); diff --git a/src/source_clang.cc b/src/source_clang.cc index 2130993..cc6c6ee 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -178,7 +178,7 @@ void Source::ClangViewParse::soft_reparse() { } std::vector Source::ClangViewParse::get_compilation_commands() { - clang::CompilationDatabase db(CMake::get_default_build_path(project_path).string()); + clang::CompilationDatabase db(CMake(project_path).get_default_build_path().string()); clang::CompileCommands commands(file_path.string(), db); std::vector cmds = commands.get_commands(); std::vector arguments; From 7e34cebded306bcf064344014fcdb5404c6dca3d Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 25 Feb 2016 12:30:00 +0100 Subject: [PATCH 2/9] Revert "CMake cleanup" This reverts commit 3ed9daccf318776598ecdf3f5b59c6e8ee3e873d. --- src/cmake.cc | 19 +++++++------------ src/cmake.h | 10 +++++----- src/directories.cc | 14 ++++++-------- src/directories.h | 5 ++--- src/notebook.cc | 22 +++++++++++----------- src/project.cc | 32 +++++++++++++++++--------------- src/source_clang.cc | 2 +- 7 files changed, 49 insertions(+), 55 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index c24ffb5..cff8f1b 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -7,12 +7,7 @@ std::unordered_set CMake::debug_build_needed; -CMake::CMake(const boost::filesystem::path &path, bool find_project_root_path) { - if(!find_project_root_path) { - project_path=path; - return; - } - +CMake::CMake(const boost::filesystem::path &path) { const auto find_cmake_project=[this](const boost::filesystem::path &cmake_path) { for(auto &line: filesystem::read_lines(cmake_path)) { const boost::regex project_regex("^ *project *\\(.*$"); @@ -40,7 +35,7 @@ CMake::CMake(const boost::filesystem::path &path, bool find_project_root_path) { } } -boost::filesystem::path CMake::get_default_build_path() { +boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::path &project_path) { boost::filesystem::path default_build_path=Config::get().project.default_build_path; const std::string path_variable_project_directory_name=""; @@ -60,7 +55,7 @@ boost::filesystem::path CMake::get_default_build_path() { return default_build_path; } -boost::filesystem::path CMake::get_debug_build_path() { +boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::path &project_path) { boost::filesystem::path debug_build_path=Config::get().project.debug_build_path; const std::string path_variable_project_directory_name=""; @@ -91,14 +86,14 @@ boost::filesystem::path CMake::get_debug_build_path() { return debug_build_path; } -bool CMake::create_default_build(bool force) { +bool CMake::create_default_build(const boost::filesystem::path &project_path, bool force) { if(project_path.empty()) return false; if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) return false; - auto default_build_path=get_default_build_path(); + auto default_build_path=get_default_build_path(project_path); if(default_build_path.empty()) return false; if(!boost::filesystem::exists(default_build_path)) { @@ -140,14 +135,14 @@ bool CMake::create_default_build(bool force) { return false; } -bool CMake::create_debug_build() { +bool CMake::create_debug_build(const boost::filesystem::path &project_path) { if(project_path.empty()) return false; if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) return false; - auto debug_build_path=get_debug_build_path(); + auto debug_build_path=get_debug_build_path(project_path); if(debug_build_path.empty()) return false; if(!boost::filesystem::exists(debug_build_path)) { diff --git a/src/cmake.h b/src/cmake.h index dc665b5..bfa463b 100644 --- a/src/cmake.h +++ b/src/cmake.h @@ -7,14 +7,14 @@ class CMake { public: - CMake(const boost::filesystem::path &path, bool find_project_root_path=false); + CMake(const boost::filesystem::path &path); boost::filesystem::path project_path; std::vector paths; - boost::filesystem::path get_default_build_path(); - boost::filesystem::path get_debug_build_path(); - bool create_default_build(bool force=false); - bool create_debug_build(); + static boost::filesystem::path get_default_build_path(const boost::filesystem::path &project_path); + static boost::filesystem::path get_debug_build_path(const boost::filesystem::path &project_path); + static bool create_default_build(const boost::filesystem::path &project_path, bool force=false); + static bool create_debug_build(const boost::filesystem::path &project_path); boost::filesystem::path get_executable(const boost::filesystem::path &file_path); diff --git a/src/directories.cc b/src/directories.cc index 6b51587..be1d779 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -3,7 +3,6 @@ #include #include #include "source.h" -#include "cmake.h" #include //TODO: remove using namespace std; //TODO: remove @@ -131,13 +130,12 @@ void Directories::open(const boost::filesystem::path& dir_path) { last_write_times.clear(); update_paths.clear(); update_mutex.unlock(); - - auto cmake=CMake(dir_path, true); - cmake.create_default_build(); - project_path=cmake.project_path; - auto project_name=cmake.get_functions_parameters("project"); - if(project_name.size()>0 && project_name[0].second.size()>0) { - auto title=project_name[0].second[0]; + + cmake=std::unique_ptr(new CMake(dir_path)); + CMake::create_default_build(cmake->project_path); + auto project=cmake->get_functions_parameters("project"); + if(project.size()>0 && project[0].second.size()>0) { + auto title=project[0].second[0]; //TODO: report that set_title does not handle '_' correctly? size_t pos=0; while((pos=title.find('_', pos))!=std::string::npos) { diff --git a/src/directories.h b/src/directories.h index e91b6c6..5e5e374 100644 --- a/src/directories.h +++ b/src/directories.h @@ -5,11 +5,11 @@ #include #include #include "boost/filesystem.hpp" +#include "cmake.h" #include #include #include #include "dispatcher.h" -#include class Directories : public Gtk::TreeView { public: @@ -40,9 +40,8 @@ public: void select(const boost::filesystem::path &path); std::function on_row_activated; - + std::unique_ptr cmake; boost::filesystem::path current_path; - boost::filesystem::path project_path; private: void add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &row); diff --git a/src/notebook.cc b/src/notebook.cc index 9545c11..f973961 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -99,18 +99,18 @@ void Notebook::open(const boost::filesystem::path &file_path) { auto language=Source::guess_language(file_path); boost::filesystem::path project_path; auto &directories=Directories::get(); - if(!directories.project_path.empty() && file_path.generic_string().substr(0, directories.project_path.generic_string().size()+1)==directories.project_path.generic_string()+'/') - project_path=directories.project_path; + if(directories.cmake && directories.cmake->project_path!="" && file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') + project_path=directories.cmake->project_path; else { project_path=file_path.parent_path(); - CMake cmake(project_path, true); + CMake cmake(project_path); if(cmake.project_path!="") { project_path=cmake.project_path; Terminal::get().print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n"); } } if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) { - CMake(project_path).create_default_build(); + CMake::create_default_build(project_path); source_views.emplace_back(new Source::ClangView(file_path, project_path, language)); } else @@ -249,19 +249,19 @@ bool Notebook::save(int page) { boost::filesystem::path project_path; if(view->file_path.filename()=="CMakeLists.txt") { auto &directories=Directories::get(); - if(!directories.project_path.empty() && view->file_path.generic_string().substr(0, directories.project_path.generic_string().size()+1)==directories.project_path.generic_string()+'/') { - if(CMake(directories.project_path).create_default_build(true)) - project_path=directories.project_path; + if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') { + if(CMake::create_default_build(directories.cmake->project_path, true)) + project_path=directories.cmake->project_path; } else { - CMake cmake(view->file_path.parent_path(), true); - if(cmake.create_default_build(true)) + CMake cmake(view->file_path.parent_path()); + if(CMake::create_default_build(cmake.project_path, true)) project_path=cmake.project_path; } if(project_path!="") { - auto debug_project_path=CMake(project_path).get_debug_build_path(); + auto debug_project_path=CMake::get_debug_build_path(project_path); if(!debug_project_path.empty() && boost::filesystem::exists(debug_project_path)) - CMake(project_path).create_debug_build(); + CMake::create_debug_build(project_path); for(auto source_view: source_views) { if(auto source_clang_view=dynamic_cast(source_view)) { if(project_path==source_clang_view->project_path) diff --git a/src/project.cc b/src/project.cc index 1e1601d..0fc11b4 100644 --- a/src/project.cc +++ b/src/project.cc @@ -82,10 +82,10 @@ std::unique_ptr Project::Clang::get_cmake() { path=Directories::get().current_path; if(path.empty()) return nullptr; - auto cmake=std::unique_ptr(new CMake(path, true)); + auto cmake=std::unique_ptr(new CMake(path)); if(cmake->project_path.empty()) return nullptr; - if(!cmake->create_default_build()) + if(!CMake::create_default_build(cmake->project_path)) return nullptr; return cmake; } @@ -96,7 +96,7 @@ std::pair Project::Clang::get_run_arguments() { return {"", ""}; auto project_path=cmake->project_path.string(); - auto run_arguments_it=run_arguments.find(cmake->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; @@ -105,16 +105,17 @@ std::pair Project::Clang::get_run_arguments() { auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(executable!="") { - auto build_path=cmake->get_default_build_path(); + auto project_path=cmake->project_path; + auto build_path=CMake::get_default_build_path(project_path); if(!build_path.empty()) { - size_t pos=executable.find(project_path); + size_t pos=executable.find(project_path.string()); if(pos!=std::string::npos) - executable.replace(pos, project_path.size(), build_path.string()); + executable.replace(pos, project_path.string().size(), build_path.string()); } arguments=filesystem::escape_argument(executable); } else - arguments=filesystem::escape_argument(cmake->get_default_build_path()); + arguments=filesystem::escape_argument(CMake::get_default_build_path(cmake->project_path)); } return {project_path, arguments}; @@ -125,7 +126,7 @@ void Project::Clang::compile() { if(!cmake) return; - auto default_build_path=cmake->get_default_build_path(); + auto default_build_path=CMake::get_default_build_path(cmake->project_path); if(default_build_path.empty()) return; compiling=true; @@ -141,7 +142,7 @@ void Project::Clang::compile_and_run() { return; auto project_path=cmake->project_path; - auto default_build_path=cmake->get_default_build_path(); + auto default_build_path=CMake::get_default_build_path(project_path); if(default_build_path.empty()) return; @@ -193,16 +194,17 @@ std::pair Project::Clang::debug_get_run_arguments() { auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(executable!="") { - auto build_path=cmake->get_debug_build_path(); + auto project_path=cmake->project_path; + auto build_path=CMake::get_debug_build_path(project_path); if(!build_path.empty()) { - size_t pos=executable.find(project_path); + size_t pos=executable.find(project_path.string()); if(pos!=std::string::npos) - executable.replace(pos, project_path.size(), build_path.string()); + executable.replace(pos, project_path.string().size(), build_path.string()); } arguments=filesystem::escape_argument(executable); } else - arguments=filesystem::escape_argument(cmake->get_debug_build_path()); + arguments=filesystem::escape_argument(CMake::get_debug_build_path(cmake->project_path)); } return {project_path, arguments}; @@ -214,10 +216,10 @@ void Project::Clang::debug_start() { return; auto project_path=cmake->project_path; - auto debug_build_path=cmake->get_debug_build_path(); + auto debug_build_path=CMake::get_debug_build_path(project_path); if(debug_build_path.empty()) return; - if(!cmake->create_debug_build()) + if(!CMake::create_debug_build(project_path)) return; auto run_arguments_it=debug_run_arguments.find(project_path.string()); diff --git a/src/source_clang.cc b/src/source_clang.cc index cc6c6ee..2130993 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -178,7 +178,7 @@ void Source::ClangViewParse::soft_reparse() { } std::vector Source::ClangViewParse::get_compilation_commands() { - clang::CompilationDatabase db(CMake(project_path).get_default_build_path().string()); + clang::CompilationDatabase db(CMake::get_default_build_path(project_path).string()); clang::CompileCommands commands(file_path.string(), db); std::vector cmds = commands.get_commands(); std::vector arguments; From 2f057b39301cf043fa9581540d2d50831297b608 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 6 Mar 2016 09:54:36 +0100 Subject: [PATCH 3/9] Auto-indent cleanup and now supports JavaScript, TypeScript and Java as well. Also removed too eager message telling which file type was opened --- src/source.cc | 72 +++++++++++++++++++++++++++++++++++++++++++-- src/source_clang.cc | 66 ----------------------------------------- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/src/source.cc b/src/source.cc index 05381cd..a06b1d1 100644 --- a/src/source.cc +++ b/src/source.cc @@ -292,6 +292,74 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy } } set_tab_char_and_size(tab_char, tab_size); + + 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")) { + auto_indent=[this]() { + auto command=Config::get().terminal.clang_format_command; + 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 { + 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) { + get_source_buffer()->begin_user_action(); + auto iter=get_buffer()->get_insert()->get_iter(); + auto cursor_line_nr=iter.get_line(); + auto cursor_line_offset=iter.get_line_offset(); + + get_buffer()->set_text(stdout_stream.str()); + + cursor_line_nr=std::min(cursor_line_nr, get_buffer()->get_line_count()-1); + if(cursor_line_nr>=0) { + iter=get_buffer()->get_iter_at_line(cursor_line_nr); + for(int c=0;cplace_cursor(iter); + while(g_main_context_pending(NULL)) //TODO: minor: might crash if the buffer is saved and closed really fast right after doing auto indent + g_main_context_iteration(NULL, false); + scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); + } + get_source_buffer()->end_user_action(); + } + }; + } } void Source::View::set_tab_char_and_size(char tab_char, unsigned tab_size) { @@ -1445,10 +1513,8 @@ Source::GenericView::GenericView(const boost::filesystem::path &file_path, const configure(); spellcheck_all=true; - if(language) { + if(language) get_source_buffer()->set_language(language); - Terminal::get().print("Language for file "+file_path.string()+" set to "+language->get_name()+".\n"); - } auto completion=get_completion(); completion->property_show_headers()=false; diff --git a/src/source_clang.cc b/src/source_clang.cc index 2130993..439aeb4 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -1030,72 +1030,6 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { } }); - auto_indent=[this]() { - auto command=Config::get().terminal.clang_format_command; - bool use_style_file=false; - - auto style_file_search_path=this->file_path.parent_path(); - while(true) { - auto style_file=style_file_search_path/"CMakeLists.txt"; - if(boost::filesystem::exists(style_file_search_path/".clang-format") || boost::filesystem::exists(style_file_search_path/"_clang-format")) { - use_style_file=true; - break; - } - if(style_file_search_path==style_file_search_path.root_directory()) - break; - style_file_search_path=style_file_search_path.parent_path(); - } - - if(use_style_file) - command+=" -style=file"; - else { - 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) { - get_source_buffer()->begin_user_action(); - auto iter=get_buffer()->get_insert()->get_iter(); - auto cursor_line_nr=iter.get_line(); - auto cursor_line_offset=iter.get_line_offset(); - - get_buffer()->erase(get_buffer()->begin(), get_buffer()->end()); - get_buffer()->insert(get_buffer()->begin(), stdout_stream.str()); - - cursor_line_nr=std::min(cursor_line_nr, get_buffer()->get_line_count()-1); - if(cursor_line_nr>=0) { - iter=get_buffer()->get_iter_at_line(cursor_line_nr); - for(int c=0;cplace_cursor(iter); - while(g_main_context_pending(NULL)) //TODO: minor: might crash if the buffer is saved and closed really fast right after doing auto indent - g_main_context_iteration(NULL, false); - scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); - } - get_source_buffer()->end_user_action(); - } - }; - get_token=[this]() -> Token { if(parsed) { auto iter=get_buffer()->get_insert()->get_iter(); From 755747bbba1279f2b9c625e31a10330a7e12288d Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 6 Mar 2016 10:23:09 +0100 Subject: [PATCH 4/9] Bracket based auto indentation added for Java, JavaScript, TypeScript --- src/source.cc | 224 +++++++++++++++++++++++++++++++++++++++++++- src/source.h | 8 ++ src/source_clang.cc | 215 +----------------------------------------- src/source_clang.h | 7 -- 4 files changed, 232 insertions(+), 222 deletions(-) diff --git a/src/source.cc b/src/source.cc index a06b1d1..edc9616 100644 --- a/src/source.cc +++ b/src/source.cc @@ -293,9 +293,15 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy } set_tab_char_and_size(tab_char, tab_size); + bracket_regex=boost::regex("^([ \\t]*).*\\{ *$"); + no_bracket_statement_regex=boost::regex("^([ \\t]*)(if|for|else if|while) *\\(.*[^;}] *$"); + no_bracket_no_para_statement_regex=boost::regex("^([ \\t]*)(else) *$"); + 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")) { + is_bracket_language=true; + auto_indent=[this]() { auto command=Config::get().terminal.clang_format_command; bool use_style_file=false; @@ -1041,8 +1047,15 @@ bool Source::View::find_left_bracket_backward(Gtk::TextIter iter, Gtk::TextIter return false; } -//Basic indentation bool Source::View::on_key_press_event(GdkEventKey* key) { + if(is_bracket_language) + return on_key_press_event_bracket_language(key); + else + return on_key_press_event_basic(key); +} + +//Basic indentation +bool Source::View::on_key_press_event_basic(GdkEventKey* key) { if(spellcheck_suggestions_dialog && spellcheck_suggestions_dialog->shown) { if(spellcheck_suggestions_dialog->on_key_press(key)) return true; @@ -1270,6 +1283,215 @@ bool Source::View::on_key_press_event(GdkEventKey* key) { return stop; } +//Bracket language indentation +bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) { + if(spellcheck_suggestions_dialog && spellcheck_suggestions_dialog->shown) { + if(spellcheck_suggestions_dialog->on_key_press(key)) + return true; + } + + auto iter=get_buffer()->get_insert()->get_iter(); + if(iter.backward_char() && (get_source_buffer()->iter_has_context_class(iter, "comment") || get_source_buffer()->iter_has_context_class(iter, "string"))) + return on_key_press_event_basic(key); + + if(get_buffer()->get_has_selection()) { + return on_key_press_event_basic(key); + } + get_source_buffer()->begin_user_action(); + iter=get_buffer()->get_insert()->get_iter(); + //Indent depending on if/else/etc and brackets + if(key->keyval==GDK_KEY_Return && !iter.starts_line()) { + //First remove spaces or tabs around cursor + 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()) {} + start_blank_iter.backward_char(); + while((*start_blank_iter==' ' || *start_blank_iter=='\t' || start_blank_iter.ends_line()) && + !start_blank_iter.starts_line() && start_blank_iter.backward_char()) {} + if(!start_blank_iter.starts_line()) { + start_blank_iter.forward_char(); + get_buffer()->erase(start_blank_iter, end_blank_iter); + } + else + get_buffer()->erase(iter, end_blank_iter); + iter=get_buffer()->get_insert()->get_iter(); + + Gtk::TextIter start_of_sentence_iter; + if(find_start_of_closed_expression(iter, start_of_sentence_iter)) { + auto start_sentence_tabs_end_iter=get_tabs_end_iter(start_of_sentence_iter); + auto tabs=get_line_before(start_sentence_tabs_end_iter); + + boost::smatch sm; + if(iter.backward_char() && *iter=='{') { + auto found_iter=iter; + bool found_right_bracket=find_right_bracket_forward(iter, found_iter); + + bool has_bracket=false; + 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_bracket=true; + } + if(*get_buffer()->get_insert()->get_iter()=='}') { + get_source_buffer()->insert_at_cursor("\n"+tabs+tab+"\n"+tabs); + auto insert_it = get_source_buffer()->get_insert()->get_iter(); + if(insert_it.backward_chars(tabs.size()+1)) { + scroll_to(get_source_buffer()->get_insert()); + get_source_buffer()->place_cursor(insert_it); + } + get_source_buffer()->end_user_action(); + return true; + } + else if(!has_bracket) { + //Insert new lines with bracket end + get_source_buffer()->insert_at_cursor("\n"+tabs+tab+"\n"+tabs+"}"); + auto insert_it = get_source_buffer()->get_insert()->get_iter(); + if(insert_it.backward_chars(tabs.size()+2)) { + scroll_to(get_source_buffer()->get_insert()); + get_source_buffer()->place_cursor(insert_it); + } + get_source_buffer()->end_user_action(); + return true; + } + else { + get_source_buffer()->insert_at_cursor("\n"+tabs+tab); + scroll_to(get_buffer()->get_insert()); + get_source_buffer()->end_user_action(); + return true; + } + } + auto line=get_line_before(); + iter=get_buffer()->get_insert()->get_iter(); + auto found_iter=iter; + if(find_open_expression_symbol(iter, start_of_sentence_iter, found_iter)) { + auto tabs_end_iter=get_tabs_end_iter(found_iter); + tabs=get_line_before(tabs_end_iter); + auto iter=tabs_end_iter; + while(iter<=found_iter) { + tabs+=' '; + iter.forward_char(); + } + } + else if(boost::regex_match(line, sm, no_bracket_statement_regex)) { + get_source_buffer()->insert_at_cursor("\n"+tabs+tab); + scroll_to(get_source_buffer()->get_insert()); + get_source_buffer()->end_user_action(); + return true; + } + else if(boost::regex_match(line, sm, no_bracket_no_para_statement_regex)) { + get_source_buffer()->insert_at_cursor("\n"+tabs+tab); + scroll_to(get_source_buffer()->get_insert()); + get_source_buffer()->end_user_action(); + return true; + } + //Indenting after for instance if(...)\n...;\n + else if(iter.backward_char() && *iter==';') { + boost::smatch sm2; + size_t line_nr=get_source_buffer()->get_insert()->get_iter().get_line(); + if(line_nr>0 && tabs.size()>=tab_size) { + std::string previous_line=get_line(line_nr-1); + if(!boost::regex_match(previous_line, sm2, bracket_regex)) { + if(boost::regex_match(previous_line, sm2, no_bracket_statement_regex)) { + get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); + scroll_to(get_source_buffer()->get_insert()); + get_source_buffer()->end_user_action(); + return true; + } + else if(boost::regex_match(previous_line, sm2, no_bracket_no_para_statement_regex)) { + get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); + scroll_to(get_source_buffer()->get_insert()); + get_source_buffer()->end_user_action(); + return true; + } + } + } + } + //Indenting after ':' + else if(*iter==':') { + Gtk::TextIter left_bracket_iter; + if(find_left_bracket_backward(iter, left_bracket_iter)) { + if(!left_bracket_iter.ends_line()) + left_bracket_iter.forward_char(); + Gtk::TextIter start_of_left_bracket_sentence_iter; + if(find_start_of_closed_expression(left_bracket_iter, start_of_left_bracket_sentence_iter)) { + boost::smatch sm; + auto tabs_end_iter=get_tabs_end_iter(start_of_left_bracket_sentence_iter); + 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;cerase(start_line_iter, start_line_plus_tab_size); + } + else { + get_source_buffer()->insert_at_cursor("\n"+tabs+tab); + scroll_to(get_source_buffer()->get_insert()); + get_source_buffer()->end_user_action(); + return true; + } + } + } + } + get_source_buffer()->insert_at_cursor("\n"+tabs); + scroll_to(get_source_buffer()->get_insert()); + get_source_buffer()->end_user_action(); + 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) { + for(auto c: line) { + if(c!=tab_char) { + get_source_buffer()->insert_at_cursor("}"); + get_source_buffer()->end_user_action(); + return true; + } + } + Gtk::TextIter insert_it = get_source_buffer()->get_insert()->get_iter(); + Gtk::TextIter line_it = get_source_buffer()->get_iter_at_line(insert_it.get_line()); + Gtk::TextIter line_plus_it=line_it; + line_plus_it.forward_chars(tab_size); + get_source_buffer()->erase(line_it, line_plus_it); + } + get_source_buffer()->insert_at_cursor("}"); + get_source_buffer()->end_user_action(); + return true; + } + //Indent left when writing { on a new line after for instance if(...)\n... + else if(key->keyval==GDK_KEY_braceleft) { + auto iter=get_buffer()->get_insert()->get_iter(); + 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) { + std::string previous_line=get_line(line_nr-1); + boost::smatch sm; + if(!boost::regex_match(previous_line, sm, bracket_regex)) { + auto start_iter=iter; + start_iter.backward_chars(tab_size); + if(boost::regex_match(previous_line, sm, no_bracket_statement_regex) || + boost::regex_match(previous_line, sm, no_bracket_no_para_statement_regex)) { + if((tabs.size()-tab_size)==sm[1].str().size()) { + get_buffer()->erase(start_iter, iter); + get_buffer()->insert_at_cursor("{"); + scroll_to(get_buffer()->get_insert()); + get_buffer()->end_user_action(); + return true; + } + } + } + } + } + + get_source_buffer()->end_user_action(); + return on_key_press_event_basic(key); +} + bool Source::View::on_button_press_event(GdkEventButton *event) { if(event->type==GDK_2BUTTON_PRESS) { Gtk::TextIter start, end; diff --git a/src/source.h b/src/source.h index 2da18b5..e9050c3 100644 --- a/src/source.h +++ b/src/source.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "selectiondialog.h" #include "tooltips.h" @@ -136,7 +137,14 @@ namespace Source { bool find_right_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter); bool find_left_bracket_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter); + boost::regex bracket_regex; + boost::regex no_bracket_statement_regex; + boost::regex no_bracket_no_para_statement_regex; + 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 is_bracket_language=false; bool on_button_press_event(GdkEventButton *event) override; std::pair find_tab_char_and_size(); diff --git a/src/source_clang.cc b/src/source_clang.cc index 439aeb4..3454322 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -70,10 +70,6 @@ void Source::ClangViewParse::configure() { JINFO("Style " + item.second + " not found in " + scheme->get_name()); } } - - bracket_regex=boost::regex("^([ \\t]*).*\\{ *$"); - no_bracket_statement_regex=boost::regex("^([ \\t]*)(if|for|else if|while) *\\(.*[^;}] *$"); - no_bracket_no_para_statement_regex=boost::regex("^([ \\t]*)(else) *$"); } void Source::ClangViewParse::parse_initialize() { @@ -451,215 +447,6 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) //type_tooltips.show(rectangle); } -//Clang indentation. -bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { - if(spellcheck_suggestions_dialog && spellcheck_suggestions_dialog->shown) { - if(spellcheck_suggestions_dialog->on_key_press(key)) - return true; - } - - auto iter=get_buffer()->get_insert()->get_iter(); - if(iter.backward_char() && (get_source_buffer()->iter_has_context_class(iter, "comment") || get_source_buffer()->iter_has_context_class(iter, "string"))) - return Source::View::on_key_press_event(key); - - if(get_buffer()->get_has_selection()) { - return Source::View::on_key_press_event(key); - } - get_source_buffer()->begin_user_action(); - iter=get_buffer()->get_insert()->get_iter(); - //Indent depending on if/else/etc and brackets - if(key->keyval==GDK_KEY_Return && !iter.starts_line()) { - //First remove spaces or tabs around cursor - 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()) {} - start_blank_iter.backward_char(); - while((*start_blank_iter==' ' || *start_blank_iter=='\t' || start_blank_iter.ends_line()) && - !start_blank_iter.starts_line() && start_blank_iter.backward_char()) {} - if(!start_blank_iter.starts_line()) { - start_blank_iter.forward_char(); - get_buffer()->erase(start_blank_iter, end_blank_iter); - } - else - get_buffer()->erase(iter, end_blank_iter); - iter=get_buffer()->get_insert()->get_iter(); - - Gtk::TextIter start_of_sentence_iter; - if(find_start_of_closed_expression(iter, start_of_sentence_iter)) { - auto start_sentence_tabs_end_iter=get_tabs_end_iter(start_of_sentence_iter); - auto tabs=get_line_before(start_sentence_tabs_end_iter); - - boost::smatch sm; - if(iter.backward_char() && *iter=='{') { - auto found_iter=iter; - bool found_right_bracket=find_right_bracket_forward(iter, found_iter); - - bool has_bracket=false; - 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_bracket=true; - } - if(*get_buffer()->get_insert()->get_iter()=='}') { - get_source_buffer()->insert_at_cursor("\n"+tabs+tab+"\n"+tabs); - auto insert_it = get_source_buffer()->get_insert()->get_iter(); - if(insert_it.backward_chars(tabs.size()+1)) { - scroll_to(get_source_buffer()->get_insert()); - get_source_buffer()->place_cursor(insert_it); - } - get_source_buffer()->end_user_action(); - return true; - } - else if(!has_bracket) { - //Insert new lines with bracket end - get_source_buffer()->insert_at_cursor("\n"+tabs+tab+"\n"+tabs+"}"); - auto insert_it = get_source_buffer()->get_insert()->get_iter(); - if(insert_it.backward_chars(tabs.size()+2)) { - scroll_to(get_source_buffer()->get_insert()); - get_source_buffer()->place_cursor(insert_it); - } - get_source_buffer()->end_user_action(); - return true; - } - else { - get_source_buffer()->insert_at_cursor("\n"+tabs+tab); - scroll_to(get_buffer()->get_insert()); - get_source_buffer()->end_user_action(); - return true; - } - } - auto line=get_line_before(); - iter=get_buffer()->get_insert()->get_iter(); - auto found_iter=iter; - if(find_open_expression_symbol(iter, start_of_sentence_iter, found_iter)) { - auto tabs_end_iter=get_tabs_end_iter(found_iter); - tabs=get_line_before(tabs_end_iter); - auto iter=tabs_end_iter; - while(iter<=found_iter) { - tabs+=' '; - iter.forward_char(); - } - } - else if(boost::regex_match(line, sm, no_bracket_statement_regex)) { - get_source_buffer()->insert_at_cursor("\n"+tabs+tab); - scroll_to(get_source_buffer()->get_insert()); - get_source_buffer()->end_user_action(); - return true; - } - else if(boost::regex_match(line, sm, no_bracket_no_para_statement_regex)) { - get_source_buffer()->insert_at_cursor("\n"+tabs+tab); - scroll_to(get_source_buffer()->get_insert()); - get_source_buffer()->end_user_action(); - return true; - } - //Indenting after for instance if(...)\n...;\n - else if(iter.backward_char() && *iter==';') { - boost::smatch sm2; - size_t line_nr=get_source_buffer()->get_insert()->get_iter().get_line(); - if(line_nr>0 && tabs.size()>=tab_size) { - std::string previous_line=get_line(line_nr-1); - if(!boost::regex_match(previous_line, sm2, bracket_regex)) { - if(boost::regex_match(previous_line, sm2, no_bracket_statement_regex)) { - get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); - scroll_to(get_source_buffer()->get_insert()); - get_source_buffer()->end_user_action(); - return true; - } - else if(boost::regex_match(previous_line, sm2, no_bracket_no_para_statement_regex)) { - get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); - scroll_to(get_source_buffer()->get_insert()); - get_source_buffer()->end_user_action(); - return true; - } - } - } - } - //Indenting after ':' - else if(*iter==':') { - Gtk::TextIter left_bracket_iter; - if(find_left_bracket_backward(iter, left_bracket_iter)) { - if(!left_bracket_iter.ends_line()) - left_bracket_iter.forward_char(); - Gtk::TextIter start_of_left_bracket_sentence_iter; - if(find_start_of_closed_expression(left_bracket_iter, start_of_left_bracket_sentence_iter)) { - boost::smatch sm; - auto tabs_end_iter=get_tabs_end_iter(start_of_left_bracket_sentence_iter); - 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;cerase(start_line_iter, start_line_plus_tab_size); - } - else { - get_source_buffer()->insert_at_cursor("\n"+tabs+tab); - scroll_to(get_source_buffer()->get_insert()); - get_source_buffer()->end_user_action(); - return true; - } - } - } - } - get_source_buffer()->insert_at_cursor("\n"+tabs); - scroll_to(get_source_buffer()->get_insert()); - get_source_buffer()->end_user_action(); - 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) { - for(auto c: line) { - if(c!=tab_char) { - get_source_buffer()->insert_at_cursor("}"); - get_source_buffer()->end_user_action(); - return true; - } - } - Gtk::TextIter insert_it = get_source_buffer()->get_insert()->get_iter(); - Gtk::TextIter line_it = get_source_buffer()->get_iter_at_line(insert_it.get_line()); - Gtk::TextIter line_plus_it=line_it; - line_plus_it.forward_chars(tab_size); - get_source_buffer()->erase(line_it, line_plus_it); - } - get_source_buffer()->insert_at_cursor("}"); - get_source_buffer()->end_user_action(); - return true; - } - //Indent left when writing { on a new line after for instance if(...)\n... - else if(key->keyval==GDK_KEY_braceleft) { - auto iter=get_buffer()->get_insert()->get_iter(); - 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) { - std::string previous_line=get_line(line_nr-1); - boost::smatch sm; - if(!boost::regex_match(previous_line, sm, bracket_regex)) { - auto start_iter=iter; - start_iter.backward_chars(tab_size); - if(boost::regex_match(previous_line, sm, no_bracket_statement_regex) || - boost::regex_match(previous_line, sm, no_bracket_no_para_statement_regex)) { - if((tabs.size()-tab_size)==sm[1].str().size()) { - get_buffer()->erase(start_iter, iter); - get_buffer()->insert_at_cursor("{"); - scroll_to(get_buffer()->get_insert()); - get_buffer()->end_user_action(); - return true; - } - } - } - } - } - - get_source_buffer()->end_user_action(); - return Source::View::on_key_press_event(key); -} - ////////////////////////////// //// ClangViewAutocomplete /// ////////////////////////////// @@ -720,7 +507,7 @@ bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { if(autocomplete_dialog->on_key_press(key)) return true; } - return ClangViewParse::on_key_press_event(key); + return View::on_key_press_event(key); } void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { diff --git a/src/source_clang.h b/src/source_clang.h index c29d863..18c9690 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -5,7 +5,6 @@ #include #include #include -#include #include "clangmm.h" #include "source.h" #include "terminal.h" @@ -42,12 +41,6 @@ namespace Source { void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) override; void show_type_tooltips(const Gdk::Rectangle &rectangle) override; - bool on_key_press_event(GdkEventKey* key) override; - - boost::regex bracket_regex; - boost::regex no_bracket_statement_regex; - boost::regex no_bracket_no_para_statement_regex; - std::set diagnostic_offsets; std::vector fix_its; From 44061a0fcaa3d1c24edaa7e06158a0e307e3c267 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 6 Mar 2016 10:45:48 +0100 Subject: [PATCH 5/9] Added auto indentation and better indentation for C# --- src/source.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/source.cc b/src/source.cc index edc9616..7d7e010 100644 --- a/src/source.cc +++ b/src/source.cc @@ -299,7 +299,8 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy 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()=="js" || language->get_id()=="ts" || language->get_id()=="proto" || + language->get_id()=="c-sharp")) { is_bracket_language=true; auto_indent=[this]() { From 89c96d598d9ed9002b67d83f6eed8f0aada8921d Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 6 Mar 2016 15:25:14 +0100 Subject: [PATCH 6/9] Smart indentation cleanup --- src/source.cc | 43 ++++++++++++++++++------------------------- src/source.h | 3 +-- src/source_clang.cc | 9 --------- src/source_clang.h | 3 --- 4 files changed, 19 insertions(+), 39 deletions(-) diff --git a/src/source.cc b/src/source.cc index 7d7e010..79f9bff 100644 --- a/src/source.cc +++ b/src/source.cc @@ -151,12 +151,12 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy if(ends_line || *iter=='/' || *iter=='*') //iter_has_context_class is sadly bugged backward_success=context_iter.backward_char(); if(backward_success) { - if(last_keyval_is_backspace && !is_word_iter(iter) && iter.forward_char()) {} //backspace fix + if(last_keyval==GDK_KEY_BackSpace && !is_word_iter(iter) && iter.forward_char()) {} //backspace fix if((spellcheck_all && !get_source_buffer()->iter_has_context_class(context_iter, "no-spell-check")) || get_source_buffer()->iter_has_context_class(context_iter, "comment") || get_source_buffer()->iter_has_context_class(context_iter, "string")) { - if(!is_word_iter(iter) || last_keyval_is_return) { //Might have used space or - to split two words + if(!is_word_iter(iter) || last_keyval==GDK_KEY_Return) { //Might have used space or - to split two words auto first=iter; auto second=iter; - if(last_keyval_is_return) { + if(last_keyval==GDK_KEY_Return) { while(first && !first.ends_line() && first.backward_char()) {} if(first.backward_char() && second.forward_char()) { get_buffer()->remove_tag_by_name("spellcheck_error", first, second); @@ -1049,6 +1049,21 @@ bool Source::View::find_left_bracket_backward(Gtk::TextIter iter, Gtk::TextIter } bool Source::View::on_key_press_event(GdkEventKey* key) { + if(spellcheck_suggestions_dialog && spellcheck_suggestions_dialog->shown) { + if(spellcheck_suggestions_dialog->on_key_press(key)) + return true; + } + + if(autocomplete_dialog && autocomplete_dialog->shown) { + if(autocomplete_dialog->on_key_press(key)) + return true; + } + + last_keyval=key->keyval; + + if(get_buffer()->get_has_selection()) + return on_key_press_event_basic(key); + if(is_bracket_language) return on_key_press_event_bracket_language(key); else @@ -1057,20 +1072,6 @@ bool Source::View::on_key_press_event(GdkEventKey* key) { //Basic indentation bool Source::View::on_key_press_event_basic(GdkEventKey* key) { - if(spellcheck_suggestions_dialog && spellcheck_suggestions_dialog->shown) { - if(spellcheck_suggestions_dialog->on_key_press(key)) - return true; - } - - if(key->keyval==GDK_KEY_BackSpace) - last_keyval_is_backspace=true; - else - last_keyval_is_backspace=false; - if(key->keyval==GDK_KEY_Return) - last_keyval_is_return=true; - else - last_keyval_is_return=false; - get_source_buffer()->begin_user_action(); auto iter=get_buffer()->get_insert()->get_iter(); //Indent as in next or previous line @@ -1286,18 +1287,10 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) { //Bracket language indentation bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) { - if(spellcheck_suggestions_dialog && spellcheck_suggestions_dialog->shown) { - if(spellcheck_suggestions_dialog->on_key_press(key)) - return true; - } - auto iter=get_buffer()->get_insert()->get_iter(); if(iter.backward_char() && (get_source_buffer()->iter_has_context_class(iter, "comment") || get_source_buffer()->iter_has_context_class(iter, "string"))) return on_key_press_event_basic(key); - if(get_buffer()->get_has_selection()) { - return on_key_press_event_basic(key); - } get_source_buffer()->begin_user_action(); iter=get_buffer()->get_insert()->get_iter(); //Indent depending on if/else/etc and brackets diff --git a/src/source.h b/src/source.h index e9050c3..f0dde90 100644 --- a/src/source.h +++ b/src/source.h @@ -154,8 +154,7 @@ namespace Source { bool spellcheck_all=false; std::unique_ptr spellcheck_suggestions_dialog; - bool last_keyval_is_backspace=false; - bool last_keyval_is_return=false; + guint last_keyval=0; private: GtkSourceSearchContext *search_context; GtkSourceSearchSettings *search_settings; diff --git a/src/source_clang.cc b/src/source_clang.cc index 3454322..439f192 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -501,15 +501,6 @@ Source::ClangViewParse(file_path, project_path, language), autocomplete_state(Au }); } -bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { - last_keyval=key->keyval; - if(autocomplete_dialog && autocomplete_dialog->shown) { - if(autocomplete_dialog->on_key_press(key)) - return true; - } - return View::on_key_press_event(key); -} - void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { auto start_iter=get_buffer()->get_insert()->get_iter(); if(prefix.size()>0 && !start_iter.backward_chars(prefix.size())) diff --git a/src/source_clang.h b/src/source_clang.h index 18c9690..e392dfd 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -76,8 +76,6 @@ namespace Source { virtual void async_delete(); bool full_reparse() override; protected: - bool on_key_press_event(GdkEventKey* key) override; - std::thread autocomplete_thread; private: std::atomic autocomplete_state; @@ -87,7 +85,6 @@ namespace Source { std::unordered_map > autocomplete_dialog_rows; std::vector autocomplete_get_suggestions(const std::string &buffer, int line_number, int column); Tooltips autocomplete_tooltips; - guint last_keyval=0; std::string prefix; std::mutex prefix_mutex; From d366618adf8c08c9b27296c3ffdfc62fbd99d1ec Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 6 Mar 2016 15:37:37 +0100 Subject: [PATCH 7/9] Yet another smart indentation cleanup --- src/source.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/source.cc b/src/source.cc index 79f9bff..6a7d4ee 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1064,6 +1064,10 @@ bool Source::View::on_key_press_event(GdkEventKey* key) { if(get_buffer()->get_has_selection()) return on_key_press_event_basic(key); + auto iter=get_buffer()->get_insert()->get_iter(); + if(iter.backward_char() && (get_source_buffer()->iter_has_context_class(iter, "comment") || get_source_buffer()->iter_has_context_class(iter, "string"))) + return on_key_press_event_basic(key); + if(is_bracket_language) return on_key_press_event_bracket_language(key); else @@ -1287,12 +1291,8 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) { //Bracket language indentation bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) { - auto iter=get_buffer()->get_insert()->get_iter(); - if(iter.backward_char() && (get_source_buffer()->iter_has_context_class(iter, "comment") || get_source_buffer()->iter_has_context_class(iter, "string"))) - return on_key_press_event_basic(key); - get_source_buffer()->begin_user_action(); - iter=get_buffer()->get_insert()->get_iter(); + auto iter=get_buffer()->get_insert()->get_iter(); //Indent depending on if/else/etc and brackets if(key->keyval==GDK_KEY_Return && !iter.starts_line()) { //First remove spaces or tabs around cursor From 90b7f364c65566c53b19f6a27a508b3f2c4c973a Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 7 Mar 2016 07:33:59 +0100 Subject: [PATCH 8/9] Renamed Dispatcher::push to Dispatcher::post --- README.md | 2 +- src/directories.cc | 2 +- src/dispatcher.cc | 2 +- src/dispatcher.h | 2 +- src/project.cc | 4 ++-- src/source_clang.cc | 12 ++++++------ src/terminal.cc | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 61d1c58..e1148a8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # juCi++ -###### a lightweight platform independent C++-IDE with support for C++11, C++14, and experimental C++17 features depending on libclang version. +###### a lightweight, platform independent C++-IDE with support for C++11, C++14, and experimental C++17 features depending on libclang version. ## About Current IDEs struggle with C++ support due to the complexity of diff --git a/src/directories.cc b/src/directories.cc index be1d779..aa1a3c7 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -98,7 +98,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { it=last_write_times.erase(it); } if(update_paths.size()>0) { - dispatcher.push([this] { + dispatcher.post([this] { update_mutex.lock(); for(auto &path: update_paths) { if(last_write_times.count(path)>0) diff --git a/src/dispatcher.cc b/src/dispatcher.cc index bc862f2..e5cc42d 100644 --- a/src/dispatcher.cc +++ b/src/dispatcher.cc @@ -18,7 +18,7 @@ Dispatcher::~Dispatcher() { functions_mutex.unlock(); } -void Dispatcher::push(std::function &&function) { +void Dispatcher::post(std::function &&function) { functions_mutex.lock(); functions.emplace_back(function); functions_mutex.unlock(); diff --git a/src/dispatcher.h b/src/dispatcher.h index 5a326e4..502c330 100644 --- a/src/dispatcher.h +++ b/src/dispatcher.h @@ -13,7 +13,7 @@ private: public: Dispatcher(); ~Dispatcher(); - void push(std::function &&function); + void post(std::function &&function); void disconnect(); }; diff --git a/src/project.cc b/src/project.cc index 0fc11b4..774411e 100644 --- a/src/project.cc +++ b/src/project.cc @@ -265,11 +265,11 @@ void Project::Clang::debug_start() { debugging=false; Terminal::get().async_print(run_arguments+" returned: "+std::to_string(exit_status)+'\n'); }, [this](const std::string &status) { - dispatcher.push([this, status] { + dispatcher.post([this, status] { debug_update_status(status); }); }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { - dispatcher.push([this, file_path, line_nr, line_index] { + dispatcher.post([this, file_path, line_nr, line_index] { Project::debug_stop.first=file_path; Project::debug_stop.second.first=line_nr; Project::debug_stop.second.second=line_index; diff --git a/src/source_clang.cc b/src/source_clang.cc index 439f192..52800d3 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -107,7 +107,7 @@ void Source::ClangViewParse::parse_initialize() { break; auto expected=ParseProcessState::STARTING; if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) { - dispatcher.push([this] { + dispatcher.post([this] { auto expected=ParseProcessState::PREPROCESSING; if(parse_mutex.try_lock()) { if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING)) @@ -126,7 +126,7 @@ void Source::ClangViewParse::parse_initialize() { if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) { clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer.bytes()-1); parse_mutex.unlock(); - dispatcher.push([this] { + dispatcher.post([this] { if(parse_mutex.try_lock()) { auto expected=ParseProcessState::POSTPROCESSING; if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) { @@ -145,7 +145,7 @@ void Source::ClangViewParse::parse_initialize() { else { parse_state=ParseState::STOP; parse_mutex.unlock(); - dispatcher.push([this] { + dispatcher.post([this] { Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); set_status(""); set_info(""); @@ -652,7 +652,7 @@ void Source::ClangViewAutocomplete::autocomplete() { auto autocomplete_data=std::make_shared >(autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr)); if(parse_state==ParseState::PROCESSING) { - dispatcher.push([this, autocomplete_data] { + dispatcher.post([this, autocomplete_data] { if(autocomplete_state==AutocompleteState::CANCELED) { set_status(""); soft_reparse(); @@ -698,7 +698,7 @@ void Source::ClangViewAutocomplete::autocomplete() { }); } else { - dispatcher.push([this] { + dispatcher.post([this] { Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true); autocomplete_state=AutocompleteState::CANCELED; full_reparse(); @@ -778,7 +778,7 @@ bool Source::ClangViewAutocomplete::full_reparse() { parse_thread.join(); if(autocomplete_thread.joinable()) autocomplete_thread.join(); - dispatcher.push([this] { + dispatcher.post([this] { parse_initialize(); full_reparse_running=false; }); diff --git a/src/terminal.cc b/src/terminal.cc index cbd8739..9681ab8 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -210,13 +210,13 @@ std::shared_ptr Terminal::print_in_progress(std::string st } void Terminal::async_print(const std::string &message, bool bold) { - dispatcher.push([this, message, bold] { + dispatcher.post([this, message, bold] { Terminal::get().print(message, bold); }); } void Terminal::async_print(size_t line_nr, const std::string &message) { - dispatcher.push([this, line_nr, message] { + dispatcher.post([this, line_nr, message] { if(line_nr Date: Mon, 7 Mar 2016 09:06:27 +0100 Subject: [PATCH 9/9] Go to cursor improvement and cleanup. Also fixed a potential crash --- src/notebook.cc | 12 ++++++++++++ src/source.cc | 9 ++++----- src/source.h | 1 + src/window.cc | 22 ++++------------------ 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index f973961..3d310c0 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -116,6 +116,18 @@ void Notebook::open(const boost::filesystem::path &file_path) { else source_views.emplace_back(new Source::GenericView(file_path, project_path, language)); + source_views.back()->scroll_to_cursor_delayed=[this](Source::View* view, bool center, bool show_tooltips) { + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); + if(get_current_page()!=-1 && 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->delayed_tooltips_connection.disconnect(); + } + }; source_views.back()->on_update_status=[this](Source::View* view, const std::string &status_text) { if(get_current_page()!=-1 && get_current_view()==view) status.set_text(status_text+" "); diff --git a/src/source.cc b/src/source.cc index 6a7d4ee..a74607b 100644 --- a/src/source.cc +++ b/src/source.cc @@ -349,6 +349,7 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy auto cursor_line_offset=iter.get_line_offset(); get_buffer()->set_text(stdout_stream.str()); + get_source_buffer()->end_user_action(); cursor_line_nr=std::min(cursor_line_nr, get_buffer()->get_line_count()-1); if(cursor_line_nr>=0) { @@ -359,11 +360,8 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy iter.forward_char(); } get_buffer()->place_cursor(iter); - while(g_main_context_pending(NULL)) //TODO: minor: might crash if the buffer is saved and closed really fast right after doing auto indent - g_main_context_iteration(NULL, false); - scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); + scroll_to_cursor_delayed(this, true, false); } - get_source_buffer()->end_user_action(); } }; } @@ -748,12 +746,13 @@ void Source::View::paste() { } } get_buffer()->place_cursor(get_buffer()->get_insert()->get_iter()); - scroll_to(get_buffer()->get_insert()); get_source_buffer()->end_user_action(); + scroll_to_cursor_delayed(this, false, false); } else { Gtk::Clipboard::get()->set_text(text); get_buffer()->paste_clipboard(Gtk::Clipboard::get()); + scroll_to_cursor_delayed(this, false, false); } } diff --git a/src/source.h b/src/source.h index f0dde90..feffbbf 100644 --- a/src/source.h +++ b/src/source.h @@ -92,6 +92,7 @@ namespace Source { Gtk::TextIter get_iter_for_dialog(); sigc::connection delayed_tooltips_connection; + std::function scroll_to_cursor_delayed=[](View* view, bool center, bool show_tooltips) {}; std::function on_update_status; std::function on_update_info; void set_status(const std::string &status); diff --git a/src/window.cc b/src/window.cc index 76081ff..c50ee81 100644 --- a/src/window.cc +++ b/src/window.cc @@ -344,10 +344,7 @@ void Window::set_menu_actions() { if(notebook.get_current_page()!=-1) { auto view=notebook.get_current_view(); - while(g_main_context_pending(NULL)) - g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) - view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); + view->scroll_to_cursor_delayed(view, true, false); } }); @@ -415,12 +412,7 @@ void Window::set_menu_actions() { index=std::min(index, end_line_index); view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(line, index)); - while(g_main_context_pending(NULL)) - g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) { - view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); - view->delayed_tooltips_connection.disconnect(); - } + view->scroll_to_cursor_delayed(view, true, false); } } } @@ -709,10 +701,7 @@ void Window::set_menu_actions() { line_index=0; view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(line_nr, line_index)); - while(g_main_context_pending(NULL)) - g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) - view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); + view->scroll_to_cursor_delayed(view, true, true); } Project::debug_update_stop(); } @@ -984,10 +973,7 @@ void Window::goto_line_entry() { line--; view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line(line)); - while(g_main_context_pending(NULL)) - g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) - view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); + view->scroll_to_cursor_delayed(view, true, false); } } catch(const std::exception &e) {}