[anjuta] language-support-cpp-java: Rewrite of cpp-java-assist.c
- From: Johannes Schmid <jhs src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta] language-support-cpp-java: Rewrite of cpp-java-assist.c
- Date: Sat, 6 Mar 2010 09:16:43 +0000 (UTC)
commit 6da6e4ce54845c03780676015c627fc033f829af
Author: Johannes Schmid <jhs gnome org>
Date: Fri Mar 5 21:06:29 2010 +0100
language-support-cpp-java: Rewrite of cpp-java-assist.c
* Take async operation better into account
* Document code (gtk-doc comments)
* Code more solid (g_asserts, etc.)
.../language-support-cpp-java/cpp-java-assist.c | 1285 ++++++++------------
1 files changed, 527 insertions(+), 758 deletions(-)
---
diff --git a/plugins/language-support-cpp-java/cpp-java-assist.c b/plugins/language-support-cpp-java/cpp-java-assist.c
index 0cc1de0..1f6464d 100644
--- a/plugins/language-support-cpp-java/cpp-java-assist.c
+++ b/plugins/language-support-cpp-java/cpp-java-assist.c
@@ -67,17 +67,14 @@ struct _CppJavaAssistPriv {
IAnjutaSymbolManager* isymbol_manager;
IAnjutaEditorAssist* iassist;
IAnjutaEditorTip* itip;
-
- /* Last used cache */
- gchar *search_cache;
- gchar *scope_context_cache;
- gchar *pre_word;
- gchar *calltip_context;
-
+
GCompletion *completion_cache;
- gboolean editor_only;
- IAnjutaIterable* start_iter;
+ gboolean member_completion;
+ gboolean autocompletion;
+ IAnjutaIterable* start_iter;
+ gchar* pre_word;
+
gboolean async_file;
gboolean async_system;
gboolean async_project;
@@ -87,50 +84,112 @@ struct _CppJavaAssistPriv {
GCancellable* cancel_project;
};
-static gchar*
-completion_function (gpointer data)
+typedef struct
{
- CppJavaAssistTag * tag = (CppJavaAssistTag*) data;
- return tag->name;
-}
+ gboolean is_func;
+ gchar* name;
+} ProposalData;
-static gint
-completion_compare (gconstpointer a, gconstpointer b)
-{
- CppJavaAssistTag * tag_a = (CppJavaAssistTag*) a;
- CppJavaAssistTag * tag_b = (CppJavaAssistTag*) b;
- gint cmp;
-
- cmp = strcmp (tag_a->name, tag_b->name);
- if (cmp == 0) cmp = tag_a->type - tag_b->type;
-
- return cmp;
+/**
+ * cpp_java_assist_proposal_new:
+ * @symbol: IAnjutaSymbol to create the proposal for
+ *
+ * Creates a new IAnjutaEditorAssistProposal for symbol
+ *
+ * Returns: a newly allocated IAnjutaEditorAssistProposal
+ */
+static IAnjutaEditorAssistProposal*
+cpp_java_assist_proposal_new (IAnjutaSymbol* symbol)
+{
+ IAnjutaEditorAssistProposal* proposal = g_new0 (IAnjutaEditorAssistProposal, 1);
+ IAnjutaSymbolType type = ianjuta_symbol_get_sym_type (symbol, NULL);
+ ProposalData* data = g_new0 (ProposalData, 1);
+
+ data->name = g_strdup (ianjuta_symbol_get_name (symbol, NULL));
+ switch (type)
+ {
+ case IANJUTA_SYMBOL_TYPE_PROTOTYPE:
+ case IANJUTA_SYMBOL_TYPE_FUNCTION:
+ case IANJUTA_SYMBOL_TYPE_METHOD:
+ case IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG:
+ proposal->label = g_strdup_printf ("%s()", ianjuta_symbol_get_name (symbol, NULL));
+ data->is_func = TRUE;
+ break;
+ default:
+ proposal->label = g_strdup (ianjuta_symbol_get_name (symbol, NULL));
+ data->is_func = FALSE;
+ }
+ proposal->data = data;
+ /* Icons are lifetime object of the symbol-db so we can cast here */
+ proposal->icon = (GdkPixbuf*) ianjuta_symbol_get_icon (symbol, NULL);
+ return proposal;
}
+/**
+ * cpp_java_assist_proposal_free:
+ * @proposal: the proposal to free
+ *
+ * Frees the proposal
+ */
static void
-cpp_java_assist_tag_destroy (CppJavaAssistTag *tag)
+cpp_java_assist_proposal_free (IAnjutaEditorAssistProposal* proposal)
{
- g_free (tag->name);
- if (tag->icon)
- g_object_unref (tag->icon);
- g_free (tag);
+ ProposalData* data = proposal->data;
+ g_free (data->name);
+ g_free (data);
+ g_free (proposal->label);
+ g_free (proposal);
}
-static gboolean
-is_scope_context_character (gchar ch)
+/**
+ * anjuta_propsal_completion_func:
+ * @data: an IAnjutaEditorAssistProposal
+ *
+ * Returns: the name of the completion func
+ */
+static gchar*
+anjuta_proposal_completion_func (gpointer data)
{
- if (g_ascii_isspace (ch))
- return FALSE;
- if (g_ascii_isalnum (ch))
- return TRUE;
- if (ch == '_' || ch == '.' || ch == ':' || ch == '>' || ch == '-')
- return TRUE;
+ IAnjutaEditorAssistProposal* proposal = data;
+ ProposalData* prop_data = proposal->data;
- return FALSE;
-}
+ return prop_data->name;
+}
+
+/**
+ * cpp_java_assist_create_completion_from_symbols:
+ * @symbols: Symbol iteration
+ *
+ * Create a list of IAnjutaEditorAssistProposals from a list of symbols
+ *
+ * Returns: a newly allocated GList of newly allocated proposals. Free
+ * with cpp_java_assist_proposal_free()
+ */
+static GList*
+cpp_java_assist_create_completion_from_symbols (IAnjutaIterable* symbols)
+{
+ GList* list = NULL;
+ do
+ {
+ IAnjutaSymbol* symbol = IANJUTA_SYMBOL (symbols);
+ IAnjutaEditorAssistProposal* proposal = cpp_java_assist_proposal_new (symbol);
+
+ list = g_list_append (list, proposal);
+ }
+ while (ianjuta_iterable_next (symbols, NULL));
+ return list;
+}
+
+/**
+ * cpp_java_assist_is_word_character:
+ * @ch: character to check
+ *
+ * Returns: TRUE if ch is a valid word character, FALSE otherwise
+ */
+
static gboolean
-is_word_character (gchar ch)
+cpp_java_assist_is_word_character (gchar ch)
{
if (g_ascii_isspace (ch))
return FALSE;
@@ -143,600 +202,88 @@ is_word_character (gchar ch)
}
/**
- * If mergeable is NULL than no merge will be made with iter elements, elsewhere
- * mergeable will be returned with iter elements.
+ * cpp_java_assist_get_pre_word:
+ * @editor: Editor object
+ * @iter: current cursor position
+ * @start_iter: return location for the start_iter (if a preword was found)
+ *
+ * Search for the current typed word
+ *
+ * Returns: The current word (needs to be freed) or NULL if no word was found
*/
-static GCompletion*
-create_completion (CppJavaAssist* assist, IAnjutaIterable* iter,
- GCompletion* mergeable)
-{
- GCompletion *completion;
-
- if (mergeable == NULL)
- completion = g_completion_new (completion_function);
- else
- completion = mergeable;
-
- GList* suggestions = NULL;
- do
- {
- const gchar* name = ianjuta_symbol_get_name (IANJUTA_SYMBOL(iter), NULL);
- if (name != NULL)
- {
- CppJavaAssistTag *tag = g_new0 (CppJavaAssistTag, 1);
- const GdkPixbuf* sym_icon;
- tag->name = g_strdup (name);
- tag->type = ianjuta_symbol_get_sym_type (IANJUTA_SYMBOL (iter),
- NULL);
- sym_icon = ianjuta_symbol_get_icon (IANJUTA_SYMBOL(iter), NULL);
- tag->icon = sym_icon ? gdk_pixbuf_copy (sym_icon) : NULL;
- tag->is_func = (tag->type == IANJUTA_SYMBOL_TYPE_PROTOTYPE ||
- tag->type == IANJUTA_SYMBOL_TYPE_FUNCTION ||
- tag->type == IANJUTA_SYMBOL_TYPE_METHOD ||
- tag->type == IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG);
- if (!g_list_find_custom (suggestions, tag, completion_compare))
- suggestions = g_list_prepend (suggestions, tag);
- else
- g_free (tag);
- }
- else
- break;
- }
- while (ianjuta_iterable_next (iter, NULL));
- suggestions = g_list_sort (suggestions, completion_compare);
- g_completion_add_items (completion, suggestions);
- return completion;
-}
-
-static void cpp_java_assist_update_autocomplete(CppJavaAssist* assist);
-
-static void
-on_query_data (gint search_id, IAnjutaIterable* iter, CppJavaAssist* assist)
-{
- assist->priv->completion_cache = create_completion (assist,
- iter,
- assist->priv->completion_cache);
- cpp_java_assist_update_autocomplete(assist);
-}
-
-static void
-system_finished (AnjutaAsyncNotify* notify, CppJavaAssist* assist)
-{
- assist->priv->async_system = FALSE;
-}
-
-static void
-file_finished (AnjutaAsyncNotify* notify, CppJavaAssist* assist)
-{
- assist->priv->async_file = FALSE;
-}
-
-static void
-project_finished (AnjutaAsyncNotify* notify, CppJavaAssist* assist)
-{
- assist->priv->async_project = FALSE;
-}
-
-#define SCOPE_BRACE_JUMP_LIMIT 50
-
-static gchar*
-cpp_java_assist_get_scope_context (IAnjutaEditor* editor,
- const gchar *scope_operator,
- IAnjutaIterable *iter)
-{
- IAnjutaIterable* end;
- gchar ch, *scope_chars = NULL;
- gboolean out_of_range = FALSE;
- gboolean scope_chars_found = FALSE;
-
- end = ianjuta_iterable_clone (iter, NULL);
- ianjuta_iterable_next (end, NULL);
-
- ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
-
- while (ch)
- {
- if (is_scope_context_character (ch))
- {
- scope_chars_found = TRUE;
- }
- else if (ch == ')')
- {
- if (!cpp_java_util_jump_to_matching_brace (iter, ch, SCOPE_BRACE_JUMP_LIMIT))
- {
- out_of_range = TRUE;
- break;
- }
- }
- else
- break;
- if (!ianjuta_iterable_previous (iter, NULL))
- {
- out_of_range = TRUE;
- break;
- }
- ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
- }
- if (scope_chars_found)
- {
- IAnjutaIterable* begin;
- begin = ianjuta_iterable_clone (iter, NULL);
- if (!out_of_range)
- ianjuta_iterable_next (begin, NULL);
- scope_chars = ianjuta_editor_get_text (editor, begin, end, NULL);
- g_object_unref (begin);
- }
- g_object_unref (end);
- return scope_chars;
-}
-
static gchar*
-cpp_java_assist_get_pre_word (IAnjutaEditor* editor, IAnjutaIterable *iter)
+cpp_java_assist_get_pre_word (IAnjutaEditor* editor, IAnjutaIterable *iter, IAnjutaIterable** start_iter)
{
- IAnjutaIterable *end;
+ IAnjutaIterable *end = ianjuta_iterable_clone (iter, NULL);
+ IAnjutaIterable *begin = ianjuta_iterable_clone (iter, NULL);
gchar ch, *preword_chars = NULL;
gboolean out_of_range = FALSE;
gboolean preword_found = FALSE;
- end = ianjuta_iterable_clone (iter, NULL);
- ianjuta_iterable_next (end, NULL);
-
- ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
+ /* Cursor points after the current characters, move back */
+ ianjuta_iterable_previous (begin, NULL);
- while (ch && is_word_character (ch))
+ ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (begin), 0, NULL);
+
+ while (ch && cpp_java_assist_is_word_character (ch))
{
preword_found = TRUE;
- if (!ianjuta_iterable_previous (iter, NULL))
+ if (!ianjuta_iterable_previous (begin, NULL))
{
out_of_range = TRUE;
break;
}
- ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
+ ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (begin), 0, NULL);
}
if (preword_found)
{
- IAnjutaIterable *begin = ianjuta_iterable_clone (iter, NULL);
if (!out_of_range)
ianjuta_iterable_next (begin, NULL);
preword_chars = ianjuta_editor_get_text (editor, begin, end, NULL);
- g_object_unref (begin);
- }
- g_object_unref (end);
- return preword_chars;
-}
-
-static void
-cpp_java_assist_destroy_completion_cache (CppJavaAssist *assist)
-{
- if (assist->priv->async_file)
- {
- g_cancellable_cancel (assist->priv->cancel_file);
- assist->priv->async_file = FALSE;
- }
- g_cancellable_reset (assist->priv->cancel_file);
-
- if (assist->priv->async_system)
- {
- g_cancellable_cancel (assist->priv->cancel_system);
- assist->priv->async_system = FALSE;
- }
- g_cancellable_reset (assist->priv->cancel_system);
-
- if (assist->priv->async_project)
- {
- g_cancellable_cancel (assist->priv->cancel_project);
- assist->priv->async_project = FALSE;
- }
- g_cancellable_reset (assist->priv->cancel_project);
-
- if (assist->priv->search_cache)
- {
- g_free (assist->priv->search_cache);
- assist->priv->search_cache = NULL;
- }
- if (assist->priv->scope_context_cache)
- {
- g_free (assist->priv->scope_context_cache);
- assist->priv->scope_context_cache = NULL;
- }
- if (assist->priv->completion_cache)
- {
- GList* items = assist->priv->completion_cache->items;
- if (items)
- {
- g_list_foreach (items, (GFunc) cpp_java_assist_tag_destroy, NULL);
- g_completion_clear_items (assist->priv->completion_cache);
- }
- g_completion_free (assist->priv->completion_cache);
- assist->priv->completion_cache = NULL;
- }
-}
-
-static void free_proposal (IAnjutaEditorAssistProposal* proposal)
-{
- g_free (proposal->label);
- g_free(proposal);
-}
-
-static void
-cpp_java_assist_update_autocomplete (CppJavaAssist *assist)
-{
- gint length;
- GList *completion_list;
- GList *node, *suggestions = NULL;
-
- gboolean queries_active = (assist->priv->async_file || assist->priv->async_project || assist->priv->async_system);
-
- if (assist->priv->completion_cache == NULL)
- {
- ianjuta_editor_assist_proposals (assist->priv->iassist, IANJUTA_PROVIDER(assist),
- NULL, !queries_active, NULL);
- return;
- }
-
- if (assist->priv->pre_word && strlen(assist->priv->pre_word))
- {
- g_completion_complete (assist->priv->completion_cache, assist->priv->pre_word, NULL);
-
- completion_list = assist->priv->completion_cache->cache;
+ *start_iter = begin;
}
else
{
- completion_list = assist->priv->completion_cache->items;
- }
-
- length = g_list_length (completion_list);
-
- DEBUG_PRINT ("Populating %d proposals", length);
-
- /* Hide autocompletion if we only have one item */
- if (length == 1)
- {
- CppJavaAssistTag* tag = completion_list->data;
- if (tag->name && assist->priv->pre_word && g_str_equal (tag->name, assist->priv->pre_word))
- {
- ianjuta_editor_assist_proposals (assist->priv->iassist, IANJUTA_PROVIDER(assist),
- NULL, !queries_active, NULL);
- }
- }
- for (node = completion_list; node != NULL; node = g_list_next (node))
- {
- CppJavaAssistTag *tag = node->data;
- IAnjutaEditorAssistProposal* proposal = g_new0(IAnjutaEditorAssistProposal, 1);
-
- if (tag->is_func)
- proposal->label = g_strdup_printf ("%s()", tag->name);
- else
- proposal->label = g_strdup(tag->name);
-
- proposal->data = tag;
- proposal->icon = tag->icon;
- suggestions = g_list_prepend (suggestions, proposal);
- }
- suggestions = g_list_reverse (suggestions);
- ianjuta_editor_assist_proposals (assist->priv->iassist, IANJUTA_PROVIDER(assist),
- suggestions, !queries_active, NULL);
- g_list_foreach (suggestions, (GFunc) free_proposal, NULL);
- g_list_free (suggestions);
-}
-
-static void
-cpp_java_assist_create_word_completion_cache (CppJavaAssist *assist)
-{
- cpp_java_assist_destroy_completion_cache (assist);
- if (!assist->priv->pre_word || strlen(assist->priv->pre_word) < 3)
- return;
-
- gchar *pattern = g_strconcat (assist->priv->pre_word, "%", NULL);
-
- if (IANJUTA_IS_FILE (assist->priv->iassist))
- {
- GFile *file = ianjuta_file_get_file (IANJUTA_FILE (assist->priv->iassist), NULL);
- if (file != NULL)
- {
- AnjutaAsyncNotify* notify = anjuta_async_notify_new();
- g_signal_connect (notify, "finished", G_CALLBACK(file_finished), assist);
- assist->priv->async_file = TRUE;
- ianjuta_symbol_manager_search_file_async (assist->priv->isymbol_manager,
- IANJUTA_SYMBOL_TYPE_UNDEF,
- TRUE,
- IANJUTA_SYMBOL_FIELD_SIMPLE|
- IANJUTA_SYMBOL_FIELD_TYPE|
- IANJUTA_SYMBOL_FIELD_ACCESS|
- IANJUTA_SYMBOL_FIELD_KIND,
- pattern, file, -1, -1,
- assist->priv->cancel_file,
- notify, (IAnjutaSymbolManagerSearchCallback) on_query_data, assist,
- NULL);
- g_object_unref (file);
- }
- }
- {
- /* This will avoid duplicates of FUNCTION and PROTOTYPE */
- IAnjutaSymbolType types = IANJUTA_SYMBOL_TYPE_MAX & ~IANJUTA_SYMBOL_TYPE_FUNCTION;
- AnjutaAsyncNotify* notify = anjuta_async_notify_new();
- g_signal_connect (notify, "finished", G_CALLBACK(project_finished), assist);
- assist->priv->async_project = TRUE;
- ianjuta_symbol_manager_search_project_async (assist->priv->isymbol_manager,
- types,
- TRUE,
- IANJUTA_SYMBOL_FIELD_SIMPLE|
- IANJUTA_SYMBOL_FIELD_TYPE|
- IANJUTA_SYMBOL_FIELD_ACCESS|
- IANJUTA_SYMBOL_FIELD_KIND,
- pattern, IANJUTA_SYMBOL_MANAGER_SEARCH_FS_PUBLIC, -1, -1,
- assist->priv->cancel_project,
- notify, (IAnjutaSymbolManagerSearchCallback) on_query_data, assist,
- NULL);
-
- }
- {
- IAnjutaSymbolType types = IANJUTA_SYMBOL_TYPE_MAX & ~IANJUTA_SYMBOL_TYPE_FUNCTION;
- AnjutaAsyncNotify* notify = anjuta_async_notify_new();
- g_signal_connect (notify, "finished", G_CALLBACK(system_finished), assist);
- assist->priv->async_system = TRUE;
- ianjuta_symbol_manager_search_system_async (assist->priv->isymbol_manager,
- types,
- TRUE,
- IANJUTA_SYMBOL_FIELD_SIMPLE|
- IANJUTA_SYMBOL_FIELD_TYPE|
- IANJUTA_SYMBOL_FIELD_ACCESS|
- IANJUTA_SYMBOL_FIELD_KIND,
- pattern, IANJUTA_SYMBOL_MANAGER_SEARCH_FS_PUBLIC, -1, -1,
- assist->priv->cancel_system,
- notify, (IAnjutaSymbolManagerSearchCallback) on_query_data, assist,
- NULL);
- }
- g_free (pattern);
- g_free (assist->priv->search_cache);
- assist->priv->search_cache = g_strdup (assist->priv->pre_word);
-
- DEBUG_PRINT ("Started async search for: %s", assist->priv->pre_word);
-}
-
-static gchar*
-cpp_java_assist_get_calltip_context (CppJavaAssist *assist,
- IAnjutaIterable *iter)
-{
- gchar ch;
- gchar *context = NULL;
-
- ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
- if (ch == ')')
- {
- if (!cpp_java_util_jump_to_matching_brace (iter, ')', -1))
- return NULL;
- if (!ianjuta_iterable_previous (iter, NULL))
- return NULL;
- }
- if (ch != '(')
- {
- if (!cpp_java_util_jump_to_matching_brace (iter, ')',
- BRACE_SEARCH_LIMIT))
- return NULL;
- }
-
- /* Skip white spaces */
- while (ianjuta_iterable_previous (iter, NULL)
- && g_ascii_isspace (ianjuta_editor_cell_get_char
- (IANJUTA_EDITOR_CELL (iter), 0, NULL)));
-
- context = cpp_java_assist_get_scope_context
- (IANJUTA_EDITOR (assist->priv->itip), "(", iter);
-
- /* Point iter to the first character of the scope to align calltip correctly */
- ianjuta_iterable_next (iter, NULL);
-
- return context;
-}
-
-static GList*
-cpp_java_assist_create_calltips (IAnjutaIterable* iter)
-{
- GList* tips = NULL;
- if (iter)
- {
- do
- {
- IAnjutaSymbol* symbol = IANJUTA_SYMBOL(iter);
- const gchar* name = ianjuta_symbol_get_name(symbol, NULL);
- if (name != NULL)
- {
- const gchar* args = ianjuta_symbol_get_args(symbol, NULL);
- const gchar* rettype = ianjuta_symbol_get_returntype (symbol, NULL);
- gchar* print_args;
- gchar* separator;
- gchar* white_name;
- gint white_count = 0;
-
- if (!rettype)
- rettype = "";
- else
- white_count += strlen(rettype) + 1;
-
- white_count += strlen(name) + 1;
-
- white_name = g_strnfill (white_count, ' ');
- separator = g_strjoin (NULL, ", \n", white_name, NULL);
-
- gchar** argv;
- if (!args)
- args = "()";
-
- argv = g_strsplit (args, ",", -1);
- print_args = g_strjoinv (separator, argv);
-
- gchar* tip = g_strdup_printf ("%s %s %s", rettype, name, print_args);
-
- if (!g_list_find_custom (tips, tip, (GCompareFunc) strcmp))
- tips = g_list_append (tips, tip);
-
- g_strfreev (argv);
- g_free (print_args);
- g_free (separator);
- g_free (white_name);
- }
- else
- break;
- }
- while (ianjuta_iterable_next (iter, NULL));
- }
- return tips;
-}
-
-static gboolean
-cpp_java_assist_show_calltip (CppJavaAssist *assist, gchar *call_context,
- IAnjutaIterable *position_iter)
-{
- GList *tips = NULL;
-
- /* Search file */
- if (IANJUTA_IS_FILE (assist->priv->itip))
- {
- GFile *file = ianjuta_file_get_file (IANJUTA_FILE (assist->priv->itip), NULL);
-
- if (file != NULL)
- {
- IAnjutaIterable* iter_file =
- ianjuta_symbol_manager_search_file (assist->priv->isymbol_manager,
- IANJUTA_SYMBOL_TYPE_PROTOTYPE|
- IANJUTA_SYMBOL_TYPE_FUNCTION|
- IANJUTA_SYMBOL_TYPE_METHOD|
- IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG,
- TRUE,
- IANJUTA_SYMBOL_FIELD_SIMPLE|
- IANJUTA_SYMBOL_FIELD_TYPE|
- IANJUTA_SYMBOL_FIELD_ACCESS|
- IANJUTA_SYMBOL_FIELD_KIND,
- call_context, file, -1, -1, NULL);
-
- if (iter_file)
- {
- tips = cpp_java_assist_create_calltips (iter_file);
- g_object_unref (iter_file);
- }
- g_object_unref (file);
- }
- }
-
- /* Search Project */
- IAnjutaIterable* iter_project =
- ianjuta_symbol_manager_search_project (assist->priv->isymbol_manager,
- IANJUTA_SYMBOL_TYPE_PROTOTYPE|
- IANJUTA_SYMBOL_TYPE_FUNCTION|
- IANJUTA_SYMBOL_TYPE_METHOD|
- IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG,
- TRUE,
- IANJUTA_SYMBOL_FIELD_SIMPLE|
- IANJUTA_SYMBOL_FIELD_TYPE|
- IANJUTA_SYMBOL_FIELD_ACCESS|
- IANJUTA_SYMBOL_FIELD_KIND,
- call_context, IANJUTA_SYMBOL_MANAGER_SEARCH_FS_PUBLIC,
- -1, -1, NULL);
- if (iter_project)
- {
- tips = g_list_concat (tips, cpp_java_assist_create_calltips (iter_project));
- g_object_unref (iter_project);
- }
-
- /* Search global */
- IAnjutaIterable* iter_global =
- ianjuta_symbol_manager_search_system (assist->priv->isymbol_manager,
- IANJUTA_SYMBOL_TYPE_PROTOTYPE|
- IANJUTA_SYMBOL_TYPE_FUNCTION|
- IANJUTA_SYMBOL_TYPE_METHOD|
- IANJUTA_SYMBOL_TYPE_MACRO_WITH_ARG,
- TRUE,
- IANJUTA_SYMBOL_FIELD_SIMPLE|
- IANJUTA_SYMBOL_FIELD_TYPE|
- IANJUTA_SYMBOL_FIELD_ACCESS|
- IANJUTA_SYMBOL_FIELD_KIND,
- call_context, IANJUTA_SYMBOL_MANAGER_SEARCH_FS_PUBLIC,
- -1, -1, NULL);
- if (iter_global)
- {
- tips = g_list_concat (tips, cpp_java_assist_create_calltips (iter_global));
- g_object_unref (iter_global);
+ g_object_unref (begin);
+ *start_iter = NULL;
}
- if (tips)
- {
- ianjuta_editor_tip_show (IANJUTA_EDITOR_TIP(assist->priv->itip), tips,
- position_iter, 0,
- NULL);
- g_list_foreach (tips, (GFunc) g_free, NULL);
- g_list_free (tips);
- return TRUE;
- }
- return FALSE;
+ g_object_unref (end);
+ return preword_chars;
}
+/**
+ * cpp_java_assist_update_pre_word:
+ * @assist: self
+ * @pre_word: new pre_word
+ *
+ * Updates the current pre_word
+ */
static void
-cpp_java_assist_calltip (CppJavaAssist *assist,
- gboolean calltips, gboolean backspace)
+cpp_java_assist_update_pre_word (CppJavaAssist* assist, const gchar* pre_word)
{
- IAnjutaEditor *editor;
- IAnjutaIterable *iter;
-
- if (!calltips)
- return; /* Nothing to do */
-
- editor = IANJUTA_EDITOR (assist->priv->itip);
-
- iter = ianjuta_editor_get_position (editor, NULL);
- ianjuta_iterable_previous (iter, NULL);
- if (calltips)
+ g_free (assist->priv->pre_word);
+ if (pre_word)
{
- gchar *call_context =
- cpp_java_assist_get_calltip_context (assist, iter);
- if (call_context)
- {
- if (ianjuta_editor_tip_visible (IANJUTA_EDITOR_TIP (editor), NULL))
- {
- if (assist->priv->calltip_context &&
- !g_str_equal (call_context, assist->priv->calltip_context))
- {
- cpp_java_assist_show_calltip (assist, call_context,
- iter);
- g_free (assist->priv->calltip_context);
- assist->priv->calltip_context = g_strdup(call_context);
- }
- }
- else
- {
- cpp_java_assist_show_calltip (assist, call_context,
- iter);
- g_free (assist->priv->calltip_context);
- assist->priv->calltip_context = g_strdup(call_context);
- }
- }
- else
- {
- ianjuta_editor_tip_cancel (IANJUTA_EDITOR_TIP(assist->priv->itip), NULL);
- g_free (assist->priv->calltip_context);
- assist->priv->calltip_context = NULL;
- }
- g_free (call_context);
+ DEBUG_PRINT ("Setting pre_word to %s", pre_word);
+ assist->priv->pre_word = g_strdup (pre_word);
}
- g_object_unref (iter);
}
-static void
-on_editor_char_added (IAnjutaEditor *editor, IAnjutaIterable *insert_pos,
- gchar ch, CppJavaAssist *assist)
-{
- gboolean enable_calltips =
- anjuta_preferences_get_bool_with_default (assist->priv->preferences,
- PREF_CALLTIP_ENABLE,
- TRUE);
- cpp_java_assist_calltip(assist, enable_calltips, (ch == '\b'));
-}
-
-#define BRACE_LIMIT 100
-
+/**
+ * cpp_java_assist_is_expression_separator:
+ * @c: character to check
+ * @skip_braces: whether to skip closing braces
+ * @iter: current cursor position
+ *
+ * Checks if a character seperates a C/C++ expression. It can skip brances
+ * because they might not really end the expression
+ *
+ * Returns: TRUE if the characters seperates an expression, FALSE otherwise
+ */
static gboolean
-is_expression_separator (gchar c, gboolean skip_braces, IAnjutaIterable* iter)
+cpp_java_assist_is_expression_separator (gchar c, gboolean skip_braces, IAnjutaIterable* iter)
{
IAnjutaEditorAttribute attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL(iter),
NULL);
@@ -748,7 +295,7 @@ is_expression_separator (gchar c, gboolean skip_braces, IAnjutaIterable* iter)
if (c == ')' && skip_braces)
{
- cpp_java_util_jump_to_matching_brace (iter, c, BRACE_LIMIT);
+ cpp_java_util_jump_to_matching_brace (iter, c, BRACE_SEARCH_LIMIT);
return TRUE;
}
else if (c == ')' && !skip_braces)
@@ -763,8 +310,16 @@ is_expression_separator (gchar c, gboolean skip_braces, IAnjutaIterable* iter)
return FALSE;
}
+/**
+ * cpp_java_assist_parse_expression:
+ * @assist: self,
+ * @iter: current cursor position
+ * @start_iter: return location for the start of the completion
+ *
+ * Returns: An iter of a list of IAnjutaSymbols or NULL
+ */
static IAnjutaIterable*
-cpp_java_parse_expression (CppJavaAssist* assist, IAnjutaIterable* iter, IAnjutaIterable** start_iter)
+cpp_java_assist_parse_expression (CppJavaAssist* assist, IAnjutaIterable* iter, IAnjutaIterable** start_iter)
{
IAnjutaEditor* editor = IANJUTA_EDITOR (assist->priv->iassist);
IAnjutaIterable* res = NULL;
@@ -772,14 +327,16 @@ cpp_java_parse_expression (CppJavaAssist* assist, IAnjutaIterable* iter, IAnjuta
gboolean op_start = FALSE;
gboolean ref_start = FALSE;
gchar* stmt = NULL;
+
+ /* Cursor points after the current characters, move back */
+ ianjuta_iterable_previous (cur_pos, NULL);
/* Search for a operator in the current line */
do
{
gchar ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL(cur_pos), 0, NULL);
- if (is_expression_separator(ch, FALSE, iter)) {
- DEBUG_PRINT ("found char '%c' which is an expression_separator", ch);
+ if (cpp_java_assist_is_expression_separator(ch, FALSE, iter)) {
break;
}
@@ -790,6 +347,7 @@ cpp_java_parse_expression (CppJavaAssist* assist, IAnjutaIterable* iter, IAnjuta
IAnjutaIterable* pre_word_end = ianjuta_iterable_clone (iter, NULL);
IAnjutaIterable* stmt_end = ianjuta_iterable_clone (pre_word_start, NULL);
+
/* we need to pass to the parser all the statement included the last operator,
* being it "." or "->" or "::"
* Increase the end bound of the statement.
@@ -807,18 +365,17 @@ cpp_java_parse_expression (CppJavaAssist* assist, IAnjutaIterable* iter, IAnjuta
{
ianjuta_iterable_next (pre_word_start, NULL);
}
- /* Move the end character to be behind the current typed character */
- ianjuta_iterable_next (pre_word_end, NULL);
- assist->priv->pre_word = ianjuta_editor_get_text (editor,
- pre_word_start, pre_word_end, NULL);
+ cpp_java_assist_update_pre_word (assist,
+ ianjuta_editor_get_text (editor,
+ pre_word_start, pre_word_end, NULL));
/* Try to get the name of the variable */
while (ianjuta_iterable_previous (cur_pos, NULL))
{
gchar word_ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL(cur_pos), 0, NULL);
- if (is_expression_separator(word_ch, FALSE, cur_pos))
+ if (cpp_java_assist_is_expression_separator(word_ch, FALSE, cur_pos))
break;
}
ianjuta_iterable_next (cur_pos, NULL);
@@ -826,6 +383,7 @@ cpp_java_parse_expression (CppJavaAssist* assist, IAnjutaIterable* iter, IAnjuta
cur_pos, stmt_end, NULL);
*start_iter = pre_word_start;
g_object_unref (stmt_end);
+ g_object_unref (pre_word_end);
break;
}
else if (ch == '>')
@@ -884,192 +442,392 @@ cpp_java_parse_expression (CppJavaAssist* assist, IAnjutaIterable* iter, IAnjuta
return res;
}
-static gboolean
-cpp_java_assist_valid_iter (CppJavaAssist* assist, IAnjutaIterable* iter)
+/**
+ * cpp_java_assist_create_completion_cache:
+ * @assist: self
+ *
+ * Create a new completion_cache object
+ */
+static void
+cpp_java_assist_create_completion_cache (CppJavaAssist* assist)
{
- IAnjutaEditorCell* cell = IANJUTA_EDITOR_CELL (iter);
- IAnjutaEditorAttribute attribute = ianjuta_editor_cell_get_attribute (cell, NULL);
- return (attribute != IANJUTA_EDITOR_STRING && attribute != IANJUTA_EDITOR_COMMENT);
+ g_assert (assist->priv->completion_cache == NULL);
+ assist->priv->completion_cache =
+ g_completion_new (anjuta_proposal_completion_func);
}
+/**
+ * cpp_java_assist_clear_completion_cache
+ * @assist: self
+ *
+ * Clear the completion cache, aborting all async operations
+ */
static void
-cpp_java_assist_populate (IAnjutaProvider* self, IAnjutaIterable* iter, GError** e)
+cpp_java_assist_clear_completion_cache (CppJavaAssist* assist)
{
- CppJavaAssist* assist = CPP_JAVA_ASSIST (self);
- IAnjutaEditor *editor;
- gboolean autocomplete = anjuta_preferences_get_bool_with_default (assist->priv->preferences,
- PREF_AUTOCOMPLETE_ENABLE,
- TRUE);
- editor = IANJUTA_EDITOR (assist->priv->iassist);
+ if (assist->priv->completion_cache)
+ {
+ g_list_foreach (assist->priv->completion_cache->items, (GFunc) cpp_java_assist_proposal_free, NULL);
+ g_completion_free (assist->priv->completion_cache);
+ }
+ assist->priv->completion_cache = NULL;
+ g_cancellable_cancel (assist->priv->cancel_file);
+ g_cancellable_cancel (assist->priv->cancel_project);
+ g_cancellable_cancel (assist->priv->cancel_system);
+}
- g_free (assist->priv->pre_word);
- assist->priv->pre_word = NULL;
+/**
+ * cpp_java_assist_populate_real:
+ * @assist: self
+ * @finished: TRUE if no more proposals are expected, FALSE otherwise
+ *
+ * Really invokes the completion interfaces and adds completions. Might be called
+ * from an async context
+ */
+static void
+cpp_java_assist_populate_real (CppJavaAssist* assist, gboolean finished)
+{
+ g_assert (assist->priv->pre_word != NULL);
+ gchar* prefix;
+ GList* proposals = g_completion_complete (assist->priv->completion_cache,
+ assist->priv->pre_word,
+ &prefix);
+ DEBUG_PRINT ("%d proposals match, prefix: %s", g_list_length (proposals), prefix);
+ g_free (prefix);
- ianjuta_iterable_previous (iter, NULL);
+ ianjuta_editor_assist_proposals (assist->priv->iassist,
+ IANJUTA_PROVIDER(assist),
+ proposals, finished, NULL);
+}
- if (autocomplete && cpp_java_assist_valid_iter (assist, iter))
- {
- /* Check for member completion */
- IAnjutaIterable* start_iter = NULL;
- IAnjutaIterable* res =
- cpp_java_parse_expression (assist, iter, &start_iter);
- if (start_iter && assist->priv->pre_word && assist->priv->search_cache && res != NULL &&
- g_str_has_prefix (assist->priv->pre_word, assist->priv->search_cache))
+/**
+ * cpp_java_assist_create_member_completion_cache
+ * @assist: self
+ * @cursor: Current cursor position
+ *
+ * Create the completion_cache for member completion if possible
+ *
+ * Returns: TRUE if a completion cache was build, FALSE otherwise
+ */
+static gboolean
+cpp_java_assist_create_member_completion_cache (CppJavaAssist* assist, IAnjutaIterable* cursor)
+{
+ IAnjutaIterable* symbol = NULL;
+ IAnjutaIterable* start_iter = NULL;
+ symbol = cpp_java_assist_parse_expression (assist, cursor, &start_iter);
+
+ if (symbol)
+ {
+ gint retval = FALSE;
+ /* Query symbol children */
+ IAnjutaIterable *children =
+ ianjuta_symbol_manager_get_members (assist->priv->isymbol_manager,
+ IANJUTA_SYMBOL(symbol),
+ IANJUTA_SYMBOL_FIELD_SIMPLE |
+ IANJUTA_SYMBOL_FIELD_KIND |
+ IANJUTA_SYMBOL_FIELD_ACCESS |
+ IANJUTA_SYMBOL_FIELD_TYPE,
+ NULL);
+ if (children)
{
- if (assist->priv->start_iter)
- g_object_unref (assist->priv->start_iter);
+ GList* proposals =
+ cpp_java_assist_create_completion_from_symbols (children);
+ cpp_java_assist_create_completion_cache (assist);
+ g_completion_add_items (assist->priv->completion_cache, proposals);
+
assist->priv->start_iter = start_iter;
- cpp_java_assist_update_autocomplete (assist);
- g_object_unref (res);
- return;
+
+ cpp_java_assist_populate_real (assist, TRUE);
+ g_list_free (proposals);
+ g_object_unref (children);
+ retval = TRUE;
}
- /* we should have a res with just one item */
- if (res != NULL)
+ g_object_unref (symbol);
+ return retval;
+ }
+ else if (start_iter)
+ g_object_unref (start_iter);
+ return FALSE;
+}
+
+/**
+ * on_symbol_search_complete:
+ * @search_id: id of this search
+ * @symbols: the returned symbols
+ * @assist: self
+ *
+ * Called by the async search method when it found symbols
+ */
+static void
+on_symbol_search_complete (gint search_id, IAnjutaIterable* symbols, CppJavaAssist* assist)
+{
+ GList* proposals = cpp_java_assist_create_completion_from_symbols (symbols);
+ DEBUG_PRINT ("Found %d symbols, adding!", g_list_length (proposals));
+ g_completion_add_items (assist->priv->completion_cache, proposals);
+ gboolean running = assist->priv->async_system || assist->priv->async_file ||
+ assist->priv->async_project;
+ cpp_java_assist_populate_real (assist, !running);
+ g_list_free (proposals);
+ g_object_unref (symbols);
+}
+
+/**
+ * notify_system_finished:
+ * @notify: the notifycation object
+ * @assist: self
+ *
+ * Called when the system search was finished
+ */
+static void
+notify_system_finished (AnjutaAsyncNotify* notify, CppJavaAssist* assist)
+{
+ assist->priv->async_system = FALSE;
+}
+
+/**
+ * notify_file_finished:
+ * @notify: the notifycation object
+ * @assist: self
+ *
+ * Called when the file search was finished
+ */
+static void
+notify_file_finished (AnjutaAsyncNotify* notify, CppJavaAssist* assist)
+{
+ assist->priv->async_file = FALSE;
+}
+
+/**
+ * notify_project_finished:
+ * @notify: the notifycation object
+ * @assist: self
+ *
+ * Called when the file search was finished
+ */
+static void
+notify_project_finished (AnjutaAsyncNotify* notify, CppJavaAssist* assist)
+{
+ assist->priv->async_project = FALSE;
+}
+
+
+/**
+ * cpp_java_assist_create_autocompletion_cache:
+ * @assist: self
+ * @cursor: Current cursor position
+ *
+ * Create completion cache for autocompletion. This is done async.
+ *
+ * Returns: TRUE if a preword was detected, FALSE otherwise
+ */
+static gboolean
+cpp_java_assist_create_autocompletion_cache (CppJavaAssist* assist, IAnjutaIterable* cursor)
+{
+ IAnjutaIterable* start_iter;
+ gchar* pre_word =
+ cpp_java_assist_get_pre_word (IANJUTA_EDITOR (assist->priv->iassist), cursor, &start_iter);
+ if (!pre_word || strlen (pre_word) <= 3)
+ {
+ if (start_iter)
+ g_object_unref (start_iter);
+ return FALSE;
+ }
+ else
+ {
+ gchar *pattern = g_strconcat (pre_word, "%", NULL);
+ AnjutaAsyncNotify* notify = NULL;
+ IAnjutaSymbolType match_types = IANJUTA_SYMBOL_TYPE_MAX;
+ IAnjutaSymbolField fields = IANJUTA_SYMBOL_FIELD_SIMPLE |
+ IANJUTA_SYMBOL_FIELD_TYPE |
+ IANJUTA_SYMBOL_FIELD_ACCESS |
+ IANJUTA_SYMBOL_FIELD_KIND;
+
+ cpp_java_assist_create_completion_cache (assist);
+ cpp_java_assist_update_pre_word (assist, pre_word);
+
+ if (IANJUTA_IS_FILE (assist->priv->iassist))
{
- do
+ GFile *file = ianjuta_file_get_file (IANJUTA_FILE (assist->priv->iassist), NULL);
+ if (file != NULL)
{
- IAnjutaSymbol* symbol = IANJUTA_SYMBOL(res);
- const gchar* name = ianjuta_symbol_get_name(symbol, NULL);
- if (name != NULL)
- {
- DEBUG_PRINT ("PARENT Completion Symbol: %s", name);
-
- /* we have just printed the parent's name */
- /* let's get it's members and print them */
- IAnjutaIterable *children =
- ianjuta_symbol_manager_get_members (assist->priv->isymbol_manager,
- symbol,
- IANJUTA_SYMBOL_FIELD_SIMPLE |
- IANJUTA_SYMBOL_FIELD_KIND |
- IANJUTA_SYMBOL_FIELD_ACCESS |
- IANJUTA_SYMBOL_FIELD_TYPE,
- NULL);
- if (children != NULL) {
- cpp_java_assist_destroy_completion_cache (assist);
- assist->priv->completion_cache = create_completion (assist,
- children,
- NULL);
- if (assist->priv->start_iter)
- g_object_unref (assist->priv->start_iter);
- assist->priv->start_iter = start_iter;
- cpp_java_assist_update_autocomplete(assist);
- }
- }
- else
- break;
+ notify = anjuta_async_notify_new();
+ g_signal_connect (notify, "finished", G_CALLBACK(notify_file_finished), assist);
+ assist->priv->async_file = TRUE;
+ g_cancellable_reset (assist->priv->cancel_file);
+ ianjuta_symbol_manager_search_file_async (assist->priv->isymbol_manager,
+ match_types,
+ TRUE,
+ fields,
+ pattern, file, -1, -1,
+ assist->priv->cancel_file,
+ notify,
+ (IAnjutaSymbolManagerSearchCallback) on_symbol_search_complete,
+ assist,
+ NULL);
+ g_object_unref (file);
}
- while (ianjuta_iterable_next (res, NULL));
- g_object_unref (res);
- return;
}
+ /* This will avoid duplicates of FUNCTION and PROTOTYPE */
+ match_types &= ~IANJUTA_SYMBOL_TYPE_FUNCTION;
+ notify = anjuta_async_notify_new();
+ g_signal_connect (notify, "finished", G_CALLBACK(notify_project_finished), assist);
+ assist->priv->async_project = TRUE;
+ g_cancellable_reset (assist->priv->cancel_project);
+ ianjuta_symbol_manager_search_project_async (assist->priv->isymbol_manager,
+ match_types,
+ TRUE,
+ fields,
+ pattern,
+ IANJUTA_SYMBOL_MANAGER_SEARCH_FS_PUBLIC, -1, -1,
+ assist->priv->cancel_project,
+ notify,
+ (IAnjutaSymbolManagerSearchCallback) on_symbol_search_complete,
+ assist,
+ NULL);
+
+
+ notify = anjuta_async_notify_new();
+ g_signal_connect (notify, "finished", G_CALLBACK(notify_system_finished), assist);
+ assist->priv->async_system = TRUE;
+ g_cancellable_reset (assist->priv->cancel_system);
+ ianjuta_symbol_manager_search_system_async (assist->priv->isymbol_manager,
+ match_types,
+ TRUE,
+ fields,
+ pattern, IANJUTA_SYMBOL_MANAGER_SEARCH_FS_PUBLIC, -1, -1,
+ assist->priv->cancel_system,
+ notify,
+ (IAnjutaSymbolManagerSearchCallback) on_symbol_search_complete,
+ assist,
+ NULL);
+ g_free (pre_word);
+ g_free (pattern);
+
+ assist->priv->start_iter = start_iter;
- /* Normal autocompletion */
- /* Moved iter to begin of word */
- assist->priv->pre_word = cpp_java_assist_get_pre_word (editor, iter);
- DEBUG_PRINT ("Pre word: %s", assist->priv->pre_word);
-
- if (assist->priv->pre_word && strlen (assist->priv->pre_word) > 3)
- {
- if (!assist->priv->search_cache ||
- !g_str_has_prefix (assist->priv->pre_word, assist->priv->search_cache))
- {
- if (assist->priv->start_iter)
- g_object_unref (assist->priv->start_iter);
- assist->priv->start_iter = ianjuta_iterable_clone(iter, NULL);
- DEBUG_PRINT ("Setting start iter!");
- ianjuta_iterable_next (IANJUTA_ITERABLE (assist->priv->start_iter), NULL);
- cpp_java_assist_create_word_completion_cache(assist);
- return;
- }
- else
- {
- cpp_java_assist_update_autocomplete (assist);
- return;
- }
- }
+ return TRUE;
}
- /* Keep completion system happy */
- ianjuta_editor_assist_proposals (assist->priv->iassist,
- IANJUTA_PROVIDER(self),
- NULL, TRUE, NULL);
-}
+}
+/**
+ * cpp_java_assist_populate:
+ * @self: IAnjutaProvider object
+ * @cursor: Iter at current cursor position (after current character)
+ * @e: Error population
+ */
static void
-cpp_java_assist_activate (IAnjutaProvider* self, IAnjutaIterable* iter, gpointer data, GError** e)
+cpp_java_assist_populate (IAnjutaProvider* self, IAnjutaIterable* cursor, GError** e)
{
- CppJavaAssist* assist = CPP_JAVA_ASSIST(self);
- CppJavaAssistTag *tag;
- GString *assistance;
- IAnjutaEditor *te;
- gboolean add_space_after_func = FALSE;
- gboolean add_brace_after_func = FALSE;
-
- //DEBUG_PRINT ("assist-chosen: %d", selection);
-
- tag = data;
-
- g_return_if_fail (tag != NULL);
-
- assistance = g_string_new (tag->name);
-
- if (tag->is_func)
+ CppJavaAssist* assist = CPP_JAVA_ASSIST (self);
+
+ /* Check if this is a valid text region for completion */
+ IAnjutaEditorAttribute attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL(cursor),
+ NULL);
+ if (attrib == IANJUTA_EDITOR_STRING ||
+ attrib == IANJUTA_EDITOR_COMMENT)
{
- add_space_after_func =
- anjuta_preferences_get_bool_with_default (assist->priv->preferences,
- PREF_AUTOCOMPLETE_SPACE_AFTER_FUNC,
- TRUE);
- add_brace_after_func =
- anjuta_preferences_get_bool_with_default (assist->priv->preferences,
- PREF_AUTOCOMPLETE_BRACE_AFTER_FUNC,
- TRUE);
- if (add_space_after_func)
- g_string_append (assistance, " ");
-
- if (add_brace_after_func)
- g_string_append (assistance, "(");
+ ianjuta_editor_assist_proposals (assist->priv->iassist,
+ IANJUTA_PROVIDER(self),
+ NULL, TRUE, NULL);
+ return;
}
- te = IANJUTA_EDITOR (assist->priv->iassist);
-
- ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (te), NULL);
-
- if (ianjuta_iterable_compare(iter, assist->priv->start_iter, NULL) != 0)
+ /* Check if completion was in progress */
+ if (assist->priv->member_completion || assist->priv->autocompletion)
{
- ianjuta_editor_selection_set (IANJUTA_EDITOR_SELECTION (te),
- assist->priv->start_iter, iter, FALSE, NULL);
- ianjuta_editor_selection_replace (IANJUTA_EDITOR_SELECTION (te),
- assistance->str, -1, NULL);
+ IAnjutaIterable* start_iter = NULL;
+ g_assert (assist->priv->completion_cache != NULL);
+ gchar* pre_word = cpp_java_assist_get_pre_word (IANJUTA_EDITOR (assist->priv->iassist), cursor, &start_iter);
+ DEBUG_PRINT ("Completion is in progress");
+ if (pre_word && g_str_has_prefix (pre_word, assist->priv->pre_word))
+ {
+ /* Great, we just continue the current completion */
+ g_object_unref (assist->priv->start_iter);
+ assist->priv->start_iter = start_iter;
+
+ cpp_java_assist_update_pre_word (assist, pre_word);
+ cpp_java_assist_populate_real (assist, TRUE);
+ g_free (pre_word);
+ return;
+ }
+ else
+ cpp_java_assist_clear_completion_cache (assist);
+ g_free (pre_word);
}
- else
+ /* Check for member completion */
+ assist->priv->member_completion = FALSE;
+ assist->priv->autocompletion = FALSE;
+ if (cpp_java_assist_create_member_completion_cache (assist, cursor))
{
- ianjuta_editor_insert (te, iter, assistance->str, -1, NULL);
+ assist->priv->member_completion = TRUE;
+ DEBUG_PRINT ("Creating member completion");
+ return;
}
- ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (te), NULL);
-
- /* Show calltip if we completed function */
- if (add_brace_after_func)
- cpp_java_assist_calltip (assist, TRUE, FALSE);
-
- g_string_free (assistance, TRUE);
- g_free(assist->priv->pre_word);
- assist->priv->pre_word = NULL;
- g_free(assist->priv->search_cache);
- assist->priv->search_cache = NULL;
+ else if (cpp_java_assist_create_autocompletion_cache (assist, cursor))
+ {
+ assist->priv->autocompletion = TRUE;
+ DEBUG_PRINT ("Creating autocompletion");
+ return;
+ }
+ /* Nothing to propose */
+ if (assist->priv->start_iter)
+ {
+ g_object_unref (assist->priv->start_iter);
+ assist->priv->start_iter = NULL;
+ }
+ ianjuta_editor_assist_proposals (assist->priv->iassist,
+ IANJUTA_PROVIDER(self),
+ NULL, TRUE, NULL);
+}
+
+/**
+ * cpp_java_assist_activate:
+ * @self: IAnjutaProvider object
+ * @iter: cursor position when proposal was activated
+ * @data: Data assigned to the completion object
+ * @e: Error population
+ */
+static void
+cpp_java_assist_activate (IAnjutaProvider* self, IAnjutaIterable* iter, gpointer data, GError** e)
+{
+
}
+/**
+ * cpp_java_assist_get_start_iter:
+ * @self: IAnjutaProvider object
+ * @e: Error population
+ *
+ * Returns: the iter where the autocompletion starts
+ */
static IAnjutaIterable*
cpp_java_assist_get_start_iter (IAnjutaProvider* provider, GError** e)
{
CppJavaAssist* assist = CPP_JAVA_ASSIST (provider);
+ DEBUG_PRINT ("Start iter: %d", ianjuta_iterable_get_position(assist->priv->start_iter, NULL));
return assist->priv->start_iter;
}
+/**
+ * cpp_java_assist_get_name:
+ * @self: IAnjutaProvider object
+ * @e: Error population
+ *
+ * Returns: the provider name
+ */
static const gchar*
cpp_java_assist_get_name (IAnjutaProvider* provider, GError** e)
{
return _("C/C++");
}
+/**
+ * cpp_java_assist_install:
+ * @self: IAnjutaProvider object
+ * @ieditor: Editor to install support for
+ *
+ * Returns: Registers provider for editor
+ */
static void
cpp_java_assist_install (CppJavaAssist *assist, IAnjutaEditor *ieditor)
{
@@ -1085,6 +843,7 @@ cpp_java_assist_install (CppJavaAssist *assist, IAnjutaEditor *ieditor)
assist->priv->iassist = NULL;
}
+#if 0
if (IANJUTA_IS_EDITOR_TIP (ieditor))
{
assist->priv->itip = IANJUTA_EDITOR_TIP (ieditor);
@@ -1093,19 +852,28 @@ cpp_java_assist_install (CppJavaAssist *assist, IAnjutaEditor *ieditor)
G_CALLBACK (on_editor_char_added), assist);
}
else
+#endif
{
assist->priv->itip = NULL;
}
}
+/**
+ * cpp_java_assist_uninstall:
+ * @self: IAnjutaProvider object
+ *
+ * Returns: Unregisters provider
+ */
static void
cpp_java_assist_uninstall (CppJavaAssist *assist)
{
g_return_if_fail (assist->priv->iassist != NULL);
DEBUG_PRINT ("uninstall called");
-
+
+#if 0
g_signal_handlers_disconnect_by_func (assist->priv->iassist, G_CALLBACK (on_editor_char_added), assist);
+#endif
ianjuta_editor_assist_remove (assist->priv->iassist, IANJUTA_PROVIDER(assist), NULL);
@@ -1116,7 +884,6 @@ static void
cpp_java_assist_init (CppJavaAssist *assist)
{
assist->priv = g_new0 (CppJavaAssistPriv, 1);
-
assist->priv->cancel_file = g_cancellable_new();
assist->priv->cancel_project = g_cancellable_new();
assist->priv->cancel_system = g_cancellable_new();
@@ -1127,15 +894,17 @@ cpp_java_assist_finalize (GObject *object)
{
CppJavaAssist *assist = CPP_JAVA_ASSIST (object);
cpp_java_assist_uninstall (assist);
- cpp_java_assist_destroy_completion_cache (assist);
+ cpp_java_assist_clear_completion_cache (assist);
+#if 0
if (assist->priv->calltip_context)
{
g_free (assist->priv->calltip_context);
assist->priv->calltip_context = NULL;
- g_object_unref (assist->priv->cancel_file);
- g_object_unref (assist->priv->cancel_project);
- g_object_unref (assist->priv->cancel_system);
}
+#endif
+ g_object_unref (assist->priv->cancel_file);
+ g_object_unref (assist->priv->cancel_project);
+ g_object_unref (assist->priv->cancel_system);
g_free (assist->priv);
G_OBJECT_CLASS (cpp_java_assist_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]