[gnome-builder/wip/completion: 4/4] completion: start on completion provider for code assistance



commit f8e3f0cf35a0d43f5c3c1778e9d45519f2e6a49e
Author: Christian Hergert <christian hergert me>
Date:   Mon Jan 12 01:46:43 2015 -0800

    completion: start on completion provider for code assistance

 .../gb-source-code-assistant-completion.c          |  246 ++++++++++++++++++++
 .../gb-source-code-assistant-completion.h          |   60 +++++
 src/code-assistant/gb-source-code-assistant.c      |   11 +-
 src/editor/gb-source-view.c                        |   14 ++
 src/gca/gca-structs.h                              |    6 +
 src/gnome-builder.mk                               |    2 +
 6 files changed, 336 insertions(+), 3 deletions(-)
---
diff --git a/src/code-assistant/gb-source-code-assistant-completion.c 
b/src/code-assistant/gb-source-code-assistant-completion.c
new file mode 100644
index 0000000..74a317b
--- /dev/null
+++ b/src/code-assistant/gb-source-code-assistant-completion.c
@@ -0,0 +1,246 @@
+/* gb-source-code-assistant-completion.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program 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.
+ *
+ * This program 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 <glib/gi18n.h>
+
+#include "gb-source-code-assistant-completion.h"
+#include "gca-structs.h"
+
+struct _GbSourceCodeAssistantCompletionPrivate
+{
+  GCancellable     *cancellable;
+  GbEditorDocument *document;
+};
+
+static void init_provider (GtkSourceCompletionProviderIface *);
+
+G_DEFINE_TYPE_EXTENDED (GbSourceCodeAssistantCompletion,
+                        gb_source_code_assistant_completion,
+                        G_TYPE_OBJECT,
+                        0,
+                        G_ADD_PRIVATE (GbSourceCodeAssistantCompletion)
+                        G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_COMPLETION_PROVIDER,
+                                               init_provider))
+
+enum {
+  PROP_0,
+  PROP_DOCUMENT,
+  LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+GtkSourceCompletionProvider *
+gb_source_code_assistant_completion_new (void)
+{
+  return g_object_new (GB_TYPE_SOURCE_CODE_ASSISTANT_COMPLETION, NULL);
+}
+
+void
+gb_source_code_assistant_completion_set_document (GbSourceCodeAssistantCompletion *completion,
+                                                  GbEditorDocument                *document)
+{
+  g_return_if_fail (GB_IS_SOURCE_CODE_ASSISTANT_COMPLETION (completion));
+  g_return_if_fail (!document || GB_IS_EDITOR_DOCUMENT (document));
+
+  if (document != completion->priv->document)
+    {
+      g_clear_object (&completion->priv->document);
+      if (document)
+        completion->priv->document = g_object_ref (document);
+    }
+}
+
+static void
+gb_source_code_assistant_completion_finalize (GObject *object)
+{
+  GbSourceCodeAssistantCompletion *self = (GbSourceCodeAssistantCompletion *)object;
+
+  g_clear_object (&self->priv->document);
+
+  G_OBJECT_CLASS (gb_source_code_assistant_completion_parent_class)->finalize (object);
+}
+
+static void
+gb_source_code_assistant_completion_get_property (GObject    *object,
+                                                  guint       prop_id,
+                                                  GValue     *value,
+                                                  GParamSpec *pspec)
+{
+  GbSourceCodeAssistantCompletion *self = GB_SOURCE_CODE_ASSISTANT_COMPLETION (object);
+
+  switch (prop_id)
+    {
+    case PROP_DOCUMENT:
+      g_value_set_object (value, self->priv->document);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_source_code_assistant_completion_set_property (GObject      *object,
+                                                  guint         prop_id,
+                                                  const GValue *value,
+                                                  GParamSpec   *pspec)
+{
+  GbSourceCodeAssistantCompletion *self = GB_SOURCE_CODE_ASSISTANT_COMPLETION (object);
+
+  switch (prop_id)
+    {
+    case PROP_DOCUMENT:
+      gb_source_code_assistant_completion_set_document (self,
+                                                        g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_source_code_assistant_completion_class_init (GbSourceCodeAssistantCompletionClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gb_source_code_assistant_completion_finalize;
+  object_class->get_property = gb_source_code_assistant_completion_get_property;
+  object_class->set_property = gb_source_code_assistant_completion_set_property;
+
+  gParamSpecs [PROP_DOCUMENT] =
+    g_param_spec_object ("document",
+                         _("Document"),
+                         _("The document to provide completion for."),
+                         GB_TYPE_EDITOR_DOCUMENT,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_DOCUMENT,
+                                   gParamSpecs [PROP_DOCUMENT]);
+}
+
+static void
+gb_source_code_assistant_completion_init (GbSourceCodeAssistantCompletion *self)
+{
+  self->priv = gb_source_code_assistant_completion_get_instance_private (self);
+}
+
+static GdkPixbuf *
+get_icon (GtkSourceCompletionProvider *provider)
+{
+  return NULL;
+}
+
+static void
+complete_cb (GObject      *object,
+             GAsyncResult *result,
+             gpointer      user_data)
+{
+  GbSourceCodeAssistant *assistant = (GbSourceCodeAssistant *)object;
+  GbSourceCodeAssistantCompletion *self;
+  gpointer *data = user_data;
+  GtkSourceCompletionContext *context;
+  GtkSourceCompletionProvider *provider;
+  GError *error = NULL;
+  GArray *ar;
+  guint i;
+  GList *list = NULL;
+
+  g_return_if_fail (GB_IS_SOURCE_CODE_ASSISTANT (assistant));
+
+  self = GB_SOURCE_CODE_ASSISTANT_COMPLETION (data[0]);
+  provider = GTK_SOURCE_COMPLETION_PROVIDER (data[0]);
+  context = GTK_SOURCE_COMPLETION_CONTEXT (data[1]);
+  ar = gb_source_code_assistant_complete_finish (assistant, result, &error);
+
+  g_clear_object (&self->priv->cancellable);
+
+  if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+    goto cleanup;
+
+  if (ar)
+    {
+      for (i = 0; i < ar->len; i++)
+        {
+          GcaCompletionResult *cr;
+
+          cr = &g_array_index (ar, GcaCompletionResult, i);
+        }
+    }
+
+  gtk_source_completion_context_add_proposals (context, provider, list, TRUE);
+
+cleanup:
+  g_list_foreach (list, (GFunc)g_object_unref, NULL);
+  g_list_free (list);
+  g_clear_error (&error);
+  g_clear_pointer (&ar, g_array_unref);
+  g_object_unref (data[0]);
+  g_object_unref (data[1]);
+  g_free (data);
+}
+
+static void
+populate (GtkSourceCompletionProvider *provider,
+          GtkSourceCompletionContext  *context)
+{
+  GbSourceCodeAssistantCompletion *self = (GbSourceCodeAssistantCompletion *)provider;
+  GbSourceCodeAssistant *assistant;
+  GtkTextIter iter;
+  gpointer *data;
+
+  g_return_if_fail (GB_IS_SOURCE_CODE_ASSISTANT_COMPLETION (self));
+
+  if (!self->priv->document)
+    goto failure;
+
+  assistant = gb_editor_document_get_code_assistant (self->priv->document);
+  if (!assistant)
+    goto failure;
+
+  gtk_source_completion_context_get_iter (context, &iter);
+
+  data = g_new0 (gpointer, 2);
+  data[0] = g_object_ref (provider);
+  data[1] = g_object_ref (context);
+
+  g_clear_object (&self->priv->cancellable);
+  self->priv->cancellable = g_cancellable_new ();
+
+  g_signal_connect_object (context,
+                           "cancelled",
+                           G_CALLBACK (g_cancellable_cancel),
+                           self->priv->cancellable,
+                           G_CONNECT_SWAPPED);
+
+  gb_source_code_assistant_complete (assistant, &iter, self->priv->cancellable,
+                                     complete_cb, data);
+
+  return;
+
+failure:
+  gtk_source_completion_context_add_proposals (context, provider, NULL, TRUE);
+}
+
+static void
+init_provider (GtkSourceCompletionProviderIface *iface)
+{
+  iface->get_icon = get_icon;
+  iface->populate = populate;
+}
diff --git a/src/code-assistant/gb-source-code-assistant-completion.h 
b/src/code-assistant/gb-source-code-assistant-completion.h
new file mode 100644
index 0000000..e9a8258
--- /dev/null
+++ b/src/code-assistant/gb-source-code-assistant-completion.h
@@ -0,0 +1,60 @@
+/* gb-source-code-assistant-completion.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program 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.
+ *
+ * This program 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 GB_SOURCE_CODE_ASSISTANT_COMPLETION_H
+#define GB_SOURCE_CODE_ASSISTANT_COMPLETION_H
+
+#include <gtksourceview/gtksource.h>
+
+#include "gb-editor-document.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_SOURCE_CODE_ASSISTANT_COMPLETION            (gb_source_code_assistant_completion_get_type())
+#define GB_SOURCE_CODE_ASSISTANT_COMPLETION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GB_TYPE_SOURCE_CODE_ASSISTANT_COMPLETION, GbSourceCodeAssistantCompletion))
+#define GB_SOURCE_CODE_ASSISTANT_COMPLETION_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GB_TYPE_SOURCE_CODE_ASSISTANT_COMPLETION, GbSourceCodeAssistantCompletion const))
+#define GB_SOURCE_CODE_ASSISTANT_COMPLETION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  
GB_TYPE_SOURCE_CODE_ASSISTANT_COMPLETION, GbSourceCodeAssistantCompletionClass))
+#define GB_IS_SOURCE_CODE_ASSISTANT_COMPLETION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GB_TYPE_SOURCE_CODE_ASSISTANT_COMPLETION))
+#define GB_IS_SOURCE_CODE_ASSISTANT_COMPLETION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  
GB_TYPE_SOURCE_CODE_ASSISTANT_COMPLETION))
+#define GB_SOURCE_CODE_ASSISTANT_COMPLETION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  
GB_TYPE_SOURCE_CODE_ASSISTANT_COMPLETION, GbSourceCodeAssistantCompletionClass))
+
+typedef struct _GbSourceCodeAssistantCompletion        GbSourceCodeAssistantCompletion;
+typedef struct _GbSourceCodeAssistantCompletionClass   GbSourceCodeAssistantCompletionClass;
+typedef struct _GbSourceCodeAssistantCompletionPrivate GbSourceCodeAssistantCompletionPrivate;
+
+struct _GbSourceCodeAssistantCompletion
+{
+  GObject parent;
+
+  /*< private >*/
+  GbSourceCodeAssistantCompletionPrivate *priv;
+};
+
+struct _GbSourceCodeAssistantCompletionClass
+{
+  GObjectClass parent;
+};
+
+GType                        gb_source_code_assistant_completion_get_type      (void);
+GtkSourceCompletionProvider *gb_source_code_assistant_completion_new           (void);
+void                         gb_source_code_assistant_completion_set_document  
(GbSourceCodeAssistantCompletion *completion,
+                                                                                GbEditorDocument             
   *document);
