[anjuta/new-assistance: 1/3] sourceview, cpp-java-assist: started porting to new GtkSourceCompletion API



commit 86519bde1e066eaebe1abc5db1f37a56e12fa343
Author: Johannes Schmid <jhs gnome org>
Date:   Tue Nov 17 21:32:04 2009 +0100

    sourceview, cpp-java-assist: started porting to new GtkSourceCompletion API

 libanjuta/interfaces/libanjuta.idl                 |  193 +++++++++++-----
 .../language-support-cpp-java/cpp-java-assist.c    |  154 ++++++-------
 plugins/language-support-cpp-java/plugin.c         |    1 +
 plugins/sourceview/Makefile.am                     |    6 +-
 plugins/sourceview/anjuta-editor-sourceview.ui     |   59 +++--
 plugins/sourceview/anjuta-view.c                   |   19 --
 plugins/sourceview/sourceview-cell.c               |   55 ++---
 plugins/sourceview/sourceview-prefs.c              |   46 ++++-
 plugins/sourceview/sourceview-private.h            |    1 -
 plugins/sourceview/sourceview-provider.c           |  132 +++++++++++
 plugins/sourceview/sourceview-provider.h           |   59 +++++
 plugins/sourceview/sourceview.c                    |  244 ++++++++++----------
 12 files changed, 618 insertions(+), 351 deletions(-)
---
diff --git a/libanjuta/interfaces/libanjuta.idl b/libanjuta/interfaces/libanjuta.idl
index d64c03d..c223766 100644
--- a/libanjuta/interfaces/libanjuta.idl
+++ b/libanjuta/interfaces/libanjuta.idl
@@ -1931,45 +1931,10 @@ interface IAnjutaEditor
 	 * @include: libanjuta/interfaces/ianjuta-editor-assist.h
 	 * 
 	 */
-	interface IAnjutaEditorAssist
+	interface IAnjutaEditorTip
 	{
-		/* IAnjutaEdiotrAssist::assist_chosen:
-		 * @obj: self
-		 * @selection: The selection index
-		 * @err: Error propagation and reporting
-		 *
-		 * User's selection from the choices. It is the index of the choice
-		 * presented with ianjuta_editor_assist_suggest().
-		 */
-		void ::assist_chosen (gint selection);
-		
-		/**
-		 * ianjuta_editor_assist_suggest:
-		 * @obj: Self
-		 * @choices: list of choices.
- 		 * @char_alignment: Character alignment.
-		 * @err: Error propagation and reporting
-		 * 
-		 * Suggest a list of choices to the user. The suggestions are viewed 
-		 * at char_alignment which should be the beginning of the completed word.
-		 * If choices is NULL, and assist_end signal
-		 * will occur
-		 *
-		 */
-		void suggest (List<const gchar*> choices, IAnjutaIterable *position, int char_alignment);
-		
-		/**
-		 * ianjuta_editor_assist_hide_suggestions:
-		 * @obj: Self
-		 * @err: Error propagation and reporting
-		 *
-		 * Hide current suggestions but do not emit assist_end signal.
-		 * This is useful when temporary waiting for more context
-		 */
-		void hide_suggestions ();
-		
 		/**
-		 * ianjuta_editor_assist_tip:
+		 * ianjuta_editor_tip_show:
 		 * @obj: Self
 		 * @tips: list of alternative tips.
 		 * @char_alignment: Character alignment.
@@ -1983,42 +1948,93 @@ interface IAnjutaEditor
 		 * position when the choices are displayed.
 		 *
 		 */
-		void show_tips (List<const gchar*> tips, IAnjutaIterable *position, gint char_alignment);
+		void show (List<const gchar*> tips, IAnjutaIterable *position, gint char_alignment);
 		
 		/**
-		 * ianjuta_editor_assist_cancel_tip:
+		 * ianjuta_editor_tip_cancel
 		 * @obj: Self
 		 * @err: Error propagation and reporting
 		 *
 		 * Cancels the last shown tooltip
 		 */
-		void cancel_tips ();
+		void cancel ();
 		
 		/**
-		 * ianjuta_editor_assist_tip_shown:
+		 * ianjuta_editor_tip_visible:
 		 * @obj: Self
 		 * @err: Error propagation and reporting
 		 * 
 		 * Returns: whether a tooltip is crrently shown		
 		 */
-		gboolean tip_shown();
-		
-		/**
-		 * ianjuta_editor_assist_get_suggestions:
-		 * @obj: Self
-		 * @context: The context for the suggestions.
-		 * @err: Error propagation and reporting
-		 *
-		 * Usually the editor might have some suggestions to make
-		 * for a context. For example in a simple word completion context.
-		 * The list of suggestion returned is allocated dynamically. The whole
-		 * list, including the the strings should be freed when done.
-		 * If the editor has no suggestions to make, it returns NULL.
-		 * 
-		 * Returns: A list of dynamically allocated strings for the given context or NULL
-		 * if there is nothing to suggest.
-		 */
-		List<const gchar*> get_suggestions (const gchar *context);
+		gboolean visible();
+	}
+
+  /**
+	 * SECTION:ianjuta-editor-assist
+	 * @title: IAnjutaEditorAssist
+	 * @short_description: Text editor assist interface
+	 * @see_also: 
+	 * @stability: Unstable
+	 * @include: libanjuta/interfaces/ianjuta-editor-assist
+	 * 
+	 */
+  interface IAnjutaEditorAssist
+	{
+     #include <libanjuta/interfaces/ianjuta-provider.h>
+     
+     struct Proposal
+     {
+        gchar* label;
+        gchar* markup;
+        gchar* info;
+        gchar* text;
+        GdkPixbuf* icon;
+        gpointer data;
+     }
+     
+     /*
+      * ianjuta_editor_assist_add
+      * @obj: self
+      * @provider: a IAnjutaProvider
+      * @err: Error handling
+      *
+      * Add a provider to the list of completion providers
+      */
+      void add(IAnjutaProvider* provider);
+
+     /*
+      * ianjuta_editor_assist_remove
+      * @obj: self
+      * @provider: a IAnjutaProvider
+      * @err: Error handling
+      *
+      * Remove a provider from the list of completion providers
+      */
+      void remove(IAnjutaProvider* provider);
+      
+     /*
+      * ianjuta_editor_assist_invoke
+      * @obj: self
+      * @provider: a IAnjutaProvider
+      * @err: Error handling
+      *
+      * Force invokation of a provider at the current cursor position
+      */
+      void invoke(IAnjutaProvider* provider);
+      
+     /*
+      * ianjuta_editor_assist_proposals
+      * @obj: self
+      * @provider: a IAnjutaProvider
+      * @proposals: a list of IAnjutaProposals
+      * @finished: whether is was the last call in an async operation
+      * @err: Error handling
+      *
+      * Add the list of proposals for the current population. You can add
+      * proposals async as long as the last call sets finished to TRUE.
+      *
+      */
+      void proposals(IAnjutaProvider* provider, GList* proposals. gboolean finished);
 	}
 	
 	/**
@@ -2034,7 +2050,7 @@ interface IAnjutaEditor
 	{
 	  #include <libanjuta/interfaces/ianjuta-iterable.h>
 	  
-	  /* IAnjutaEditorAssist::hover-over:
+	  /* IAnjutaEditorHover::hover-over:
 		 * @obj: self
 		 * @position: IAnjutaEditorCell specifying the position the mouse is over
 		 *
@@ -2043,7 +2059,7 @@ interface IAnjutaEditor
 		 */
 		void ::hover_over (GObject* position);
 
