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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
/*
4coder_scope_commands.cpp - A set of commands and helpers relevant for scope level navigation and editing.
*/
// TOP
function void
select_next_scope_after_pos(Application_Links *app, View_ID view, Buffer_ID buffer,
i64 pos){
Find_Nest_Flag flags = FindNest_Scope;
Range_i64 range = {};
if (find_nest_side(app, buffer, pos + 1, flags, Scan_Forward, NestDelim_Open,
&range) &&
find_nest_side(app, buffer, range.end,
flags|FindNest_Balanced|FindNest_EndOfToken, Scan_Forward,
NestDelim_Close, &range.end)){
select_scope(app, view, range);
}
}
function b32
range_is_scope_selection(Application_Links *app, Buffer_ID buffer, Range_i64 range){
return (buffer_get_char(app, buffer, range.min) == '{' &&
buffer_get_char(app, buffer, range.max - 1) == '}');
}
CUSTOM_COMMAND_SIG(select_surrounding_scope)
CUSTOM_DOC("Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.")
{
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible);
i64 pos = view_get_cursor_pos(app, view);
Range_i64 range = {};
if (find_surrounding_nest(app, buffer, pos, FindNest_Scope, &range)){
select_scope(app, view, range);
}
}
CUSTOM_COMMAND_SIG(select_surrounding_scope_maximal)
CUSTOM_DOC("Selects the top-most scope that surrounds the cursor.")
{
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible);
i64 pos = view_get_cursor_pos(app, view);
Range_i64 range = {};
if (find_surrounding_nest(app, buffer, pos, FindNest_Scope, &range)){
for (;;){
pos = range.min;
if (!find_surrounding_nest(app, buffer, pos, FindNest_Scope, &range)){
break;
}
}
select_scope(app, view, range);
}
}
CUSTOM_COMMAND_SIG(select_next_scope_absolute)
CUSTOM_DOC("Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.")
{
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible);
i64 pos = view_get_cursor_pos(app, view);
select_next_scope_after_pos(app, view, buffer, pos);
}
CUSTOM_COMMAND_SIG(select_next_scope_after_current)
CUSTOM_DOC("If a scope is selected, find first scope that starts after the selected scope. Otherwise find the first scope that starts after the cursor.")
{
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible);
i64 cursor_pos = view_get_cursor_pos(app, view);
i64 mark_pos = view_get_mark_pos(app, view);
Range_i64 range = Ii64(cursor_pos, mark_pos);
if (range_is_scope_selection(app, buffer, range)){
select_next_scope_after_pos(app, view, buffer, range.max);
}
else{
select_next_scope_after_pos(app, view, buffer, cursor_pos);
}
}
CUSTOM_COMMAND_SIG(select_prev_scope_absolute)
CUSTOM_DOC("Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.")
{
View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible);
i64 pos = view_get_cursor_pos(app, view);
Find_Nest_Flag flags = FindNest_Scope;
Range_i64 range = {};
if (find_nest_side(app, buffer, pos - 1,
flags, Scan_Backward, NestDelim_Open, &range) &&
find_nest_side(app, buffer, range.end,
flags|FindNest_Balanced|FindNest_EndOfToken, Scan_Forward,
NestDelim_Close, &range.end)){
select_scope(app, view, range);
}
}
CUSTOM_COMMAND_SIG(select_prev_top_most_scope)
CUSTOM_DOC("Finds the first scope that starts before the cursor, then finds the top most scope that contains that scope.")
{
select_prev_scope_absolute(app);
select_surrounding_scope_maximal(app);
}
CUSTOM_COMMAND_SIG(place_in_scope)
CUSTOM_DOC("Wraps the code contained in the range between cursor and mark with a new curly brace scope.")
{
place_begin_and_end_on_own_lines(app, "{", "}");
}
CUSTOM_COMMAND_SIG(delete_current_scope)
CUSTOM_DOC("Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.")
{
View_ID view = get_active_view(app, Access_ReadWriteVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
Range_i64 range = get_view_range(app, view);
if (range_is_scope_selection(app, buffer, range)){
i32 top_len = 1;
i32 bot_len = 1;
if (buffer_get_char(app, buffer, range.min - 1) == '\n'){
top_len = 2;
}
if (buffer_get_char(app, buffer, range.max + 1) == '\n'){
bot_len = 2;
}
Batch_Edit batch_first = {};
Batch_Edit batch_last = {};
batch_first.edit.text = SCu8();
batch_first.edit.range = Ii64(range.min + 1 - top_len, range.min + 1);
batch_first.next = &batch_last;
batch_last.edit.text = SCu8();
batch_last.edit.range = Ii64((i32)(range.max - 1), (i32)(range.max - 1 + bot_len));
buffer_batch_edit(app, buffer, &batch_first);
}
}
// BOTTOM
|