+
+G_END_DECLS
+
+#endif /* GB_SOURCE_CODE_ASSISTANT_COMPLETION_H */
diff --git a/src/code-assistant/gb-source-code-assistant.c b/src/code-assistant/gb-source-code-assistant.c
index 2b88bc2..e51771e 100644
--- a/src/code-assistant/gb-source-code-assistant.c
+++ b/src/code-assistant/gb-source-code-assistant.c
@@ -655,13 +655,16 @@ gb_source_code_assistant_complete_cb (GObject      *source_object,
 
   if (!gca_completion_call_complete_finish (completion, &variant, result, &error))
     {
+      g_message ("%s", error->message);
       g_task_return_error (task, error);
       GOTO (failure);
     }
 
-  g_task_return_pointer (task, variant, (GDestroyNotify)g_variant_unref);
+  /* TODO: Marshal variant into results */
+  g_variant_print (variant, FALSE);
 
 failure:
+  g_clear_pointer (&variant, g_variant_unref);
   g_object_unref (task);
 
   EXIT;
@@ -752,10 +755,12 @@ gb_source_code_assistant_complete_finish (GbSourceCodeAssistant  *assistant,
                                           GAsyncResult           *result,
                                           GError                **error)
 {
+  GTask *task = (GTask *)result;
+
   g_return_val_if_fail (GB_IS_SOURCE_CODE_ASSISTANT (assistant), NULL);
-  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+  g_return_val_if_fail (G_IS_TASK (task), NULL);
 
-  return NULL;
+  return g_task_propagate_pointer (task, error);
 }
 
 static void
diff --git a/src/editor/gb-source-view.c b/src/editor/gb-source-view.c
index 141991a..5588896 100644
--- a/src/editor/gb-source-view.c
+++ b/src/editor/gb-source-view.c
@@ -27,6 +27,7 @@
 #include "gb-source-auto-indenter-c.h"
 #include "gb-source-auto-indenter-python.h"
 #include "gb-source-auto-indenter-xml.h"
+#include "gb-source-code-assistant-completion.h"
 #include "gb-box-theatric.h"
 #include "gb-cairo.h"
 #include "gb-editor-document.h"
@@ -51,6 +52,7 @@ struct _GbSourceViewPrivate
   GbSourceSearchHighlighter   *search_highlighter;
   GtkTextBuffer               *buffer;
   GbSourceAutoIndenter        *auto_indenter;
+  GtkSourceCompletionProvider *gca_provider;
   GtkSourceCompletionProvider *html_provider;
   GtkSourceCompletionProvider *snippets_provider;
   GtkSourceCompletionProvider *words_provider;
@@ -1183,6 +1185,9 @@ gb_source_view_reload_providers (GbSourceView *view)
                                           NULL);
     }
 
