anjuta: Fixed a memory leak
[anjuta.git] / plugins / language-support-cpp-java / cpp-java-assist.c
blob967402fff4bf9038ca3da1f8e0f8b71dea07b0cd
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 "cxxparser/engine-parser.h"
28 #include <ctype.h>
29 #include <string.h>
30 #include <libanjuta/anjuta-debug.h>
31 #include <libanjuta/interfaces/ianjuta-file.h>
32 #include <libanjuta/interfaces/ianjuta-editor-cell.h>
33 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
34 #include <libanjuta/interfaces/ianjuta-editor-assist.h>
35 #include <libanjuta/interfaces/ianjuta-editor-tip.h>
36 #include <libanjuta/interfaces/ianjuta-provider.h>
37 #include <libanjuta/interfaces/ianjuta-document.h>
38 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
39 #include "cpp-java-assist.h"
40 #include "cpp-java-utils.h"
42 #define PREF_AUTOCOMPLETE_ENABLE "cpp-completion-enable"
43 #define PREF_AUTOCOMPLETE_SPACE_AFTER_FUNC "cpp-completion-space-after-func"
44 #define PREF_AUTOCOMPLETE_BRACE_AFTER_FUNC "cpp-completion-brace-after-func"
45 #define PREF_CALLTIP_ENABLE "cpp-calltip-enable"
46 #define BRACE_SEARCH_LIMIT 500
48 static void cpp_java_assist_iface_init(IAnjutaProviderIface* iface);
50 G_DEFINE_TYPE_WITH_CODE (CppJavaAssist,
51 cpp_java_assist,
52 G_TYPE_OBJECT,
53 G_IMPLEMENT_INTERFACE (IANJUTA_TYPE_PROVIDER,
54 cpp_java_assist_iface_init))
56 typedef struct
58 gchar *name;
59 gboolean is_func;
60 GdkPixbuf* icon;
61 IAnjutaSymbolType type;
62 } CppJavaAssistTag;
64 struct _CppJavaAssistPriv {
65 GSettings* settings;
66 IAnjutaEditorAssist* iassist;
67 IAnjutaEditorTip* itip;
69 GCompletion *completion_cache;
71 /* Calltips */
72 gboolean calltip_active;
73 gchar* calltip_context;
74 GList* tips;
75 IAnjutaIterable* calltip_iter;
77 gint async_calltip_file;
78 gint async_calltip_system;
79 gint async_calltip_project;
81 IAnjutaSymbolQuery *calltip_query_file;
82 IAnjutaSymbolQuery *calltip_query_system;
83 IAnjutaSymbolQuery *calltip_query_project;
85 /* Autocompletion */
86 gboolean member_completion;
87 gboolean autocompletion;
88 IAnjutaIterable* start_iter;
89 gchar* pre_word;
91 gint async_file_id;
92 gint async_system_id;
93 gint async_project_id;
95 IAnjutaSymbolQuery *ac_query_file;
96 IAnjutaSymbolQuery *ac_query_system;
97 IAnjutaSymbolQuery *ac_query_project;
99 /* Member autocompletion */
100 IAnjutaSymbolQuery *query_members;
103 typedef struct
105 gboolean is_func;
106 gchar* name;
107 } ProposalData;
110 * cpp_java_assist_proposal_new:
111 * @symbol: IAnjutaSymbol to create the proposal for
113 * Creates a new IAnjutaEditorAssistProposal for symbol
115 * Returns: a newly allocated IAnjutaEditorAssistProposal
117 static IAnjutaEditorAssistProposal*
118 cpp_java_assist_proposal_new (IAnjutaSymbol* symbol)
120 IAnjutaEditorAssistProposal* proposal = g_new0 (IAnjutaEditorAssistProposal, 1);
121 IAnjutaSymbolType type = ianjuta_symbol_get_sym_type (symbol, NULL);
122 ProposalData* data = g_new0 (ProposalData, 1);
124 data->name = g_strdup (ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_NAME, NULL));
125 switch (type)
127 case IANJUTA_SYMBOL_TYPE_PROTOTYPE:
128 case IANJUTA_SYMBOL_TYPE_FUNCTION:
129 case IANJUTA_SYMBOL_TYPE_METHOD:
130 case IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG:
131 proposal->label = g_strdup_printf ("%s()", data->name);
132 data->is_func = TRUE;
133 break;
134 default:
135 proposal->label = g_strdup (data->name);
136 data->is_func = FALSE;
138 proposal->data = data;
139 /* Icons are lifetime object of the symbol-db so we can cast here */
140 proposal->icon = (GdkPixbuf*) ianjuta_symbol_get_icon (symbol, NULL);
141 return proposal;
145 * cpp_java_assist_proposal_free:
146 * @proposal: the proposal to free
148 * Frees the proposal
150 static void
151 cpp_java_assist_proposal_free (IAnjutaEditorAssistProposal* proposal)
153 ProposalData* data = proposal->data;
154 g_free (data->name);
155 g_free (data);
156 g_free (proposal->label);
157 g_free (proposal);
161 * anjuta_propsal_completion_func:
162 * @data: an IAnjutaEditorAssistProposal
164 * Returns: the name of the completion func
166 static gchar*
167 anjuta_proposal_completion_func (gpointer data)
169 IAnjutaEditorAssistProposal* proposal = data;
170 ProposalData* prop_data = proposal->data;
172 return prop_data->name;
176 * cpp_java_assist_create_completion_from_symbols:
177 * @symbols: Symbol iteration
179 * Create a list of IAnjutaEditorAssistProposals from a list of symbols
181 * Returns: a newly allocated GList of newly allocated proposals. Free
182 * with cpp_java_assist_proposal_free()
184 static GList*
185 cpp_java_assist_create_completion_from_symbols (IAnjutaIterable* symbols)
187 GList* list = NULL;
189 if (!symbols)
190 return NULL;
193 IAnjutaSymbol* symbol = IANJUTA_SYMBOL (symbols);
194 IAnjutaEditorAssistProposal* proposal = cpp_java_assist_proposal_new (symbol);
196 list = g_list_append (list, proposal);
198 while (ianjuta_iterable_next (symbols, NULL));
200 return list;
204 * cpp_java_assist_is_word_character:
205 * @ch: character to check
207 * Returns: TRUE if ch is a valid word character, FALSE otherwise
210 static gboolean
211 cpp_java_assist_is_word_character (gchar ch)
213 if (g_ascii_isspace (ch))
214 return FALSE;
215 if (g_ascii_isalnum (ch))
216 return TRUE;
217 if (ch == '_')
218 return TRUE;
220 return FALSE;
224 * cpp_java_assist_get_pre_word:
225 * @editor: Editor object
226 * @iter: current cursor position
227 * @start_iter: return location for the start_iter (if a preword was found)
229 * Search for the current typed word
231 * Returns: The current word (needs to be freed) or NULL if no word was found
233 static gchar*
234 cpp_java_assist_get_pre_word (IAnjutaEditor* editor, IAnjutaIterable *iter, IAnjutaIterable** start_iter)
236 IAnjutaIterable *end = ianjuta_iterable_clone (iter, NULL);
237 IAnjutaIterable *begin = ianjuta_iterable_clone (iter, NULL);
238 gchar ch, *preword_chars = NULL;
239 gboolean out_of_range = FALSE;
240 gboolean preword_found = FALSE;
242 /* Cursor points after the current characters, move back */
243 ianjuta_iterable_previous (begin, NULL);
245 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (begin), 0, NULL);
247 while (ch && cpp_java_assist_is_word_character (ch))
249 preword_found = TRUE;
250 if (!ianjuta_iterable_previous (begin, NULL))
252 out_of_range = TRUE;
253 break;
255 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (begin), 0, NULL);
258 if (preword_found)
260 if (!out_of_range)
261 ianjuta_iterable_next (begin, NULL);
262 preword_chars = ianjuta_editor_get_text (editor, begin, end, NULL);
263 *start_iter = begin;
265 else
267 g_object_unref (begin);
268 *start_iter = NULL;
271 g_object_unref (end);
272 return preword_chars;
276 * cpp_java_assist_update_pre_word:
277 * @assist: self
278 * @pre_word: new pre_word
280 * Updates the current pre_word
282 static void
283 cpp_java_assist_update_pre_word (CppJavaAssist* assist, const gchar* pre_word)
285 g_free (assist->priv->pre_word);
286 if (pre_word == NULL) pre_word = "";
287 assist->priv->pre_word = g_strdup (pre_word);
291 * cpp_java_assist_is_expression_separator:
292 * @c: character to check
293 * @skip_braces: whether to skip closing braces
294 * @iter: current cursor position
296 * Checks if a character seperates a C/C++ expression. It can skip brances
297 * because they might not really end the expression
299 * Returns: TRUE if the characters seperates an expression, FALSE otherwise
301 static gboolean
302 cpp_java_assist_is_expression_separator (gchar c, gboolean skip_braces, IAnjutaIterable* iter)
304 IAnjutaEditorAttribute attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL(iter),
305 NULL);
306 int i;
307 const gchar separators[] = {',', ';', '\n', '\r', '\t', '(',
308 '{', '}', '=', '<', '\v', '!',
309 '&', '%', '*', '[', ']', '?', '/',
310 '+', 0};
312 if (attrib == IANJUTA_EDITOR_STRING ||
313 attrib == IANJUTA_EDITOR_COMMENT)
315 return FALSE;
318 if (c == ')' && skip_braces)
320 cpp_java_util_jump_to_matching_brace (iter, c, BRACE_SEARCH_LIMIT);
321 return TRUE;
323 else if (c == ')' && !skip_braces)
324 return FALSE;
326 for (i = 0; separators[i] != 0; i++)
328 if (separators[i] == c)
329 return TRUE;
332 return FALSE;
336 * cpp_java_assist_parse_expression:
337 * @assist: self,
338 * @iter: current cursor position
339 * @start_iter: return location for the start of the completion
341 * Returns: An iter of a list of IAnjutaSymbols or NULL
343 static IAnjutaIterable*
344 cpp_java_assist_parse_expression (CppJavaAssist* assist, IAnjutaIterable* iter, IAnjutaIterable** start_iter)
346 IAnjutaEditor* editor = IANJUTA_EDITOR (assist->priv->iassist);
347 IAnjutaIterable* res = NULL;
348 IAnjutaIterable* cur_pos = ianjuta_iterable_clone (iter, NULL);
349 gboolean op_start = FALSE;
350 gboolean ref_start = FALSE;
351 gchar* stmt = NULL;
353 /* Cursor points after the current characters, move back */
354 ianjuta_iterable_previous (cur_pos, NULL);
356 /* Search for a operator in the current line */
359 gchar ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL(cur_pos), 0, NULL);
361 if (cpp_java_assist_is_expression_separator(ch, FALSE, iter)) {
362 break;
365 if (ch == '.' || (op_start && ch == '-') || (ref_start && ch == ':'))
367 /* Found an operator, get the statement and the pre_word */
368 IAnjutaIterable* pre_word_start = ianjuta_iterable_clone (cur_pos, NULL);
369 IAnjutaIterable* pre_word_end = ianjuta_iterable_clone (iter, NULL);
370 IAnjutaIterable* stmt_end = ianjuta_iterable_clone (pre_word_start, NULL);
373 /* we need to pass to the parser all the statement included the last operator,
374 * being it "." or "->" or "::"
375 * Increase the end bound of the statement.
377 ianjuta_iterable_next (stmt_end, NULL);
378 if (op_start == TRUE || ref_start == TRUE)
379 ianjuta_iterable_next (stmt_end, NULL);
382 /* Move one character forward so we have the start of the pre_word and
383 * not the last operator */
384 ianjuta_iterable_next (pre_word_start, NULL);
385 /* If this is a two character operator, skip the second character */
386 if (op_start)
388 ianjuta_iterable_next (pre_word_start, NULL);
391 cpp_java_assist_update_pre_word (assist,
392 ianjuta_editor_get_text (editor,
393 pre_word_start, pre_word_end, NULL));
395 /* Try to get the name of the variable */
396 while (ianjuta_iterable_previous (cur_pos, NULL))
398 gchar word_ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL(cur_pos), 0, NULL);
400 if (cpp_java_assist_is_expression_separator(word_ch, FALSE, cur_pos))
401 break;
403 ianjuta_iterable_next (cur_pos, NULL);
404 stmt = ianjuta_editor_get_text (editor,
405 cur_pos, stmt_end, NULL);
406 *start_iter = pre_word_start;
407 g_object_unref (stmt_end);
408 g_object_unref (pre_word_end);
409 break;
411 else if (ch == '>')
412 op_start = TRUE;
413 else if (ch == ':')
414 ref_start = TRUE;
415 else
417 op_start = FALSE;
418 ref_start = FALSE;
421 while (ianjuta_iterable_previous (cur_pos, NULL));
423 if (stmt)
425 gint lineno;
426 gchar *filename = NULL;
427 gchar *above_text;
428 IAnjutaIterable* start;
430 if (IANJUTA_IS_FILE (assist->priv->iassist))
432 GFile *file = ianjuta_file_get_file (IANJUTA_FILE (assist->priv->iassist), NULL);
433 if (file != NULL)
435 filename = g_file_get_path (file);
436 g_object_unref (file);
438 else
440 g_free (stmt);
441 return NULL;
444 start = ianjuta_editor_get_start_position (editor, NULL);
445 above_text = ianjuta_editor_get_text (editor, start, iter, NULL);
446 g_object_unref (start);
448 lineno = ianjuta_editor_get_lineno (editor, NULL);
450 /* the parser works even for the "Gtk::" like expressions, so it shouldn't be
451 * created a specific case to handle this.
453 res = engine_parser_process_expression (stmt,
454 above_text,
455 filename,
456 lineno);
457 g_free (filename);
458 g_free (stmt);
460 g_object_unref (cur_pos);
461 return res;
464 /**
465 * cpp_java_assist_create_completion_cache:
466 * @assist: self
468 * Create a new completion_cache object
470 static void
471 cpp_java_assist_create_completion_cache (CppJavaAssist* assist)
473 g_assert (assist->priv->completion_cache == NULL);
474 assist->priv->completion_cache =
475 g_completion_new (anjuta_proposal_completion_func);
479 * cpp_java_assist_cancel_queries:
480 * @assist: self
482 * Abort all async operations
484 static void
485 cpp_java_assist_cancel_queries (CppJavaAssist* assist)
487 ianjuta_symbol_query_cancel (assist->priv->ac_query_file, NULL);
488 ianjuta_symbol_query_cancel (assist->priv->ac_query_project, NULL);
489 ianjuta_symbol_query_cancel (assist->priv->ac_query_system, NULL);
490 assist->priv->async_file_id = 0;
491 assist->priv->async_project_id = 0;
492 assist->priv->async_system_id = 0;
496 * cpp_java_assist_clear_completion_cache:
497 * @assist: self
499 * Clear the completion cache, aborting all async operations
501 static void
502 cpp_java_assist_clear_completion_cache (CppJavaAssist* assist)
504 cpp_java_assist_cancel_queries (assist);
505 if (assist->priv->completion_cache)
507 g_list_foreach (assist->priv->completion_cache->items, (GFunc) cpp_java_assist_proposal_free, NULL);
508 g_completion_free (assist->priv->completion_cache);
510 assist->priv->completion_cache = NULL;
511 assist->priv->member_completion = FALSE;
512 assist->priv->autocompletion = FALSE;
516 * cpp_java_assist_populate_real:
517 * @assist: self
518 * @finished: TRUE if no more proposals are expected, FALSE otherwise
520 * Really invokes the completion interfaces and adds completions. Might be called
521 * from an async context
523 static void
524 cpp_java_assist_populate_real (CppJavaAssist* assist, gboolean finished)
526 g_assert (assist->priv->pre_word != NULL);
527 gchar* prefix;
528 GList* proposals = g_completion_complete (assist->priv->completion_cache,
529 assist->priv->pre_word,
530 &prefix);
531 if (g_list_length (proposals) == 1)
533 IAnjutaEditorAssistProposal* proposal = proposals->data;
534 ProposalData* data = proposal->data;
535 if (g_str_equal (assist->priv->pre_word, data->name))
537 ianjuta_editor_assist_proposals (assist->priv->iassist,
538 IANJUTA_PROVIDER(assist),
539 NULL, finished, NULL);
540 return;
544 ianjuta_editor_assist_proposals (assist->priv->iassist,
545 IANJUTA_PROVIDER(assist),
546 proposals, finished, NULL);
550 * cpp_java_assist_create_member_completion_cache
551 * @assist: self
552 * @cursor: Current cursor position
554 * Create the completion_cache for member completion if possible
556 * Returns: TRUE if a completion cache was build, FALSE otherwise
558 static gboolean
559 cpp_java_assist_create_member_completion_cache (CppJavaAssist* assist, IAnjutaIterable* cursor)
561 IAnjutaIterable* symbol = NULL;
562 IAnjutaIterable* start_iter = NULL;
563 symbol = cpp_java_assist_parse_expression (assist, cursor, &start_iter);
565 if (symbol)
567 gint retval = FALSE;
568 /* Query symbol children */
569 IAnjutaIterable *children =
570 ianjuta_symbol_query_search_members (assist->priv->query_members,
571 IANJUTA_SYMBOL(symbol),
572 NULL);
573 if (children)
575 GList* proposals =
576 cpp_java_assist_create_completion_from_symbols (children);
577 cpp_java_assist_create_completion_cache (assist);
578 g_completion_add_items (assist->priv->completion_cache, proposals);
580 assist->priv->start_iter = start_iter;
582 cpp_java_assist_populate_real (assist, TRUE);
583 g_list_free (proposals);
584 g_object_unref (children);
585 retval = TRUE;
587 g_object_unref (symbol);
588 return retval;
590 else if (start_iter)
591 g_object_unref (start_iter);
592 return FALSE;
596 * on_symbol_search_complete:
597 * @search_id: id of this search
598 * @symbols: the returned symbols
599 * @assist: self
601 * Called by the async search method when it found symbols
603 static void
604 on_symbol_search_complete (IAnjutaSymbolQuery *query, IAnjutaIterable* symbols,
605 CppJavaAssist* assist)
607 GList* proposals;
608 proposals = cpp_java_assist_create_completion_from_symbols (symbols);
610 if (query == assist->priv->ac_query_file)
611 assist->priv->async_file_id = 0;
612 else if (query == assist->priv->ac_query_project)
613 assist->priv->async_project_id = 0;
614 else if (query == assist->priv->ac_query_system)
615 assist->priv->async_system_id = 0;
616 else
617 g_assert_not_reached ();
619 g_completion_add_items (assist->priv->completion_cache, proposals);
620 gboolean running = assist->priv->async_system_id || assist->priv->async_file_id ||
621 assist->priv->async_project_id;
622 if (!running)
623 cpp_java_assist_populate_real (assist, TRUE);
624 g_list_free (proposals);
628 * cpp_java_assist_create_autocompletion_cache:
629 * @assist: self
630 * @cursor: Current cursor position
632 * Create completion cache for autocompletion. This is done async.
634 * Returns: TRUE if a preword was detected, FALSE otherwise
636 static gboolean
637 cpp_java_assist_create_autocompletion_cache (CppJavaAssist* assist, IAnjutaIterable* cursor)
639 IAnjutaIterable* start_iter;
640 gchar* pre_word =
641 cpp_java_assist_get_pre_word (IANJUTA_EDITOR (assist->priv->iassist), cursor, &start_iter);
642 if (!pre_word || strlen (pre_word) <= 3)
644 if (start_iter)
645 g_object_unref (start_iter);
646 return FALSE;
648 else
650 gchar *pattern = g_strconcat (pre_word, "%", NULL);
652 cpp_java_assist_create_completion_cache (assist);
653 cpp_java_assist_update_pre_word (assist, pre_word);
655 if (IANJUTA_IS_FILE (assist->priv->iassist))
657 GFile *file = ianjuta_file_get_file (IANJUTA_FILE (assist->priv->iassist), NULL);
658 if (file != NULL)
660 assist->priv->async_file_id = 1;
661 ianjuta_symbol_query_search_file (assist->priv->ac_query_file,
662 pattern, file, NULL);
663 g_object_unref (file);
666 /* This will avoid duplicates of FUNCTION and PROTOTYPE */
667 assist->priv->async_project_id = 1;
668 ianjuta_symbol_query_search (assist->priv->ac_query_project, pattern, NULL);
669 assist->priv->async_system_id = 1;
670 ianjuta_symbol_query_search (assist->priv->ac_query_system, pattern, NULL);
671 g_free (pre_word);
672 g_free (pattern);
674 assist->priv->start_iter = start_iter;
676 return TRUE;
682 * cpp_java_assist_create_calltips:
683 * @iter: List of symbols
684 * @merge: list of calltips to merge or NULL
686 * Create a list of Calltips (string) from a list of symbols
688 * A newly allocated GList* with newly allocated strings
690 static GList*
691 cpp_java_assist_create_calltips (IAnjutaIterable* iter, GList* merge)
693 GList* tips = merge;
694 if (iter)
698 IAnjutaSymbol* symbol = IANJUTA_SYMBOL(iter);
699 const gchar* name = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_NAME, NULL);
700 if (name != NULL)
702 const gchar* args = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_SIGNATURE, NULL);
703 const gchar* rettype = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_RETURNTYPE, NULL);
704 gchar* print_args;
705 gchar* separator;
706 gchar* white_name;
707 gint white_count = 0;
709 if (!rettype)
710 rettype = "";
711 else
712 white_count += strlen(rettype) + 1;
714 white_count += strlen(name) + 1;
716 white_name = g_strnfill (white_count, ' ');
717 separator = g_strjoin (NULL, ", \n", white_name, NULL);
719 gchar** argv;
720 if (!args)
721 args = "()";
723 argv = g_strsplit (args, ",", -1);
724 print_args = g_strjoinv (separator, argv);
726 gchar* tip = g_strdup_printf ("%s %s %s", rettype, name, print_args);
728 if (!g_list_find_custom (tips, tip, (GCompareFunc) strcmp))
729 tips = g_list_append (tips, tip);
731 g_strfreev (argv);
732 g_free (print_args);
733 g_free (separator);
734 g_free (white_name);
736 else
737 break;
739 while (ianjuta_iterable_next (iter, NULL));
741 return tips;
745 * on_calltip_search_complete:
746 * @search_id: id of this search
747 * @symbols: the returned symbols
748 * @assist: self
750 * Called by the async search method when it found calltips
752 static void
753 on_calltip_search_complete (IAnjutaSymbolQuery *query, IAnjutaIterable* symbols,
754 CppJavaAssist* assist)
756 assist->priv->tips = cpp_java_assist_create_calltips (symbols, assist->priv->tips);
757 if (query == assist->priv->calltip_query_file)
758 assist->priv->async_calltip_file = 0;
759 else if (query == assist->priv->calltip_query_project)
760 assist->priv->async_calltip_project = 0;
761 else if (query == assist->priv->calltip_query_system)
762 assist->priv->async_calltip_system = 0;
763 else
764 g_assert_not_reached ();
765 gboolean running = assist->priv->async_calltip_system || assist->priv->async_calltip_file ||
766 assist->priv->async_calltip_project;
768 DEBUG_PRINT ("Calltip search finished with %d items", g_list_length (assist->priv->tips));
770 if (!running && assist->priv->tips)
772 ianjuta_editor_tip_show (IANJUTA_EDITOR_TIP(assist->priv->itip), assist->priv->tips,
773 assist->priv->calltip_iter,
774 NULL);
779 * cpp_java_assist_query_calltip:
780 * @assist: self
781 * @call_context: name of method/function
783 * Starts an async query for the calltip
785 static void
786 cpp_java_assist_query_calltip (CppJavaAssist *assist, const gchar *call_context)
788 CppJavaAssistPriv* priv = assist->priv;
790 /* Search file */
791 if (IANJUTA_IS_FILE (assist->priv->itip))
793 GFile *file = ianjuta_file_get_file (IANJUTA_FILE (priv->itip), NULL);
795 if (file != NULL)
797 priv->async_calltip_file = 1;
798 ianjuta_symbol_query_search_file (assist->priv->calltip_query_file,
799 call_context, file,
800 NULL);
801 g_object_unref (file);
805 /* Search Project */
806 priv->async_calltip_project = 1;
807 ianjuta_symbol_query_search (assist->priv->calltip_query_project,
808 call_context, NULL);
810 /* Search system */
811 assist->priv->async_calltip_system = 1;
812 ianjuta_symbol_query_search (assist->priv->calltip_query_system,
813 call_context, NULL);
817 * cpp_java_assist_is_scope_context_character:
818 * @ch: character to check
820 * Returns: if the current character seperates a scope
822 static gboolean
823 cpp_java_assist_is_scope_context_character (gchar ch)
825 if (g_ascii_isspace (ch))
826 return FALSE;
827 if (g_ascii_isalnum (ch))
828 return TRUE;
829 if (ch == '_' || ch == '.' || ch == ':' || ch == '>' || ch == '-')
830 return TRUE;
832 return FALSE;
835 #define SCOPE_BRACE_JUMP_LIMIT 50
838 * cpp_java_assist_get_scope_context
839 * @editor: current editor
840 * @scope_operator: The scope operator to check for
841 * @iter: Current cursor position
843 * Find the scope context for calltips
845 static gchar*
846 cpp_java_assist_get_scope_context (IAnjutaEditor* editor,
847 const gchar *scope_operator,
848 IAnjutaIterable *iter)
850 IAnjutaIterable* end;
851 gchar ch, *scope_chars = NULL;
852 gboolean out_of_range = FALSE;
853 gboolean scope_chars_found = FALSE;
855 end = ianjuta_iterable_clone (iter, NULL);
856 ianjuta_iterable_next (end, NULL);
858 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
860 while (ch)
862 if (cpp_java_assist_is_scope_context_character (ch))
864 scope_chars_found = TRUE;
866 else if (ch == ')')
868 if (!cpp_java_util_jump_to_matching_brace (iter, ch, SCOPE_BRACE_JUMP_LIMIT))
870 out_of_range = TRUE;
871 break;
874 else
875 break;
876 if (!ianjuta_iterable_previous (iter, NULL))
878 out_of_range = TRUE;
879 break;
881 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
883 if (scope_chars_found)
885 IAnjutaIterable* begin;
886 begin = ianjuta_iterable_clone (iter, NULL);
887 if (!out_of_range)
888 ianjuta_iterable_next (begin, NULL);
889 scope_chars = ianjuta_editor_get_text (editor, begin, end, NULL);
890 g_object_unref (begin);
892 g_object_unref (end);
893 return scope_chars;
897 * cpp_java_assist_create_calltip_context:
898 * @assist: self
899 * @iter: current cursor position
901 * Searches for a calltip context
903 * Returns: name of the method to show a calltip for or NULL
905 static gchar*
906 cpp_java_assist_get_calltip_context (CppJavaAssist *assist,
907 IAnjutaIterable *iter)
909 gchar ch;
910 gchar *context = NULL;
912 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
913 if (ch == ')')
915 if (!cpp_java_util_jump_to_matching_brace (iter, ')', -1))
916 return NULL;
917 if (!ianjuta_iterable_previous (iter, NULL))
918 return NULL;
920 if (ch != '(')
922 if (!cpp_java_util_jump_to_matching_brace (iter, ')',
923 BRACE_SEARCH_LIMIT))
924 return NULL;
927 /* Skip white spaces */
928 while (ianjuta_iterable_previous (iter, NULL)
929 && g_ascii_isspace (ianjuta_editor_cell_get_char
930 (IANJUTA_EDITOR_CELL (iter), 0, NULL)));
932 context = cpp_java_assist_get_scope_context
933 (IANJUTA_EDITOR (assist->priv->itip), "(", iter);
935 /* Point iter to the first character of the scope to align calltip correctly */
936 ianjuta_iterable_next (iter, NULL);
938 return context;
942 * cpp_java_assist_create_calltip_context:
943 * @assist: self
944 * @call_context: The context (method/function name)
945 * @position: iter where to show calltips
947 * Create the calltip context
949 static void
950 cpp_java_assist_create_calltip_context (CppJavaAssist* assist,
951 const gchar* call_context,
952 IAnjutaIterable* position)
954 assist->priv->calltip_context = g_strdup (call_context);
955 assist->priv->calltip_iter = position;
959 * cpp_java_assist_clear_calltip_context:
960 * @assist: self
962 * Clears the calltip context and brings it back into a save state
964 static void
965 cpp_java_assist_clear_calltip_context (CppJavaAssist* assist)
967 ianjuta_symbol_query_cancel (assist->priv->calltip_query_file, NULL);
968 ianjuta_symbol_query_cancel (assist->priv->calltip_query_project, NULL);
969 ianjuta_symbol_query_cancel (assist->priv->calltip_query_system, NULL);
971 assist->priv->async_calltip_file = 0;
972 assist->priv->async_calltip_project = 0;
973 assist->priv->async_calltip_system = 0;
975 g_free (assist->priv->calltip_context);
976 assist->priv->calltip_context = NULL;
978 g_list_foreach (assist->priv->tips, (GFunc) g_free, NULL);
979 g_list_free (assist->priv->tips);
980 assist->priv->tips = NULL;
982 if (assist->priv->calltip_iter)
983 g_object_unref (assist->priv->calltip_iter);
984 assist->priv->calltip_iter = NULL;
988 * cpp_java_assist_calltip:
989 * @assist: self
991 * Creates a calltip if there is something to show a tip for
992 * Calltips are queried async
994 * Returns: TRUE if a calltips was queried, FALSE otherwise
997 static gboolean
998 cpp_java_assist_calltip (CppJavaAssist *assist)
1000 IAnjutaEditor *editor;
1001 IAnjutaIterable *iter;
1003 editor = IANJUTA_EDITOR (assist->priv->itip);
1005 iter = ianjuta_editor_get_position (editor, NULL);
1006 ianjuta_iterable_previous (iter, NULL);
1007 gchar *call_context =
1008 cpp_java_assist_get_calltip_context (assist, iter);
1009 if (call_context)
1011 DEBUG_PRINT ("Searching calltip for: %s", call_context);
1012 if (assist->priv->calltip_context &&
1013 g_str_equal (call_context, assist->priv->calltip_context))
1015 /* Continue tip */
1016 if (assist->priv->tips)
1018 if (!ianjuta_editor_tip_visible (IANJUTA_EDITOR_TIP (editor), NULL))
1020 ianjuta_editor_tip_show (IANJUTA_EDITOR_TIP (editor),
1021 assist->priv->tips,
1022 assist->priv->calltip_iter, NULL);
1025 g_free (call_context);
1026 return TRUE;
1028 else /* New tip */
1030 if (ianjuta_editor_tip_visible (IANJUTA_EDITOR_TIP (editor), NULL))
1031 ianjuta_editor_tip_cancel (IANJUTA_EDITOR_TIP (editor), NULL);
1033 cpp_java_assist_clear_calltip_context (assist);
1034 cpp_java_assist_create_calltip_context (assist, call_context, iter);
1035 cpp_java_assist_query_calltip (assist, call_context);
1036 g_free (call_context);
1037 return TRUE;
1040 else
1042 if (ianjuta_editor_tip_visible (IANJUTA_EDITOR_TIP (editor), NULL))
1043 ianjuta_editor_tip_cancel (IANJUTA_EDITOR_TIP (editor), NULL);
1044 cpp_java_assist_clear_calltip_context (assist);
1047 g_object_unref (iter);
1048 return FALSE;
1052 * cpp_java_assist_cancelled:
1053 * @iassist: IAnjutaEditorAssist that emitted the signal
1054 * @assist: CppJavaAssist object
1056 * Stop any autocompletion queries when the cancelled signal was received
1058 static void
1059 cpp_java_assist_cancelled (IAnjutaEditorAssist* iassist, CppJavaAssist* assist)
1061 cpp_java_assist_cancel_queries (assist);
1065 * cpp_java_assist_none:
1066 * @self: IAnjutaProvider object
1067 * @assist: CppJavaAssist object
1069 * Indicate that there is nothing to autocomplete
1071 static void
1072 cpp_java_assist_none (IAnjutaProvider* self,
1073 CppJavaAssist* assist)
1075 ianjuta_editor_assist_proposals (assist->priv->iassist,
1076 self,
1077 NULL, TRUE, NULL);
1082 * cpp_java_assist_populate:
1083 * @self: IAnjutaProvider object
1084 * @cursor: Iter at current cursor position (after current character)
1085 * @e: Error population
1087 static void
1088 cpp_java_assist_populate (IAnjutaProvider* self, IAnjutaIterable* cursor, GError** e)
1090 CppJavaAssist* assist = CPP_JAVA_ASSIST (self);
1092 /* Check if we actually want autocompletion at all */
1093 if (!g_settings_get_boolean (assist->priv->settings,
1094 PREF_AUTOCOMPLETE_ENABLE))
1096 cpp_java_assist_none (self, assist);
1097 return;
1100 /* Check if this is a valid text region for completion */
1101 IAnjutaEditorAttribute attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL(cursor),
1102 NULL);
1103 if (attrib == IANJUTA_EDITOR_STRING ||
1104 attrib == IANJUTA_EDITOR_COMMENT)
1106 cpp_java_assist_none (self, assist);
1107 return;
1110 /* Check for calltip */
1111 if (assist->priv->itip &&
1112 g_settings_get_boolean (assist->priv->settings,
1113 PREF_CALLTIP_ENABLE))
1115 assist->priv->calltip_active = cpp_java_assist_calltip (assist);
1119 /* Check if completion was in progress */
1120 if (assist->priv->member_completion || assist->priv->autocompletion)
1122 IAnjutaIterable* start_iter = NULL;
1123 g_assert (assist->priv->completion_cache != NULL);
1124 gchar* pre_word = cpp_java_assist_get_pre_word (IANJUTA_EDITOR (assist->priv->iassist), cursor, &start_iter);
1125 if (pre_word && g_str_has_prefix (pre_word, assist->priv->pre_word))
1127 /* Great, we just continue the current completion */
1128 g_object_unref (assist->priv->start_iter);
1129 assist->priv->start_iter = start_iter;
1131 cpp_java_assist_update_pre_word (assist, pre_word);
1132 cpp_java_assist_populate_real (assist, TRUE);
1133 g_free (pre_word);
1134 return;
1136 g_free (pre_word);
1139 cpp_java_assist_clear_completion_cache (assist);
1141 /* Check for member completion */
1142 if (cpp_java_assist_create_member_completion_cache (assist, cursor))
1144 assist->priv->member_completion = TRUE;
1145 return;
1147 else if (cpp_java_assist_create_autocompletion_cache (assist, cursor))
1149 assist->priv->autocompletion = TRUE;
1150 return;
1152 /* Nothing to propose */
1153 if (assist->priv->start_iter)
1155 g_object_unref (assist->priv->start_iter);
1156 assist->priv->start_iter = NULL;
1158 cpp_java_assist_none (self, assist);
1162 * cpp_java_assist_find_next_brace:
1163 * @self: CppJavaAssist object
1164 * @iter: Iter to start searching at
1166 * Returns: TRUE if the next non-whitespace character is a opening brace,
1167 * FALSE otherwise
1169 static gboolean
1170 cpp_java_assist_find_next_brace (CppJavaAssist* assist,
1171 IAnjutaIterable* iter)
1173 IAnjutaIterable* my_iter = ianjuta_iterable_clone (iter, NULL);
1174 char ch;
1177 ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (my_iter), 0, NULL);
1178 if (ch == '(')
1180 g_object_unref (my_iter);
1181 return TRUE;
1184 while (g_ascii_isspace (ch) && ianjuta_iterable_next (my_iter, NULL));
1186 return FALSE;
1190 * cpp_java_assist_activate:
1191 * @self: IAnjutaProvider object
1192 * @iter: cursor position when proposal was activated
1193 * @data: Data assigned to the completion object
1194 * @e: Error population
1196 * Called from the provider when the user activated a proposal
1198 static void
1199 cpp_java_assist_activate (IAnjutaProvider* self, IAnjutaIterable* iter, gpointer data, GError** e)
1201 CppJavaAssist* assist = CPP_JAVA_ASSIST(self);
1202 ProposalData *prop_data = data;
1203 GString *assistance;
1204 IAnjutaEditor *te;
1205 gboolean add_space_after_func = FALSE;
1206 gboolean add_brace_after_func = FALSE;
1208 g_return_if_fail (prop_data != NULL);
1210 assistance = g_string_new (prop_data->name);
1212 if (prop_data->is_func)
1214 add_space_after_func =
1215 g_settings_get_boolean (assist->priv->settings,
1216 PREF_AUTOCOMPLETE_SPACE_AFTER_FUNC);
1217 add_brace_after_func =
1218 g_settings_get_boolean (assist->priv->settings,
1219 PREF_AUTOCOMPLETE_BRACE_AFTER_FUNC);
1221 if (!cpp_java_assist_find_next_brace (assist, iter))
1223 if (add_space_after_func)
1224 g_string_append (assistance, " ");
1225 if (add_brace_after_func)
1226 g_string_append (assistance, "(");
1230 te = IANJUTA_EDITOR (assist->priv->iassist);
1232 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (te), NULL);
1234 if (ianjuta_iterable_compare(iter, assist->priv->start_iter, NULL) != 0)
1236 ianjuta_editor_selection_set (IANJUTA_EDITOR_SELECTION (te),
1237 assist->priv->start_iter, iter, FALSE, NULL);
1238 ianjuta_editor_selection_replace (IANJUTA_EDITOR_SELECTION (te),
1239 assistance->str, -1, NULL);
1241 else
1243 ianjuta_editor_insert (te, iter, assistance->str, -1, NULL);
1245 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (te), NULL);
1247 /* Show calltip if we completed function */
1248 if (add_brace_after_func)
1250 /* Check for calltip */
1251 if (assist->priv->itip &&
1252 g_settings_get_boolean (assist->priv->settings,
1253 PREF_CALLTIP_ENABLE))
1254 assist->priv->calltip_active = cpp_java_assist_calltip (assist);
1257 g_string_free (assistance, TRUE);
1261 * cpp_java_assist_get_start_iter:
1262 * @self: IAnjutaProvider object
1263 * @e: Error population
1265 * Returns: the iter where the autocompletion starts
1267 static IAnjutaIterable*
1268 cpp_java_assist_get_start_iter (IAnjutaProvider* provider, GError** e)
1270 CppJavaAssist* assist = CPP_JAVA_ASSIST (provider);
1271 return assist->priv->start_iter;
1275 * cpp_java_assist_get_name:
1276 * @self: IAnjutaProvider object
1277 * @e: Error population
1279 * Returns: the provider name
1281 static const gchar*
1282 cpp_java_assist_get_name (IAnjutaProvider* provider, GError** e)
1284 return _("C/C++");
1288 * cpp_java_assist_install:
1289 * @self: IAnjutaProvider object
1290 * @ieditor: Editor to install support for
1292 * Returns: Registers provider for editor
1294 static void
1295 cpp_java_assist_install (CppJavaAssist *assist, IAnjutaEditor *ieditor)
1297 g_return_if_fail (assist->priv->iassist == NULL);
1299 if (IANJUTA_IS_EDITOR_ASSIST (ieditor))
1301 assist->priv->iassist = IANJUTA_EDITOR_ASSIST (ieditor);
1302 ianjuta_editor_assist_add (IANJUTA_EDITOR_ASSIST (ieditor), IANJUTA_PROVIDER(assist), NULL);
1303 g_signal_connect (ieditor, "cancelled", G_CALLBACK (cpp_java_assist_cancelled), assist);
1305 else
1307 assist->priv->iassist = NULL;
1310 if (IANJUTA_IS_EDITOR_TIP (ieditor))
1312 assist->priv->itip = IANJUTA_EDITOR_TIP (ieditor);
1315 else
1317 assist->priv->itip = NULL;
1322 * cpp_java_assist_uninstall:
1323 * @self: IAnjutaProvider object
1325 * Returns: Unregisters provider
1327 static void
1328 cpp_java_assist_uninstall (CppJavaAssist *assist)
1330 g_return_if_fail (assist->priv->iassist != NULL);
1332 g_signal_handlers_disconnect_by_func (assist->priv->iassist,
1333 cpp_java_assist_cancelled, assist);
1334 ianjuta_editor_assist_remove (assist->priv->iassist, IANJUTA_PROVIDER(assist), NULL);
1335 assist->priv->iassist = NULL;
1338 static void
1339 cpp_java_assist_init (CppJavaAssist *assist)
1341 assist->priv = g_new0 (CppJavaAssistPriv, 1);
1344 static void
1345 cpp_java_assist_finalize (GObject *object)
1347 CppJavaAssist *assist = CPP_JAVA_ASSIST (object);
1348 CppJavaAssistPriv* priv = assist->priv;
1350 cpp_java_assist_uninstall (assist);
1351 cpp_java_assist_clear_completion_cache (assist);
1352 cpp_java_assist_clear_calltip_context (assist);
1355 if (priv->calltip_query_file)
1356 g_object_unref (priv->calltip_query_file);
1357 priv->calltip_query_file = NULL;
1359 if (priv->calltip_query_system)
1360 g_object_unref (priv->calltip_query_system);
1361 priv->calltip_query_system = NULL;
1363 if (priv->calltip_query_project)
1364 g_object_unref (priv->calltip_query_project);
1365 priv->calltip_query_project = NULL;
1367 if (priv->ac_query_file)
1368 g_object_unref (priv->ac_query_file);
1369 priv->ac_query_file = NULL;
1371 if (priv->ac_query_system)
1372 g_object_unref (priv->ac_query_system);
1373 priv->ac_query_system = NULL;
1375 if (priv->ac_query_project)
1376 g_object_unref (priv->ac_query_project);
1377 priv->ac_query_project = NULL;
1379 if (priv->query_members)
1380 g_object_unref (priv->query_members);
1381 priv->query_members = NULL;
1383 engine_parser_deinit ();
1385 g_free (assist->priv);
1386 G_OBJECT_CLASS (cpp_java_assist_parent_class)->finalize (object);
1389 static void
1390 cpp_java_assist_class_init (CppJavaAssistClass *klass)
1392 GObjectClass* object_class = G_OBJECT_CLASS (klass);
1394 object_class->finalize = cpp_java_assist_finalize;
1397 CppJavaAssist *
1398 cpp_java_assist_new (IAnjutaEditor *ieditor,
1399 IAnjutaSymbolManager *isymbol_manager,
1400 GSettings* settings)
1402 CppJavaAssist *assist;
1403 static IAnjutaSymbolField calltip_fields[] = {
1404 IANJUTA_SYMBOL_FIELD_ID,
1405 IANJUTA_SYMBOL_FIELD_NAME,
1406 IANJUTA_SYMBOL_FIELD_RETURNTYPE,
1407 IANJUTA_SYMBOL_FIELD_SIGNATURE
1409 static IAnjutaSymbolField ac_fields[] = {
1410 IANJUTA_SYMBOL_FIELD_ID,
1411 IANJUTA_SYMBOL_FIELD_NAME,
1412 IANJUTA_SYMBOL_FIELD_KIND,
1413 IANJUTA_SYMBOL_FIELD_TYPE,
1414 IANJUTA_SYMBOL_FIELD_ACCESS
1417 if (!IANJUTA_IS_EDITOR_ASSIST (ieditor) && !IANJUTA_IS_EDITOR_TIP (ieditor))
1419 /* No assistance is available with the current editor */
1420 return NULL;
1422 assist = g_object_new (TYPE_CPP_JAVA_ASSIST, NULL);
1423 assist->priv->settings = settings;
1425 /* Create call tip queries */
1426 /* Calltip in file */
1427 assist->priv->calltip_query_file =
1428 ianjuta_symbol_manager_create_query (isymbol_manager,
1429 IANJUTA_SYMBOL_QUERY_SEARCH_FILE,
1430 IANJUTA_SYMBOL_QUERY_DB_PROJECT,
1431 NULL);
1432 ianjuta_symbol_query_set_fields (assist->priv->calltip_query_file,
1433 G_N_ELEMENTS (calltip_fields),
1434 calltip_fields, NULL);
1435 ianjuta_symbol_query_set_filters (assist->priv->calltip_query_file,
1436 IANJUTA_SYMBOL_TYPE_PROTOTYPE |
1437 IANJUTA_SYMBOL_TYPE_FUNCTION |
1438 IANJUTA_SYMBOL_TYPE_METHOD |
1439 IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG,
1440 TRUE, NULL);
1441 ianjuta_symbol_query_set_file_scope (assist->priv->calltip_query_file,
1442 IANJUTA_SYMBOL_QUERY_SEARCH_FS_PRIVATE, NULL);
1443 ianjuta_symbol_query_set_mode (assist->priv->calltip_query_file,
1444 IANJUTA_SYMBOL_QUERY_MODE_ASYNC, NULL);
1445 g_signal_connect (assist->priv->calltip_query_file, "async-result",
1446 G_CALLBACK (on_calltip_search_complete), assist);
1447 /* Calltip in project */
1448 assist->priv->calltip_query_project =
1449 ianjuta_symbol_manager_create_query (isymbol_manager,
1450 IANJUTA_SYMBOL_QUERY_SEARCH,
1451 IANJUTA_SYMBOL_QUERY_DB_PROJECT,
1452 NULL);
1453 ianjuta_symbol_query_set_fields (assist->priv->calltip_query_project,
1454 G_N_ELEMENTS (calltip_fields),
1455 calltip_fields, NULL);
1456 ianjuta_symbol_query_set_filters (assist->priv->calltip_query_project,
1457 IANJUTA_SYMBOL_TYPE_PROTOTYPE |
1458 IANJUTA_SYMBOL_TYPE_METHOD |
1459 IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG,
1460 TRUE, NULL);
1461 ianjuta_symbol_query_set_file_scope (assist->priv->calltip_query_project,
1462 IANJUTA_SYMBOL_QUERY_SEARCH_FS_PUBLIC, NULL);
1463 ianjuta_symbol_query_set_mode (assist->priv->calltip_query_project,
1464 IANJUTA_SYMBOL_QUERY_MODE_ASYNC, NULL);
1465 g_signal_connect (assist->priv->calltip_query_project, "async-result",
1466 G_CALLBACK (on_calltip_search_complete), assist);
1467 /* Calltip in system */
1468 assist->priv->calltip_query_system =
1469 ianjuta_symbol_manager_create_query (isymbol_manager,
1470 IANJUTA_SYMBOL_QUERY_SEARCH,
1471 IANJUTA_SYMBOL_QUERY_DB_SYSTEM,
1472 NULL);
1473 ianjuta_symbol_query_set_fields (assist->priv->calltip_query_system,
1474 G_N_ELEMENTS (calltip_fields),
1475 calltip_fields, NULL);
1476 ianjuta_symbol_query_set_filters (assist->priv->calltip_query_system,
1477 IANJUTA_SYMBOL_TYPE_PROTOTYPE |
1478 IANJUTA_SYMBOL_TYPE_METHOD |
1479 IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG,
1480 TRUE, NULL);
1481 ianjuta_symbol_query_set_file_scope (assist->priv->calltip_query_system,
1482 IANJUTA_SYMBOL_QUERY_SEARCH_FS_PUBLIC, NULL);
1483 ianjuta_symbol_query_set_mode (assist->priv->calltip_query_system,
1484 IANJUTA_SYMBOL_QUERY_MODE_ASYNC, NULL);
1485 g_signal_connect (assist->priv->calltip_query_system, "async-result",
1486 G_CALLBACK (on_calltip_search_complete), assist);
1488 /* Create autocomplete queries */
1489 /* AC in file */
1490 assist->priv->ac_query_file =
1491 ianjuta_symbol_manager_create_query (isymbol_manager,
1492 IANJUTA_SYMBOL_QUERY_SEARCH_FILE,
1493 IANJUTA_SYMBOL_QUERY_DB_PROJECT,
1494 NULL);
1495 ianjuta_symbol_query_set_group_by (assist->priv->ac_query_file,
1496 IANJUTA_SYMBOL_FIELD_NAME, NULL);
1497 ianjuta_symbol_query_set_fields (assist->priv->ac_query_file,
1498 G_N_ELEMENTS (ac_fields),
1499 ac_fields, NULL);
1500 ianjuta_symbol_query_set_file_scope (assist->priv->ac_query_file,
1501 IANJUTA_SYMBOL_QUERY_SEARCH_FS_PRIVATE, NULL);
1502 ianjuta_symbol_query_set_mode (assist->priv->ac_query_file,
1503 IANJUTA_SYMBOL_QUERY_MODE_ASYNC, NULL);
1504 g_signal_connect (assist->priv->ac_query_file, "async-result",
1505 G_CALLBACK (on_symbol_search_complete), assist);
1506 /* AC in project */
1507 assist->priv->ac_query_project =
1508 ianjuta_symbol_manager_create_query (isymbol_manager,
1509 IANJUTA_SYMBOL_QUERY_SEARCH,
1510 IANJUTA_SYMBOL_QUERY_DB_PROJECT,
1511 NULL);
1512 ianjuta_symbol_query_set_group_by (assist->priv->ac_query_project,
1513 IANJUTA_SYMBOL_FIELD_NAME, NULL);
1514 ianjuta_symbol_query_set_fields (assist->priv->ac_query_project,
1515 G_N_ELEMENTS (ac_fields),
1516 ac_fields, NULL);
1517 ianjuta_symbol_query_set_file_scope (assist->priv->ac_query_project,
1518 IANJUTA_SYMBOL_QUERY_SEARCH_FS_PUBLIC, NULL);
1519 ianjuta_symbol_query_set_mode (assist->priv->ac_query_project,
1520 IANJUTA_SYMBOL_QUERY_MODE_ASYNC, NULL);
1521 g_signal_connect (assist->priv->ac_query_project, "async-result",
1522 G_CALLBACK (on_symbol_search_complete), assist);
1523 /* AC in system */
1524 assist->priv->ac_query_system =
1525 ianjuta_symbol_manager_create_query (isymbol_manager,
1526 IANJUTA_SYMBOL_QUERY_SEARCH,
1527 IANJUTA_SYMBOL_QUERY_DB_SYSTEM,
1528 NULL);
1529 ianjuta_symbol_query_set_group_by (assist->priv->ac_query_system,
1530 IANJUTA_SYMBOL_FIELD_NAME, NULL);
1531 ianjuta_symbol_query_set_fields (assist->priv->ac_query_system,
1532 G_N_ELEMENTS (ac_fields),
1533 ac_fields, NULL);
1534 ianjuta_symbol_query_set_file_scope (assist->priv->ac_query_system,
1535 IANJUTA_SYMBOL_QUERY_SEARCH_FS_PUBLIC, NULL);
1536 ianjuta_symbol_query_set_mode (assist->priv->ac_query_system,
1537 IANJUTA_SYMBOL_QUERY_MODE_ASYNC, NULL);
1538 g_signal_connect (assist->priv->ac_query_system, "async-result",
1539 G_CALLBACK (on_symbol_search_complete), assist);
1541 /* Members autocompletion */
1542 assist->priv->query_members =
1543 ianjuta_symbol_manager_create_query (isymbol_manager,
1544 IANJUTA_SYMBOL_QUERY_SEARCH_MEMBERS,
1545 IANJUTA_SYMBOL_QUERY_DB_PROJECT,
1546 NULL);
1547 ianjuta_symbol_query_set_fields (assist->priv->query_members,
1548 G_N_ELEMENTS (ac_fields),
1549 ac_fields, NULL);
1550 /* Install support */
1551 cpp_java_assist_install (assist, ieditor);
1553 engine_parser_init (isymbol_manager);
1555 return assist;
1558 static void cpp_java_assist_iface_init(IAnjutaProviderIface* iface)
1560 iface->populate = cpp_java_assist_populate;
1561 iface->get_start_iter = cpp_java_assist_get_start_iter;
1562 iface->activate = cpp_java_assist_activate;
1563 iface->get_name = cpp_java_assist_get_name;