[anjuta/python-support] python-plugin: Make autocompletion async
- From: Johannes Schmid <jhs src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta/python-support] python-plugin: Make autocompletion async
- Date: Mon, 2 Aug 2010 20:20:27 +0000 (UTC)
commit 1de65137f3abb2cdb85b62313b28e2124f157d8e
Author: Johannes Schmid <jhs gnome org>
Date: Mon Aug 2 22:19:50 2010 +0200
python-plugin: Make autocompletion async
It uses AnjutaLauncher and GRegex now. There are still some small things to polish but it
already works quite well.
plugins/language-support-python/plugin.c | 15 +--
plugins/language-support-python/python-assist.c | 193 +++++++++++------------
plugins/language-support-python/python-assist.h | 10 --
3 files changed, 93 insertions(+), 125 deletions(-)
---
diff --git a/plugins/language-support-python/plugin.c b/plugins/language-support-python/plugin.c
index 77bbf22..2102a81 100644
--- a/plugins/language-support-python/plugin.c
+++ b/plugins/language-support-python/plugin.c
@@ -1250,20 +1250,7 @@ on_auto_complete (GtkAction *action, gpointer data)
PythonPlugin *lang_plugin = (PythonPlugin*) (data);;
PythonAssist *assist = PYTHON_ASSIST (lang_plugin->assist);
- python_assist_create_word_completion_cache (assist);
- python_assist_update_autocomplete (assist);
-
-
-
-/* if (lang_plugin->assist)
- {
-// python_assist_check (lang_plugin->assist, TRUE, TRUE, FALSE);
- dialog = gtk_message_dialog_new (NULL,
- GTK_DIALOG_NO_SEPARATOR,
- GTK_MESSAGE_INFO,
- GTK_BUTTONS_OK, "%s", "on_auto_complete");
- gtk_widget_show (dialog);
- }*/
+ // TODO
}
static GtkActionEntry actions[] = {
diff --git a/plugins/language-support-python/python-assist.c b/plugins/language-support-python/python-assist.c
index 1132206..7775457 100644
--- a/plugins/language-support-python/python-assist.c
+++ b/plugins/language-support-python/python-assist.c
@@ -264,45 +264,6 @@ python_assist_destroy_completion_cache (PythonAssist *assist)
}
}
-static gchar*
-get_tag_name (gchar* tag)
-{
- gchar tagname[256];
- gint i;
-
- for (i=0; i<strlen(tag) && tag[i]!=' '; i++)
- tagname[i] = tag[i];
- tagname[i]='\0';
- return g_strdup(tagname);
-}
-
-static IAnjutaSymbolType
-get_tag_type (gchar* tag)
-{
- int i;
- int startpos;
- int counter=0;
- gchar type[20];
- for (i=0; i<strlen(tag); i++)
- if (tag[i]==',')
- {
- startpos=i+2;
- break;
- }
- if (startpos<strlen(tag))
- {
- for (i=startpos; tag[i]!=')' && tag[i]!='\0'; i++)
- type[counter++]=tag[i];
- type[counter]='\0';
- }
- if (g_str_equal(type, "function") || g_str_equal(type, "builtin") /*|| g_str_equal(type, "imported")*/)
- return IANJUTA_SYMBOL_TYPE_FUNCTION;
- else
- return IANJUTA_SYMBOL_TYPE_VARIABLE;
-
-}
-
-
static gboolean
is_cache_fresh (IAnjutaEditor *editor, gint editor_position, gint cache_position)
{
@@ -333,7 +294,7 @@ static void free_proposal (IAnjutaEditorAssistProposal* proposal)
g_free(proposal);
}
-void
+static void
python_assist_update_autocomplete (PythonAssist *assist)
{
gint length;
@@ -342,8 +303,6 @@ python_assist_update_autocomplete (PythonAssist *assist)
IAnjutaEditor *editor = (IAnjutaEditor*)assist->priv->editor;
int editor_position = ianjuta_editor_get_offset(editor,NULL);
- // if cache is stale
-
if (!is_cache_fresh(editor, editor_position, assist->priv->cache_position))
{
python_assist_destroy_completion_cache (assist);
@@ -352,11 +311,12 @@ python_assist_update_autocomplete (PythonAssist *assist)
return;
}
- // If cache is empty, show nothing
+ // Check if we need to wait or more results
if (assist->priv->completion_cache == NULL)
{
+ gboolean finished = (assist->priv->launcher == NULL);
ianjuta_editor_assist_proposals (assist->priv->iassist, IANJUTA_PROVIDER(assist),
- NULL, TRUE, NULL);
+ NULL, finished , NULL);
return;
}
@@ -375,37 +335,26 @@ python_assist_update_autocomplete (PythonAssist *assist)
DEBUG_PRINT ("Populating %d proposals", length);
-
- if (1) //length <= max_completions)
- {
-
- GList *node, *suggestions = NULL;
-
- for (node = completion_list; node != NULL; node = g_list_next (node))
- {
- PythonAssistTag *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;
- suggestions = g_list_prepend (suggestions, proposal);
- }
- suggestions = g_list_reverse (suggestions);
- ianjuta_editor_assist_proposals (assist->priv->iassist, IANJUTA_PROVIDER(assist),
- suggestions, TRUE, NULL);
- g_list_foreach (suggestions, (GFunc) free_proposal, NULL);
- g_list_free (suggestions);
- }
- else
+ GList *node, *suggestions = NULL;
+
+ for (node = completion_list; node != NULL; node = g_list_next (node))
{
- ianjuta_editor_assist_proposals (assist->priv->iassist, IANJUTA_PROVIDER(assist),
- NULL, TRUE, NULL);
- return;
+ PythonAssistTag *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;
+ suggestions = g_list_prepend (suggestions, proposal);
}
+ suggestions = g_list_reverse (suggestions);
+ ianjuta_editor_assist_proposals (assist->priv->iassist, IANJUTA_PROVIDER(assist),
+ suggestions, TRUE, NULL);
+ g_list_foreach (suggestions, (GFunc) free_proposal, NULL);
+ g_list_free (suggestions);
}
/* Returns NULL if creation fails */
@@ -459,25 +408,75 @@ on_autocomplete_finished (AnjutaLauncher* launcher,
gulong time, gpointer user_data)
{
PythonAssist* assist = PYTHON_ASSIST (user_data);
- DEBUG_PRINT ("Python-Complete took %lu seconds", time);
- if (exit_status != 0)
- {
- python_assist_destroy_completion_cache (assist);
- return;
- }
- else
+ DEBUG_PRINT ("Python-Complete took %lu seconds and returned %d", time, exit_status);
+
+ g_object_unref (launcher);
+ assist->priv->launcher = NULL;
+
+ if (assist->priv->rope_cache)
{
- g_message ("PythonAssist: %s", assist->priv->rope_cache->str);
+ GStrv completions = g_strsplit (assist->priv->rope_cache->str, "\n", -1);
+ GStrv cur_comp;
+ GList* suggestions = NULL;
+ GError *err = NULL;
+ GRegex* regex = g_regex_new ("(\\w+) \\((\\w+), (\\w+)\\)",
+ 0, 0, &err);
+ if (err)
+ {
+ DEBUG_PRINT ("Error creating regex: %s", err->message);
+ g_error_free (err);
+ return;
+ }
+
+ /* Parse output and create completion list */
+ for (cur_comp = completions; *cur_comp != NULL; cur_comp++)
+ {
+ PythonAssistTag* tag;
+ GMatchInfo* match_info;
+
+ g_regex_match (regex, *cur_comp, 0, &match_info);
+ if (g_match_info_matches (match_info) &&
+ g_match_info_get_match_count (match_info) == 4)
+ {
+ gchar* type = g_match_info_fetch (match_info, 3);
+ tag = g_new0 (PythonAssistTag, 1);
+ tag->name = g_match_info_fetch (match_info, 1);
+
+ if (g_str_equal(type, "function") || g_str_equal (type, "builtin"))
+ {
+ tag->type = IANJUTA_SYMBOL_TYPE_FUNCTION;
+ tag->is_func = TRUE;
+ }
+ else
+ tag->type = IANJUTA_SYMBOL_TYPE_VARIABLE;
+ g_free (type);
+
+ if (!g_list_find_custom (suggestions, tag, completion_compare))
+ {
+ suggestions = g_list_prepend (suggestions, tag);
+ }
+ else
+ g_free (tag);
+ }
+ g_match_info_free (match_info);
+ }
+
+ g_regex_unref (regex);
+
+ assist->priv->completion_cache = g_completion_new (completion_function);
+ g_completion_add_items (assist->priv->completion_cache, suggestions);
+
+ g_strfreev (completions);
g_string_free (assist->priv->rope_cache, TRUE);
assist->priv->rope_cache = NULL;
+ g_list_free (suggestions);
+
+ /* Show autocompletion */
+ python_assist_update_autocomplete (assist);
}
}
-/* This needs to be ported to AnjutaLauncher and made asynchronous. Extra
- * points for avoiding the intermediate script and using the Python/C API
- */
-#define BUFFER_SIZE 1024
-gboolean // VERIFY CONTENTS
+static void
python_assist_create_word_completion_cache (PythonAssist *assist)
{
IAnjutaEditor *editor = IANJUTA_EDITOR (assist->priv->iassist);
@@ -487,7 +486,6 @@ python_assist_create_word_completion_cache (PythonAssist *assist)
gchar *interpreter_path;
gchar *ropecommand;
- GList *suggestions = NULL;
gchar *source = ianjuta_editor_get_text_all (editor, NULL);
gchar *tmp_file;
@@ -495,6 +493,7 @@ python_assist_create_word_completion_cache (PythonAssist *assist)
if (!project)
project = g_get_tmp_dir ();
+ /* Create rope command and temporary source file */
interpreter_path = anjuta_preferences_get (assist->priv->preferences,
PREF_INTERPRETER_PATH);
@@ -502,15 +501,15 @@ python_assist_create_word_completion_cache (PythonAssist *assist)
g_free (source);
if (!tmp_file)
- return FALSE;
+ return;
ropecommand = g_strdup_printf("%s %s -o autocomplete -p \"%s\" -r \"%s\" -s \"%s\" -f %d",
interpreter_path, AUTOCOMPLETE_SCRIPT, project,
cur_filename, tmp_file, offset);
g_free (tmp_file);
- DEBUG_PRINT ("%s\n", ropecommand);
+ /* Exec command and wait for results */
assist->priv->launcher = anjuta_launcher_new ();
g_signal_connect (assist->priv->launcher, "child-exited",
G_CALLBACK(on_autocomplete_finished), assist);
@@ -518,13 +517,9 @@ python_assist_create_word_completion_cache (PythonAssist *assist)
on_autocomplete_output,
assist);
g_free (ropecommand);
-
- assist->priv->completion_cache = g_completion_new (completion_function);
- g_completion_add_items (assist->priv->completion_cache, suggestions);
+
assist->priv->cache_position = offset;
assist->priv->search_cache = g_strdup (assist->priv->pre_word);
-
- return TRUE;
}
@@ -604,7 +599,7 @@ python_assist_create_rope_calltips (PythonAssist *assist, IAnjutaIterable* iter)
const gchar *project = assist->priv->project_root;
gchar *tmp_file;
gchar *ropecommand;
- gchar calltip[BUFFER_SIZE];
+ gchar calltip[1024];
int counter = 0;
FILE *rope;
@@ -630,7 +625,7 @@ python_assist_create_rope_calltips (PythonAssist *assist, IAnjutaIterable* iter)
g_free (tmp_file);
rope = popen (ropecommand, "r");
- while (fgets(calltip, BUFFER_SIZE, rope) != NULL)
+ while (fgets(calltip, 1024, rope) != NULL)
{
calltip[strlen(calltip)-1] = '\0';
tips = g_list_append (tips, g_strdup(calltip));
@@ -864,8 +859,7 @@ python_assist_populate (IAnjutaProvider* self, IAnjutaIterable* iter, GError** e
}
/* Normal autocompletion */
- /* Moved iter to begin of word */
- DEBUG_PRINT ("NORMAL\n");
+ /* Moved iter to begin of word */
assist->priv->pre_word = python_assist_get_pre_word (editor, iter);
DEBUG_PRINT ("Pre word: %s\n", assist->priv->pre_word);
@@ -909,8 +903,6 @@ python_assist_activate (IAnjutaProvider* self, IAnjutaIterable* iter, gpointer d
gboolean add_space_after_func = FALSE;
gboolean add_brace_after_func = FALSE;
- DEBUG_PRINT ("assist-chosen: \n");
-
tag = data;
assistance = g_string_new (tag->name);
@@ -1060,7 +1052,6 @@ python_assist_new (IAnjutaEditorAssist *iassist,
assist->priv->project_root = project_root;
assist->priv->editor=(IAnjutaEditor*)iassist;
python_assist_install (assist, IANJUTA_EDITOR (iassist));
- DEBUG_PRINT("New done\n");
return assist;
}
diff --git a/plugins/language-support-python/python-assist.h b/plugins/language-support-python/python-assist.h
index bd84b7d..397690a 100644
--- a/plugins/language-support-python/python-assist.h
+++ b/plugins/language-support-python/python-assist.h
@@ -71,16 +71,6 @@ PythonAssist *python_assist_new (IAnjutaEditorAssist *assist,
const gchar *editor_filename,
const gchar *project_root);
-
-void python_assist_check (PythonAssist *assist, gboolean autocomplete,
- gboolean calltips, gboolean backspace);
-gboolean
-python_assist_create_word_completion_cache (PythonAssist *assist);
-
-void
-python_assist_update_autocomplete (PythonAssist *assist);
-
-
G_END_DECLS
#endif /* _PYTHON_ASSIST_H_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]