+  if (GB_IS_EDITOR_DOCUMENT (buffer))
+    g_object_set (view->priv->gca_provider, "document", buffer, NULL);
+
   gb_source_view_reload_snippets (view);
 }
 
@@ -1242,6 +1247,7 @@ gb_source_view_notify_buffer (GObject    *object,
       g_object_remove_weak_pointer (G_OBJECT (priv->buffer),
                                     (gpointer *) &priv->buffer);
       priv->buffer = NULL;
+      g_object_set (priv->gca_provider, "document", NULL, NULL);
     }
 
   buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (object));
@@ -2178,6 +2184,9 @@ gb_source_view_constructed (GObject *object)
   gtk_source_completion_add_provider (completion,
                                       source_view->priv->snippets_provider,
                                       NULL);
+  gtk_source_completion_add_provider (completion,
+                                      source_view->priv->gca_provider,
+                                      NULL);
 }
 
 static gboolean
@@ -2234,6 +2243,7 @@ gb_source_view_finalize (GObject *object)
   g_clear_pointer (&priv->snippets, g_queue_free);
   g_clear_object (&priv->search_highlighter);
   g_clear_object (&priv->auto_indenter);
+  g_clear_object (&priv->gca_provider);
   g_clear_object (&priv->html_provider);
   g_clear_object (&priv->snippets_provider);
   g_clear_object (&priv->words_provider);
