Fix warning
[geany-mirror.git] / src / sciwrappers.c
blob07370a788d3fbc1dc36495f1732d529af1d5a637
1 /*
2 * sciwrappers.c - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2005 The Geany contributors
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.
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.
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.
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.
25 * To get Scintilla notifications, use the
26 * @link pluginsignals.c @c "editor-notify" signal @endlink.
28 * @note These functions were originally from the cssed project
29 * (http://cssed.sf.net, thanks).
30 * @see scintilla_send_message().
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
37 #include "sciwrappers.h"
38 #include <Lexilla.h> /* ILexer5 */
40 #include "utils.h"
42 #include <string.h>
45 #ifndef NDEBUG
47 sptr_t sci_send_message_internal (const gchar *file, guint line, ScintillaObject *sci,
48 guint msg, uptr_t wparam, sptr_t lparam)
50 sptr_t result;
51 gint status;
53 scintilla_send_message(sci, SCI_SETSTATUS, 0, 0);
54 result = scintilla_send_message(sci, msg, wparam, lparam);
55 status = scintilla_send_message(sci, SCI_GETSTATUS, 0, 0);
57 if (status != 0)
59 const gchar *sub_msg = "unknown";
60 switch (status)
62 case SC_STATUS_FAILURE:
63 sub_msg = "generic failure";
64 break;
65 case SC_STATUS_BADALLOC:
66 sub_msg = "memory is exhausted";
67 break;
68 case SC_STATUS_WARN_REGEX:
69 sub_msg = "regular expression is invalid";
70 break;
71 default:
72 if (status >= SC_STATUS_WARN_START)
73 sub_msg = "unknown warning";
74 else
75 sub_msg = "unknown failure";
76 break;
78 #define SCI_STATUS_FORMAT_STRING "%s:%u: scintilla has non-zero status " \
79 "code '%d' after sending message '%u' to instance '%p' with " \
80 "wParam='%lu' and lParam='%ld': %s"
81 if (status >= SC_STATUS_WARN_START)
83 g_warning(SCI_STATUS_FORMAT_STRING, file, line, status, msg,
84 (gpointer)sci, wparam, lparam, sub_msg);
86 else
88 g_critical(SCI_STATUS_FORMAT_STRING, file, line, status, msg,
89 (gpointer)sci, wparam, lparam, sub_msg);
93 return result;
95 #endif
98 /* line numbers visibility */
99 void sci_set_line_numbers(ScintillaObject *sci, gboolean set)
101 if (set)
103 gchar tmp_str[15];
104 gint len = (gint) SSM(sci, SCI_GETLINECOUNT, 0, 0);
105 gint width;
107 g_snprintf(tmp_str, 15, "_%d", len);
108 width = sci_text_width(sci, STYLE_LINENUMBER, tmp_str);
109 SSM(sci, SCI_SETMARGINWIDTHN, 0, width);
110 SSM(sci, SCI_SETMARGINSENSITIVEN, 0, FALSE); /* use default behaviour */
112 else
114 SSM(sci, SCI_SETMARGINWIDTHN, 0, 0);
119 void sci_set_mark_long_lines(ScintillaObject *sci, gint type, gint column, const gchar *colour)
121 glong colour_val = utils_parse_color_to_bgr(colour); /* Scintilla uses a "long" value */
123 if (column == 0)
124 type = 2;
125 switch (type)
127 case 0:
129 SSM(sci, SCI_SETEDGEMODE, EDGE_LINE, 0);
130 break;
132 case 1:
134 SSM(sci, SCI_SETEDGEMODE, EDGE_BACKGROUND, 0);
135 break;
137 case 2:
139 SSM(sci, SCI_SETEDGEMODE, EDGE_NONE, 0);
140 return;
143 SSM(sci, SCI_SETEDGECOLUMN, (uptr_t) column, 0);
144 SSM(sci, SCI_SETEDGECOLOUR, (uptr_t) colour_val, 0);
148 /* Calls SCI_TEXTHEIGHT but tries very hard to cache the result as it's a very
149 * expensive operation */
150 static gint sci_text_height_cached(ScintillaObject *sci)
152 struct height_spec {
153 gchar *font;
154 gint size;
155 gint zoom;
156 gint extra;
158 static struct height_spec cache = {0};
159 static gint cache_value = 0;
160 struct height_spec current;
162 current.font = sci_get_string(sci, SCI_STYLEGETFONT, 0);
163 current.size = SSM(sci, SCI_STYLEGETSIZEFRACTIONAL, 0, 0);
164 current.zoom = SSM(sci, SCI_GETZOOM, 0, 0);
165 current.extra = SSM(sci, SCI_GETEXTRAASCENT, 0, 0) + SSM(sci, SCI_GETEXTRADESCENT, 0, 0);
167 if (g_strcmp0(current.font, cache.font) == 0 &&
168 current.size == cache.size &&
169 current.zoom == cache.zoom &&
170 current.extra == cache.extra)
172 g_free(current.font);
174 else
176 g_free(cache.font);
177 cache = current;
179 cache_value = SSM(sci, SCI_TEXTHEIGHT, 0, 0);
182 return cache_value;
185 /* compute margin width based on ratio of line height */
186 static gint margin_width_from_line_height(ScintillaObject *sci, gdouble ratio, gint threshold)
188 const gint line_height = sci_text_height_cached(sci);
189 gint width;
191 width = line_height * ratio;
192 /* round down to an even size */
193 width = width - (width % 2);
194 /* if under threshold, just use the line height */
195 if (width < threshold)
196 width = MIN(threshold, line_height);
198 return width;
202 /* symbol margin visibility */
203 void sci_set_symbol_margin(ScintillaObject *sci, gboolean set)
205 if (set)
207 const gint width = margin_width_from_line_height(sci, 0.88, 16);
209 SSM(sci, SCI_SETMARGINWIDTHN, 1, width);
210 SSM(sci, SCI_SETMARGINSENSITIVEN, 1, TRUE);
212 else
214 SSM(sci, SCI_SETMARGINWIDTHN, 1, 0);
215 SSM(sci, SCI_SETMARGINSENSITIVEN, 1, FALSE);
220 /* folding margin visibility */
221 void sci_set_folding_margin_visible(ScintillaObject *sci, gboolean set)
223 if (set)
225 const gint width = margin_width_from_line_height(sci, 0.66, 12);
227 SSM(sci, SCI_SETMARGINWIDTHN, 2, width);
228 SSM(sci, SCI_SETMARGINSENSITIVEN, 2, TRUE);
230 else
232 SSM(sci, SCI_SETMARGINSENSITIVEN, 2, FALSE);
233 SSM(sci, SCI_SETMARGINWIDTHN, 2, 0);
238 /* end of lines */
239 void sci_set_visible_eols(ScintillaObject *sci, gboolean set)
241 SSM(sci, SCI_SETVIEWEOL, set != FALSE, 0);
245 void sci_set_visible_white_spaces(ScintillaObject *sci, gboolean set)
247 if (set)
248 SSM(sci, SCI_SETVIEWWS, SCWS_VISIBLEALWAYS, 0);
249 else
250 SSM(sci, SCI_SETVIEWWS, SCWS_INVISIBLE, 0);
254 void sci_set_lines_wrapped(ScintillaObject *sci, gboolean set)
256 if (set)
257 SSM(sci, SCI_SETWRAPMODE, SC_WRAP_WORD, 0);
258 else
259 SSM(sci, SCI_SETWRAPMODE, SC_WRAP_NONE, 0);
263 gint sci_get_eol_mode(ScintillaObject *sci)
265 return (gint) SSM(sci, SCI_GETEOLMODE, 0, 0);
269 void sci_set_eol_mode(ScintillaObject *sci, gint eolmode)
271 SSM(sci, SCI_SETEOLMODE, (uptr_t) eolmode, 0);
275 void sci_convert_eols(ScintillaObject *sci, gint eolmode)
277 SSM(sci, SCI_CONVERTEOLS, (uptr_t) eolmode, 0);
281 void sci_add_text(ScintillaObject *sci, const gchar *text)
283 if (text != NULL)
284 { /* if null text is passed scintilla will segfault */
285 SSM(sci, SCI_ADDTEXT, strlen(text), (sptr_t) text);
290 /** Sets all text.
291 * @param sci Scintilla widget.
292 * @param text Text. */
293 GEANY_API_SYMBOL
294 void sci_set_text(ScintillaObject *sci, const gchar *text)
296 if( text != NULL ){ /* if null text is passed to scintilla will segfault */
297 SSM(sci, SCI_SETTEXT, 0, (sptr_t) text);
302 gboolean sci_can_undo(ScintillaObject *sci)
304 return SSM(sci, SCI_CANUNDO, 0, 0) != FALSE;
308 gboolean sci_can_redo(ScintillaObject *sci)
310 return SSM(sci, SCI_CANREDO, 0, 0) != FALSE;
314 void sci_undo(ScintillaObject *sci)
316 if (sci_can_undo(sci))
317 SSM(sci, SCI_UNDO, 0, 0);
321 void sci_redo(ScintillaObject *sci)
323 if (sci_can_redo(sci))
324 SSM(sci, SCI_REDO, 0, 0);
328 /** Begins grouping a set of edits together as one Undo action.
329 * You must call sci_end_undo_action() after making your edits.
330 * @param sci Scintilla @c GtkWidget. */
331 GEANY_API_SYMBOL
332 void sci_start_undo_action(ScintillaObject *sci)
334 SSM(sci, SCI_BEGINUNDOACTION, 0, 0);
338 /** Ends grouping a set of edits together as one Undo action.
339 * @param sci Scintilla @c GtkWidget.
340 * @see sci_start_undo_action(). */
341 GEANY_API_SYMBOL
342 void sci_end_undo_action(ScintillaObject *sci)
344 SSM(sci, SCI_ENDUNDOACTION, 0, 0);
348 void sci_set_undo_collection(ScintillaObject *sci, gboolean set)
350 SSM(sci, SCI_SETUNDOCOLLECTION, set != FALSE, 0);
354 void sci_empty_undo_buffer(ScintillaObject *sci)
356 SSM(sci, SCI_EMPTYUNDOBUFFER, 0, 0);
360 gboolean sci_is_modified(ScintillaObject *sci)
362 return (SSM(sci, SCI_GETMODIFY, 0, 0) != 0);
366 void sci_zoom_in(ScintillaObject *sci)
368 SSM(sci, SCI_ZOOMIN, 0, 0);
372 void sci_zoom_out(ScintillaObject *sci)
374 SSM(sci, SCI_ZOOMOUT, 0, 0);
378 void sci_zoom_off(ScintillaObject *sci)
380 SSM(sci, SCI_SETZOOM, 0, 0);
384 /** Sets a line marker.
385 * @param sci Scintilla widget.
386 * @param line_number Line number.
387 * @param marker Marker number. */
388 GEANY_API_SYMBOL
389 void sci_set_marker_at_line(ScintillaObject *sci, gint line_number, gint marker)
391 SSM(sci, SCI_MARKERADD, (uptr_t) line_number, marker);
395 /** Deletes a line marker.
396 * @param sci Scintilla widget.
397 * @param line_number Line number.
398 * @param marker Marker number. */
399 GEANY_API_SYMBOL
400 void sci_delete_marker_at_line(ScintillaObject *sci, gint line_number, gint marker)
402 SSM(sci, SCI_MARKERDELETE, (uptr_t) line_number, marker);
406 /** Checks if a line has a marker set.
407 * @param sci Scintilla widget.
408 * @param line Line number.
409 * @param marker Marker number.
410 * @return Whether it's set. */
411 GEANY_API_SYMBOL
412 gboolean sci_is_marker_set_at_line(ScintillaObject *sci, gint line, gint marker)
414 gint state;
416 state = (gint) SSM(sci, SCI_MARKERGET, (uptr_t) line, 0);
417 return (state & (1 << marker));
421 void sci_toggle_marker_at_line(ScintillaObject *sci, gint line, gint marker)
423 gboolean set = sci_is_marker_set_at_line(sci, line, marker);
425 if (!set)
426 sci_set_marker_at_line(sci, line, marker);
427 else
428 sci_delete_marker_at_line(sci, line, marker);
432 /* Returns the line number of the next marker that matches marker_mask, or -1.
433 * marker_mask is a bitor of 1 << marker_index. (See MarkerHandleSet::MarkValue()).
434 * Note: If there is a marker on the line, it returns the same line. */
435 gint sci_marker_next(ScintillaObject *sci, gint line, gint marker_mask, gboolean wrap)
437 gint marker_line;
439 marker_line = (gint) SSM(sci, SCI_MARKERNEXT, (uptr_t) line, marker_mask);
440 if (wrap && marker_line == -1)
441 marker_line = (gint) SSM(sci, SCI_MARKERNEXT, 0, marker_mask);
442 return marker_line;
446 /* Returns the line number of the previous marker that matches marker_mask, or -1.
447 * marker_mask is a bitor of 1 << marker_index. (See MarkerHandleSet::MarkValue()).
448 * Note: If there is a marker on the line, it returns the same line. */
449 gint sci_marker_previous(ScintillaObject *sci, gint line, gint marker_mask, gboolean wrap)
451 gint marker_line;
453 marker_line = (gint) SSM(sci, SCI_MARKERPREVIOUS, (uptr_t) line, marker_mask);
454 if (wrap && marker_line == -1)
456 gint len = sci_get_length(sci);
457 gint last_line = sci_get_line_from_position(sci, len - 1);
459 marker_line = (gint) SSM(sci, SCI_MARKERPREVIOUS, (uptr_t) last_line, marker_mask);
461 return marker_line;
465 /** Gets the line number from @a position.
466 * @param sci Scintilla widget.
467 * @param position Position.
468 * @return The line. */
469 GEANY_API_SYMBOL
470 gint sci_get_line_from_position(ScintillaObject *sci, gint position)
472 return (gint) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) position, 0);
476 /** Gets the column number relative to the start of the line that @a position is on.
477 * @param sci Scintilla widget.
478 * @param position Position.
479 * @return The column. */
480 GEANY_API_SYMBOL
481 gint sci_get_col_from_position(ScintillaObject *sci, gint position)
483 return (gint) SSM(sci, SCI_GETCOLUMN, (uptr_t) position, 0);
487 gint sci_get_position_from_col(ScintillaObject *sci, gint line, gint col)
489 return (gint) SSM(sci, SCI_FINDCOLUMN, line, col);
493 /** Gets the position for the start of @a line.
494 * @param sci Scintilla widget.
495 * @param line Line.
496 * @return Position. */
497 GEANY_API_SYMBOL
498 gint sci_get_position_from_line(ScintillaObject *sci, gint line)
500 return (gint) SSM(sci, SCI_POSITIONFROMLINE, (uptr_t) line, 0);
504 /** Gets the cursor position.
505 * @param sci Scintilla widget.
506 * @return Position. */
507 GEANY_API_SYMBOL
508 gint sci_get_current_position(ScintillaObject *sci)
510 return (gint) SSM(sci, SCI_GETCURRENTPOS, 0, 0);
514 gint sci_get_cursor_virtual_space(ScintillaObject *sci)
516 gint selection_mode = sci_get_selection_mode(sci);
518 return selection_mode == SC_SEL_RECTANGLE || selection_mode == SC_SEL_THIN ?
519 SSM(sci, SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE, 0, 0) :
520 SSM(sci, SCI_GETSELECTIONNCARETVIRTUALSPACE,
521 SSM(sci, SCI_GETMAINSELECTION, 0, 0), 0);
525 /** Sets the cursor position.
526 * @param sci Scintilla widget.
527 * @param position Position.
528 * @param scroll_to_caret Whether to scroll the cursor in view. */
529 GEANY_API_SYMBOL
530 void sci_set_current_position(ScintillaObject *sci, gint position, gboolean scroll_to_caret)
532 if (scroll_to_caret)
533 SSM(sci, SCI_GOTOPOS, (uptr_t) position, 0);
534 else
536 SSM(sci, SCI_SETCURRENTPOS, (uptr_t) position, 0);
537 SSM(sci, SCI_SETANCHOR, (uptr_t) position, 0); /* to avoid creation of a selection */
539 SSM(sci, SCI_CHOOSECARETX, 0, 0);
543 /* Set the cursor line without scrolling the view.
544 * Use sci_goto_line() to also scroll. */
545 void sci_set_current_line(ScintillaObject *sci, gint line)
547 gint pos = sci_get_position_from_line(sci, line);
548 sci_set_current_position(sci, pos, FALSE);
552 /** Gets the total number of lines.
553 * @param sci Scintilla widget.
554 * @return The line count. */
555 GEANY_API_SYMBOL
556 gint sci_get_line_count(ScintillaObject *sci)
558 return (gint) SSM(sci, SCI_GETLINECOUNT, 0, 0);
562 /** Sets the selection start position.
563 * @param sci Scintilla widget.
564 * @param position Position. */
565 GEANY_API_SYMBOL
566 void sci_set_selection_start(ScintillaObject *sci, gint position)
568 SSM(sci, SCI_SETSELECTIONSTART, (uptr_t) position, 0);
572 /** Sets the selection end position.
573 * @param sci Scintilla widget.
574 * @param position Position. */
575 GEANY_API_SYMBOL
576 void sci_set_selection_end(ScintillaObject *sci, gint position)
578 SSM(sci, SCI_SETSELECTIONEND, (uptr_t) position, 0);
582 void sci_set_selection(ScintillaObject *sci, gint anchorPos, gint currentPos)
584 SSM(sci, SCI_SETSEL, (uptr_t) anchorPos, currentPos);
588 /** Gets the position at the end of a line
589 * @param sci Scintilla widget.
590 * @param line Line.
591 * @return The position at the end of the line. */
592 GEANY_API_SYMBOL
593 gint sci_get_line_end_position(ScintillaObject *sci, gint line)
595 return (gint) SSM(sci, SCI_GETLINEENDPOSITION, (uptr_t) line, 0);
599 void sci_cut(ScintillaObject *sci)
601 SSM(sci, SCI_CUT, 0, 0);
605 void sci_copy(ScintillaObject *sci)
607 SSM(sci, SCI_COPY, 0, 0);
611 void sci_paste(ScintillaObject *sci)
613 SSM(sci, SCI_PASTE, 0, 0);
617 void sci_clear(ScintillaObject *sci)
619 SSM(sci, SCI_CLEAR, 0, 0);
623 /** Gets the selection start position.
624 * @param sci Scintilla widget.
625 * @return Position. */
626 GEANY_API_SYMBOL
627 gint sci_get_selection_start(ScintillaObject *sci)
629 return (gint) SSM(sci, SCI_GETSELECTIONSTART, 0, 0);
633 /** Gets the selection end position.
634 * @param sci Scintilla widget.
635 * @return Position. */
636 GEANY_API_SYMBOL
637 gint sci_get_selection_end(ScintillaObject *sci)
639 return (gint) SSM(sci, SCI_GETSELECTIONEND, 0, 0);
643 /** Replaces selection.
644 * @param sci Scintilla widget.
645 * @param text Text. */
646 GEANY_API_SYMBOL
647 void sci_replace_sel(ScintillaObject *sci, const gchar *text)
649 SSM(sci, SCI_REPLACESEL, 0, (sptr_t) text);
653 /** Gets the length of all text.
654 * @param sci Scintilla widget.
655 * @return Length. */
656 GEANY_API_SYMBOL
657 gint sci_get_length(ScintillaObject *sci)
659 return (gint) SSM(sci, SCI_GETLENGTH, 0, 0);
663 /** Gets the currently used lexer
664 * @param sci Scintilla widget.
665 * @returns The lexer ID
667 GEANY_API_SYMBOL
668 gint sci_get_lexer(ScintillaObject *sci)
670 return (gint) SSM(sci, SCI_GETLEXER, 0, 0);
674 void sci_set_lexer(ScintillaObject *sci, guint lexer_id)
676 gint old = sci_get_lexer(sci);
678 /* TODO, LexerNameFromID() is already deprecated */
679 ILexer5 *lexer = CreateLexer(LexerNameFromID(lexer_id));
681 SSM(sci, SCI_SETILEXER, 0, (uintptr_t) lexer);
683 if (old != (gint)lexer_id)
684 SSM(sci, SCI_CLEARDOCUMENTSTYLE, 0, 0);
688 /** Gets line length.
689 * @param sci Scintilla widget.
690 * @param line Line number.
691 * @return Length. */
692 GEANY_API_SYMBOL
693 gint sci_get_line_length(ScintillaObject *sci, gint line)
695 return (gint) SSM(sci, SCI_LINELENGTH, (uptr_t) line, 0);
699 /* safe way to read Scintilla string into new memory.
700 * works with any string buffer messages that follow the Windows message convention. */
701 gchar *sci_get_string(ScintillaObject *sci, guint msg, gulong wParam)
703 gint size = (gint) SSM(sci, msg, wParam, 0);
704 gchar *str = g_malloc(size + 1);
706 SSM(sci, msg, wParam, (sptr_t) str);
707 str[size] = '\0'; /* ensure termination, needed for SCI_GETLINE */
708 return str;
712 /** Gets line contents.
713 * @param sci Scintilla widget.
714 * @param line_num Line number.
715 * @return A @c NULL-terminated copy of the line text. */
716 GEANY_API_SYMBOL
717 gchar *sci_get_line(ScintillaObject *sci, gint line_num)
719 return sci_get_string(sci, SCI_GETLINE, (gulong) line_num);
723 /** Gets all text.
724 * @deprecated sci_get_text is deprecated and should not be used in newly-written code.
725 * Use sci_get_contents() instead.
727 * @param sci Scintilla widget.
728 * @param len Length of @a text buffer, usually sci_get_length() + 1.
729 * @param text Text buffer; must be allocated @a len bytes for null-termination. */
730 GEANY_API_SYMBOL
731 void sci_get_text(ScintillaObject *sci, gint len, gchar *text)
733 g_return_if_fail(len > 0);
734 SSM(sci, SCI_GETTEXT, (uptr_t) len - 1, (sptr_t) text);
738 /** Allocates and fills a buffer with text from the start of the document.
739 * @param sci Scintilla widget.
740 * @param buffer_len Buffer length to allocate, including the terminating
741 * null char, e.g. sci_get_length() + 1. Alternatively use @c -1 to get all
742 * text (since Geany 1.23).
743 * @return A copy of the text. Should be freed when no longer needed.
745 * @since 1.23 (0.17)
747 GEANY_API_SYMBOL
748 gchar *sci_get_contents(ScintillaObject *sci, gint buffer_len)
750 gchar *text;
752 g_return_val_if_fail(buffer_len != 0, NULL);
754 if (buffer_len < 0)
755 buffer_len = sci_get_length(sci) + 1;
757 text = g_malloc(buffer_len);
758 SSM(sci, SCI_GETTEXT, (uptr_t) buffer_len - 1, (sptr_t) text);
759 return text;
763 /** Gets selected text.
764 * @deprecated sci_get_selected_text is deprecated and should not be used in newly-written code.
765 * Use sci_get_selection_contents() instead.
767 * @note You must ensure NUL termination yourself, this function does
768 * not NUL terminate the buffer itself.
770 * @param sci Scintilla widget.
771 * @param text Text buffer; must be allocated sci_get_selected_text_length() + 1 bytes
772 * for null-termination. */
773 GEANY_API_SYMBOL
774 void sci_get_selected_text(ScintillaObject *sci, gchar *text)
776 SSM(sci, SCI_GETSELTEXT, 0, (sptr_t) text);
780 /** Gets selected text.
781 * @param sci Scintilla widget.
783 * @return The selected text. Should be freed when no longer needed.
785 * @since 0.17
787 GEANY_API_SYMBOL
788 gchar *sci_get_selection_contents(ScintillaObject *sci)
790 return sci_get_string(sci, SCI_GETSELTEXT, 0);
794 /** Gets selected text length including the terminating NUL character.
795 * @param sci Scintilla widget.
796 * @return Length. */
797 GEANY_API_SYMBOL
798 gint sci_get_selected_text_length(ScintillaObject *sci)
800 return (gint) SSM(sci, SCI_GETSELTEXT, 0, 0) + 1;
804 gint sci_get_position_from_xy(ScintillaObject *sci, gint x, gint y, gboolean nearby)
806 /* for nearby return -1 if there is no character near to the x,y point. */
807 return (gint) SSM(sci, (nearby) ? SCI_POSITIONFROMPOINTCLOSE : SCI_POSITIONFROMPOINT, (uptr_t) x, y);
811 /** Checks if a line is visible (folding may have hidden it).
812 * @param sci Scintilla widget.
813 * @param line Line number.
814 * @return Whether @a line will be drawn on the screen. */
815 GEANY_API_SYMBOL
816 gboolean sci_get_line_is_visible(ScintillaObject *sci, gint line)
818 return SSM(sci, SCI_GETLINEVISIBLE, (uptr_t) line, 0) != FALSE;
822 /** Makes @a line visible (folding may have hidden it).
823 * @param sci Scintilla widget.
824 * @param line Line number. */
825 GEANY_API_SYMBOL
826 void sci_ensure_line_is_visible(ScintillaObject *sci, gint line)
828 SSM(sci, SCI_ENSUREVISIBLE, (uptr_t) line, 0);
832 gint sci_get_fold_level(ScintillaObject *sci, gint line)
834 return (gint) SSM(sci, SCI_GETFOLDLEVEL, (uptr_t) line, 0);
838 /* Get the line number of the fold point before start_line, or -1 if there isn't one */
839 gint sci_get_fold_parent(ScintillaObject *sci, gint start_line)
841 return (gint) SSM(sci, SCI_GETFOLDPARENT, (uptr_t) start_line, 0);
845 void sci_toggle_fold(ScintillaObject *sci, gint line)
847 SSM(sci, SCI_TOGGLEFOLD, (uptr_t) line, 0);
851 gboolean sci_get_fold_expanded(ScintillaObject *sci, gint line)
853 return SSM(sci, SCI_GETFOLDEXPANDED, (uptr_t) line, 0) != FALSE;
857 void sci_colourise(ScintillaObject *sci, gint start, gint end)
859 SSM(sci, SCI_COLOURISE, (uptr_t) start, end);
863 void sci_clear_all(ScintillaObject *sci)
865 SSM(sci, SCI_CLEARALL, 0, 0);
869 gint sci_get_end_styled(ScintillaObject *sci)
871 return (gint) SSM(sci, SCI_GETENDSTYLED, 0, 0);
875 void sci_set_tab_width(ScintillaObject *sci, gint width)
877 SSM(sci, SCI_SETTABWIDTH, (uptr_t) width, 0);
881 /** Gets display tab width (this is not indent width, see GeanyIndentPrefs).
882 * @param sci Scintilla widget.
883 * @return Width.
885 * @since 0.15
887 GEANY_API_SYMBOL
888 gint sci_get_tab_width(ScintillaObject *sci)
890 return (gint) SSM(sci, SCI_GETTABWIDTH, 0, 0);
894 /** Gets a character.
895 * @param sci Scintilla widget.
896 * @param pos Position.
897 * @return Char. */
898 GEANY_API_SYMBOL
899 gchar sci_get_char_at(ScintillaObject *sci, gint pos)
901 return (gchar) SSM(sci, SCI_GETCHARAT, (uptr_t) pos, 0);
905 void sci_set_savepoint(ScintillaObject *sci)
907 SSM(sci, SCI_SETSAVEPOINT, 0, 0);
911 void sci_set_indentation_guides(ScintillaObject *sci, gint mode)
913 SSM(sci, SCI_SETINDENTATIONGUIDES, (uptr_t) mode, 0);
917 void sci_use_popup(ScintillaObject *sci, gboolean enable)
919 SSM(sci, SCI_USEPOPUP, enable != FALSE, 0);
923 /** Checks if there's a selection.
924 * @param sci Scintilla widget.
925 * @return Whether a selection is present.
927 * @since 0.15
929 GEANY_API_SYMBOL
930 gboolean sci_has_selection(ScintillaObject *sci)
932 if (SSM(sci, SCI_GETSELECTIONEND, 0, 0) - SSM(sci, SCI_GETSELECTIONSTART, 0, 0))
933 return TRUE;
934 else
935 return FALSE;
939 void sci_goto_pos(ScintillaObject *sci, gint pos, gboolean unfold)
941 if (unfold) SSM(sci, SCI_ENSUREVISIBLE, (uptr_t) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) pos, 0), 0);
942 SSM(sci, SCI_GOTOPOS, (uptr_t) pos, 0);
946 void sci_set_search_anchor(ScintillaObject *sci)
948 SSM(sci, SCI_SEARCHANCHOR, 0, 0);
952 /* removes a selection if pos < 0 */
953 void sci_set_anchor(ScintillaObject *sci, gint pos)
955 if (pos < 0)
956 pos = sci_get_current_position(sci);
958 SSM(sci, SCI_SETANCHOR, (uptr_t) pos, 0);
962 /** Scrolls the cursor in view.
963 * @param sci Scintilla widget. */
964 GEANY_API_SYMBOL
965 void sci_scroll_caret(ScintillaObject *sci)
967 SSM(sci, SCI_SCROLLCARET, 0, 0);
971 void sci_scroll_columns(ScintillaObject *sci, gint columns)
973 SSM(sci, SCI_LINESCROLL, (uptr_t) columns, 0);
977 gint sci_search_next(ScintillaObject *sci, gint flags, const gchar *text)
979 /* FIXME: SCI_SEACHNEXT() actually returns long */
980 return (gint) SSM(sci, SCI_SEARCHNEXT, (uptr_t) flags, (sptr_t) text);
984 gint sci_search_prev(ScintillaObject *sci, gint flags, const gchar *text)
986 /* FIXME: SCI_SEACHPREV() actually returns long */
987 return (gint) SSM(sci, SCI_SEARCHPREV, (uptr_t) flags, (sptr_t) text);
991 /** Finds text in the document.
992 * The @a ttf argument should be a pointer to a Sci_TextToFind structure which contains
993 * the text to find and the range in which the text should be searched.
995 * Please refer to the Scintilla documentation for a more detailed description.
997 * @param sci Scintilla widget.
998 * @param flags Bitmask of Scintilla search flags (@c SCFIND_*, see Scintilla documentation).
999 * @param ttf Pointer to a TextToFind structure which contains the text to find and the range.
1000 * @return The position of the start of the found text if it succeeds, otherwise @c -1.
1001 * The @c chrgText.cpMin and @c chrgText.cpMax members of @c TextToFind are filled in
1002 * with the start and end positions of the found text.
1004 GEANY_API_SYMBOL
1005 gint sci_find_text(ScintillaObject *sci, gint flags, struct Sci_TextToFind *ttf)
1007 return (gint) SSM(sci, SCI_FINDTEXT, (uptr_t) flags, (sptr_t) ttf);
1010 /* * Sets the font for a particular style.
1011 * @param sci Scintilla widget.
1012 * @param style The style.
1013 * @param font The font name.
1014 * @param size The font (fractional) size. */
1015 void sci_set_font_fractional(ScintillaObject *sci, gint style, const gchar *font, gdouble size)
1017 SSM(sci, SCI_STYLESETFONT, (uptr_t) style, (sptr_t) font);
1019 /* Adding 0.5 is for rounding. */
1020 SSM(sci, SCI_STYLESETSIZEFRACTIONAL, (uptr_t) style, (sptr_t) (SC_FONT_SIZE_MULTIPLIER * size + 0.5));
1023 /** Sets the font for a particular style.
1024 * @param sci Scintilla widget.
1025 * @param style The style.
1026 * @param font The font name.
1027 * @param size The font size. */
1028 GEANY_API_SYMBOL
1029 void sci_set_font(ScintillaObject *sci, gint style, const gchar *font, gint size)
1031 sci_set_font_fractional(sci, style, font, size);
1035 /** Jumps to the specified line in the document.
1036 * If @a unfold is set and @a line is hidden by a fold, it is unfolded
1037 * first to ensure it is visible.
1038 * @param sci Scintilla widget.
1039 * @param line Line.
1040 * @param unfold Whether to unfold first.
1042 GEANY_API_SYMBOL
1043 void sci_goto_line(ScintillaObject *sci, gint line, gboolean unfold)
1045 if (unfold) SSM(sci, SCI_ENSUREVISIBLE, (uptr_t) line, 0);
1046 SSM(sci, SCI_GOTOLINE, (uptr_t) line, 0);
1050 void sci_marker_delete_all(ScintillaObject *sci, gint marker)
1052 SSM(sci, SCI_MARKERDELETEALL, (uptr_t) marker, 0);
1056 /** Gets style ID at @a position.
1057 * @param sci Scintilla widget.
1058 * @param position Position.
1059 * @return Style ID. */
1060 GEANY_API_SYMBOL
1061 gint sci_get_style_at(ScintillaObject *sci, gint position)
1063 return (gint) SSM(sci, SCI_GETSTYLEAT, (uptr_t) position, 0);
1067 void sci_set_codepage(ScintillaObject *sci, gint cp)
1069 g_return_if_fail(cp == 0 || cp == SC_CP_UTF8);
1070 SSM(sci, SCI_SETCODEPAGE, (uptr_t) cp, 0);
1074 void sci_assign_cmdkey(ScintillaObject *sci, gint key, gint command)
1076 SSM(sci, SCI_ASSIGNCMDKEY, (uptr_t) key, command);
1080 void sci_clear_cmdkey(ScintillaObject *sci, gint key)
1082 SSM(sci, SCI_CLEARCMDKEY, (uptr_t) key, 0);
1086 /** Gets text between @a start and @a end.
1087 * @deprecated sci_get_text_range is deprecated and should not be used in newly-written code.
1088 * Use sci_get_contents_range() instead.
1090 * @param sci Scintilla widget.
1091 * @param start Start.
1092 * @param end End.
1093 * @param text Text will be zero terminated and must be allocated (end - start + 1) bytes. */
1094 GEANY_API_SYMBOL
1095 void sci_get_text_range(ScintillaObject *sci, gint start, gint end, gchar *text)
1097 struct Sci_TextRange tr;
1098 tr.chrg.cpMin = start;
1099 tr.chrg.cpMax = end;
1100 tr.lpstrText = text;
1101 SSM(sci, SCI_GETTEXTRANGE, 0, (sptr_t) &tr);
1105 /** Gets text between @a start and @a end.
1106 * @param sci Scintilla widget.
1107 * @param start Start position.
1108 * @param end End position.
1109 * @return The text inside the given range. Should be freed when no longer needed.
1111 * @since 0.17
1113 GEANY_API_SYMBOL
1114 gchar *sci_get_contents_range(ScintillaObject *sci, gint start, gint end)
1116 gchar *text;
1118 g_return_val_if_fail(start < end, NULL);
1120 text = g_malloc((gsize) (end - start) + 1);
1121 sci_get_text_range(sci, start, end, text);
1122 return text;
1126 void sci_line_duplicate(ScintillaObject *sci)
1128 SSM(sci, SCI_LINEDUPLICATE, 0, 0);
1132 void sci_selection_duplicate(ScintillaObject *sci)
1134 SSM(sci, SCI_SELECTIONDUPLICATE, 0, 0);
1138 /** Inserts text.
1139 * @param sci Scintilla widget.
1140 * @param pos Position, or -1 for current.
1141 * @param text Text. */
1142 GEANY_API_SYMBOL
1143 void sci_insert_text(ScintillaObject *sci, gint pos, const gchar *text)
1145 SSM(sci, SCI_INSERTTEXT, (uptr_t) pos, (sptr_t) text);
1149 GEANY_API_SYMBOL
1150 void sci_set_target_start(ScintillaObject *sci, gint start)
1152 SSM(sci, SCI_SETTARGETSTART, (uptr_t) start, 0);
1156 GEANY_API_SYMBOL
1157 void sci_set_target_end(ScintillaObject *sci, gint end)
1159 SSM(sci, SCI_SETTARGETEND, (uptr_t) end, 0);
1163 GEANY_API_SYMBOL
1164 gint sci_replace_target(ScintillaObject *sci, const gchar *text, gboolean regex)
1166 return (gint) SSM(sci, (regex) ? SCI_REPLACETARGETRE : SCI_REPLACETARGET, (uptr_t) -1, (sptr_t) text);
1170 void sci_set_keywords(ScintillaObject *sci, guint k, const gchar *text)
1172 SSM(sci, SCI_SETKEYWORDS, k, (sptr_t) text);
1176 void sci_set_readonly(ScintillaObject *sci, gboolean readonly)
1178 SSM(sci, SCI_SETREADONLY, readonly != FALSE, 0);
1182 /** Sends Scintilla commands without any parameters.
1183 * @param sci The Scintilla @c GtkWidget.
1184 * @param cmd @c SCI_COMMAND.
1185 * @see http://scintilla.org for the documentation.
1187 * @since 0.16
1189 GEANY_API_SYMBOL
1190 void sci_send_command(ScintillaObject *sci, gint cmd)
1192 SSM(sci, cmd, 0, 0);
1196 /** Gets current line number.
1197 * @param sci Scintilla widget.
1198 * @return Line number. */
1199 GEANY_API_SYMBOL
1200 gint sci_get_current_line(ScintillaObject *sci)
1202 return (gint) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) SSM(sci, SCI_GETCURRENTPOS, 0, 0), 0);
1206 /* Get number of lines partially or fully selected.
1207 * Returns 1 if there is a partial selection on the same line.
1208 * Returns 2 if a whole line is selected including the line break char(s). */
1209 gint sci_get_lines_selected(ScintillaObject *sci)
1211 gint start = (gint) SSM(sci, SCI_GETSELECTIONSTART, 0, 0);
1212 gint end = (gint) SSM(sci, SCI_GETSELECTIONEND, 0, 0);
1213 gint line_start;
1214 gint line_end;
1216 if (start == end)
1217 return 0; /* no selection */
1219 line_start = (gint) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) start, 0);
1220 line_end = (gint) SSM(sci, SCI_LINEFROMPOSITION, (uptr_t) end, 0);
1222 return line_end - line_start + 1;
1226 gint sci_get_first_visible_line(ScintillaObject *sci)
1228 return (gint) SSM(sci, SCI_GETFIRSTVISIBLELINE, 0, 0);
1233 * Sets the current indicator. This is necessary to define an indicator for a range of text or
1234 * clearing indicators for a range of text.
1236 * @param sci Scintilla widget.
1237 * @param indic The indicator number to set.
1239 * @see sci_indicator_clear
1241 * @since 0.16
1243 GEANY_API_SYMBOL
1244 void sci_indicator_set(ScintillaObject *sci, gint indic)
1246 SSM(sci, SCI_SETINDICATORCURRENT, (uptr_t) indic, 0);
1250 void sci_indicator_fill(ScintillaObject *sci, gint pos, gint len)
1252 SSM(sci, SCI_INDICATORFILLRANGE, (uptr_t) pos, len);
1257 * Clears the currently set indicator from a range of text.
1258 * Starting at @a pos, @a len characters long.
1259 * In order to make this function properly, you need to set the current indicator before with
1260 * @ref sci_indicator_set().
1262 * @param sci Scintilla widget.
1263 * @param pos Starting position.
1264 * @param len Length.
1266 * @since 0.16
1268 GEANY_API_SYMBOL
1269 void sci_indicator_clear(ScintillaObject *sci, gint pos, gint len)
1271 SSM(sci, SCI_INDICATORCLEARRANGE, (uptr_t) pos, len);
1275 void sci_select_all(ScintillaObject *sci)
1277 SSM(sci, SCI_SELECTALL, 0, 0);
1281 gint sci_get_line_indent_position(ScintillaObject *sci, gint line)
1283 return (gint) SSM(sci, SCI_GETLINEINDENTPOSITION, (uptr_t) line, 0);
1287 void sci_set_autoc_max_height(ScintillaObject *sci, gint val)
1289 SSM(sci, SCI_AUTOCSETMAXHEIGHT, (uptr_t) val, 0);
1293 /** Finds a matching brace at @a pos.
1294 * @param sci Scintilla widget.
1295 * @param pos Position.
1296 * @return Matching brace position.
1298 * @since 0.15
1300 GEANY_API_SYMBOL
1301 gint sci_find_matching_brace(ScintillaObject *sci, gint pos)
1303 return (gint) SSM(sci, SCI_BRACEMATCH, (uptr_t) pos, 0);
1307 gint sci_get_overtype(ScintillaObject *sci)
1309 return (gint) SSM(sci, SCI_GETOVERTYPE, 0, 0);
1313 void sci_set_tab_indents(ScintillaObject *sci, gboolean set)
1315 SSM(sci, SCI_SETTABINDENTS, set != FALSE, 0);
1319 void sci_set_use_tabs(ScintillaObject *sci, gboolean set)
1321 SSM(sci, SCI_SETUSETABS, set != FALSE, 0);
1325 gint sci_get_pos_at_line_sel_start(ScintillaObject *sci, gint line)
1327 return (gint) SSM(sci, SCI_GETLINESELSTARTPOSITION, (uptr_t) line, 0);
1331 gint sci_get_pos_at_line_sel_end(ScintillaObject *sci, gint line)
1333 return (gint) SSM(sci, SCI_GETLINESELENDPOSITION, (uptr_t) line, 0);
1337 /** Gets selection mode.
1338 * @param sci Scintilla widget.
1339 * @return Selection mode. */
1340 GEANY_API_SYMBOL
1341 gint sci_get_selection_mode(ScintillaObject *sci)
1343 return (gint) SSM(sci, SCI_GETSELECTIONMODE, 0, 0);
1347 /** Sets selection mode.
1348 * @param sci Scintilla widget.
1349 * @param mode Mode. */
1350 GEANY_API_SYMBOL
1351 void sci_set_selection_mode(ScintillaObject *sci, gint mode)
1353 SSM(sci, SCI_SETSELECTIONMODE, (uptr_t) mode, 0);
1357 void sci_set_scrollbar_mode(ScintillaObject *sci, gboolean visible)
1359 SSM(sci, SCI_SETHSCROLLBAR, visible != FALSE, 0);
1360 SSM(sci, SCI_SETVSCROLLBAR, visible != FALSE, 0);
1364 /** Sets the indentation of a line.
1365 * @param sci Scintilla widget.
1366 * @param line Line to indent.
1367 * @param indent Indentation width.
1369 * @since 0.19
1371 GEANY_API_SYMBOL
1372 void sci_set_line_indentation(ScintillaObject *sci, gint line, gint indent)
1374 SSM(sci, SCI_SETLINEINDENTATION, (uptr_t) line, indent);
1378 /** Gets the indentation width of a line.
1379 * @param sci Scintilla widget.
1380 * @param line Line to get the indentation from.
1381 * @return Indentation width.
1383 * @since 0.19
1385 GEANY_API_SYMBOL
1386 gint sci_get_line_indentation(ScintillaObject *sci, gint line)
1388 return (gint) SSM(sci, SCI_GETLINEINDENTATION, (uptr_t) line, 0);
1392 void sci_set_caret_policy_x(ScintillaObject *sci, gint policy, gint slop)
1394 SSM(sci, SCI_SETXCARETPOLICY, (uptr_t) policy, slop);
1398 void sci_set_caret_policy_y(ScintillaObject *sci, gint policy, gint slop)
1400 SSM(sci, SCI_SETYCARETPOLICY, (uptr_t) policy, slop);
1404 void sci_set_scroll_stop_at_last_line(ScintillaObject *sci, gboolean set)
1406 SSM(sci, SCI_SETENDATLASTLINE, set != FALSE, 0);
1410 void sci_cancel(ScintillaObject *sci)
1412 SSM(sci, SCI_CANCEL, 0, 0);
1416 gint sci_get_position_after(ScintillaObject *sci, gint start)
1418 return (gint) SSM(sci, SCI_POSITIONAFTER, (uptr_t) start, 0);
1422 void sci_lines_join(ScintillaObject *sci)
1424 SSM(sci, SCI_LINESJOIN, 0, 0);
1428 gint sci_text_width(ScintillaObject *sci, gint styleNumber, const gchar *text)
1430 return (gint) SSM(sci, SCI_TEXTWIDTH, (uptr_t) styleNumber, (sptr_t) text);
1434 void sci_move_selected_lines_down(ScintillaObject *sci)
1436 SSM(sci, SCI_MOVESELECTEDLINESDOWN, 0, 0);
1440 void sci_move_selected_lines_up(ScintillaObject *sci)
1442 SSM(sci, SCI_MOVESELECTEDLINESUP, 0, 0);
1446 gint sci_word_start_position(ScintillaObject *sci, gint position, gboolean onlyWordCharacters)
1448 return SSM(sci, SCI_WORDSTARTPOSITION, position, onlyWordCharacters);
1452 gint sci_word_end_position(ScintillaObject *sci, gint position, gboolean onlyWordCharacters)
1454 return SSM(sci, SCI_WORDENDPOSITION, position, onlyWordCharacters);