1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2000 Naba Kumar
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
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <libanjuta/anjuta-shell.h>
25 #include <libanjuta/anjuta-debug.h>
26 #include <libanjuta/anjuta-pkg-config-chooser.h>
27 #include <libanjuta/interfaces/ianjuta-iterable.h>
28 #include <libanjuta/interfaces/ianjuta-document.h>
29 #include <libanjuta/interfaces/ianjuta-document-manager.h>
30 #include <libanjuta/interfaces/ianjuta-editor.h>
31 #include <libanjuta/interfaces/ianjuta-file.h>
32 #include <libanjuta/interfaces/ianjuta-editor-cell.h>
33 #include <libanjuta/interfaces/ianjuta-editor-language.h>
34 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
35 #include <libanjuta/interfaces/ianjuta-editor-assist.h>
36 #include <libanjuta/interfaces/ianjuta-editor-tip.h>
37 #include <libanjuta/interfaces/ianjuta-preferences.h>
38 #include <libanjuta/interfaces/ianjuta-symbol.h>
39 #include <libanjuta/interfaces/ianjuta-language.h>
42 #include "cpp-java-utils.h"
45 #define ANJUTA_PIXMAP_SWAP "anjuta-swap"
46 #define ANJUTA_PIXMAP_AUTOINDENT "anjuta-indent-auto"
47 #define ANJUTA_STOCK_SWAP "anjuta-swap"
48 #define ANJUTA_STOCK_COMPLETE "anjuta-complete"
49 #define ANJUTA_STOCK_AUTOINDENT "anjuta-indent"
51 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-language-support-cpp-java.xml"
52 #define PREFS_BUILDER PACKAGE_DATA_DIR"/glade/anjuta-language-cpp-java.ui"
53 #define ICON_FILE "anjuta-language-cpp-java-plugin.png"
55 #define FIXME_DEFAULT_PACKAGE_VERSION "1.0"
57 /* Preferences keys */
59 #define PREF_INDENT_AUTOMATIC "language.cpp.indent.automatic"
60 #define PREF_INDENT_STATEMENT_SIZE "language.cpp.indent.statement.size"
61 #define PREF_INDENT_BRACE_SIZE "language.cpp.indent.brace.size"
62 #define PREF_INDENT_PARANTHESE_LINEUP "language.cpp.indent.paranthese.lineup"
63 #define PREF_INDENT_PARANTHESE_SIZE "language.cpp.indent.paranthese.size"
64 #define PREF_BRACE_AUTOCOMPLETION "language.cpp.brace.autocompletion"
66 #define TAB_SIZE (ianjuta_editor_get_tabsize (editor, NULL))
68 #define USE_SPACES_FOR_INDENTATION (ianjuta_editor_get_use_spaces (editor, NULL))
71 (plugin->param_statement_indentation >= 0? \
72 plugin->param_statement_indentation : \
73 anjuta_preferences_get_int (plugin->prefs, PREF_INDENT_STATEMENT_SIZE))
75 #define BRACE_INDENT \
76 (plugin->param_brace_indentation >= 0? \
77 plugin->param_brace_indentation : \
78 anjuta_preferences_get_int (plugin->prefs, PREF_INDENT_BRACE_SIZE))
80 #define CASE_INDENT (INDENT_SIZE)
81 #define LABEL_INDENT (INDENT_SIZE)
83 static gpointer parent_class
;
86 iter_is_newline (IAnjutaIterable
*iter
, gchar ch
)
88 if (ch
== '\n' || ch
== '\r')
93 /* Returns TRUE if iter was moved */
95 skip_iter_to_newline_head (IAnjutaIterable
*iter
, gchar ch
)
97 gboolean ret_val
= FALSE
;
101 /* Possibly at tail */
102 if (ianjuta_iterable_previous (iter
, NULL
))
104 ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter
),
107 /* Already at head, undo iter */
108 ianjuta_iterable_next (iter
, NULL
);
110 /* Correctly at head */
117 /* Returns TRUE if iter was moved */
119 skip_iter_to_newline_tail (IAnjutaIterable
*iter
, gchar ch
)
121 gboolean ret_val
= FALSE
;
125 /* Possibly at head */
126 if (ianjuta_iterable_previous (iter
, NULL
))
128 ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter
),
131 /* Already at tail, undo iter */
132 ianjuta_iterable_next (iter
, NULL
);
134 /* Correctly at tail */
141 /* Jumps to the reverse matching brace of the given brace character */
144 get_line_indentation (IAnjutaEditor
*editor
, gint line_num
)
146 IAnjutaIterable
*line_begin
, *line_end
;
147 gchar
*line_string
, *idx
;
148 gint line_indent
= 0;
150 line_begin
= ianjuta_editor_get_line_begin_position (editor
, line_num
, NULL
);
151 line_end
= ianjuta_editor_get_line_end_position (editor
, line_num
, NULL
);
153 DEBUG_PRINT ("%s: line begin = %d, line end = %d", __FUNCTION__,
154 line_begin, line_end);
156 if (ianjuta_iterable_compare (line_begin
, line_end
, NULL
) == 0)
158 g_object_unref (line_begin
);
159 g_object_unref (line_end
);
163 line_string
= ianjuta_editor_get_text (editor
, line_begin
, line_end
,
165 g_object_unref (line_begin
);
166 g_object_unref (line_end
);
168 /* DEBUG_PRINT ("line_string = '%s'", line_string); */
175 /* Find first non-white space */
176 while (*idx
!= '\0' && isspace (*idx
))
179 line_indent
+= TAB_SIZE
;
182 idx
++; /* Since we are looking for first non-space char, simple
183 * increment of the utf8 chars would do */
185 g_free (line_string
);
190 get_line_indentation_string (IAnjutaEditor
*editor
, gint spaces
, gint line_indent_spaces
)
193 gchar
*indent_string
;
195 if ((spaces
+ line_indent_spaces
) <= 0)
198 if (USE_SPACES_FOR_INDENTATION
)
200 indent_string
= g_new0 (gchar
, spaces
+ line_indent_spaces
+ 1);
201 for (i
= 0; i
< (spaces
+ line_indent_spaces
); i
++)
202 indent_string
[i
] = ' ';
206 gint num_tabs
= spaces
/ TAB_SIZE
;
207 gint num_spaces
= spaces
% TAB_SIZE
;
208 indent_string
= g_new0 (gchar
, num_tabs
+ num_spaces
+ line_indent_spaces
+ 1);
210 for (i
= 0; i
< num_tabs
; i
++)
211 indent_string
[i
] = '\t';
212 for (; i
< num_tabs
+ (num_spaces
+ line_indent_spaces
); i
++)
213 indent_string
[i
] = ' ';
215 return indent_string
;
218 /* Sets the iter to line end of previous line and TRUE is returned.
219 * If there is no previous line, iter is set to first character in the
220 * buffer and FALSE is returned.
223 skip_iter_to_previous_line (IAnjutaEditor
*editor
, IAnjutaIterable
*iter
)
225 gboolean found
= FALSE
;
228 while (ianjuta_iterable_previous (iter
, NULL
))
230 ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter
), 0, NULL
);
231 if (iter_is_newline (iter
, ch
))
233 skip_iter_to_newline_head (iter
, ch
);
241 /* Returns TRUE if the line is continuation of previous line (that is, it is
242 * part of the same logical line).
245 line_is_continuation (IAnjutaEditor
*editor
, IAnjutaIterable
*iter
)
247 int is_continuation
= FALSE
;
249 IAnjutaIterable
*new_iter
= ianjuta_iterable_clone (iter
, NULL
);
250 if (skip_iter_to_previous_line (editor
, new_iter
))
252 while (ianjuta_iterable_previous (new_iter
, NULL
))
254 gchar ch
= ianjuta_editor_cell_get_char
255 (IANJUTA_EDITOR_CELL (new_iter
), 0, NULL
);
256 if (ch
== ' ' || ch
== '\t')
261 is_continuation
= TRUE
;
265 if (iter_is_newline (new_iter
, ch
))
269 g_object_unref (new_iter
);
270 return is_continuation
;
273 /* Sets the iter to line end of previous logical line and TRUE is returned.
274 * If there is no previous logical line, iter is set to first character in the
275 * buffer and FALSE is returned. logical line is defined as one or more
276 * real lines that are joined with line escapes ('\' at the end of real
280 skip_iter_to_previous_logical_line (IAnjutaEditor
*editor
,
281 IAnjutaIterable
*iter
)
283 gboolean found
= TRUE
;
285 while (line_is_continuation (editor
, iter
))
288 DEBUG_PRINT ("Line %d is continuation line .. Skipping",
289 ianjuta_editor_get_line_from_position (editor, iter, NULL));
291 found
= skip_iter_to_previous_line (editor
, iter
);
296 DEBUG_PRINT ("Line %d is *not* continuation line .. Breaking",
297 ianjuta_editor_get_line_from_position (editor, iter, NULL));
300 found
= skip_iter_to_previous_line (editor
, iter
);
302 DEBUG_PRINT ("Line %d is next logical line",
303 ianjuta_editor_get_line_from_position (editor, iter, NULL));
309 line_is_preprocessor (IAnjutaEditor
*editor
, IAnjutaIterable
*iter
)
311 gboolean is_preprocessor
= FALSE
;
312 IAnjutaIterable
*new_iter
= ianjuta_iterable_clone (iter
, NULL
);
314 if (skip_iter_to_previous_logical_line (editor
, new_iter
))
316 /* Forward the newline char and point to line begin of next line */
318 ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter
),
320 skip_iter_to_newline_tail (new_iter
, ch
);
321 ianjuta_iterable_next (new_iter
, NULL
);
323 /* else, line is already pointed at first char of the line */
328 ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter
),
332 is_preprocessor
= TRUE
;
335 if (iter_is_newline (new_iter
, ch
) || !isspace (ch
))
338 while (ianjuta_iterable_next (new_iter
, NULL
));
340 g_object_unref (new_iter
);
342 return is_preprocessor
;
345 /* Skips to the end-of-line of previous non-preprocessor line. Any multiple
346 * preprocessor lines are skipped. If current
347 * line is not preprocessor line, nothing happens. If there is no previous
348 * non-preprocessor line (we are at first line of the document which happens
349 * to be preprocessor line), iter is set to the first character in the
350 * document. It returns TRUE if the line is preprocessor line, otherwise
354 skip_preprocessor_lines (IAnjutaEditor
*editor
, IAnjutaIterable
*iter
)
356 gboolean line_found
= FALSE
;
357 gboolean preprocessor_found
= FALSE
;
358 IAnjutaIterable
*new_iter
= ianjuta_iterable_clone (iter
, NULL
);
362 gboolean is_preprocessor
= FALSE
;
363 if (skip_iter_to_previous_logical_line (editor
, new_iter
))
366 ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter
),
368 skip_iter_to_newline_tail (new_iter
, ch
);
369 ianjuta_iterable_next (new_iter
, NULL
);
373 gchar ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter
),
377 is_preprocessor
= TRUE
;
379 DEBUG_PRINT ("Line %d is preprocessor line .. Skipping",
380 ianjuta_editor_get_line_from_position
381 (editor, new_iter, NULL));
385 if (iter_is_newline (new_iter
, ch
) || !isspace (ch
))
387 skip_iter_to_newline_tail (new_iter
, ch
);
391 while (ianjuta_iterable_next (new_iter
, NULL
));
395 line_found
= skip_iter_to_previous_line (editor
, new_iter
);
396 ianjuta_iterable_assign (iter
, new_iter
, NULL
);
397 preprocessor_found
= TRUE
;
402 DEBUG_PRINT ("Line %d is *not* preprocessor line .. Breaking",
403 ianjuta_editor_get_line_from_position
404 (editor, new_iter, NULL));
411 g_object_unref (new_iter
);
412 return preprocessor_found
;
416 set_indentation_param_emacs (CppJavaPlugin
* plugin
, const gchar
*param
,
419 //DEBUG_PRINT ("Setting indent param: %s = %s", param, value);
420 if (strcasecmp (param
, "indent-tabs-mode") == 0)
422 if (strcasecmp (value
, "t") == 0)
424 plugin
->param_use_spaces
= 0;
425 ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin
->current_editor
),
428 else if (strcasecmp (value
, "nil") == 0)
430 plugin
->param_use_spaces
= 1;
431 ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin
->current_editor
),
435 else if (strcasecmp (param
, "c-basic-offset") == 0)
437 plugin
->param_statement_indentation
= atoi (value
);
439 else if (strcasecmp (param
, "tab-width") == 0)
441 plugin
->param_tab_size
= atoi (value
);
442 ianjuta_editor_set_tabsize (IANJUTA_EDITOR (plugin
->current_editor
),
443 plugin
->param_tab_size
, NULL
);
448 set_indentation_param_vim (CppJavaPlugin
* plugin
, const gchar
*param
,
451 //DEBUG_PRINT ("Setting indent param: %s = %s", param, value);
452 if (g_str_equal (param
, "expandtab") ||
453 g_str_equal (param
, "et"))
455 plugin
->param_use_spaces
= 1;
456 ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin
->current_editor
),
459 else if (g_str_equal (param
, "noexpandtabs") ||
460 g_str_equal (param
, "noet"))
462 plugin
->param_use_spaces
= 0;
463 ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin
->current_editor
),
468 else if (g_str_equal (param
, "shiftwidth") ||
469 g_str_equal (param
, "sw"))
471 plugin
->param_statement_indentation
= atoi (value
);
473 else if (g_str_equal (param
, "softtabstop") ||
474 g_str_equal (param
, "sts") ||
475 g_str_equal (param
, "tabstop") ||
476 g_str_equal (param
, "ts"))
478 plugin
->param_tab_size
= atoi (value
);
479 ianjuta_editor_set_tabsize (IANJUTA_EDITOR (plugin
->current_editor
),
480 plugin
->param_tab_size
, NULL
);
485 parse_mode_line_emacs (CppJavaPlugin
*plugin
, const gchar
*modeline
)
489 strv
= g_strsplit (modeline
, ";", -1);
494 keyval
= g_strsplit (*ptr
, ":", 2);
495 if (keyval
[0] && keyval
[1])
497 g_strstrip (keyval
[0]);
498 g_strstrip (keyval
[1]);
499 set_indentation_param_emacs (plugin
, g_strchug (keyval
[0]),
500 g_strchug (keyval
[1]));
509 parse_mode_line_vim (CppJavaPlugin
*plugin
, const gchar
*modeline
)
513 strv
= g_strsplit_set (modeline
, " \t:", -1);
518 keyval
= g_strsplit (*ptr
, "=", 2);
521 g_strstrip (keyval
[0]);
524 g_strstrip (keyval
[1]);
525 set_indentation_param_vim (plugin
, g_strchug (keyval
[0]),
526 g_strchug (keyval
[1]));
529 set_indentation_param_vim (plugin
, g_strchug (keyval
[0]),
539 extract_mode_line (const gchar
*comment_text
, gboolean
* vim
)
541 /* Search for emacs-like modelines */
542 gchar
*begin_modeline
, *end_modeline
;
543 begin_modeline
= strstr (comment_text
, "-*-");
547 end_modeline
= strstr (begin_modeline
, "-*-");
551 return g_strndup (begin_modeline
, end_modeline
- begin_modeline
);
554 /* Search for vim-like modelines */
555 begin_modeline
= strstr (comment_text
, "vim:");
558 begin_modeline
+= strlen ("vim:");
559 end_modeline
= strstr (begin_modeline
, "*/");
560 /* Check for escape characters */
563 if (!g_str_equal ((end_modeline
- 1), "\\"))
566 end_modeline
= strstr (end_modeline
, "*/");
570 gchar
* vim_modeline
= g_strndup (begin_modeline
, end_modeline
- begin_modeline
);
578 #define MINI_BUFFER_SIZE 3
581 initialize_indentation_params (CppJavaPlugin
*plugin
)
583 IAnjutaIterable
*iter
;
584 GString
*comment_text
;
585 gboolean comment_begun
= FALSE
;
586 gboolean line_comment
= FALSE
;
587 gchar mini_buffer
[MINI_BUFFER_SIZE
] = {0};
589 plugin
->smart_indentation
= anjuta_preferences_get_bool (plugin
->prefs
, PREF_INDENT_AUTOMATIC
);
590 /* Disable editor intern auto-indent if smart indentation is enabled */
591 ianjuta_editor_set_auto_indent (IANJUTA_EDITOR(plugin
->current_editor
),
592 !plugin
->smart_indentation
, NULL
);
594 /* Initialize indentation parameters */
595 plugin
->param_tab_size
= -1;
596 plugin
->param_statement_indentation
= -1;
597 plugin
->param_brace_indentation
= -1;
598 plugin
->param_case_indentation
= -1;
599 plugin
->param_label_indentation
= -1;
600 plugin
->param_use_spaces
= -1;
602 /* Find the first comment text in the buffer */
603 comment_text
= g_string_new (NULL
);
604 iter
= ianjuta_editor_get_start_position (IANJUTA_EDITOR (plugin
->current_editor
),
608 gboolean shift_buffer
= TRUE
;
610 gchar ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter
),
613 for (i
= 0; i
< MINI_BUFFER_SIZE
- 1; i
++)
615 if (mini_buffer
[i
] == '\0')
618 shift_buffer
= FALSE
;
622 if (shift_buffer
== TRUE
)
624 /* Shift buffer and add */
625 for (i
= 0; i
< MINI_BUFFER_SIZE
- 1; i
++)
626 mini_buffer
[i
] = mini_buffer
[i
+1];
630 if (!comment_begun
&& strncmp (mini_buffer
, "/*", 2) == 0)
632 comment_begun
= TRUE
;
634 mini_buffer
[0] = mini_buffer
[1] = '\0';
636 else if (!comment_begun
&& strncmp (mini_buffer
, "//", 2) == 0)
638 comment_begun
= TRUE
;
641 else if (!comment_begun
&& mini_buffer
[1] != '\0')
643 /* The buffer doesn't begin with a comment */
646 else if (comment_begun
)
648 if ((line_comment
&& ch
== '\n') ||
649 (!line_comment
&& strncmp (mini_buffer
, "*/", 2) == 0))
656 g_string_append_c (comment_text
, ch
);
659 while (ianjuta_iterable_next (iter
, NULL
));
661 /* DEBUG_PRINT ("Comment text: %s", comment_text->str);*/
662 if (comment_text
->len
> 0)
665 /* First comment found */
667 gchar
*modeline
= extract_mode_line (comment_text
->str
, &vim
);
671 parse_mode_line_emacs (plugin
, modeline
);
673 parse_mode_line_vim (plugin
, modeline
);
677 g_string_free (comment_text
, TRUE
);
678 g_object_unref (iter
);
682 set_line_indentation (IAnjutaEditor
*editor
, gint line_num
, gint indentation
, gint line_indent_spaces
)
684 IAnjutaIterable
*line_begin
, *line_end
, *indent_position
;
685 IAnjutaIterable
*current_pos
;
686 gint carat_offset
, nchars
= 0, nchars_removed
= 0;
687 gchar
*old_indent_string
= NULL
, *indent_string
= NULL
;
689 /* DEBUG_PRINT ("In %s()", __FUNCTION__); */
690 line_begin
= ianjuta_editor_get_line_begin_position (editor
, line_num
, NULL
);
691 line_end
= ianjuta_editor_get_line_end_position (editor
, line_num
, NULL
);
694 DEBUG_PRINT ("line begin = %d, line end = %d, current_pos = %d",
695 line_begin, line_end, current_pos);
697 indent_position
= ianjuta_iterable_clone (line_begin
, NULL
);
699 if (ianjuta_iterable_compare (line_end
, line_begin
, NULL
) > 0)
702 gchar
*line_string
= ianjuta_editor_get_text (editor
, line_begin
,
705 //DEBUG_PRINT ("line_string = '%s'", line_string);
710 /* Find first non-white space */
711 while (*idx
!= '\0' && isspace (*idx
))
713 idx
= g_utf8_find_next_char (idx
, NULL
);
714 ianjuta_iterable_next (indent_position
, NULL
);
716 g_free (line_string
);
719 /* Indent iter defined at this point, Identify how much is current
720 * position is beyound this point. We need to restore it later after
723 current_pos
= ianjuta_editor_get_position (editor
, NULL
);
724 carat_offset
= ianjuta_iterable_diff (indent_position
, current_pos
, NULL
);
725 //DEBUG_PRINT ("carat offset is = %d", carat_offset);
727 /* Set new indentation */
728 if ((indentation
+ line_indent_spaces
) > 0)
730 indent_string
= get_line_indentation_string (editor
, indentation
, line_indent_spaces
);
731 nchars
= indent_string
? g_utf8_strlen (indent_string
, -1) : 0;
733 /* Only indent if there is something to indent with */
736 /* Get existing indentation */
737 if (ianjuta_iterable_compare (indent_position
, line_begin
, NULL
) > 0)
740 ianjuta_editor_get_text (editor
, line_begin
,
741 indent_position
, NULL
);
743 //DEBUG_PRINT ("old_indent_string = '%s'", old_indent_string);
744 nchars_removed
= g_utf8_strlen (old_indent_string
, -1);
747 /* Only indent if there was no indentation before or old
748 * indentation string was different from the new indent string
750 if (old_indent_string
== NULL
||
751 strcmp (old_indent_string
, indent_string
) != 0)
753 /* Remove the old indentation string, if there is any */
754 if (old_indent_string
)
755 ianjuta_editor_erase (editor
, line_begin
,
756 indent_position
, NULL
);
758 /* Insert the new indentation string */
759 ianjuta_editor_insert (editor
, line_begin
,
760 indent_string
, -1, NULL
);
765 /* If indentation == 0, we really didn't enter the previous code block,
766 * but we may need to clear existing indentation.
768 if ((indentation
+ line_indent_spaces
) == 0)
770 /* Get existing indentation */
771 if (ianjuta_iterable_compare (indent_position
, line_begin
, NULL
) > 0)
774 ianjuta_editor_get_text (editor
, line_begin
,
775 indent_position
, NULL
);
776 nchars_removed
= g_utf8_strlen (old_indent_string
, -1);
778 if (old_indent_string
)
779 ianjuta_editor_erase (editor
, line_begin
, indent_position
, NULL
);
782 /* Restore current position */
783 if (carat_offset
>= 0)
785 /* If the cursor was not before the first non-space character in
786 * the line, restore it's position after indentation.
789 IAnjutaIterable
*pos
= ianjuta_editor_get_line_begin_position (editor
, line_num
, NULL
);
790 for (i
= 0; i
< nchars
+ carat_offset
; i
++)
791 ianjuta_iterable_next (pos
, NULL
);
792 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
793 ianjuta_editor_goto_position (editor
, pos
, NULL
);
794 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
795 g_object_unref (pos
);
797 else /* cursor_offset < 0 */
799 /* If the cursor was somewhere in the old indentation spaces,
800 * home the cursor to first non-space character in the line (or
801 * end of line if there is no non-space characters in the line.
804 IAnjutaIterable
*pos
= ianjuta_editor_get_line_begin_position (editor
, line_num
, NULL
);
805 for (i
= 0; i
< nchars
; i
++)
806 ianjuta_iterable_next (pos
, NULL
);
807 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
808 ianjuta_editor_goto_position (editor
, pos
, NULL
);
809 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
810 g_object_unref (pos
);
813 g_object_unref (current_pos
);
814 g_object_unref (indent_position
);
815 g_object_unref (line_begin
);
816 g_object_unref (line_end
);
818 g_free (old_indent_string
);
819 g_free (indent_string
);
823 /* incomplete_statement:
824 * 1 == COMPLETE STATEMENT
825 * 0 == INCOMPLETE STATEMENT
829 get_line_indentation_base (CppJavaPlugin
*plugin
,
830 IAnjutaEditor
*editor
,
832 gint
*incomplete_statement
,
833 gint
*line_indent_spaces
,
834 gboolean
*colon_indent
)
836 IAnjutaIterable
*iter
;
838 gint line_indent
= 0;
839 gint extra_indent
= 0;
840 gboolean looking_at_just_next_line
= TRUE
;
841 gboolean current_line_is_preprocessor
= FALSE
;
842 gboolean current_line_is_continuation
= FALSE
;
843 gboolean line_checked_for_comment
= FALSE
;
845 *incomplete_statement
= -1;
846 *line_indent_spaces
= 0;
851 /* DEBUG_PRINT ("In %s()", __FUNCTION__); */
853 iter
= ianjuta_editor_get_line_begin_position (editor
, line_num
, NULL
);
855 current_line_is_preprocessor
= line_is_preprocessor (editor
, iter
);
856 current_line_is_continuation
=
857 line_is_continuation (editor
, iter
);
859 DEBUG_PRINT ("Current line is preprocessor = %d",
860 current_line_is_preprocessor);
861 DEBUG_PRINT ("Current line is continuation = %d",
862 current_line_is_continuation);
864 /* line_indent = get_line_indentation (editor, line_num - 1); */
866 if (current_line_is_preprocessor
&& current_line_is_continuation
)
868 /* Continuation of preprocessor line -- just maintain indentation */
869 g_object_unref (iter
);
870 return get_line_indentation (editor
, line_num
- 1);
872 else if (current_line_is_preprocessor
)
874 /* Preprocessor line -- indentation should be 0 */
875 g_object_unref (iter
);
879 while (ianjuta_iterable_previous (iter
, NULL
))
882 IAnjutaEditorAttribute attrib
=
883 ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter
), NULL
);
884 if (attrib
== IANJUTA_EDITOR_STRING
)
887 point_ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter
), 0,
890 /* DEBUG_PRINT("point_ch = %c", point_ch); */
892 /* Check for line comment comment */
893 if (!line_checked_for_comment
&& !isspace(point_ch
))
895 gboolean comment
= FALSE
;
896 IAnjutaIterable
* new_iter
= ianjuta_iterable_clone (iter
, NULL
);
900 c
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter
), 0,
902 if (iter_is_newline (new_iter
, c
))
904 line_checked_for_comment
= TRUE
;
909 IAnjutaIterable
* tmp_iter
= ianjuta_iterable_clone (new_iter
, NULL
);
910 if (!ianjuta_iterable_previous (tmp_iter
, NULL
))
912 g_object_unref (tmp_iter
);
915 c
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (tmp_iter
), 0,
919 /* is a line comment, skip until begin of comment */
921 g_object_unref (tmp_iter
);
924 g_object_unref (tmp_iter
);
926 } while (ianjuta_iterable_previous (new_iter
, NULL
));
929 ianjuta_iterable_assign (iter
, new_iter
, NULL
);
930 ianjuta_iterable_previous (iter
, NULL
);
931 g_object_unref (new_iter
);
934 g_object_unref (new_iter
);
936 /* Check if we are inside a comment */
937 if (point_ch
== '/' || point_ch
== '*')
939 gboolean comment
= FALSE
;
940 gboolean comment_end
= FALSE
;
941 IAnjutaIterable
* new_iter
= ianjuta_iterable_clone (iter
, NULL
);
944 gchar c
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL(new_iter
),
946 if (!comment_end
&& iter_is_newline (new_iter
, c
))
952 IAnjutaIterable
* prev
= ianjuta_iterable_clone (new_iter
, NULL
);
953 IAnjutaIterable
* next
= ianjuta_iterable_clone (new_iter
, NULL
);
954 ianjuta_iterable_previous (prev
, NULL
);
955 ianjuta_iterable_next (next
, NULL
);
956 gchar prev_c
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (prev
), 0,
958 gchar next_c
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (next
), 0,
967 /* In the middle of a comment we can't know
968 * if the statement is incomplete
970 *incomplete_statement
= -1;
971 /* ":" have to be ignored inside comments */
974 *colon_indent
= FALSE
;
975 extra_indent
-= INDENT_SIZE
;
978 g_object_unref (prev
);
979 g_object_unref (next
);
983 else if (next_c
== '/')
987 g_object_unref (prev
);
988 g_object_unref (next
);
991 /* Possibly continued comment */
992 else if (isspace(prev_c
))
994 gboolean possible_comment
= FALSE
;
995 while (ianjuta_iterable_previous (prev
, NULL
))
997 prev_c
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (prev
), 0,
999 if (!isspace(prev_c
))
1001 if (iter_is_newline (prev
, prev_c
))
1003 possible_comment
= TRUE
;
1007 if (possible_comment
)
1009 ianjuta_iterable_assign (new_iter
, prev
, NULL
);
1010 g_object_unref (prev
);
1011 g_object_unref (next
);
1015 g_object_unref (prev
);
1016 g_object_unref (next
);
1018 } while (ianjuta_iterable_previous (new_iter
, NULL
));
1021 ianjuta_iterable_assign (iter
, new_iter
, NULL
);
1022 ianjuta_iterable_previous (iter
, NULL
);
1023 g_object_unref (new_iter
);
1026 g_object_unref (new_iter
);
1028 if (point_ch
== ')' || point_ch
== ']' || point_ch
== '}')
1032 line_saved
= ianjuta_editor_get_line_from_position (editor
, iter
,
1035 /* If we encounter a block-end before anything else, the
1036 * statement could hardly be incomplte.
1038 if (point_ch
== '}' && *incomplete_statement
== -1)
1039 *incomplete_statement
= 0;
1041 /* If at level 0 indentation, encoutered a
1042 * block end, don't bother going further
1044 if (point_ch
== '}' && get_line_indentation (editor
, line_saved
) <= 0)
1047 line_indent
+= extra_indent
;
1051 /* Find matching brace and continue */
1052 if (!cpp_java_util_jump_to_matching_brace (iter
, point_ch
, -1))
1054 line_indent
= get_line_indentation (editor
, line_saved
);
1055 line_indent
+= extra_indent
;
1059 else if (point_ch
== '{')
1061 gint line_for_indent
=
1062 ianjuta_editor_get_line_from_position (editor
, iter
, NULL
);
1063 line_indent
= get_line_indentation (editor
, line_for_indent
);
1064 /* Increase line indentation */
1065 line_indent
+= INDENT_SIZE
;
1066 line_indent
+= extra_indent
;
1068 /* If we encounter a block-start before anything else, the
1069 * statement could hardly be incomplte.
1071 if (point_ch
== '{' && *incomplete_statement
== -1)
1072 *incomplete_statement
= 0;
1076 else if (point_ch
== '(' || point_ch
== '[')
1079 if (anjuta_preferences_get_bool (plugin
->prefs
,
1080 PREF_INDENT_PARANTHESE_LINEUP
))
1082 while (ianjuta_iterable_previous (iter
, NULL
))
1084 gchar dummy_ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter
), 0,
1086 if (iter_is_newline (iter
, dummy_ch
))
1088 skip_iter_to_newline_head (iter
, dummy_ch
);
1091 if (dummy_ch
== '\t')
1092 line_indent
+= TAB_SIZE
;
1094 (*line_indent_spaces
)++;
1096 (*line_indent_spaces
)++;
1097 line_indent
+= extra_indent
;
1101 gint line_for_indent
=
1102 ianjuta_editor_get_line_from_position (editor
, iter
, NULL
);
1103 line_indent
= get_line_indentation (editor
, line_for_indent
);
1104 line_indent
+= extra_indent
;
1106 (*line_indent_spaces
) += anjuta_preferences_get_int (plugin
->prefs
,
1107 PREF_INDENT_PARANTHESE_SIZE
);
1110 /* Although statement is incomplete at this point, we don't
1111 * set it to incomplete and just leave it to unknown to avaoid
1112 * increating indentation for it, because incomplete braces,
1113 * overrides any existing indentation
1115 *incomplete_statement
= -1;
1118 else if (point_ch
== ';' || point_ch
== ',')
1120 /* If we encounter statement-end before any non-whitespace
1121 * char, the statement is complete.
1123 if (*incomplete_statement
== -1)
1124 *incomplete_statement
= 0;
1126 else if (point_ch
== ':' && *colon_indent
== FALSE
)
1128 /* This is a forward reference, all lines below should have
1129 * increased indentation until the next statement has
1131 * If current line indentation is zero, that we don't indent
1133 IAnjutaIterable
* new_iter
= ianjuta_iterable_clone (iter
, NULL
);
1134 IAnjutaIterable
* line_begin
;
1135 gboolean indent
= FALSE
;
1138 /* Is the last non-whitespace in line */
1139 while (ianjuta_iterable_next (new_iter
, NULL
))
1141 c
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter
),
1145 if (iter_is_newline (new_iter
, c
))
1151 line_begin
= ianjuta_editor_get_line_begin_position(editor
,
1152 ianjuta_editor_get_line_from_position(editor
, iter
, NULL
),
1154 c
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (line_begin
),
1158 *colon_indent
= TRUE
;
1159 if (*incomplete_statement
== -1)
1160 *incomplete_statement
= 0;
1162 if (indent
&& isspace(c
))
1164 extra_indent
+= INDENT_SIZE
;
1166 g_object_unref (new_iter
);
1167 g_object_unref (line_begin
);
1169 else if (iter_is_newline (iter
, point_ch
))
1171 skip_iter_to_newline_head (iter
, point_ch
);
1173 /* We just crossed a line boundary. Skip any preprocessor lines,
1174 * and ensure that line_indent is updated with correct real
1175 * previous non-preprocessor line.
1177 if (skip_preprocessor_lines (editor
, iter
) &&
1178 looking_at_just_next_line
)
1181 gint line = ianjuta_editor_get_line_from_position (editor, iter, NULL);
1182 line_indent = get_line_indentation (editor, line);
1185 looking_at_just_next_line
= FALSE
;
1186 line_checked_for_comment
= FALSE
;
1188 else if (!isspace (point_ch
))
1190 /* If we encounter any non-whitespace char before any of the
1191 * statement-complete indicators, the statement is basically
1194 if (*incomplete_statement
== -1)
1195 *incomplete_statement
= 1;
1198 if (!line_indent
&& extra_indent
)
1200 line_indent
+= extra_indent
;
1202 g_object_unref (iter
);
1207 /* Check if iter is inside string. Begining of string
1208 * is not counted as inside.
1211 is_iter_inside_string (IAnjutaIterable
*iter
)
1213 IAnjutaEditorAttribute attrib
;
1215 attrib
= ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter
),
1217 /* Check if we are *inside* string. Begining
1218 * of string does not count as inside.
1220 if (attrib
== IANJUTA_EDITOR_STRING
)
1222 /* Peek previous attrib and see what it was */
1223 if (ianjuta_iterable_previous (iter
, NULL
))
1225 attrib
= ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL
1227 if (attrib
== IANJUTA_EDITOR_STRING
)
1229 /* We are inside string */
1234 /* The string just began, not inside.
1235 * Restore iter from the peek
1237 ianjuta_iterable_next (iter
, NULL
);
1240 /* else, there is no previous and so we can't be inside string
1247 spaces_only (IAnjutaEditor
* editor
, IAnjutaIterable
* begin
, IAnjutaIterable
* end
)
1249 gboolean empty
= TRUE
;
1251 gchar
* text
= ianjuta_editor_get_text (editor
, begin
, end
, NULL
);
1257 for (idx
= text
; *idx
!= '\0'; idx
++)
1270 get_line_auto_indentation (CppJavaPlugin
*plugin
, IAnjutaEditor
*editor
,
1271 gint line
, gint
*line_indent_spaces
)
1273 IAnjutaIterable
*iter
;
1274 IAnjutaIterable
*end_iter
;
1275 gint line_indent
= 0;
1276 gint incomplete_statement
= -1;
1277 gboolean colon_indent
= FALSE
;
1279 g_return_val_if_fail (line
> 0, 0);
1281 /* be sure to set a default if we're in the first line otherwise
1282 * the pointer'll be left hanging with no value.
1284 *line_indent_spaces
= 0;
1286 if (line
== 1) /* First line */
1292 IAnjutaIterable
* begin
= ianjuta_editor_get_line_begin_position (editor
, line
-1 , NULL
);
1293 IAnjutaIterable
* end
= ianjuta_editor_get_line_end_position (editor
, line
-1 , NULL
);
1295 if (spaces_only (editor
, begin
, end
))
1297 set_line_indentation (editor
, line
-1, 0, 0);
1299 g_object_unref (begin
);
1300 g_object_unref (end
);
1303 iter
= ianjuta_editor_get_line_begin_position (editor
, line
, NULL
);
1305 if (is_iter_inside_string (iter
))
1307 line_indent
= get_line_indentation (editor
, line
- 1);
1311 line_indent
= get_line_indentation_base (plugin
, editor
, line
,
1312 &incomplete_statement
,
1319 /* If the last non-whitespace character in the line is ":" then
1320 * we remove the extra colon_indent
1322 end_iter
= ianjuta_editor_get_line_end_position (editor
, line
, NULL
);
1324 while (ianjuta_iterable_previous (end_iter
, NULL
))
1326 ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (end_iter
),
1330 line_indent
-= INDENT_SIZE
;
1333 if (!isspace(ch
) || iter_is_newline (end_iter
, ch
))
1336 g_object_unref (end_iter
);
1339 /* Determine what the first non-white char in the line is */
1343 /* Check if we are *inside* comment or string. Begining of comment
1344 * or string does not count as inside. If inside, just align with
1345 * previous indentation.
1347 if (is_iter_inside_string (iter
))
1349 line_indent
= get_line_indentation (editor
, line
- 1);
1352 ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter
),
1354 if (iter_is_newline (iter
, ch
))
1356 skip_iter_to_newline_tail (iter
, ch
);
1358 /* First levels are excused from incomplete statement indent */
1359 if (incomplete_statement
== 1 && line_indent
> 0)
1360 line_indent
+= INDENT_SIZE
;
1366 if (line_indent
> 0)
1368 /* The first level braces are excused from brace indentation */
1370 DEBUG_PRINT ("Increasing indent level from %d to %d",
1372 line_indent + BRACE_INDENT);
1374 line_indent
+= BRACE_INDENT
;
1375 /* It looks ugly to add extra indent after case: so remove that */
1377 line_indent
-= INDENT_SIZE
;
1383 ianjuta_iterable_previous (iter
, NULL
);
1384 if (cpp_java_util_jump_to_matching_brace (iter
, ch
, -1))
1386 gint line
= ianjuta_editor_get_line_from_position (editor
,
1389 line_indent
= get_line_indentation (editor
, line
);
1396 *line_indent_spaces
= 0;
1398 else if (!isspace (ch
))
1400 /* First levels are excused from incomplete statement indent */
1401 if (incomplete_statement
== 1 && line_indent
> 0)
1402 line_indent
+= INDENT_SIZE
;
1406 while (ianjuta_iterable_next (iter
, NULL
));
1407 g_object_unref (iter
);
1413 on_editor_char_inserted_cpp (IAnjutaEditor
*editor
,
1414 IAnjutaIterable
*insert_pos
,
1416 CppJavaPlugin
*plugin
)
1418 IAnjutaEditorAttribute attrib
;
1419 IAnjutaIterable
*iter
;
1420 gboolean should_auto_indent
= FALSE
;
1422 iter
= ianjuta_iterable_clone (insert_pos
, NULL
);
1424 /* If autoindent is enabled*/
1425 if (plugin
->smart_indentation
)
1428 /* DEBUG_PRINT ("Char added at position %d: '%c'", insert_pos, ch); */
1430 if (iter_is_newline (iter
, ch
))
1432 skip_iter_to_newline_head (iter
, ch
);
1433 /* All newline entries means enable indenting */
1434 should_auto_indent
= TRUE
;
1436 else if (ch
== '{' || ch
== '}' || ch
== '#')
1438 /* Indent only when it's the first non-white space char in the line */
1440 /* Don't bother if we are inside string */
1441 attrib
= ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter
),
1443 if (attrib
!= IANJUTA_EDITOR_STRING
)
1445 /* Iterate backwards till the begining of the line and disable
1446 * indenting if any non-white space char is encountered
1449 /* Begin by assuming it should be indented */
1450 should_auto_indent
= TRUE
;
1452 while (ianjuta_iterable_previous (iter
, NULL
))
1454 ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter
),
1457 //DEBUG_PRINT ("Looking at char '%c'", ch);
1459 /* Break on begining of line (== end of previous line) */
1460 if (iter_is_newline (iter
, ch
))
1462 skip_iter_to_newline_head (iter
, ch
);
1465 /* If a non-white space char is encountered, disabled indenting */
1468 should_auto_indent
= FALSE
;
1474 if (should_auto_indent
)
1478 gint line_indent_spaces
;
1480 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
1481 initialize_indentation_params (plugin
);
1483 insert_line
= ianjuta_editor_get_lineno (editor
, NULL
);
1484 line_indent
= get_line_auto_indentation (plugin
, editor
, insert_line
, &line_indent_spaces
);
1485 set_line_indentation (editor
, insert_line
, line_indent
, line_indent_spaces
);
1486 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
1490 if (anjuta_preferences_get_bool (plugin
->prefs
, PREF_BRACE_AUTOCOMPLETION
))
1492 if (ch
== '[' || ch
== '(')
1495 IAnjutaIterable
*previous
;
1497 previous
= ianjuta_iterable_clone (iter
, NULL
);
1498 ianjuta_iterable_previous (previous
, NULL
);
1499 prev_char
= ianjuta_editor_get_text (editor
, previous
, iter
, NULL
);
1501 /* If the previous char is a ' we don't have to autocomplete */
1502 if (*prev_char
!= '\'')
1504 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (editor
), NULL
);
1505 ianjuta_iterable_next (iter
, NULL
);
1509 ianjuta_editor_insert (editor
, iter
,
1513 ianjuta_editor_insert (editor
, iter
,
1519 ianjuta_editor_goto_position (editor
, iter
, NULL
);
1520 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (editor
), NULL
);
1522 g_object_unref (previous
);
1524 else if (ch
== '"' || ch
== '\'')
1527 IAnjutaIterable
*previous
;
1529 previous
= ianjuta_iterable_clone (iter
, NULL
);
1530 ianjuta_iterable_previous (previous
, NULL
);
1531 prev_char
= ianjuta_editor_get_text (editor
, previous
, iter
, NULL
);
1534 ianjuta_iterable_next (iter
, NULL
);
1537 * If the character is " we have to decide if we need insert
1538 * another " or we have to skip the character
1540 if (ch
== '"' || ch
== '\'')
1543 * Now we have to detect if we want to manage " as a char
1545 if (*prev_char
!= '\'' && *prev_char
!= '\\')
1550 c
= g_strdup ("\"");
1551 else c
= g_strdup ("'");
1553 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (editor
), NULL
);
1554 ianjuta_editor_insert (editor
, iter
, c
, 1, NULL
);
1555 ianjuta_editor_goto_position (editor
, iter
, NULL
);
1556 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (editor
), NULL
);
1560 g_object_unref (previous
);
1561 g_object_unref (iter
);
1564 g_object_unref (previous
);
1567 g_object_unref (iter
);
1571 on_editor_char_inserted_java (IAnjutaEditor
*editor
,
1572 IAnjutaIterable
*insert_pos
,
1574 CppJavaPlugin
*plugin
)
1576 on_editor_char_inserted_cpp (editor
, insert_pos
, ch
, plugin
);
1580 install_support (CppJavaPlugin
*lang_plugin
)
1582 IAnjutaLanguage
* lang_manager
=
1583 anjuta_shell_get_interface (ANJUTA_PLUGIN (lang_plugin
)->shell
,
1584 IAnjutaLanguage
, NULL
);
1589 if (lang_plugin
->support_installed
)
1592 lang_plugin
->current_language
=
1593 ianjuta_language_get_name_from_editor (lang_manager
,
1594 IANJUTA_EDITOR_LANGUAGE (lang_plugin
->current_editor
), NULL
);
1596 DEBUG_PRINT("Language support installed for: %s",
1597 lang_plugin
->current_language
);
1599 if (lang_plugin
->current_language
&&
1600 (g_str_equal (lang_plugin
->current_language
, "C")
1601 || g_str_equal (lang_plugin
->current_language
, "C++")
1602 || g_str_equal (lang_plugin
->current_language
, "Vala")))
1604 g_signal_connect (lang_plugin
->current_editor
,
1606 G_CALLBACK (on_editor_char_inserted_cpp
),
1609 else if (lang_plugin
->current_language
&&
1610 (g_str_equal (lang_plugin
->current_language
, "Java")))
1612 g_signal_connect (lang_plugin
->current_editor
,
1614 G_CALLBACK (on_editor_char_inserted_java
),
1622 initialize_indentation_params (lang_plugin
);
1624 if (!g_str_equal (lang_plugin
->current_language
, "Vala"))
1626 CppJavaAssist
*assist
;
1628 g_assert (lang_plugin
->assist
== NULL
);
1630 assist
= cpp_java_assist_new (IANJUTA_EDITOR (lang_plugin
->current_editor
),
1631 anjuta_shell_get_interface (ANJUTA_PLUGIN (lang_plugin
)->shell
,
1632 IAnjutaSymbolManager
,
1634 lang_plugin
->prefs
);
1635 lang_plugin
->assist
= assist
;
1638 lang_plugin
->support_installed
= TRUE
;
1642 uninstall_support (CppJavaPlugin
*lang_plugin
)
1644 if (!lang_plugin
->support_installed
)
1647 if (lang_plugin
->current_language
&&
1648 (g_str_equal (lang_plugin
->current_language
, "C")
1649 || g_str_equal (lang_plugin
->current_language
, "C++")
1650 || g_str_equal (lang_plugin
->current_language
, "Vala")))
1652 g_signal_handlers_disconnect_by_func (lang_plugin
->current_editor
,
1653 G_CALLBACK (on_editor_char_inserted_cpp
),
1656 else if (lang_plugin
->current_language
&&
1657 (g_str_equal (lang_plugin
->current_language
, "Java")))
1659 g_signal_handlers_disconnect_by_func (lang_plugin
->current_editor
,
1660 G_CALLBACK (on_editor_char_inserted_java
),
1664 if (lang_plugin
->assist
)
1666 g_object_unref (lang_plugin
->assist
);
1667 lang_plugin
->assist
= NULL
;
1670 lang_plugin
->support_installed
= FALSE
;
1674 on_editor_language_changed (IAnjutaEditor
*editor
,
1675 const gchar
*new_language
,
1676 CppJavaPlugin
*plugin
)
1678 uninstall_support (plugin
);
1679 install_support (plugin
);
1683 on_value_added_current_editor (AnjutaPlugin
*plugin
, const gchar
*name
,
1684 const GValue
*value
, gpointer data
)
1686 CppJavaPlugin
*lang_plugin
;
1687 IAnjutaDocument
* doc
= IANJUTA_DOCUMENT(g_value_get_object (value
));
1688 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
1689 if (IANJUTA_IS_EDITOR(doc
))
1690 lang_plugin
->current_editor
= G_OBJECT(doc
);
1693 lang_plugin
->current_editor
= NULL
;
1696 if (IANJUTA_IS_EDITOR(lang_plugin
->current_editor
))
1697 install_support (lang_plugin
);
1698 g_signal_connect (lang_plugin
->current_editor
, "language-changed",
1699 G_CALLBACK (on_editor_language_changed
),
1704 on_value_removed_current_editor (AnjutaPlugin
*plugin
, const gchar
*name
,
1707 CppJavaPlugin
*lang_plugin
;
1708 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
1709 if (lang_plugin
->current_editor
)
1710 g_signal_handlers_disconnect_by_func (lang_plugin
->current_editor
,
1711 G_CALLBACK (on_editor_language_changed
),
1713 if (IANJUTA_IS_EDITOR(lang_plugin
->current_editor
))
1714 uninstall_support (lang_plugin
);
1715 lang_plugin
->current_editor
= NULL
;
1718 const gchar
* SOURCE_EXT
[] =
1729 const gchar
* HEADER_EXT
[] =
1741 on_swap_activate (GtkAction
* action
, gpointer data
)
1748 CppJavaPlugin
*lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
1749 IAnjutaDocumentManager
* docman
=
1750 anjuta_shell_get_interface (ANJUTA_PLUGIN(lang_plugin
)->shell
,
1751 IAnjutaDocumentManager
,
1753 if (!lang_plugin
->current_editor
|| !docman
)
1756 file
= ianjuta_file_get_file (IANJUTA_FILE (lang_plugin
->current_editor
),
1758 parent
= g_file_get_parent (file
);
1759 parent_uri
= g_file_get_uri (parent
);
1760 basename
= g_file_get_basename (file
);
1761 g_object_unref (file
);
1762 g_object_unref (parent
);
1763 ext
= strstr (basename
, ".");
1767 for (i
= 0; SOURCE_EXT
[i
] != NULL
; i
++)
1769 if (g_str_equal (ext
, SOURCE_EXT
[i
]))
1772 for (j
= 0; HEADER_EXT
[j
] != NULL
; j
++)
1778 filename
= g_strdup_printf ("%s%s", basename
, HEADER_EXT
[j
]);
1779 uri
= g_build_filename (parent_uri
, filename
, NULL
);
1780 new_file
= g_file_new_for_uri (uri
);
1783 if (g_file_query_exists (new_file
, NULL
))
1785 ianjuta_document_manager_goto_file_line (docman
,
1789 g_object_unref (new_file
);
1792 g_object_unref (new_file
);
1796 if (g_str_equal (ext
, HEADER_EXT
[i
]))
1799 for (j
= 0; SOURCE_EXT
[j
] != NULL
; j
++)
1805 filename
= g_strdup_printf ("%s%s", basename
, SOURCE_EXT
[j
]);
1806 uri
= g_build_filename (parent_uri
, filename
, NULL
);
1807 new_file
= g_file_new_for_uri (uri
);
1810 if (g_file_query_exists (new_file
, NULL
))
1812 ianjuta_document_manager_goto_file_line (docman
,
1816 g_object_unref (new_file
);
1819 g_object_unref (new_file
);
1826 g_free (parent_uri
);
1830 on_auto_indent (GtkAction
*action
, gpointer data
)
1832 gint line_start
, line_end
;
1835 gboolean has_selection
;
1837 CppJavaPlugin
*lang_plugin
;
1838 IAnjutaEditor
*editor
;
1839 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
1840 editor
= IANJUTA_EDITOR (lang_plugin
->current_editor
);
1842 has_selection
= ianjuta_editor_selection_has_selection
1843 (IANJUTA_EDITOR_SELECTION (editor
), NULL
);
1846 IAnjutaIterable
*sel_start
, *sel_end
;
1847 sel_start
= ianjuta_editor_selection_get_start (IANJUTA_EDITOR_SELECTION (editor
),
1849 sel_end
= ianjuta_editor_selection_get_end (IANJUTA_EDITOR_SELECTION (editor
),
1851 line_start
= ianjuta_editor_get_line_from_position (editor
, sel_start
, NULL
);
1852 line_end
= ianjuta_editor_get_line_from_position (editor
, sel_end
, NULL
);
1853 g_object_unref (sel_start
);
1854 g_object_unref (sel_end
);
1858 line_start
= ianjuta_editor_get_lineno (IANJUTA_EDITOR(editor
), NULL
);
1859 line_end
= line_start
;
1861 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
1862 initialize_indentation_params (lang_plugin
);
1864 for (insert_line
= line_start
; insert_line
<= line_end
; insert_line
++)
1866 gint line_indent_spaces
= 0;
1867 line_indent
= get_line_auto_indentation (lang_plugin
, editor
,
1869 &line_indent_spaces
);
1870 /* DEBUG_PRINT ("Line indent for line %d = %d", insert_line, line_indent); */
1871 set_line_indentation (editor
, insert_line
, line_indent
, line_indent_spaces
);
1873 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
1876 static GtkActionEntry actions
[] = {
1883 "ActionEditAutoindent",
1884 ANJUTA_STOCK_AUTOINDENT
,
1885 N_("Auto-Indent"), "<control>i",
1886 N_("Auto-indent current line or selection based on indentation settings"),
1887 G_CALLBACK (on_auto_indent
)
1891 N_("Swap .h/.c"), NULL
,
1892 N_("Swap C header and source files"),
1893 G_CALLBACK (on_swap_activate
)
1898 register_stock_icons (AnjutaPlugin
*plugin
)
1900 static gboolean registered
= FALSE
;
1906 /* Register stock icons */
1907 BEGIN_REGISTER_ICON (plugin
);
1908 REGISTER_ICON_FULL (ANJUTA_PIXMAP_SWAP
, ANJUTA_STOCK_SWAP
);
1909 REGISTER_ICON_FULL (ANJUTA_PIXMAP_AUTOINDENT
, ANJUTA_STOCK_AUTOINDENT
);
1914 cpp_java_plugin_activate_plugin (AnjutaPlugin
*plugin
)
1917 CppJavaPlugin
*lang_plugin
;
1918 static gboolean initialized
= FALSE
;
1920 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
1922 DEBUG_PRINT ("%s", "AnjutaLanguageCppJavaPlugin: Activating plugin ...");
1926 register_stock_icons (plugin
);
1929 lang_plugin
->prefs
= anjuta_shell_get_preferences (plugin
->shell
, NULL
);
1930 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
1931 lang_plugin
->action_group
=
1932 anjuta_ui_add_action_group_entries (ui
, "ActionGroupCppJavaAssist",
1933 _("C++/Java Assistance"),
1935 G_N_ELEMENTS (actions
),
1936 GETTEXT_PACKAGE
, TRUE
,
1938 lang_plugin
->uiid
= anjuta_ui_merge (ui
, UI_FILE
);
1940 lang_plugin
->editor_watch_id
=
1941 anjuta_plugin_add_watch (plugin
,
1942 IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT
,
1943 on_value_added_current_editor
,
1944 on_value_removed_current_editor
,
1946 initialized
= FALSE
;
1951 cpp_java_plugin_deactivate_plugin (AnjutaPlugin
*plugin
)
1954 CppJavaPlugin
*lang_plugin
;
1955 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
1957 anjuta_plugin_remove_watch (plugin
,
1958 lang_plugin
->editor_watch_id
,
1961 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
1962 anjuta_ui_unmerge (ui
, lang_plugin
->uiid
);
1963 anjuta_ui_remove_action_group (ui
, lang_plugin
->action_group
);
1965 lang_plugin
->action_group
= NULL
;
1966 lang_plugin
->uiid
= 0;
1967 DEBUG_PRINT ("%s", "AnjutaLanguageCppJavaPlugin: Deactivated plugin.");
1972 cpp_java_plugin_finalize (GObject
*obj
)
1974 /* CppJavaPlugin* plugin = ANJUTA_PLUGIN_CPP_JAVA (obj); */
1976 /* Finalization codes here */
1977 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
1981 cpp_java_plugin_dispose (GObject
*obj
)
1983 /* Disposition codes */
1984 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
1988 cpp_java_plugin_instance_init (GObject
*obj
)
1990 CppJavaPlugin
*plugin
= ANJUTA_PLUGIN_CPP_JAVA (obj
);
1991 plugin
->action_group
= NULL
;
1992 plugin
->current_editor
= NULL
;
1993 plugin
->current_language
= NULL
;
1994 plugin
->editor_watch_id
= 0;
1996 plugin
->assist
= NULL
;
2000 cpp_java_plugin_class_init (GObjectClass
*klass
)
2002 AnjutaPluginClass
*plugin_class
= ANJUTA_PLUGIN_CLASS (klass
);
2004 parent_class
= g_type_class_peek_parent (klass
);
2006 plugin_class
->activate
= cpp_java_plugin_activate_plugin
;
2007 plugin_class
->deactivate
= cpp_java_plugin_deactivate_plugin
;
2008 klass
->finalize
= cpp_java_plugin_finalize
;
2009 klass
->dispose
= cpp_java_plugin_dispose
;
2012 #define PREF_WIDGET_SPACE "preferences_toggle:bool:1:1:language.cpp.code.completion.space.after.func"
2013 #define PREF_WIDGET_BRACE "preferences_toggle:bool:1:1:language.cpp.code.completion.brace.after.func"
2014 #define PREF_WIDGET_AUTO "preferences_toggle:bool:1:1:language.cpp.code.completion.enable"
2015 #define PREF_WIDGET_PKG_CONFIG "pkg_config_chooser1"
2019 on_autocompletion_toggled (GtkToggleButton
* button
,
2023 gboolean sensitive
= gtk_toggle_button_get_active (button
);
2025 widget
= GTK_WIDGET (gtk_builder_get_object (bxml
, PREF_WIDGET_SPACE
));
2026 gtk_widget_set_sensitive (widget
, sensitive
);
2027 widget
= GTK_WIDGET (gtk_builder_get_object (bxml
, PREF_WIDGET_BRACE
));
2028 gtk_widget_set_sensitive (widget
, sensitive
);
2032 on_package_activated (AnjutaPkgConfigChooser
*self
, const gchar
* package
,
2035 CppJavaPlugin
* plugin
;
2036 IAnjutaSymbolManager
*isymbol_manager
;
2038 plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
2040 DEBUG_PRINT ("activated %s", package
);
2041 isymbol_manager
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
2042 IAnjutaSymbolManager
,
2045 ianjuta_symbol_manager_activate_package (isymbol_manager
,
2047 FIXME_DEFAULT_PACKAGE_VERSION
,
2053 on_package_deactivated (AnjutaPkgConfigChooser
*self
, const gchar
* package
,
2056 CppJavaPlugin
* plugin
;
2057 IAnjutaSymbolManager
*isymbol_manager
;
2059 plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
2061 DEBUG_PRINT ("deactivated %s", package
);
2063 isymbol_manager
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
2064 IAnjutaSymbolManager
,
2066 ianjuta_symbol_manager_deactivate_package (isymbol_manager
,
2068 FIXME_DEFAULT_PACKAGE_VERSION
,
2073 ipreferences_merge (IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
,
2076 GError
* error
= NULL
;
2077 CppJavaPlugin
* plugin
= ANJUTA_PLUGIN_CPP_JAVA (ipref
);
2078 plugin
->bxml
= gtk_builder_new ();
2080 GtkWidget
* pkg_config
;
2082 /* Add preferences */
2083 if (!gtk_builder_add_from_file (plugin
->bxml
, PREFS_BUILDER
, &error
))
2085 g_warning ("Couldn't load builder file: %s", error
->message
);
2086 g_error_free (error
);
2088 anjuta_preferences_add_from_builder (prefs
,
2089 plugin
->bxml
, "preferences", _("C/C++/Java/Vala"),
2091 toggle
= GTK_WIDGET (gtk_builder_get_object (plugin
->bxml
, PREF_WIDGET_AUTO
));
2092 g_signal_connect (toggle
, "toggled", G_CALLBACK (on_autocompletion_toggled
),
2094 on_autocompletion_toggled (GTK_TOGGLE_BUTTON (toggle
), plugin
->bxml
);
2096 pkg_config
= GTK_WIDGET (gtk_builder_get_object (plugin
->bxml
, PREF_WIDGET_PKG_CONFIG
));
2097 anjuta_pkg_config_chooser_show_active_column (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config
),
2099 g_signal_connect (G_OBJECT (pkg_config
), "package-activated",
2100 G_CALLBACK (on_package_activated
), plugin
);
2102 g_signal_connect (G_OBJECT (pkg_config
), "package-deactivated",
2103 G_CALLBACK (on_package_deactivated
), plugin
);
2105 gtk_widget_show_all (pkg_config
);
2109 ipreferences_unmerge (IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
,
2112 CppJavaPlugin
* plugin
= ANJUTA_PLUGIN_CPP_JAVA (ipref
);
2113 anjuta_preferences_remove_page(prefs
, _("C/C++/Java/Vala"));
2114 g_object_unref (plugin
->bxml
);
2118 ipreferences_iface_init (IAnjutaPreferencesIface
* iface
)
2120 iface
->merge
= ipreferences_merge
;
2121 iface
->unmerge
= ipreferences_unmerge
;
2124 ANJUTA_PLUGIN_BEGIN (CppJavaPlugin
, cpp_java_plugin
);
2125 ANJUTA_PLUGIN_ADD_INTERFACE(ipreferences
, IANJUTA_TYPE_PREFERENCES
);
2128 ANJUTA_SIMPLE_PLUGIN (CppJavaPlugin
, cpp_java_plugin
);