Browse Source

Cleanup of cursor history

pipelines/235045657
eidheim 6 years ago
parent
commit
c65261d5ff
  1. 130
      src/notebook.cpp
  2. 6
      src/notebook.hpp
  3. 2
      src/source_base.cpp
  4. 60
      src/window.cpp

130
src/notebook.cpp

@ -320,75 +320,89 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position
}; };
view->update_tab_label(view); view->update_tab_label(view);
//Add star on tab label when the page is not saved: // Add star on tab label when the page is not saved:
view->get_buffer()->signal_modified_changed().connect([view]() { view->get_buffer()->signal_modified_changed().connect([view]() {
if(view->update_tab_label) if(view->update_tab_label)
view->update_tab_label(view); view->update_tab_label(view);
}); });
//Cursor history // Cursor history
auto update_cursor_locations = [this, view](const Gtk::TextBuffer::iterator &iter) { auto update_cursor_locations = [this, view]() {
bool mark_moved = false; auto iter = view->get_buffer()->get_insert()->get_iter();
if(current_cursor_location != static_cast<size_t>(-1)) {
auto &cursor_location = cursor_locations.at(current_cursor_location); if(current_cursor_location != cursor_locations.end()) {
if(cursor_location.view == view && abs(cursor_location.mark->get_iter().get_line() - iter.get_line()) <= 2) { bool moved = false;
view->get_buffer()->move_mark(cursor_location.mark, iter); if(current_cursor_location->view == view && abs(current_cursor_location->mark->get_iter().get_line() - iter.get_line()) <= 2) {
mark_moved = true; current_cursor_location->view->get_buffer()->move_mark(current_cursor_location->mark, iter); // Move current cursor
} moved = true;
} }
if(!mark_moved) {
if(current_cursor_location != static_cast<size_t>(-1) && current_cursor_location + 1 < cursor_locations.size()) { // Combine cursor histories adjacent and similar to current cursor
for(auto it = cursor_locations.begin() + current_cursor_location + 1; it != cursor_locations.end();) { auto it = std::next(current_cursor_location);
if(it != cursor_locations.end()) {
if(it->view == current_cursor_location->view && abs(it->mark->get_iter().get_line() - current_cursor_location->mark->get_iter().get_line()) <= 2) {
it->view->get_buffer()->delete_mark(it->mark); it->view->get_buffer()->delete_mark(it->mark);
it = cursor_locations.erase(it); cursor_locations.erase(it);
} }
} }
cursor_locations.emplace_back(view, view->get_buffer()->create_mark(iter)); if(current_cursor_location != cursor_locations.begin()) {
current_cursor_location = cursor_locations.size() - 1; it = std::prev(current_cursor_location);
if(it->view == current_cursor_location->view && abs(it->mark->get_iter().get_line() - current_cursor_location->mark->get_iter().get_line()) <= 2) {
it->view->get_buffer()->delete_mark(it->mark);
cursor_locations.erase(it);
}
} }
// Combine adjacent cursor histories that are similar if(moved)
if(cursor_locations.size() > 1) { return;
size_t cursor_locations_index = 1;
auto last_it = cursor_locations.begin(); // Remove history newer than current (create new history branch)
for(auto it = cursor_locations.begin() + 1; it != cursor_locations.end();) { for(auto it = std::next(current_cursor_location); it != cursor_locations.end();) {
if(last_it->view == it->view && abs(last_it->mark->get_iter().get_line() - it->mark->get_iter().get_line()) <= 2) { it->view->get_buffer()->delete_mark(it->mark);
last_it->view->get_buffer()->delete_mark(last_it->mark);
last_it->mark = it->mark;
it = cursor_locations.erase(it); it = cursor_locations.erase(it);
if(current_cursor_location != static_cast<size_t>(-1) && current_cursor_location > cursor_locations_index)
--current_cursor_location;
}
else {
++it;
++last_it;
++cursor_locations_index;
}
} }
} }
current_cursor_location = cursor_locations.emplace(cursor_locations.end(), view, view->get_buffer()->create_mark(iter, false));
// Remove start of cache if cache limit is exceeded if(cursor_locations.size() > 10) {
while(cursor_locations.size() > 10) { auto it = cursor_locations.begin();
cursor_locations.begin()->view->get_buffer()->delete_mark(cursor_locations.begin()->mark); it->view->get_buffer()->delete_mark(it->mark);
cursor_locations.erase(cursor_locations.begin()); cursor_locations.erase(it);
if(current_cursor_location != static_cast<size_t>(-1))
--current_cursor_location;
} }
if(current_cursor_location >= cursor_locations.size())
current_cursor_location = cursor_locations.size() - 1;
}; };
view->get_buffer()->signal_mark_set().connect([this, update_cursor_locations](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) { view->get_buffer()->signal_mark_set().connect([this, update_cursor_locations](const Gtk::TextBuffer::iterator & /*iter*/, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
if(mark->get_name() == "insert") { if(mark->get_name() == "insert") {
if(disable_next_update_cursor_locations) { if(disable_next_update_cursor_locations) {
disable_next_update_cursor_locations = false; disable_next_update_cursor_locations = false;
return; return;
} }
update_cursor_locations(iter); update_cursor_locations();
} }
}); });
view->get_buffer()->signal_changed().connect([view, update_cursor_locations] { view->get_buffer()->signal_changed().connect([this, update_cursor_locations] {
update_cursor_locations(view->get_buffer()->get_insert()->get_iter()); update_cursor_locations();
// Combine adjacent cursor histories that are similar
if(cursor_locations.size() > 1) {
auto prev_it = cursor_locations.begin();
for(auto it = std::next(prev_it); it != cursor_locations.end();) {
if(prev_it->view == it->view && abs(prev_it->mark->get_iter().get_line() - it->mark->get_iter().get_line()) <= 2) {
if(current_cursor_location == it) {
prev_it->view->get_buffer()->delete_mark(prev_it->mark);
cursor_locations.erase(prev_it);
prev_it = it;
++it;
}
else {
it->view->get_buffer()->delete_mark(it->mark);
it = cursor_locations.erase(it);
}
}
else {
++it;
++prev_it;
}
}
}
}); });
#ifdef JUCI_ENABLE_DEBUG #ifdef JUCI_ENABLE_DEBUG
@ -552,21 +566,29 @@ bool Notebook::close(size_t index) {
} }
void Notebook::delete_cursor_locations(Source::View *view) { void Notebook::delete_cursor_locations(Source::View *view) {
size_t cursor_locations_index = 0;
for(auto it = cursor_locations.begin(); it != cursor_locations.end();) { for(auto it = cursor_locations.begin(); it != cursor_locations.end();) {
if(it->view == view) { if(it->view == view) {
view->get_buffer()->delete_mark(it->mark); if(current_cursor_location != cursor_locations.end() && current_cursor_location->view == view)
current_cursor_location = cursor_locations.end();
it->view->get_buffer()->delete_mark(it->mark);
it = cursor_locations.erase(it); it = cursor_locations.erase(it);
if(current_cursor_location != static_cast<size_t>(-1) && current_cursor_location > cursor_locations_index)
--current_cursor_location;
} }
else { else
++it; ++it;
++cursor_locations_index; }
// Update current location
if(current_cursor_location == cursor_locations.end()) {
if(auto current_view = get_current_view()) {
auto iter = current_view->get_buffer()->get_insert()->get_iter();
for(auto it = cursor_locations.begin(); it != cursor_locations.end(); ++it) {
if(it->view == current_view && it->mark->get_iter() == iter) {
current_cursor_location = it;
break;
}
}
} }
} }
if(current_cursor_location >= cursor_locations.size())
current_cursor_location = cursor_locations.size() - 1;
} }
bool Notebook::close_current() { bool Notebook::close_current() {

6
src/notebook.hpp

@ -2,9 +2,11 @@
#include "source.hpp" #include "source.hpp"
#include <gtkmm.h> #include <gtkmm.h>
#include <iostream> #include <iostream>
#include <list>
#include <map> #include <map>
#include <sigc++/sigc++.h> #include <sigc++/sigc++.h>
#include <type_traits> #include <type_traits>
#include <vector>
class Notebook : public Gtk::Paned { class Notebook : public Gtk::Paned {
class TabLabel : public Gtk::EventBox { class TabLabel : public Gtk::EventBox {
@ -62,8 +64,8 @@ public:
std::function<void(Source::View *)> on_close_page; std::function<void(Source::View *)> on_close_page;
/// Cursor history /// Cursor history
std::vector<CursorLocation> cursor_locations; std::list<CursorLocation> cursor_locations;
size_t current_cursor_location = -1; std::list<CursorLocation>::iterator current_cursor_location = cursor_locations.end();
bool disable_next_update_cursor_locations = false; bool disable_next_update_cursor_locations = false;
void delete_cursor_locations(Source::View *view); void delete_cursor_locations(Source::View *view);

2
src/source_base.cpp

@ -1273,7 +1273,7 @@ bool Source::BaseView::select_snippet_parameter() {
auto start = snippet_parameter.start->get_iter(); auto start = snippet_parameter.start->get_iter();
auto end = snippet_parameter.end->get_iter(); auto end = snippet_parameter.end->get_iter();
if(first) { if(first) {
if(snippet_parameter.size > 0 && end.get_offset() - start.get_offset() == 0) { // If the parameter has been erased if(snippet_parameter.size > 0 && start == end) { // If the parameter has been erased
snippet_parameters_list.erase(snippet_parameters_it); snippet_parameters_list.erase(snippet_parameters_it);
return select_snippet_parameter(); return select_snippet_parameter();
} }

60
src/window.cpp

@ -773,46 +773,54 @@ void Window::set_menu_actions() {
view->scroll_to_cursor_delayed(true, false); view->scroll_to_cursor_delayed(true, false);
}); });
menu.add_action("source_cursor_history_back", []() { menu.add_action("source_cursor_history_back", []() {
if(Notebook::get().cursor_locations.size() == 0) auto &current_cursor_location = Notebook::get().current_cursor_location;
if(current_cursor_location == Notebook::get().cursor_locations.end())
return; return;
if(Notebook::get().current_cursor_location == static_cast<size_t>(-1))
Notebook::get().current_cursor_location = Notebook::get().cursor_locations.size() - 1;
auto cursor_location = &Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location); if(current_cursor_location->view != Notebook::get().get_current_view()) {
// Move to current position if current position's view is not current view // Move to current position if current position's view is not current view
// (in case one is looking at a new file but has not yet placed the cursor within the file) // (for instance, in case one is looking at a new file but has not yet placed the cursor within the file)
if(cursor_location->view != Notebook::get().get_current_view()) if(!Notebook::get().open(current_cursor_location->view->file_path))
Notebook::get().open(cursor_location->view->file_path);
else {
if(Notebook::get().cursor_locations.size() <= 1)
return; return;
if(Notebook::get().current_cursor_location == 0) }
else {
if(current_cursor_location == Notebook::get().cursor_locations.begin())
return; return;
--Notebook::get().current_cursor_location; --current_cursor_location;
cursor_location = &Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location); if(current_cursor_location->view != Notebook::get().get_current_view()) {
if(Notebook::get().get_current_view() != cursor_location->view) if(!Notebook::get().open(current_cursor_location->view->file_path))
Notebook::get().open(cursor_location->view->file_path); return;
}
} }
Notebook::get().disable_next_update_cursor_locations = true; Notebook::get().disable_next_update_cursor_locations = true;
cursor_location->view->get_buffer()->place_cursor(cursor_location->mark->get_iter()); current_cursor_location->view->get_buffer()->place_cursor(current_cursor_location->mark->get_iter());
cursor_location->view->scroll_to_cursor_delayed(true, false); current_cursor_location->view->scroll_to_cursor_delayed(true, false);
}); });
menu.add_action("source_cursor_history_forward", []() { menu.add_action("source_cursor_history_forward", []() {
if(Notebook::get().cursor_locations.size() <= 1) auto &current_cursor_location = Notebook::get().current_cursor_location;
if(current_cursor_location == Notebook::get().cursor_locations.end())
return; return;
if(Notebook::get().current_cursor_location == static_cast<size_t>(-1))
Notebook::get().current_cursor_location = Notebook::get().cursor_locations.size() - 1; if(current_cursor_location->view != Notebook::get().get_current_view()) {
if(Notebook::get().current_cursor_location == Notebook::get().cursor_locations.size() - 1) // Move to current position if current position's view is not current view
// (for instance, in case one is looking at a new file but has not yet placed the cursor within the file)
if(!Notebook::get().open(current_cursor_location->view->file_path))
return;
}
else {
if(std::next(current_cursor_location) == Notebook::get().cursor_locations.end())
return; return;
++Notebook::get().current_cursor_location; ++current_cursor_location;
auto &cursor_location = Notebook::get().cursor_locations.at(Notebook::get().current_cursor_location); if(current_cursor_location->view != Notebook::get().get_current_view()) {
if(Notebook::get().get_current_view() != cursor_location.view) if(!Notebook::get().open(current_cursor_location->view->file_path))
Notebook::get().open(cursor_location.view->file_path); return;
}
}
Notebook::get().disable_next_update_cursor_locations = true; Notebook::get().disable_next_update_cursor_locations = true;
cursor_location.view->get_buffer()->place_cursor(cursor_location.mark->get_iter()); current_cursor_location->view->get_buffer()->place_cursor(current_cursor_location->mark->get_iter());
cursor_location.view->scroll_to_cursor_delayed(true, false); current_cursor_location->view->scroll_to_cursor_delayed(true, false);
}); });
menu.add_action("source_show_completion", [] { menu.add_action("source_show_completion", [] {

Loading…
Cancel
Save