@@ -2535,6 +2545,10 @@ gb_source_view_init (GbSourceView *view)
                   "source-view", view,
                   NULL);
 
+  view->priv->gca_provider =
+    g_object_new (GB_TYPE_SOURCE_CODE_ASSISTANT_COMPLETION,
+                  NULL);
+
   view->priv->words_provider =
     g_object_new (GTK_SOURCE_TYPE_COMPLETION_WORDS,
                   "minimum-word-size", 4,
diff --git a/src/gca/gca-structs.h b/src/gca/gca-structs.h
index 57b8219..a7731bb 100644
--- a/src/gca/gca-structs.h
+++ b/src/gca/gca-structs.h
@@ -60,6 +60,12 @@ typedef struct
   gchar       *message;
 } GcaDiagnostic;
 
+typedef struct
+{
+  int cursor_kind;
+  int priority;
+} GcaCompletionResult;
+
 GArray *gca_diagnostics_from_variant (GVariant *variant);
 
 G_END_DECLS
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index 6c877ac..0be6da2 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -19,6 +19,8 @@ libgnome_builder_la_SOURCES = \
        src/auto-indent/gb-source-auto-indenter-xml.h \
        src/auto-indent/gb-source-auto-indenter.c \
        src/auto-indent/gb-source-auto-indenter.h \
+       src/code-assistant/gb-source-code-assistant-completion.c \
+       src/code-assistant/gb-source-code-assistant-completion.h \
        src/code-assistant/gb-source-code-assistant-renderer.c \
        src/code-assistant/gb-source-code-assistant-renderer.h \
        src/code-assistant/gb-source-code-assistant.c \


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