1 /*
2 * Copyright 2018 Jiri Techet <techet@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "cmds/txtobjs.h"
20
21
find_upper_level_brace(ScintillaObject * sci,gint pos,gint open_brace,gint close_brace)22 static gint find_upper_level_brace(ScintillaObject *sci, gint pos, gint open_brace, gint close_brace)
23 {
24 while (pos > 0)
25 {
26 pos = PREV(sci, pos);
27 gchar c = SSM(sci, SCI_GETCHARAT, pos, 0);
28
29 if (c == open_brace)
30 return pos;
31 else if (c == close_brace)
32 {
33 pos = SSM(sci, SCI_BRACEMATCH, pos, 0);
34 if (pos < 0)
35 break;
36 }
37 }
38 return -1;
39 }
40
41
find_char(ScintillaObject * sci,gint pos,gint ch,gboolean forward)42 static gint find_char(ScintillaObject *sci, gint pos, gint ch, gboolean forward)
43 {
44 while (pos > 0)
45 {
46 gint last_pos = pos;
47 gchar c;
48
49 pos = forward ? NEXT(sci, pos) : PREV(sci, pos);
50 c = SSM(sci, SCI_GETCHARAT, pos, 0);
51
52 if (c == ch)
53 return pos;
54 if (pos == last_pos)
55 break;
56 }
57 return -1;
58 }
59
60
select_brace(CmdContext * c,CmdParams * p,gint open_brace,gint close_brace,gboolean inner)61 static void select_brace(CmdContext *c, CmdParams *p, gint open_brace, gint close_brace, gboolean inner)
62 {
63 gint pos = p->pos;
64 gint start_pos = 0;
65 gint end_pos = 0;
66 gint i;
67
68 for (i = 0; i < p->num; i++)
69 {
70 if (open_brace == close_brace)
71 {
72 start_pos = find_char(p->sci, pos, open_brace, FALSE);
73 if (start_pos < 0)
74 return;
75 end_pos = find_char(p->sci, pos, close_brace, TRUE);
76 }
77 else
78 {
79 start_pos = find_upper_level_brace(p->sci, pos, open_brace, close_brace);
80 if (start_pos < 0)
81 return;
82 end_pos = SSM(p->sci, SCI_BRACEMATCH, start_pos, 0);
83 }
84
85 if (end_pos < 0)
86 return;
87
88 pos = start_pos;
89 }
90
91 if (inner)
92 start_pos = NEXT(p->sci, start_pos);
93 else
94 end_pos = NEXT(p->sci, end_pos);
95
96 if (VI_IS_VISUAL(vi_get_mode()))
97 {
98 c->sel_anchor = start_pos;
99 SET_POS(p->sci, end_pos, TRUE);
100 }
101 else
102 {
103 p->sel_start = start_pos;
104 p->sel_len = end_pos - start_pos;
105 }
106 }
107
108
cmd_select_quotedbl(CmdContext * c,CmdParams * p)109 void cmd_select_quotedbl(CmdContext *c, CmdParams *p)
110 {
111 select_brace(c, p, '\"', '\"', FALSE);
112 }
113
114
cmd_select_quoteleft(CmdContext * c,CmdParams * p)115 void cmd_select_quoteleft(CmdContext *c, CmdParams *p)
116 {
117 select_brace(c, p, '`', '`', FALSE);
118 }
119
120
cmd_select_apostrophe(CmdContext * c,CmdParams * p)121 void cmd_select_apostrophe(CmdContext *c, CmdParams *p)
122 {
123 select_brace(c, p, '\'', '\'', FALSE);
124 }
125
126
cmd_select_brace(CmdContext * c,CmdParams * p)127 void cmd_select_brace(CmdContext *c, CmdParams *p)
128 {
129 select_brace(c, p, '{', '}', FALSE);
130 }
131
132
cmd_select_paren(CmdContext * c,CmdParams * p)133 void cmd_select_paren(CmdContext *c, CmdParams *p)
134 {
135 select_brace(c, p, '(', ')', FALSE);
136 }
137
138
cmd_select_less(CmdContext * c,CmdParams * p)139 void cmd_select_less(CmdContext *c, CmdParams *p)
140 {
141 select_brace(c, p, '<', '>', FALSE);
142 }
143
144
cmd_select_bracket(CmdContext * c,CmdParams * p)145 void cmd_select_bracket(CmdContext *c, CmdParams *p)
146 {
147 select_brace(c, p, '[', ']', FALSE);
148 }
149
150
cmd_select_quotedbl_inner(CmdContext * c,CmdParams * p)151 void cmd_select_quotedbl_inner(CmdContext *c, CmdParams *p)
152 {
153 select_brace(c, p, '\"', '\"', TRUE);
154 }
155
156
cmd_select_quoteleft_inner(CmdContext * c,CmdParams * p)157 void cmd_select_quoteleft_inner(CmdContext *c, CmdParams *p)
158 {
159 select_brace(c, p, '`', '`', TRUE);
160 }
161
162
cmd_select_apostrophe_inner(CmdContext * c,CmdParams * p)163 void cmd_select_apostrophe_inner(CmdContext *c, CmdParams *p)
164 {
165 select_brace(c, p, '\'', '\'', TRUE);
166 }
167
168
cmd_select_brace_inner(CmdContext * c,CmdParams * p)169 void cmd_select_brace_inner(CmdContext *c, CmdParams *p)
170 {
171 select_brace(c, p, '{', '}', TRUE);
172 }
173
174
cmd_select_paren_inner(CmdContext * c,CmdParams * p)175 void cmd_select_paren_inner(CmdContext *c, CmdParams *p)
176 {
177 select_brace(c, p, '(', ')', TRUE);
178 }
179
180
cmd_select_less_inner(CmdContext * c,CmdParams * p)181 void cmd_select_less_inner(CmdContext *c, CmdParams *p)
182 {
183 select_brace(c, p, '<', '>', TRUE);
184 }
185
186
cmd_select_bracket_inner(CmdContext * c,CmdParams * p)187 void cmd_select_bracket_inner(CmdContext *c, CmdParams *p)
188 {
189 select_brace(c, p, '[', ']', TRUE);
190 }
191