-	  /* IAnjutaEditorAssist::hover-leave
+	  /* IAnjutaEditorHover::hover-leave
 		 * @obj: self
 		 * @position: IAnjutaEditorCell specifying the position the mouse was over
 		 *
@@ -2441,6 +2457,61 @@ interface IAnjutaEditorFactory
 }
 
 /**
+ * SECTION:ianjuta-provider
+ * @title: IAnjutaProvider
+ * @short_description: Provider for autocompletion features
+ * @see_also: 
+ * @stability: Unstable
+ * @include: libanjuta/interfaces/ianjuta-provider.h
+ */
+interface IAnjutaProvider
+{
+  #include "ianjuta-iterable.h"
+  
+ /**
+	* ianjuta_provider_populate
+	* @obj: Self
+	* @iter: the text iter where the provider should be populated
+	* @err: Error propagation and reporting.
+	* 
+ 	* Show completion for the context at position @iter
+	*/
+  void populate(IAnjutaIterable* iter);
+  
+ /**
+	* ianjuta_provider_get_start_iter
+	* @obj: Self
+	* @err: Error propagation and reporting.
+	* 
+ 	* Get the iter where the current completion started
+ 	*
+ 	* Returns: current start iter
+	*/
+  IAnjutaIterable* get_start_iter();
+ 
+ /**
+	* ianjuta_provider_activate
+	* @obj: Self
+	* @iter: position where the completion occurs
+	* @data: data assigned to the proposal
+	* @err: Error propagation and reporting.
+	* 
+ 	* Show completion for the context at position @iter
+	*/
+  void activate(IAnjutaIterable* iter, gpointer data);
+
+ /**
+	* ianjuta_provider_cancelled
+	* @obj: Self
+	* @err: Error propagation and reporting.
+	* 
+ 	* Called when the current completion was cancelled
+	*/
+  void cancelled();
+
+}
+
+/**
  * SECTION:ianjuta-document-manager
  * @title: IAnjutaDocumentManager
  * @short_description: Interface for plugin that manages all the editors
diff --git a/plugins/language-support-cpp-java/cpp-java-assist.c b/plugins/language-support-cpp-java/cpp-java-assist.c
index 3ac66ae..c8ff939 100644
--- a/plugins/language-support-cpp-java/cpp-java-assist.c
+++ b/plugins/language-support-cpp-java/cpp-java-assist.c
@@ -42,7 +42,13 @@
 #define MAX_COMPLETIONS 10
 #define BRACE_SEARCH_LIMIT 500
 
-G_DEFINE_TYPE (CppJavaAssist, cpp_java_assist, G_TYPE_OBJECT);
+static void cpp_java_assist_iface_init(IAnjutaProviderIface* iface);
+
+G_DEFINE_TYPE_WITH_CODE (CppJavaAssist,
+			 cpp_java_assist,
+			 G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (IANJUTA_TYPE_PROVIDER,
+			                        cpp_java_assist_iface_init))
 
 typedef struct
 {
@@ -65,6 +71,7 @@ struct _CppJavaAssistPriv {
 	GCompletion *completion_cache;
 	gboolean editor_only;
 	guint word_idle;
+	IAnjutaIterable* start_iter;
 };
 
 static gchar*
@@ -120,6 +127,12 @@ is_word_character (gchar ch)
 	return FALSE;
 }	
 
+static void
+on_search_complete (gint search_id, IAnjutaIterable* iter, CppJavaAssist* assist)
+{
+
+}
+
 /**
  * If mergeable is NULL than no merge will be made with iter elements, elsewhere
  * mergeable will be returned with iter elements.
@@ -364,7 +377,7 @@ cpp_java_assist_show_autocomplete (CppJavaAssist *assist)
 	return FALSE;
 }
 
-static gboolean
+static void
 cpp_java_assist_create_word_completion_cache (CppJavaAssist *assist)
 {
 	gint max_completions;
@@ -644,50 +657,19 @@ cpp_java_assist_show_calltip (CppJavaAssist *assist, gchar *call_context,
 }
 
 void
-cpp_java_assist_check (CppJavaAssist *assist, gboolean autocomplete,
-					   gboolean calltips, gboolean backspace)
+cpp_java_assist_check (CppJavaAssist *assist
+					             gboolean calltips, gboolean backspace)
 {
 	IAnjutaEditor *editor;
 	IAnjutaIterable *iter;
 	
-	if (!autocomplete && !calltips)
+	if (!calltips)
 		return; /* Nothing to do */
 	
 	editor = IANJUTA_EDITOR (assist->priv->iassist);
 	
 	iter = ianjuta_editor_get_position (editor, NULL);
 	ianjuta_iterable_previous (iter, NULL);
-
-	if (autocomplete)
-	{
-		gboolean shown = FALSE;
-		g_free (assist->priv->pre_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 (!backspace)
-				{
-					g_idle_add_full (G_PRIORITY_LOW,
-					                 (GSourceFunc) cpp_java_assist_create_word_completion_cache,
-					                 assist,
-					                 NULL);
-					DEBUG_PRINT ("Idle source added");
-				}
-			}
-			shown = cpp_java_assist_show_autocomplete (assist);
-		}
-		else
-			shown = FALSE;
-		if (!shown)
-			ianjuta_editor_assist_hide_suggestions (assist->priv->iassist,
-			                                        NULL);
-		DEBUG_PRINT ("Show autocomplete: %d", shown);
-	}
 	if (calltips)
 	{
 		gchar *call_context =
@@ -728,28 +710,47 @@ static void
 on_editor_char_added (IAnjutaEditor *editor, IAnjutaIterable *insert_pos,
 					  gchar ch, CppJavaAssist *assist)
 {
-	gboolean enable_complete =
-		anjuta_preferences_get_bool_with_default (assist->priv->preferences,
-												 PREF_AUTOCOMPLETE_ENABLE,
-												 TRUE);
-	
 	gboolean enable_calltips =
 		anjuta_preferences_get_bool_with_default (assist->priv->preferences,
 												 PREF_CALLTIP_ENABLE,
 												 TRUE);
-	cpp_java_assist_check (assist, enable_complete, enable_calltips, ch == '\b');
+	cpp_java_assist_check (assist, enable_calltips, (ch == '\b'));
 }
 
 static void
-on_editor_backspace (IAnjutaEditor* editor, CppJavaAssist* assist)
+cpp_java_assist_populate (IAnjutaProvider* self, IAnjutaIterable* iter, GError** e)
 {
-	on_editor_char_added (editor, NULL, '\b', assist);
-}
+	CppJavaAssist* assist = CPP_JAVA_ASSIST (self);
+	IAnjutaEditor *editor;
+	gboolean autocomplete = anjuta_preferences_get_bool_with_default (assist->priv->prefs,
+	                                                                  AUTOCOMPLETE_ENABLE,
+	                                                                  TRUE);	
+	editor = IANJUTA_EDITOR (assist->priv->iassist);
+	
+	if (autocomplete)
+	{
+		gboolean shown = FALSE;
+		g_free (assist->priv->pre_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))
+			{
+					cpp_java_assist_create_word_completion_cache(assist);
+			}
+			else
+				shown = cpp_java_assist_update_autocomplete (assist);
+		}
+	}
+} 
 
 static void
