diff --git a/src/cmake.cpp b/src/cmake.cpp index 116a530..0bac4b7 100644 --- a/src/cmake.cpp +++ b/src/cmake.cpp @@ -5,6 +5,7 @@ #include "filesystem.hpp" #include "terminal.hpp" #include "utility.hpp" +#include #include CMake::CMake(const boost::filesystem::path &path) { @@ -141,7 +142,7 @@ boost::filesystem::path CMake::get_executable(const boost::filesystem::path &bui } } - size_t best_match_size = -1; + boost::optional best_match_size; boost::filesystem::path best_match_executable; for(auto &cmake_executable : cmake_executables) { @@ -154,7 +155,7 @@ boost::filesystem::path CMake::get_executable(const boost::filesystem::path &bui 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 < size) { + if(best_match_size < size) { best_match_size = size; best_match_executable = maybe_executable; } @@ -173,7 +174,7 @@ boost::filesystem::path CMake::get_executable(const boost::filesystem::path &bui 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 < size) { + if(!best_match_size || best_match_size < size) { best_match_size = size; best_match_executable = maybe_executable; } diff --git a/src/documentation.cpp b/src/documentation.cpp index 33d4612..808e3f2 100644 --- a/src/documentation.cpp +++ b/src/documentation.cpp @@ -1,6 +1,10 @@ #include "documentation.hpp" #include +// For both get_headers and get_url: +// - Removed " (utility)" from "std::move (utility)" +// - Removed lines with "move (algorithm)" + std::vector Documentation::CppReference::get_headers(const std::string &symbol) noexcept { // Extracted from http://upload.cppreference.com/mwiki/images/b/b1/cppreference-doc-20190607.zip // Using raw string instead of map to reduce compile time @@ -1908,7 +1912,7 @@ std::ignore tuple std::ranges::swap concepts std::forward utility std::exchange utility -std::move (utility) utility +std::move utility std::move_if_noexcept utility std::declval utility std::as_const utility @@ -2342,7 +2346,6 @@ std::copy algorithm std::copy_if algorithm std::copy_n algorithm std::copy_backward algorithm -std::move (algorithm) algorithm std::move_backward algorithm std::fill algorithm std::fill_n algorithm @@ -5939,7 +5942,7 @@ std::ignore cpp/utility/tuple/ignore std::ranges::swap cpp/utility/ranges/swap std::forward cpp/utility/forward std::exchange cpp/utility/exchange -std::move (utility) cpp/utility/move +std::move cpp/utility/move std::move_if_noexcept cpp/utility/move_if_noexcept std::declval cpp/utility/declval std::as_const cpp/utility/as_const @@ -9073,7 +9076,6 @@ std::copy cpp/algorithm/copy std::copy_if cpp/algorithm/copy std::copy_n cpp/algorithm/copy_n std::copy_backward cpp/algorithm/copy_backward -std::move (algorithm) cpp/algorithm/move std::move_backward cpp/algorithm/move_backward std::fill cpp/algorithm/fill std::fill_n cpp/algorithm/fill_n diff --git a/src/git.cpp b/src/git.cpp index 1c61326..7476def 100644 --- a/src/git.cpp +++ b/src/git.cpp @@ -252,11 +252,10 @@ std::shared_ptr Git::get_repository(const boost::filesystem::pa return instance; } -boost::filesystem::path Git::path(const char *cpath, size_t cpath_length) noexcept { +boost::filesystem::path Git::path(const char *cpath, boost::optional cpath_length_) noexcept { if(cpath == nullptr) return boost::filesystem::path(); - if(cpath_length == static_cast(-1)) - cpath_length = strlen(cpath); + auto cpath_length = cpath_length_.value_or(strlen(cpath)); if(cpath_length > 0 && (cpath[cpath_length - 1] == '/' || cpath[cpath_length - 1] == '\\')) return std::string(cpath, cpath_length - 1); else diff --git a/src/git.hpp b/src/git.hpp index 9a67414..c03d97e 100644 --- a/src/git.hpp +++ b/src/git.hpp @@ -1,6 +1,7 @@ #pragma once #include "mutex.hpp" #include +#include #include #include #include @@ -98,7 +99,7 @@ private: ///Call initialize in public static methods static void initialize() noexcept REQUIRES(mutex); - static boost::filesystem::path path(const char *cpath, size_t cpath_length = static_cast(-1)) noexcept REQUIRES(mutex); + static boost::filesystem::path path(const char *cpath, boost::optional cpath_length = {}) noexcept REQUIRES(mutex); public: static std::shared_ptr get_repository(const boost::filesystem::path &path); diff --git a/src/grep.cpp b/src/grep.cpp index d636ee8..facc908 100644 --- a/src/grep.cpp +++ b/src/grep.cpp @@ -42,7 +42,6 @@ Grep::Grep(const boost::filesystem::path &path, const std::string &pattern, bool std::string command = Config::get().project.grep_command + " -R " + flags + " --color=always --binary-files=without-match " + exclude + " -n " + escaped_pattern + " *"; std::stringstream stdin_stream; - //TODO: when debian stable gets newer g++ version that supports move on streams, remove unique_ptr below Terminal::get().process(stdin_stream, output, command, project_path); } diff --git a/src/meson.cpp b/src/meson.cpp index cffa9a2..9717efe 100644 --- a/src/meson.cpp +++ b/src/meson.cpp @@ -5,6 +5,7 @@ #include "filesystem.hpp" #include "terminal.hpp" #include "utility.hpp" +#include #include Meson::Meson(const boost::filesystem::path &path) { @@ -94,7 +95,7 @@ bool Meson::update_debug_build(const boost::filesystem::path &debug_build_path, boost::filesystem::path Meson::get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path) { CompileCommands compile_commands(build_path); - size_t best_match_size = -1; + boost::optional best_match_size; boost::filesystem::path best_match_executable; for(auto &command : compile_commands.commands) { auto command_file = filesystem::get_normal_path(command.file); @@ -109,7 +110,7 @@ boost::filesystem::path Meson::get_executable(const boost::filesystem::path &bui 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 < size) { + if(best_match_size < size) { best_match_size = size; best_match_executable = executable; } diff --git a/src/notebook.cpp b/src/notebook.cpp index 7f2fa63..23f2465 100644 --- a/src/notebook.cpp +++ b/src/notebook.cpp @@ -52,7 +52,7 @@ Notebook::Notebook() : Gtk::Paned(), notebooks(2) { break; } } - last_index = -1; + last_index.reset(); }); notebook.signal_page_added().connect([this](Gtk::Widget *widget, guint) { auto hbox = dynamic_cast(widget); @@ -171,7 +171,7 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position auto previous_view = get_current_view(); if(previous_view) { view->replace_text(previous_view->get_buffer()->get_text()); - position = get_notebook_page(get_index(previous_view)).first == 0 ? Position::right : Position::left; + position = get_notebook_page(previous_view).first == 0 ? Position::right : Position::left; } } @@ -299,9 +299,7 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position //Set up tab label tab_labels.emplace_back(new TabLabel([this, view]() { - auto index = get_index(view); - if(index != static_cast(-1)) - close(index); + close(get_index(view)); })); view->update_tab_label = [this](Source::BaseView *view) { std::string title = view->file_path.filename().string(); @@ -311,9 +309,8 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position title += ' '; for(size_t c = 0; c < size(); ++c) { if(source_views[c] == view) { - auto &tab_label = tab_labels.at(c); - tab_label->label.set_text(title); - tab_label->set_tooltip_text(filesystem::get_short_path(view->file_path).string()); + tab_labels[c]->label.set_text(title); + tab_labels[c]->set_tooltip_text(filesystem::get_short_path(view->file_path).string()); return; } } @@ -446,7 +443,7 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position else if(notebooks[1].get_n_pages() == 0) position = Position::right; else if(last_view) - position = get_notebook_page(get_index(last_view)).first == 0 ? Position::left : Position::right; + position = get_notebook_page(last_view).first == 0 ? Position::left : Position::right; } size_t notebook_index = position == Position::right ? 1 : 0; auto ¬ebook = notebooks[notebook_index]; @@ -458,11 +455,10 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position show_all_children(); notebook.set_current_page(notebook.get_n_pages() - 1); - last_index = -1; + last_index.reset(); if(last_view) { auto index = get_index(last_view); - auto notebook_page = get_notebook_page(index); - if(notebook_page.first == notebook_index) + if(get_notebook_page(index).first == notebook_index) last_index = index; } @@ -517,17 +513,17 @@ bool Notebook::close(size_t index) { } if(view == get_current_view()) { bool focused = false; - if(last_index != static_cast(-1)) { - auto notebook_page = get_notebook_page(last_index); - if(notebook_page.first == get_notebook_page(get_index(view)).first) { - focus_view(source_views[last_index]); - notebooks[notebook_page.first].set_current_page(notebook_page.second); - last_index = -1; + if(last_index) { + auto last_notebook_page = get_notebook_page(*last_index); + if(get_notebook_page(view).first == last_notebook_page.first) { + focus_view(source_views[*last_index]); + notebooks[last_notebook_page.first].set_current_page(last_notebook_page.second); + last_index.reset(); focused = true; } } if(!focused) { - auto notebook_page = get_notebook_page(get_index(view)); + auto notebook_page = get_notebook_page(view); if(notebook_page.second > 0) focus_view(get_view(notebook_page.first, notebook_page.second - 1)); else { @@ -540,9 +536,9 @@ bool Notebook::close(size_t index) { } } else if(index == last_index) - last_index = -1; - else if(index < last_index && last_index != static_cast(-1)) - last_index--; + last_index.reset(); + else if(index < last_index) + (*last_index)--; auto notebook_page = get_notebook_page(index); notebooks[notebook_page.first].remove_page(notebook_page.second); @@ -600,7 +596,7 @@ bool Notebook::close_current() { void Notebook::next() { if(auto view = get_current_view()) { - auto notebook_page = get_notebook_page(get_index(view)); + auto notebook_page = get_notebook_page(view); int page = notebook_page.second + 1; if(page >= notebooks[notebook_page.first].get_n_pages()) notebooks[notebook_page.first].set_current_page(0); @@ -611,7 +607,7 @@ void Notebook::next() { void Notebook::previous() { if(auto view = get_current_view()) { - auto notebook_page = get_notebook_page(get_index(view)); + auto notebook_page = get_notebook_page(view); int page = notebook_page.second - 1; if(page < 0) notebooks[notebook_page.first].set_current_page(notebooks[notebook_page.first].get_n_pages() - 1); @@ -634,8 +630,7 @@ void Notebook::toggle_split() { } else { for(size_t c = size() - 1; c != static_cast(-1); --c) { - auto notebook_index = get_notebook_page(c).first; - if(notebook_index == 1 && !close(c)) + if(get_notebook_page(c).first == 1 && !close(c)) return; } remove(notebooks[1]); @@ -651,10 +646,8 @@ void Notebook::toggle_tabs() { std::vector> Notebook::get_notebook_views() { std::vector> notebook_views; for(size_t notebook_index = 0; notebook_index < notebooks.size(); ++notebook_index) { - for(int page = 0; page < notebooks[notebook_index].get_n_pages(); ++page) { - if(auto view = get_view(notebook_index, page)) - notebook_views.emplace_back(notebook_index, view); - } + for(int page = 0; page < notebooks[notebook_index].get_n_pages(); ++page) + notebook_views.emplace_back(notebook_index, get_view(notebook_index, page)); } return notebook_views; } @@ -680,19 +673,13 @@ void Notebook::clear_status() { status_state.set_text(""); } -size_t Notebook::get_index(Source::View *view) { - for(size_t c = 0; c < size(); ++c) { - if(source_views[c] == view) - return c; - } - return -1; -} - Source::View *Notebook::get_view(size_t notebook_index, int page) { - if(notebook_index == static_cast(-1) || notebook_index >= notebooks.size() || - page < 0 || page >= notebooks[notebook_index].get_n_pages()) - return nullptr; - auto hbox = dynamic_cast(notebooks[notebook_index].get_nth_page(page)); + if(notebook_index >= notebooks.size()) + throw "notebook index out of bounds"; + auto widget = notebooks[notebook_index].get_nth_page(page); + if(!widget) + throw "page number out of bounds"; + auto hbox = dynamic_cast(widget); auto scrolled_window = dynamic_cast(hbox->get_children()[0]); return dynamic_cast(scrolled_window->get_children()[0]); } @@ -702,15 +689,30 @@ void Notebook::focus_view(Source::View *view) { view->grab_focus(); } +size_t Notebook::get_index(Source::View *view) { + for(size_t c = 0; c < size(); ++c) { + if(source_views[c] == view) + return c; + } + throw "view not found"; +} + std::pair Notebook::get_notebook_page(size_t index) { - if(index >= hboxes.size()) - return {-1, -1}; for(size_t c = 0; c < notebooks.size(); ++c) { auto page_num = notebooks[c].page_num(*hboxes[index]); if(page_num >= 0) return {c, page_num}; } - return {-1, -1}; + throw "index out of bounds"; +} + +std::pair Notebook::get_notebook_page(Source::View *view) { + try { + return get_notebook_page(get_index(view)); + } + catch(...) { + throw "view not found"; + } } void Notebook::set_current_view(Source::View *view) { diff --git a/src/notebook.hpp b/src/notebook.hpp index f312e64..e563290 100644 --- a/src/notebook.hpp +++ b/src/notebook.hpp @@ -1,5 +1,6 @@ #pragma once #include "source.hpp" +#include #include #include #include @@ -70,10 +71,15 @@ public: void delete_cursor_locations(Source::View *view); private: - size_t get_index(Source::View *view); + /// Throws on out of bounds arguments Source::View *get_view(size_t notebook_index, int page); void focus_view(Source::View *view); + /// Throws if view is not found + size_t get_index(Source::View *view); + /// Throws on out of bounds index std::pair get_notebook_page(size_t index); + /// Throws if view is not found + std::pair get_notebook_page(Source::View *view); std::vector notebooks; std::vector source_views; //Is NOT freed in destructor, this is intended for quick program exit. @@ -83,7 +89,7 @@ private: std::vector> tab_labels; bool split = false; - size_t last_index = -1; + boost::optional last_index; void set_current_view(Source::View *view); Source::View *current_view = nullptr; diff --git a/src/selection_dialog.cpp b/src/selection_dialog.cpp index e9f2cb1..ae6bd2c 100644 --- a/src/selection_dialog.cpp +++ b/src/selection_dialog.cpp @@ -150,7 +150,7 @@ void SelectionDialogBase::cursor_changed() { if(!is_visible()) return; auto it = list_view_text.get_selection()->get_selected(); - auto index = static_cast(-1); + boost::optional index; if(it) index = it->get_value(list_view_text.column_record.index); if(last_index == index) @@ -159,7 +159,7 @@ void SelectionDialogBase::cursor_changed() { std::string text; if(it) text = it->get_value(list_view_text.column_record.text); - on_changed(index, text); + on_changed(index.value_or(-1), text); } last_index = index; } @@ -208,7 +208,7 @@ void SelectionDialogBase::hide() { if(on_hide) on_hide(); list_view_text.clear(); - last_index = static_cast(-1); + last_index.reset(); } std::unique_ptr SelectionDialog::instance; diff --git a/src/selection_dialog.hpp b/src/selection_dialog.hpp index 99a9893..c438bed 100644 --- a/src/selection_dialog.hpp +++ b/src/selection_dialog.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -65,7 +66,7 @@ protected: SearchEntry search_entry; bool show_search_entry; - unsigned int last_index = static_cast(-1); + boost::optional last_index; }; class SelectionDialog : public SelectionDialogBase { diff --git a/src/source.cpp b/src/source.cpp index c4ebbb1..4b3b726 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -235,7 +235,7 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr< --line_end; bool lines_commented = true; bool extra_spaces = true; - int min_indentation = -1; + boost::optional min_indentation; for(auto line = line_start; line <= line_end; ++line) { auto iter = get_buffer()->get_iter_at_line(line); bool line_added = false; @@ -281,7 +281,7 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr< if(line_added) { lines_commented &= line_commented; extra_spaces &= extra_space; - if(min_indentation == -1 || indentation < min_indentation) + if(!min_indentation || indentation < min_indentation) min_indentation = indentation; } } @@ -290,7 +290,7 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr< get_buffer()->begin_user_action(); for(auto &line : lines) { auto iter = get_buffer()->get_iter_at_line(line); - iter.forward_chars(min_indentation); + iter.forward_chars(min_indentation.value_or(0)); if(lines_commented) { auto end_iter = iter; end_iter.forward_chars(comment_characters.size() + static_cast(extra_spaces)); @@ -420,7 +420,7 @@ bool Source::View::save() { boost::system::error_code ec; last_write_time = boost::filesystem::last_write_time(file_path, ec); if(ec) - last_write_time = static_cast(-1); + last_write_time.reset(); // Remonitor file in case it did not exist before monitor_file(); get_buffer()->set_modified(false); @@ -578,9 +578,7 @@ void Source::View::setup_signals() { if(on_motion_last_x != event->x || on_motion_last_y != event->y) { delayed_tooltips_connection.disconnect(); if((event->state & GDK_BUTTON1_MASK) == 0) { - gdouble x = event->x; - gdouble y = event->y; - delayed_tooltips_connection = Glib::signal_timeout().connect([this, x, y]() { + delayed_tooltips_connection = Glib::signal_timeout().connect([this, x = event->x, y = event->y]() { type_tooltips.hide(); diagnostic_tooltips.hide(); Tooltips::init(); @@ -610,8 +608,8 @@ void Source::View::setup_signals() { }, 100); } - auto last_mouse_pos = std::make_pair(on_motion_last_x, on_motion_last_y); - auto mouse_pos = std::make_pair(event->x, event->y); + auto last_mouse_pos = std::make_pair(on_motion_last_x, on_motion_last_y); + auto mouse_pos = std::make_pair(event->x, event->y); type_tooltips.hide(last_mouse_pos, mouse_pos); diagnostic_tooltips.hide(last_mouse_pos, mouse_pos); } @@ -1350,7 +1348,7 @@ void Source::View::extend_selection() { if(!select_matching_brackets) { bool select_end_block = language->get_id() == "cmake" || language->get_id() == "meson"; - auto get_tabs = [this](Gtk::TextIter iter) { + auto get_tabs = [this](Gtk::TextIter iter) -> boost::optional { iter = get_buffer()->get_iter_at_line(iter.get_line()); int tabs = 0; while(!iter.ends_line() && (*iter == ' ' || *iter == '\t')) { @@ -1359,7 +1357,7 @@ void Source::View::extend_selection() { break; } if(iter.ends_line()) - return -1; + return {}; return tabs; }; @@ -1380,19 +1378,18 @@ void Source::View::extend_selection() { end.forward_to_line_end(); // Try select block that starts at cursor - auto end_tabs = get_tabs(end); auto iter = end; - if(end_tabs >= 0) { + if(auto end_tabs = get_tabs(end)) { bool can_select_end_block = false; while(iter.forward_char()) { auto tabs = get_tabs(iter); - if(tabs < 0 || tabs > end_tabs || (select_end_block && can_select_end_block && tabs == end_tabs)) { + if(!tabs || tabs > end_tabs || (select_end_block && can_select_end_block && tabs == end_tabs)) { if(!iter.ends_line()) iter.forward_to_line_end(); end = iter; if(tabs > end_tabs) can_select_end_block = true; - if(tabs == end_tabs) + else if(tabs == end_tabs) break; continue; } @@ -3072,7 +3069,7 @@ bool Source::View::on_key_press_event_smart_inserts(GdkEventKey *key) { } } // Insert '' - else if(key->keyval == GDK_KEY_apostrophe && allow_insertion(iter) && symbol_count(iter, '\'', -1) % 2 == 0) { + else if(key->keyval == GDK_KEY_apostrophe && allow_insertion(iter) && symbol_count(iter, '\'') % 2 == 0) { get_buffer()->insert_at_cursor("''"); auto iter = get_buffer()->get_insert()->get_iter(); iter.backward_char(); @@ -3081,7 +3078,7 @@ bool Source::View::on_key_press_event_smart_inserts(GdkEventKey *key) { return true; } // Insert "" - else if(key->keyval == GDK_KEY_quotedbl && allow_insertion(iter) && symbol_count(iter, '"', -1) % 2 == 0) { + else if(key->keyval == GDK_KEY_quotedbl && allow_insertion(iter) && symbol_count(iter, '"') % 2 == 0) { get_buffer()->insert_at_cursor("\"\""); auto iter = get_buffer()->get_insert()->get_iter(); iter.backward_char(); diff --git a/src/source.hpp b/src/source.hpp index 59b9177..53a3eb1 100644 --- a/src/source.hpp +++ b/src/source.hpp @@ -134,7 +134,7 @@ namespace Source { Gtk::TextIter get_start_of_expression(Gtk::TextIter iter); bool find_close_symbol_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter, unsigned int positive_char, unsigned int negative_char); bool find_open_symbol_backward(Gtk::TextIter iter, Gtk::TextIter &found_iter, unsigned int positive_char, unsigned int negative_char); - long symbol_count(Gtk::TextIter iter, unsigned int positive_char, unsigned int negative_char); + long symbol_count(Gtk::TextIter iter, unsigned int positive_char, unsigned int negative_char = 0); bool is_templated_function(Gtk::TextIter iter, Gtk::TextIter &parenthesis_end_iter); /// If insert is at an possible argument. Also based on last key press. bool is_possible_argument(); diff --git a/src/source_base.cpp b/src/source_base.cpp index cf37573..c8853d3 100644 --- a/src/source_base.cpp +++ b/src/source_base.cpp @@ -129,7 +129,7 @@ Source::BaseView::BaseView(const boost::filesystem::path &file_path, const Glib: get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0)); signal_focus_in_event().connect([this](GdkEventFocus *event) { - if(this->last_write_time != static_cast(-1)) + if(last_write_time) check_last_write_time(); return false; }); @@ -202,7 +202,7 @@ bool Source::BaseView::load(bool not_undoable_action) { boost::system::error_code ec; last_write_time = boost::filesystem::last_write_time(file_path, ec); if(ec) - last_write_time = static_cast(-1); + last_write_time.reset(); disable_spellcheck = true; if(not_undoable_action) @@ -312,7 +312,7 @@ void Source::BaseView::rename(const boost::filesystem::path &path) { boost::system::error_code ec; last_write_time = boost::filesystem::last_write_time(file_path, ec); if(ec) - last_write_time = static_cast(-1); + last_write_time.reset(); monitor_file(); if(update_status_file_path) @@ -325,7 +325,7 @@ void Source::BaseView::monitor_file() { #ifdef __APPLE__ // TODO: Gio file monitor is bugged on MacOS class Recursive { public: - static void f(BaseView *view, std::time_t previous_last_write_time = static_cast(-1), bool check_called = false) { + static void f(BaseView *view, boost::optional previous_last_write_time = {}, bool check_called = false) { view->delayed_monitor_changed_connection.disconnect(); view->delayed_monitor_changed_connection = Glib::signal_timeout().connect([view, previous_last_write_time, check_called]() { boost::system::error_code ec; @@ -346,10 +346,10 @@ void Source::BaseView::monitor_file() { } }; delayed_monitor_changed_connection.disconnect(); - if(last_write_time != static_cast(-1)) + if(last_write_time) Recursive::f(this); #else - if(this->last_write_time != static_cast(-1)) { + if(last_write_time) { monitor = Gio::File::create_for_path(file_path.string())->monitor_file(Gio::FileMonitorFlags::FILE_MONITOR_NONE); monitor_changed_connection.disconnect(); monitor_changed_connection = monitor->signal_changed().connect([this](const Glib::RefPtr &file, @@ -367,13 +367,13 @@ void Source::BaseView::monitor_file() { #endif } -void Source::BaseView::check_last_write_time(std::time_t last_write_time_) { - if(this->last_write_time == static_cast(-1)) +void Source::BaseView::check_last_write_time(boost::optional last_write_time_) { + if(!this->last_write_time) return; if(Config::get().source.auto_reload_changed_files && !get_buffer()->get_modified()) { boost::system::error_code ec; - auto last_write_time = last_write_time_ != static_cast(-1) ? last_write_time_ : boost::filesystem::last_write_time(file_path, ec); + auto last_write_time = last_write_time_.value_or(boost::filesystem::last_write_time(file_path, ec)); if(!ec && last_write_time != this->last_write_time) { if(load()) return; @@ -381,7 +381,7 @@ void Source::BaseView::check_last_write_time(std::time_t last_write_time_) { } else if(has_focus()) { boost::system::error_code ec; - auto last_write_time = last_write_time_ != static_cast(-1) ? last_write_time_ : boost::filesystem::last_write_time(file_path, ec); + auto last_write_time = last_write_time_.value_or(boost::filesystem::last_write_time(file_path, ec)); if(!ec && last_write_time != this->last_write_time) Info::get().print("Caution: " + file_path.filename().string() + " was changed outside of juCi++"); } @@ -820,7 +820,7 @@ void Source::BaseView::paste() { size_t end_line = 0; bool paste_line = false; bool first_paste_line = true; - size_t paste_line_tabs = -1; + auto paste_line_tabs = static_cast(-1); bool first_paste_line_has_tabs = false; for(size_t c = 0; c < text.size(); c++) { if(text[c] == '\n') { @@ -1161,7 +1161,7 @@ void Source::BaseView::setup_extra_cursor_signals() { extra_cursor.offset = extra_cursor_iter.get_line_offset(); } for(auto &extra_cursor : extra_snippet_cursors) { - extra_cursor.initial_forward_erase_size = std::numeric_limits::max(); + extra_cursor.initial_forward_erase_size.reset(); auto iter = extra_cursor.mark->get_iter(); iter.forward_chars(offset); get_buffer()->insert(iter, text); @@ -1196,9 +1196,9 @@ void Source::BaseView::setup_extra_cursor_signals() { auto start_iter = extra_cursor.mark->get_iter(); auto end_iter = start_iter; start_iter.backward_chars(*erase_backward_length); - if(extra_cursor.initial_forward_erase_size != std::numeric_limits::max()) { // In case of different sized placeholders - end_iter.forward_chars(extra_cursor.initial_forward_erase_size); - extra_cursor.initial_forward_erase_size = std::numeric_limits::max(); + if(extra_cursor.initial_forward_erase_size) { // In case of different sized placeholders + end_iter.forward_chars(*extra_cursor.initial_forward_erase_size); + extra_cursor.initial_forward_erase_size.reset(); } else end_iter.forward_chars(*erase_forward_length); diff --git a/src/source_base.hpp b/src/source_base.hpp index ed3f217..0702445 100644 --- a/src/source_base.hpp +++ b/src/source_base.hpp @@ -3,6 +3,7 @@ #include "mutex.hpp" #include "snippets.hpp" #include +#include #include #include #include @@ -96,9 +97,9 @@ namespace Source { bool keep_clipboard = false; protected: - std::time_t last_write_time; + boost::optional last_write_time; void monitor_file(); - void check_last_write_time(std::time_t last_write_time_ = static_cast(-1)); + void check_last_write_time(boost::optional last_write_time_ = {}); bool is_bracket_language = false; @@ -148,7 +149,7 @@ namespace Source { std::vector extra_cursors; struct ExtraSnippetCursor { Glib::RefPtr mark; - int initial_forward_erase_size; + boost::optional initial_forward_erase_size; }; bool on_key_press_event_extra_cursors(GdkEventKey *key); diff --git a/src/source_language_protocol.cpp b/src/source_language_protocol.cpp index 3e78bbe..8865546 100644 --- a/src/source_language_protocol.cpp +++ b/src/source_language_protocol.cpp @@ -189,9 +189,6 @@ void LanguageProtocol::Client::close(Source::LanguageProtocolView *view) { void LanguageProtocol::Client::parse_server_message() { if(!header_read) { - server_message_size = static_cast(-1); - server_message_stream.seekg(0, std::ios::beg); - std::string line; while(!header_read && std::getline(server_message_stream, line)) { if(!line.empty() && line != "\r") { @@ -203,9 +200,9 @@ void LanguageProtocol::Client::parse_server_message() { } } } - else if(server_message_size != static_cast(-1)) { + else if(server_message_size) { server_message_content_pos = server_message_stream.tellg(); - server_message_size += server_message_content_pos; + *server_message_size += server_message_content_pos; header_read = true; } } @@ -215,11 +212,11 @@ void LanguageProtocol::Client::parse_server_message() { server_message_stream.seekg(0, std::ios::end); size_t read_size = server_message_stream.tellg(); std::stringstream tmp; - if(read_size >= server_message_size) { - if(read_size > server_message_size) { - server_message_stream.seekg(server_message_size, std::ios::beg); - server_message_stream.seekp(server_message_size, std::ios::beg); - for(size_t c = server_message_size; c < read_size; ++c) { + if(read_size >= *server_message_size) { + if(read_size > *server_message_size) { + server_message_stream.seekg(*server_message_size, std::ios::beg); + server_message_stream.seekp(*server_message_size, std::ios::beg); + for(size_t c = *server_message_size; c < read_size; ++c) { tmp.put(server_message_stream.get()); server_message_stream.put(' '); } @@ -279,13 +276,13 @@ void LanguageProtocol::Client::parse_server_message() { } server_message_stream = std::stringstream(); + server_message_size.reset(); header_read = false; - server_message_size = static_cast(-1); tmp.seekg(0, std::ios::end); if(tmp.tellg() > 0) { - tmp.seekg(0, std::ios::beg); - server_message_stream << tmp.rdbuf(); + server_message_stream = std::move(tmp); + server_message_stream.seekg(0, std::ios::beg); parse_server_message(); } } diff --git a/src/source_language_protocol.hpp b/src/source_language_protocol.hpp index 0b73579..be5bd90 100644 --- a/src/source_language_protocol.hpp +++ b/src/source_language_protocol.hpp @@ -4,6 +4,7 @@ #include "process.hpp" #include "source.hpp" #include +#include #include #include #include @@ -118,7 +119,7 @@ namespace LanguageProtocol { std::unique_ptr process GUARDED_BY(read_write_mutex); std::stringstream server_message_stream; - size_t server_message_size = static_cast(-1); + boost::optional server_message_size; size_t server_message_content_pos; bool header_read = false; diff --git a/src/terminal.cpp b/src/terminal.cpp index 5273f0e..a09719a 100644 --- a/src/terminal.cpp +++ b/src/terminal.cpp @@ -165,7 +165,7 @@ bool Terminal::on_motion_notify_event(GdkEventMotion *event) { return Gtk::TextView::on_motion_notify_event(event); } -std::tuple Terminal::find_link(const std::string &line) { +boost::optional Terminal::find_link(const std::string &line) { const static std::regex link_regex("^([A-Z]:)?([^:]+):([0-9]+):([0-9]+): .*$|" // C/C++ compile warning/error/rename usages "^ --> ([A-Z]:)?([^:]+):([0-9]+):([0-9]+)$|" // Rust "^Assertion failed: .*file ([A-Z]:)?([^:]+), line ([0-9]+)\\.$|" // clang assert() @@ -173,26 +173,30 @@ std::tuple Terminal::find "^ERROR:([A-Z]:)?([^:]+):([0-9]+):.*$|" // g_assert (glib.h) "^([A-Z]:)?([\\/][^:]+):([0-9]+)$|" // Node.js "^ File \"([A-Z]:)?([^\"]+)\", line ([0-9]+), in .*$"); // Python - size_t start_position = -1, end_position = -1; - std::string path, line_number, line_offset; std::smatch sm; if(std::regex_match(line, sm, link_regex)) { for(size_t sub = 1; sub < link_regex.mark_count();) { size_t subs = sub == 1 || sub == 5 ? 4 : 3; if(sm.length(sub + 1)) { - start_position = sm.position(sub + 1) - sm.length(sub); - end_position = sm.position(sub + subs - 1) + sm.length(sub + subs - 1); + auto start_pos = static_cast(sm.position(sub + 1) - sm.length(sub)); + auto end_pos = static_cast(sm.position(sub + subs - 1) + sm.length(sub + subs - 1)); + std::string path; if(sm.length(sub)) - path += sm[sub].str(); + path = sm[sub].str(); path += sm[sub + 1].str(); - line_number = sm[sub + 2].str(); - line_offset = subs == 4 ? sm[sub + 3].str() : "1"; - break; + try { + auto line_number = std::stoi(sm[sub + 2].str()); + auto line_offset = std::stoi(subs == 4 ? sm[sub + 3].str() : "1"); + return Link{start_pos, end_pos, path, line_number, line_offset}; + } + catch(...) { + return {}; + } } sub += subs; } } - return std::make_tuple(start_position, end_position, path, line_number, line_offset); + return {}; } void Terminal::apply_link_tags(const Gtk::TextIter &start_iter, const Gtk::TextIter &end_iter) { @@ -224,11 +228,11 @@ void Terminal::apply_link_tags(const Gtk::TextIter &start_iter, const Gtk::TextI line.replace(c, 1, "a"); } auto link = find_link(line.raw()); - if(std::get<0>(link) != static_cast(-1)) { + if(link) { auto link_start = line_start; auto link_end = line_start; - link_start.forward_chars(std::get<0>(link)); - link_end.forward_chars(std::get<1>(link)); + link_start.forward_chars(link->start_pos); + link_end.forward_chars(link->end_pos); get_buffer()->apply_tag(link_tag, link_start, link_end); } line_start_set = false; @@ -356,10 +360,8 @@ bool Terminal::on_button_press_event(GdkEventButton *button_event) { while(!end_iter.ends_line() && end_iter.forward_char()) { } auto link = find_link(get_buffer()->get_text(start_iter, end_iter).raw()); - if(std::get<0>(link) != static_cast(-1)) { - auto path = filesystem::get_long_path(std::get<2>(link)); - std::string line = std::get<3>(link); - std::string index = std::get<4>(link); + if(link) { + auto path = filesystem::get_long_path(link->path); if(path.is_relative()) { if(Project::current) { @@ -379,16 +381,10 @@ bool Terminal::on_button_press_event(GdkEventButton *button_event) { boost::system::error_code ec; if(boost::filesystem::is_regular_file(path, ec)) { if(Notebook::get().open(path)) { - try { - int line_int = std::stoi(line) - 1; - int index_int = std::stoi(index) - 1; - auto view = Notebook::get().get_current_view(); - view->place_cursor_at_line_index(line_int, index_int); - view->scroll_to_cursor_delayed(true, true); - return true; - } - catch(...) { - } + auto view = Notebook::get().get_current_view(); + view->place_cursor_at_line_index(link->line - 1, link->line_index - 1); + view->scroll_to_cursor_delayed(true, true); + return true; } } } diff --git a/src/terminal.hpp b/src/terminal.hpp index 4d0ec58..e201c30 100644 --- a/src/terminal.hpp +++ b/src/terminal.hpp @@ -4,6 +4,7 @@ #include "process.hpp" #include "source_base.hpp" #include +#include #include #include #include @@ -45,7 +46,12 @@ private: Glib::RefPtr default_mouse_cursor; size_t deleted_lines = 0; - std::tuple find_link(const std::string &line); + struct Link { + int start_pos, end_pos; + std::string path; + int line, line_index; + }; + boost::optional find_link(const std::string &line); void apply_link_tags(const Gtk::TextIter &start_iter, const Gtk::TextIter &end_iter); Mutex processes_mutex; diff --git a/src/tooltips.cpp b/src/tooltips.cpp index 31434ea..21cdc75 100644 --- a/src/tooltips.cpp +++ b/src/tooltips.cpp @@ -287,14 +287,14 @@ void Tooltip::show(bool disregard_drawn, const std::function &on_motion) shown = true; } -void Tooltip::hide(const std::pair &last_mouse_pos, const std::pair &mouse_pos) { +void Tooltip::hide(const boost::optional> &last_mouse_pos, const boost::optional> &mouse_pos) { // Keep tooltip if mouse is moving towards it // Calculated using dot product between the mouse_pos vector and the corners of the tooltip window - if(text_view && window && shown && last_mouse_pos.first != -1 && last_mouse_pos.second != -1 && mouse_pos.first != -1 && mouse_pos.second != -1) { + if(text_view && window && shown && last_mouse_pos && mouse_pos) { static int root_x, root_y; - text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(last_mouse_pos.first, last_mouse_pos.second, root_x, root_y); - int diff_x = mouse_pos.first - last_mouse_pos.first; - int diff_y = mouse_pos.second - last_mouse_pos.second; + text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(last_mouse_pos->first, last_mouse_pos->second, root_x, root_y); + int diff_x = mouse_pos->first - last_mouse_pos->first; + int diff_y = mouse_pos->second - last_mouse_pos->second; class Corner { public: Corner(int x, int y) : x(x - root_x), y(y - root_y) {} @@ -792,7 +792,7 @@ void Tooltips::show(const Gdk::Rectangle &rectangle, bool disregard_drawn) { if(rectangle.intersects(tooltip.activation_rectangle)) tooltip.show(disregard_drawn, on_motion); else - tooltip.hide(); + tooltip.hide({}, {}); } } @@ -803,7 +803,7 @@ void Tooltips::show(bool disregard_drawn) { } } -void Tooltips::hide(const std::pair &last_mouse_pos, const std::pair &mouse_pos) { +void Tooltips::hide(boost::optional> last_mouse_pos, boost::optional> mouse_pos) { for(auto &tooltip : tooltip_list) tooltip.hide(last_mouse_pos, mouse_pos); } diff --git a/src/tooltips.hpp b/src/tooltips.hpp index 2db8ea5..8bce712 100644 --- a/src/tooltips.hpp +++ b/src/tooltips.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -14,7 +15,7 @@ public: void update(); void show(bool disregard_drawn = false, const std::function &on_motion = nullptr); - void hide(const std::pair &last_mouse_pos = {-1, -1}, const std::pair &mouse_pos = {-1, -1}); + void hide(const boost::optional> &last_mouse_pos, const boost::optional> &mouse_pos); Gdk::Rectangle activation_rectangle; Glib::RefPtr start_mark; @@ -61,7 +62,7 @@ public: void show(const Gdk::Rectangle &rectangle, bool disregard_drawn = false); void show(bool disregard_drawn = false); - void hide(const std::pair &last_mouse_pos = {-1, -1}, const std::pair &mouse_pos = {-1, -1}); + void hide(boost::optional> last_mouse_pos = {}, boost::optional> mouse_pos = {}); void clear() { tooltip_list.clear(); }; template diff --git a/tests/terminal_test.cpp b/tests/terminal_test.cpp index 6d25e24..9a87b44 100644 --- a/tests/terminal_test.cpp +++ b/tests/terminal_test.cpp @@ -13,31 +13,38 @@ int main() { { auto link = Terminal::get().find_link("~/test/test.cc:7:41: error: expected ';' after expression."); - assert(std::get<0>(link) == 0); - assert(std::get<1>(link) == 19); - assert(std::get<2>(link) == "~/test/test.cc"); - assert(std::get<3>(link) == "7"); - assert(std::get<4>(link) == "41"); + assert(link); + assert(link->start_pos == 0); + assert(link->end_pos == 19); + assert(link->path == "~/test/test.cc"); + assert(link->line == 7); + assert(link->line_index == 41); } { auto link = Terminal::get().find_link("Assertion failed: (false), function main, file ~/test/test.cc, line 15."); - assert(std::get<0>(link) == 47); - assert(std::get<1>(link) == 70); - assert(std::get<2>(link) == "~/test/test.cc"); - assert(std::get<3>(link) == "15"); + assert(link); + assert(link->start_pos == 47); + assert(link->end_pos == 70); + assert(link->path == "~/test/test.cc"); + assert(link->line == 15); + assert(link->line_index == 1); } { auto link = Terminal::get().find_link("test: ~/examples/main.cpp:17: int main(int, char**): Assertion `false' failed."); - assert(std::get<0>(link) == 6); - assert(std::get<1>(link) == 28); - assert(std::get<2>(link) == "~/examples/main.cpp"); - assert(std::get<3>(link) == "17"); + assert(link); + assert(link->start_pos == 6); + assert(link->end_pos == 28); + assert(link->path == "~/examples/main.cpp"); + assert(link->line == 17); + assert(link->line_index == 1); } { auto link = Terminal::get().find_link("ERROR:~/test/test.cc:36:int main(): assertion failed: (false)"); - assert(std::get<0>(link) == 6); - assert(std::get<1>(link) == 23); - assert(std::get<2>(link) == "~/test/test.cc"); - assert(std::get<3>(link) == "36"); + assert(link); + assert(link->start_pos == 6); + assert(link->end_pos == 23); + assert(link->path == "~/test/test.cc"); + assert(link->line == 36); + assert(link->line_index == 1); } }