diff --git a/src/source_base.cpp b/src/source_base.cpp index 0fd282c..97d5abb 100644 --- a/src/source_base.cpp +++ b/src/source_base.cpp @@ -10,7 +10,7 @@ #include #include -Source::SearchView::SearchView() : Gsv::View() { +Source::SearchView::SearchView(const Glib::RefPtr &language) : Gsv::View(), language(language) { search_settings = gtk_source_search_settings_new(); gtk_source_search_settings_set_wrap_around(search_settings, true); search_context = gtk_source_search_context_new(get_source_buffer()->gobj(), search_settings); @@ -136,7 +136,130 @@ bool Source::SearchView::on_key_press_event(GdkEventKey *event) { return Gsv::View::on_key_press_event(event); } -Source::BaseView::BaseView(const boost::filesystem::path &file_path, const Glib::RefPtr &language) : SearchView(), file_path(file_path), language(language), status_diagnostics(0, 0, 0) { +void Source::SearchView::cut() { + if(!get_editable()) + return copy(); + + disable_spellcheck = true; + ScopeGuard guard{[this] { + disable_spellcheck = false; + }}; + + if(!get_buffer()->get_has_selection()) + cut_lines(); + else if(language && language->get_id() == "diff") { + Gtk::TextIter start, end; + get_buffer()->get_selection_bounds(start, end); + Glib::ustring selection; + selection.reserve(end.get_offset() - start.get_offset()); + for(auto iter = start; iter < end; ++iter) { + if(iter.starts_line() && *iter == '@') { + selection = get_buffer()->get_text(start, end); + break; + } + if(!(iter.starts_line() && (*iter == '-' || *iter == '+'))) + selection += *iter; + } + Gtk::Clipboard::get()->set_text(selection); + get_buffer()->erase(start, end); + } + else + get_buffer()->cut_clipboard(Gtk::Clipboard::get()); + keep_clipboard = true; +} + +void Source::SearchView::cut_lines() { + if(!get_editable()) + return copy_lines(); + + disable_spellcheck = true; + ScopeGuard guard{[this] { + disable_spellcheck = false; + }}; + + Gtk::TextIter start, end; + get_buffer()->get_selection_bounds(start, end); + start = get_buffer()->get_iter_at_line(start.get_line()); + + if(!end.ends_line()) + end.forward_to_line_end(); + end.forward_char(); + + if(language && language->get_id() == "diff") { + Glib::ustring selection; + selection.reserve(end.get_offset() - start.get_offset()); + for(auto iter = start; iter < end; ++iter) { + if(iter.starts_line() && *iter == '@') { + selection = get_buffer()->get_text(start, end); + break; + } + if(!(iter.starts_line() && (*iter == '-' || *iter == '+'))) + selection += *iter; + } + if(keep_clipboard) + Gtk::Clipboard::get()->set_text(Gtk::Clipboard::get()->wait_for_text() + selection); + else + Gtk::Clipboard::get()->set_text(selection); + } + else { + if(keep_clipboard) + Gtk::Clipboard::get()->set_text(Gtk::Clipboard::get()->wait_for_text() + get_buffer()->get_text(start, end)); + else + Gtk::Clipboard::get()->set_text(get_buffer()->get_text(start, end)); + } + get_buffer()->erase(start, end); + keep_clipboard = true; +} + +void Source::SearchView::copy() { + if(!get_buffer()->get_has_selection()) + copy_lines(); + else if(language && language->get_id() == "diff") { + Gtk::TextIter start, end; + get_buffer()->get_selection_bounds(start, end); + Glib::ustring selection; + selection.reserve(end.get_offset() - start.get_offset()); + for(auto iter = start; iter < end; ++iter) { + if(iter.starts_line() && *iter == '@') { + selection = get_buffer()->get_text(start, end); + break; + } + if(!(iter.starts_line() && (*iter == '-' || *iter == '+'))) + selection += *iter; + } + Gtk::Clipboard::get()->set_text(selection); + } + else + get_buffer()->copy_clipboard(Gtk::Clipboard::get()); +} + +void Source::SearchView::copy_lines() { + Gtk::TextIter start, end; + get_buffer()->get_selection_bounds(start, end); + start = get_buffer()->get_iter_at_line(start.get_line()); + + if(!end.ends_line()) + end.forward_to_line_end(); + end.forward_char(); + + if(language && language->get_id() == "diff") { + Glib::ustring selection; + selection.reserve(end.get_offset() - start.get_offset()); + for(auto iter = start; iter < end; ++iter) { + if(iter.starts_line() && *iter == '@') { + selection = get_buffer()->get_text(start, end); + break; + } + if(!(iter.starts_line() && (*iter == '-' || *iter == '+'))) + selection += *iter; + } + Gtk::Clipboard::get()->set_text(selection); + } + else + Gtk::Clipboard::get()->set_text(get_buffer()->get_text(start, end)); +} + +Source::BaseView::BaseView(const boost::filesystem::path &file_path, const Glib::RefPtr &language) : SearchView(language), file_path(file_path), status_diagnostics(0, 0, 0) { get_style_context()->add_class("juci_source_view"); load(true); @@ -766,35 +889,17 @@ void Source::BaseView::cleanup_whitespace_characters(const Gtk::TextIter &iter) get_buffer()->erase(start_blank_iter, end_blank_iter); } -void Source::BaseView::cut() { - if(!get_buffer()->get_has_selection()) - cut_line(); - else - get_buffer()->cut_clipboard(Gtk::Clipboard::get()); - keep_clipboard = true; -} - -void Source::BaseView::cut_line() { - Gtk::TextIter start, end; - get_buffer()->get_selection_bounds(start, end); - start = get_buffer()->get_iter_at_line(start.get_line()); - if(!end.ends_line()) - end.forward_to_line_end(); - end.forward_char(); - if(keep_clipboard) - Gtk::Clipboard::get()->set_text(Gtk::Clipboard::get()->wait_for_text() + get_buffer()->get_text(start, end)); - else - Gtk::Clipboard::get()->set_text(get_buffer()->get_text(start, end)); - get_buffer()->erase(start, end); - keep_clipboard = true; -} - void Source::BaseView::paste() { + disable_spellcheck = true; + ScopeGuard spellcheck_guard{[this] { + disable_spellcheck = false; + }}; + if(CompletionDialog::get()) CompletionDialog::get()->hide(); enable_multiple_cursors = true; - ScopeGuard guard{[this] { + ScopeGuard multiple_cursors_guard{[this] { enable_multiple_cursors = false; }}; diff --git a/src/source_base.hpp b/src/source_base.hpp index 5dfa9d5..0d24a03 100644 --- a/src/source_base.hpp +++ b/src/source_base.hpp @@ -29,7 +29,7 @@ namespace Source { class SearchView : public Gsv::View { public: - SearchView(); + SearchView(const Glib::RefPtr &language = {}); ~SearchView() override; void search_highlight(const std::string &text, bool case_sensitive, bool regex); void search_forward(); @@ -38,6 +38,18 @@ namespace Source { void replace_backward(const std::string &replacement); void replace_all(const std::string &replacement); + Glib::RefPtr language; + + protected: + bool keep_clipboard = false; + + public: + void cut(); + void cut_lines(); + void copy(); + void copy_lines(); + bool disable_spellcheck = false; + std::function update_search_occurrences; protected: @@ -55,8 +67,6 @@ namespace Source { ~BaseView() override; boost::filesystem::path file_path; - Glib::RefPtr language; - bool load(bool not_undoable_action = false); /// Set new text more optimally and without unnecessary scrolling void replace_text(const std::string &new_text); @@ -102,19 +112,12 @@ namespace Source { std::function update_status_branch; std::string status_branch; - void cut(); - void cut_line(); void paste(); std::string get_selected_text(); - bool disable_spellcheck = false; - void set_snippets(); - private: - bool keep_clipboard = false; - protected: boost::optional last_write_time; void monitor_file(); diff --git a/src/window.cpp b/src/window.cpp index e80c66b..f805405 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -632,15 +632,8 @@ void Window::set_menu_actions() { else entry->cut_clipboard(); } - else if(auto view = dynamic_cast(widget)) { - if(!view->get_editable()) - return; - if(auto source_view = dynamic_cast(view)) { - source_view->disable_spellcheck = true; - source_view->cut(); - source_view->disable_spellcheck = false; - } - } + else if(auto view = dynamic_cast(widget)) + view->cut(); }); menu.add_action("edit_cut_lines", [this]() { // Return if a shown tooltip has selected text @@ -655,15 +648,8 @@ void Window::set_menu_actions() { Gtk::Clipboard::get()->set_text(entry->get_text()); entry->set_text(""); } - else if(auto view = dynamic_cast(widget)) { - if(!view->get_editable()) - return; - if(auto source_view = dynamic_cast(view)) { - source_view->disable_spellcheck = true; - source_view->cut_line(); - source_view->disable_spellcheck = false; - } - } + else if(auto view = dynamic_cast(widget)) + view->cut_lines(); }); menu.add_action("edit_copy", [this]() { // Copy from a tooltip if it has selected text @@ -683,18 +669,8 @@ void Window::set_menu_actions() { else entry->copy_clipboard(); } - else if(auto view = dynamic_cast(widget)) { - if(!view->get_buffer()->get_has_selection()) { - auto start = view->get_buffer()->get_iter_at_line(view->get_buffer()->get_insert()->get_iter().get_line()); - auto end = start; - if(!end.ends_line()) - end.forward_to_line_end(); - end.forward_char(); - Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end)); - } - else - view->get_buffer()->copy_clipboard(Gtk::Clipboard::get()); - } + else if(auto view = dynamic_cast(widget)) + view->copy(); }); menu.add_action("edit_copy_lines", [this]() { // Copy from a tooltip if it has selected text @@ -715,15 +691,8 @@ void Window::set_menu_actions() { auto widget = get_focus(); if(auto entry = dynamic_cast(widget)) Gtk::Clipboard::get()->set_text(entry->get_text()); - else if(auto view = dynamic_cast(widget)) { - Gtk::TextIter start, end; - view->get_buffer()->get_selection_bounds(start, end); - start = view->get_buffer()->get_iter_at_line(start.get_line()); - if(!end.ends_line()) - end.forward_to_line_end(); - end.forward_char(); - Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end)); - } + else if(auto view = dynamic_cast(widget)) + view->copy_lines(); }); menu.add_action("edit_paste", [this]() { auto widget = get_focus(); @@ -731,9 +700,7 @@ void Window::set_menu_actions() { entry->paste_clipboard(); else if(auto view = dynamic_cast(widget)) { if(auto source_view = dynamic_cast(view)) { - source_view->disable_spellcheck = true; source_view->paste(); - source_view->disable_spellcheck = false; source_view->hide_tooltips(); } else if(auto terminal = dynamic_cast(view)) {