1 /* Bluefish HTML Editor
2  * bftextview2.h
3  *
4  * Copyright (C) 2008,2009,2010,2011,2012,2013,2014 Olivier Sessink
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 3 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
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 /*
21 BFTEXTVIEW2 DESIGN DOCS
22 
23 requirements: a textwidget with
24 - syntax highlighting
25 - block folding
26 - context-sensitive autocompletion
27 - for various languages
28 - fast (doesn't lock the GUI when syntaxt-scanning very large files)
29 
30 ============= The widget code =============
31 - to avoid locking the GUI, it should be able to scan in multiple runs
32   - it should be able to mark a region as 'needs scanning'
33   - it should be able to resume scanning on any point marked as 'needs scanning'
34 
35 the widget code, including signal handlers and idle handlers are in bftextview2.c
36 
37 ============== Syntax scanning =============
38 - scanning is done with patterns that scan within a context
39  - for e.g. php we start with an html context that scans for html tags and it scans
40    for the php-open tag <?php
41   - within a html tag we scan the html-attribute context and we scan for the end-of-tag '>'
42   - withing <?php we scan for functions/variables and for end-of-php '?>'
43 - autocompletion is also done based on the context. so for autocompletion we look-up
44   the context, and based on the context we know the possibilities
45   - for e.g. scanning within the '<img' html tag context we know that 'src' is one of
46     the valid attributes
47 - the context is kept on a stack. once the end-of-context pattern is found (a pattern that has
48 nextcontext -1), we revert to the previous context
49 
50 - changed areas are marked with a GtkTextTag called 'needscanning'.
51  - a idle function is started (if not running) to do the actual scanning
52  - the scanner keeps a timer and stops scanning once a certain time has passed
53  - if the scanning is finished the idle function stops
54 
55 
56 ============ The scanned syntax cache ============
57 - to find where to resume scanning it simply searches for the first position
58   that is marked with the needscanning tag
59  - to know which patterns to use we have to know in which context we are. we therefore keep
60    a cache of the (context)stack. on each position where the contextstack changes, we make a copy
61    of the current state and store it in a sorted balanced tree (a GSequence), sorted by the
62    character offset in the text. We store a Tfound structure. A member of the Tfound structure
63    is a pointer to the Tfoundcontext stucture which describes the current context.
64    - the positions change when text is inserted or deleted, but never their order. a GSequence
65      allows us to update the offsets for the stacks without re-sorting the entire tree
66  - same holds for the blocks. we keep a blockstack, and we keep a cache of the blockstack in the
67    same foundcache as where we keep the contextstack. The member of the Tfound structure that
68    describes the state for blocks is the Tfoundblock structure.
69 
70 - when a new block is found, a Tfound structure has a member fblock of type Tfoundblock
71   that points to the new block, and member numblockchange is 1. That Tfoundblock has a
72   pointer to it's parent block.
73 - when an end-of-block is found, the Tfound structure has again a member fblock that
74   points to the popped block, and numblockchange is -1. So to get the active block *after*
75   a popped block, you have to look at the parent of the fblock member!!!!
76 - the Tfound member charoffset_o has the character offset of the end-of-the-end-of-context-match
77   (Tfoundcontext->end_o) or the end-of-the-end-of-block-match (Tfoundblock->end2_o).
78 
79 The next ascii art shows how blocks are stored in the scancache. This is a special situation
80 in which a second block starts but does not have an end, so both blocks are popped at 'f'. A
81 Tfound structure is saved at offset B, D and F.
82 
83      --------------------Block-1-with-valid-end--------------------
84      |  |                                                      |  |
85      |  |                        ------Block-without-end-------|--|
86      |  |                        |   |                         |  |
87 -----a--B------------------------c---D-------------------------e--F---------
88      |  |                        |   |                         |  |
89      |  |Tfound numblockchange=1 |   |Tfound numblockchange=1  |  |Tfound nublockchange=-2
90      |  |end1_o == charoffset_o  |   |end1_o == charoffset_o   |  | end2_o == charoffset_o for the block1
91      |                           |                             |
92      |start1_o                   |start1_o                     |start2_o for block1
93 
94 
95 - to paint the margin and detect if we can expand/collapse blocks, we can use this same
96   scancache. Along with walking the lines to draw the line numbers we walk the GSequence
97   and see in the Tfound structures if there are new blocks that can be folded.
98 
99 
100 =========== Scanning with a DFA engine ==============
101 - the current scanning is based on Deterministic Finite Automata (DFA) just like the 1.1.6
102 unstable engine (see wikipedia for more info). The 1.1.6 engine alloc's each state in a
103 separate memory block. This new engine alloc's a large array for all states at once, so you can
104 simply move trough the array instead of following pointers.
105 The array is the array 'table' in structure Tcontext. So each context has it's own
106 DFA table. Following the DFA is then as simple as state = table[state][character];
107 where state is just an integer position in the array, and character is the current character
108 you're scanning. The array will help to speed up the scanner. I used guint16 because I
109 suspect that we never hit the 65500 states for a single context (largest patterns set right
110 now is php, 4500 functions use 32000 states).
111 When a state has a positive result (it matches something) it has an index number to
112 an array 'matches' in structure Tscantable which is an array of type Tpattern structure
113 that has the information for the matched pattern.
114 
115 - each context has it's own DFA table. The startcontext for each context is always
116 position 0 and the identstate is always position 1 in that array
117 
118 - Compared to the engine in the 1.0 series the main advantage is that we do only a single scanning
119 run for all patterns in a given context. The 1.0 scanner does multiple scanning runs for <\?php
120 and for <[a-z]+>. The new engine scans (<\?php|<[a-z]+>) but knows that both sub-patterns lead
121 to different results (different color, different context).
122 
123 ========== language parsing from the XML file ==========
124 - the languages are defined in an XML file. On startup, only the header of that file is parsed,
125 into a Tbflang struct, which defines the language and the mime types. Only when scanning for
126 one of these mime-types is requested the rest of the file is parsed (in a separate thread!!!)
127 and the DFA for this language is created. This saves memory and startup time for languages
128 that are not used in a certain session.
129 
130 For parsing we use the libxml2 textreader interface
131 http://xmlsoft.org/xmlreader.html
132 It does not need to load the full XML file into memory, it
133 is a parser that moves through the file while parsing. This
134 makes it an excellent choice to quickly parse large language
135 files in order to build the DFA table.
136 
137 A tag, keyword or patterns may have a class="foo" attribute. This pattern is only
138 added to the DFA when option "foo" is enabled. This way we can have gtk functions
139 in the C patterns for those of us that do GTK programming in Bluefish. All
140 others will have a much smaller DFA table for the C language.
141 
142 Language file loading is done in bftextview2_langmgr.c, the found patterns are added
143 to the Tscantable structure and it's members (and compiled into a DFA table)
144 in bftextview2_patcompile.c.
145 
146 ========== Symbols and identifiers in the DFA table ==========
147 Each context has symbols. Symbols are characters that may start or end a pattern.
148 Try to highlight for example:
149  char *rc_char(char*chara);
150  ^^^^          ^^^^
151 Only two of the four 'char' need to be highlighted. How does the scanner know which
152 one to highlight? In the above example there are several symbols such as whitespace
153 , brackets and operators:
154  char *rc_char(char*chara);
155 ^    ^^       ^    ^     ^^
156 see that the occurences of 'char' that should be highlighted are all in between symbols?!
157 
158 The Tcontext structure has a startstate for each context and an identifier-state (identstate).
159 In the next example state 0 is the startstate and state 1 the identstate:
160 -----------------------------------------------------------------------
161 |state|| space| a | c | h | r | * | ( | ) | _ | have match ?          |
162 -----------------------------------------------------------------------
163 |  0  ||   0  | 1 | 2 | 1 | 1 | 0 | 0 | 0 | 1 | no                    |
164 |  1  ||   0  | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | no                    |
165 |  2  ||   0  | 1 | 1 | 3 | 1 | 0 | 0 | 0 | 1 | no                    |
166 |  3  ||   0  | 4 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | no                    |
167 |  4  ||   0  | 1 | 1 | 1 | 5 | 0 | 0 | 0 | 1 | no                    |
168 |  5  ||   0  | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | yes! we have: char    |
169 -----------------------------------------------------------------------
170 now try to parse the bit '(char*' starting at state 0 (the startstate)
171 ( -> state 0 if we find state 0 we check if there is a match.. no
172 c -> state 2
173 h -> state 3
174 a -> state 4
175 r -> state 5
176 * -> state 0 if we find state 0 we check if there is a match.. YES!
177 
178 now try to scan the bit '*rc_char('
179 * -> state 0 if we find state 0 we check if there is a match.. no
180 r -> state 1
181 c -> state 1
182 _ -> state 1
183 c -> state 1
184 h -> state 1
185 a -> state 1
186 r -> state 1
187 ( -> state 0 if we find state 0 we check if there is a match.. no
188 
189 now try to scan the bit ' chara)':
190   -> state 0 if we find state 0 we check if there is a match.. no
191 c -> state 2
192 h -> state 3
193 a -> state 4
194 r -> state 5
195 a -> state 1
196 ) -> state 0 if we find state 0 we check if there is a match.. no
197 
198 as you see, the scanner is stuck in state 1 (the identstate) if
199 either on the start or on the end there is no symbol.
200 
201 ======== Autocompleting patterns =============
202 for autocompletion we keep a GCompletion in each context (member 'ac' of structure Tcontext).
203 This is filled with all the patterns during XML load.
204 
205 we use a similar scanning engine as above that can tell us where the string that
206 the user is typing started, and in which context the curor position is. Once
207 we know the context we know which GCompletion structure to use, so we can get
208 a list of possible completion strings.
209 
210 The scanning for the context is done in bftextview2_scanner.c, the rest of the autocompletion
211 code is in bftextview2_autocomp.c
212 
213 ======== Reference information ==========
214 reference information can be shown in a tooltip above the text and in a side window
215 during autocompletion. The reference information is stored in a member of the Tpattern
216 structure. Each Tcontext structure has a member patternhash that is a hashtable with the
217 match as key and the index to the pattern in array Tscantable->matches as value.
218 
219 For the tooltip we do a short scanning run to find the context and  which pattern is
220 actually under the cursor and we do a hash table lookup to find the corresponding
221 reference information.
222 
223 ========= Spell checker ===========
224 the spell checker is in bftextview2_spell.c
225 
226 after the syntax scanning is finished the spell checker is started. Similar to the syntax
227 scanner it runs in short timeslices such that it won't block the GUI. It scans only in
228 certain GtkTextTag's (for example in the GtktextTag for comments and for strings).
229 
230 ======= Storing found function names and such for jump and autocompletion ======
231 
232 identifiers, such as function names or variable names can be stored for jump and for
233 autocompletion. Code is in bftextview2_identifier.c
234 
235 for jump: found functions names are stored in a hashtable
236 bfwin->identifier_jump as
237 key Tbflang-context-name -> value Tdocument-linenumber
238 
239 for autocompletion they are added to a GCompletion
240 the GCompletion can be found in hashtable
241 bfwin->identifier_ac with
242 key Tbflang-context -> value GCompletion
243 
244 identifier_mode="1" means that the following the *following* identifier is to be stored. For example in
245 php 'function', and in python 'def' and 'class' (implemented in bluefish 2.0.3).
246 identifier_mode="2" means that the match itself is to be stored as an identifier, for example in php
247 the variable '$[a-zA-Z_][a-zA-Z0-9_]*' (implemented in 2.0.4)
248 
249 ======= Split view / slave widget =======
250 
251 a slave widget is a widget that does not do scanning itself, it doesn't
252 have a scanning table, it doesn't have any settings. It relies for all
253 of these things on the master widget. On a master widget btv->master will
254 point to itself, on a slave widget btv->master will point to the master.
255 
256 The slave widget should always be destroyed before the master.
257 */
258 
259 #ifndef _BFTEXTVIEW2_H_
260 #define _BFTEXTVIEW2_H_
261 
262 #include <gtk/gtk.h>
263 #include "config.h"
264 
265 #define IDENTSTORING
266 #define UPDATE_OFFSET_DELAYED
267 
268 /* MARKREGION: the new code the store the text locations where scanning or spellcheck is required */
269 #define MARKREGION
270 /* NEEDSCANNING: the old code the store the text locations where scanning or spellcheck is required.
271 if both old and new are defined, their results will be compared */
272 /*#define NEEDSCANNING*/
273 #ifndef NEEDSCANNING
274 #define MARKREGION
275 #endif
276 
277 #ifdef MARKREGION
278 typedef struct {
279 	gpointer head;
280 	gpointer tail;
281 	gpointer last;
282 } Tregions;
283 #endif
284 
285 typedef enum {
286 	comment_type_block,
287 	comment_type_line
288 } Tcomment_type;
289 
290 typedef struct {
291 	gchar *so;
292 	gchar *eo;
293 	Tcomment_type type;
294 } Tcomment;
295 
296 typedef struct {
297 	guint8 allsymbols[128];		/* this lookup table holds all symbols for all contexts, and is used to trigger scanning if reduced_scan_triggers is enabled */
298 	GArray *contexts;			/* dynamic sized array of Tcontext that translates a context number into a rownumber in the DFA table */
299 	GArray *matches;			/* dynamic sized array of Tpattern */
300 	GArray *comments;			/* array of Tcomment, has max. 256 entries, we use a guint8 as index */
301 	GArray *blocks; 			/* array of Tpattern_block with a guint16 as index */
302 	GArray *conditions;	/* array of Tpattern_condition with a guint16 as index */
303 } Tscantable;
304 
305 typedef struct {
306 	GSequence *foundcaches;		/* a sorted structure of Tfound for
307 								   each position where the stack changes so we can restart scanning
308 								   on any location */
309 #ifdef UPDATE_OFFSET_DELAYED
310 	gpointer offsetupdates; /* points to the last Toffsetupdate in the list (has an embedded list) */
311 #endif
312 } Tscancache;
313 /********************************/
314 /* language manager */
315 /********************************/
316 typedef struct {
317 	gchar *name;
318 	GList *mimetypes;
319 	GList *tags;				/* all tags used for highlighting in this language. we use this list when
320 								   we want to remove all tags and want to re-highlight */
321 	gchar *filename;			/* the .bflang2 file */
322 	Tscantable *st;				/* NULL or complete */
323 	gchar *smartindentchars;
324 	gchar *smartoutdentchars;
325 	gchar *smartselectionchars;
326 #ifdef HAVE_LIBENCHANT
327 	gboolean default_spellcheck;
328 	gboolean spell_decode_entities;
329 #endif
330 	gboolean no_st;				/* no scantable, for Text, don't try to load the scantable if st=NULL */
331 	gboolean parsing;			/* set to TRUE when a thread is parsing the scantable already */
332 	gboolean in_menu; /* set to TRUE to show this language in the menu */
333 	gint size_table;
334 	gint size_contexts;
335 	gint size_matches;
336 } Tbflang;
337 
338 #define BFLANG(var)  ((Tbflang *)var)
339 
340 /* Color Configuation data */
341 typedef enum {
342 	BTV_COLOR_ED_BG,
343 	BTV_COLOR_ED_FG,
344 	BTV_COLOR_WHITESPACE,
345 	BTV_COLOR_CURRENT_LINE,
346 	BTV_COLOR_RIGHT_MARGIN,
347 	BTV_COLOR_CURSOR,
348 	BTV_COLOR_SELECTION,
349 	BTV_COLOR_CURSOR_HIGHLIGHT,
350 	BTV_COLOR_MARGIN_FG,
351 	BTV_COLOR_MARGIN_BG,
352 /*	BTV_COLOR_SEARCH_BG,
353 	BTV_COLOR_SEARCH_FG,*/
354 	BTV_COLOR_COUNT
355 } Tbtv_colors;
356 
357 
358 /*****************************************************************/
359 /* stuff for the widget */
360 /*****************************************************************/
361 
362 #define BLUEFISH_TYPE_TEXT_VIEW            (bluefish_text_view_get_type ())
363 #define BLUEFISH_TEXT_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), BLUEFISH_TYPE_TEXT_VIEW, BluefishTextView))
364 #define BLUEFISH_TEXT_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), BLUEFISH_TYPE_TEXT_VIEW, BluefishTextViewClass))
365 #define BLUEFISH_IS_TEXT_VIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), BLUEFISH_TYPE_TEXT_VIEW))
366 #define BLUEFISH_IS_TEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), BLUEFISH_TYPE_TEXT_VIEW))
367 #define BLUEFISH_TEXT_VIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), BLUEFISH_TYPE_TEXT_VIEW, BluefishTextViewClass))
368 
369 typedef struct _BluefishTextView BluefishTextView;
370 typedef struct _BluefishTextViewClass BluefishTextViewClass;
371 
372 struct _BluefishTextView {
373 	GtkTextView parent;
374 	gpointer master;			/* points usually to self, but in the case of a slave widget
375 								   (two widgets showing the same buffer it will point to the master widget) */
376 	gpointer slave;				/* usually NULL, but might point to a slave widget */
377 	Tbflang *bflang;			/* Tbflang */
378 	gpointer doc;				/* Tdocument */
379 	GtkTextBuffer *buffer;
380 #ifdef NEEDSCANNING
381 	GtkTextTag *needscanning;
382 #ifdef HAVE_LIBENCHANT
383 	GtkTextTag *needspellcheck;
384 #endif 	/*HAVE_LIBENCHANT */
385 #endif
386 #ifdef MARKREGION
387 	Tregions scanning;
388 #ifdef HAVE_LIBENCHANT
389 	Tregions spellcheck;
390 #endif /*HAVE_LIBENCHANT*/
391 #endif /*MARKREGION*/
392 	GtkTextTag *blockmatch;
393 	GtkTextTag *cursortag;
394 	Tscancache scancache;
395 	guint scanner_immediate; /* event ID for the high priority scanning run */
396 	guint scanner_idle;			/* event ID for the idle function that handles the scanning. 0 if no idle function is running */
397 	guint scanner_delayed;		/* event ID for the timeout function that handles the delayed scanning. 0 if no timeout function is running */
398 	GTimer *user_idle_timer;
399 	guint user_idle;			/* event ID for the timed function that handles user idle events such as autocompletion popups */
400 	guint mark_set_idle;		/* event ID for the mark_set idle function that avoids showing matching block bounds while
401 								   you hold the arrow key to scroll quickly */
402 	gulong insert_text_id;
403 	gulong insert_text_after_id;
404 	gulong mark_set_id;
405 	gulong delete_range_id;
406 	gulong delete_range_after_id;
407 
408 	gpointer autocomp;			/* a Tacwin* with the current autocompletion window */
409 	gboolean needs_autocomp;	/* a state of the widget, autocomplete is needed on user keyboard actions */
410 	gboolean needs_blockmatch;	/* a state of the widget, if the cursor position was changed */
411 	gboolean key_press_inserted_char;	/* FALSE if the key press was used by autocomplete popup, or simply not in our widget */
412 	gdouble button_press_line; /* line location of the button press, used in the release */
413 	/*gboolean key_press_was_autocomplete;  a state of the widget, if the last keypress was handled by the autocomplete popup window */
414 	gboolean showing_blockmatch;	/* a state of the widget if we are currently showing a blockmatch */
415 	gboolean insert_was_auto_indent;	/* a state of the widget if the last keypress (enter) caused
416 										   autoindent (so we should unindent on a closing bracket */
417 	guint needremovetags;	/* after we have removed all old highlighting, we set this to G_MAXUINT32, or to the
418 									offset up to the point where we removed the old highlighting. but after a change that
419 									needs highlighting we set this to the offset of the change. */
420 	gint spacingtoclickstart;
421 	gint spacingtoclickend;
422 
423 	/* next three are used for margin painting */
424 	gint margin_pixels_per_char;
425 	gint margin_pixels_chars;
426 	gint margin_pixels_block;
427 	gint margin_pixels_symbol;
428 
429 	/* following options are simple true/false settings */
430 	gboolean enable_scanner;	/* only run scanner when TRUE, this is FALSE if the document is in the background for example */
431 	gboolean auto_indent;
432 	gboolean auto_complete;
433 	gboolean show_line_numbers;
434 	gboolean show_blocks;
435 	gboolean showsymbols;
436 	gboolean visible_spacing;
437 	gboolean show_right_margin;
438 	gboolean show_mbhl;			/* show matching block highlighting */
439 #ifdef HAVE_LIBENCHANT
440 	gboolean spell_check;
441 #endif
442 };
443 
444 struct _BluefishTextViewClass {
445 	GtkTextViewClass parent_class;
446 };
447 
448 GType bluefish_text_view_get_type(void);
449 const gchar *bluefish_text_view_get_lang_name(BluefishTextView *btv);
450 gboolean bluefish_text_view_get_active_block_boundaries(BluefishTextView *btv, guint location, gboolean innerblock, GtkTextIter *so, GtkTextIter *eo);
451 gboolean bluefish_text_view_get_active_identifier(BluefishTextView *btv, GtkTextIter *currentlocation, GtkTextIter *so, GtkTextIter *eo);
452 gpointer bftextview2_get_block_at_boundary_location(BluefishTextView *btv, guint offset, GtkTextIter *it1, GtkTextIter *it2, GtkTextIter *it3, GtkTextIter *it4);
453 gboolean bluefish_text_view_get_auto_complete(BluefishTextView * btv);
454 void bluefish_text_view_set_auto_complete(BluefishTextView * btv, gboolean enable);
455 gboolean bluefish_text_view_get_auto_indent(BluefishTextView * btv);
456 void bluefish_text_view_set_auto_indent(BluefishTextView * btv, gboolean enable);
457 void bftextview2_init_globals(void);
458 void bluefish_text_view_set_colors(BluefishTextView * btv, gchar * const *colors);
459 void bluefish_text_view_select_language(BluefishTextView * btv, const gchar * mime, const gchar * filename);
460 gboolean bluefish_text_view_get_show_blocks(BluefishTextView * btv);
461 void bluefish_text_view_set_show_blocks(BluefishTextView * btv, gboolean show);
462 void bluefish_text_view_set_show_symbols_redraw(BluefishTextView * btv, gboolean show);
463 gboolean bluefish_text_view_get_show_line_numbers(BluefishTextView * btv);
464 void bluefish_text_view_set_show_line_numbers(BluefishTextView * btv, gboolean show);
465 gboolean bluefish_text_view_get_show_visible_spacing(BluefishTextView * btv);
466 void bluefish_text_view_set_show_visible_spacing(BluefishTextView * btv, gboolean show);
467 gboolean bluefish_text_view_get_show_right_margin(BluefishTextView * btv);
468 void bluefish_text_view_set_show_right_margin(BluefishTextView * btv, gboolean show);
469 void bluefish_text_view_set_font(BluefishTextView *btv, PangoFontDescription *font_desc);
470 gboolean bluefish_text_view_get_show_mbhl(BluefishTextView * btv);
471 void bluefish_text_view_set_show_mbhl(BluefishTextView * btv, gboolean show);
472 #ifdef HAVE_LIBENCHANT
473 void bluefish_text_view_set_spell_check(BluefishTextView * btv, gboolean spell_check);
474 #endif
475 /* this functions is used in the widget in _autocomp.c */
476 gchar *get_line_indenting(GtkTextBuffer * buffer, GtkTextIter * iter, gboolean prevline);
477 void bluefish_text_view_scan_cleanup(BluefishTextView * btv);
478 void bluefish_text_view_rescan(BluefishTextView * btv);
479 void bftextview2_schedule_scanning(BluefishTextView * btv);
480 gboolean bluefish_text_view_in_comment(BluefishTextView * btv, GtkTextIter * its, GtkTextIter * ite);
481 Tcomment *bluefish_text_view_get_comment(BluefishTextView * btv, GtkTextIter * it,
482 										 Tcomment_type preferred_type);
483 gboolean last_undo_is_spacingtoclick(BluefishTextView * btv);
484 void bluefish_text_view_remove_spacingtoclick(BluefishTextView * btv);
485 
486 void bluefish_text_view_multiset(BluefishTextView * btv, gpointer doc, gint view_line_numbers,
487 							gint view_blocks, gint autoindent, gint autocomplete, gint show_mbhl, gint enable_scanner);
488 
489 GtkWidget *bftextview2_new(void);
490 GtkWidget *bftextview2_new_with_buffer(GtkTextBuffer * buffer);
491 GtkWidget *bftextview2_new_slave(BluefishTextView * master);
492 
493 #endif
494