-on_assist_chosen (IAnjutaEditorAssist* iassist, gint selection,
-				  CppJavaAssist* assist)
+cpp_java_assist_activate (IAnjutaProvider* self, IAnjutaIterable* cursor, gpointer data);
 {
+	CppJavaAssist assist = CPP_JAVA_ASSIST(self);
 	CppJavaAssistTag *tag;
 	IAnjutaIterable *cur_pos;
 	GString *assistance;
@@ -761,13 +762,7 @@ on_assist_chosen (IAnjutaEditorAssist* iassist, gint selection,
 	
 	//DEBUG_PRINT ("assist-chosen: %d", selection);
 	
-	if (assist->priv->completion_cache->cache)
-		tag = g_list_nth_data (assist->priv->completion_cache->cache,
-							   selection);
-	else
-		tag = g_list_nth_data (assist->priv->completion_cache->items,
-							   selection);
-	
+	tag = data;	
 	assistance = g_string_new (tag->name);
 	
 	if (tag->is_func)
@@ -788,38 +783,27 @@ on_assist_chosen (IAnjutaEditorAssist* iassist, gint selection,
 	}
 	
 	te = IANJUTA_EDITOR (assist->priv->iassist);
-	cur_pos = ianjuta_editor_get_position (te, NULL);
-	iter = ianjuta_iterable_clone (cur_pos, NULL);
-	
-	if (ianjuta_iterable_previous (iter, NULL))
-	{
-		pre_word = cpp_java_assist_get_pre_word (te, iter);
-	}
-	
+		
 	ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (te), NULL);
-	if (pre_word)
+	
+	if (ianjuta_iterable_compare(iter, assist->priv->start_iter) != 0)
 	{
-		ianjuta_iterable_next (iter, NULL);
 		ianjuta_editor_selection_set (IANJUTA_EDITOR_SELECTION (te),
-									  iter, cur_pos, FALSE, NULL);
+									  assist->priv->start_iter, iter, FALSE, NULL);
 		ianjuta_editor_selection_replace (IANJUTA_EDITOR_SELECTION (te),
 										  assistance->str, -1, NULL);
-		g_free (pre_word);
 	}
 	else
 	{
-		ianjuta_editor_insert (te, cur_pos, assistance->str, -1, NULL);
+		ianjuta_editor_insert (te, iter, assistance->str, NULL);
 	}
-	g_object_unref (iter);
-	g_object_unref (cur_pos);
-
+	g_object_unref (assist->priv->start_iter);
+	assist->priv->start_iter = NULL;
 	ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (te), NULL);
 	
-	ianjuta_editor_assist_hide_suggestions (assist->priv->iassist, NULL);
-	
 	/* Show calltip if we completed function */
 	if (add_brace_after_func)
-		cpp_java_assist_check (assist, FALSE, TRUE, FALSE);
+		cpp_java_assist_check (assist, TRUE, FALSE);
 	
 	g_string_free (assistance, TRUE);
 }
@@ -829,27 +813,15 @@ cpp_java_assist_install (CppJavaAssist *assist, IAnjutaEditorAssist *iassist)
 {
 	g_return_if_fail (assist->priv->iassist == NULL);
 	
-	assist->priv->iassist = iassist;
-	g_signal_connect (iassist, "char-added",
-					  G_CALLBACK (on_editor_char_added), assist);
-	g_signal_connect (iassist, "backspace",
-					  G_CALLBACK (on_editor_backspace), assist);
-	g_signal_connect (iassist, "assist-chosen",
-					  G_CALLBACK(on_assist_chosen), assist);
+	ianjuta_editor_assist_add (iassist, IANJUTA_PROVIDER(assist));
 }
 
 static void
 cpp_java_assist_uninstall (CppJavaAssist *assist)
 {
 	g_return_if_fail (assist->priv->iassist != NULL);
-	g_signal_handlers_disconnect_by_func (assist->priv->iassist,
-										  G_CALLBACK(on_assist_chosen), assist);
-	g_signal_handlers_disconnect_by_func (assist->priv->iassist,
-										  G_CALLBACK (on_editor_char_added),
-										  assist);
- g_signal_handlers_disconnect_by_func (assist->priv->iassist,
 
-  G_CALLBACK (on_editor_backspace), assist);
+	ianjuta_editor_assist_remove (assist->priv->iassist, IANJUTA_PROVIDER(assist));
 
 	assist->priv->iassist = NULL;
 }
@@ -894,3 +866,11 @@ cpp_java_assist_new (IAnjutaEditorAssist *iassist,
 	cpp_java_assist_install (assist, iassist);
 	return assist;
 }
+
+static void cpp_java_assist_iface_init(IAnjutaProviderIface* iface)
+{
+	iface->populate = cpp_java_assist_populate;
+	iface->get_start_iter = cpp_java_assist_get_start_iter;
+	iface->activate = cpp_java_assist_activate;
+	iface->cancelled = cpp_java_assist_cancelled;
+}
diff --git a/plugins/language-support-cpp-java/plugin.c b/plugins/language-support-cpp-java/plugin.c
index 9fd804f..51bf87f 100644
--- a/plugins/language-support-cpp-java/plugin.c
+++ b/plugins/language-support-cpp-java/plugin.c
@@ -32,6 +32,7 @@
 #include <libanjuta/interfaces/ianjuta-editor-language.h>
 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
 #include <libanjuta/interfaces/ianjuta-editor-assist.h>
+#include <libanjuta/interfaces/ianjuta-editor-tip.h>
 #include <libanjuta/interfaces/ianjuta-preferences.h>
 #include <libanjuta/interfaces/ianjuta-symbol.h>
 #include <libanjuta/interfaces/ianjuta-language.h>
diff --git a/plugins/sourceview/Makefile.am b/plugins/sourceview/Makefile.am
index d9b524a..3221d0c 100644
--- a/plugins/sourceview/Makefile.am
+++ b/plugins/sourceview/Makefile.am
@@ -53,8 +53,6 @@ libanjuta_sourceview_la_SOURCES = \
 	plugin.h \
 	sourceview.c \
 	sourceview.h \
-	assist-window.h \
-	assist-window.c \
 	anjuta-view.h \
 	anjuta-view.c \
 	sourceview-prefs.h \
@@ -67,7 +65,9 @@ libanjuta_sourceview_la_SOURCES = \
 	assist-tip.h \
 	assist-tip.c \
 	sourceview-io.h \
-	sourceview-io.c
+	sourceview-io.c \
+	sourceview-provider.h \
+	sourceview-provider.c
 
 libanjuta_sourceview_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
 
diff --git a/plugins/sourceview/anjuta-editor-sourceview.ui b/plugins/sourceview/anjuta-editor-sourceview.ui
index 7c3f022..508c00b 100644
--- a/plugins/sourceview/anjuta-editor-sourceview.ui
+++ b/plugins/sourceview/anjuta-editor-sourceview.ui
@@ -1,23 +1,20 @@
 <?xml version="1.0"?>
 <interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkAdjustment" id="adjustment1">
-    <property name="upper">100</property>
+    <property name="value">4</property>
     <property name="lower">1</property>
-    <property name="page_increment">10</property>
+    <property name="upper">100</property>
     <property name="step_increment">1</property>
-    <property name="page_size">0</property>
-    <property name="value">4</property>
+    <property name="page_increment">10</property>
   </object>
   <object class="GtkAdjustment" id="adjustment2">
+    <property name="value">80</property>
     <property name="upper">200</property>
-    <property name="lower">0</property>
-    <property name="page_increment">10</property>
     <property name="step_increment">1</property>
-    <property name="page_size">0</property>
-    <property name="value">80</property>
+    <property name="page_increment">10</property>
   </object>
-  <!-- interface-requires gtk+ 2.16 -->
-  <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkWindow" id="preferences_dialog">
     <property name="title">window1</property>
     <child>
@@ -73,8 +70,8 @@
                           <packing>
                             <property name="left_attach">3</property>
                             <property name="right_attach">4</property>
-                            <property name="x_options"/>
-                            <property name="y_options"/>
+                            <property name="x_options"></property>
+                            <property name="y_options"></property>
                           </packing>
                         </child>
                         <child>
@@ -221,7 +218,19 @@
                               </packing>
                             </child>
                             <child>
-                              <placeholder/>
+                              <object class="GtkCheckButton" id="preferences_toggle:bool:1:0:sourceview.autocomplete">
+                                <property name="label" translatable="yes">Enable autocompletion</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">3</property>
+                              </packing>
                             </child>
                             <child>
                               <placeholder/>
@@ -343,7 +352,7 @@
                                     <property name="left_attach">1</property>
                                     <property name="right_attach">2</property>
                                     <property name="x_options">GTK_FILL</property>
