[gnome-builder/wip/chergert/langserv] langserv-client: allow specifying supported languages



commit 7b26ba1c9ff8f25e03dcb0ab771ddd36e1eb394c
Author: Christian Hergert <chergert redhat com>
Date:   Mon Oct 24 23:19:28 2016 -0700

    langserv-client: allow specifying supported languages
    
    We don't necessarily want to send information about all buffers to all
    language server clients. That could get out of hand fairly quickly. So
    allow specifying the language with ide_langserv_client_add_language() or
    for subclassing, overriding the IdeLangservClientClass::supports_language()
    signal or vfunc.

 libide/langserv/ide-langserv-client.c |   78 +++++++++++++++++++++++++++++++++
 libide/langserv/ide-langserv-client.h |   12 +++--
 2 files changed, 86 insertions(+), 4 deletions(-)
---
diff --git a/libide/langserv/ide-langserv-client.c b/libide/langserv/ide-langserv-client.c
index fa671aa..71c4689 100644
--- a/libide/langserv/ide-langserv-client.c
+++ b/libide/langserv/ide-langserv-client.c
@@ -43,6 +43,7 @@ typedef struct
   JsonrpcClient  *rpc_client;
   GIOStream      *io_stream;
   GHashTable     *diagnostics_by_file;
+  GPtrArray      *languages;
 } IdeLangservClientPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (IdeLangservClient, ide_langserv_client, IDE_TYPE_OBJECT)
