70 lines
2.1 KiB
C++
70 lines
2.1 KiB
C++
#include "everything.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, file, &content);
|
|
|
|
// All complete lines in between
|
|
for(count_type r = end.r-1; r > start.r; --r)
|
|
func(r, file, &content);
|
|
|
|
// First line end
|
|
string start_line = file->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, file, &content);
|
|
}
|
|
// Copying selection
|
|
void Selection::copy_selection(position p) {
|
|
apply_on_selection(p,
|
|
[](count_type r, Treap *file, Treap *sel){ sel->insert(0, file->get_line(r, false)); },
|
|
[](count_type r, count_type start_c, count_type size, Treap *file, Treap *sel) { sel->insert(0, file->get_line(r, false).substr(start_c - file->get_tab_offset({r, start_c}), size)); }
|
|
);
|
|
}
|
|
// Removing selection
|
|
count_type Selection::remove_selection(position p) {
|
|
apply_on_selection(p,
|
|
[](count_type r, Treap *file, Treap *sel){ file->remove(r); },
|
|
[](count_type r, count_type start_c, count_type size, Treap *file, Treap *sel) { file->remove({r, start_c-file->get_tab_offset({r, start_c})}, size); }
|
|
);
|
|
|
|
count_type min = p.r, max = pos.r;
|
|
if(min > max)
|
|
min = pos.r, max = p.r;
|
|
|
|
if(max > min) {
|
|
file->merge_line(min+1, false);
|
|
return max - min + 2;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
// Pasting selection
|
|
count_type Selection::paste_selection(position p) {
|
|
if(content.size() == 0) return 0;
|
|
|
|
// Insert last line inside of this
|
|
file->insert(p, content.get_line(content.size()-1, false));
|
|
if(content.size() == 1) return 1;
|
|
|
|
// Insert first line in front and split
|
|
file->split_line(p, false);
|
|
file->insert(p, content.get_line(0, false));
|
|
if(content.size() == 2) return 4;
|
|
|
|
// Insert lines
|
|
for(count_type i = content.size()-2; i > 0; --i)
|
|
file->insert(p.r+1, content.get_line(i, false));
|
|
|
|
return content.size()+2;
|
|
}
|