-                                    <property name="y_options"/>
+                                    <property name="y_options"></property>
                                   </packing>
                                 </child>
                                 <child>
@@ -356,7 +365,7 @@
                                   </object>
                                   <packing>
                                     <property name="x_options">GTK_FILL</property>
-                                    <property name="y_options"/>
+                                    <property name="y_options"></property>
                                   </packing>
                                 </child>
                                 <child>
@@ -446,7 +455,7 @@
                             <property name="right_attach">2</property>
                             <property name="top_attach">1</property>
                             <property name="bottom_attach">2</property>
-                            <property name="y_options"/>
+                            <property name="y_options"></property>
                           </packing>
                         </child>
                         <child>
@@ -461,7 +470,7 @@
                           <packing>
                             <property name="right_attach">2</property>
                             <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"/>
+                            <property name="y_options"></property>
                           </packing>
                         </child>
                       </object>
@@ -537,6 +546,9 @@
               </packing>
             </child>
           </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
         </child>
         <child type="tab">
           <object class="GtkLabel" id="label12360">
@@ -577,7 +589,7 @@
                     <property name="top_attach">1</property>
                     <property name="bottom_attach">2</property>
                     <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"/>
+                    <property name="y_options"></property>
                   </packing>
                 </child>
                 <child>
@@ -591,7 +603,7 @@
                   </object>
                   <packing>
                     <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"/>
+                    <property name="y_options"></property>
                   </packing>
                 </child>
                 <child>
@@ -607,7 +619,7 @@
                     <property name="top_attach">2</property>
                     <property name="bottom_attach">3</property>
                     <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"/>
+                    <property name="y_options"></property>
                   </packing>
                 </child>
                 <child>
@@ -623,7 +635,7 @@
                     <property name="top_attach">3</property>
                     <property name="bottom_attach">4</property>
                     <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"/>
+                    <property name="y_options"></property>
                   </packing>
                 </child>
                 <child>
@@ -639,7 +651,7 @@
                     <property name="top_attach">4</property>
                     <property name="bottom_attach">5</property>
                     <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"/>
+                    <property name="y_options"></property>
                   </packing>
                 </child>
                 <child>
@@ -659,6 +671,9 @@
               </object>
             </child>
           </object>
+          <packing>
+            <property name="position">2</property>
+          </packing>
         </child>
         <child type="tab">
           <object class="GtkLabel" id="label12352">