@@ -68,12 +69,33 @@ enum {
 
 enum {
   NOTIFICATION,
+  SUPPORTS_LANGUAGE,
   N_SIGNALS
 };
 
 static GParamSpec *properties [N_PROPS];
 static guint signals [N_SIGNALS];
 
+static gboolean
+ide_langserv_client_supports_buffer (IdeLangservClient *self,
+                                     IdeBuffer         *buffer)
+{
+  GtkSourceLanguage *language;
+  const gchar *language_id = "text/plain";
+  gboolean ret = FALSE;
+
+  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (IDE_IS_BUFFER (buffer));
+
+  language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
+  if (language != NULL)
+    language_id = gtk_source_language_get_id (language);
+
+  g_signal_emit (self, signals [SUPPORTS_LANGUAGE], 0, language_id, &ret);
+
+  return ret;
+}
+
 static void
 ide_langserv_client_clear_diagnostics (IdeLangservClient *self,
                                        const gchar       *uri)
@@ -108,6 +130,9 @@ ide_langserv_client_buffer_saved (IdeLangservClient *self,
   g_assert (IDE_IS_BUFFER (buffer));
   g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
 
+  if (!ide_langserv_client_supports_buffer (self, buffer))
+    IDE_EXIT;
+
   uri = ide_buffer_get_uri (buffer);
 
   params = JCON_NEW (
@@ -255,6 +280,9 @@ ide_langserv_client_buffer_loaded (IdeLangservClient *self,
   g_assert (IDE_IS_BUFFER (buffer));
   g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
 
+  if (!ide_langserv_client_supports_buffer (self, buffer))
+    IDE_EXIT;
+
   g_signal_connect_object (buffer,
                            "insert-text",
                            G_CALLBACK (ide_langserv_client_buffer_insert_text),
@@ -298,6 +326,9 @@ ide_langserv_client_buffer_unloaded (IdeLangservClient *self,
   g_assert (IDE_IS_BUFFER (buffer));
   g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
 
+  if (!ide_langserv_client_supports_buffer (self, buffer))
+    IDE_EXIT;
+
   uri = ide_buffer_get_uri (buffer);
 
   params = JCON_NEW (
@@ -608,6 +639,7 @@ ide_langserv_client_finalize (GObject *object)
   IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
 
   g_clear_pointer (&priv->diagnostics_by_file, g_hash_table_unref);
+  g_clear_pointer (&priv->languages, g_ptr_array_unref);
   g_clear_object (&priv->rpc_client);
   g_clear_object (&priv->buffer_manager_signals);
   g_clear_object (&priv->project_signals);
@@ -615,6 +647,26 @@ ide_langserv_client_finalize (GObject *object)
   G_OBJECT_CLASS (ide_langserv_client_parent_class)->finalize (object);
 }
 
+static gboolean
+ide_langserv_client_real_supports_language (IdeLangservClient *self,
+                                            const gchar       *language_id)
+{
+  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+
+  g_assert (IDE_IS_LANGSERV_CLIENT (self));
+  g_assert (language_id != NULL);
+
+  for (guint i = 0; i < priv->languages->len; i++)
+    {
+      const gchar *id = g_ptr_array_index (priv->languages, i);
+
+      if (g_strcmp0 (language_id, id) == 0)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
 static void
 ide_langserv_client_get_property (GObject    *object,
                                   guint       prop_id,
@@ -665,6 +717,7 @@ ide_langserv_client_class_init (IdeLangservClientClass *klass)
   object_class->set_property = ide_langserv_client_set_property;
 
   klass->notification = ide_langserv_client_real_notification;
+  klass->supports_language = ide_langserv_client_real_supports_language;
 
   properties [PROP_IO_STREAM] =
     g_param_spec_object ("io-stream",
@@ -685,6 +738,17 @@ ide_langserv_client_class_init (IdeLangservClientClass *klass)
                   2,
                   G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
                   JSON_TYPE_NODE);
+
+  signals [SUPPORTS_LANGUAGE] =
+    g_signal_new ("supports-language",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (IdeLangservClientClass, supports_language),
+                  g_signal_accumulator_true_handled, NULL,
+                  NULL,
+                  G_TYPE_BOOLEAN,
+                  1,
+                  G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
 }
 
 static void
@@ -692,6 +756,8 @@ ide_langserv_client_init (IdeLangservClient *self)
 {
   IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
 
+  priv->languages = g_ptr_array_new_with_free_func (g_free);
+
   priv->diagnostics_by_file = g_hash_table_new_full ((GHashFunc)g_file_hash,
                                                      (GEqualFunc)g_file_equal,
                                                      g_object_unref,
@@ -1128,3 +1194,15 @@ ide_langserv_client_get_diagnostics_finish (IdeLangservClient  *self,
 
   return ret;
 }
+
+void
+ide_langserv_client_add_language (IdeLangservClient *self,
+                                  const gchar       *language_id)
+{
+  IdeLangservClientPrivate *priv = ide_langserv_client_get_instance_private (self);
+
+  g_return_if_fail (IDE_IS_LANGSERV_CLIENT (self));
+  g_return_if_fail (language_id != NULL);
+
+  g_ptr_array_add (priv->languages, g_strdup (language_id));
+}
diff --git a/libide/langserv/ide-langserv-client.h b/libide/langserv/ide-langserv-client.h
index 546f528..a0c9893 100644
--- a/libide/langserv/ide-langserv-client.h
+++ b/libide/langserv/ide-langserv-client.h
@@ -33,9 +33,11 @@ struct _IdeLangservClientClass
 {
   IdeObjectClass parent_class;
 
-  void (*notification) (IdeLangservClient *self,
-                        const gchar       *method,
-                        JsonNode          *params);
+  void     (*notification)      (IdeLangservClient *self,
+                                 const gchar       *method,
+                                 JsonNode          *params);
+  gboolean (*supports_language) (IdeLangservClient *self,
+                                 const gchar       *language_id);
 
   gpointer _reserved1;
   gpointer _reserved2;
@@ -48,7 +50,9 @@ struct _IdeLangservClientClass
 };
 
 IdeLangservClient *ide_langserv_client_new                    (IdeContext           *context,
-                                                              GIOStream            *io_stream);
+                                                               GIOStream            *io_stream);
+void               ide_langserv_client_add_language           (IdeLangservClient    *self,
+                                                               const gchar          *language_id);
 void               ide_langserv_client_start                  (IdeLangservClient    *self);
 void               ide_langserv_client_stop                   (IdeLangservClient    *self);
 void               ide_langserv_client_call_async             (IdeLangservClient    *self,


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