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-glade-signal.h>
37 #include <libanjuta/interfaces/ianjuta-editor-tip.h>
38 #include <libanjuta/interfaces/ianjuta-preferences.h>
39 #include <libanjuta/interfaces/ianjuta-symbol.h>
40 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
41 #include <libanjuta/interfaces/ianjuta-language.h>
42 #include <libanjuta/interfaces/ianjuta-indenter.h>
45 #include "cpp-java-utils.h"
46 #include "cpp-java-indentation.h"
49 #define ANJUTA_PIXMAP_SWAP "anjuta-swap"
50 #define ANJUTA_PIXMAP_AUTOINDENT "anjuta-indent-auto"
51 #define ANJUTA_STOCK_SWAP "anjuta-swap"
52 #define ANJUTA_STOCK_COMPLETE "anjuta-complete"
53 #define ANJUTA_STOCK_AUTOINDENT "anjuta-indent"
54 #define ANJUTA_STOCK_COMMENT "anjuta-comment"
56 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-language-support-cpp-java.xml"
57 #define PREFS_BUILDER PACKAGE_DATA_DIR"/glade/anjuta-language-cpp-java.ui"
58 #define ICON_FILE "anjuta-language-cpp-java-plugin.png"
60 #define FIXME_DEFAULT_PACKAGE_VERSION "1.0"
62 /* Preferences keys */
64 #define PREF_SCHEMA "org.gnome.anjuta.cpp"
65 #define PREF_INDENT_AUTOMATIC "cpp-indent-automatic"
66 #define PREF_INDENT_MODELINE "cpp-indent-modeline"
67 #define PREF_PROJECT_PACKAGES "cpp-load-project-packages"
69 static gpointer parent_class
;
72 set_indentation_param_emacs (CppJavaPlugin
* plugin
, const gchar
*param
,
75 //DEBUG_PRINT ("Setting indent param: %s = %s", param, value);
76 if (strcasecmp (param
, "indent-tabs-mode") == 0)
78 if (strcasecmp (value
, "t") == 0)
80 plugin
->param_use_spaces
= 0;
81 ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin
->current_editor
),
84 else if (strcasecmp (value
, "nil") == 0)
86 plugin
->param_use_spaces
= 1;
87 ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin
->current_editor
),
91 else if (strcasecmp (param
, "c-basic-offset") == 0)
93 plugin
->param_statement_indentation
= atoi (value
);
95 else if (strcasecmp (param
, "tab-width") == 0)
97 plugin
->param_tab_size
= atoi (value
);
98 ianjuta_editor_set_tabsize (IANJUTA_EDITOR (plugin
->current_editor
),
99 plugin
->param_tab_size
, NULL
);
104 set_indentation_param_vim (CppJavaPlugin
* plugin
, const gchar
*param
,
107 //DEBUG_PRINT ("Setting indent param: %s = %s", param, value);
108 if (g_str_equal (param
, "expandtab") ||
109 g_str_equal (param
, "et"))
111 plugin
->param_use_spaces
= 1;
112 ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin
->current_editor
),
115 else if (g_str_equal (param
, "noexpandtabs") ||
116 g_str_equal (param
, "noet"))
118 plugin
->param_use_spaces
= 0;
119 ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin
->current_editor
),
124 else if (g_str_equal (param
, "shiftwidth") ||
125 g_str_equal (param
, "sw"))
127 plugin
->param_statement_indentation
= atoi (value
);
129 else if (g_str_equal (param
, "softtabstop") ||
130 g_str_equal (param
, "sts") ||
131 g_str_equal (param
, "tabstop") ||
132 g_str_equal (param
, "ts"))
134 plugin
->param_tab_size
= atoi (value
);
135 ianjuta_editor_set_tabsize (IANJUTA_EDITOR (plugin
->current_editor
),
136 plugin
->param_tab_size
, NULL
);
141 parse_mode_line_emacs (CppJavaPlugin
*plugin
, const gchar
*modeline
)
145 strv
= g_strsplit (modeline
, ";", -1);
150 keyval
= g_strsplit (*ptr
, ":", 2);
151 if (keyval
[0] && keyval
[1])
153 g_strstrip (keyval
[0]);
154 g_strstrip (keyval
[1]);
155 set_indentation_param_emacs (plugin
, g_strchug (keyval
[0]),
156 g_strchug (keyval
[1]));
165 parse_mode_line_vim (CppJavaPlugin
*plugin
, const gchar
*modeline
)
169 strv
= g_strsplit_set (modeline
, " \t:", -1);
174 keyval
= g_strsplit (*ptr
, "=", 2);
177 g_strstrip (keyval
[0]);
180 g_strstrip (keyval
[1]);
181 set_indentation_param_vim (plugin
, g_strchug (keyval
[0]),
182 g_strchug (keyval
[1]));
185 set_indentation_param_vim (plugin
, g_strchug (keyval
[0]),
195 extract_mode_line (const gchar
*comment_text
, gboolean
* vim
)
197 /* Search for emacs-like modelines */
198 gchar
*begin_modeline
, *end_modeline
;
199 begin_modeline
= strstr (comment_text
, "-*-");
203 end_modeline
= strstr (begin_modeline
, "-*-");
207 return g_strndup (begin_modeline
, end_modeline
- begin_modeline
);
210 /* Search for vim-like modelines */
211 begin_modeline
= strstr (comment_text
, "vim:");
214 begin_modeline
+= strlen ("vim:");
215 end_modeline
= strstr (begin_modeline
, "*/");
216 /* Check for escape characters */
219 if (!g_str_equal ((end_modeline
- 1), "\\"))
222 end_modeline
= strstr (end_modeline
, "*/");
226 gchar
* vim_modeline
= g_strndup (begin_modeline
, end_modeline
- begin_modeline
);
234 #define MINI_BUFFER_SIZE 3
236 initialize_indentation_params (CppJavaPlugin
*plugin
)
238 IAnjutaIterable
*iter
;
239 GString
*comment_text
;
240 gboolean comment_begun
= FALSE
;
241 gboolean line_comment
= FALSE
;
242 gchar mini_buffer
[MINI_BUFFER_SIZE
] = {0};
244 plugin
->smart_indentation
= g_settings_get_boolean (plugin
->settings
, PREF_INDENT_AUTOMATIC
);
245 /* Disable editor intern auto-indent if smart indentation is enabled */
246 ianjuta_editor_set_auto_indent (IANJUTA_EDITOR(plugin
->current_editor
),
247 !plugin
->smart_indentation
, NULL
);
249 /* Initialize indentation parameters */
250 plugin
->param_tab_size
= -1;
251 plugin
->param_statement_indentation
= -1;
252 plugin
->param_brace_indentation
= -1;
253 plugin
->param_case_indentation
= -1;
254 plugin
->param_label_indentation
= -1;
255 plugin
->param_use_spaces
= -1;
257 if (g_settings_get_boolean (plugin
->settings
,
258 PREF_INDENT_MODELINE
))
260 /* Find the first comment text in the buffer */
261 comment_text
= g_string_new (NULL
);
262 iter
= ianjuta_editor_get_start_position (IANJUTA_EDITOR (plugin
->current_editor
),
266 gboolean shift_buffer
= TRUE
;
268 gchar ch
= ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter
),
271 for (i
= 0; i
< MINI_BUFFER_SIZE
- 1; i
++)
273 if (mini_buffer
[i
] == '\0')
276 shift_buffer
= FALSE
;
280 if (shift_buffer
== TRUE
)
282 /* Shift buffer and add */
283 for (i
= 0; i
< MINI_BUFFER_SIZE
- 1; i
++)
284 mini_buffer
[i
] = mini_buffer
[i
+1];
288 if (!comment_begun
&& strncmp (mini_buffer
, "/*", 2) == 0)
290 comment_begun
= TRUE
;
292 mini_buffer
[0] = mini_buffer
[1] = '\0';
294 else if (!comment_begun
&& strncmp (mini_buffer
, "//", 2) == 0)
296 comment_begun
= TRUE
;
299 else if (!comment_begun
&& mini_buffer
[1] != '\0')
301 /* The buffer doesn't begin with a comment */
304 else if (comment_begun
)
306 if ((line_comment
&& ch
== '\n') ||
307 (!line_comment
&& strncmp (mini_buffer
, "*/", 2) == 0))
314 g_string_append_c (comment_text
, ch
);
317 while (ianjuta_iterable_next (iter
, NULL
));
319 /* DEBUG_PRINT ("Comment text: %s", comment_text->str);*/
320 if (comment_text
->len
> 0)
323 /* First comment found */
325 gchar
*modeline
= extract_mode_line (comment_text
->str
, &vim
);
329 parse_mode_line_emacs (plugin
, modeline
);
331 parse_mode_line_vim (plugin
, modeline
);
335 g_string_free (comment_text
, TRUE
);
336 g_object_unref (iter
);
343 init_file_type (CppJavaPlugin
* lang_plugin
)
345 GFile
* file
= ianjuta_file_get_file (IANJUTA_FILE (lang_plugin
->current_editor
),
350 gchar
* mime_type
= anjuta_util_get_file_mime_type (file
);
353 if (g_str_equal (mime_type
, "text/x-csrc"))
354 lang_plugin
->filetype
= LS_FILE_C
;
355 else if (g_str_equal (mime_type
, "text/x-chdr"))
356 lang_plugin
->filetype
= LS_FILE_CHDR
;
357 else if (g_str_equal (mime_type
, "text/x-c++src"))
358 lang_plugin
->filetype
= LS_FILE_CPP
;
359 else if (g_str_equal (mime_type
, "text/x-c++hdr"))
360 lang_plugin
->filetype
= LS_FILE_CPPHDR
;
362 lang_plugin
->filetype
= LS_FILE_OTHER
;
366 lang_plugin
->filetype
= LS_FILE_OTHER
;
370 on_glade_drop_possible (IAnjutaEditor
* editor
,
371 IAnjutaIterable
* iterator
,
372 CppJavaPlugin
* lang_plugin
)
374 switch (lang_plugin
->filetype
)
385 language_support_check_param_name (const gchar
* name
,
389 GString
* real_name
= g_string_new (name
);
390 while (g_list_find_custom (*names
, real_name
->str
, (GCompareFunc
) strcmp
))
392 g_string_free (real_name
, TRUE
);
393 real_name
= g_string_new (name
);
394 g_string_append_printf (real_name
, "%d", ++index
);
396 *names
= g_list_append (*names
, real_name
->str
);
397 return g_string_free (real_name
, FALSE
);
401 language_support_get_signal_parameter (const gchar
* type_name
, GList
** names
)
404 const gchar
* param_name
= NULL
;
405 GString
* param_string
;
407 /* Search for the second upper character */
408 for (c
= type_name
+ 1; *c
!= '\0'; c
++)
410 if (g_ascii_isupper (*c
))
416 if (param_name
&& strlen (param_name
))
418 param_string
= g_string_new (param_name
);
419 g_string_down (param_string
);
423 param_string
= g_string_new ("arg");
425 real_name
= language_support_check_param_name (g_string_free (param_string
, FALSE
), names
);
431 language_support_generate_c_signature (const gchar
* widget
,
434 const gchar
* handler
)
437 GString
* str
= g_string_new ("\n");
438 const gchar
* widget_param
= language_support_get_signal_parameter (widget
,
441 g_string_append (str
, g_type_name (query
.return_type
));
443 g_string_append_printf (str
, "\n%s (%s *%s", handler
, widget
, widget_param
);
445 g_string_append_printf (str
, "\n%s (gpointer user_data, %s *%s", handler
, widget
, widget_param
);
446 for (i
= 0; i
< query
.n_params
; i
++)
448 const gchar
* type_name
= g_type_name (query
.param_types
[i
]);
449 const gchar
* param_name
= language_support_get_signal_parameter (type_name
,
452 if (query
.param_types
[i
] <= G_TYPE_DOUBLE
)
454 g_string_append_printf (str
, ", %s %s", type_name
, param_name
);
458 g_string_append_printf (str
, ", %s *%s", type_name
, param_name
);
462 g_string_append (str
, ", gpointer user_data)");
464 g_string_append (str
, ")");
466 anjuta_util_glist_strings_free (names
);
472 language_support_has_symbol (CppJavaPlugin
* lang_plugin
,
473 const gchar
* handler
)
475 IAnjutaSymbolManager
*isymbol_manager
= anjuta_shell_get_interface (
476 ANJUTA_PLUGIN (lang_plugin
)->shell
,
477 IAnjutaSymbolManager
,
480 IAnjutaSymbolQuery
*symbol_query
= ianjuta_symbol_manager_create_query (
482 IANJUTA_SYMBOL_QUERY_SEARCH_FILE
,
483 IANJUTA_SYMBOL_QUERY_DB_PROJECT
,
486 GFile
* file
= ianjuta_file_get_file (IANJUTA_FILE (lang_plugin
->current_editor
),
488 IAnjutaIterable
* iter
= ianjuta_symbol_query_search_file (symbol_query
,
489 handler
, file
, NULL
);
492 g_object_unref (iter
);
498 on_glade_drop (IAnjutaEditor
* editor
,
499 IAnjutaIterable
* iterator
,
500 const gchar
* signal_data
,
501 CppJavaPlugin
* lang_plugin
)
509 const gchar
* handler
;
510 const gchar
* user_data
;
513 GStrv data
= g_strsplit(signal_data
, ":", 5);
519 swapped
= g_str_equal (data
[4], "1");
521 type
= g_type_from_name (widget
);
522 id
= g_signal_lookup (signal
, type
);
524 g_signal_query (id
, &query
);
526 if (!language_support_has_symbol (lang_plugin
, handler
))
528 switch (lang_plugin
->filetype
)
532 GString
* str
= language_support_generate_c_signature (widget
, query
,
534 g_string_append (str
, "\n{\n\n}\n");
535 ianjuta_editor_insert (editor
, iterator
,
537 g_string_free (str
, TRUE
);
542 GString
* str
= language_support_generate_c_signature (widget
, query
,
544 g_string_append (str
, ";\n");
545 ianjuta_editor_insert (editor
, iterator
,
547 g_string_free (str
, TRUE
);
557 /* Enable/Disable language-support */
560 install_support (CppJavaPlugin
*lang_plugin
)
562 IAnjutaLanguage
* lang_manager
=
563 anjuta_shell_get_interface (ANJUTA_PLUGIN (lang_plugin
)->shell
,
564 IAnjutaLanguage
, NULL
);
569 if (lang_plugin
->support_installed
)
572 lang_plugin
->current_language
=
573 ianjuta_language_get_name_from_editor (lang_manager
,
574 IANJUTA_EDITOR_LANGUAGE (lang_plugin
->current_editor
), NULL
);
576 DEBUG_PRINT("Language support installed for: %s",
577 lang_plugin
->current_language
);
579 if (lang_plugin
->current_language
&&
580 (g_str_equal (lang_plugin
->current_language
, "C")
581 || g_str_equal (lang_plugin
->current_language
, "C++")
582 || g_str_equal (lang_plugin
->current_language
, "Vala")))
584 g_signal_connect (lang_plugin
->current_editor
,
586 G_CALLBACK (cpp_indentation
),
589 else if (lang_plugin
->current_language
&&
590 (g_str_equal (lang_plugin
->current_language
, "Java")))
592 g_signal_connect (lang_plugin
->current_editor
,
594 G_CALLBACK (java_indentation
),
602 initialize_indentation_params (lang_plugin
);
603 init_file_type (lang_plugin
);
606 if (!g_str_equal (lang_plugin
->current_language
, "Vala"))
608 CppJavaAssist
*assist
;
610 g_assert (lang_plugin
->assist
== NULL
);
612 assist
= cpp_java_assist_new (IANJUTA_EDITOR (lang_plugin
->current_editor
),
613 anjuta_shell_get_interface (ANJUTA_PLUGIN (lang_plugin
)->shell
,
614 IAnjutaSymbolManager
,
616 lang_plugin
->settings
);
617 lang_plugin
->assist
= assist
;
620 if (IANJUTA_IS_EDITOR_GLADE_SIGNAL (lang_plugin
->current_editor
))
622 g_signal_connect (lang_plugin
->current_editor
,
623 "drop-possible", G_CALLBACK (on_glade_drop_possible
),
625 g_signal_connect (lang_plugin
->current_editor
,
626 "drop", G_CALLBACK (on_glade_drop
),
631 lang_plugin
->support_installed
= TRUE
;
635 uninstall_support (CppJavaPlugin
*lang_plugin
)
637 if (!lang_plugin
->support_installed
)
640 if (lang_plugin
->current_language
&&
641 (g_str_equal (lang_plugin
->current_language
, "C")
642 || g_str_equal (lang_plugin
->current_language
, "C++")
643 || g_str_equal (lang_plugin
->current_language
, "Vala")))
645 g_signal_handlers_disconnect_by_func (lang_plugin
->current_editor
,
646 G_CALLBACK (cpp_indentation
),
649 else if (lang_plugin
->current_language
&&
650 (g_str_equal (lang_plugin
->current_language
, "Java")))
652 g_signal_handlers_disconnect_by_func (lang_plugin
->current_editor
,
653 G_CALLBACK (java_indentation
),
657 if (lang_plugin
->assist
)
659 g_object_unref (lang_plugin
->assist
);
660 lang_plugin
->assist
= NULL
;
663 g_signal_handlers_disconnect_by_func (lang_plugin
->current_editor
,
664 on_glade_drop_possible
, lang_plugin
);
665 g_signal_handlers_disconnect_by_func (lang_plugin
->current_editor
,
666 on_glade_drop
, lang_plugin
);
669 lang_plugin
->support_installed
= FALSE
;
673 on_editor_language_changed (IAnjutaEditor
*editor
,
674 const gchar
*new_language
,
675 CppJavaPlugin
*plugin
)
677 uninstall_support (plugin
);
678 install_support (plugin
);
682 on_value_added_current_editor (AnjutaPlugin
*plugin
, const gchar
*name
,
683 const GValue
*value
, gpointer data
)
685 CppJavaPlugin
*lang_plugin
;
686 IAnjutaDocument
* doc
= IANJUTA_DOCUMENT(g_value_get_object (value
));
687 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
688 if (IANJUTA_IS_EDITOR(doc
))
689 lang_plugin
->current_editor
= G_OBJECT(doc
);
692 lang_plugin
->current_editor
= NULL
;
695 if (IANJUTA_IS_EDITOR(lang_plugin
->current_editor
))
696 install_support (lang_plugin
);
697 g_signal_connect (lang_plugin
->current_editor
, "language-changed",
698 G_CALLBACK (on_editor_language_changed
),
703 on_value_removed_current_editor (AnjutaPlugin
*plugin
, const gchar
*name
,
706 CppJavaPlugin
*lang_plugin
;
707 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
708 if (lang_plugin
->current_editor
)
709 g_signal_handlers_disconnect_by_func (lang_plugin
->current_editor
,
710 G_CALLBACK (on_editor_language_changed
),
712 if (IANJUTA_IS_EDITOR(lang_plugin
->current_editor
))
713 uninstall_support (lang_plugin
);
714 lang_plugin
->current_editor
= NULL
;
717 const gchar
* SOURCE_EXT
[] =
728 const gchar
* HEADER_EXT
[] =
740 on_swap_activate (GtkAction
* action
, gpointer data
)
747 CppJavaPlugin
*lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
748 IAnjutaDocumentManager
* docman
=
749 anjuta_shell_get_interface (ANJUTA_PLUGIN(lang_plugin
)->shell
,
750 IAnjutaDocumentManager
,
752 if (!lang_plugin
->current_editor
|| !docman
)
755 file
= ianjuta_file_get_file (IANJUTA_FILE (lang_plugin
->current_editor
),
757 parent
= g_file_get_parent (file
);
758 parent_uri
= g_file_get_uri (parent
);
759 basename
= g_file_get_basename (file
);
760 g_object_unref (file
);
761 g_object_unref (parent
);
762 ext
= strstr (basename
, ".");
766 for (i
= 0; SOURCE_EXT
[i
] != NULL
; i
++)
768 if (g_str_equal (ext
, SOURCE_EXT
[i
]))
771 for (j
= 0; HEADER_EXT
[j
] != NULL
; j
++)
777 filename
= g_strdup_printf ("%s%s", basename
, HEADER_EXT
[j
]);
778 uri
= g_build_filename (parent_uri
, filename
, NULL
);
779 new_file
= g_file_new_for_uri (uri
);
782 if (g_file_query_exists (new_file
, NULL
))
784 ianjuta_document_manager_goto_file_line (docman
,
788 g_object_unref (new_file
);
791 g_object_unref (new_file
);
795 if (g_str_equal (ext
, HEADER_EXT
[i
]))
798 for (j
= 0; SOURCE_EXT
[j
] != NULL
; j
++)
804 filename
= g_strdup_printf ("%s%s", basename
, SOURCE_EXT
[j
]);
805 uri
= g_build_filename (parent_uri
, filename
, NULL
);
806 new_file
= g_file_new_for_uri (uri
);
809 if (g_file_query_exists (new_file
, NULL
))
811 ianjuta_document_manager_goto_file_line (docman
,
815 g_object_unref (new_file
);
818 g_object_unref (new_file
);
829 on_auto_indent (GtkAction
*action
, gpointer data
)
831 CppJavaPlugin
*lang_plugin
;
832 IAnjutaEditor
*editor
;
833 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
834 editor
= IANJUTA_EDITOR (lang_plugin
->current_editor
);
836 cpp_auto_indentation (editor
, lang_plugin
, NULL
, NULL
);
839 /* Automatic comments */
842 is_commented_multiline (IAnjutaEditor
*editor
,
843 IAnjutaIterable
*start
,
844 IAnjutaIterable
*end
)
847 gboolean is_commented
= TRUE
;
849 text
= ianjuta_editor_get_text (editor
, start
, end
, NULL
);
850 while (is_commented
&& !g_str_has_prefix (text
, "/*"))
852 if (!ianjuta_iterable_previous (start
, NULL
))
853 is_commented
= FALSE
;
855 text
= ianjuta_editor_get_text (editor
, start
, end
, NULL
);
856 if (g_str_has_prefix (text
, "*/"))
857 is_commented
= FALSE
;
859 while (is_commented
&& !g_str_has_suffix (text
, "*/"))
861 if (!ianjuta_iterable_next (end
, NULL
))
862 is_commented
= FALSE
;
864 text
= ianjuta_editor_get_text (editor
, start
, end
, NULL
);
865 if (g_str_has_suffix (text
, "/*"))
866 is_commented
= FALSE
;
874 toggle_comment_multiline (IAnjutaEditor
*editor
,
875 IAnjutaIterable
*start
,
876 IAnjutaIterable
*end
)
878 IAnjutaIterable
*start_copy
, *end_copy
;
880 gboolean is_commented
;
882 start_copy
= ianjuta_iterable_clone (start
, NULL
);
883 end_copy
= ianjuta_iterable_clone (end
, NULL
);
884 is_commented
= is_commented_multiline (editor
, start_copy
, end_copy
);
885 text
= ianjuta_editor_get_text (editor
, start_copy
, end_copy
, NULL
);
889 ianjuta_editor_erase (editor
, start_copy
, end_copy
, NULL
);
890 ianjuta_editor_insert (editor
, start_copy
, text
+ 2,
891 (strlen (text
) - 4), NULL
);
895 ianjuta_editor_insert (editor
, end
, "*/", -1, NULL
);
896 ianjuta_editor_insert (editor
, start
, "/*", -1, NULL
);
899 g_object_unref (start_copy
);
900 g_object_unref (end_copy
);
905 toggle_comment_singleline (CppJavaPlugin
*plugin
, IAnjutaEditor
*editor
,
908 IAnjutaIterable
*begin
, *end
, *begin_copy
, *end_copy
;
909 gchar
*text
, *text_stripped
, **text_diff
= NULL
;
911 begin
= ianjuta_editor_get_line_begin_position (editor
, line
, NULL
);
912 end
= ianjuta_editor_get_line_end_position (editor
, line
, NULL
);
913 begin_copy
= ianjuta_iterable_clone (begin
, NULL
);
914 end_copy
= ianjuta_iterable_clone (end
, NULL
);
916 if (is_commented_multiline (editor
, begin_copy
, end_copy
))
918 toggle_comment_multiline (editor
, begin_copy
, end_copy
);
919 g_object_unref (begin
);
920 g_object_unref (end
);
921 g_object_unref (begin_copy
);
922 g_object_unref (end_copy
);
925 g_object_unref (begin_copy
);
926 g_object_unref (end_copy
);
928 text
= ianjuta_editor_get_text (editor
, begin
, end
, NULL
);
929 text_stripped
= g_strstrip (g_strdup (text
));
930 text_diff
= g_strsplit (text
, text_stripped
, 2);
932 if (plugin
->current_language
&&
933 (g_str_equal (plugin
->current_language
, "C")))
935 if (g_str_has_prefix (text_stripped
, "/*") &&
936 g_str_has_suffix (text_stripped
, "*/"))
938 ianjuta_editor_erase (editor
, begin
, end
, NULL
);
939 ianjuta_editor_insert (editor
, begin
, text_stripped
+ 2,
940 (strlen (text_stripped
) - 4), NULL
);
941 if (text_diff
!= NULL
)
942 ianjuta_editor_insert (editor
, begin
, *text_diff
, -1, NULL
);
946 ianjuta_editor_insert (editor
, end
, "*/", -1, NULL
);
947 ianjuta_editor_insert (editor
, begin
, "/*", -1, NULL
);
952 if (g_str_has_prefix (text_stripped
, "//"))
954 ianjuta_editor_erase (editor
, begin
, end
, NULL
);
955 ianjuta_editor_insert (editor
, begin
, text_stripped
+ 2, -1, NULL
);
956 if (text_diff
!= NULL
)
957 ianjuta_editor_insert (editor
, begin
, *text_diff
, -1, NULL
);
961 ianjuta_editor_insert (editor
, begin
, "//", -1, NULL
);
965 g_object_unref (begin
);
966 g_object_unref (end
);
968 g_free (text_stripped
);
969 g_strfreev (text_diff
);
974 on_toggle_comment (GtkAction
*action
, gpointer data
)
977 gboolean has_selection
;
979 CppJavaPlugin
*lang_plugin
;
980 IAnjutaEditor
*editor
;
981 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
982 editor
= IANJUTA_EDITOR (lang_plugin
->current_editor
);
984 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
986 has_selection
= ianjuta_editor_selection_has_selection
987 (IANJUTA_EDITOR_SELECTION (editor
), NULL
);
990 IAnjutaIterable
*sel_start
, *sel_end
;
991 sel_start
= ianjuta_editor_selection_get_start (IANJUTA_EDITOR_SELECTION (editor
),
993 sel_end
= ianjuta_editor_selection_get_end (IANJUTA_EDITOR_SELECTION (editor
),
995 toggle_comment_multiline (editor
, sel_start
, sel_end
);
996 g_object_unref (sel_start
);
997 g_object_unref (sel_end
);
1001 line
= ianjuta_editor_get_lineno (IANJUTA_EDITOR(editor
), NULL
);
1002 toggle_comment_singleline (lang_plugin
, editor
, line
);
1004 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor
), NULL
);
1009 static GtkActionEntry actions
[] = {
1016 "ActionEditAutoindent",
1017 ANJUTA_STOCK_AUTOINDENT
,
1018 N_("Auto-Indent"), "<control>i",
1019 N_("Auto-indent current line or selection based on indentation settings"),
1020 G_CALLBACK (on_auto_indent
)
1023 "ActionEditToggleComment",
1024 ANJUTA_STOCK_COMMENT
,
1025 N_("Comment/Uncomment"), "<control>m",
1026 N_("Comment or uncomment current selection"),
1027 G_CALLBACK (on_toggle_comment
)
1031 N_("Swap .h/.c"), NULL
,
1032 N_("Swap C header and source files"),
1033 G_CALLBACK (on_swap_activate
)
1038 register_stock_icons (AnjutaPlugin
*plugin
)
1040 static gboolean registered
= FALSE
;
1046 /* Register stock icons */
1047 BEGIN_REGISTER_ICON (plugin
);
1048 REGISTER_ICON_FULL (ANJUTA_PIXMAP_SWAP
, ANJUTA_STOCK_SWAP
);
1049 REGISTER_ICON_FULL (ANJUTA_PIXMAP_AUTOINDENT
, ANJUTA_STOCK_AUTOINDENT
);
1054 cpp_java_plugin_activate_plugin (AnjutaPlugin
*plugin
)
1057 CppJavaPlugin
*lang_plugin
;
1058 static gboolean initialized
= FALSE
;
1060 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
1062 DEBUG_PRINT ("%s", "AnjutaLanguageCppJavaPlugin: Activating plugin ...");
1066 register_stock_icons (plugin
);
1069 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
1070 lang_plugin
->action_group
=
1071 anjuta_ui_add_action_group_entries (ui
, "ActionGroupCppJavaAssist",
1072 _("C++/Java Assistance"),
1074 G_N_ELEMENTS (actions
),
1075 GETTEXT_PACKAGE
, TRUE
,
1077 lang_plugin
->uiid
= anjuta_ui_merge (ui
, UI_FILE
);
1079 lang_plugin
->editor_watch_id
=
1080 anjuta_plugin_add_watch (plugin
,
1081 IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT
,
1082 on_value_added_current_editor
,
1083 on_value_removed_current_editor
,
1085 initialized
= FALSE
;
1090 cpp_java_plugin_deactivate_plugin (AnjutaPlugin
*plugin
)
1093 CppJavaPlugin
*lang_plugin
;
1094 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
1096 anjuta_plugin_remove_watch (plugin
,
1097 lang_plugin
->editor_watch_id
,
1100 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
1101 anjuta_ui_unmerge (ui
, lang_plugin
->uiid
);
1102 anjuta_ui_remove_action_group (ui
, lang_plugin
->action_group
);
1104 lang_plugin
->action_group
= NULL
;
1105 lang_plugin
->uiid
= 0;
1106 DEBUG_PRINT ("%s", "AnjutaLanguageCppJavaPlugin: Deactivated plugin.");
1111 cpp_java_plugin_finalize (GObject
*obj
)
1113 /* CppJavaPlugin* plugin = ANJUTA_PLUGIN_CPP_JAVA (obj); */
1115 /* Finalization codes here */
1116 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
1120 cpp_java_plugin_dispose (GObject
*obj
)
1122 CppJavaPlugin
* plugin
= ANJUTA_PLUGIN_CPP_JAVA (obj
);
1123 /* Disposition codes */
1125 g_object_unref (plugin
->settings
);
1127 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
1131 cpp_java_plugin_instance_init (GObject
*obj
)
1133 CppJavaPlugin
*plugin
= ANJUTA_PLUGIN_CPP_JAVA (obj
);
1134 plugin
->action_group
= NULL
;
1135 plugin
->current_editor
= NULL
;
1136 plugin
->current_language
= NULL
;
1137 plugin
->editor_watch_id
= 0;
1139 plugin
->assist
= NULL
;
1140 plugin
->settings
= g_settings_new (PREF_SCHEMA
);
1144 cpp_java_plugin_class_init (GObjectClass
*klass
)
1146 AnjutaPluginClass
*plugin_class
= ANJUTA_PLUGIN_CLASS (klass
);
1148 parent_class
= g_type_class_peek_parent (klass
);
1150 plugin_class
->activate
= cpp_java_plugin_activate_plugin
;
1151 plugin_class
->deactivate
= cpp_java_plugin_deactivate_plugin
;
1152 klass
->finalize
= cpp_java_plugin_finalize
;
1153 klass
->dispose
= cpp_java_plugin_dispose
;
1156 #define PREF_WIDGET_SPACE "preferences_toggle:bool:1:1:cpp-completion-space-after-func"
1157 #define PREF_WIDGET_BRACE "preferences_toggle:bool:1:1:cpp-completion-brace-after-func"
1158 #define PREF_WIDGET_AUTO "preferences_toggle:bool:1:1:cpp-completion-enable"
1159 #define PREF_WIDGET_PACKAGES "preferences_toggle:bool:1:1:cpp-load-project-packages"
1160 #define PREF_WIDGET_PKG_CONFIG "pkg_config_chooser1"
1163 on_autocompletion_toggled (GtkToggleButton
* button
,
1167 gboolean sensitive
= gtk_toggle_button_get_active (button
);
1169 widget
= GTK_WIDGET (gtk_builder_get_object (bxml
, PREF_WIDGET_SPACE
));
1170 gtk_widget_set_sensitive (widget
, sensitive
);
1171 widget
= GTK_WIDGET (gtk_builder_get_object (bxml
, PREF_WIDGET_BRACE
));
1172 gtk_widget_set_sensitive (widget
, sensitive
);
1176 on_project_packages_toggled (GtkToggleButton
* button
,
1179 GtkWidget
* pkg_config
;
1180 gboolean sensitive
= !gtk_toggle_button_get_active (button
);
1181 pkg_config
= GTK_WIDGET (gtk_builder_get_object (bxml
, PREF_WIDGET_PKG_CONFIG
));
1183 gtk_widget_set_sensitive (pkg_config
, sensitive
);
1184 anjuta_pkg_config_chooser_show_active_only (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config
),
1189 on_package_activated (AnjutaPkgConfigChooser
*self
, const gchar
* package
,
1192 CppJavaPlugin
* plugin
;
1193 IAnjutaSymbolManager
*isymbol_manager
;
1195 plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
1197 DEBUG_PRINT ("activated %s", package
);
1198 isymbol_manager
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
1199 IAnjutaSymbolManager
,
1202 ianjuta_symbol_manager_activate_package (isymbol_manager
,
1204 FIXME_DEFAULT_PACKAGE_VERSION
,
1210 on_package_deactivated (AnjutaPkgConfigChooser
*self
, const gchar
* package
,
1213 CppJavaPlugin
* plugin
;
1214 IAnjutaSymbolManager
*isymbol_manager
;
1216 plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
1218 DEBUG_PRINT ("deactivated %s", package
);
1220 isymbol_manager
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
1221 IAnjutaSymbolManager
,
1223 ianjuta_symbol_manager_deactivate_package (isymbol_manager
,
1225 FIXME_DEFAULT_PACKAGE_VERSION
,
1230 ipreferences_merge (IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
,
1233 GError
* error
= NULL
;
1234 CppJavaPlugin
* plugin
= ANJUTA_PLUGIN_CPP_JAVA (ipref
);
1235 plugin
->bxml
= gtk_builder_new ();
1237 GtkWidget
* pkg_config
;
1239 /* Add preferences */
1240 if (!gtk_builder_add_from_file (plugin
->bxml
, PREFS_BUILDER
, &error
))
1242 g_warning ("Couldn't load builder file: %s", error
->message
);
1243 g_error_free (error
);
1245 anjuta_preferences_add_from_builder (prefs
,
1246 plugin
->bxml
, plugin
->settings
,
1247 "preferences", _("C/C++/Java/Vala"),
1249 toggle
= GTK_WIDGET (gtk_builder_get_object (plugin
->bxml
, PREF_WIDGET_AUTO
));
1250 g_signal_connect (toggle
, "toggled", G_CALLBACK (on_autocompletion_toggled
),
1252 on_autocompletion_toggled (GTK_TOGGLE_BUTTON (toggle
), plugin
->bxml
);
1254 toggle
= GTK_WIDGET (gtk_builder_get_object (plugin
->bxml
, PREF_WIDGET_PACKAGES
));
1255 g_signal_connect (toggle
, "toggled", G_CALLBACK (on_project_packages_toggled
),
1257 on_autocompletion_toggled (GTK_TOGGLE_BUTTON (toggle
), plugin
->bxml
);
1258 on_project_packages_toggled (GTK_TOGGLE_BUTTON (toggle
), plugin
->bxml
);
1260 pkg_config
= GTK_WIDGET (gtk_builder_get_object (plugin
->bxml
, PREF_WIDGET_PKG_CONFIG
));
1261 anjuta_pkg_config_chooser_show_active_column (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config
),
1263 g_signal_connect (G_OBJECT (pkg_config
), "package-activated",
1264 G_CALLBACK (on_package_activated
), plugin
);
1266 g_signal_connect (G_OBJECT (pkg_config
), "package-deactivated",
1267 G_CALLBACK (on_package_deactivated
), plugin
);
1269 gtk_widget_show_all (pkg_config
);
1273 ipreferences_unmerge (IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
,
1276 CppJavaPlugin
* plugin
= ANJUTA_PLUGIN_CPP_JAVA (ipref
);
1277 anjuta_preferences_remove_page(prefs
, _("C/C++/Java/Vala"));
1278 g_object_unref (plugin
->bxml
);
1282 ipreferences_iface_init (IAnjutaPreferencesIface
* iface
)
1284 iface
->merge
= ipreferences_merge
;
1285 iface
->unmerge
= ipreferences_unmerge
;
1289 iindenter_indent (IAnjutaIndenter
* indenter
,
1290 IAnjutaIterable
* start
,
1291 IAnjutaIterable
* end
,
1294 CppJavaPlugin
* plugin
= ANJUTA_PLUGIN_CPP_JAVA (indenter
);
1296 cpp_auto_indentation (IANJUTA_EDITOR (plugin
->current_editor
),
1302 iindenter_iface_init (IAnjutaIndenterIface
* iface
)
1304 iface
->indent
= iindenter_indent
;
1307 ANJUTA_PLUGIN_BEGIN (CppJavaPlugin
, cpp_java_plugin
);
1308 ANJUTA_PLUGIN_ADD_INTERFACE(ipreferences
, IANJUTA_TYPE_PREFERENCES
);
1309 ANJUTA_PLUGIN_ADD_INTERFACE(iindenter
, IANJUTA_TYPE_INDENTER
);
1312 ANJUTA_SIMPLE_PLUGIN (CppJavaPlugin
, cpp_java_plugin
);