diff --git a/plugins/sourceview/anjuta-view.c b/plugins/sourceview/anjuta-view.c
index e0e91c7..df19893 100644
--- a/plugins/sourceview/anjuta-view.c
+++ b/plugins/sourceview/anjuta-view.c
@@ -439,12 +439,8 @@ static gint
 anjuta_view_focus_out (GtkWidget *widget, GdkEventFocus *event)
 {
 	AnjutaView *view = ANJUTA_VIEW (widget);
-	AssistWindow* assist_win = view->priv->sv->priv->assist_win;
 	AssistTip* assist_tip = view->priv->sv->priv->assist_tip;
 	
-	if (assist_win)
-		gtk_widget_destroy(GTK_WIDGET(assist_win));
-	
 	if (assist_tip)
 		gtk_widget_destroy(GTK_WIDGET(assist_tip));
 	
@@ -675,20 +671,10 @@ anjuta_view_key_press_event		(GtkWidget *widget, GdkEventKey       *event)
 {
 	GtkTextBuffer *buffer;
 	AnjutaView* view = ANJUTA_VIEW(widget);
-	AssistWindow* assist_win;
 	AssistTip* assist_tip;
 	
 	buffer  = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
 	
-	assist_win = view->priv->sv->priv->assist_win;
-	if (assist_win)
-	{
-		if (assist_window_filter_keypress(assist_win, event->keyval))
-		{
-			DEBUG_PRINT("key filtered: %d", event->keyval);
-			return TRUE;
-		}
-	}
 	assist_tip = view->priv->sv->priv->assist_tip;
 	if (assist_tip)
 	{
@@ -713,11 +699,6 @@ anjuta_view_button_press_event	(GtkWidget *widget, GdkEventButton *event)
 	
   /* If we have a calltip shown - hide it */
   AssistTip* assist_tip = view->priv->sv->priv->assist_tip;
-  AssistWindow* assist_win = view->priv->sv->priv->assist_win;
-  if (assist_win)
-  {
-    gtk_widget_destroy (GTK_WIDGET (assist_win));
-  }
 	if (assist_tip)
 	{
     gtk_widget_destroy (GTK_WIDGET (assist_tip));
diff --git a/plugins/sourceview/sourceview-cell.c b/plugins/sourceview/sourceview-cell.c
index 85d22d7..3fda48a 100644
--- a/plugins/sourceview/sourceview-cell.c
+++ b/plugins/sourceview/sourceview-cell.c
@@ -38,7 +38,7 @@ static void sourceview_cell_instance_init(SourceviewCell *sp);
 static void sourceview_cell_finalize(GObject *object);
 
 struct _SourceviewCellPrivate {
-	GtkTextIter* iter;
+	GtkTextIter iter;
 	GtkTextView* view;
 	GtkTextBuffer* buffer;
 };
@@ -69,8 +69,6 @@ sourceview_cell_finalize(GObject *object)
 	SourceviewCell *cobj;
 	cobj = SOURCEVIEW_CELL(object);
 	
-	gtk_text_iter_free(cobj->priv->iter);
-	
 	g_slice_free(SourceviewCellPrivate, cobj->priv);
 	G_OBJECT_CLASS(sourceview_cell_parent_class)->finalize(object);
 }
@@ -83,7 +81,7 @@ sourceview_cell_new(GtkTextIter* iter, GtkTextView* view)
 	obj = SOURCEVIEW_CELL(g_object_new(SOURCEVIEW_TYPE_CELL, NULL));
 	
 	obj->priv->buffer = gtk_text_view_get_buffer(view);
-	obj->priv->iter = gtk_text_iter_copy (iter);
+	obj->priv->iter = *iter;
 	obj->priv->view = view;
 	
 	return obj;
@@ -92,14 +90,14 @@ sourceview_cell_new(GtkTextIter* iter, GtkTextView* view)
 GtkTextIter*
 sourceview_cell_get_iter (SourceviewCell* cell)
 {
-	return cell->priv->iter;
+	return &cell->priv->iter;
 }
 
 static gchar*
 icell_get_character(IAnjutaEditorCell* icell, GError** e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(icell);
-	gunichar c = gtk_text_iter_get_char (cell->priv->iter);
+	gunichar c = gtk_text_iter_get_char (&cell->priv->iter);
 	gchar* outbuf = g_new0(gchar, 6);
 	g_unichar_to_utf8 (c, outbuf);
 	return outbuf;
@@ -120,7 +118,7 @@ static gchar
 icell_get_char(IAnjutaEditorCell* icell, gint index, GError** e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(icell);
-	gunichar c = gtk_text_iter_get_char (cell->priv->iter);
+	gunichar c = gtk_text_iter_get_char (&cell->priv->iter);
 	gchar* outbuf = g_new0(gchar, 6);
 	gint len = g_unichar_to_utf8 (c, outbuf);
 	gchar retval;
@@ -161,7 +159,7 @@ icell_style_get_font_description(IAnjutaEditorCellStyle* icell_style, GError **
 {
 	const gchar* font;
 	SourceviewCell* cell = SOURCEVIEW_CELL(icell_style);
-	GtkTextAttributes* atts = get_attributes(cell->priv->iter, 
+	GtkTextAttributes* atts = get_attributes(&cell->priv->iter, 
 																					 cell->priv->view);
 	font = pango_font_description_to_string(atts->font);
 	g_free(atts);
@@ -173,7 +171,7 @@ icell_style_get_color(IAnjutaEditorCellStyle* icell_style, GError ** e)
 {
 	gchar* color;
 	SourceviewCell* cell = SOURCEVIEW_CELL(icell_style);
-	GtkTextAttributes* atts = get_attributes(cell->priv->iter, cell->priv->view);
+	GtkTextAttributes* atts = get_attributes(&cell->priv->iter, cell->priv->view);
 	color = anjuta_util_string_from_color(atts->appearance.fg_color.red,
 																				atts->appearance.fg_color.green, atts->appearance.fg_color.blue);
 	g_free(atts);
@@ -185,7 +183,7 @@ icell_style_get_background_color(IAnjutaEditorCellStyle* icell_style, GError **
 {
 	gchar* color;
 	SourceviewCell* cell = SOURCEVIEW_CELL(icell_style);
-	GtkTextAttributes* atts = get_attributes(cell->priv->iter, cell->priv->view);
+	GtkTextAttributes* atts = get_attributes(&cell->priv->iter, cell->priv->view);
 	color = anjuta_util_string_from_color(atts->appearance.bg_color.red,
 																				atts->appearance.bg_color.green, atts->appearance.bg_color.blue);
 	g_free(atts);
@@ -204,9 +202,9 @@ static gboolean
 iiter_first(IAnjutaIterable* iter, GError** e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
-	gboolean retval = gtk_text_iter_is_start (cell->priv->iter);
+	gboolean retval = gtk_text_iter_is_start (&cell->priv->iter);
 	if (!retval)
-		gtk_text_iter_set_offset (cell->priv->iter, 0);
+		gtk_text_iter_set_offset (&cell->priv->iter, 0);
 	return retval;
 }
 
@@ -215,7 +213,7 @@ iiter_next(IAnjutaIterable* iter, GError** e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
 	
-	return gtk_text_iter_forward_char(cell->priv->iter);
+	return gtk_text_iter_forward_char(&cell->priv->iter);
 }
 
 static gboolean
@@ -223,16 +221,16 @@ iiter_previous(IAnjutaIterable* iter, GError** e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
 	
-	return gtk_text_iter_backward_char(cell->priv->iter);
+	return gtk_text_iter_backward_char(&cell->priv->iter);
 }
 
 static gboolean
 iiter_last(IAnjutaIterable* iter, GError** e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
-	gboolean retval = gtk_text_iter_is_end (cell->priv->iter);
+	gboolean retval = gtk_text_iter_is_end (&cell->priv->iter);
 	if (retval)
-		gtk_text_iter_forward_to_end(cell->priv->iter);
+		gtk_text_iter_forward_to_end(&cell->priv->iter);
 	return retval;
 }
 
@@ -243,13 +241,13 @@ iiter_foreach(IAnjutaIterable* iter, GFunc callback, gpointer data, GError** e)
 	
 	gint saved_offset;
 	
-	saved_offset = gtk_text_iter_get_offset (cell->priv->iter);
-	gtk_text_iter_set_offset(cell->priv->iter, 0);
-	while (gtk_text_iter_forward_char(cell->priv->iter))
+	saved_offset = gtk_text_iter_get_offset (&cell->priv->iter);
+	gtk_text_iter_set_offset(&cell->priv->iter, 0);
+	while (gtk_text_iter_forward_char(&cell->priv->iter))
 	{
 		(*callback)(cell, data);
 	}
-	gtk_text_iter_set_offset(cell->priv->iter, saved_offset);
+	gtk_text_iter_set_offset(&cell->priv->iter, saved_offset);
 }
 
 static gboolean
@@ -257,7 +255,7 @@ iiter_set_position (IAnjutaIterable* iter, gint position, GError** e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
 	
-	gtk_text_iter_set_offset (cell->priv->iter, position);
+	gtk_text_iter_set_offset (&cell->priv->iter, position);
 	return TRUE;
 }
 
@@ -265,7 +263,7 @@ static gint
 iiter_get_position(IAnjutaIterable* iter, GError** e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
-	return gtk_text_iter_get_offset(cell->priv->iter);
+	return gtk_text_iter_get_offset(&cell->priv->iter);
 }
 
 static gint
@@ -273,7 +271,7 @@ iiter_get_length(IAnjutaIterable* iter, GError** e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
 	
-	return gtk_text_buffer_get_char_count (gtk_text_iter_get_buffer(cell->priv->iter));
+	return gtk_text_buffer_get_char_count (gtk_text_iter_get_buffer(&cell->priv->iter));
 }
 
 static IAnjutaIterable *
@@ -281,7 +279,7 @@ iiter_clone (IAnjutaIterable *iter, GError **e)
 {
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
 	
-	return IANJUTA_ITERABLE (sourceview_cell_new (cell->priv->iter, cell->priv->view));
+	return IANJUTA_ITERABLE (sourceview_cell_new (&cell->priv->iter, cell->priv->view));
 }
 
 static void
@@ -290,8 +288,7 @@ iiter_assign (IAnjutaIterable *iter, IAnjutaIterable *src_iter, GError **e)
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
 	SourceviewCell* src_cell = SOURCEVIEW_CELL(src_iter);
 	
-	gtk_text_iter_free(cell->priv->iter);
-	cell->priv->iter = gtk_text_iter_copy (src_cell->priv->iter);
+	cell->priv->iter = src_cell->priv->iter;
 }
 
 static gint
@@ -300,7 +297,7 @@ iiter_compare (IAnjutaIterable *iter, IAnjutaIterable *other_iter, GError **e)
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
 	SourceviewCell* other_cell = SOURCEVIEW_CELL(other_iter);
 	
-	return gtk_text_iter_compare (cell->priv->iter, other_cell->priv->iter);
+	return gtk_text_iter_compare (&cell->priv->iter, &other_cell->priv->iter);
 }
 
 static gint
@@ -309,8 +306,8 @@ iiter_diff (IAnjutaIterable *iter, IAnjutaIterable *other_iter, GError **e)
 	SourceviewCell* cell = SOURCEVIEW_CELL(iter);
 	SourceviewCell* other_cell = SOURCEVIEW_CELL(other_iter);
 	
-	return (gtk_text_iter_get_offset (other_cell->priv->iter) 
-					- gtk_text_iter_get_offset (cell->priv->iter));
+	return (gtk_text_iter_get_offset (&other_cell->priv->iter) 
+					- gtk_text_iter_get_offset (&cell->priv->iter));
 }
 
 static void
diff --git a/plugins/sourceview/sourceview-prefs.c b/plugins/sourceview/sourceview-prefs.c
index a156b37..17abc9b 100644
--- a/plugins/sourceview/sourceview-prefs.c
+++ b/plugins/sourceview/sourceview-prefs.c
@@ -16,7 +16,9 @@
 
 #include "sourceview-prefs.h"
 #include "sourceview-private.h"
+#include "sourceview-provider.h"
 #include <gtksourceview/gtksourceview.h>
+#include <gtksourceview/completion-providers/words/gtksourcecompletionwords.h>
 
 #include <libanjuta/anjuta-debug.h>
 
@@ -34,6 +36,7 @@
 #define HIGHLIGHT_BRACKETS         "sourceview.brackets.highlight"
 #define TAB_SIZE                   "tabsize"
 #define INDENT_SIZE                "indent.size"
+#define AUTOCOMPLETION             "sourceview.autocompletion"
 
 #define VIEW_LINENUMBERS           "margin.linenumber.visible"
 #define VIEW_MARKS                 "margin.marker.visible"
@@ -172,6 +175,42 @@ on_notify_braces_check (AnjutaPreferences* prefs,
 }
 
 static void
+on_notify_autocompletion (AnjutaPreferences* prefs,
+                         const gchar* key,
+                         gboolean autocomplete,
+                         gpointer user_data)
+{
+	Sourceview *sv;
+	sv = ANJUTA_SOURCEVIEW(user_data);
+  GtkSourceCompletion* completion = gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv->priv->view));
+  
+  if (autocomplete)
+  {
+    GtkSourceCompletionWords *prov_words;
+    prov_words = gtk_source_completion_words_new (NULL, NULL);
+
+    gtk_source_completion_words_register (prov_words,
+                                          gtk_text_view_get_buffer (GTK_TEXT_VIEW (sv->priv->view)));
+
+    gtk_source_completion_add_provider (completion, 
+                                        GTK_SOURCE_COMPLETION_PROVIDER (prov_words), 
+                                        NULL);
+  }
+  else
+  {
+    GList* node;
+    for (node = gtk_source_completion_get_providers(completion); node != NULL; node = g_list_next (node))
+    {
+      if (GTK_IS_SOURCE_COMPLETION_WORDS(node->data))
+      {
+        gtk_source_completion_remove_provider(completion, GTK_SOURCE_COMPLETION_PROVIDER(node->data), NULL);
+        break;
+      }
+    }
+  }
+}
+
+static void
 on_notify_view_marks (AnjutaPreferences* prefs,
                       const gchar* key,
                       gboolean show_markers,
@@ -349,14 +388,17 @@ sourceview_prefs_init(Sourceview* sv)
 																	 flags);
 	
 	init_fonts(sv);
-	
+
+	on_notify_autocompletion(sv->priv->prefs, AUTOCOMPLETION, get_key_bool(sv, AUTOCOMPLETION, TRUE), sv);
+  
 	/* Register gconf notifications */
 	REGISTER_NOTIFY (TAB_SIZE, on_notify_tab_size, int);
 	REGISTER_NOTIFY (USE_TABS, on_notify_use_tab_for_indentation, bool);
 	REGISTER_NOTIFY (HIGHLIGHT_SYNTAX, on_notify_disable_hilite, bool);
 	REGISTER_NOTIFY (HIGHLIGHT_CURRENT_LINE, on_notify_highlight_current_line, bool);
 	REGISTER_NOTIFY (HIGHLIGHT_BRACKETS, on_notify_braces_check, bool);
-	REGISTER_NOTIFY (VIEW_MARKS, on_notify_view_marks, bool);
+	REGISTER_NOTIFY (AUTOCOMPLETION, on_notify_autocompletion, bool);
+  REGISTER_NOTIFY (VIEW_MARKS, on_notify_view_marks, bool);
 	REGISTER_NOTIFY (VIEW_LINENUMBERS, on_notify_view_linenums, bool);
 	REGISTER_NOTIFY (VIEW_WHITE_SPACES, on_notify_view_spaces, bool);		
 	REGISTER_NOTIFY (VIEW_EOL, on_notify_view_eol, bool);		  
diff --git a/plugins/sourceview/sourceview-private.h b/plugins/sourceview/sourceview-private.h
index 5f48cff..729915f 100644
--- a/plugins/sourceview/sourceview-private.h
+++ b/plugins/sourceview/sourceview-private.h
@@ -68,7 +68,6 @@ struct SourceviewPrivate {
 	GSList* idle_sources;
 	
 	/* Assist */
-	AssistWindow* assist_win;
 	AssistTip* assist_tip;
 	
 	/* Hover */
diff --git a/plugins/sourceview/sourceview-provider.c b/plugins/sourceview/sourceview-provider.c
new file mode 100644
index 0000000..7bf14db
--- /dev/null
+++ b/plugins/sourceview/sourceview-provider.c
@@ -0,0 +1,132 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) Johannes Schmid 2009 <jhs gnome org>
+ * 
+ * anjuta is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * anjuta is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "sourceview-provider.h"
+#include "sourceview-cell.h"
+#include "sourceview-private.h"
+
+
+static void
+sourceview_provider_iface_init (GtkSourceCompletionProviderIface* provider);
+
+G_DEFINE_TYPE_WITH_CODE (SourceviewProvider,
+			 sourceview_provider,
+			 G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_SOURCE_COMPLETION_PROVIDER,
+			                        sourceview_provider_iface_init))
+
+static void on_context_cancelled (GtkSourceCompletionContext* context,
+                                  SourceviewProvider* prov)
+{
+	ianjuta_provider_cancelled(prov->iprov, NULL);
+}
+
+static void
+sourceview_provider_populate (GtkSourceCompletionProvider* provider, GtkSourceCompletionContext* context)
+{
+	SourceviewProvider* prov = SOURCEVIEW_PROVIDER(provider);
+	GtkTextIter iter;
+	SourceviewCell* cell;
+	gtk_source_completion_context_get_iter(context, &iter);
+	cell = sourceview_cell_new (&iter, GTK_TEXT_VIEW(prov->sv->priv->view));
+	prov->context = context;
+	g_signal_connect (context, "cancelled", G_CALLBACK(on_context_cancelled), prov);
+	ianjuta_provider_populate(prov->iprov, IANJUTA_ITERABLE(cell), NULL);
+	prov->context = NULL;
+	g_object_unref (cell);
+}
+
+static const gchar*
+sourceview_provider_get_name (GtkSourceCompletionProvider* provider)
+{
+	return "Internal Sourceview editor provider";
+}
+
+
+static gboolean
+sourceview_provider_get_start_iter (GtkSourceCompletionProvider* provider, 
+                                    GtkSourceCompletionContext* context,
+                                    GtkSourceCompletionProposal* proposal, GtkTextIter* iter)
+{
+	SourceviewProvider* prov = SOURCEVIEW_PROVIDER(provider);
+	IAnjutaIterable* iiter = ianjuta_provider_get_start_iter (prov->iprov, NULL);
+	if (iiter)
+	{
+		SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
+		GtkTextIter* source_iter = sourceview_cell_get_iter(cell);
+		*iter = *source_iter;
+		return TRUE;
+	}
+	else
+		return FALSE;
+}
+
+static void
+sourceview_provider_activate_proposal (GtkSourceCompletionProvider* provider,
+                                       GtkSourceCompletionProposal* proposal,
+                                       GtkTextIter* iter)
+{
+	SourceviewProvider* prov = SOURCEVIEW_PROVIDER (provider);
+	SourceviewCell* cell = sourceview_cell_new (iter, GTK_TEXT_VIEW(prov->sv->priv->view));
+	gpointer data = g_object_get_data (proposal, "__data");
+
+	ianjuta_provider_activate(prov->iprov, IANJUTA_ITERABLE(cell), data);
+	
+	g_object_unref (cell);
+}
+
+static void
+sourceview_provider_iface_init (GtkSourceCompletionProviderIface* provider)
+{
+	provider->get_name = sourceview_provider_get_name;
+	provider->populate = sourceview_provider_populate;
+	provider->get_start_iter = sourceview_provider_get_start_iter;
+	provider->activate_proposal = sourceview_provider_activate_proposal;
+}
+
+static void
+sourceview_provider_init (SourceviewProvider *object)
+{
+  object->context = NULL;
+}
+
+static void
+sourceview_provider_dispose (GObject* obj)
+{
+
+}
+
+static void
+sourceview_provider_class_init (SourceviewProviderClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	object_class->dispose = sourceview_provider_dispose;
+}
+
+GtkSourceCompletionProvider* sourceview_provider_new (Sourceview* sv,
+                                                      IAnjutaProvider* iprov)
+{
+	GObject* obj = g_object_new (SOURCEVIEW_TYPE_PROVIDER, NULL);
+	SourceviewProvider* prov = SOURCEVIEW_PROVIDER(obj);
+	prov->sv = sv;
+	prov->iprov = iprov;
+	return GTK_SOURCE_COMPLETION_PROVIDER(obj);
+}
+
diff --git a/plugins/sourceview/sourceview-provider.h b/plugins/sourceview/sourceview-provider.h
new file mode 100644
index 0000000..360e6d6
--- /dev/null
+++ b/plugins/sourceview/sourceview-provider.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) Johannes Schmid 2009 <jhs gnome org>
+ * 
+ * anjuta is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * anjuta is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SOURCEVIEW_PROVIDER_H_
+#define _SOURCEVIEW_PROVIDER_H_
+
+#include <libanjuta/interfaces/ianjuta-provider.h>
+#include <gtksourceview/gtksourceview.h>
+#include "sourceview.h"
+
+G_BEGIN_DECLS
+
+#define SOURCEVIEW_TYPE_PROVIDER             (sourceview_provider_get_type ())
+#define SOURCEVIEW_PROVIDER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOURCEVIEW_TYPE_PROVIDER, SourceviewProvider))
+#define SOURCEVIEW_PROVIDER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SOURCEVIEW_TYPE_PROVIDER, SourceviewProviderClass))
+#define SOURCEVIEW_IS_PROVIDER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SOURCEVIEW_TYPE_PROVIDER))
+#define SOURCEVIEW_IS_PROVIDER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SOURCEVIEW_TYPE_PROVIDER))
+#define SOURCEVIEW_PROVIDER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SOURCEVIEW_TYPE_PROVIDER, SourceviewProviderClass))
+
+typedef struct _SourceviewProviderClass SourceviewProviderClass;
+typedef struct _SourceviewProvider SourceviewProvider;
+
+struct _SourceviewProviderClass
+{
+	GObjectClass parent_class;
+};
+
+struct _SourceviewProvider
+{
+	GObject parent_instance;
+	
+	Sourceview* sv;
+	IAnjutaProvider* iprov;
+	GtkSourceCompletionContext* context;
+};
+
+GType sourceview_provider_get_type (void) G_GNUC_CONST;
+
+GtkSourceCompletionProvider* sourceview_provider_new (Sourceview* sv, IAnjutaProvider* iprov);
+
+G_END_DECLS
+
+#endif /* _SOURCEVIEW_PROVIDER_H_ */
diff --git a/plugins/sourceview/sourceview.c b/plugins/sourceview/sourceview.c
index 263b0a8..279f30a 100644
--- a/plugins/sourceview/sourceview.c
+++ b/plugins/sourceview/sourceview.c
@@ -39,16 +39,19 @@
 #include <libanjuta/interfaces/ianjuta-editor.h>
 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
 #include <libanjuta/interfaces/ianjuta-editor-assist.h>
+#include <libanjuta/interfaces/ianjuta-editor-tip.h>
 #include <libanjuta/interfaces/ianjuta-editor-convert.h>
 #include <libanjuta/interfaces/ianjuta-editor-language.h>
 #include <libanjuta/interfaces/ianjuta-editor-search.h>
 #include <libanjuta/interfaces/ianjuta-editor-hover.h>
+#include <libanjuta/interfaces/ianjuta-provider.h>
 
 #include <gtksourceview/gtksourceview.h>
 #include <gtksourceview/gtksourcelanguage.h>
 #include <gtksourceview/gtksourcelanguagemanager.h>
 #include <gtksourceview/gtksourcebuffer.h>
 #include <gtksourceview/gtksourceiter.h>
+#include <gtksourceview/gtksourcecompletionitem.h>
 
 #include "config.h"
 #include "anjuta-view.h"
@@ -59,6 +62,7 @@
 #include "sourceview-prefs.h"
 #include "sourceview-print.h"
 #include "sourceview-cell.h"
+#include "sourceview-provider.h"
 #include "plugin.h"
 		 
 #define FORWARD 	0
@@ -222,34 +226,12 @@ sourceview_set_message_area (Sourceview* sv,  GtkWidget *message_area)
 }
 
 /* Callbacks */
-
-static void
-on_assist_window_destroyed (Sourceview* sv, gpointer where_object_was)
-{
-	sv->priv->assist_win = NULL;
-}
-
 static void 
 on_assist_tip_destroyed (Sourceview* sv, gpointer where_object_was)
 {
 	sv->priv->assist_tip = NULL;
 }
 
-static void 
-on_assist_chosen(AssistWindow* assist_win, gint num, Sourceview* sv)
-{
-	g_signal_emit_by_name(G_OBJECT(sv), "assist-chosen", num);
-}
-
-static void 
-on_assist_cancel(AssistWindow* assist_win, Sourceview* sv)
-{
-	if (sv->priv->assist_win)
-	{
-		gtk_widget_destroy(GTK_WIDGET(sv->priv->assist_win));
-	}
-}
-
 static void on_insert_text (GtkTextBuffer* buffer, 
 							GtkTextIter* location,
 							char* text,
@@ -597,9 +579,6 @@ static void
 sourceview_adjustment_changed(GtkAdjustment* ad, Sourceview* sv)
 {
 	/* Hide assistance windows when scrolling vertically */
-
-	if (sv->priv->assist_win)
-		gtk_widget_destroy (GTK_WIDGET (sv->priv->assist_win));
 	if (sv->priv->assist_tip)
 		gtk_widget_destroy (GTK_WIDGET (sv->priv->assist_tip));
 }
@@ -668,8 +647,6 @@ sourceview_dispose(GObject *object)
 {
 	Sourceview *cobj = ANJUTA_SOURCEVIEW(object);
 	GSList* node;
-	if (cobj->priv->assist_win)
-		on_assist_cancel(cobj->priv->assist_win, cobj);
 	if (cobj->priv->assist_tip)
 		gtk_widget_destroy(GTK_WIDGET(cobj->priv->assist_tip));
 	g_object_unref (cobj->priv->io);
@@ -1995,98 +1972,9 @@ ilanguage_iface_init (IAnjutaEditorLanguageIface *iface)
 	iface->set_language = ilanguage_set_language;
 }
 
-/* Maximal found autocompletition words */
-const gchar* AUTOCOMPLETE_REGEX = "\\s%s[\\w_*]*\\s";
-static GList*
-iassist_get_suggestions (IAnjutaEditorAssist *iassist, const gchar *context, GError **err)
-{
-	GList* words = NULL;
-	GError* error = NULL;
-	GMatchInfo *match_info;
-	gchar* text = ianjuta_editor_get_text_all (IANJUTA_EDITOR(iassist), NULL);
-	gchar* expr = g_strdup_printf (AUTOCOMPLETE_REGEX, context);
-	GRegex* regex = g_regex_new (expr, 0, 0, &error);
-	g_free(expr);
-	
-	if (error)
-	{
-		g_regex_unref(regex);
-		g_error_free(error);
-		return NULL;
-	}
-	
-	g_regex_match (regex, text, 0, &match_info);
-	while (g_match_info_matches (match_info))
-	{
-		gchar* word = g_match_info_fetch (match_info, 0);
-		g_strstrip(word);
-		if (strlen(word) <= 3 || g_str_equal (word, context) ||
-			g_list_find_custom (words, word, (GCompareFunc)strcmp) != NULL)
-			g_free(word);
-		else
-			words = g_list_prepend (words, word);
-		g_match_info_next (match_info, NULL);
-	}
-	g_match_info_free (match_info);
-	g_regex_unref (regex);
-	
-	return words;
-}
-
-static void
-iassist_suggest (IAnjutaEditorAssist *iassist, GList* choices, IAnjutaIterable* ipos,
-				 int char_alignment, GError **err)
-{
-	Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
-	
-	if (choices == NULL)
-	{
-		if (sv->priv->assist_win)
-			gtk_widget_destroy(GTK_WIDGET(sv->priv->assist_win));
-	}
-	else
-	{
-		if (!sv->priv->assist_win)
-		{
-			sv->priv->assist_win = assist_window_new(GTK_TEXT_VIEW(sv->priv->view), NULL,
-													 ianjuta_iterable_get_position (ipos, NULL));
-			g_object_weak_ref (G_OBJECT(sv->priv->assist_win),
-			                   (GWeakNotify)on_assist_window_destroyed, sv);
-			g_signal_connect(G_OBJECT(sv->priv->assist_win), "chosen", 
-								 G_CALLBACK(on_assist_chosen), sv);
-			g_signal_connect(G_OBJECT(sv->priv->assist_win), "cancel", 
-								 G_CALLBACK(on_assist_cancel), sv);
-		}
-		assist_window_update(sv->priv->assist_win, choices);
-		gtk_widget_show(GTK_WIDGET(sv->priv->assist_win));
-		if (char_alignment > 0)
-		{
-			/* Calculate offset */
-			GtkTextIter cursor;
-			GtkTextBuffer* buffer = GTK_TEXT_BUFFER (sv->priv->document);
-			gtk_text_buffer_get_iter_at_mark (buffer,
-											  &cursor,
-											  gtk_text_buffer_get_insert(buffer));
-			
-			gint offset = gtk_text_iter_get_offset (&cursor);
-			assist_window_move(sv->priv->assist_win, offset - char_alignment);
-		}
-	}
-}
-
-static void
-iassist_hide_suggestions (IAnjutaEditorAssist* iassist, GError** err)
-{
-	Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
-	if (sv->priv->assist_win)
-	{
-		gtk_widget_hide (GTK_WIDGET (sv->priv->assist_win));
-	}
-}
-
 static void 
-iassist_show_tips (IAnjutaEditorAssist *iassist, GList* tips, IAnjutaIterable* ipos,
-				   gint char_alignment, GError **err)
+itips_show (IAnjutaEditorTip *iassist, GList* tips, IAnjutaIterable* ipos,
+            gint char_alignment, GError **err)
 {
 	Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
 	SourceviewCell* cell = SOURCEVIEW_CELL (ipos);
@@ -2113,7 +2001,7 @@ iassist_show_tips (IAnjutaEditorAssist *iassist, GList* tips, IAnjutaIterable* i
 }
 
 static void
-iassist_cancel_tips (IAnjutaEditorAssist* iassist, GError** err)
+itips_cancel (IAnjutaEditorTip* iassist, GError** err)
 {
 	Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
 	if (sv->priv->assist_tip)
@@ -2121,23 +2009,124 @@ iassist_cancel_tips (IAnjutaEditorAssist* iassist, GError** err)
 }
 
 static gboolean
-iassist_tip_shown (IAnjutaEditorAssist* iassist, GError** err)
+itips_visible (IAnjutaEditorTip* iassist, GError** err)
 {
 	Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
 	return (sv->priv->assist_tip != NULL);
 }
 
 static void
-iassist_iface_init(IAnjutaEditorAssistIface* iface)
+itip_iface_init(IAnjutaEditorTipIface* iface)
+{
+	iface->show = itips_show;
+	iface->cancel = itips_cancel;
+	iface->visible = itips_visible;
+}
+
+static void
+iassist_add(IAnjutaEditorAssist* iassist, 
+            IAnjutaProvider* provider,
+            GError** e)
+{
+	Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
+	GtkSourceCompletion* completion = gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv->priv->view));
+	gtk_source_completion_add_provider(completion, 
+	                                   GTK_SOURCE_COMPLETION_PROVIDER(sourceview_provider_new(sv, provider)),
+	                                   NULL);
+}
+
+static void
+iassist_remove(IAnjutaEditorAssist* iassist, 
+               IAnjutaProvider* provider,
+               GError** e)
+{
+	Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
+	GtkSourceCompletion* completion = gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv->priv->view));
+	gtk_source_completion_remove_provider(completion, 
+	                                      GTK_SOURCE_COMPLETION_PROVIDER(sourceview_provider_new(sv, provider)),
+	                                      NULL);
+}
+
+static void
+iassist_invoke(IAnjutaEditorAssist* iassist, 
+               IAnjutaProvider* provider,
+               GError** e)
+{
+	Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
+	GtkSourceCompletion* completion = gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv->priv->view));
+	GList* node;
+	for (node = gtk_source_completion_get_providers(completion); node != NULL; node = g_list_next(node))
+	{
+		SourceviewProvider* prov = SOURCEVIEW_PROVIDER(node->data);
+		if (prov->iprov == provider)
+		{
+			GList* list = g_list_append(NULL, prov);
+			GtkTextIter iter;
+			GtkSourceCompletionContext* context;
+			gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (sv->priv->document),
+			                                  &iter,
+			                                  gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(sv->priv->document)));
+			context = 
+				gtk_source_completion_create_context(completion, &iter);
+			gtk_source_completion_show(completion, list, context);
+			g_list_free(list);
+		}
+	}
+}
+
+static void
+iassist_proposals(IAnjutaEditorAssist* iassist, 
+                  IAnjutaProvider* provider,
+                  GList* proposals,
+                  gboolean finished
+                  GError** e)
+{
+	Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
+	GtkSourceCompletion* completion = gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv->priv->view));
+	GList* node;
+	for (node = gtk_source_completion_get_providers(completion); node != NULL; node = g_list_next(node))
+	{
+		SourceviewProvider* prov = SOURCEVIEW_PROVIDER(node->data);
+		if (prov->iprov == provider)
+		{
+    	GList* prop;
+   	  GList* items = NULL;
+    	for (prop = proposals; prop != NULL; prop = g_list_next(node))
+    	{
+    	  IAnjutaEditorAssistProposal* proposal = node->data;
+    	  GtkSourceCompletionItem* item;
+    	  if (proposal->markup)
+    	  {    	    
+    	     item = gtk_source_completion_item_new_with_markup(proposal->markup,
+									 		  	                                   proposal->text,
+    	             										                       proposal->icon,
+    	             										                       proposal->info);
+    	  }
+    	  else
+    	  {
+    	     item = gtk_source_completion_item_new_with_markup(proposal->markup,
+    	                                                       proposal->text,
+    	                                                       proposal->icon,
+    	                                    									 proposal->info);
+    	  }    	                                    
+    	  items = g_list_append (items, item);
+    	  g_object_set_data (G_OBJECT(item), "__data", proposal->data);
+    	}
+    	gtk_source_completion_context_add_proposals (prov->context, GTK_SOURCE_COMPLETION_PROVIDER(prov),
+    																							 items, finished);
+		}
+	}
+}
+	
+static void	iassist_iface_init(IAnjutaEditorAssistIface* iface)
 {
-	iface->suggest = iassist_suggest;
-	iface->hide_suggestions = iassist_hide_suggestions;
-	iface->get_suggestions = iassist_get_suggestions;
-	iface->show_tips = iassist_show_tips;
-	iface->cancel_tips = iassist_cancel_tips;
-	iface->tip_shown = iassist_tip_shown;
+	iface->add = iassist_add;
+	iface->remove = iassist_remove;
+	iface->invoke = iassist_invoke;
+	iface->proposals = iassist_proposals;
 }
 
+
 static gboolean
 isearch_forward (IAnjutaEditorSearch* isearch,
 				 const gchar* search,
@@ -2324,6 +2313,7 @@ ANJUTA_TYPE_ADD_INTERFACE(imark, IANJUTA_TYPE_MARKABLE);
 ANJUTA_TYPE_ADD_INTERFACE(iindic, IANJUTA_TYPE_INDICABLE);
 ANJUTA_TYPE_ADD_INTERFACE(iselect, IANJUTA_TYPE_EDITOR_SELECTION);
 ANJUTA_TYPE_ADD_INTERFACE(iassist, IANJUTA_TYPE_EDITOR_ASSIST);
+ANJUTA_TYPE_ADD_INTERFACE(itip, IANJUTA_TYPE_EDITOR_TIP);
 ANJUTA_TYPE_ADD_INTERFACE(iconvert, IANJUTA_TYPE_EDITOR_CONVERT);
 ANJUTA_TYPE_ADD_INTERFACE(iprint, IANJUTA_TYPE_PRINT);
 ANJUTA_TYPE_ADD_INTERFACE(ilanguage, IANJUTA_TYPE_EDITOR_LANGUAGE);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]