zeed/selection.cpp

57 lines
1.6 KiB
C++

#include "editor.hpp"
// Selection manipulation
template <typename F, typename G>
void Selection::apply_on_selection(position p, F func, G func2) {
// Determine first and last selected position
position start = p, end = pos;
if(pos.r < p.r || (pos.r == p.r && pos.c < p.c))
start = pos, end = p;
// Clear previous selection
content.clear();
// Last line start
if(start.r < end.r)
func2(end.r, 0, end.c+1, &content);
// All complete lines in between
for(count_type r = end.r-1; r > start.r; --r)
func(r, &content);
// First line end
string start_line = get_line(start.r);
count_type size = ((start.r == end.r) ? end.c+1 : start_line.size()) - start.c;
func2(start.r, start.c, size, &content);
}
// Removing selection
void Selection::remove_selection(position p) {
apply_on_selection(p,
[](count_type r, treap* sel){ remove(r); },
[](count_type r, count_type start_c, count_type size, treap* sel) { remove({r, start_c}, size); }
);
}
// Copying selection
void Selection::copy_selection(position p) {
apply_on_selection(p,
[](count_type r, treap* sel){ sel->insert(0, get_line(r)); },
[](count_type r, count_type start_c, count_type size, treap* sel) { sel->insert(0, get_line(r).substr(start_c, size)); }
);
}
// Pasting selection
void Selection::paste_selection(position p) {
if(content.size() == 0) return;
// Insert last line inside of this
insert(p, content.get(content.size()-1));
if(content.size() == 1) return;
// Insert first line in front and split
split_line(p);
insert(p, content.get(0));
if(content.size() == 2) return;
// Insert lines
for(count_type i = content.size()-2; i > 0; --i)
new_line(p.r, content.get(i));
}