Updated Spanish translation
[anjuta-git-plugin.git] / plugins / language-support-cpp-java / cpp-java-assist.c
blob5b9f005a7e66eca068f8139824e2fd7d2d5948eb
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * cpp-java-assist.c
4 * Copyright (C) 2007 Naba Kumar <naba@gnome.org>
5 * Johannes Schmid <jhs@gnome.org>
6 *
7 * anjuta is free software.
8 *
9 * You may redistribute it and/or modify it under the terms of the
10 * GNU General Public License, as published by the Free Software
11 * Foundation; either version 2 of the License, or (at your option)
12 * any later version.
14 * anjuta is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 * See the GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with anjuta. If not, write to:
21 * The Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02110-1301, USA.
26 #include <ctype.h>
27 #include <string.h>
28 #include <libanjuta/anjuta-debug.h>
29 #include <libanjuta/interfaces/ianjuta-editor-cell.h>
30 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
31 #include <libanjuta/interfaces/ianjuta-document.h>
32 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
33 #include "cpp-java-assist.h"
34 #include "cpp-java-utils.h"
36 #define PREF_AUTOCOMPLETE_ENABLE "language.cpp.code.completion.enable"
37 #define PREF_AUTOCOMPLETE_CHOICES "language.cpp.code.completion.choices"
38 #define PREF_AUTOCOMPLETE_SPACE_AFTER_FUNC "language.cpp.code.completion.space.after.func"
39 #define PREF_AUTOCOMPLETE_BRACE_AFTER_FUNC "language.cpp.code.completion.brace.after.func"
40 #define PREF_CALLTIP_ENABLE "language.cpp.code.calltip.enable"
41 #define MAX_COMPLETIONS 10
42 #define BRACE_SEARCH_LIMIT 500
44 G_DEFINE_TYPE (CppJavaAssist, cpp_java_assist, G_TYPE_OBJECT);
46 typedef struct
48 gchar *name;
49 gboolean is_func;
50 IAnjutaSymbolType type;
51 } CppJavaAssistTag;
53 struct _CppJavaAssistPriv {
54 AnjutaPreferences *preferences;
55 IAnjutaSymbolManager* isymbol_manager;
56 IAnjutaEditorAssist* iassist;
58 /* Last used cache */
59 gchar *search_cache;
60 gchar *scope_context_cache;
61 GCompletion *completion_cache;
64 static gchar*
65 completion_function (gpointer data)
67 CppJavaAssistTag * tag = (CppJavaAssistTag*) data;
68 return tag->name;
71 static gint
72 completion_compare (gconstpointer a, gconstpointer b)
74 CppJavaAssistTag * tag_a = (CppJavaAssistTag*) a;
75 CppJavaAssistTag * tag_b = (CppJavaAssistTag*) b;
76 return (strcmp (tag_a->name, tag_b->name) &&
77 tag_a->type == tag_b->type);
80 static void
81 cpp_java_assist_tag_destroy (CppJavaAssistTag *tag)
83 g_free (tag->name);
84 g_free (tag);
87 static gint
88 get_iter_column (CppJavaAssist *assist, IAnjutaIterable *iter)
90 gchar ch;
91 gint offset = 0;
92 gint tabsize =
93 ianjuta_editor_get_tabsize (IANJUTA_EDITOR (assist->priv->iassist),
94 NULL);
95 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
96 0, NULL);
98 while (ch != '\n')
100 if (!ianjuta_iterable_previous (iter, NULL))
101 break;
102 if (ch == '\t')
103 offset += tabsize - 1;
104 offset++;
105 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
106 0, NULL);
108 //DEBUG_PRINT ("Iter column: %d", offset);
109 return offset;
112 static gboolean
113 is_scope_context_character (gchar ch)
115 if (g_ascii_isspace (ch))
116 return FALSE;
117 if (g_ascii_isalnum (ch))
118 return TRUE;
119 if (ch == '_' || ch == '.' || ch == ':' || ch == '>' || ch == '-')
120 return TRUE;
122 return FALSE;
125 static gboolean
126 is_word_character (gchar ch)
128 if (g_ascii_isspace (ch))
129 return FALSE;
130 if (g_ascii_isalnum (ch))
131 return TRUE;
132 if (ch == '_')
133 return TRUE;
135 return FALSE;
138 static GCompletion*
139 create_completion (IAnjutaEditorAssist* iassist, IAnjutaIterable* iter)
141 GCompletion *completion = g_completion_new (completion_function);
142 GList* suggestions = NULL;
145 const gchar* name = ianjuta_symbol_get_name (IANJUTA_SYMBOL(iter), NULL);
146 if (name != NULL)
148 CppJavaAssistTag *tag = g_new0 (CppJavaAssistTag, 1);
149 tag->name = g_strdup (name);
150 tag->type = ianjuta_symbol_get_sym_type (IANJUTA_SYMBOL (iter),
151 NULL);
152 tag->is_func = (tag->type == IANJUTA_SYMBOL_TYPE_FUNCTION ||
153 tag->type == IANJUTA_SYMBOL_TYPE_METHOD ||
154 tag->type == IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG);
155 if (!g_list_find_custom (suggestions, tag, completion_compare))
156 suggestions = g_list_prepend (suggestions, tag);
157 else
158 g_free (tag);
160 else
161 break;
163 while (ianjuta_iterable_next (iter, NULL));
165 suggestions = g_list_sort (suggestions, completion_compare);
166 g_completion_add_items (completion, suggestions);
167 return completion;
170 static gchar*
171 cpp_java_assist_get_scope_context (IAnjutaEditor* editor,
172 const gchar *scope_operator,
173 IAnjutaIterable *iter)
175 IAnjutaIterable* end;
176 gchar ch, *scope_chars = NULL;
177 gboolean out_of_range = FALSE;
178 gboolean scope_chars_found = FALSE;
180 end = ianjuta_iterable_clone (iter, NULL);
181 ianjuta_iterable_next (end, NULL);
183 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
185 while (ch && is_scope_context_character (ch))
187 scope_chars_found = TRUE;
188 if (!ianjuta_iterable_previous (iter, NULL))
190 out_of_range = TRUE;
191 break;
193 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
195 if (scope_chars_found)
197 IAnjutaIterable* begin;
198 begin = ianjuta_iterable_clone (iter, NULL);
199 if (!out_of_range)
200 ianjuta_iterable_next (begin, NULL);
201 scope_chars = ianjuta_editor_get_text (editor, begin, end, NULL);
202 g_object_unref (begin);
204 g_object_unref (end);
205 return scope_chars;
208 static gchar*
209 cpp_java_assist_get_pre_word (IAnjutaEditor* editor, IAnjutaIterable *iter)
211 IAnjutaIterable *end;
212 gchar ch, *preword_chars = NULL;
213 gboolean out_of_range = FALSE;
214 gboolean preword_found = TRUE;
216 end = ianjuta_iterable_clone (iter, NULL);
217 ianjuta_iterable_next (end, NULL);
219 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
221 while (ch && is_word_character (ch))
223 preword_found = TRUE;
224 if (!ianjuta_iterable_previous (iter, NULL))
226 out_of_range = TRUE;
227 break;
229 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
232 if (preword_found)
234 IAnjutaIterable *begin = ianjuta_iterable_clone (iter, NULL);
235 if (!out_of_range)
236 ianjuta_iterable_next (begin, NULL);
237 preword_chars = ianjuta_editor_get_text (editor, begin, end, NULL);
238 g_object_unref (begin);
240 g_object_unref (end);
241 return preword_chars;
244 static gchar*
245 cpp_java_assist_get_scope_operator (IAnjutaEditor* editor,
246 IAnjutaIterable *iter)
248 gchar op[3] = {'\0', '\0', '\0'};
250 op[1] = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
251 if (op[1] == ':' || op[1] == '>' || op[1] == '.')
253 if (ianjuta_iterable_previous (iter, NULL))
255 op[0] = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
256 0, NULL);
257 if ((op[0] == ':' && op[1] == ':') ||
258 (op[0] == '-' && op[1] == '>'))
260 ianjuta_iterable_previous (iter, NULL);
261 return g_strdup (op);
263 else
265 if (op[1] == '.')
266 return g_strdup (&op[1]);
269 else
271 if (op[1] == '.')
272 return g_strdup (&op[1]);
275 return NULL;
278 static void
279 cpp_java_assist_destroy_completion_cache (CppJavaAssist *assist)
281 if (assist->priv->search_cache)
283 g_free (assist->priv->search_cache);
284 assist->priv->search_cache = NULL;
286 if (assist->priv->scope_context_cache)
288 g_free (assist->priv->scope_context_cache);
289 assist->priv->scope_context_cache = NULL;
291 if (assist->priv->completion_cache)
293 GList* items = assist->priv->completion_cache->items;
294 if (items)
296 g_list_foreach (items, (GFunc) cpp_java_assist_tag_destroy, NULL);
297 g_completion_clear_items (assist->priv->completion_cache);
299 g_completion_free (assist->priv->completion_cache);
300 assist->priv->completion_cache = NULL;
304 static void
305 cpp_java_assist_create_scope_completion_cache (CppJavaAssist *assist,
306 const gchar *scope_operator,
307 const gchar *scope_context)
309 DEBUG_PRINT ("TODO: cpp_java_assist_create_scope_completion_cache ()");
310 #if 0
311 cpp_java_assist_destroy_completion_cache (assist);
312 if (g_str_equal (scope_operator, "::"))
314 IAnjutaIterable* iter =
315 ianjuta_symbol_manager_get_members (assist->priv->isymbol_manager,
316 scope_context, TRUE, NULL);
317 if (iter)
319 assist->priv->completion_cache =
320 create_completion (assist->priv->iassist, iter);
321 assist->priv->scope_context_cache = g_strdup (scope_context);
322 g_object_unref (iter);
325 else if (g_str_equal (scope_operator, ".") ||
326 g_str_equal (scope_operator, "->"))
328 /* TODO: Find the type of context by parsing the file somehow and
329 search for the member as it is done with the :: context */
331 #endif
334 static void
335 cpp_java_assist_create_word_completion_cache (CppJavaAssist *assist,
336 const gchar *pre_word)
338 gint max_completions;
339 max_completions =
340 anjuta_preferences_get_int_with_default (assist->priv->preferences,
341 PREF_AUTOCOMPLETE_CHOICES,
342 MAX_COMPLETIONS);
344 cpp_java_assist_destroy_completion_cache (assist);
345 IAnjutaIterable* iter =
346 ianjuta_symbol_manager_search (assist->priv->isymbol_manager,
347 IANJUTA_SYMBOL_TYPE_MAX,
348 TRUE,
349 IANJUTA_SYMBOL_FIELD_SIMPLE|IANJUTA_SYMBOL_FIELD_TYPE,
350 pre_word, TRUE, TRUE, max_completions, -1, NULL);
351 if (iter)
353 assist->priv->completion_cache =
354 create_completion (assist->priv->iassist, iter);
355 assist->priv->search_cache = g_strdup (pre_word);
356 g_object_unref (iter);
360 static gboolean
361 cpp_java_assist_show_autocomplete (CppJavaAssist *assist,
362 const gchar *pre_word)
364 IAnjutaIterable *position;
365 gint max_completions, length;
366 GList *completion_list;
368 if (assist->priv->completion_cache == NULL) return FALSE;
370 if (pre_word)
371 g_completion_complete (assist->priv->completion_cache, pre_word, NULL);
372 else
373 g_completion_complete (assist->priv->completion_cache, "", NULL);
375 position =
376 ianjuta_editor_get_position (IANJUTA_EDITOR (assist->priv->iassist),
377 NULL);
378 max_completions =
379 anjuta_preferences_get_int_with_default (assist->priv->preferences,
380 PREF_AUTOCOMPLETE_CHOICES,
381 MAX_COMPLETIONS);
382 /* If there is cache use that */
383 if (assist->priv->completion_cache->cache)
384 completion_list = assist->priv->completion_cache->cache;
386 /* If there is no cache, it means that no string completion happened
387 * because the list is being shown for member completion just after
388 * scope operator where there is no preword yet entered. So use the
389 * full list because that's the full list of members of that scope.
391 else if (!pre_word)
392 completion_list = assist->priv->completion_cache->items;
394 /* If there is no cache and no pre_word, it means something else (?) */
395 else
396 return FALSE;
398 length = g_list_length (completion_list);
399 if (length <= max_completions)
401 if (length > 1 || !pre_word ||
402 !g_str_equal (pre_word,
403 ((CppJavaAssistTag*)completion_list->data)->name))
405 GList *node, *suggestions = NULL;
406 gint alignment;
408 node = completion_list;
409 while (node)
411 CppJavaAssistTag *tag = node->data;
413 gchar *entry;
415 if (tag->is_func)
416 entry = g_strdup_printf ("%s()", tag->name);
417 else
418 entry = g_strdup_printf ("%s", tag->name);
419 suggestions = g_list_prepend (suggestions, entry);
420 node = g_list_next (node);
422 suggestions = g_list_reverse (suggestions);
423 alignment = pre_word? strlen (pre_word) : 0;
425 ianjuta_editor_assist_suggest (assist->priv->iassist,
426 suggestions,
427 position,
428 alignment,
429 NULL);
430 g_list_foreach (suggestions, (GFunc) g_free, NULL);
431 g_list_free (suggestions);
432 return TRUE;
435 g_object_unref (position);
436 return FALSE;
439 static gchar*
440 cpp_java_assist_get_calltip_context (CppJavaAssist *assist,
441 IAnjutaIterable *iter,
442 gint *context_offset)
444 gchar ch;
445 gchar *context = NULL;
447 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
448 if (ch == ')')
450 if (!cpp_java_util_jump_to_matching_brace (iter, ')', -1))
451 return NULL;
452 if (!ianjuta_iterable_previous (iter, NULL))
453 return NULL;
455 if (ch != '(')
457 if (!cpp_java_util_jump_to_matching_brace (iter, ')',
458 BRACE_SEARCH_LIMIT))
459 return NULL;
462 /* Skip white spaces */
463 while (ianjuta_iterable_previous (iter, NULL)
464 && g_ascii_isspace (ianjuta_editor_cell_get_char
465 (IANJUTA_EDITOR_CELL (iter), 0, NULL)));
468 context = cpp_java_assist_get_scope_context
469 (IANJUTA_EDITOR (assist->priv->iassist), "(", iter);
471 if (context_offset)
473 *context_offset = get_iter_column (assist, iter);
476 return context;
479 static gboolean
480 cpp_java_assist_show_calltip (CppJavaAssist *assist, gchar *call_context,
481 gint context_offset,
482 IAnjutaIterable *position_iter)
484 GList *tips = NULL;
485 gint max_completions;
487 max_completions =
488 anjuta_preferences_get_int_with_default (assist->priv->preferences,
489 PREF_AUTOCOMPLETE_CHOICES,
490 MAX_COMPLETIONS);
492 IAnjutaIterable* iter =
493 ianjuta_symbol_manager_search (assist->priv->isymbol_manager,
494 IANJUTA_SYMBOL_TYPE_PROTOTYPE|
495 IANJUTA_SYMBOL_TYPE_FUNCTION|
496 IANJUTA_SYMBOL_TYPE_METHOD|
497 IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG,
498 TRUE,
499 IANJUTA_SYMBOL_FIELD_SIMPLE,
500 call_context, FALSE, TRUE, max_completions,
501 -1, NULL);
502 if (iter)
506 IAnjutaSymbol* symbol = IANJUTA_SYMBOL(iter);
507 const gchar* name = ianjuta_symbol_get_name(symbol, NULL);
508 if (name != NULL)
510 const gchar* args = ianjuta_symbol_get_args(symbol, NULL);
511 gchar* print_args;
512 gchar* separator;
513 gchar* white_name = g_strnfill (strlen(name) + 1, ' ');
515 separator = g_strjoin (NULL, ", \n", white_name, NULL);
516 //DEBUG_PRINT ("Separator: \n%s", separator);
518 gchar** argv;
519 if (!args)
520 args = "()";
522 argv = g_strsplit (args, ",", -1);
523 print_args = g_strjoinv (separator, argv);
525 gchar* tip = g_strdup_printf ("%s %s", name, print_args);
527 if (!g_list_find_custom (tips, tip, (GCompareFunc) strcmp))
528 tips = g_list_append (tips, tip);
530 g_strfreev (argv);
531 g_free (print_args);
532 g_free (separator);
533 g_free (white_name);
535 else
536 break;
538 while (ianjuta_iterable_next (iter, NULL));
540 if (tips)
542 /* Calculate calltip offset from context offset */
543 gint char_alignment =
544 get_iter_column (assist, position_iter)- context_offset;
546 if (char_alignment < 0)
547 char_alignment = context_offset;
549 ianjuta_editor_assist_show_tips (assist->priv->iassist, tips,
550 position_iter, char_alignment,
551 NULL);
552 g_list_foreach (tips, (GFunc) g_free, NULL);
553 g_list_free (tips);
554 return TRUE;
557 return FALSE;
560 gboolean
561 cpp_java_assist_check (CppJavaAssist *assist, gboolean autocomplete,
562 gboolean calltips)
564 gboolean shown = FALSE;
565 IAnjutaEditor *editor;
566 IAnjutaIterable *iter, *iter_save;
567 IAnjutaEditorAttribute attribute;
568 gchar *pre_word = NULL, *scope_operator = NULL;
570 //DEBUG_PRINT ("Autocomplete enable is: %d", autocomplete);
571 //DEBUG_PRINT ("Calltips enable is: %d", calltips);
573 if (!autocomplete && !calltips)
574 return FALSE; /* Nothing to do */
576 editor = IANJUTA_EDITOR (assist->priv->iassist);
578 iter = ianjuta_editor_get_position (editor, NULL);
579 ianjuta_iterable_previous (iter, NULL);
580 iter_save = ianjuta_iterable_clone (iter, NULL);
582 attribute = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter),
583 NULL);
585 if (attribute == IANJUTA_EDITOR_COMMENT ||
586 attribute == IANJUTA_EDITOR_STRING);
588 g_object_unref (iter);
589 g_object_unref (iter_save);
590 return FALSE;
594 //DEBUG_PRINT ("assist init: %f", g_timer_elapsed (timer, NULL));
596 if (autocomplete)
598 pre_word = cpp_java_assist_get_pre_word (editor, iter);
599 //DEBUG_PRINT ("assist pre word: %f", g_timer_elapsed (timer, NULL));
601 scope_operator = cpp_java_assist_get_scope_operator (editor, iter);
602 //DEBUG_PRINT ("assist scope operator: %f", g_timer_elapsed (timer, NULL));
604 //DEBUG_PRINT ("Pre word: %s", pre_word);
605 //DEBUG_PRINT ("Scope op: %s", scope_operator);
607 if (scope_operator)
609 gchar *scope_context = NULL;
610 scope_context = cpp_java_assist_get_scope_context (editor,
611 scope_operator,
612 iter);
614 DEBUG_PRINT ("Scope context: %s", scope_context);
616 if (scope_context)
618 if (!assist->priv->scope_context_cache ||
619 strcmp (scope_context,
620 assist->priv->scope_context_cache) != 0)
622 cpp_java_assist_create_scope_completion_cache (assist,
623 scope_operator,
624 scope_context);
626 shown = cpp_java_assist_show_autocomplete (assist, pre_word);
628 g_free (scope_context);
630 else if (pre_word && strlen (pre_word) > 3)
632 if (!assist->priv->search_cache ||
633 strncmp (assist->priv->search_cache,
634 pre_word, strlen (assist->priv->search_cache)) != 0)
636 cpp_java_assist_create_word_completion_cache (assist, pre_word);
638 shown = cpp_java_assist_show_autocomplete (assist, pre_word);
640 if (!shown)
642 ianjuta_editor_assist_hide_suggestions (assist->priv->iassist,
643 NULL);
645 //DEBUG_PRINT ("assist autocomplete: %f", g_timer_elapsed (timer, NULL));
647 if (calltips)
649 if (!shown)
651 gint offset;
652 gchar *call_context =
653 cpp_java_assist_get_calltip_context (assist, iter, &offset);
654 //DEBUG_PRINT ("get calltip context: %f", g_timer_elapsed (timer, NULL));
655 if (call_context)
657 shown = cpp_java_assist_show_calltip (assist, call_context,
658 offset, iter_save);
660 else
662 ianjuta_editor_assist_cancel_tips (assist->priv->iassist, NULL);
664 g_free (call_context);
666 //DEBUG_PRINT ("assist calltip: %f", g_timer_elapsed (timer, NULL));
668 g_object_unref (iter);
669 g_object_unref (iter_save);
670 g_free (pre_word);
671 g_free (scope_operator);
672 return shown;
675 static void
676 on_editor_char_added (IAnjutaEditor *editor, IAnjutaIterable *insert_pos,
677 gchar ch, CppJavaAssist *assist)
679 gboolean enable_complete =
680 anjuta_preferences_get_int_with_default (assist->priv->preferences,
681 PREF_AUTOCOMPLETE_ENABLE,
682 TRUE);
684 gboolean enable_calltips =
685 anjuta_preferences_get_int_with_default (assist->priv->preferences,
686 PREF_CALLTIP_ENABLE,
687 TRUE);
688 cpp_java_assist_check (assist, enable_complete, enable_calltips);
691 static void
692 on_assist_chosen (IAnjutaEditorAssist* iassist, gint selection,
693 CppJavaAssist* assist)
695 CppJavaAssistTag *tag;
696 IAnjutaIterable *cur_pos;
697 GString *assistance;
698 IAnjutaEditor *te;
699 IAnjutaIterable *iter;
700 gchar *pre_word = NULL;
701 gboolean add_space_after_func = FALSE;
702 gboolean add_brace_after_func = FALSE;
704 //DEBUG_PRINT ("assist-chosen: %d", selection);
706 if (assist->priv->completion_cache->cache)
707 tag = g_list_nth_data (assist->priv->completion_cache->cache,
708 selection);
709 else
710 tag = g_list_nth_data (assist->priv->completion_cache->items,
711 selection);
713 assistance = g_string_new (tag->name);
715 if (tag->is_func)
717 add_space_after_func =
718 anjuta_preferences_get_int_with_default (assist->priv->preferences,
719 PREF_AUTOCOMPLETE_SPACE_AFTER_FUNC,
720 TRUE);
721 add_brace_after_func =
722 anjuta_preferences_get_int_with_default (assist->priv->preferences,
723 PREF_AUTOCOMPLETE_BRACE_AFTER_FUNC,
724 TRUE);
725 if (add_space_after_func)
726 g_string_append (assistance, " ");
728 if (add_brace_after_func)
729 g_string_append (assistance, "(");
732 te = IANJUTA_EDITOR (assist->priv->iassist);
733 cur_pos = ianjuta_editor_get_position (te, NULL);
734 iter = ianjuta_iterable_clone (cur_pos, NULL);
736 if (ianjuta_iterable_previous (iter, NULL))
738 pre_word = cpp_java_assist_get_pre_word (te, iter);
741 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (te), NULL);
742 if (pre_word)
744 ianjuta_iterable_next (iter, NULL);
745 ianjuta_editor_selection_set (IANJUTA_EDITOR_SELECTION (te),
746 iter, cur_pos, NULL);
747 ianjuta_editor_selection_replace (IANJUTA_EDITOR_SELECTION (te),
748 assistance->str, -1, NULL);
749 g_free (pre_word);
751 else
753 ianjuta_editor_insert (te, cur_pos, assistance->str, -1, NULL);
755 g_object_unref (iter);
756 g_object_unref (cur_pos);
758 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (te), NULL);
760 ianjuta_editor_assist_hide_suggestions (assist->priv->iassist, NULL);
762 /* Show calltip if we completed function */
763 if (add_brace_after_func)
764 cpp_java_assist_check (assist, FALSE, TRUE);
766 g_string_free (assistance, TRUE);
769 static void
770 cpp_java_assist_install (CppJavaAssist *assist, IAnjutaEditorAssist *iassist)
772 g_return_if_fail (assist->priv->iassist == NULL);
774 assist->priv->iassist = iassist;
775 g_signal_connect (iassist, "char-added",
776 G_CALLBACK (on_editor_char_added), assist);
777 g_signal_connect (iassist, "assist-chosen",
778 G_CALLBACK(on_assist_chosen), assist);
781 static void
782 cpp_java_assist_uninstall (CppJavaAssist *assist)
784 g_return_if_fail (assist->priv->iassist != NULL);
785 g_signal_handlers_disconnect_by_func (assist->priv->iassist,
786 G_CALLBACK(on_assist_chosen), assist);
787 g_signal_handlers_disconnect_by_func (assist->priv->iassist,
788 G_CALLBACK (on_editor_char_added),
789 assist);
790 assist->priv->iassist = NULL;
793 static void
794 cpp_java_assist_init (CppJavaAssist *assist)
796 assist->priv = g_new0 (CppJavaAssistPriv, 1);
799 static void
800 cpp_java_assist_finalize (GObject *object)
802 CppJavaAssist *assist = CPP_JAVA_ASSIST (object);
803 cpp_java_assist_uninstall (assist);
804 cpp_java_assist_destroy_completion_cache (assist);
805 g_free (assist->priv);
806 G_OBJECT_CLASS (cpp_java_assist_parent_class)->finalize (object);
809 static void
810 cpp_java_assist_class_init (CppJavaAssistClass *klass)
812 GObjectClass* object_class = G_OBJECT_CLASS (klass);
814 object_class->finalize = cpp_java_assist_finalize;
817 CppJavaAssist *
818 cpp_java_assist_new (IAnjutaEditorAssist *iassist,
819 IAnjutaSymbolManager *isymbol_manager,
820 AnjutaPreferences *prefs)
822 CppJavaAssist *assist = g_object_new (TYPE_CPP_JAVA_ASSIST, NULL);
823 assist->priv->isymbol_manager = isymbol_manager;
824 assist->priv->preferences = prefs;
825 cpp_java_assist_install (assist, iassist);
826 return assist;