forked from martanne/vis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvis-text-objects.c
130 lines (114 loc) · 5.04 KB
/
vis-text-objects.c
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "vis-core.h"
#include "text-objects.h"
#include "util.h"
int vis_textobject_register(Vis *vis, int type, void *data,
Filerange (*textobject)(Vis*, Win*, void*, size_t pos)) {
TextObject *obj = calloc(1, sizeof *obj);
if (!obj)
return -1;
obj->user = textobject;
obj->type = type;
obj->data = data;
if (array_add_ptr(&vis->textobjects, obj))
return LENGTH(vis_textobjects) + array_length(&vis->textobjects) - 1;
free(obj);
return -1;
}
bool vis_textobject(Vis *vis, enum VisTextObject id) {
if (id < LENGTH(vis_textobjects))
vis->action.textobj = &vis_textobjects[id];
else
vis->action.textobj = array_get_ptr(&vis->textobjects, id - LENGTH(vis_textobjects));
if (!vis->action.textobj)
return false;
vis_do(vis);
return true;
}
static Filerange search_forward(Vis *vis, Text *txt, size_t pos) {
Filerange range = text_range_empty();
Regex *regex = vis_regex(vis, NULL);
if (regex)
range = text_object_search_forward(txt, pos, regex);
text_regex_free(regex);
return range;
}
static Filerange search_backward(Vis *vis, Text *txt, size_t pos) {
Filerange range = text_range_empty();
Regex *regex = vis_regex(vis, NULL);
if (regex)
range = text_object_search_backward(txt, pos, regex);
text_regex_free(regex);
return range;
}
static Filerange object_unpaired(Text *txt, size_t pos, char obj) {
char c;
bool before = false;
Iterator it = text_iterator_get(txt, pos), rit = it;
while (text_iterator_byte_get(&rit, &c) && c != '\n') {
if (c == obj) {
before = true;
break;
}
text_iterator_byte_prev(&rit, NULL);
}
/* if there is no previous occurence on the same line, advance starting position */
if (!before) {
while (text_iterator_byte_get(&it, &c) && c != '\n') {
if (c == obj) {
pos = it.pos;
break;
}
text_iterator_byte_next(&it, NULL);
}
}
switch (obj) {
case '"':
return text_object_quote(txt, pos);
case '\'':
return text_object_single_quote(txt, pos);
case '`':
return text_object_backtick(txt, pos);
default:
return text_range_empty();
}
}
static Filerange object_quote(Text *txt, size_t pos) {
return object_unpaired(txt, pos, '"');
}
static Filerange object_single_quote(Text *txt, size_t pos) {
return object_unpaired(txt, pos, '\'');
}
static Filerange object_backtick(Text *txt, size_t pos) {
return object_unpaired(txt, pos, '`');
}
const TextObject vis_textobjects[] = {
[VIS_TEXTOBJECT_INNER_WORD] = { .txt = text_object_word },
[VIS_TEXTOBJECT_OUTER_WORD] = { .txt = text_object_word_outer },
[VIS_TEXTOBJECT_INNER_LONGWORD] = { .txt = text_object_longword },
[VIS_TEXTOBJECT_OUTER_LONGWORD] = { .txt = text_object_longword_outer },
[VIS_TEXTOBJECT_SENTENCE] = { .txt = text_object_sentence },
[VIS_TEXTOBJECT_PARAGRAPH] = { .txt = text_object_paragraph },
[VIS_TEXTOBJECT_OUTER_SQUARE_BRACKET] = { .txt = text_object_square_bracket, .type = OUTER },
[VIS_TEXTOBJECT_INNER_SQUARE_BRACKET] = { .txt = text_object_square_bracket, .type = INNER },
[VIS_TEXTOBJECT_OUTER_CURLY_BRACKET] = { .txt = text_object_curly_bracket, .type = OUTER },
[VIS_TEXTOBJECT_INNER_CURLY_BRACKET] = { .txt = text_object_curly_bracket, .type = INNER },
[VIS_TEXTOBJECT_OUTER_ANGLE_BRACKET] = { .txt = text_object_angle_bracket, .type = OUTER },
[VIS_TEXTOBJECT_INNER_ANGLE_BRACKET] = { .txt = text_object_angle_bracket, .type = INNER },
[VIS_TEXTOBJECT_OUTER_PARANTHESE] = { .txt = text_object_paranthese, .type = OUTER },
[VIS_TEXTOBJECT_INNER_PARANTHESE] = { .txt = text_object_paranthese, .type = INNER },
[VIS_TEXTOBJECT_OUTER_QUOTE] = { .txt = object_quote, .type = OUTER },
[VIS_TEXTOBJECT_INNER_QUOTE] = { .txt = object_quote, .type = INNER },
[VIS_TEXTOBJECT_OUTER_SINGLE_QUOTE] = { .txt = object_single_quote, .type = OUTER },
[VIS_TEXTOBJECT_INNER_SINGLE_QUOTE] = { .txt = object_single_quote, .type = INNER },
[VIS_TEXTOBJECT_OUTER_BACKTICK] = { .txt = object_backtick, .type = OUTER },
[VIS_TEXTOBJECT_INNER_BACKTICK] = { .txt = object_backtick, .type = INNER },
[VIS_TEXTOBJECT_OUTER_ENTIRE] = { .txt = text_object_entire, },
[VIS_TEXTOBJECT_INNER_ENTIRE] = { .txt = text_object_entire_inner, },
[VIS_TEXTOBJECT_OUTER_FUNCTION] = { .txt = text_object_function, },
[VIS_TEXTOBJECT_INNER_FUNCTION] = { .txt = text_object_function_inner, },
[VIS_TEXTOBJECT_OUTER_LINE] = { .txt = text_object_line, },
[VIS_TEXTOBJECT_INNER_LINE] = { .txt = text_object_line_inner, },
[VIS_TEXTOBJECT_INDENTATION] = { .txt = text_object_indentation, },
[VIS_TEXTOBJECT_SEARCH_FORWARD] = { .vis = search_forward, .type = SPLIT },
[VIS_TEXTOBJECT_SEARCH_BACKWARD] = { .vis = search_backward, .type = SPLIT },
};