diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..50f9423 --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +IndentWidth: 2 +AccessModifierOffset: -2 +UseTab: Never +ColumnLimit: 0 +MaxEmptyLinesToKeep: 2 +SpaceBeforeParens: Never +BreakBeforeBraces: Custom +BraceWrapping: {BeforeElse: true, BeforeCatch: true} +NamespaceIndentation: All diff --git a/README.md b/README.md index 0ca1873..4b525e1 100644 --- a/README.md +++ b/README.md @@ -77,3 +77,30 @@ See [installation guide](docs/install.md). ## Documentation See [how to build the API doc](docs/api.md). + +## Coding style +Due to poor lambda support in clang-format, a custom clang-format is used with the following patch applied: +```diff +diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp +index bb8efd61a3..e80a487055 100644 +--- a/lib/Format/ContinuationIndenter.cpp ++++ b/lib/Format/ContinuationIndenter.cpp +@@ -276,6 +276,8 @@ LineState ContinuationIndenter::getInitialState(unsigned FirstIndent, + } + + bool ContinuationIndenter::canBreak(const LineState &State) { ++ if(Style.ColumnLimit==0) ++ return true; + const FormatToken &Current = *State.NextToken; + const FormatToken &Previous = *Current.Previous; + assert(&Previous == Current.Previous); +@@ -325,6 +327,8 @@ bool ContinuationIndenter::canBreak(const LineState &State) { + } + + bool ContinuationIndenter::mustBreak(const LineState &State) { ++ if(Style.ColumnLimit==0) ++ return false; + const FormatToken &Current = *State.NextToken; + const FormatToken &Previous = *Current.Previous; + if (Current.MustBreakBefore || Current.is(TT_InlineASMColon)) +``` diff --git a/src/autocomplete.cc b/src/autocomplete.cc index 8d5b684..fb2e9ad 100644 --- a/src/autocomplete.cc +++ b/src/autocomplete.cc @@ -130,10 +130,10 @@ void Autocomplete::stop() { } void Autocomplete::setup_dialog() { - CompletionDialog::get()->on_show=[this] { + CompletionDialog::get()->on_show = [this] { on_show(); }; - + CompletionDialog::get()->on_hide = [this]() { view->get_buffer()->end_user_action(); tooltips.hide(); @@ -141,39 +141,39 @@ void Autocomplete::setup_dialog() { 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 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()) + + 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 1d5939b..6e2fc45 100644 --- a/src/autocomplete.h +++ b/src/autocomplete.h @@ -40,19 +40,19 @@ public: /// The handler is not run in the main loop. std::function add_rows = [](std::string &, int, int) {}; - + std::function on_show = [] {}; std::function on_hide = [] {}; std::function on_changed = [](unsigned int index, const std::string &text) {}; std::function on_select = [](unsigned int index, const std::string &text, bool hide_window) {}; - - std::function get_tooltip = [](unsigned int index) {return std::string();}; + + std::function 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(); }; diff --git a/src/cmake.cc b/src/cmake.cc index 1d23a31..ccb3cb3 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -1,14 +1,14 @@ #include "cmake.h" -#include "filesystem.h" -#include "dialogs.h" +#include "compile_commands.h" #include "config.h" +#include "dialogs.h" +#include "filesystem.h" #include "terminal.h" #include -#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 auto find_cmake_project = [](const boost::filesystem::path &cmake_path) { + for(auto &line : filesystem::read_lines(cmake_path)) { const static std::regex project_regex(R"(^ *project *\(.*\r?$)", std::regex::icase); std::smatch sm; if(std::regex_match(line, sm, project_regex)) @@ -16,53 +16,53 @@ CMake::CMake(const boost::filesystem::path &path) { } return false; }; - - auto search_path=boost::filesystem::is_directory(path)?path:path.parent_path(); + + auto search_path = boost::filesystem::is_directory(path) ? path : path.parent_path(); while(true) { - auto search_cmake_path=search_path/"CMakeLists.txt"; + 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; + project_path = search_path; break; } } - if(search_path==search_path.root_directory()) + if(search_path == search_path.root_directory()) break; - search_path=search_path.parent_path(); + 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()) + 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); + 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")) + + if(!force && boost::filesystem::exists(default_build_path / "compile_commands.json")) return true; - - auto compile_commands_path=default_build_path/"compile_commands.json"; + + 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); + 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) { + 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 compile_commands_file = filesystem::read(compile_commands_path); + auto replace_drive = [&compile_commands_file](const std::string ¶m) { + 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 cmake_executables; - for(auto ¶meter: 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) + for(auto ¶meter : 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> 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"); + 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); + 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; + + 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) + + 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(); + auto command_file_directory = command_file.parent_path(); if(filesystem::file_in_path(file_path, command_file_directory)) { - auto size=static_cast(std::distance(command_file_directory.begin(), command_file_directory.end())); - if(best_match_size==static_cast(-1) || best_match_size(std::distance(command_file_directory.begin(), command_file_directory.end())); + if(best_match_size == static_cast(-1) || best_match_size < size) { + best_match_size = size; + best_match_executable = maybe_executable; } } } @@ -159,18 +159,18 @@ boost::filesystem::path CMake::get_executable(const boost::filesystem::path &bui } 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) + + 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(); + auto command_file_directory = command_file.parent_path(); if(filesystem::file_in_path(file_path, command_file_directory)) { - auto size=static_cast(std::distance(command_file_directory.begin(), command_file_directory.end())); - if(best_match_size==static_cast(-1) || best_match_size(std::distance(command_file_directory.begin(), command_file_directory.end())); + if(best_match_size == static_cast(-1) || best_match_size < size) { + best_match_size = size; + best_match_executable = maybe_executable; } } } @@ -178,33 +178,33 @@ boost::filesystem::path CMake::get_executable(const boost::filesystem::path &bui } void CMake::read_files() { - for(auto &path: paths) + 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; + for(auto &file : files) { + size_t pos = 0; size_t comment_start; - bool inside_comment=false; - while(pos(-1)) - last_char=data[pos]; + + if(pos != static_cast(-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+'}'); + 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); + 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); } } @@ -285,93 +285,93 @@ void CMake::parse() { remove_tabs(); remove_comments(); remove_newlines_inside_parentheses(); - parsed=true; + parsed = true; } std::vector CMake::get_function_parameters(std::string &data) { std::vector parameters; - size_t pos=0; - size_t parameter_pos=0; - bool inside_quote=false; - char last_char=0; - while(pos(-1)) - last_char=data[pos]; + + if(pos != static_cast(-1)) + last_char = data[pos]; pos++; } parameters.emplace_back(data.substr(parameter_pos)); - for(auto &var: variables) { - for(auto ¶meter: 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+'}'); + for(auto &var : variables) { + for(auto ¶meter : 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 > > CMake::get_functions_parameters(const std::string &name) { - const std::regex function_regex("^ *"+name+R"( *\( *(.*)\) *\r?$)", std::regex::icase); +std::vector>> 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 > > functions; - for(size_t c=0;cstart_line) { - auto line=files[c].substr(start_line, end_line-start_line); + std::vector>> 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()==' ') + auto data = sm[2].str(); + while(data.size() > 0 && data.back() == ' ') data.pop_back(); parse_variable_parameters(data); - variables[sm[1].str()]=data; + variables[sm[1].str()] = data; } else if(std::regex_match(line, sm, project_regex)) { - auto data=sm[1].str(); + 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; + 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()==' ') + auto data = sm[1].str(); + while(data.size() > 0 && data.back() == ' ') data.pop_back(); - auto parameters=get_function_parameters(data); + auto parameters = get_function_parameters(data); functions.emplace_back(paths[c], parameters); } } - pos=end_line+1; + pos = end_line + 1; } } return functions; diff --git a/src/cmake.h b/src/cmake.h index f87010a..b60f089 100644 --- a/src/cmake.h +++ b/src/cmake.h @@ -1,19 +1,19 @@ #pragma once #include -#include #include #include +#include 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); - + + 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 paths; std::vector files; @@ -25,6 +25,6 @@ private: void parse_variable_parameters(std::string &data); void parse(); std::vector get_function_parameters(std::string &data); - std::vector > > get_functions_parameters(const std::string &name); - bool parsed=false; + std::vector>> get_functions_parameters(const std::string &name); + bool parsed = false; }; diff --git a/src/compile_commands.cc b/src/compile_commands.cc index 4c58eda..01952f2 100644 --- a/src/compile_commands.cc +++ b/src/compile_commands.cc @@ -5,101 +5,102 @@ std::vector CompileCommands::Command::parameter_values(const std::string ¶meter_name) const { std::vector parameter_values; - - bool found_argument=false; - for(auto ¶meter: parameters) { + + bool found_argument = false; + for(auto ¶meter : parameters) { if(found_argument) { parameter_values.emplace_back(parameter); - found_argument=false; + found_argument = false; } - else if(parameter==parameter_name) - found_argument=true; + 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("directory"); - auto parameters_str=command.second.get("command"); - boost::filesystem::path file=command.second.get("file"); - + 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("directory"); + auto parameters_str = command.second.get("command"); + boost::filesystem::path file = command.second.get("file"); + std::vector 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=[¶meters, ¶meters_str, ¶meter_start_pos, ¶meter_size] { - auto parameter=parameters_str.substr(parameter_start_pos, parameter_size); + 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 = [¶meters, ¶meters_str, ¶meter_start_pos, ¶meter_size] { + auto parameter = parameters_str.substr(parameter_start_pos, parameter_size); // Remove escaping - for(size_t c=0;c CompileCommands::get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) { - std::string default_std_argument="-std=c++1y"; - + std::string default_std_argument = "-std=c++1y"; + std::vector 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) { + for(auto &cmd : cmds) { auto cmd_arguments = cmd.get_arguments(); - bool ignore_next=false; - for (size_t c = 1; c < cmd_arguments.size(); c++) { + bool ignore_next = false; + for(size_t c = 1; c < cmd_arguments.size(); c++) { if(ignore_next) { - ignore_next=false; + ignore_next = false; continue; } - else if(cmd_arguments[c]=="-o" || cmd_arguments[c]=="-c" || - cmd_arguments[c]=="-x") { // Remove language arguments since some tools add languages not understood by clang - ignore_next=true; + else if(cmd_arguments[c] == "-o" || cmd_arguments[c] == "-c" || + cmd_arguments[c] == "-x") { // Remove language arguments since some tools add languages not understood by clang + ignore_next = true; continue; } arguments.emplace_back(cmd_arguments[c]); @@ -111,44 +112,44 @@ std::vector CompileCommands::get_arguments(const boost::filesystem: } else arguments.emplace_back(default_std_argument); - - auto clang_version_string=clangmm::to_string(clang_getClangVersion()); + + 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; 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"); + 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(); - bool is_header=CompileCommands::is_header(file_path) || extension.empty(); // Include std C++ headers that are without extensions - + + auto extension = file_path.extension().string(); + bool is_header = CompileCommands::is_header(file_path) || extension.empty(); // Include std C++ headers that are without extensions + if(is_header) { 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") { + + if(extension == ".cu" || extension == ".cuh") { arguments.emplace_back("-xcuda"); arguments.emplace_back("-D__CUDACC__"); arguments.emplace_back("-include"); arguments.emplace_back("cuda_runtime.h"); arguments.emplace_back("-ferror-limit=1000"); // CUDA headers redeclares some std functions } - else if(extension==".cl") { + else if(extension == ".cl") { arguments.emplace_back("-xcl"); arguments.emplace_back("-cl-std=CL2.0"); arguments.emplace_back("-Xclang"); @@ -157,7 +158,7 @@ std::vector CompileCommands::get_arguments(const boost::filesystem: } else if(is_header) arguments.emplace_back("-xc++"); - + if(!build_path.empty()) { arguments.emplace_back("-working-directory"); arguments.emplace_back(build_path.string()); @@ -168,9 +169,9 @@ std::vector CompileCommands::get_arguments(const boost::filesystem: bool CompileCommands::is_header(const boost::filesystem::path &path) { auto ext = path.extension(); - if(ext == ".h" || // c headers + if(ext == ".h" || // c headers ext == ".hh" || ext == ".hp" || ext == ".hpp" || ext == ".h++" || ext == ".tcc" || // c++ headers - ext == ".cuh") // CUDA headers + ext == ".cuh") // CUDA headers return true; else return false; @@ -178,10 +179,10 @@ bool CompileCommands::is_header(const boost::filesystem::path &path) { bool CompileCommands::is_source(const boost::filesystem::path &path) { auto ext = path.extension(); - if(ext == ".c" || // c sources + 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 + ext == ".cu" || // CUDA sources + ext == ".cl") // OpenCL sources return true; else return false; diff --git a/src/compile_commands.h b/src/compile_commands.h index a992019..54f6424 100644 --- a/src/compile_commands.h +++ b/src/compile_commands.h @@ -1,7 +1,7 @@ #pragma once #include -#include #include +#include class CompileCommands { public: @@ -10,16 +10,16 @@ public: boost::filesystem::path directory; std::vector parameters; boost::filesystem::path file; - + std::vector parameter_values(const std::string ¶meter_name) const; }; - + CompileCommands(const boost::filesystem::path &build_path); std::vector commands; - + /// Return arguments for the given file using libclangmm static std::vector get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path); - + static bool is_header(const boost::filesystem::path &path); static bool is_source(const boost::filesystem::path &path); }; diff --git a/src/config.cc b/src/config.cc index 934b438..fda194f 100644 --- a/src/config.cc +++ b/src/config.cc @@ -1,20 +1,20 @@ #include "config.h" -#include #include "files.h" -#include #include "filesystem.h" #include "terminal.h" #include +#include +#include Config::Config() { - home_path=filesystem::get_home_path(); + 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_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 + 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(); @@ -23,8 +23,8 @@ void Config::load() { 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); + 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; @@ -34,67 +34,67 @@ void Config::load() { } void Config::find_or_create_config_files() { - auto config_dir = home_juci_path/"config"; - auto config_json = config_dir/"config.json"; + 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)) + if(!boost::filesystem::exists(config_json)) filesystem::write(config_json, default_config_file); - auto juci_style_path = home_juci_path/"styles"; + 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"; + 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"; + 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"; + 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("version")!=JUCI_VERSION) { + bool cfg_ok = true; + if(cfg.get("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()) { + 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; + 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); + + 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); + 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::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"); + 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()=="p") { + 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() == "p") { dispatcher.post([] { ::Terminal::get().print("Preference change: keybindings.print set to \"\"\n"); }); - it_file_print->second.data()=""; + it_file_print->second.data() = ""; } } } @@ -104,37 +104,37 @@ void Config::make_version_dependent_corrections(boost::property_tree::ptree &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; + if(parent_path.size() > 0) + parent_path += "."; + bool unchanged = true; + for(auto &node : default_cfg) { + auto path = parent_path + node.first; try { cfg.get(path); } catch(const std::exception &e) { cfg.add(path, node.second.data()); - unchanged=false; + unchanged = false; } - unchanged&=add_missing_nodes(cfg, node.second, path); + 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; + 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(path); - unchanged&=remove_deprecated_nodes(it->second, default_cfg, path); + unchanged &= remove_deprecated_nodes(it->second, default_cfg, path); ++it; } catch(const std::exception &e) { - it=cfg.erase(it); - unchanged=false; + it = cfg.erase(it); + unchanged = false; } } return unchanged; @@ -142,21 +142,21 @@ bool Config::remove_deprecated_nodes(boost::property_tree::ptree &cfg, const boo void Config::read(const boost::property_tree::ptree &cfg) { auto keybindings_pt = cfg.get_child("keybindings"); - for (auto &i : keybindings_pt) { + for(auto &i : keybindings_pt) { menu.keys[i.first] = i.second.get_value(); } - + auto source_json = cfg.get_child("source"); - source.style=source_json.get("style"); - source.font=source_json.get("font"); - source.cleanup_whitespace_characters=source_json.get("cleanup_whitespace_characters"); - source.show_whitespace_characters=source_json.get("show_whitespace_characters"); - source.format_style_on_save=source_json.get("format_style_on_save"); - source.format_style_on_save_if_style_file_found=source_json.get("format_style_on_save_if_style_file_found"); - source.smart_brackets=source_json.get("smart_brackets"); - source.smart_inserts=source_json.get("smart_inserts"); + source.style = source_json.get("style"); + source.font = source_json.get("font"); + source.cleanup_whitespace_characters = source_json.get("cleanup_whitespace_characters"); + source.show_whitespace_characters = source_json.get("show_whitespace_characters"); + source.format_style_on_save = source_json.get("format_style_on_save"); + source.format_style_on_save_if_style_file_found = source_json.get("format_style_on_save_if_style_file_found"); + source.smart_brackets = source_json.get("smart_brackets"); + source.smart_inserts = source_json.get("smart_inserts"); if(source.smart_inserts) - source.smart_brackets=true; + source.smart_brackets = true; source.show_map = source_json.get("show_map"); source.map_font_size = source_json.get("map_font_size"); source.show_git_diff = source_json.get("show_git_diff"); @@ -175,30 +175,30 @@ void Config::read(const boost::property_tree::ptree &cfg) { source.auto_reload_changed_files = source_json.get("auto_reload_changed_files"); source.clang_format_style = source_json.get("clang_format_style"); source.clang_usages_threads = static_cast(source_json.get("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("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(); + 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("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(); } } - window.theme_name=cfg.get("gtk_theme.name"); - window.theme_variant=cfg.get("gtk_theme.variant"); + window.theme_name = cfg.get("gtk_theme.name"); + window.theme_variant = cfg.get("gtk_theme.variant"); window.version = cfg.get("version"); - - project.default_build_path=cfg.get("project.default_build_path"); - project.debug_build_path=cfg.get("project.debug_build_path"); - project.cmake.command=cfg.get("project.cmake.command"); - project.cmake.compile_command=cfg.get("project.cmake.compile_command"); - project.meson.command=cfg.get("project.meson.command"); - project.meson.compile_command=cfg.get("project.meson.compile_command"); - project.save_on_compile_or_run=cfg.get("project.save_on_compile_or_run"); - project.clear_terminal_on_compile=cfg.get("project.clear_terminal_on_compile"); - project.ctags_command=cfg.get("project.ctags_command"); - project.python_command=cfg.get("project.python_command"); - - terminal.history_size=cfg.get("terminal.history_size"); - terminal.font=cfg.get("terminal.font"); + + project.default_build_path = cfg.get("project.default_build_path"); + project.debug_build_path = cfg.get("project.debug_build_path"); + project.cmake.command = cfg.get("project.cmake.command"); + project.cmake.compile_command = cfg.get("project.cmake.compile_command"); + project.meson.command = cfg.get("project.meson.command"); + project.meson.compile_command = cfg.get("project.meson.compile_command"); + project.save_on_compile_or_run = cfg.get("project.save_on_compile_or_run"); + project.clear_terminal_on_compile = cfg.get("project.clear_terminal_on_compile"); + project.ctags_command = cfg.get("project.ctags_command"); + project.python_command = cfg.get("project.python_command"); + + terminal.history_size = cfg.get("terminal.history_size"); + terminal.font = cfg.get("terminal.font"); } diff --git a/src/config.h b/src/config.h index 1c1000b..7307b7b 100644 --- a/src/config.h +++ b/src/config.h @@ -1,11 +1,11 @@ #pragma once -#include +#include "dispatcher.h" #include -#include +#include #include +#include #include #include -#include "dispatcher.h" class Config { public: @@ -13,20 +13,20 @@ public: public: std::unordered_map 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 { @@ -39,7 +39,7 @@ public: std::string command; std::string compile_command; }; - + std::string default_build_path; std::string debug_build_path; CMake cmake; @@ -49,7 +49,7 @@ public: std::string ctags_command; std::string python_command; }; - + class Source { public: class DocumentationSearch { @@ -57,27 +57,27 @@ public: std::string separator; std::unordered_map 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; @@ -87,39 +87,41 @@ public: 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 documentation_searches; }; + private: 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; 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=""); + 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 55b9fb4..9fda5fd 100644 --- a/src/ctags.cc +++ b/src/ctags.cc @@ -1,38 +1,38 @@ #include "ctags.h" #include "config.h" -#include "terminal.h" -#include "project_build.h" #include "filesystem.h" +#include "project_build.h" +#include "terminal.h" +#include #include -#include #include -#include +#include -std::pair > Ctags::get_result(const boost::filesystem::path &path) { - auto build=Project::Build::create(path); - auto run_path=build->project_path; +std::pair> 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); + 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); + 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(); + exclude += " --exclude=" + relative_debug_path.string(); } else { boost::system::error_code ec; if(boost::filesystem::is_directory(path, ec) || ec) - run_path=path; + run_path = path; else - run_path=path.parent_path(); + 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(); - auto command=Config::get().project.ctags_command+exclude+" --fields=ns --sort=foldcase -I \"override noexcept\" -f - -R *"; + auto stdout_stream = std::make_unique(); + 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)}; } @@ -41,166 +41,166 @@ Ctags::Location Ctags::get_location(const std::string &line, bool markup) { Location location; #ifdef _WIN32 - auto line_fixed=line; - if(!line_fixed.empty() && line_fixed.back()=='\r') + 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(R"(^([^\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(); + location.symbol = sm[1].str(); //fix location.symbol for operators - if(9='a' && chr<='z') || (chr>='A' && chr<='Z') || (chr>='0' && chr<='9') || chr=='_')) + 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(); + + location.file_path = sm[2].str(); + location.source = sm[4].str(); try { - location.line=std::stoul(sm[6])-1; + location.line = std::stoul(sm[6]) - 1; } - catch(const std::exception&) { - location.line=0; + catch(const std::exception &) { + location.line = 0; } - location.scope=sm[7].str(); + 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; - + 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(), ""); + 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(), ""); location.source.insert(pos, ""); - pos+=7+symbol.size(); + pos += 7 + symbol.size(); } } } else { - location.index=0; - location.source=location.symbol; + location.index = 0; + location.source = location.symbol; if(markup) - location.source=""+Glib::Markup::escape_text(location.source)+""; + location.source = "" + Glib::Markup::escape_text(location.source) + ""; } } 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 Ctags::get_type_parts(const std::string &type) { std::vector parts; - size_t text_start=-1; - for(size_t c=0;c='0' && chr<='9') || (chr>='a' && chr<='z') || (chr>='A' && chr<='Z') || chr=='_' || chr=='~') { - if(text_start==static_cast(-1)) - text_start=c; + 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(-1)) + text_start = c; } else { - if(text_start!=static_cast(-1)) { - parts.emplace_back(type.substr(text_start, c-text_start)); - text_start=-1; + if(text_start != static_cast(-1)) { + parts.emplace_back(type.substr(text_start, c - text_start)); + text_start = -1; } - if(chr=='*' || chr=='&') - parts.emplace_back(std::string()+chr); + if(chr == '*' || chr == '&') + parts.emplace_back(std::string() + chr); } } return parts; } std::vector Ctags::get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type) { - auto result=get_result(path); + auto result = get_result(path); result.second->seekg(0, std::ios::end); - if(result.second->tellg()==0) + if(result.second->tellg() == 0) return std::vector(); result.second->seekg(0, std::ios::beg); - + //insert name into type - size_t c=0; - size_t bracket_count=0; - for(;c') + else if(type[c] == '>') --bracket_count; - else if(bracket_count==0 && type[c]=='(') + else if(bracket_count == 0 && type[c] == '(') break; } - auto full_type=type; + auto full_type = type; full_type.insert(c, name); - - auto parts=get_type_parts(full_type); - + + auto parts = get_type_parts(full_type); + std::string line; - long best_score=LONG_MIN; + long best_score = LONG_MIN; std::vector best_locations; while(std::getline(*result.second, line)) { - if(line.size()>2048) + if(line.size() > 2048) continue; - auto location=Ctags::get_location(line, false); + auto location = Ctags::get_location(line, false); if(!location.scope.empty()) { - if(location.scope+"::"+location.symbol!=name) + if(location.scope + "::" + location.symbol != name) continue; } - else if(location.symbol!=name) + else if(location.symbol != name) continue; - - location.file_path=result.first/location.file_path; - - auto source_parts=get_type_parts(location.source); - + + 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;cbest_score) { - best_score=score; + + if(score > best_score) { + best_score = score; best_locations.clear(); best_locations.emplace_back(location); } - else if(score==best_score) + else if(score == best_score) best_locations.emplace_back(location); } - + return best_locations; } diff --git a/src/ctags.h b/src/ctags.h index ad56dca..fab226b 100644 --- a/src/ctags.h +++ b/src/ctags.h @@ -1,7 +1,7 @@ #pragma once -#include #include #include +#include #include class Ctags { @@ -16,12 +16,13 @@ public: std::string source; operator bool() const { return !file_path.empty(); } }; - - static std::pair > get_result(const boost::filesystem::path &path); - + + static std::pair> get_result(const boost::filesystem::path &path); + static Location get_location(const std::string &line, bool markup); - + static std::vector get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type); + private: static std::vector get_type_parts(const std::string &type); }; diff --git a/src/debug_lldb.cc b/src/debug_lldb.cc index 04a73e4..2469897 100644 --- a/src/debug_lldb.cc +++ b/src/debug_lldb.cc @@ -3,12 +3,12 @@ #ifdef __APPLE__ #include #endif -#include -#include -#include "terminal.h" +#include "config.h" #include "filesystem.h" #include "process.hpp" -#include "config.h" +#include "terminal.h" +#include +#include extern char **environ; @@ -16,7 +16,7 @@ void log(const char *msg, void *) { std::cout << "debugger log: " << msg << std::endl; } -Debug::LLDB::LLDB(): state(lldb::StateType::eStateInvalid), buffer_size(131072) { +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"); @@ -35,211 +35,211 @@ Debug::LLDB::LLDB(): state(lldb::StateType::eStateInvalid), buffer_size(131072) } } -std::tuple, std::string, std::vector > Debug::LLDB::parse_run_arguments(const std::string &command) { +std::tuple, std::string, std::vector> Debug::LLDB::parse_run_arguments(const std::string &command) { std::vector environment; std::string executable; std::vector 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); + + 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='a' && argument[c]<='z') || (argument[c]>='A' && argument[c]<='Z') || - (argument[c]>='0' && argument[c]<='9') || argument[c]=='_') + 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 > &breakpoints, - const std::vector &startup_commands, const std::string &remote_host) { + const std::vector> &breakpoints, + const std::vector &startup_commands, const std::string &remote_host) { if(!debugger) { lldb::SBDebugger::Initialize(); - debugger=std::make_unique(lldb::SBDebugger::Create(true, log, nullptr)); - listener=std::make_unique("juCi++ lldb listener"); + debugger = std::make_unique(lldb::SBDebugger::Create(true, log, nullptr)); + listener = std::make_unique("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 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); #ifdef _WIN32 if(remote_host.empty()) - executable+=".exe"; + executable += ".exe"; #endif - auto &arguments=std::get<2>(parsed_run_arguments); - - std::vector argv; + auto &arguments = std::get<2>(parsed_run_arguments); + + std::vector 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()); + + 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) + 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) { + 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) + 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::SBError error; if(!remote_host.empty()) { - auto connect_string="connect://"+remote_host; + auto connect_string = "connect://" + remote_host; process = std::make_unique(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) + 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) + 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 environment; + std::vector environment; environment.reserve(environment_from_arguments.size()); - for(auto &e: environment_from_arguments) + 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 environment; + std::vector environment; environment.reserve(environment_from_arguments.size()); - for(auto &e: environment_from_arguments) + for(auto &e : environment_from_arguments) environment.emplace_back(e.c_str()); - size_t environ_size=0; - while(environ[environ_size]!=nullptr) + size_t environ_size = 0; + while(environ[environ_size] != nullptr) ++environ_size; - for(size_t c=0;c(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) + 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) + for(auto &handler : on_start) handler(*process); - - for(auto &command: startup_commands) { + + 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]() { + + debug_thread = std::thread([this]() { lldb::SBEvent event; while(true) { std::unique_lock 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;cGetNumThreads();c++) { - auto thread=process->GetThreadAtIndex(c); - if(thread.GetStopReason()>=2) { + 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) + 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(); + + 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) + for(auto &handler : on_exit) handler(exit_status); lock.lock(); process.reset(); - this->state=lldb::StateType::eStateInvalid; + this->state = lldb::StateType::eStateInvalid; return; } } - if((event.GetType() & lldb::SBProcess::eBroadcastBitSTDOUT)>0) { + if((event.GetType() & lldb::SBProcess::eBroadcastBitSTDOUT) > 0) { char buffer[buffer_size]; size_t n; - while((n=process->GetSTDOUT(buffer, buffer_size))!=0) + 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) { + if((event.GetType() & lldb::SBProcess::eBroadcastBitSTDERR) > 0) { char buffer[buffer_size]; size_t n; - while((n=process->GetSTDERR(buffer, buffer_size))!=0) + while((n = process->GetSTDERR(buffer, buffer_size)) != 0) Terminal::get().async_print(std::string(buffer, n), true); } } @@ -251,45 +251,45 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat void Debug::LLDB::continue_debug() { std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateStopped) + if(state == lldb::StateType::eStateStopped) process->Continue(); } void Debug::LLDB::stop() { std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateRunning) { - auto error=process->Stop(); + if(state == lldb::StateType::eStateRunning) { + auto error = process->Stop(); if(error.Fail()) - Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true); + Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true); } } void Debug::LLDB::kill() { std::unique_lock lock(mutex); if(process) { - auto error=process->Kill(); + auto error = process->Kill(); if(error.Fail()) - Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true); + Terminal::get().async_print(std::string("Error (debug): ") + error.GetCString() + '\n', true); } } void Debug::LLDB::step_over() { std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateStopped) { + if(state == lldb::StateType::eStateStopped) { process->GetSelectedThread().StepOver(); } } void Debug::LLDB::step_into() { std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateStopped) { + if(state == lldb::StateType::eStateStopped) { process->GetSelectedThread().StepInto(); } } void Debug::LLDB::step_out() { std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateStopped) { + if(state == lldb::StateType::eStateStopped) { process->GetSelectedThread().StepOut(); } } @@ -297,15 +297,15 @@ void Debug::LLDB::step_out() { std::pair Debug::LLDB::run_command(const std::string &command) { std::pair command_return; std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateStopped || state==lldb::StateType::eStateRunning) { + 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(); + auto output = command_return_object.GetOutput(); if(output) - command_return.first=output; - auto error=command_return_object.GetError(); + command_return.first = output; + auto error = command_return_object.GetError(); if(error) - command_return.second=error; + command_return.second = error; } return command_return; } @@ -313,32 +313,32 @@ std::pair Debug::LLDB::run_command(const std::string & std::vector Debug::LLDB::get_backtrace() { std::vector backtrace; std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateStopped) { - auto thread=process->GetSelectedThread(); - for(uint32_t c_f=0;c_fGetSelectedThread(); + 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 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(); + + 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; + 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); } @@ -349,48 +349,48 @@ std::vector Debug::LLDB::get_backtrace() { std::vector Debug::LLDB::get_variables() { std::vector variables; std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateStopped) { - for(uint32_t c_t=0;c_tGetNumThreads();c_t++) { - auto thread=process->GetThreadAtIndex(c_t); - for(uint32_t c_f=0;c_fGetNumThreads(); 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); - + 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(); + 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(); + 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(); + 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(); + 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(); + 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); @@ -403,10 +403,11 @@ std::vector Debug::LLDB::get_variables() { void Debug::LLDB::select_frame(uint32_t frame_index, uint32_t thread_index_id) { std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateStopped) { - if(thread_index_id!=0) + if(state == lldb::StateType::eStateStopped) { + if(thread_index_id != 0) process->SetSelectedThreadByIndexID(thread_index_id); - process->GetSelectedThread().SetSelectedFrame(frame_index);; + process->GetSelectedThread().SetSelectedFrame(frame_index); + ; } } @@ -419,26 +420,26 @@ void Debug::LLDB::cancel() { 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 lock(mutex); - if(state==lldb::StateType::eStateStopped) { - auto frame=process->GetSelectedThread().GetSelectedFrame(); - - auto values=frame.GetVariables(true, true, true, false); + 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 lock(mutex); - if(state==lldb::StateType::eStateStopped) { - auto thread=process->GetSelectedThread(); - auto thread_return_value=thread.GetStopReturnValue(); + 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(); + 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)) { + 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_value = stream.GetData(); } } } @@ -484,43 +485,43 @@ std::string Debug::LLDB::get_return_value(const boost::filesystem::path &file_pa bool Debug::LLDB::is_invalid() { std::unique_lock lock(mutex); - return state==lldb::StateType::eStateInvalid; + return state == lldb::StateType::eStateInvalid; } bool Debug::LLDB::is_stopped() { std::unique_lock lock(mutex); - return state==lldb::StateType::eStateStopped; + return state == lldb::StateType::eStateStopped; } bool Debug::LLDB::is_running() { std::unique_lock lock(mutex); - return state==lldb::StateType::eStateRunning; + return state == lldb::StateType::eStateRunning; } void Debug::LLDB::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { std::unique_lock lock(mutex); - if(state==lldb::eStateStopped || state==lldb::eStateRunning) { + 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); + 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 lock(mutex); - if(state==lldb::eStateStopped || state==lldb::eStateRunning) { - auto target=process->GetTarget(); - for(int line_nr_try=line_nr;line_nr_try(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(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(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); + Terminal::get().async_print("Error (debug): Could not delete breakpoint at: " + file_path.string() + ":" + std::to_string(line_nr) + '\n', true); return; } } @@ -532,7 +533,7 @@ void Debug::LLDB::remove_breakpoint(const boost::filesystem::path &file_path, in void Debug::LLDB::write(const std::string &buffer) { std::unique_lock lock(mutex); - if(state==lldb::StateType::eStateRunning) { + 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 42560c3..6f36b25 100644 --- a/src/debug_lldb.h +++ b/src/debug_lldb.h @@ -2,8 +2,8 @@ #include #include #include -#include #include +#include #include namespace Debug { @@ -29,25 +29,27 @@ namespace Debug { int line_nr; int line_index; }; + private: LLDB(); + public: static LLDB &get() { static LLDB singleton; return singleton; } - + std::list> on_start; /// The handlers are not run in the main loop. std::list> on_exit; /// The handlers are not run in the main loop. std::list> on_event; - + std::mutex mutex; - void start(const std::string &command, const boost::filesystem::path &path="", - const std::vector > &breakpoints={}, - const std::vector &startup_commands={}, const std::string &remote_host=""); + void start(const std::string &command, const boost::filesystem::path &path = "", + const std::vector> &breakpoints = {}, + const std::vector &startup_commands = {}, const std::string &remote_host = ""); void continue_debug(); //can't use continue as function name void stop(); void kill(); @@ -57,32 +59,32 @@ namespace Debug { std::pair run_command(const std::string &command); std::vector get_backtrace(); std::vector get_variables(); - void select_frame(uint32_t frame_index, uint32_t thread_index_id=0); - + 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::string, std::vector> parse_run_arguments(const std::string &command); - + std::unique_ptr debugger; std::unique_ptr listener; std::unique_ptr process; std::thread debug_thread; - + lldb::StateType state; - + size_t buffer_size; }; -} +} // namespace Debug diff --git a/src/dialogs.cc b/src/dialogs.cc index ab5bc55..9eb7ba4 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -1,27 +1,27 @@ #include "dialogs.h" #include -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::cast_static(gio_application); +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::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; + 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)); + + 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); } @@ -31,21 +31,23 @@ bool Dialog::Message::on_delete_event(GdkEventAny *event) { } std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::string &title, - const std::vector> &buttons, - Gtk::FileChooserAction action) { + const std::vector> &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) {} + 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) + 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); @@ -55,25 +57,25 @@ std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::s #else 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::cast_static(gio_application); + + auto g_application = g_application_get_default(); + auto gio_application = Glib::wrap(g_application, true); + auto application = Glib::RefPtr::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(dialog.gobj()), path.string().c_str()); + + if(title == "Save File As") + gtk_file_chooser_set_filename(reinterpret_cast(dialog.gobj()), path.string().c_str()); else if(!path.empty()) - gtk_file_chooser_set_current_folder(reinterpret_cast(dialog.gobj()), path.string().c_str()); + gtk_file_chooser_set_current_folder(reinterpret_cast(dialog.gobj()), path.string().c_str()); else { boost::system::error_code ec; - auto current_path=boost::filesystem::current_path(ec); + auto current_path = boost::filesystem::current_path(ec); if(!ec) - gtk_file_chooser_set_current_folder(reinterpret_cast(dialog.gobj()), current_path.string().c_str()); + gtk_file_chooser_set_current_folder(reinterpret_cast(dialog.gobj()), current_path.string().c_str()); } - - for (auto &button : buttons) + + 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 e1deeb5..d746826 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -1,8 +1,8 @@ #pragma once -#include #include -#include #include +#include +#include class Dialog { public: @@ -11,16 +11,17 @@ public: static std::string new_file(const boost::filesystem::path &path); static std::string new_folder(const boost::filesystem::path &path); static std::string save_file_as(const boost::filesystem::path &path); - + 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> &buttons, - Gtk::FileChooserAction gtk_options); + const std::vector> &buttons, + Gtk::FileChooserAction gtk_options); }; diff --git a/src/dialogs_unix.cc b/src/dialogs_unix.cc index 2512ce8..c797594 100644 --- a/src/dialogs_unix.cc +++ b/src/dialogs_unix.cc @@ -2,31 +2,30 @@ 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); + {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); + {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); + {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); + {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); + {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 72d1869..092acc1 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,136 +1,136 @@ #include "dialogs.h" -#include "singletons.h" #include "juci.h" +#include "singletons.h" #undef NTDDI_VERSION #define NTDDI_VERSION NTDDI_VISTA #undef _WIN32_WINNT #define _WIN32_WINNT _WIN32_WINNT_VISTA -#include #include #include +#include -#include //TODO: remove +#include //TODO: remove using namespace std; //TODO: remove class Win32Dialog { public: - Win32Dialog() {}; - + Win32Dialog(){}; + ~Win32Dialog() { - if(dialog!=nullptr) + if(dialog != nullptr) dialog->Release(); } - + /** Returns the selected item's path as a string */ - std::string open(const std::wstring &title, unsigned option=0) { + 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) { + + 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 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(); + 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) + if(dialog->SetFileTypes(extensions.size(), extensions.data()) != S_OK) return ""; - + return show(); } private: - IFileDialog *dialog=nullptr; + IFileDialog *dialog = nullptr; DWORD options; - + bool init(CLSID type) { - if(CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog))!=S_OK) + if(CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog)) != S_OK) return false; - if(dialog->GetOptions(&options)!=S_OK) + 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) + 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) + 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) + 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::cast_static(gio_application); - - auto current_path=application->window->notebook.get_current_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::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); + 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 + + 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) + if(SHCreateItemFromParsingName(path.c_str(), nullptr, IID_PPV_ARGS(&folder)) != S_OK) return false; - if(dialog->SetFolder(folder)!=S_OK) + if(dialog->SetFolder(folder) != S_OK) return false; folder->Release(); return true; } - + std::string show() { - if(dialog->Show(nullptr)!=S_OK) + if(dialog->Show(nullptr) != S_OK) return ""; IShellItem *result = nullptr; - if(dialog->GetResult(&result)!=S_OK) + if(dialog->GetResult(&result) != S_OK) return ""; - LPWSTR file_path = nullptr; - auto hresult=result->GetDisplayName(SIGDN_FILESYSPATH, &file_path); + LPWSTR file_path = nullptr; + auto hresult = result->GetDisplayName(SIGDN_FILESYSPATH, &file_path); result->Release(); - if(hresult!=S_OK) + 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()); @@ -150,12 +150,12 @@ std::string Dialog::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); + {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) { diff --git a/src/directories.cc b/src/directories.cc index bbc07b5..7bd0979 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -1,38 +1,38 @@ #include "directories.h" -#include +#include "entrybox.h" +#include "filesystem.h" +#include "notebook.h" #include "source.h" #include "terminal.h" -#include "notebook.h" -#include "filesystem.h" -#include "entrybox.h" +#include 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) + 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); + auto it = get_iter(path); if(it) { - auto prev_path=path; + auto prev_path = path; prev_path.up(); - it=get_iter(prev_path); + it = get_iter(prev_path); if(it) return it->get_value(directories.column_record.path); } else { - auto prev_path=path; + auto prev_path = path; prev_path.up(); - if(prev_path.size()==1) + if(prev_path.size() == 1) return directories.path; else { prev_path.up(); - it=get_iter(prev_path); + it = get_iter(prev_path); if(it) return it->get_value(directories.column_record.path); } @@ -40,122 +40,122 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat } return boost::filesystem::path(); }; - - auto it=directories.get_selection()->get_selected(); + + auto it = directories.get_selection()->get_selected(); if(it) { - auto source_path=it->get_value(directories.column_record.path); + 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) + + 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); + 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); - + 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); + Terminal::get().print("Error: could not move file: " + ec.message() + '\n', true); return false; } - - for(size_t c=0;cfile_path, source_path)) { - auto file_it=view->file_path.begin(); - for(auto source_it=source_path.begin();source_it!=source_path.end();source_it++) + 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; + 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) { + 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); } - + EntryBox::get().hide(); return false; } -bool Directories::TreeStore::drag_data_delete_vfunc (const Gtk::TreeModel::Path &path) { +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(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(renderer)) - renderer_text->property_markup()=iter->get_value(column_record.markup); + + auto renderer = dynamic_cast(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(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){ + + 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))) + 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)=="") + + 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){ + 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; + 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(); @@ -163,41 +163,41 @@ Directories::Directories() : Gtk::ListViewText(1) { on_save_file(target_path); } else { - Terminal::get().print("Error: could not create "+target_path.string()+'\n', true); + 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); + 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(); + auto entry_it = EntryBox::get().entries.begin(); entry_it->set_placeholder_text("Filename"); - EntryBox::get().buttons.emplace_back("Create New File", [entry_it](){ + 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; + 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); @@ -206,154 +206,154 @@ Directories::Directories() : Gtk::ListViewText(1) { select(target_path); } else { - Terminal::get().print("Error: could not create "+target_path.string()+": "+ec.message(), true); + 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); + 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(); + auto entry_it = EntryBox::get().entries.begin(); entry_it->set_placeholder_text("Folder name"); - EntryBox::get().buttons.emplace_back("Create New Folder", [entry_it](){ + 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; - + 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); + 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); + 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;cfile_path, source_path)) { - auto file_it=view->file_path.begin(); - for(auto source_it=source_path.begin();source_it!=source_path.end();source_it++) + 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; + 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) { + 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); + 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"); + 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(); + + auto entry_it = EntryBox::get().entries.begin(); entry_it->set_placeholder_text("Filename"); - - EntryBox::get().buttons.emplace_back("Rename file", [entry_it](){ + + EntryBox::get().buttons.emplace_back("Rename file", [entry_it]() { entry_it->activate(); }); - + EntryBox::get().show(); - - auto end_pos=Glib::ustring(menu_popup_row_path.filename().string()).rfind('.'); - if(end_pos!=Glib::ustring::npos) + + auto end_pos = Glib::ustring(menu_popup_row_path.filename().string()).rfind('.'); + if(end_pos != Glib::ustring::npos) entry_it->select_region(0, end_pos); }); 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(get_toplevel()), "Delete!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO); + Gtk::MessageDialog dialog(*static_cast(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()+"?"); + 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); - + 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); + Terminal::get().print("Error: could not delete " + menu_popup_row_path.string() + ": " + ec.message() + "\n", true); else { update(); - - for(size_t c=0;cfile_path, menu_popup_row_path)) view->get_buffer()->set_modified(); } - else if(view->file_path==menu_popup_row_path) + 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") { + 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; + 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; @@ -370,40 +370,40 @@ 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); - + + 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) { + auto title = path.filename().string(); + size_t pos = 0; + while((pos = title.find('_', pos)) != std::string::npos) { title.replace(pos, 1, "__"); - pos+=2; + pos += 2; } get_column(0)->set_title(title); - for(auto &directory: directories) { + 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 > saved_directories; - for(auto &directory: directories) + std::vector> saved_directories; + for(auto &directory : directories) saved_directories.emplace_back(directory.first, directory.second.row); - for(auto &directory: saved_directories) + for(auto &directory : saved_directories) add_or_update_path(directory.first, directory.second, false); } void Directories::on_save_file(const boost::filesystem::path &file_path) { - auto it=directories.find(file_path.parent_path().string()); - if(it!=directories.end()) { + 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); @@ -411,32 +411,32 @@ void Directories::on_save_file(const boost::filesystem::path &file_path) { } void Directories::select(const boost::filesystem::path &select_path) { - if(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(); + auto iter = get_selection()->get_selected(); if(iter) { - if(iter->get_value(column_record.path)==select_path) + if(iter->get_value(column_record.path) == select_path) return; } - + std::list paths; boost::filesystem::path parent_path; if(boost::filesystem::is_directory(select_path)) - parent_path=select_path; + parent_path = select_path; else - parent_path=select_path.parent_path(); - + parent_path = select_path.parent_path(); + //check if select_path is already expanded - if(directories.find(parent_path.string())!=directories.end()) { + 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); + 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; @@ -445,28 +445,28 @@ 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(); + 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) { + 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); + 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; @@ -475,18 +475,18 @@ void Directories::select(const boost::filesystem::path &select_path) { }); } -bool Directories::on_button_press_event(GdkEventButton* event) { - if(event->type==GDK_BUTTON_PRESS && event->button==GDK_BUTTON_SECONDARY) { +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(event->x), static_cast(event->y), path)) { - menu_popup_row_path=get_model()->get_iter(path)->get_value(column_record.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(); + auto parent = get_model()->get_iter(path)->parent(); if(parent) - menu_popup_row_path=parent->get_value(column_record.path); + menu_popup_row_path = parent->get_value(column_record.path); else { - menu_popup_row_path=this->path; + menu_popup_row_path = this->path; menu_root.popup(event->button, event->time); return true; } @@ -495,88 +495,89 @@ bool Directories::on_button_press_event(GdkEventButton* event) { return true; } else if(!this->path.empty()) { - menu_popup_row_path=this->path; + menu_popup_row_path = this->path; menu_root.popup(event->button, event->time); return true; } } - + 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()); + auto path_it = directories.find(dir_path.string()); if(!boost::filesystem::exists(dir_path)) { - if(path_it!=directories.end()) + 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 >(dir_path, row); - auto connection=std::make_shared(); - + + 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>(dir_path, row); + auto connection = std::make_shared(); + std::shared_ptr repository; try { - repository=Git::get_repository(dir_path); + repository = Git::get_repository(dir_path); } - catch(const std::exception &) {} - - monitor->signal_changed().connect([this, connection, path_and_row, repository] (const Glib::RefPtr &file, - const Glib::RefPtr&, - Gio::FileMonitorEvent monitor_event) { - if(monitor_event!=Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) { + catch(const std::exception &) { + } + + monitor->signal_changed().connect([this, connection, path_and_row, repository](const Glib::RefPtr &file, + const Glib::RefPtr &, + 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()) + *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 repository_connection(new sigc::connection(), [](sigc::connection *connection) { connection->disconnect(); delete connection; }); - + if(repository) { - auto connection=std::make_shared(); - *repository_connection=repository->monitor->signal_changed().connect([this, connection, path_and_row](const Glib::RefPtr &file, - const Glib::RefPtr&, - Gio::FileMonitorEvent monitor_event) { - if(monitor_event!=Gio::FileMonitorEvent::FILE_MONITOR_EVENT_CHANGES_DONE_HINT) { + auto connection = std::make_shared(); + *repository_connection = repository->monitor->signal_changed().connect([this, connection, path_and_row](const Glib::RefPtr &file, + const Glib::RefPtr &, + 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()) + *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()); + + Gtk::TreeNodeChildren children(row ? row.children() : tree_store->children()); if(children) { - if(children.begin()->get_value(column_record.path)=="") + if(children.begin()->get_value(column_record.path) == "") tree_store->erase(children.begin()); } std::unordered_set 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; + 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) { + for(auto &child : children) { + if(child->get_value(column_record.name) == filename) { not_deleted.emplace(filename); - already_added=true; + already_added = true; break; } } @@ -587,59 +588,59 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co 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()); + 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()); + 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); + 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); + 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()) + 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();) { + 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); + it = directories.erase(it); else it++; } - + if(children) { while(children) { tree_store->erase(children.begin()); } - auto child=tree_store->append(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); @@ -647,82 +648,82 @@ void Directories::remove_path(const boost::filesystem::path &dir_path) { } void Directories::colorize_path(boost::filesystem::path dir_path_, bool include_parent_paths) { - auto dir_path=std::make_shared(std::move(dir_path_)); - auto it=directories.find(dir_path->string()); - if(it==directories.end()) + auto dir_path = std::make_shared(std::move(dir_path_)); + auto it = directories.find(dir_path->string()); + if(it == directories.end()) return; - - if(it!=directories.end() && it->second.repository) { - auto repository=it->second.repository; + + 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(); + status = repository->get_status(); } catch(const std::exception &e) { - Terminal::get().async_print(std::string("Error (git): ")+e.what()+'\n', true); + 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()) + + 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); + + 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())); + 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())); - + 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()); + 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); + + 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; + 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; - + 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, ""+name+""); - - auto type=child.get_value(column_record.type); - if(type==PathType::UNKNOWN) - child.set_value(column_record.markup, ""+child.get_value(column_record.markup)+""); + 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, "" + name + ""); + + auto type = child.get_value(column_record.type); + if(type == PathType::UNKNOWN) + child.set_value(column_record.markup, "" + child.get_value(column_record.markup) + ""); } - + if(!include_parent_paths) break; - - auto path=boost::filesystem::path(it->first); - if(boost::filesystem::exists(path/".git")) + + auto path = boost::filesystem::path(it->first); + if(boost::filesystem::exists(path / ".git")) break; - if(path==path.root_directory()) + 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()); + 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 73c2861..e6fae8f 100644 --- a/src/directories.h +++ b/src/directories.h @@ -1,15 +1,15 @@ #pragma once +#include "boost/filesystem.hpp" +#include "dispatcher.h" +#include "git.h" +#include #include -#include +#include #include -#include "boost/filesystem.hpp" #include -#include -#include #include #include -#include "git.h" -#include "dispatcher.h" +#include class Directories : public Gtk::ListViewText { class DirectoryData { @@ -19,17 +19,17 @@ class Directories : public Gtk::ListViewText { std::shared_ptr repository; std::shared_ptr connection; }; - - enum class PathType {KNOWN, UNKNOWN}; - + + enum class PathType { KNOWN, UNKNOWN }; + class TreeStore : public Gtk::TreeStore { protected: - TreeStore()=default; - + 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; - + bool drag_data_delete_vfunc(const Gtk::TreeModel::Path &path) override; + public: class ColumnRecord : public Gtk::TreeModel::ColumnRecord { public: @@ -46,40 +46,41 @@ class Directories : public Gtk::ListViewText { Gtk::TreeModelColumn path; Gtk::TreeModelColumn type; }; - - static Glib::RefPtr create() {return Glib::RefPtr(new TreeStore());} + + static Glib::RefPtr create() { return Glib::RefPtr(new TreeStore()); } }; Directories(); + public: static Directories &get() { static Directories singleton; return singleton; } ~Directories() override; - - void open(const boost::filesystem::path &dir_path=""); + + 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 tree_store; TreeStore::ColumnRecord column_record; - + std::unordered_map directories; - + Dispatcher dispatcher; - + Gtk::Menu menu; Gtk::MenuItem menu_item_new_file; Gtk::MenuItem menu_item_new_folder; diff --git a/src/dispatcher.cc b/src/dispatcher.cc index 5ad2d60..17f99c0 100644 --- a/src/dispatcher.cc +++ b/src/dispatcher.cc @@ -2,21 +2,21 @@ #include Dispatcher::Dispatcher() { - connection=dispatcher.connect([this] { + connection = dispatcher.connect([this] { std::vector>::iterator> its; { std::unique_lock lock(functions_mutex); if(functions.empty()) return; its.reserve(functions.size()); - for(auto it=functions.begin();it!=functions.end();++it) + for(auto it = functions.begin(); it != functions.end(); ++it) its.emplace_back(it); } - for(auto &it: its) + for(auto &it : its) (*it)(); { std::unique_lock lock(functions_mutex); - for(auto &it: its) + for(auto &it : its) functions.erase(it); } }); diff --git a/src/dispatcher.h b/src/dispatcher.h index 8476628..cdcc7cd 100644 --- a/src/dispatcher.h +++ b/src/dispatcher.h @@ -1,8 +1,8 @@ #pragma once -#include -#include #include +#include #include +#include class Dispatcher { private: @@ -10,11 +10,12 @@ private: std::mutex functions_mutex; Glib::Dispatcher dispatcher; sigc::connection connection; + public: Dispatcher(); ~Dispatcher(); - - template + + template void post(T &&function) { { std::unique_lock lock(functions_mutex); @@ -22,6 +23,6 @@ public: } dispatcher(); } - + void disconnect(); }; diff --git a/src/documentation_cppreference.cc b/src/documentation_cppreference.cc index fe132ea..5873ad4 100644 --- a/src/documentation_cppreference.cc +++ b/src/documentation_cppreference.cc @@ -12173,34 +12173,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 map; }; - + static SymbolToUrl symbol_to_url(symbol_urls); - auto it=symbol_to_url.map.find(symbol); - if(it==symbol_to_url.map.end()) + 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; + return "http://en.cppreference.com/w/" + it->second; } diff --git a/src/documentation_cppreference.h b/src/documentation_cppreference.h index 5c0bd0c..f890b40 100644 --- a/src/documentation_cppreference.h +++ b/src/documentation_cppreference.h @@ -6,4 +6,4 @@ namespace Documentation { public: static std::string get_url(const std::string &symbol) noexcept; }; -} +} // namespace Documentation diff --git a/src/entrybox.cc b/src/entrybox.cc index f29c5e0..abe6800 100644 --- a/src/entrybox.cc +++ b/src/entrybox.cc @@ -1,37 +1,37 @@ #include "entrybox.h" -std::unordered_map > EntryBox::entry_histories; +std::unordered_map> EntryBox::entry_histories; -EntryBox::Entry::Entry(const std::string& content, std::function on_activate_, unsigned width_chars) : Gtk::Entry(), on_activate(std::move(on_activate_)) { +EntryBox::Entry::Entry(const std::string &content, std::function on_activate_, unsigned width_chars) : Gtk::Entry(), on_activate(std::move(on_activate_)) { set_max_length(0); set_width_chars(width_chars); set_text(content); - selected_history=0; - signal_activate().connect([this](){ + 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)) + 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; + 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) { + 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; + 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) + 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); @@ -41,25 +41,25 @@ EntryBox::Entry::Entry(const std::string& content, std::function on_activate_) : Gtk::Button(label), on_activate(std::move(on_activate_)) { +EntryBox::Button::Button(const std::string &label, std::function on_activate_) : Gtk::Button(label), on_activate(std::move(on_activate_)) { set_focus_on_click(false); - signal_clicked().connect([this](){ + signal_clicked().connect([this]() { if(this->on_activate) this->on_activate(); }); } -EntryBox::ToggleButton::ToggleButton(const std::string& label, std::function on_activate_) : Gtk::ToggleButton(label), on_activate(std::move(on_activate_)) { +EntryBox::ToggleButton::ToggleButton(const std::string &label, std::function on_activate_) : Gtk::ToggleButton(label), on_activate(std::move(on_activate_)) { set_focus_on_click(false); - signal_clicked().connect([this](){ + signal_clicked().connect([this]() { if(this->on_activate) this->on_activate(); }); } -EntryBox::Label::Label(std::function update_) : Gtk::Label(), update(std::move(update_)) { - if(this->update) - this->update(-1, ""); +EntryBox::Label::Label(std::function update_) : Gtk::Label(), update(std::move(update_)) { + if(this->update) + this->update(-1, ""); } EntryBox::EntryBox() : Gtk::Box(Gtk::ORIENTATION_VERTICAL), upper_box(Gtk::ORIENTATION_HORIZONTAL), lower_box(Gtk::ORIENTATION_HORIZONTAL) { @@ -77,20 +77,20 @@ void EntryBox::clear() { } void EntryBox::show() { - std::vector focus_chain; - for(auto& entry: entries) { + std::vector focus_chain; + for(auto &entry : entries) { lower_box.pack_start(entry, Gtk::PACK_SHRINK); focus_chain.emplace_back(&entry); } - for(auto& button: buttons) + for(auto &button : buttons) lower_box.pack_start(button, Gtk::PACK_SHRINK); - for(auto& toggle_button: toggle_buttons) + for(auto &toggle_button : toggle_buttons) lower_box.pack_start(toggle_button, Gtk::PACK_SHRINK); - for(auto& label: labels) + 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) { + 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 7781e5c..ab41449 100644 --- a/src/entrybox.h +++ b/src/entrybox.h @@ -1,54 +1,56 @@ #pragma once -#include -#include #include "gtkmm.h" -#include +#include +#include #include +#include #include class EntryBox : public Gtk::Box { public: class Entry : public Gtk::Entry { public: - Entry(const std::string& content="", std::function on_activate_=nullptr, unsigned width_chars=-1); - std::function on_activate; + Entry(const std::string &content = "", std::function on_activate_ = nullptr, unsigned width_chars = -1); + std::function on_activate; + private: size_t selected_history; }; class Button : public Gtk::Button { public: - Button(const std::string& label, std::function on_activate_=nullptr); + Button(const std::string &label, std::function on_activate_ = nullptr); std::function on_activate; }; class ToggleButton : public Gtk::ToggleButton { public: - ToggleButton(const std::string& label, std::function on_activate_=nullptr); + ToggleButton(const std::string &label, std::function on_activate_ = nullptr); std::function on_activate; }; class Label : public Gtk::Label { public: - Label(std::function update_=nullptr); - std::function update; + Label(std::function update_ = nullptr); + std::function update; }; - + private: EntryBox(); + public: static EntryBox &get() { static EntryBox singleton; return singleton; } - + Gtk::Box upper_box; Gtk::Box lower_box; void clear(); - void hide() {clear();} + void hide() { clear(); } void show(); std::list entries; std::list