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 https://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 * (https://sourceforge.net/projects/cssed/, thanks).
30 * @see scintilla_send_message().
37 #include "sciwrappers.h"
38 #include <Lexilla.h> /* ILexer5 */
48 sptr_t
sci_send_message_internal (const gchar
*file
, guint line
, ScintillaObject
*sci
,
49 guint msg
, uptr_t wparam
, sptr_t lparam
)
54 scintilla_send_message(sci
, SCI_SETSTATUS
, 0, 0);
55 result
= scintilla_send_message(sci
, msg
, wparam
, lparam
);
56 status
= scintilla_send_message(sci
, SCI_GETSTATUS
, 0, 0);
60 const gchar
*sub_msg
= "unknown";
63 case SC_STATUS_FAILURE
:
64 sub_msg
= "generic failure";
66 case SC_STATUS_BADALLOC
:
67 sub_msg
= "memory is exhausted";
69 case SC_STATUS_WARN_REGEX
:
70 sub_msg
= "regular expression is invalid";
73 if (status
>= SC_STATUS_WARN_START
)
74 sub_msg
= "unknown warning";
76 sub_msg
= "unknown failure";
79 #define SCI_STATUS_FORMAT_STRING "%s:%u: scintilla has non-zero status " \
80 "code '%d' after sending message '%u' to instance '%p' with " \
81 "wParam='%lu' and lParam='%ld': %s"
82 if (status
>= SC_STATUS_WARN_START
)
84 g_warning(SCI_STATUS_FORMAT_STRING
, file
, line
, status
, msg
,
85 (gpointer
)sci
, wparam
, lparam
, sub_msg
);
89 g_critical(SCI_STATUS_FORMAT_STRING
, file
, line
, status
, msg
,
90 (gpointer
)sci
, wparam
, lparam
, sub_msg
);
99 /* line numbers visibility */
100 void sci_set_line_numbers(ScintillaObject
*sci
, gboolean set
)
105 gint len
= (gint
) SSM(sci
, SCI_GETLINECOUNT
, 0, 0);
108 g_snprintf(tmp_str
, 15, "_%d", len
);
109 width
= sci_text_width(sci
, STYLE_LINENUMBER
, tmp_str
);
110 SSM(sci
, SCI_SETMARGINWIDTHN
, 0, width
);
111 SSM(sci
, SCI_SETMARGINSENSITIVEN
, 0, FALSE
); /* use default behaviour */
115 SSM(sci
, SCI_SETMARGINWIDTHN
, 0, 0);
120 void sci_set_mark_long_lines(ScintillaObject
*sci
, gint type
, gint column
, const gchar
*colour
)
122 glong colour_val
= utils_parse_color_to_bgr(colour
); /* Scintilla uses a "long" value */
130 SSM(sci
, SCI_SETEDGEMODE
, EDGE_LINE
, 0);
135 SSM(sci
, SCI_SETEDGEMODE
, EDGE_BACKGROUND
, 0);
140 SSM(sci
, SCI_SETEDGEMODE
, EDGE_NONE
, 0);
144 SSM(sci
, SCI_SETEDGECOLUMN
, (uptr_t
) column
, 0);
145 SSM(sci
, SCI_SETEDGECOLOUR
, (uptr_t
) colour_val
, 0);
149 /* Calls SCI_TEXTHEIGHT but tries very hard to cache the result as it's a very
150 * expensive operation */
151 static gint
sci_text_height_cached(ScintillaObject
*sci
)
159 static struct height_spec cache
= {0};
160 static gint cache_value
= 0;
161 struct height_spec current
;
163 current
.font
= sci_get_string(sci
, SCI_STYLEGETFONT
, 0);
164 current
.size
= SSM(sci
, SCI_STYLEGETSIZEFRACTIONAL
, 0, 0);
165 current
.zoom
= SSM(sci
, SCI_GETZOOM
, 0, 0);
166 current
.extra
= SSM(sci
, SCI_GETEXTRAASCENT
, 0, 0) + SSM(sci
, SCI_GETEXTRADESCENT
, 0, 0);
168 if (g_strcmp0(current
.font
, cache
.font
) == 0 &&
169 current
.size
== cache
.size
&&
170 current
.zoom
== cache
.zoom
&&
171 current
.extra
== cache
.extra
)
173 g_free(current
.font
);
180 cache_value
= SSM(sci
, SCI_TEXTHEIGHT
, 0, 0);
186 /* compute margin width based on ratio of line height */
187 static gint
margin_width_from_line_height(ScintillaObject
*sci
, gdouble ratio
, gint threshold
)
189 const gint line_height
= sci_text_height_cached(sci
);
192 width
= line_height
* ratio
;
193 /* round down to an even size */
194 width
= width
- (width
% 2);
195 /* if under threshold, just use the line height */
196 if (width
< threshold
)
197 width
= MIN(threshold
, line_height
);
203 /* symbol margin visibility */
204 void sci_set_symbol_margin(ScintillaObject
*sci
, gboolean set
)
208 const gint width
= margin_width_from_line_height(sci
, 0.88, 16);
210 SSM(sci
, SCI_SETMARGINWIDTHN
, 1, width
);
211 SSM(sci
, SCI_SETMARGINSENSITIVEN
, 1, TRUE
);
215 SSM(sci
, SCI_SETMARGINWIDTHN
, 1, 0);
216 SSM(sci
, SCI_SETMARGINSENSITIVEN
, 1, FALSE
);
221 /* folding margin visibility */
222 void sci_set_folding_margin_visible(ScintillaObject
*sci
, gboolean set
)
226 const gint width
= margin_width_from_line_height(sci
, 0.66, 12);
228 SSM(sci
, SCI_SETMARGINWIDTHN
, 2, width
);
229 SSM(sci
, SCI_SETMARGINSENSITIVEN
, 2, TRUE
);
233 SSM(sci
, SCI_SETMARGINSENSITIVEN
, 2, FALSE
);
234 SSM(sci
, SCI_SETMARGINWIDTHN
, 2, 0);
240 void sci_set_visible_eols(ScintillaObject
*sci
, gboolean set
)
242 SSM(sci
, SCI_SETVIEWEOL
, set
!= FALSE
, 0);
246 void sci_set_visible_white_spaces(ScintillaObject
*sci
, gboolean set
)
249 SSM(sci
, SCI_SETVIEWWS
, SCWS_VISIBLEALWAYS
, 0);
251 SSM(sci
, SCI_SETVIEWWS
, SCWS_INVISIBLE
, 0);
255 void sci_set_lines_wrapped(ScintillaObject
*sci
, gboolean set
)
258 SSM(sci
, SCI_SETWRAPMODE
, SC_WRAP_WORD
, 0);
260 SSM(sci
, SCI_SETWRAPMODE
, SC_WRAP_NONE
, 0);
264 gint
sci_get_eol_mode(ScintillaObject
*sci
)
266 return (gint
) SSM(sci
, SCI_GETEOLMODE
, 0, 0);
270 void sci_set_eol_mode(ScintillaObject
*sci
, gint eolmode
)
272 SSM(sci
, SCI_SETEOLMODE
, (uptr_t
) eolmode
, 0);
273 sci_set_eol_representation_characters(sci
, eolmode
);
277 /* Show only EOL characters if they differ from the file default EOL character */
278 void sci_set_eol_representation_characters(ScintillaObject
*sci
, gint new_eolmode
)
280 const gchar
*eolchar
= NULL
;
281 const gchar
*new_eolchar
= NULL
;
282 gboolean visible
= FALSE
;
285 gint eol_modes
[3] = {SC_EOL_CRLF
, SC_EOL_CR
, SC_EOL_LF
};
287 foreach_c_array(eolmode
, eol_modes
, 3)
289 visible
= (*eolmode
!= new_eolmode
) || ! editor_prefs
.show_line_endings_only_when_differ
;
290 new_eolchar
= (visible
) ? utils_get_eol_short_name(*eolmode
) : "";
291 appearance
= (visible
) ? SC_REPRESENTATION_BLOB
: SC_REPRESENTATION_PLAIN
;
292 eolchar
= utils_get_eol_char(*eolmode
);
294 SSM(sci
, SCI_SETREPRESENTATION
, (sptr_t
) eolchar
, (sptr_t
) new_eolchar
);
295 SSM(sci
, SCI_SETREPRESENTATIONAPPEARANCE
, (sptr_t
) eolchar
, appearance
);
300 void sci_convert_eols(ScintillaObject
*sci
, gint eolmode
)
302 SSM(sci
, SCI_CONVERTEOLS
, (uptr_t
) eolmode
, 0);
306 void sci_add_text(ScintillaObject
*sci
, const gchar
*text
)
309 { /* if null text is passed scintilla will segfault */
310 SSM(sci
, SCI_ADDTEXT
, strlen(text
), (sptr_t
) text
);
316 * @param sci Scintilla widget.
317 * @param text Text. */
319 void sci_set_text(ScintillaObject
*sci
, const gchar
*text
)
321 if( text
!= NULL
){ /* if null text is passed to scintilla will segfault */
322 SSM(sci
, SCI_SETTEXT
, 0, (sptr_t
) text
);
327 gboolean
sci_can_undo(ScintillaObject
*sci
)
329 return SSM(sci
, SCI_CANUNDO
, 0, 0) != FALSE
;
333 gboolean
sci_can_redo(ScintillaObject
*sci
)
335 return SSM(sci
, SCI_CANREDO
, 0, 0) != FALSE
;
339 void sci_undo(ScintillaObject
*sci
)
341 if (sci_can_undo(sci
))
342 SSM(sci
, SCI_UNDO
, 0, 0);
346 void sci_redo(ScintillaObject
*sci
)
348 if (sci_can_redo(sci
))
349 SSM(sci
, SCI_REDO
, 0, 0);
353 /** Begins grouping a set of edits together as one Undo action.
354 * You must call sci_end_undo_action() after making your edits.
355 * @param sci Scintilla @c GtkWidget. */
357 void sci_start_undo_action(ScintillaObject
*sci
)
359 SSM(sci
, SCI_BEGINUNDOACTION
, 0, 0);
363 /** Ends grouping a set of edits together as one Undo action.
364 * @param sci Scintilla @c GtkWidget.
365 * @see sci_start_undo_action(). */
367 void sci_end_undo_action(ScintillaObject
*sci
)
369 SSM(sci
, SCI_ENDUNDOACTION
, 0, 0);
373 void sci_set_undo_collection(ScintillaObject
*sci
, gboolean set
)
375 SSM(sci
, SCI_SETUNDOCOLLECTION
, set
!= FALSE
, 0);
379 void sci_empty_undo_buffer(ScintillaObject
*sci
)
381 SSM(sci
, SCI_EMPTYUNDOBUFFER
, 0, 0);
385 gboolean
sci_is_modified(ScintillaObject
*sci
)
387 return (SSM(sci
, SCI_GETMODIFY
, 0, 0) != 0);
391 void sci_zoom_in(ScintillaObject
*sci
)
393 SSM(sci
, SCI_ZOOMIN
, 0, 0);
397 void sci_zoom_out(ScintillaObject
*sci
)
399 SSM(sci
, SCI_ZOOMOUT
, 0, 0);
403 void sci_zoom_off(ScintillaObject
*sci
)
405 SSM(sci
, SCI_SETZOOM
, 0, 0);
409 /** Sets a line marker.
410 * @param sci Scintilla widget.
411 * @param line_number Line number.
412 * @param marker Marker number. */
414 void sci_set_marker_at_line(ScintillaObject
*sci
, gint line_number
, gint marker
)
416 SSM(sci
, SCI_MARKERADD
, (uptr_t
) line_number
, marker
);
420 /** Deletes a line marker.
421 * @param sci Scintilla widget.
422 * @param line_number Line number.
423 * @param marker Marker number. */
425 void sci_delete_marker_at_line(ScintillaObject
*sci
, gint line_number
, gint marker
)
427 SSM(sci
, SCI_MARKERDELETE
, (uptr_t
) line_number
, marker
);
431 /** Checks if a line has a marker set.
432 * @param sci Scintilla widget.
433 * @param line Line number.
434 * @param marker Marker number.
435 * @return Whether it's set. */
437 gboolean
sci_is_marker_set_at_line(ScintillaObject
*sci
, gint line
, gint marker
)
441 state
= (gint
) SSM(sci
, SCI_MARKERGET
, (uptr_t
) line
, 0);
442 return (state
& (1 << marker
));
446 void sci_toggle_marker_at_line(ScintillaObject
*sci
, gint line
, gint marker
)
448 gboolean set
= sci_is_marker_set_at_line(sci
, line
, marker
);
451 sci_set_marker_at_line(sci
, line
, marker
);
453 sci_delete_marker_at_line(sci
, line
, marker
);
457 /* Returns the line number of the next marker that matches marker_mask, or -1.
458 * marker_mask is a bitor of 1 << marker_index. (See MarkerHandleSet::MarkValue()).
459 * Note: If there is a marker on the line, it returns the same line. */
460 gint
sci_marker_next(ScintillaObject
*sci
, gint line
, gint marker_mask
, gboolean wrap
)
464 marker_line
= (gint
) SSM(sci
, SCI_MARKERNEXT
, (uptr_t
) line
, marker_mask
);
465 if (wrap
&& marker_line
== -1)
466 marker_line
= (gint
) SSM(sci
, SCI_MARKERNEXT
, 0, marker_mask
);
471 /* Returns the line number of the previous marker that matches marker_mask, or -1.
472 * marker_mask is a bitor of 1 << marker_index. (See MarkerHandleSet::MarkValue()).
473 * Note: If there is a marker on the line, it returns the same line. */
474 gint
sci_marker_previous(ScintillaObject
*sci
, gint line
, gint marker_mask
, gboolean wrap
)
478 marker_line
= (gint
) SSM(sci
, SCI_MARKERPREVIOUS
, (uptr_t
) line
, marker_mask
);
479 if (wrap
&& marker_line
== -1)
481 gint len
= sci_get_length(sci
);
482 gint last_line
= sci_get_line_from_position(sci
, len
- 1);
484 marker_line
= (gint
) SSM(sci
, SCI_MARKERPREVIOUS
, (uptr_t
) last_line
, marker_mask
);
490 /** Gets the line number from @a position.
491 * @param sci Scintilla widget.
492 * @param position Position.
493 * @return The line. */
495 gint
sci_get_line_from_position(ScintillaObject
*sci
, gint position
)
497 return (gint
) SSM(sci
, SCI_LINEFROMPOSITION
, (uptr_t
) position
, 0);
501 /** Gets the column number relative to the start of the line that @a position is on.
502 * @param sci Scintilla widget.
503 * @param position Position.
504 * @return The column. */
506 gint
sci_get_col_from_position(ScintillaObject
*sci
, gint position
)
508 return (gint
) SSM(sci
, SCI_GETCOLUMN
, (uptr_t
) position
, 0);
512 gint
sci_get_position_from_col(ScintillaObject
*sci
, gint line
, gint col
)
514 return (gint
) SSM(sci
, SCI_FINDCOLUMN
, line
, col
);
518 /** Gets the position for the start of @a line.
519 * @param sci Scintilla widget.
521 * @return Position. */
523 gint
sci_get_position_from_line(ScintillaObject
*sci
, gint line
)
525 return (gint
) SSM(sci
, SCI_POSITIONFROMLINE
, (uptr_t
) line
, 0);
529 /** Gets the cursor position.
530 * @param sci Scintilla widget.
531 * @return Position. */
533 gint
sci_get_current_position(ScintillaObject
*sci
)
535 return (gint
) SSM(sci
, SCI_GETCURRENTPOS
, 0, 0);
539 gint
sci_get_cursor_virtual_space(ScintillaObject
*sci
)
541 gint selection_mode
= sci_get_selection_mode(sci
);
543 return selection_mode
== SC_SEL_RECTANGLE
|| selection_mode
== SC_SEL_THIN
?
544 SSM(sci
, SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE
, 0, 0) :
545 SSM(sci
, SCI_GETSELECTIONNCARETVIRTUALSPACE
,
546 SSM(sci
, SCI_GETMAINSELECTION
, 0, 0), 0);
550 /** Sets the cursor position.
551 * @param sci Scintilla widget.
552 * @param position Position.
553 * @param scroll_to_caret Whether to scroll the cursor in view. */
555 void sci_set_current_position(ScintillaObject
*sci
, gint position
, gboolean scroll_to_caret
)
558 SSM(sci
, SCI_GOTOPOS
, (uptr_t
) position
, 0);
561 SSM(sci
, SCI_SETCURRENTPOS
, (uptr_t
) position
, 0);
562 SSM(sci
, SCI_SETANCHOR
, (uptr_t
) position
, 0); /* to avoid creation of a selection */
564 SSM(sci
, SCI_CHOOSECARETX
, 0, 0);
568 /* Set the cursor line without scrolling the view.
569 * Use sci_goto_line() to also scroll. */
570 void sci_set_current_line(ScintillaObject
*sci
, gint line
)
572 gint pos
= sci_get_position_from_line(sci
, line
);
573 sci_set_current_position(sci
, pos
, FALSE
);
577 /** Gets the total number of lines.
578 * @param sci Scintilla widget.
579 * @return The line count. */
581 gint
sci_get_line_count(ScintillaObject
*sci
)
583 return (gint
) SSM(sci
, SCI_GETLINECOUNT
, 0, 0);
587 /** Sets the selection start position.
588 * @param sci Scintilla widget.
589 * @param position Position. */
591 void sci_set_selection_start(ScintillaObject
*sci
, gint position
)
593 SSM(sci
, SCI_SETSELECTIONSTART
, (uptr_t
) position
, 0);
597 /** Sets the selection end position.
598 * @param sci Scintilla widget.
599 * @param position Position. */
601 void sci_set_selection_end(ScintillaObject
*sci
, gint position
)
603 SSM(sci
, SCI_SETSELECTIONEND
, (uptr_t
) position
, 0);
607 void sci_set_selection(ScintillaObject
*sci
, gint anchorPos
, gint currentPos
)
609 SSM(sci
, SCI_SETSEL
, (uptr_t
) anchorPos
, currentPos
);
613 /** Gets the position at the end of a line
614 * @param sci Scintilla widget.
616 * @return The position at the end of the line. */
618 gint
sci_get_line_end_position(ScintillaObject
*sci
, gint line
)
620 return (gint
) SSM(sci
, SCI_GETLINEENDPOSITION
, (uptr_t
) line
, 0);
624 void sci_cut(ScintillaObject
*sci
)
626 SSM(sci
, SCI_CUT
, 0, 0);
630 void sci_copy(ScintillaObject
*sci
)
632 SSM(sci
, SCI_COPY
, 0, 0);
636 void sci_paste(ScintillaObject
*sci
)
638 SSM(sci
, SCI_PASTE
, 0, 0);
642 void sci_clear(ScintillaObject
*sci
)
644 SSM(sci
, SCI_CLEAR
, 0, 0);
648 /** Gets the selection start position.
649 * @param sci Scintilla widget.
650 * @return Position. */
652 gint
sci_get_selection_start(ScintillaObject
*sci
)
654 return (gint
) SSM(sci
, SCI_GETSELECTIONSTART
, 0, 0);
658 /** Gets the selection end position.
659 * @param sci Scintilla widget.
660 * @return Position. */
662 gint
sci_get_selection_end(ScintillaObject
*sci
)
664 return (gint
) SSM(sci
, SCI_GETSELECTIONEND
, 0, 0);
668 /** Replaces selection.
669 * @param sci Scintilla widget.
670 * @param text Text. */
672 void sci_replace_sel(ScintillaObject
*sci
, const gchar
*text
)
674 SSM(sci
, SCI_REPLACESEL
, 0, (sptr_t
) text
);
678 /** Gets the length of all text.
679 * @param sci Scintilla widget.
682 gint
sci_get_length(ScintillaObject
*sci
)
684 return (gint
) SSM(sci
, SCI_GETLENGTH
, 0, 0);
688 /** Gets the currently used lexer
689 * @param sci Scintilla widget.
690 * @returns The lexer ID
693 gint
sci_get_lexer(ScintillaObject
*sci
)
695 return (gint
) SSM(sci
, SCI_GETLEXER
, 0, 0);
699 void sci_set_lexer(ScintillaObject
*sci
, guint lexer_id
)
701 gint old
= sci_get_lexer(sci
);
703 /* TODO, LexerNameFromID() is already deprecated */
704 ILexer5
*lexer
= CreateLexer(LexerNameFromID(lexer_id
));
706 SSM(sci
, SCI_SETILEXER
, 0, (uintptr_t) lexer
);
708 if (old
!= (gint
)lexer_id
)
709 SSM(sci
, SCI_CLEARDOCUMENTSTYLE
, 0, 0);
713 /** Gets line length.
714 * @param sci Scintilla widget.
715 * @param line Line number.
718 gint
sci_get_line_length(ScintillaObject
*sci
, gint line
)
720 return (gint
) SSM(sci
, SCI_LINELENGTH
, (uptr_t
) line
, 0);
724 /* safe way to read Scintilla string into new memory.
725 * works with any string buffer messages that follow the Windows message convention. */
726 gchar
*sci_get_string(ScintillaObject
*sci
, guint msg
, gulong wParam
)
728 gint size
= (gint
) SSM(sci
, msg
, wParam
, 0);
729 gchar
*str
= g_malloc(size
+ 1);
731 SSM(sci
, msg
, wParam
, (sptr_t
) str
);
732 str
[size
] = '\0'; /* ensure termination, needed for SCI_GETLINE */
737 /** Gets line contents.
738 * @param sci Scintilla widget.
739 * @param line_num Line number.
740 * @return A @c NULL-terminated copy of the line text. */
742 gchar
*sci_get_line(ScintillaObject
*sci
, gint line_num
)
744 return sci_get_string(sci
, SCI_GETLINE
, (gulong
) line_num
);
749 * @deprecated sci_get_text is deprecated and should not be used in newly-written code.
750 * Use sci_get_contents() instead.
752 * @param sci Scintilla widget.
753 * @param len Length of @a text buffer, usually sci_get_length() + 1.
754 * @param text Text buffer; must be allocated @a len bytes for null-termination. */
756 void sci_get_text(ScintillaObject
*sci
, gint len
, gchar
*text
)
758 g_return_if_fail(len
> 0);
759 SSM(sci
, SCI_GETTEXT
, (uptr_t
) len
- 1, (sptr_t
) text
);
763 /** Allocates and fills a buffer with text from the start of the document.
764 * @param sci Scintilla widget.
765 * @param buffer_len Buffer length to allocate, including the terminating
766 * null char, e.g. sci_get_length() + 1. Alternatively use @c -1 to get all
767 * text (since Geany 1.23).
768 * @return A copy of the text. Should be freed when no longer needed.
773 gchar
*sci_get_contents(ScintillaObject
*sci
, gint buffer_len
)
777 g_return_val_if_fail(buffer_len
!= 0, NULL
);
780 buffer_len
= sci_get_length(sci
) + 1;
782 text
= g_malloc(buffer_len
);
783 SSM(sci
, SCI_GETTEXT
, (uptr_t
) buffer_len
- 1, (sptr_t
) text
);
788 /** Gets selected text.
789 * @deprecated sci_get_selected_text is deprecated and should not be used in newly-written code.
790 * Use sci_get_selection_contents() instead.
792 * @note You must ensure NUL termination yourself, this function does
793 * not NUL terminate the buffer itself.
795 * @param sci Scintilla widget.
796 * @param text Text buffer; must be allocated sci_get_selected_text_length() + 1 bytes
797 * for null-termination. */
799 void sci_get_selected_text(ScintillaObject
*sci
, gchar
*text
)
801 SSM(sci
, SCI_GETSELTEXT
, 0, (sptr_t
) text
);
805 /** Gets selected text.
806 * @param sci Scintilla widget.
808 * @return The selected text. Should be freed when no longer needed.
813 gchar
*sci_get_selection_contents(ScintillaObject
*sci
)
815 return sci_get_string(sci
, SCI_GETSELTEXT
, 0);
819 /** Gets selected text length including the terminating NUL character.
820 * @deprecated sci_get_selected_text_length is deprecated and should not be used in newly-written code.
821 * Use sci_get_selected_text_length2() instead.
822 * @param sci Scintilla widget.
825 gint
sci_get_selected_text_length(ScintillaObject
*sci
)
827 return (gint
) SSM(sci
, SCI_GETSELTEXT
, 0, 0) + 1;
831 /** Gets selected text length without the terminating NUL character.
832 * @param sci Scintilla widget.
835 gint
sci_get_selected_text_length2(ScintillaObject
*sci
)
837 return (gint
) SSM(sci
, SCI_GETSELTEXT
, 0, 0);
841 gint
sci_get_position_from_xy(ScintillaObject
*sci
, gint x
, gint y
, gboolean nearby
)
843 /* for nearby return -1 if there is no character near to the x,y point. */
844 return (gint
) SSM(sci
, (nearby
) ? SCI_POSITIONFROMPOINTCLOSE
: SCI_POSITIONFROMPOINT
, (uptr_t
) x
, y
);
848 /** Checks if a line is visible (folding may have hidden it).
849 * @param sci Scintilla widget.
850 * @param line Line number.
851 * @return Whether @a line will be drawn on the screen. */
853 gboolean
sci_get_line_is_visible(ScintillaObject
*sci
, gint line
)
855 return SSM(sci
, SCI_GETLINEVISIBLE
, (uptr_t
) line
, 0) != FALSE
;
859 /** Makes @a line visible (folding may have hidden it).
860 * @param sci Scintilla widget.
861 * @param line Line number. */
863 void sci_ensure_line_is_visible(ScintillaObject
*sci
, gint line
)
865 SSM(sci
, SCI_ENSUREVISIBLE
, (uptr_t
) line
, 0);
869 gint
sci_get_fold_level(ScintillaObject
*sci
, gint line
)
871 return (gint
) SSM(sci
, SCI_GETFOLDLEVEL
, (uptr_t
) line
, 0);
875 /* Get the line number of the fold point before start_line, or -1 if there isn't one */
876 gint
sci_get_fold_parent(ScintillaObject
*sci
, gint start_line
)
878 return (gint
) SSM(sci
, SCI_GETFOLDPARENT
, (uptr_t
) start_line
, 0);
882 void sci_toggle_fold(ScintillaObject
*sci
, gint line
)
884 SSM(sci
, SCI_TOGGLEFOLD
, (uptr_t
) line
, 0);
888 gboolean
sci_get_fold_expanded(ScintillaObject
*sci
, gint line
)
890 return SSM(sci
, SCI_GETFOLDEXPANDED
, (uptr_t
) line
, 0) != FALSE
;
894 void sci_colourise(ScintillaObject
*sci
, gint start
, gint end
)
896 SSM(sci
, SCI_COLOURISE
, (uptr_t
) start
, end
);
900 void sci_clear_all(ScintillaObject
*sci
)
902 SSM(sci
, SCI_CLEARALL
, 0, 0);
906 gint
sci_get_end_styled(ScintillaObject
*sci
)
908 return (gint
) SSM(sci
, SCI_GETENDSTYLED
, 0, 0);
912 void sci_set_tab_width(ScintillaObject
*sci
, gint width
)
914 SSM(sci
, SCI_SETTABWIDTH
, (uptr_t
) width
, 0);
918 /** Gets display tab width (this is not indent width, see GeanyIndentPrefs).
919 * @param sci Scintilla widget.
925 gint
sci_get_tab_width(ScintillaObject
*sci
)
927 return (gint
) SSM(sci
, SCI_GETTABWIDTH
, 0, 0);
931 /** Gets a character.
932 * @param sci Scintilla widget.
933 * @param pos Position.
936 gchar
sci_get_char_at(ScintillaObject
*sci
, gint pos
)
938 return (gchar
) SSM(sci
, SCI_GETCHARAT
, (uptr_t
) pos
, 0);
942 void sci_set_savepoint(ScintillaObject
*sci
)
944 SSM(sci
, SCI_SETSAVEPOINT
, 0, 0);
948 void sci_set_indentation_guides(ScintillaObject
*sci
, gint mode
)
950 SSM(sci
, SCI_SETINDENTATIONGUIDES
, (uptr_t
) mode
, 0);
954 void sci_use_popup(ScintillaObject
*sci
, gboolean enable
)
956 SSM(sci
, SCI_USEPOPUP
, enable
!= FALSE
, 0);
960 /** Checks if there's a selection.
961 * @param sci Scintilla widget.
962 * @return Whether a selection is present.
967 gboolean
sci_has_selection(ScintillaObject
*sci
)
969 if (SSM(sci
, SCI_GETSELECTIONEND
, 0, 0) - SSM(sci
, SCI_GETSELECTIONSTART
, 0, 0))
976 void sci_goto_pos(ScintillaObject
*sci
, gint pos
, gboolean unfold
)
978 if (unfold
) SSM(sci
, SCI_ENSUREVISIBLE
, (uptr_t
) SSM(sci
, SCI_LINEFROMPOSITION
, (uptr_t
) pos
, 0), 0);
979 SSM(sci
, SCI_GOTOPOS
, (uptr_t
) pos
, 0);
983 void sci_set_search_anchor(ScintillaObject
*sci
)
985 SSM(sci
, SCI_SEARCHANCHOR
, 0, 0);
989 /* removes a selection if pos < 0 */
990 void sci_set_anchor(ScintillaObject
*sci
, gint pos
)
993 pos
= sci_get_current_position(sci
);
995 SSM(sci
, SCI_SETANCHOR
, (uptr_t
) pos
, 0);
999 /** Scrolls the cursor in view.
1000 * @param sci Scintilla widget. */
1002 void sci_scroll_caret(ScintillaObject
*sci
)
1004 SSM(sci
, SCI_SCROLLCARET
, 0, 0);
1008 void sci_scroll_columns(ScintillaObject
*sci
, gint columns
)
1010 SSM(sci
, SCI_LINESCROLL
, (uptr_t
) columns
, 0);
1014 gint
sci_search_next(ScintillaObject
*sci
, gint flags
, const gchar
*text
)
1016 /* FIXME: SCI_SEACHNEXT() actually returns long */
1017 return (gint
) SSM(sci
, SCI_SEARCHNEXT
, (uptr_t
) flags
, (sptr_t
) text
);
1021 gint
sci_search_prev(ScintillaObject
*sci
, gint flags
, const gchar
*text
)
1023 /* FIXME: SCI_SEACHPREV() actually returns long */
1024 return (gint
) SSM(sci
, SCI_SEARCHPREV
, (uptr_t
) flags
, (sptr_t
) text
);
1028 /** Finds text in the document.
1029 * The @a ttf argument should be a pointer to a Sci_TextToFind structure which contains
1030 * the text to find and the range in which the text should be searched.
1032 * Please refer to the Scintilla documentation for a more detailed description.
1034 * @param sci Scintilla widget.
1035 * @param flags Bitmask of Scintilla search flags (@c SCFIND_*, see Scintilla documentation).
1036 * @param ttf Pointer to a TextToFind structure which contains the text to find and the range.
1037 * @return The position of the start of the found text if it succeeds, otherwise @c -1.
1038 * The @c chrgText.cpMin and @c chrgText.cpMax members of @c TextToFind are filled in
1039 * with the start and end positions of the found text.
1042 gint
sci_find_text(ScintillaObject
*sci
, gint flags
, struct Sci_TextToFind
*ttf
)
1044 return (gint
) SSM(sci
, SCI_FINDTEXT
, (uptr_t
) flags
, (sptr_t
) ttf
);
1047 /* * Sets the font for a particular style.
1048 * @param sci Scintilla widget.
1049 * @param style The style.
1050 * @param font The font name.
1051 * @param size The font (fractional) size. */
1052 void sci_set_font_fractional(ScintillaObject
*sci
, gint style
, const gchar
*font
, gdouble size
)
1054 SSM(sci
, SCI_STYLESETFONT
, (uptr_t
) style
, (sptr_t
) font
);
1056 /* Adding 0.5 is for rounding. */
1057 SSM(sci
, SCI_STYLESETSIZEFRACTIONAL
, (uptr_t
) style
, (sptr_t
) (SC_FONT_SIZE_MULTIPLIER
* size
+ 0.5));
1060 /** Sets the font for a particular style.
1061 * @param sci Scintilla widget.
1062 * @param style The style.
1063 * @param font The font name.
1064 * @param size The font size. */
1066 void sci_set_font(ScintillaObject
*sci
, gint style
, const gchar
*font
, gint size
)
1068 sci_set_font_fractional(sci
, style
, font
, size
);
1072 /** Jumps to the specified line in the document.
1073 * If @a unfold is set and @a line is hidden by a fold, it is unfolded
1074 * first to ensure it is visible.
1075 * @param sci Scintilla widget.
1077 * @param unfold Whether to unfold first.
1080 void sci_goto_line(ScintillaObject
*sci
, gint line
, gboolean unfold
)
1082 if (unfold
) SSM(sci
, SCI_ENSUREVISIBLE
, (uptr_t
) line
, 0);
1083 SSM(sci
, SCI_GOTOLINE
, (uptr_t
) line
, 0);
1087 void sci_marker_delete_all(ScintillaObject
*sci
, gint marker
)
1089 SSM(sci
, SCI_MARKERDELETEALL
, (uptr_t
) marker
, 0);
1093 /** Gets style ID at @a position.
1094 * @param sci Scintilla widget.
1095 * @param position Position.
1096 * @return Style ID. */
1098 gint
sci_get_style_at(ScintillaObject
*sci
, gint position
)
1100 return (gint
) SSM(sci
, SCI_GETSTYLEAT
, (uptr_t
) position
, 0);
1104 void sci_set_codepage(ScintillaObject
*sci
, gint cp
)
1106 g_return_if_fail(cp
== 0 || cp
== SC_CP_UTF8
);
1107 SSM(sci
, SCI_SETCODEPAGE
, (uptr_t
) cp
, 0);
1111 void sci_assign_cmdkey(ScintillaObject
*sci
, gint key
, gint command
)
1113 SSM(sci
, SCI_ASSIGNCMDKEY
, (uptr_t
) key
, command
);
1117 void sci_clear_cmdkey(ScintillaObject
*sci
, gint key
)
1119 SSM(sci
, SCI_CLEARCMDKEY
, (uptr_t
) key
, 0);
1123 /** Gets text between @a start and @a end.
1124 * @deprecated sci_get_text_range is deprecated and should not be used in newly-written code.
1125 * Use sci_get_contents_range() instead.
1127 * @param sci Scintilla widget.
1128 * @param start Start.
1130 * @param text Text will be zero terminated and must be allocated (end - start + 1) bytes. */
1132 void sci_get_text_range(ScintillaObject
*sci
, gint start
, gint end
, gchar
*text
)
1134 struct Sci_TextRange tr
;
1135 tr
.chrg
.cpMin
= start
;
1136 tr
.chrg
.cpMax
= end
;
1137 tr
.lpstrText
= text
;
1138 SSM(sci
, SCI_GETTEXTRANGE
, 0, (sptr_t
) &tr
);
1142 /** Gets text between @a start and @a end.
1143 * @param sci Scintilla widget.
1144 * @param start Start position.
1145 * @param end End position.
1146 * @return The text inside the given range. Should be freed when no longer needed.
1151 gchar
*sci_get_contents_range(ScintillaObject
*sci
, gint start
, gint end
)
1155 g_return_val_if_fail(start
< end
, NULL
);
1157 text
= g_malloc((gsize
) (end
- start
) + 1);
1158 sci_get_text_range(sci
, start
, end
, text
);
1163 void sci_line_duplicate(ScintillaObject
*sci
)
1165 SSM(sci
, SCI_LINEDUPLICATE
, 0, 0);
1169 void sci_selection_duplicate(ScintillaObject
*sci
)
1171 SSM(sci
, SCI_SELECTIONDUPLICATE
, 0, 0);
1176 * @param sci Scintilla widget.
1177 * @param pos Position, or -1 for current.
1178 * @param text Text. */
1180 void sci_insert_text(ScintillaObject
*sci
, gint pos
, const gchar
*text
)
1182 SSM(sci
, SCI_INSERTTEXT
, (uptr_t
) pos
, (sptr_t
) text
);
1187 void sci_set_target_start(ScintillaObject
*sci
, gint start
)
1189 SSM(sci
, SCI_SETTARGETSTART
, (uptr_t
) start
, 0);
1194 void sci_set_target_end(ScintillaObject
*sci
, gint end
)
1196 SSM(sci
, SCI_SETTARGETEND
, (uptr_t
) end
, 0);
1201 gint
sci_replace_target(ScintillaObject
*sci
, const gchar
*text
, gboolean regex
)
1203 return (gint
) SSM(sci
, (regex
) ? SCI_REPLACETARGETRE
: SCI_REPLACETARGET
, (uptr_t
) -1, (sptr_t
) text
);
1207 void sci_set_keywords(ScintillaObject
*sci
, guint k
, const gchar
*text
)
1209 SSM(sci
, SCI_SETKEYWORDS
, k
, (sptr_t
) text
);
1213 void sci_set_readonly(ScintillaObject
*sci
, gboolean readonly
)
1215 SSM(sci
, SCI_SETREADONLY
, readonly
!= FALSE
, 0);
1219 /** Sends Scintilla commands without any parameters.
1220 * @param sci The Scintilla @c GtkWidget.
1221 * @param cmd @c SCI_COMMAND.
1222 * @see https://scintilla.org for the documentation.
1227 void sci_send_command(ScintillaObject
*sci
, gint cmd
)
1229 SSM(sci
, cmd
, 0, 0);
1233 /** Gets current line number.
1234 * @param sci Scintilla widget.
1235 * @return Line number. */
1237 gint
sci_get_current_line(ScintillaObject
*sci
)
1239 return (gint
) SSM(sci
, SCI_LINEFROMPOSITION
, (uptr_t
) SSM(sci
, SCI_GETCURRENTPOS
, 0, 0), 0);
1243 /* Get number of lines partially or fully selected.
1244 * Returns 1 if there is a partial selection on the same line.
1245 * Returns 2 if a whole line is selected including the line break char(s). */
1246 gint
sci_get_lines_selected(ScintillaObject
*sci
)
1248 gint start
= (gint
) SSM(sci
, SCI_GETSELECTIONSTART
, 0, 0);
1249 gint end
= (gint
) SSM(sci
, SCI_GETSELECTIONEND
, 0, 0);
1254 return 0; /* no selection */
1256 line_start
= (gint
) SSM(sci
, SCI_LINEFROMPOSITION
, (uptr_t
) start
, 0);
1257 line_end
= (gint
) SSM(sci
, SCI_LINEFROMPOSITION
, (uptr_t
) end
, 0);
1259 return line_end
- line_start
+ 1;
1263 gint
sci_get_first_visible_line(ScintillaObject
*sci
)
1265 return (gint
) SSM(sci
, SCI_GETFIRSTVISIBLELINE
, 0, 0);
1270 * Sets the current indicator. This is necessary to define an indicator for a range of text or
1271 * clearing indicators for a range of text.
1273 * @param sci Scintilla widget.
1274 * @param indic The indicator number to set.
1276 * @see sci_indicator_clear
1281 void sci_indicator_set(ScintillaObject
*sci
, gint indic
)
1283 SSM(sci
, SCI_SETINDICATORCURRENT
, (uptr_t
) indic
, 0);
1287 void sci_indicator_fill(ScintillaObject
*sci
, gint pos
, gint len
)
1289 SSM(sci
, SCI_INDICATORFILLRANGE
, (uptr_t
) pos
, len
);
1294 * Clears the currently set indicator from a range of text.
1295 * Starting at @a pos, @a len characters long.
1296 * In order to make this function properly, you need to set the current indicator before with
1297 * @ref sci_indicator_set().
1299 * @param sci Scintilla widget.
1300 * @param pos Starting position.
1301 * @param len Length.
1306 void sci_indicator_clear(ScintillaObject
*sci
, gint pos
, gint len
)
1308 SSM(sci
, SCI_INDICATORCLEARRANGE
, (uptr_t
) pos
, len
);
1312 void sci_select_all(ScintillaObject
*sci
)
1314 SSM(sci
, SCI_SELECTALL
, 0, 0);
1318 gint
sci_get_line_indent_position(ScintillaObject
*sci
, gint line
)
1320 return (gint
) SSM(sci
, SCI_GETLINEINDENTPOSITION
, (uptr_t
) line
, 0);
1324 void sci_set_autoc_max_height(ScintillaObject
*sci
, gint val
)
1326 SSM(sci
, SCI_AUTOCSETMAXHEIGHT
, (uptr_t
) val
, 0);
1330 /** Finds a matching brace at @a pos.
1331 * @param sci Scintilla widget.
1332 * @param pos Position.
1333 * @return Matching brace position.
1338 gint
sci_find_matching_brace(ScintillaObject
*sci
, gint pos
)
1340 return (gint
) SSM(sci
, SCI_BRACEMATCH
, (uptr_t
) pos
, 0);
1344 gint
sci_get_overtype(ScintillaObject
*sci
)
1346 return (gint
) SSM(sci
, SCI_GETOVERTYPE
, 0, 0);
1350 void sci_set_tab_indents(ScintillaObject
*sci
, gboolean set
)
1352 SSM(sci
, SCI_SETTABINDENTS
, set
!= FALSE
, 0);
1356 void sci_set_use_tabs(ScintillaObject
*sci
, gboolean set
)
1358 SSM(sci
, SCI_SETUSETABS
, set
!= FALSE
, 0);
1362 gint
sci_get_pos_at_line_sel_start(ScintillaObject
*sci
, gint line
)
1364 return (gint
) SSM(sci
, SCI_GETLINESELSTARTPOSITION
, (uptr_t
) line
, 0);
1368 gint
sci_get_pos_at_line_sel_end(ScintillaObject
*sci
, gint line
)
1370 return (gint
) SSM(sci
, SCI_GETLINESELENDPOSITION
, (uptr_t
) line
, 0);
1374 /** Gets selection mode.
1375 * @param sci Scintilla widget.
1376 * @return Selection mode. */
1378 gint
sci_get_selection_mode(ScintillaObject
*sci
)
1380 return (gint
) SSM(sci
, SCI_GETSELECTIONMODE
, 0, 0);
1384 /** Sets selection mode.
1385 * @param sci Scintilla widget.
1386 * @param mode Mode. */
1388 void sci_set_selection_mode(ScintillaObject
*sci
, gint mode
)
1390 SSM(sci
, SCI_SETSELECTIONMODE
, (uptr_t
) mode
, 0);
1394 void sci_set_scrollbar_mode(ScintillaObject
*sci
, gboolean visible
)
1396 SSM(sci
, SCI_SETHSCROLLBAR
, visible
!= FALSE
, 0);
1397 SSM(sci
, SCI_SETVSCROLLBAR
, visible
!= FALSE
, 0);
1401 /** Sets the indentation of a line.
1402 * @param sci Scintilla widget.
1403 * @param line Line to indent.
1404 * @param indent Indentation width.
1409 void sci_set_line_indentation(ScintillaObject
*sci
, gint line
, gint indent
)
1411 SSM(sci
, SCI_SETLINEINDENTATION
, (uptr_t
) line
, indent
);
1415 /** Gets the indentation width of a line.
1416 * @param sci Scintilla widget.
1417 * @param line Line to get the indentation from.
1418 * @return Indentation width.
1423 gint
sci_get_line_indentation(ScintillaObject
*sci
, gint line
)
1425 return (gint
) SSM(sci
, SCI_GETLINEINDENTATION
, (uptr_t
) line
, 0);
1429 void sci_set_caret_policy_x(ScintillaObject
*sci
, gint policy
, gint slop
)
1431 SSM(sci
, SCI_SETXCARETPOLICY
, (uptr_t
) policy
, slop
);
1435 void sci_set_caret_policy_y(ScintillaObject
*sci
, gint policy
, gint slop
)
1437 SSM(sci
, SCI_SETYCARETPOLICY
, (uptr_t
) policy
, slop
);
1441 void sci_set_scroll_stop_at_last_line(ScintillaObject
*sci
, gboolean set
)
1443 SSM(sci
, SCI_SETENDATLASTLINE
, set
!= FALSE
, 0);
1447 void sci_cancel(ScintillaObject
*sci
)
1449 SSM(sci
, SCI_CANCEL
, 0, 0);
1453 gint
sci_get_position_after(ScintillaObject
*sci
, gint start
)
1455 return (gint
) SSM(sci
, SCI_POSITIONAFTER
, (uptr_t
) start
, 0);
1459 void sci_lines_join(ScintillaObject
*sci
)
1461 SSM(sci
, SCI_LINESJOIN
, 0, 0);
1465 gint
sci_text_width(ScintillaObject
*sci
, gint styleNumber
, const gchar
*text
)
1467 return (gint
) SSM(sci
, SCI_TEXTWIDTH
, (uptr_t
) styleNumber
, (sptr_t
) text
);
1471 void sci_move_selected_lines_down(ScintillaObject
*sci
)
1473 SSM(sci
, SCI_MOVESELECTEDLINESDOWN
, 0, 0);
1477 void sci_move_selected_lines_up(ScintillaObject
*sci
)
1479 SSM(sci
, SCI_MOVESELECTEDLINESUP
, 0, 0);
1483 gint
sci_word_start_position(ScintillaObject
*sci
, gint position
, gboolean onlyWordCharacters
)
1485 return SSM(sci
, SCI_WORDSTARTPOSITION
, position
, onlyWordCharacters
);
1489 gint
sci_word_end_position(ScintillaObject
*sci
, gint position
, gboolean onlyWordCharacters
)
1491 return SSM(sci
, SCI_WORDENDPOSITION
, position
, onlyWordCharacters
);