blob: 5ddc67c145910d952bad6cfe7b54d2858ca751d1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#include "selection.h"
#include "editor.h"
#include "util/unicode.h"
static bool include_cursor_char_in_selection(const View *view)
{
const EditorState *e = view->window->editor;
if (!e->options.select_cursor_char) {
return false;
}
bool overwrite = view->buffer->options.overwrite;
CursorInputMode mode = overwrite ? CURSOR_MODE_OVERWRITE : CURSOR_MODE_INSERT;
TermCursorType type = e->cursor_styles[mode].type;
if (type == CURSOR_KEEP) {
type = e->cursor_styles[CURSOR_MODE_DEFAULT].type;
}
// If "select-cursor-char" option is true, include character under cursor
// in selections for any cursor type except bars (where it makes no sense
// to do so)
return !(type == CURSOR_STEADY_BAR || type == CURSOR_BLINKING_BAR);
}
void init_selection(const View *view, SelectionInfo *info)
{
info->so = view->sel_so;
info->eo = block_iter_get_offset(&view->cursor);
info->si = view->cursor;
block_iter_goto_offset(&info->si, info->so);
info->swapped = false;
if (info->so > info->eo) {
size_t o = info->so;
info->so = info->eo;
info->eo = o;
info->si = view->cursor;
info->swapped = true;
}
BlockIter ei = info->si;
block_iter_skip_bytes(&ei, info->eo - info->so);
if (block_iter_is_eof(&ei)) {
if (info->so == info->eo) {
return;
}
CodePoint u;
info->eo -= block_iter_prev_char(&ei, &u);
}
if (view->selection == SELECT_LINES) {
info->so -= block_iter_bol(&info->si);
info->eo += block_iter_eat_line(&ei);
} else {
if (include_cursor_char_in_selection(view)) {
info->eo += block_iter_next_column(&ei);
}
}
}
size_t prepare_selection(View *view)
{
SelectionInfo info;
init_selection(view, &info);
view->cursor = info.si;
return info.eo - info.so;
}
char *view_get_selection(View *view, size_t *size)
{
if (view->selection == SELECT_NONE) {
*size = 0;
return NULL;
}
BlockIter save = view->cursor;
*size = prepare_selection(view);
char *buf = block_iter_get_bytes(&view->cursor, *size);
view->cursor = save;
return buf;
}
size_t get_nr_selected_lines(const SelectionInfo *info)
{
BlockIter bi = info->si;
size_t pos = info->so;
CodePoint u = 0;
size_t nr_lines = 1;
while (pos < info->eo) {
if (u == '\n') {
nr_lines++;
}
pos += block_iter_next_char(&bi, &u);
}
return nr_lines;
}
size_t get_nr_selected_chars(const SelectionInfo *info)
{
BlockIter bi = info->si;
size_t pos = info->so;
CodePoint u;
size_t nr_chars = 0;
while (pos < info->eo) {
nr_chars++;
pos += block_iter_next_char(&bi, &u);
}
return nr_chars;
}
|