1 /*
2  *      sciwrappers.c - this file is part of Geany, a fast and lightweight IDE
3  *
4  *      Copyright 2005 The Geany contributors
5  *
6  *      This program is free software; you can redistribute it and/or modify
7  *      it under the terms of the GNU General Public License as published by
8  *      the Free Software Foundation; either version 2 of the License, or
9  *      (at your option) any later version.
10  *
11  *      This program is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *      GNU General Public License for more details.
15  *
16  *      You should have received a copy of the GNU General Public License along
17  *      with this program; if not, write to the Free Software Foundation, Inc.,
18  *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 /** @file sciwrappers.h
22  * Wrapper functions for the Scintilla editor widget @c SCI_* messages.
23  * You should also check the http://scintilla.org documentation, as it is more detailed.
24  *
25  * To get Scintilla notifications, use the
26  * @link pluginsignals.c @c "editor-notify" signal @endlink.
27  *
28  * @note These functions were originally from the cssed project
29  * (http://cssed.sf.net, thanks).
30  * @see scintilla_send_message().
31  */
32 
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36 
37 #include "sciwrappers.h"
38 
39 #include "utils.h"
40 
41 #include <string.h>
42 
43 
44 #ifndef NDEBUG
45 
sci_send_message_internal(const gchar * file,guint line,ScintillaObject * sci,guint msg,uptr_t wparam,sptr_t lparam)46 sptr_t sci_send_message_internal (const gchar *file, guint line, ScintillaObject *sci,
47 	guint msg, uptr_t wparam, sptr_t lparam)
48 {
49 	sptr_t result;
50 	gint status;
51 
52 	scintilla_send_message(sci, SCI_SETSTATUS, 0, 0);
53 	result = scintilla_send_message(sci, msg, wparam, lparam);
54 	status = scintilla_send_message(sci, SCI_GETSTATUS, 0, 0);
55 
56 	if (status != 0)
57 	{
58 		const gchar *sub_msg = "unknown";
59 		switch (status)
60 		{
61 			case SC_STATUS_FAILURE:
62 				sub_msg = "generic failure";
63 				break;
64 			case SC_STATUS_BADALLOC:
65 				sub_msg = "memory is exhausted";
66 				break;
67 			case SC_STATUS_WARN_REGEX:
68 				sub_msg = "regular expression is invalid";
69 				break;
70 			default:
71 				if (status >= SC_STATUS_WARN_START)
72 					sub_msg = "unknown warning";
73 				else
74 					sub_msg = "unknown failure";
75 				break;
76 		}
77 #define SCI_STATUS_FORMAT_STRING "%s:%u: scintilla has non-zero status " \
78 			"code '%d' after sending message '%u' to instance '%p' with " \
79 			"wParam='%lu' and lParam='%ld': %s"
80 		if (status >= SC_STATUS_WARN_START)
81 		{
82 			g_warning(SCI_STATUS_FORMAT_STRING, file, line, status, msg,
83 				(gpointer)sci, wparam, lparam, sub_msg);
84 		}
85 		else
86 		{
87 			g_critical(SCI_STATUS_FORMAT_STRING, file, line, status, msg,
88 				(gpointer)sci, wparam, lparam, sub_msg);
89 		}
90 	}
91 
92 	return result;
93 }
94 #endif
95 
96 
97 /* line numbers visibility */
sci_set_line_numbers(ScintillaObject * sci,gboolean set)98 void sci_set_line_numbers(ScintillaObject *sci, gboolean set)
99 {
100 	if (set)
101 	{
102 		gchar tmp_str[15];
103 		gint len = (gint) SSM(sci, SCI_GETLINECOUNT, 0, 0);
104 		gint width;
105 
106 		g_snprintf(tmp_str, 15, "_%d", len);
107 		width = sci_text_width(sci, STYLE_LINENUMBER, tmp_str);
108 		SSM(sci, SCI_SETMARGINWIDTHN, 0, width);
109 		SSM(sci, SCI_SETMARGINSENSITIVEN, 0, FALSE); /* use default behaviour */
110 	}
111 	else
112 	{
113 		SSM(sci, SCI_SETMARGINWIDTHN, 0, 0);
114 	}
115 }
116 
117 
sci_set_mark_long_lines(ScintillaObject * sci,gint type,gint column,const gchar * colour)118 void sci_set_mark_long_lines(ScintillaObject *sci, gint type, gint column, const gchar *colour)
119 {
120 	glong colour_val = utils_parse_color_to_bgr(colour); /* Scintilla uses a "long" value */
121 
122 	if (column == 0)
123 		type = 2;
124 	switch (type)
125 	{
126 		case 0:
127 		{
128 			SSM(sci, SCI_SETEDGEMODE, EDGE_LINE, 0);
129 			break;
130 		}
131 		case 1:
132 		{
133 			SSM(sci, SCI_SETEDGEMODE, EDGE_BACKGROUND, 0);
134 			break;
135 		}
136 		case 2:
137 		{
138 			SSM(sci, SCI_SETEDGEMODE, EDGE_NONE, 0);
139 			return;
140 		}
141 	}
142 	SSM(sci, SCI_SETEDGECOLUMN, (uptr_t) column, 0);
143 	SSM(sci, SCI_SETEDGECOLOUR, (uptr_t) colour_val, 0);
144 }
145 
146 
147 /* Calls SCI_TEXTHEIGHT but tries very hard to cache the result as it's a very
148  * expensive operation */
sci_text_height_cached(ScintillaObject * sci)149 static gint sci_text_height_cached(ScintillaObject *sci)
150 {
151 	struct height_spec {
152 		gchar *font;
153 		gint size;
154 		gint zoom;
155 		gint extra;
156 	};
157 	static struct height_spec cache = {0};
158 	static gint cache_value = 0;
159 	struct height_spec current;
160 
161 	current.font = sci_get_string(sci, SCI_STYLEGETFONT, 0);
162 	current.size = SSM(sci, SCI_STYLEGETSIZEFRACTIONAL, 0, 0);
163 	current.zoom = SSM(sci, SCI_GETZOOM, 0, 0);
164 	current.extra = SSM(sci, SCI_GETEXTRAASCENT, 0, 0) + SSM(sci, SCI_GETEXTRADESCENT, 0, 0);
165 
166 	if (g_strcmp0(current.font, cache.font) == 0 &&
167 		current.size == cache.size &&
168 		current.zoom == cache.zoom &&
169 		current.extra == cache.extra)
170 	{
171 		g_free(current.font);
172 	}
173 	else
174 	{
175 		g_free(cache.font);
176 		cache = current;
177 
178 		cache_value = SSM(sci, SCI_TEXTHEIGHT, 0, 0);
179 	}
180 
181 	return cache_value;
182 }
183 
184 /* compute margin width based on ratio of line height */
margin_width_from_line_height(ScintillaObject * sci,gdouble ratio,gint threshold)185 static gint margin_width_from_line_height(ScintillaObject *sci, gdouble ratio, gint threshold)
186 {
187 	const gint line_height = sci_text_height_cached(sci);
188 	gint width;
189 
190 	width = line_height * ratio;
191 	/* round down to an even size */
192 	width = width - (width % 2);
193 	/* if under threshold, just use the line height */
194 	if (width < threshold)
195 		width = MIN(threshold, line_height);
196 
197 	return width;
198 }
199 
200 
201 /* symbol margin visibility */
sci_set_symbol_margin(ScintillaObject * sci,gboolean set)202 void sci_set_symbol_margin(ScintillaObject *sci, gboolean set)
203 {
204 	if (set)
205 	{
206 		const gint width = margin_width_from_line_height(sci, 0.88, 16);
207 
208 		SSM(sci, SCI_SETMARGINWIDTHN, 1, width);
209 		SSM(sci, SCI_SETMARGINSENSITIVEN, 1, TRUE);
210 	}
211 	else
212 	{
213 		SSM(sci, SCI_SETMARGINWIDTHN, 1, 0);
214 		SSM(sci, SCI_SETMARGINSENSITIVEN, 1, FALSE);
215 	}
216 }
217 
218 
219 /* folding margin visibility */
sci_set_folding_margin_visible(ScintillaObject * sci,gboolean set)220 void sci_set_folding_margin_visible(ScintillaObject *sci, gboolean set)
221 {
222 	if (set)
223 	{
224 		const gint width = margin_width_from_line_height(sci, 0.66, 12);
225 
226 		SSM(sci, SCI_SETMARGINWIDTHN, 2, width);
227 		SSM(sci, SCI_SETMARGINSENSITIVEN, 2, TRUE);
228 	}
229 	else
230 	{
231 		SSM(sci, SCI_SETMARGINSENSITIVEN, 2, FALSE);
232 		SSM(sci, SCI_SETMARGINWIDTHN, 2, 0);
233 	}
234 }
235 
236 
237 /* end of lines */
sci_set_visible_eols(ScintillaObject * sci,gboolean set)238 void sci_set_visible_eols(ScintillaObject *sci, gboolean set)
239 {
240 	SSM(sci, SCI_SETVIEWEOL, set != FALSE, 0);
241 }
242 
243 
sci_set_visible_white_spaces(ScintillaObject * sci,gboolean set)244 void sci_set_visible_white_spaces(ScintillaObject *sci, gboolean set)
245 {
246 	if (set)
247 		SSM(sci, SCI_SETVIEWWS, SCWS_VISIBLEALWAYS, 0);
248 	else
249 		SSM(sci, SCI_SETVIEWWS, SCWS_INVISIBLE, 0);
250 }
251 
252 
sci_set_lines_wrapped(ScintillaObject * sci,gboolean set)253 void sci_set_lines_wrapped(ScintillaObject *sci, gboolean set)
254 {
255 	if (set)
256 		SSM(sci, SCI_SETWRAPMODE, SC_WRAP_WORD, 0);
257 	else
258 		SSM(sci, SCI_SETWRAPMODE, SC_WRAP_NONE, 0);
259 }
260 
261 
sci_get_eol_mode(ScintillaObject * sci)262 gint sci_get_eol_mode(ScintillaObject *sci)
263 {
264 	return (gint) SSM(sci, SCI_GETEOLMODE, 0, 0);
265 }
266 
267 
sci_set_eol_mode(ScintillaObject * sci,gint eolmode)268 void sci_set_eol_mode(ScintillaObject *sci, gint eolmode)
269 {
270 	SSM(sci, SCI_SETEOLMODE, (uptr_t) eolmode, 0);
271 }
272 
273 
sci_convert_eols(ScintillaObject * sci,gint eolmode)274 void sci_convert_eols(ScintillaObject *sci, gint eolmode)
275 {
276 	SSM(sci, SCI_CONVERTEOLS, (uptr_t) eolmode, 0);
277 }
278 
279 
sci_add_text(ScintillaObject * sci,const gchar * text)280 void sci_add_text(ScintillaObject *sci, const gchar *text)
281 {
282 	if (text != NULL)
283 	{ /* if null text is passed scintilla will segfault */
284 		SSM(sci, SCI_ADDTEXT, strlen(text), (sptr_t) text);
285 	}
286 }
287 
288 
289 /** Sets all text.
290  * @param sci Scintilla widget.
291  * @param text Text. */
292 GEANY_API_SYMBOL
sci_set_text(ScintillaObject * sci,const gchar * text)293 void sci_set_text(ScintillaObject *sci, const gchar *text)
294 {
295 	if( text != NULL ){ /* if null text is passed to scintilla will segfault */
296 		SSM(sci, SCI_SETTEXT, 0, (sptr_t) text);
297 	}
298 }
299 
300 
sci_can_undo(ScintillaObject * sci)301 gboolean sci_can_undo(ScintillaObject *sci)
302 {
303 	return SSM(sci, SCI_CANUNDO, 0, 0) != FALSE;
304 }
305 
306 
sci_can_redo(ScintillaObject * sci)307 gboolean sci_can_redo(ScintillaObject *sci)
308 {
309 	return SSM(sci, SCI_CANREDO, 0, 0) != FALSE;
310 }
311 
312 
sci_undo(ScintillaObject * sci)313 void sci_undo(ScintillaObject *sci)
314 {
315 	if (sci_can_undo(sci))
316 		SSM(sci, SCI_UNDO, 0, 0);
317 }
318 
319 
sci_redo(ScintillaObject * sci)320 void sci_redo(ScintillaObject *sci)
321 {
322 	if (sci_can_redo(sci))
323 		SSM(sci, SCI_REDO, 0, 0);
324 }
325 
326 
327 /** Begins grouping a set of edits together as one Undo action.
328  * You must call sci_end_undo_action() after making your edits.
329  * @param sci Scintilla @c GtkWidget. */
330 GEANY_API_SYMBOL
sci_start_undo_action(ScintillaObject * sci)331 void sci_start_undo_action(ScintillaObject *sci)
332 {
333 	SSM(sci, SCI_BEGINUNDOACTION, 0, 0);
334 }
335 
336 
337 /** Ends grouping a set of edits together as one Undo action.
338  * @param sci Scintilla @c GtkWidget.
339  * @see sci_start_undo_action(). */
340 GEANY_API_SYMBOL
sci_end_undo_action(ScintillaObject * sci)341 void sci_end_undo_action(ScintillaObject *sci)
342 {
343 	SSM(sci, SCI_ENDUNDOACTION, 0, 0);
344 }
345 
346 
sci_set_undo_collection(ScintillaObject * sci,gboolean set)347 void sci_set_undo_collection(ScintillaObject *sci, gboolean set)
348 {
349 	SSM(sci, SCI_SETUNDOCOLLECTION, set != FALSE, 0);
350 }
351 
352 
sci_empty_undo_buffer(ScintillaObject * sci)353 void sci_empty_undo_buffer(ScintillaObject *sci)
354 {
355 	SSM(sci, SCI_EMPTYUNDOBUFFER, 0, 0);
356 }
357 
358 
sci_is_modified(ScintillaObject * sci)359 gboolean sci_is_modified(ScintillaObject *sci)
360 {
361 	return (SSM(sci, SCI_GETMODIFY, 0, 0) != 0);
362 }
363 
364 
sci_zoom_in(ScintillaObject * sci)365 void sci_zoom_in(ScintillaObject *sci)
366 {
367 	SSM(sci, SCI_ZOOMIN, 0, 0);
368 }
369 
370 
sci_zoom_out(ScintillaObject * sci)371 void sci_zoom_out(ScintillaObject *sci)
372 {
373 	SSM(sci, SCI_ZOOMOUT, 0, 0);
374 }
375 
376 
sci_zoom_off(ScintillaObject * sci)377 void sci_zoom_off(ScintillaObject *sci)
378 {
379 	SSM(sci, SCI_SETZOOM, 0, 0);
380 }
381 
382 
383 /** Sets a line marker.
384  * @param sci Scintilla widget.
385  * @param line_number Line number.
386  * @param marker Marker number. */
387 GEANY_API_SYMBOL
sci_set_marker_at_line(ScintillaObject * sci,gint line_number,gint marker)388 void sci_set_marker_at_line(ScintillaObject *sci, gint line_number, gint marker)
389 {
390 	SSM(sci, SCI_MARKERADD, (uptr_t) line_number, marker);
391 }
392 
393 
394 /** Deletes a line marker.
395  * @param sci Scintilla widget.
396  * @param line_number Line number.
397  * @param marker Marker number. */
398 GEANY_API_SYMBOL
sci_delete_marker_at_line(ScintillaObject * sci,gint line_number,gint marker)399 void sci_delete_marker_at_line(ScintillaObject *sci, gint line_number, gint marker)
400 {
401 	SSM(sci, SCI_MARKERDELETE, (uptr_t) line_number, marker);
402 }
403 
404 
405 /** Checks if a line has a marker set.
406  * @param sci Scintilla widget.
407  * @param line Line number.
408  * @param marker Marker number.
409  * @return Whether it's set. */
410 GEANY_API_SYMBOL
sci_is_marker_set_at_line(ScintillaObject * sci,gint line,gint marker)411 gboolean sci_is_marker_set_at_line(ScintillaObject *sci, gint line, gint marker)
412 {
413 	gint state;
414 
415 	state = (gint) SSM(sci, SCI_MARKERGET, (uptr_t) line, 0);
416 	return (state & (1 << marker));
417 }
418 
419 
sci_toggle_marker_at_line(ScintillaObject * sci,gint line,gint marker)420 void sci_toggle_marker_at_line(ScintillaObject *sci, gint line, gint marker)
421 {
422 	gboolean set = sci_is_marker_set_at_line(sci, line, marker);
423 
424 	if (!set)
425 		sci_set_marker_at_line(sci, line, marker);
426 	else
427 		sci_delete_marker_at_line(sci, line, marker);
428 }
429 
430 
431 /* Returns the line number of the next marker that matches marker_mask, or -1.
432  * marker_mask is a bitor of 1 << marker_index. (See MarkerHandleSet::MarkValue()).
433  * Note: If there is a marker on the line, it returns the same line. */
sci_marker_next(ScintillaObject * sci,gint line,gint marker_mask,gboolean wrap)434 gint sci_marker_next(ScintillaObject *sci, gint line, gint marker_mask, gboolean wrap)
435 {
436 	gint marker_line;
437 
438 	marker_line = (gint) SSM(sci, SCI_MARKERNEXT, (uptr_t) line, marker_mask);
439 	if (wrap && marker_line == -1)
440 		marker_line = (gint) SSM(sci, SCI_MARKERNEXT, 0, marker_mask);
441 	return marker_line;
442 }
443 
444 
445 /* Returns the line number of the previous marker that matches marker_mask, or -1.
446  * marker_mask is a bitor of 1 << marker_index. (See MarkerHandleSet::MarkValue()).
447  * Note: If there is a marker on the line, it returns the same line. */
sci_marker_previous(ScintillaObject * sci,gint line,gint marker_mask,gboolean wrap)448 gint sci_marker_previous(ScintillaObject *sci, gint line, gint marker_mask, gboolean wrap)
449 {
450 	gint marker_line;
451 
452 	marker_line = (gint) SSM(sci, SCI_MARKERPREVIOUS, (uptr_t) line, marker_mask);
453 	if (wrap && marker_line == -1)
454 	{
455 		gint len = sci_get_length(sci);
456 		gint last_line = sci_get_line_from_position(sci, len - 1);
457 
458 		marker_line = (gint) SSM(sci, SCI_MARKERPREVIOUS, (uptr_t) last_line, marker_mask);
459 	}
460 	return marker_line;
461 }
462 
463 
464 /** Gets the line number from @a position.
465  * @param sci Scintilla widget.
466  * @param position Position.
467  * @return The line. */
468 GEANY_API_SYMBOL
sci_get_line_from_position(ScintillaObject * sci,gint position)469 gint sci_get_line_from_position(ScintillaObject *sci, gint position)
470 {
471 	return (gint) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) position, 0);
472 }
473 
474 
475 /** Gets the column number relative to the start of the line that @a position is on.
476  * @param sci Scintilla widget.
477  * @param position Position.
478  * @return The column. */
479 GEANY_API_SYMBOL
sci_get_col_from_position(ScintillaObject * sci,gint position)480 gint sci_get_col_from_position(ScintillaObject *sci, gint position)
481 {
482 	return (gint) SSM(sci, SCI_GETCOLUMN, (uptr_t) position, 0);
483 }
484 
485 
sci_get_position_from_col(ScintillaObject * sci,gint line,gint col)486 gint sci_get_position_from_col(ScintillaObject *sci, gint line, gint col)
487 {
488 	return (gint) SSM(sci, SCI_FINDCOLUMN, line, col);
489 }
490 
491 
492 /** Gets the position for the start of @a line.
493  * @param sci Scintilla widget.
494  * @param line Line.
495  * @return Position. */
496 GEANY_API_SYMBOL
sci_get_position_from_line(ScintillaObject * sci,gint line)497 gint sci_get_position_from_line(ScintillaObject *sci, gint line)
498 {
499 	return (gint) SSM(sci, SCI_POSITIONFROMLINE, (uptr_t) line, 0);
500 }
501 
502 
503 /** Gets the cursor position.
504  * @param sci Scintilla widget.
505  * @return Position. */
506 GEANY_API_SYMBOL
sci_get_current_position(ScintillaObject * sci)507 gint sci_get_current_position(ScintillaObject *sci)
508 {
509 	return (gint) SSM(sci, SCI_GETCURRENTPOS, 0, 0);
510 }
511 
512 
sci_get_cursor_virtual_space(ScintillaObject * sci)513 gint sci_get_cursor_virtual_space(ScintillaObject *sci)
514 {
515 	gint selection_mode = sci_get_selection_mode(sci);
516 
517 	return selection_mode == SC_SEL_RECTANGLE || selection_mode == SC_SEL_THIN ?
518 		SSM(sci, SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE, 0, 0) :
519 		SSM(sci, SCI_GETSELECTIONNCARETVIRTUALSPACE,
520 			SSM(sci, SCI_GETMAINSELECTION, 0, 0), 0);
521 }
522 
523 
524 /** Sets the cursor position.
525  * @param sci Scintilla widget.
526  * @param position Position.
527  * @param scroll_to_caret Whether to scroll the cursor in view. */
528 GEANY_API_SYMBOL
sci_set_current_position(ScintillaObject * sci,gint position,gboolean scroll_to_caret)529 void sci_set_current_position(ScintillaObject *sci, gint position, gboolean scroll_to_caret)
530 {
531 	if (scroll_to_caret)
532 		SSM(sci, SCI_GOTOPOS, (uptr_t) position, 0);
533 	else
534 	{
535 		SSM(sci, SCI_SETCURRENTPOS, (uptr_t) position, 0);
536 		SSM(sci, SCI_SETANCHOR, (uptr_t) position, 0); /* to avoid creation of a selection */
537 	}
538 	SSM(sci, SCI_CHOOSECARETX, 0, 0);
539 }
540 
541 
542 /* Set the cursor line without scrolling the view.
543  * Use sci_goto_line() to also scroll. */
sci_set_current_line(ScintillaObject * sci,gint line)544 void sci_set_current_line(ScintillaObject *sci, gint line)
545 {
546 	gint pos = sci_get_position_from_line(sci, line);
547 	sci_set_current_position(sci, pos, FALSE);
548 }
549 
550 
551 /** Gets the total number of lines.
552  * @param sci Scintilla widget.
553  * @return The line count. */
554 GEANY_API_SYMBOL
sci_get_line_count(ScintillaObject * sci)555 gint sci_get_line_count(ScintillaObject *sci)
556 {
557 	return (gint) SSM(sci, SCI_GETLINECOUNT, 0, 0);
558 }
559 
560 
561 /** Sets the selection start position.
562  * @param sci Scintilla widget.
563  * @param position Position. */
564 GEANY_API_SYMBOL
sci_set_selection_start(ScintillaObject * sci,gint position)565 void sci_set_selection_start(ScintillaObject *sci, gint position)
566 {
567 	SSM(sci, SCI_SETSELECTIONSTART, (uptr_t) position, 0);
568 }
569 
570 
571 /** Sets the selection end position.
572  * @param sci Scintilla widget.
573  * @param position Position. */
574 GEANY_API_SYMBOL
sci_set_selection_end(ScintillaObject * sci,gint position)575 void sci_set_selection_end(ScintillaObject *sci, gint position)
576 {
577 	SSM(sci, SCI_SETSELECTIONEND, (uptr_t) position, 0);
578 }
579 
580 
sci_set_selection(ScintillaObject * sci,gint anchorPos,gint currentPos)581 void sci_set_selection(ScintillaObject *sci, gint anchorPos, gint currentPos)
582 {
583 	SSM(sci, SCI_SETSEL, (uptr_t) anchorPos, currentPos);
584 }
585 
586 
587 /** Gets the position at the end of a line
588  * @param sci Scintilla widget.
589  * @param line Line.
590  * @return The position at the end of the line. */
591 GEANY_API_SYMBOL
sci_get_line_end_position(ScintillaObject * sci,gint line)592 gint sci_get_line_end_position(ScintillaObject *sci, gint line)
593 {
594 	return (gint) SSM(sci, SCI_GETLINEENDPOSITION, (uptr_t) line, 0);
595 }
596 
597 
sci_cut(ScintillaObject * sci)598 void sci_cut(ScintillaObject *sci)
599 {
600 	SSM(sci, SCI_CUT, 0, 0);
601 }
602 
603 
sci_copy(ScintillaObject * sci)604 void sci_copy(ScintillaObject *sci)
605 {
606 	SSM(sci, SCI_COPY, 0, 0);
607 }
608 
609 
sci_paste(ScintillaObject * sci)610 void sci_paste(ScintillaObject *sci)
611 {
612 	SSM(sci, SCI_PASTE, 0, 0);
613 }
614 
615 
sci_clear(ScintillaObject * sci)616 void sci_clear(ScintillaObject *sci)
617 {
618 	SSM(sci, SCI_CLEAR, 0, 0);
619 }
620 
621 
622 /** Gets the selection start position.
623  * @param sci Scintilla widget.
624  * @return Position. */
625 GEANY_API_SYMBOL
sci_get_selection_start(ScintillaObject * sci)626 gint sci_get_selection_start(ScintillaObject *sci)
627 {
628 	return (gint) SSM(sci, SCI_GETSELECTIONSTART, 0, 0);
629 }
630 
631 
632 /** Gets the selection end position.
633  * @param sci Scintilla widget.
634  * @return Position. */
635 GEANY_API_SYMBOL
sci_get_selection_end(ScintillaObject * sci)636 gint sci_get_selection_end(ScintillaObject *sci)
637 {
638 	return (gint) SSM(sci, SCI_GETSELECTIONEND, 0, 0);
639 }
640 
641 
642 /** Replaces selection.
643  * @param sci Scintilla widget.
644  * @param text Text. */
645 GEANY_API_SYMBOL
sci_replace_sel(ScintillaObject * sci,const gchar * text)646 void sci_replace_sel(ScintillaObject *sci, const gchar *text)
647 {
648 	SSM(sci, SCI_REPLACESEL, 0, (sptr_t) text);
649 }
650 
651 
652 /** Gets the length of all text.
653  * @param sci Scintilla widget.
654  * @return Length. */
655 GEANY_API_SYMBOL
sci_get_length(ScintillaObject * sci)656 gint sci_get_length(ScintillaObject *sci)
657 {
658 	return (gint) SSM(sci, SCI_GETLENGTH, 0, 0);
659 }
660 
661 
662 /** Gets the currently used lexer
663  * @param sci Scintilla widget.
664  * @returns The lexer ID
665  */
666 GEANY_API_SYMBOL
sci_get_lexer(ScintillaObject * sci)667 gint sci_get_lexer(ScintillaObject *sci)
668 {
669 	return (gint) SSM(sci, SCI_GETLEXER, 0, 0);
670 }
671 
672 
sci_set_lexer(ScintillaObject * sci,guint lexer_id)673 void sci_set_lexer(ScintillaObject *sci, guint lexer_id)
674 {
675 	gint old = sci_get_lexer(sci);
676 
677 	SSM(sci, SCI_SETLEXER, lexer_id, 0);
678 
679 	if (old != (gint)lexer_id)
680 		SSM(sci, SCI_CLEARDOCUMENTSTYLE, 0, 0);
681 }
682 
683 
684 /** Gets line length.
685  * @param sci Scintilla widget.
686  * @param line Line number.
687  * @return Length. */
688 GEANY_API_SYMBOL
sci_get_line_length(ScintillaObject * sci,gint line)689 gint sci_get_line_length(ScintillaObject *sci, gint line)
690 {
691 	return (gint) SSM(sci, SCI_LINELENGTH, (uptr_t) line, 0);
692 }
693 
694 
695 /* safe way to read Scintilla string into new memory.
696  * works with any string buffer messages that follow the Windows message convention. */
sci_get_string(ScintillaObject * sci,guint msg,gulong wParam)697 gchar *sci_get_string(ScintillaObject *sci, guint msg, gulong wParam)
698 {
699 	gint size = (gint) SSM(sci, msg, wParam, 0);
700 	gchar *str = g_malloc(size + 1);
701 
702 	SSM(sci, msg, wParam, (sptr_t) str);
703 	str[size] = '\0';	/* ensure termination, needed for SCI_GETLINE */
704 	return str;
705 }
706 
707 
708 /** Gets line contents.
709  * @param sci Scintilla widget.
710  * @param line_num Line number.
711  * @return A @c NULL-terminated copy of the line text. */
712 GEANY_API_SYMBOL
sci_get_line(ScintillaObject * sci,gint line_num)713 gchar *sci_get_line(ScintillaObject *sci, gint line_num)
714 {
715 	return sci_get_string(sci, SCI_GETLINE, (gulong) line_num);
716 }
717 
718 
719 /** Gets all text.
720  * @deprecated sci_get_text is deprecated and should not be used in newly-written code.
721  * Use sci_get_contents() instead.
722  *
723  * @param sci Scintilla widget.
724  * @param len Length of @a text buffer, usually sci_get_length() + 1.
725  * @param text Text buffer; must be allocated @a len + 1 bytes for null-termination. */
726 GEANY_API_SYMBOL
sci_get_text(ScintillaObject * sci,gint len,gchar * text)727 void sci_get_text(ScintillaObject *sci, gint len, gchar *text)
728 {
729 	SSM(sci, SCI_GETTEXT, (uptr_t) len, (sptr_t) text);
730 }
731 
732 
733 /** Allocates and fills a buffer with text from the start of the document.
734  * @param sci Scintilla widget.
735  * @param buffer_len Buffer length to allocate, including the terminating
736  * null char, e.g. sci_get_length() + 1. Alternatively use @c -1 to get all
737  * text (since Geany 1.23).
738  * @return A copy of the text. Should be freed when no longer needed.
739  *
740  * @since 1.23 (0.17)
741  */
742 GEANY_API_SYMBOL
sci_get_contents(ScintillaObject * sci,gint buffer_len)743 gchar *sci_get_contents(ScintillaObject *sci, gint buffer_len)
744 {
745 	gchar *text;
746 
747 	if (buffer_len < 0)
748 		buffer_len = sci_get_length(sci) + 1;
749 
750 	text = g_malloc(buffer_len);
751 	SSM(sci, SCI_GETTEXT, (uptr_t) buffer_len, (sptr_t) text);
752 	return text;
753 }
754 
755 
756 /** Gets selected text.
757  * @deprecated sci_get_selected_text is deprecated and should not be used in newly-written code.
758  * Use sci_get_selection_contents() instead.
759  *
760  * @param sci Scintilla widget.
761  * @param text Text buffer; must be allocated sci_get_selected_text_length() + 1 bytes
762  * for null-termination. */
763 GEANY_API_SYMBOL
sci_get_selected_text(ScintillaObject * sci,gchar * text)764 void sci_get_selected_text(ScintillaObject *sci, gchar *text)
765 {
766 	SSM(sci, SCI_GETSELTEXT, 0, (sptr_t) text);
767 }
768 
769 
770 /** Gets selected text.
771  * @param sci Scintilla widget.
772  *
773  * @return The selected text. Should be freed when no longer needed.
774  *
775  * @since 0.17
776  */
777 GEANY_API_SYMBOL
sci_get_selection_contents(ScintillaObject * sci)778 gchar *sci_get_selection_contents(ScintillaObject *sci)
779 {
780 	return sci_get_string(sci, SCI_GETSELTEXT, 0);
781 }
782 
783 
784 /** Gets selected text length.
785  * @param sci Scintilla widget.
786  * @return Length. */
787 GEANY_API_SYMBOL
sci_get_selected_text_length(ScintillaObject * sci)788 gint sci_get_selected_text_length(ScintillaObject *sci)
789 {
790 	return (gint) SSM(sci, SCI_GETSELTEXT, 0, 0);
791 }
792 
793 
sci_get_position_from_xy(ScintillaObject * sci,gint x,gint y,gboolean nearby)794 gint sci_get_position_from_xy(ScintillaObject *sci, gint x, gint y, gboolean nearby)
795 {
796 	/* for nearby return -1 if there is no character near to the x,y point. */
797 	return (gint) SSM(sci, (nearby) ? SCI_POSITIONFROMPOINTCLOSE : SCI_POSITIONFROMPOINT, (uptr_t) x, y);
798 }
799 
800 
801 /** Checks if a line is visible (folding may have hidden it).
802  * @param sci Scintilla widget.
803  * @param line Line number.
804  * @return Whether @a line will be drawn on the screen. */
805 GEANY_API_SYMBOL
sci_get_line_is_visible(ScintillaObject * sci,gint line)806 gboolean sci_get_line_is_visible(ScintillaObject *sci, gint line)
807 {
808 	return SSM(sci, SCI_GETLINEVISIBLE, (uptr_t) line, 0) != FALSE;
809 }
810 
811 
812 /** Makes @a line visible (folding may have hidden it).
813  * @param sci Scintilla widget.
814  * @param line Line number. */
815 GEANY_API_SYMBOL
sci_ensure_line_is_visible(ScintillaObject * sci,gint line)816 void sci_ensure_line_is_visible(ScintillaObject *sci, gint line)
817 {
818 	SSM(sci, SCI_ENSUREVISIBLE, (uptr_t) line, 0);
819 }
820 
821 
sci_get_fold_level(ScintillaObject * sci,gint line)822 gint sci_get_fold_level(ScintillaObject *sci, gint line)
823 {
824 	return (gint) SSM(sci, SCI_GETFOLDLEVEL, (uptr_t) line, 0);
825 }
826 
827 
828 /* Get the line number of the fold point before start_line, or -1 if there isn't one */
sci_get_fold_parent(ScintillaObject * sci,gint start_line)829 gint sci_get_fold_parent(ScintillaObject *sci, gint start_line)
830 {
831 	return (gint) SSM(sci, SCI_GETFOLDPARENT, (uptr_t) start_line, 0);
832 }
833 
834 
sci_toggle_fold(ScintillaObject * sci,gint line)835 void sci_toggle_fold(ScintillaObject *sci, gint line)
836 {
837 	SSM(sci, SCI_TOGGLEFOLD, (uptr_t) line, 0);
838 }
839 
840 
sci_get_fold_expanded(ScintillaObject * sci,gint line)841 gboolean sci_get_fold_expanded(ScintillaObject *sci, gint line)
842 {
843 	return SSM(sci, SCI_GETFOLDEXPANDED, (uptr_t) line, 0) != FALSE;
844 }
845 
846 
sci_colourise(ScintillaObject * sci,gint start,gint end)847 void sci_colourise(ScintillaObject *sci, gint start, gint end)
848 {
849 	SSM(sci, SCI_COLOURISE, (uptr_t) start, end);
850 }
851 
852 
sci_clear_all(ScintillaObject * sci)853 void sci_clear_all(ScintillaObject *sci)
854 {
855 	SSM(sci, SCI_CLEARALL, 0, 0);
856 }
857 
858 
sci_get_end_styled(ScintillaObject * sci)859 gint sci_get_end_styled(ScintillaObject *sci)
860 {
861 	return (gint) SSM(sci, SCI_GETENDSTYLED, 0, 0);
862 }
863 
864 
sci_set_tab_width(ScintillaObject * sci,gint width)865 void sci_set_tab_width(ScintillaObject *sci, gint width)
866 {
867 	SSM(sci, SCI_SETTABWIDTH, (uptr_t) width, 0);
868 }
869 
870 
871 /** Gets display tab width (this is not indent width, see GeanyIndentPrefs).
872  * @param sci Scintilla widget.
873  * @return Width.
874  *
875  * @since 0.15
876  **/
877 GEANY_API_SYMBOL
sci_get_tab_width(ScintillaObject * sci)878 gint sci_get_tab_width(ScintillaObject *sci)
879 {
880 	return (gint) SSM(sci, SCI_GETTABWIDTH, 0, 0);
881 }
882 
883 
884 /** Gets a character.
885  * @param sci Scintilla widget.
886  * @param pos Position.
887  * @return Char. */
888 GEANY_API_SYMBOL
sci_get_char_at(ScintillaObject * sci,gint pos)889 gchar sci_get_char_at(ScintillaObject *sci, gint pos)
890 {
891 	return (gchar) SSM(sci, SCI_GETCHARAT, (uptr_t) pos, 0);
892 }
893 
894 
sci_set_savepoint(ScintillaObject * sci)895 void sci_set_savepoint(ScintillaObject *sci)
896 {
897 	SSM(sci, SCI_SETSAVEPOINT, 0, 0);
898 }
899 
900 
sci_set_indentation_guides(ScintillaObject * sci,gint mode)901 void sci_set_indentation_guides(ScintillaObject *sci, gint mode)
902 {
903 	SSM(sci, SCI_SETINDENTATIONGUIDES, (uptr_t) mode, 0);
904 }
905 
906 
sci_use_popup(ScintillaObject * sci,gboolean enable)907 void sci_use_popup(ScintillaObject *sci, gboolean enable)
908 {
909 	SSM(sci, SCI_USEPOPUP, enable != FALSE, 0);
910 }
911 
912 
913 /** Checks if there's a selection.
914  * @param sci Scintilla widget.
915  * @return Whether a selection is present.
916  *
917  * @since 0.15
918  **/
919 GEANY_API_SYMBOL
sci_has_selection(ScintillaObject * sci)920 gboolean sci_has_selection(ScintillaObject *sci)
921 {
922 	if (SSM(sci, SCI_GETSELECTIONEND, 0, 0) - SSM(sci, SCI_GETSELECTIONSTART, 0, 0))
923 		return TRUE;
924 	else
925 		return FALSE;
926 }
927 
928 
sci_goto_pos(ScintillaObject * sci,gint pos,gboolean unfold)929 void sci_goto_pos(ScintillaObject *sci, gint pos, gboolean unfold)
930 {
931 	if (unfold) SSM(sci, SCI_ENSUREVISIBLE, (uptr_t) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) pos, 0), 0);
932 	SSM(sci, SCI_GOTOPOS, (uptr_t) pos, 0);
933 }
934 
935 
sci_set_search_anchor(ScintillaObject * sci)936 void sci_set_search_anchor(ScintillaObject *sci)
937 {
938 	SSM(sci, SCI_SEARCHANCHOR, 0, 0);
939 }
940 
941 
942 /* removes a selection if pos < 0 */
sci_set_anchor(ScintillaObject * sci,gint pos)943 void sci_set_anchor(ScintillaObject *sci, gint pos)
944 {
945 	if (pos < 0)
946 		pos = sci_get_current_position(sci);
947 
948 	SSM(sci, SCI_SETANCHOR, (uptr_t) pos, 0);
949 }
950 
951 
952 /** Scrolls the cursor in view.
953  * @param sci Scintilla widget. */
954 GEANY_API_SYMBOL
sci_scroll_caret(ScintillaObject * sci)955 void sci_scroll_caret(ScintillaObject *sci)
956 {
957 	SSM(sci, SCI_SCROLLCARET, 0, 0);
958 }
959 
960 
sci_scroll_columns(ScintillaObject * sci,gint columns)961 void sci_scroll_columns(ScintillaObject *sci, gint columns)
962 {
963 	SSM(sci, SCI_LINESCROLL, (uptr_t) columns, 0);
964 }
965 
966 
sci_search_next(ScintillaObject * sci,gint flags,const gchar * text)967 gint sci_search_next(ScintillaObject *sci, gint flags, const gchar *text)
968 {
969 	/* FIXME: SCI_SEACHNEXT() actually returns long */
970 	return (gint) SSM(sci, SCI_SEARCHNEXT, (uptr_t) flags, (sptr_t) text);
971 }
972 
973 
sci_search_prev(ScintillaObject * sci,gint flags,const gchar * text)974 gint sci_search_prev(ScintillaObject *sci, gint flags, const gchar *text)
975 {
976 	/* FIXME: SCI_SEACHPREV() actually returns long */
977 	return (gint) SSM(sci, SCI_SEARCHPREV, (uptr_t) flags, (sptr_t) text);
978 }
979 
980 
981 /** Finds text in the document.
982  * The @a ttf argument should be a pointer to a Sci_TextToFind structure which contains
983  * the text to find and the range in which the text should be searched.
984  *
985  * Please refer to the Scintilla documentation for a more detailed description.
986  *
987  * @param sci Scintilla widget.
988  * @param flags Bitmask of Scintilla search flags (@c SCFIND_*, see Scintilla documentation).
989  * @param ttf Pointer to a TextToFind structure which contains the text to find and the range.
990  * @return The position of the start of the found text if it succeeds, otherwise @c -1.
991  *         The @c chrgText.cpMin and @c chrgText.cpMax members of @c TextToFind are filled in
992  *         with the start and end positions of the found text.
993  */
994 GEANY_API_SYMBOL
sci_find_text(ScintillaObject * sci,gint flags,struct Sci_TextToFind * ttf)995 gint sci_find_text(ScintillaObject *sci, gint flags, struct Sci_TextToFind *ttf)
996 {
997 	return (gint) SSM(sci, SCI_FINDTEXT, (uptr_t) flags, (sptr_t) ttf);
998 }
999 
1000 /* * Sets the font for a particular style.
1001  * @param sci Scintilla widget.
1002  * @param style The style.
1003  * @param font The font name.
1004  * @param size The font (fractional) size. */
sci_set_font_fractional(ScintillaObject * sci,gint style,const gchar * font,gdouble size)1005 void sci_set_font_fractional(ScintillaObject *sci, gint style, const gchar *font, gdouble size)
1006 {
1007 	SSM(sci, SCI_STYLESETFONT, (uptr_t) style, (sptr_t) font);
1008 
1009 	/* Adding 0.5 is for rounding. */
1010 	SSM(sci, SCI_STYLESETSIZEFRACTIONAL, (uptr_t) style, (sptr_t) (SC_FONT_SIZE_MULTIPLIER * size + 0.5));
1011 }
1012 
1013 /** Sets the font for a particular style.
1014  * @param sci Scintilla widget.
1015  * @param style The style.
1016  * @param font The font name.
1017  * @param size The font size. */
1018 GEANY_API_SYMBOL
sci_set_font(ScintillaObject * sci,gint style,const gchar * font,gint size)1019 void sci_set_font(ScintillaObject *sci, gint style, const gchar *font, gint size)
1020 {
1021 	sci_set_font_fractional(sci, style, font, size);
1022 }
1023 
1024 
1025 /** Jumps to the specified line in the document.
1026  * If @a unfold is set and @a line is hidden by a fold, it is unfolded
1027  * first to ensure it is visible.
1028  * @param sci Scintilla widget.
1029  * @param line Line.
1030  * @param unfold Whether to unfold first.
1031  */
1032 GEANY_API_SYMBOL
sci_goto_line(ScintillaObject * sci,gint line,gboolean unfold)1033 void sci_goto_line(ScintillaObject *sci, gint line, gboolean unfold)
1034 {
1035 	if (unfold) SSM(sci, SCI_ENSUREVISIBLE, (uptr_t) line, 0);
1036 	SSM(sci, SCI_GOTOLINE, (uptr_t) line, 0);
1037 }
1038 
1039 
sci_marker_delete_all(ScintillaObject * sci,gint marker)1040 void sci_marker_delete_all(ScintillaObject *sci, gint marker)
1041 {
1042 	SSM(sci, SCI_MARKERDELETEALL, (uptr_t) marker, 0);
1043 }
1044 
1045 
1046 /** Gets style ID at @a position.
1047  * @param sci Scintilla widget.
1048  * @param position Position.
1049  * @return Style ID. */
1050 GEANY_API_SYMBOL
sci_get_style_at(ScintillaObject * sci,gint position)1051 gint sci_get_style_at(ScintillaObject *sci, gint position)
1052 {
1053 	return (gint) SSM(sci, SCI_GETSTYLEAT, (uptr_t) position, 0);
1054 }
1055 
1056 
sci_set_codepage(ScintillaObject * sci,gint cp)1057 void sci_set_codepage(ScintillaObject *sci, gint cp)
1058 {
1059 	g_return_if_fail(cp == 0 || cp == SC_CP_UTF8);
1060 	SSM(sci, SCI_SETCODEPAGE, (uptr_t) cp, 0);
1061 }
1062 
1063 
sci_assign_cmdkey(ScintillaObject * sci,gint key,gint command)1064 void sci_assign_cmdkey(ScintillaObject *sci, gint key, gint command)
1065 {
1066 	SSM(sci, SCI_ASSIGNCMDKEY, (uptr_t) key, command);
1067 }
1068 
1069 
sci_clear_cmdkey(ScintillaObject * sci,gint key)1070 void sci_clear_cmdkey(ScintillaObject *sci, gint key)
1071 {
1072 	SSM(sci, SCI_CLEARCMDKEY, (uptr_t) key, 0);
1073 }
1074 
1075 
1076 /** Gets text between @a start and @a end.
1077  * @deprecated sci_get_text_range is deprecated and should not be used in newly-written code.
1078  * Use sci_get_contents_range() instead.
1079  *
1080  * @param sci Scintilla widget.
1081  * @param start Start.
1082  * @param end End.
1083  * @param text Text will be zero terminated and must be allocated (end - start + 1) bytes. */
1084 GEANY_API_SYMBOL
sci_get_text_range(ScintillaObject * sci,gint start,gint end,gchar * text)1085 void sci_get_text_range(ScintillaObject *sci, gint start, gint end, gchar *text)
1086 {
1087 	struct Sci_TextRange tr;
1088 	tr.chrg.cpMin = start;
1089 	tr.chrg.cpMax = end;
1090 	tr.lpstrText = text;
1091 	SSM(sci, SCI_GETTEXTRANGE, 0, (sptr_t) &tr);
1092 }
1093 
1094 
1095 /** Gets text between @a start and @a end.
1096  * @param sci Scintilla widget.
1097  * @param start Start position.
1098  * @param end End position.
1099  * @return The text inside the given range. Should be freed when no longer needed.
1100  *
1101  * @since 0.17
1102  */
1103 GEANY_API_SYMBOL
sci_get_contents_range(ScintillaObject * sci,gint start,gint end)1104 gchar *sci_get_contents_range(ScintillaObject *sci, gint start, gint end)
1105 {
1106 	gchar *text;
1107 
1108 	g_return_val_if_fail(start < end, NULL);
1109 
1110 	text = g_malloc((gsize) (end - start) + 1);
1111 	sci_get_text_range(sci, start, end, text);
1112 	return text;
1113 }
1114 
1115 
sci_line_duplicate(ScintillaObject * sci)1116 void sci_line_duplicate(ScintillaObject *sci)
1117 {
1118 	SSM(sci, SCI_LINEDUPLICATE, 0, 0);
1119 }
1120 
1121 
sci_selection_duplicate(ScintillaObject * sci)1122 void sci_selection_duplicate(ScintillaObject *sci)
1123 {
1124 	SSM(sci, SCI_SELECTIONDUPLICATE, 0, 0);
1125 }
1126 
1127 
1128 /** Inserts text.
1129  * @param sci Scintilla widget.
1130  * @param pos Position, or -1 for current.
1131  * @param text Text. */
1132 GEANY_API_SYMBOL
sci_insert_text(ScintillaObject * sci,gint pos,const gchar * text)1133 void sci_insert_text(ScintillaObject *sci, gint pos, const gchar *text)
1134 {
1135 	SSM(sci, SCI_INSERTTEXT, (uptr_t) pos, (sptr_t) text);
1136 }
1137 
1138 
1139 GEANY_API_SYMBOL
sci_set_target_start(ScintillaObject * sci,gint start)1140 void sci_set_target_start(ScintillaObject *sci, gint start)
1141 {
1142 	SSM(sci, SCI_SETTARGETSTART, (uptr_t) start, 0);
1143 }
1144 
1145 
1146 GEANY_API_SYMBOL
sci_set_target_end(ScintillaObject * sci,gint end)1147 void sci_set_target_end(ScintillaObject *sci, gint end)
1148 {
1149 	SSM(sci, SCI_SETTARGETEND, (uptr_t) end, 0);
1150 }
1151 
1152 
1153 GEANY_API_SYMBOL
sci_replace_target(ScintillaObject * sci,const gchar * text,gboolean regex)1154 gint sci_replace_target(ScintillaObject *sci, const gchar *text, gboolean regex)
1155 {
1156 	return (gint) SSM(sci, (regex) ? SCI_REPLACETARGETRE : SCI_REPLACETARGET, (uptr_t) -1, (sptr_t) text);
1157 }
1158 
1159 
sci_set_keywords(ScintillaObject * sci,guint k,const gchar * text)1160 void sci_set_keywords(ScintillaObject *sci, guint k, const gchar *text)
1161 {
1162 	SSM(sci, SCI_SETKEYWORDS, k, (sptr_t) text);
1163 }
1164 
1165 
sci_set_readonly(ScintillaObject * sci,gboolean readonly)1166 void sci_set_readonly(ScintillaObject *sci, gboolean readonly)
1167 {
1168 	SSM(sci, SCI_SETREADONLY, readonly != FALSE, 0);
1169 }
1170 
1171 
1172 /** Sends Scintilla commands without any parameters.
1173  * @param sci The Scintilla @c GtkWidget.
1174  * @param cmd @c SCI_COMMAND.
1175  * @see http://scintilla.org for the documentation.
1176  *
1177  *  @since 0.16
1178  */
1179 GEANY_API_SYMBOL
sci_send_command(ScintillaObject * sci,gint cmd)1180 void sci_send_command(ScintillaObject *sci, gint cmd)
1181 {
1182 	SSM(sci, cmd, 0, 0);
1183 }
1184 
1185 
1186 /** Gets current line number.
1187  * @param sci Scintilla widget.
1188  * @return Line number. */
1189 GEANY_API_SYMBOL
sci_get_current_line(ScintillaObject * sci)1190 gint sci_get_current_line(ScintillaObject *sci)
1191 {
1192 	return (gint) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) SSM(sci, SCI_GETCURRENTPOS, 0, 0), 0);
1193 }
1194 
1195 
1196 /* Get number of lines partially or fully selected.
1197  * Returns 1 if there is a partial selection on the same line.
1198  * Returns 2 if a whole line is selected including the line break char(s). */
sci_get_lines_selected(ScintillaObject * sci)1199 gint sci_get_lines_selected(ScintillaObject *sci)
1200 {
1201 	gint start = (gint) SSM(sci, SCI_GETSELECTIONSTART, 0, 0);
1202 	gint end = (gint) SSM(sci, SCI_GETSELECTIONEND, 0, 0);
1203 	gint line_start;
1204 	gint line_end;
1205 
1206 	if (start == end)
1207 		return 0; /* no selection */
1208 
1209 	line_start = (gint) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) start, 0);
1210 	line_end = (gint) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) end, 0);
1211 
1212 	return line_end - line_start + 1;
1213 }
1214 
1215 
sci_get_first_visible_line(ScintillaObject * sci)1216 gint sci_get_first_visible_line(ScintillaObject *sci)
1217 {
1218 	return (gint) SSM(sci, SCI_GETFIRSTVISIBLELINE, 0, 0);
1219 }
1220 
1221 
1222 /**
1223  *  Sets the current indicator. This is necessary to define an indicator for a range of text or
1224  *  clearing indicators for a range of text.
1225  *
1226  *  @param sci Scintilla widget.
1227  *  @param indic The indicator number to set.
1228  *
1229  *  @see sci_indicator_clear
1230  *
1231  *  @since 0.16
1232  */
1233 GEANY_API_SYMBOL
sci_indicator_set(ScintillaObject * sci,gint indic)1234 void sci_indicator_set(ScintillaObject *sci, gint indic)
1235 {
1236 	SSM(sci, SCI_SETINDICATORCURRENT, (uptr_t) indic, 0);
1237 }
1238 
1239 
sci_indicator_fill(ScintillaObject * sci,gint pos,gint len)1240 void sci_indicator_fill(ScintillaObject *sci, gint pos, gint len)
1241 {
1242 	SSM(sci, SCI_INDICATORFILLRANGE, (uptr_t) pos, len);
1243 }
1244 
1245 
1246 /**
1247  *  Clears the currently set indicator from a range of text.
1248  *  Starting at @a pos, @a len characters long.
1249  *  In order to make this function properly, you need to set the current indicator before with
1250  *  @ref sci_indicator_set().
1251  *
1252  *  @param sci Scintilla widget.
1253  *  @param pos Starting position.
1254  *  @param len Length.
1255  *
1256  *  @since 0.16
1257  */
1258 GEANY_API_SYMBOL
sci_indicator_clear(ScintillaObject * sci,gint pos,gint len)1259 void sci_indicator_clear(ScintillaObject *sci, gint pos, gint len)
1260 {
1261 	SSM(sci, SCI_INDICATORCLEARRANGE, (uptr_t) pos, len);
1262 }
1263 
1264 
sci_select_all(ScintillaObject * sci)1265 void sci_select_all(ScintillaObject *sci)
1266 {
1267 	SSM(sci, SCI_SELECTALL, 0, 0);
1268 }
1269 
1270 
sci_get_line_indent_position(ScintillaObject * sci,gint line)1271 gint sci_get_line_indent_position(ScintillaObject *sci, gint line)
1272 {
1273 	return (gint) SSM(sci, SCI_GETLINEINDENTPOSITION, (uptr_t) line, 0);
1274 }
1275 
1276 
sci_set_autoc_max_height(ScintillaObject * sci,gint val)1277 void sci_set_autoc_max_height(ScintillaObject *sci, gint val)
1278 {
1279 	SSM(sci, SCI_AUTOCSETMAXHEIGHT, (uptr_t) val, 0);
1280 }
1281 
1282 
1283 /** Finds a matching brace at @a pos.
1284  * @param sci Scintilla widget.
1285  * @param pos Position.
1286  * @return Matching brace position.
1287  *
1288  * @since 0.15
1289  **/
1290 GEANY_API_SYMBOL
sci_find_matching_brace(ScintillaObject * sci,gint pos)1291 gint sci_find_matching_brace(ScintillaObject *sci, gint pos)
1292 {
1293 	return (gint) SSM(sci, SCI_BRACEMATCH, (uptr_t) pos, 0);
1294 }
1295 
1296 
sci_get_overtype(ScintillaObject * sci)1297 gint sci_get_overtype(ScintillaObject *sci)
1298 {
1299 	return (gint) SSM(sci, SCI_GETOVERTYPE, 0, 0);
1300 }
1301 
1302 
sci_set_tab_indents(ScintillaObject * sci,gboolean set)1303 void sci_set_tab_indents(ScintillaObject *sci, gboolean set)
1304 {
1305 	SSM(sci, SCI_SETTABINDENTS, set != FALSE, 0);
1306 }
1307 
1308 
sci_set_use_tabs(ScintillaObject * sci,gboolean set)1309 void sci_set_use_tabs(ScintillaObject *sci, gboolean set)
1310 {
1311 	SSM(sci, SCI_SETUSETABS, set != FALSE, 0);
1312 }
1313 
1314 
sci_get_pos_at_line_sel_start(ScintillaObject * sci,gint line)1315 gint sci_get_pos_at_line_sel_start(ScintillaObject *sci, gint line)
1316 {
1317 	return (gint) SSM(sci, SCI_GETLINESELSTARTPOSITION, (uptr_t) line, 0);
1318 }
1319 
1320 
sci_get_pos_at_line_sel_end(ScintillaObject * sci,gint line)1321 gint sci_get_pos_at_line_sel_end(ScintillaObject *sci, gint line)
1322 {
1323 	return (gint) SSM(sci, SCI_GETLINESELENDPOSITION, (uptr_t) line, 0);
1324 }
1325 
1326 
1327 /** Gets selection mode.
1328  * @param sci Scintilla widget.
1329  * @return Selection mode. */
1330 GEANY_API_SYMBOL
sci_get_selection_mode(ScintillaObject * sci)1331 gint sci_get_selection_mode(ScintillaObject *sci)
1332 {
1333 	return (gint) SSM(sci, SCI_GETSELECTIONMODE, 0, 0);
1334 }
1335 
1336 
1337 /** Sets selection mode.
1338  * @param sci Scintilla widget.
1339  * @param mode Mode. */
1340 GEANY_API_SYMBOL
sci_set_selection_mode(ScintillaObject * sci,gint mode)1341 void sci_set_selection_mode(ScintillaObject *sci, gint mode)
1342 {
1343 	SSM(sci, SCI_SETSELECTIONMODE, (uptr_t) mode, 0);
1344 }
1345 
1346 
sci_set_scrollbar_mode(ScintillaObject * sci,gboolean visible)1347 void sci_set_scrollbar_mode(ScintillaObject *sci, gboolean visible)
1348 {
1349 	SSM(sci, SCI_SETHSCROLLBAR, visible != FALSE, 0);
1350 	SSM(sci, SCI_SETVSCROLLBAR, visible != FALSE, 0);
1351 }
1352 
1353 
1354 /** Sets the indentation of a line.
1355  * @param sci Scintilla widget.
1356  * @param line Line to indent.
1357  * @param indent Indentation width.
1358  *
1359  * @since 0.19
1360  */
1361 GEANY_API_SYMBOL
sci_set_line_indentation(ScintillaObject * sci,gint line,gint indent)1362 void sci_set_line_indentation(ScintillaObject *sci, gint line, gint indent)
1363 {
1364 	SSM(sci, SCI_SETLINEINDENTATION, (uptr_t) line, indent);
1365 }
1366 
1367 
1368 /** Gets the indentation width of a line.
1369  * @param sci Scintilla widget.
1370  * @param line Line to get the indentation from.
1371  * @return Indentation width.
1372  *
1373  * @since 0.19
1374  */
1375 GEANY_API_SYMBOL
sci_get_line_indentation(ScintillaObject * sci,gint line)1376 gint sci_get_line_indentation(ScintillaObject *sci, gint line)
1377 {
1378 	return (gint) SSM(sci, SCI_GETLINEINDENTATION, (uptr_t) line, 0);
1379 }
1380 
1381 
sci_set_caret_policy_x(ScintillaObject * sci,gint policy,gint slop)1382 void sci_set_caret_policy_x(ScintillaObject *sci, gint policy, gint slop)
1383 {
1384 	SSM(sci, SCI_SETXCARETPOLICY, (uptr_t) policy, slop);
1385 }
1386 
1387 
sci_set_caret_policy_y(ScintillaObject * sci,gint policy,gint slop)1388 void sci_set_caret_policy_y(ScintillaObject *sci, gint policy, gint slop)
1389 {
1390 	SSM(sci, SCI_SETYCARETPOLICY, (uptr_t) policy, slop);
1391 }
1392 
1393 
sci_set_scroll_stop_at_last_line(ScintillaObject * sci,gboolean set)1394 void sci_set_scroll_stop_at_last_line(ScintillaObject *sci, gboolean set)
1395 {
1396 	SSM(sci, SCI_SETENDATLASTLINE, set != FALSE, 0);
1397 }
1398 
1399 
sci_cancel(ScintillaObject * sci)1400 void sci_cancel(ScintillaObject *sci)
1401 {
1402 	SSM(sci, SCI_CANCEL, 0, 0);
1403 }
1404 
1405 
sci_get_position_after(ScintillaObject * sci,gint start)1406 gint sci_get_position_after(ScintillaObject *sci, gint start)
1407 {
1408 	return (gint) SSM(sci, SCI_POSITIONAFTER, (uptr_t) start, 0);
1409 }
1410 
1411 
sci_lines_join(ScintillaObject * sci)1412 void sci_lines_join(ScintillaObject *sci)
1413 {
1414 	SSM(sci, SCI_LINESJOIN, 0, 0);
1415 }
1416 
1417 
sci_text_width(ScintillaObject * sci,gint styleNumber,const gchar * text)1418 gint sci_text_width(ScintillaObject *sci, gint styleNumber, const gchar *text)
1419 {
1420 	return (gint) SSM(sci, SCI_TEXTWIDTH, (uptr_t) styleNumber, (sptr_t) text);
1421 }
1422 
1423 
sci_move_selected_lines_down(ScintillaObject * sci)1424 void sci_move_selected_lines_down(ScintillaObject *sci)
1425 {
1426 	SSM(sci, SCI_MOVESELECTEDLINESDOWN, 0, 0);
1427 }
1428 
1429 
sci_move_selected_lines_up(ScintillaObject * sci)1430 void sci_move_selected_lines_up(ScintillaObject *sci)
1431 {
1432 	SSM(sci, SCI_MOVESELECTEDLINESUP, 0, 0);
1433 }
1434 
1435 
sci_word_start_position(ScintillaObject * sci,gint position,gboolean onlyWordCharacters)1436 gint sci_word_start_position(ScintillaObject *sci, gint position, gboolean onlyWordCharacters)
1437 {
1438 	return SSM(sci, SCI_WORDSTARTPOSITION, position, onlyWordCharacters);
1439 }
1440 
1441 
sci_word_end_position(ScintillaObject * sci,gint position,gboolean onlyWordCharacters)1442 gint sci_word_end_position(ScintillaObject *sci, gint position, gboolean onlyWordCharacters)
1443 {
1444 	return SSM(sci, SCI_WORDENDPOSITION, position, onlyWordCharacters);
1445 }
1446 
1447