From b5e5219a1c827fc257f6d7d3c03dd200e647d198 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 16 Apr 2020 12:25:22 +0200 Subject: [PATCH] Cleanup of Ctags and Grep classes --- src/ctags.cc | 48 ++++++++++++------------- src/ctags.h | 10 ++++-- src/grep.cc | 21 ++++++----- src/grep.h | 10 ++++-- src/project.cc | 17 ++++----- src/source_generic.cc | 13 +++---- src/window.cc | 20 +++++------ tests/ctags_grep_test.cc | 78 ++++++++++++++++++++-------------------- 8 files changed, 110 insertions(+), 107 deletions(-) diff --git a/src/ctags.cc b/src/ctags.cc index 5a55fe4..6d89cb5 100644 --- a/src/ctags.cc +++ b/src/ctags.cc @@ -4,12 +4,9 @@ #include "project_build.h" #include "terminal.h" #include -#include -#include #include -std::pair> Ctags::get_result(const boost::filesystem::path &path, bool enable_scope, bool enable_kind) { - boost::filesystem::path run_path; +Ctags::Ctags(const boost::filesystem::path &path, bool enable_scope, bool enable_kind) : enable_scope(enable_scope), enable_kind(enable_kind) { std::string fields(" --fields=n"); if(enable_scope) fields += 's'; @@ -21,27 +18,32 @@ std::pair> Ctags::ge auto build = Project::Build::create(path); std::string exclude = " --exclude=node_modules"; if(!build->project_path.empty()) { - run_path = build->project_path; - exclude += " --exclude=" + filesystem::escape_argument(filesystem::get_relative_path(build->get_default_path(), run_path).string()); - exclude += " --exclude=" + filesystem::escape_argument(filesystem::get_relative_path(build->get_debug_path(), run_path).string()); + project_path = build->project_path; + exclude += " --exclude=" + filesystem::escape_argument(filesystem::get_relative_path(build->get_default_path(), project_path).string()); + exclude += " --exclude=" + filesystem::escape_argument(filesystem::get_relative_path(build->get_debug_path(), project_path).string()); } else - run_path = path; + project_path = path; command = Config::get().project.ctags_command + exclude + fields + " --sort=foldcase -I \"override noexcept\" -f - -R *"; } else { - run_path = path.parent_path(); + project_path = path.parent_path(); command = Config::get().project.ctags_command + fields + " --sort=foldcase -I \"override noexcept\" -f - " + path.string(); } 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(); - Terminal::get().process(stdin_stream, *stdout_stream, command, run_path); - return {run_path, std::move(stdout_stream)}; + Terminal::get().process(stdin_stream, output, command, project_path); } -Ctags::Location Ctags::get_location(const std::string &line_, bool add_markup, bool scope_enabled, bool kind_enabled) { +Ctags::operator bool() { + output.seekg(0, std::ios::end); + if(output.tellg() == 0) + return false; + output.seekg(0, std::ios::beg); + return true; +} + +Ctags::Location Ctags::get_location(const std::string &line_, bool add_markup) const { Location location; #ifdef _WIN32 @@ -105,7 +107,7 @@ Ctags::Location Ctags::get_location(const std::string &line_, bool add_markup, b } size_t line_start; - if(kind_enabled) { + if(enable_kind) { auto kind_start = source_end + 4; if(kind_start >= line.size()) { std::cerr << "Warning (ctags): could not parse line: " << line << std::endl; @@ -135,7 +137,7 @@ Ctags::Location Ctags::get_location(const std::string &line_, bool add_markup, b location.line = 0; } - if(scope_enabled && line_end != std::string::npos && line_end + 1 < line.size()) { + if(enable_scope && line_end != std::string::npos && line_end + 1 < line.size()) { auto scope_start = line.find(':', line_end + 1); if(scope_start != std::string::npos && scope_start + 1 < line.size()) location.scope = line.substr(scope_start + 1); @@ -188,11 +190,9 @@ std::vector Ctags::get_type_parts(const std::string &type) { } std::vector Ctags::get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type) { - auto result = get_result(path, true); - result.second->seekg(0, std::ios::end); - if(result.second->tellg() == 0) - return std::vector(); - result.second->seekg(0, std::ios::beg); + Ctags ctags(path, true); + if(!ctags) + return {}; //insert name into type size_t c = 0; @@ -213,10 +213,10 @@ std::vector Ctags::get_locations(const boost::filesystem::path std::string line; long best_score = LONG_MIN; std::vector best_locations; - while(std::getline(*result.second, line)) { + while(std::getline(ctags.output, line)) { if(line.size() > 2048) continue; - auto location = Ctags::get_location(line, false, true); + auto location = ctags.get_location(line); if(!location.scope.empty()) { if(location.scope + "::" + location.symbol != name) continue; @@ -224,7 +224,7 @@ std::vector Ctags::get_locations(const boost::filesystem::path else if(location.symbol != name) continue; - location.file_path = result.first / location.file_path; + location.file_path = ctags.project_path / location.file_path; auto source_parts = get_type_parts(location.source); diff --git a/src/ctags.h b/src/ctags.h index 3f08b8d..df55b38 100644 --- a/src/ctags.h +++ b/src/ctags.h @@ -18,12 +18,18 @@ public: operator bool() const { return !file_path.empty(); } }; - static std::pair> get_result(const boost::filesystem::path &path, bool enable_scope = false, bool enable_kind = false); + Ctags(const boost::filesystem::path &path, bool enable_scope = false, bool enable_kind = false); - static Location get_location(const std::string &line, bool add_markup, bool scope_enabled = false, bool kind_enabled = false); + operator bool(); + + Location get_location(const std::string &line, bool add_markup = false) const; + + boost::filesystem::path project_path; + std::stringstream output; static std::vector get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type); private: + bool enable_scope, enable_kind; static std::vector get_type_parts(const std::string &type); }; diff --git a/src/grep.cc b/src/grep.cc index 2a91a41..c8cf97a 100644 --- a/src/grep.cc +++ b/src/grep.cc @@ -4,17 +4,16 @@ #include "project_build.h" #include "terminal.h" -std::pair> Grep::get_result(const boost::filesystem::path &path, const std::string &pattern, bool case_sensitive, bool extended_regex) { - boost::filesystem::path run_path; +Grep::Grep(const boost::filesystem::path &path, const std::string &pattern, bool case_sensitive, bool extended_regex) { auto build = Project::Build::create(path); std::string exclude = "--exclude-dir=node_modules"; if(!build->project_path.empty()) { - run_path = build->project_path; + project_path = build->project_path; exclude += " --exclude-dir=" + filesystem::escape_argument(filesystem::get_relative_path(build->get_default_path(), build->project_path).string()); exclude += " --exclude-dir=" + filesystem::escape_argument(filesystem::get_relative_path(build->get_debug_path(), build->project_path).string()); } else - run_path = path; + project_path = path; std::string flags; if(!case_sensitive) @@ -34,12 +33,18 @@ std::pair> Grep::get 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(); - Terminal::get().process(stdin_stream, *stdout_stream, command, run_path); - return {run_path, std::move(stdout_stream)}; + Terminal::get().process(stdin_stream, output, command, project_path); } -Grep::Location Grep::get_location(std::string line, bool color_codes_to_markup, bool include_offset, const std::string &only_for_file) { +Grep::operator bool() { + output.seekg(0, std::ios::end); + if(output.tellg() == 0) + return false; + output.seekg(0, std::ios::beg); + return true; +} + +Grep::Location Grep::get_location(std::string line, bool color_codes_to_markup, bool include_offset, const std::string &only_for_file) const { std::vector> positions; size_t file_end = std::string::npos, line_end = std::string::npos; if(color_codes_to_markup) { diff --git a/src/grep.h b/src/grep.h index 93495b5..416f720 100644 --- a/src/grep.h +++ b/src/grep.h @@ -1,5 +1,6 @@ #pragma once #include +#include class Grep { public: @@ -12,7 +13,12 @@ public: operator bool() const { return !file_path.empty(); } }; - static std::pair> get_result(const boost::filesystem::path &path, const std::string &pattern, bool case_sensitive, bool extended_regex); + Grep(const boost::filesystem::path &path, const std::string &pattern, bool case_sensitive, bool extended_regex); - static Location get_location(std::string line, bool color_codes_to_markup, bool include_offset, const std::string &only_for_file = {}); + operator bool(); + + Location get_location(std::string line, bool color_codes_to_markup, bool include_offset, const std::string &only_for_file = {}) const; + + boost::filesystem::path project_path; + std::stringstream output; }; \ No newline at end of file diff --git a/src/project.cc b/src/project.cc index 2e01e8d..7dde15c 100644 --- a/src/project.cc +++ b/src/project.cc @@ -219,16 +219,11 @@ void Project::Base::recreate_build() { } void Project::Base::show_symbols() { - auto pair = Ctags::get_result(get_preferably_view_folder()); - - auto path = std::move(pair.first); - auto stream = std::move(pair.second); - stream->seekg(0, std::ios::end); - if(stream->tellg() == 0) { + Ctags ctags(get_preferably_view_folder()); + if(!ctags) { Info::get().print("No symbols found in current project"); return; } - stream->seekg(0, std::ios::beg); auto view = Notebook::get().get_current_view(); if(view) @@ -239,8 +234,8 @@ void Project::Base::show_symbols() { std::vector rows; std::string line; - while(std::getline(*stream, line)) { - auto location = Ctags::get_location(line, true); + while(std::getline(ctags.output, line)) { + auto location = ctags.get_location(line, true); std::string row = location.file_path.string() + ":" + std::to_string(location.line + 1) + ": " + location.source; rows.emplace_back(Source::Offset(location.line, location.index, location.file_path)); @@ -249,11 +244,11 @@ void Project::Base::show_symbols() { if(rows.size() == 0) return; - SelectionDialog::get()->on_select = [rows = std::move(rows), path = std::move(path)](unsigned int index, const std::string &text, bool hide_window) { + SelectionDialog::get()->on_select = [rows = std::move(rows), project_path = std::move(ctags.project_path)](unsigned int index, const std::string &text, bool hide_window) { if(index >= rows.size()) return; auto offset = rows[index]; - auto full_path = path / offset.file_path; + auto full_path = project_path / offset.file_path; boost::system::error_code ec; if(!boost::filesystem::is_regular_file(full_path, ec)) return; diff --git a/src/source_generic.cc b/src/source_generic.cc index c427656..59220cf 100644 --- a/src/source_generic.cc +++ b/src/source_generic.cc @@ -82,22 +82,17 @@ Source::GenericView::GenericView(const boost::filesystem::path &file_path, const else file_path = this->file_path; - auto pair = Ctags::get_result(file_path, false, true); + Ctags ctags(file_path, false, true); if(use_tmp_file) boost::filesystem::remove_all(file_path.parent_path(), ec); - auto path = std::move(pair.first); - auto stream = std::move(pair.second); - stream->seekg(0, std::ios::end); - - if(stream->tellg() == 0) { + if(!ctags) { Info::get().print("No methods found in current buffer"); return methods; } - stream->seekg(0, std::ios::beg); std::string line; - while(std::getline(*stream, line)) { - auto location = Ctags::get_location(line, true, false, true); + while(std::getline(ctags.output, line)) { + auto location = ctags.get_location(line, true); std::transform(location.kind.begin(), location.kind.end(), location.kind.begin(), [](char c) { return std::tolower(c); }); std::vector ignore_kinds = {"variable", "local", "constant", "global", "property", "member", "enum", diff --git a/src/window.cc b/src/window.cc index 622bcbb..891ee37 100644 --- a/src/window.cc +++ b/src/window.cc @@ -793,16 +793,12 @@ void Window::set_menu_actions() { auto pattern = pattern_; // Store pattern to safely hide entrybox EntryBox::get().hide(); if(!pattern.empty()) { - auto pair = Grep::get_result(Project::get_preferably_view_folder(), pattern, find_pattern_case_sensitive, find_pattern_extended_regex); - auto path = std::move(pair.first); - auto stream = std::move(pair.second); - stream->seekg(0, std::ios::end); - if(stream->tellg() == 0) { + auto grep = std::make_shared(Project::get_preferably_view_folder(), pattern, find_pattern_case_sensitive, find_pattern_extended_regex); + if(!*grep) { Info::get().print("Pattern not found"); EntryBox::get().hide(); return; } - stream->seekg(0, std::ios::beg); if(auto view = Notebook::get().get_current_view()) SelectionDialog::create(view, true, true); @@ -814,12 +810,12 @@ void Window::set_menu_actions() { unsigned int current_line = 0; auto view = Notebook::get().get_current_view(); if(view) { - current_path = filesystem::get_relative_path(view->file_path, path).string(); + current_path = filesystem::get_relative_path(view->file_path, grep->project_path).string(); current_line = view->get_buffer()->get_insert()->get_iter().get_line(); } bool set_cursor_at_path = true; - while(std::getline(*stream, line)) { - auto location = Grep::get_location(std::move(line), true, false, current_path); + while(std::getline(grep->output, line)) { + auto location = grep->get_location(std::move(line), true, false, current_path); SelectionDialog::get()->add_row(location.markup); if(view && location) { if(set_cursor_at_path) { @@ -832,9 +828,9 @@ void Window::set_menu_actions() { } } } - SelectionDialog::get()->on_select = [path = std::move(path)](unsigned int index, const std::string &text, bool hide_window) { - auto location = Grep::get_location(text, false, true); - Notebook::get().open(path / location.file_path); + SelectionDialog::get()->on_select = [grep](unsigned int index, const std::string &text, bool hide_window) { + auto location = grep->get_location(text, false, true); + Notebook::get().open(grep->project_path / location.file_path); auto view = Notebook::get().get_current_view(); view->place_cursor_at_line_offset(location.line, location.offset); view->scroll_to_cursor_delayed(true, false); diff --git a/tests/ctags_grep_test.cc b/tests/ctags_grep_test.cc index e8eb8eb..cf2a2df 100644 --- a/tests/ctags_grep_test.cc +++ b/tests/ctags_grep_test.cc @@ -22,16 +22,16 @@ int main() { // Ctags tests { - auto result = Ctags::get_result(tests_path); - g_assert(result.first == tests_path.parent_path()); + Ctags ctags(tests_path); + g_assert(ctags.project_path == tests_path.parent_path()); bool found = false; std::string line; - while(std::getline(*result.second, line)) { + while(std::getline(ctags.output, line)) { if(line.find("ctags_grep_test_function") != std::string::npos) { { - auto location = Ctags::get_location(line, false); + auto location = ctags.get_location(line, false); g_assert(location.source == "void ctags_grep_test_function() {"); - g_assert(result.first / location.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(ctags.project_path / location.file_path == tests_path / "ctags_grep_test.cc"); g_assert_cmpint(location.line, ==, 6); g_assert_cmpint(location.index, ==, 5); g_assert(location.symbol == "ctags_grep_test_function"); @@ -39,9 +39,9 @@ int main() { g_assert(location.kind.empty()); } { - auto location = Ctags::get_location(line, true); + auto location = ctags.get_location(line, true); g_assert(location.source == "void ctags_grep_test_function() {"); - g_assert(result.first / location.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(ctags.project_path / location.file_path == tests_path / "ctags_grep_test.cc"); g_assert_cmpint(location.line, ==, 6); g_assert_cmpint(location.index, ==, 5); g_assert(location.symbol == "ctags_grep_test_function"); @@ -55,16 +55,16 @@ int main() { g_assert(found == true); } { - auto result = Ctags::get_result(tests_path, false, true); - g_assert(result.first == tests_path.parent_path()); + Ctags ctags(tests_path, false, true); + g_assert(ctags.project_path == tests_path.parent_path()); bool found = false; std::string line; - while(std::getline(*result.second, line)) { + while(std::getline(ctags.output, line)) { if(line.find("ctags_grep_test_function") != std::string::npos) { { - auto location = Ctags::get_location(line, false, false, true); + auto location = ctags.get_location(line, false); g_assert(location.source == "void ctags_grep_test_function() {"); - g_assert(result.first / location.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(ctags.project_path / location.file_path == tests_path / "ctags_grep_test.cc"); g_assert_cmpint(location.line, ==, 6); g_assert_cmpint(location.index, ==, 5); g_assert(location.symbol == "ctags_grep_test_function"); @@ -72,9 +72,9 @@ int main() { g_assert(location.kind == "function"); } { - auto location = Ctags::get_location(line, true, false, true); + auto location = ctags.get_location(line, true); g_assert(location.source == "void ctags_grep_test_function() {"); - g_assert(result.first / location.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(ctags.project_path / location.file_path == tests_path / "ctags_grep_test.cc"); g_assert_cmpint(location.line, ==, 6); g_assert_cmpint(location.index, ==, 5); g_assert(location.symbol == "ctags_grep_test_function"); @@ -88,16 +88,16 @@ int main() { g_assert(found == true); } { - auto result = Ctags::get_result(tests_path, true); - g_assert(result.first == tests_path.parent_path()); + Ctags ctags(tests_path, true); + g_assert(ctags.project_path == tests_path.parent_path()); bool found = false; std::string line; - while(std::getline(*result.second, line)) { + while(std::getline(ctags.output, line)) { if(line.find("ctags_grep_test_function2") != std::string::npos) { { - auto location = Ctags::get_location(line, false, true); + auto location = ctags.get_location(line, false); g_assert(location.source == "void ctags_grep_test_function2() {"); - g_assert(result.first / location.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(ctags.project_path / location.file_path == tests_path / "ctags_grep_test.cc"); g_assert_cmpint(location.line, ==, 10); g_assert_cmpint(location.index, ==, 7); g_assert(location.symbol == "ctags_grep_test_function2"); @@ -113,50 +113,50 @@ int main() { // Grep tests { - auto result = Grep::get_result(tests_path, "ctags_grep_test_function", true, false); - g_assert(result.first == tests_path.parent_path()); + Grep grep(tests_path, "ctags_grep_test_function", true, false); + g_assert(grep.project_path == tests_path.parent_path()); bool found = false; std::string line; - while(std::getline(*result.second, line)) { + while(std::getline(grep.output, line)) { if(line.find("ctags_grep_test_function") != std::string::npos) { { - auto location = Grep::get_location(line, true, true); + auto location = grep.get_location(line, true, true); g_assert(location.markup == "tests/ctags_grep_test.cc:7:void ctags_grep_test_function() {"); - g_assert(result.first / location.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(grep.project_path / location.file_path == tests_path / "ctags_grep_test.cc"); g_assert_cmpint(location.line, ==, 6); g_assert_cmpint(location.offset, ==, 5); { - auto location2 = Grep::get_location(location.markup, false, true); + auto location2 = grep.get_location(location.markup, false, true); g_assert(location2.markup == "tests/ctags_grep_test.cc:7:void ctags_grep_test_function() {"); - g_assert(result.first / location2.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(grep.project_path / location2.file_path == tests_path / "ctags_grep_test.cc"); g_assert_cmpint(location2.line, ==, 6); g_assert_cmpint(location2.offset, ==, 5); } } { - auto location = Grep::get_location(line, true, false); + auto location = grep.get_location(line, true, false); g_assert(location.markup == "tests/ctags_grep_test.cc:7:void ctags_grep_test_function() {"); - g_assert(result.first / location.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(grep.project_path / location.file_path == tests_path / "ctags_grep_test.cc"); g_assert_cmpint(location.line, ==, 6); g_assert_cmpint(location.offset, ==, 0); { - auto location2 = Grep::get_location(location.markup, false, false); + auto location2 = grep.get_location(location.markup, false, false); g_assert(location2.markup == "tests/ctags_grep_test.cc:7:void ctags_grep_test_function() {"); - g_assert(result.first / location2.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(grep.project_path / location2.file_path == tests_path / "ctags_grep_test.cc"); g_assert_cmpint(location2.line, ==, 6); g_assert_cmpint(location2.offset, ==, 0); } } { - auto location = Grep::get_location(line, true, true, (boost::filesystem::path("tests") / "ctags_grep_test.cc").string()); + auto location = grep.get_location(line, true, true, (boost::filesystem::path("tests") / "ctags_grep_test.cc").string()); g_assert(location.markup == "tests/ctags_grep_test.cc:7:void ctags_grep_test_function() {"); - g_assert(result.first / location.file_path == tests_path / "ctags_grep_test.cc"); + g_assert(grep.project_path / location.file_path == tests_path / "ctags_grep_test.cc"); g_assert(location); g_assert_cmpint(location.line, ==, 6); g_assert_cmpint(location.offset, ==, 5); } { - auto location = Grep::get_location(line, true, true, "CMakeLists.txt"); + auto location = grep.get_location(line, true, true, "CMakeLists.txt"); g_assert(location.markup == "tests/ctags_grep_test.cc:7:void ctags_grep_test_function() {"); g_assert(location.file_path.empty()); g_assert(!location); @@ -172,22 +172,22 @@ int main() { { auto pattern = std::string("C") + "tags_grep_test_function"; { - auto result = Grep::get_result(tests_path, pattern, true, false); - g_assert(result.first == tests_path.parent_path()); + Grep grep(tests_path, pattern, true, false); + g_assert(grep.project_path == tests_path.parent_path()); bool found = false; std::string line; - while(std::getline(*result.second, line)) { + while(std::getline(grep.output, line)) { if(line.find("ctags_grep_test_function") != std::string::npos) found = true; } g_assert(found == false); } { - auto result = Grep::get_result(tests_path, pattern, false, false); - g_assert(result.first == tests_path.parent_path()); + Grep grep(tests_path, pattern, false, false); + g_assert(grep.project_path == tests_path.parent_path()); bool found = false; std::string line; - while(std::getline(*result.second, line)) { + while(std::getline(grep.output, line)) { if(line.find("ctags_grep_test_function") != std::string::npos) found = true; }