[gnome-builder] libide-lsp: port to GtkSourceView 5



commit 9066ea00c40b1a23be9750aa490356c97072a43c
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jul 11 17:58:32 2022 -0700

    libide-lsp: port to GtkSourceView 5
    
    Also includes various availability macro updates and uses the incoming
    IdeRunContext features from libide-foundry.

 src/libide/lsp/ide-lsp-completion-item.c     | 102 ++++++++++----
 src/libide/lsp/ide-lsp-completion-provider.c | 204 +++++++++++++--------------
 src/libide/lsp/ide-lsp-completion-results.c  |  10 +-
 src/libide/lsp/ide-lsp-hover-provider.c      | 160 ++++++++++-----------
 src/libide/lsp/ide-lsp-search-result.c       |  10 +-
 src/libide/lsp/ide-lsp-service.c             |  25 ++--
 src/libide/lsp/meson.build                   |   1 -
 7 files changed, 276 insertions(+), 236 deletions(-)
---
diff --git a/src/libide/lsp/ide-lsp-completion-item.c b/src/libide/lsp/ide-lsp-completion-item.c
index f51741d8d..b050608d6 100644
--- a/src/libide/lsp/ide-lsp-completion-item.c
+++ b/src/libide/lsp/ide-lsp-completion-item.c
@@ -22,7 +22,8 @@
 
 #include "config.h"
 
-#include <libide-sourceview.h>
+#include <gtksourceview/gtksource.h>
+
 #include <jsonrpc-glib.h>
 
 #include "ide-lsp-completion-item.h"
@@ -38,7 +39,7 @@ struct _IdeLspCompletionItem
 };
 
 G_DEFINE_FINAL_TYPE_WITH_CODE (IdeLspCompletionItem, ide_lsp_completion_item, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (IDE_TYPE_COMPLETION_PROPOSAL, NULL))
+                               G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_COMPLETION_PROPOSAL, NULL))
 
 static void
 ide_lsp_completion_item_finalize (GObject *object)
@@ -87,15 +88,6 @@ ide_lsp_completion_item_new (GVariant *variant)
   return self;
 }
 
-gchar *
-ide_lsp_completion_item_get_markup (IdeLspCompletionItem *self,
-                                    const gchar          *typed_text)
-{
-  g_return_val_if_fail (IDE_IS_LSP_COMPLETION_ITEM (self), NULL);
-
-  return ide_completion_fuzzy_highlight (self->label, typed_text);
-}
-
 const gchar *
 ide_lsp_completion_item_get_return_type (IdeLspCompletionItem *self)
 {
@@ -122,6 +114,68 @@ ide_lsp_completion_item_get_detail (IdeLspCompletionItem *self)
   return self->detail;
 }
 
+void
+ide_lsp_completion_item_display (IdeLspCompletionItem    *self,
+                                 GtkSourceCompletionCell *cell,
+                                 const char              *typed_text)
+{
+  GtkSourceCompletionColumn column;
+
+  g_return_if_fail (IDE_IS_LSP_COMPLETION_ITEM (self));
+  g_return_if_fail (GTK_SOURCE_IS_COMPLETION_CELL (cell));
+
+  column = gtk_source_completion_cell_get_column (cell);
+
+  switch (column)
+    {
+    case GTK_SOURCE_COMPLETION_COLUMN_ICON:
+      gtk_source_completion_cell_set_icon_name (cell, ide_lsp_completion_item_get_icon_name (self));
+      break;
+
+    case GTK_SOURCE_COMPLETION_COLUMN_TYPED_TEXT:
+      {
+        PangoAttrList *attrs;
+
+        attrs = gtk_source_completion_fuzzy_highlight (self->label, typed_text);
+        gtk_source_completion_cell_set_text_with_attributes (cell, self->label, attrs);
+        pango_attr_list_unref (attrs);
+
+        break;
+      }
+
+    case GTK_SOURCE_COMPLETION_COLUMN_COMMENT:
+      if (self->detail != NULL && self->detail[0] != 0)
+        {
+          const char *endptr = strchr (self->detail, '\n');
+
+          if (endptr == NULL)
+            {
+              gtk_source_completion_cell_set_text (cell, self->detail);
+            }
+          else
+            {
+              g_autofree char *detail = g_strndup (self->detail, endptr - self->detail);
+              gtk_source_completion_cell_set_text (cell, detail);
+            }
+        }
+      break;
+
+    case GTK_SOURCE_COMPLETION_COLUMN_DETAILS:
+      /* TODO: If there is markdown, we *could* use a markedview here
+       * and set_child() with the WebKit view.
+       */
+      gtk_source_completion_cell_set_text (cell, self->detail);
+      break;
+
+    default:
+    case GTK_SOURCE_COMPLETION_COLUMN_AFTER:
+    case GTK_SOURCE_COMPLETION_COLUMN_BEFORE:
+      /* TODO: Can we get this info from LSP? */
+      gtk_source_completion_cell_set_text (cell, NULL);
+      break;
+    }
+}
+
 /**
  * ide_lsp_completion_item_get_snippet:
  * @self: a #IdeLspCompletionItem
@@ -129,15 +183,13 @@ ide_lsp_completion_item_get_detail (IdeLspCompletionItem *self)
  * Creates a new snippet for the completion item to be inserted into
  * the document.
  *
- * Returns: (transfer full): an #IdeSnippet
- *
- * Since: 3.30
+ * Returns: (transfer full): an #GtkSourceSnippet
  */
-IdeSnippet *
+GtkSourceSnippet *
 ide_lsp_completion_item_get_snippet (IdeLspCompletionItem *self)
 {
-  g_autoptr(IdeSnippet) snippet = NULL;
-  g_autoptr(IdeSnippetChunk) plainchunk = NULL;
+  g_autoptr(GtkSourceSnippet) snippet = NULL;
+  g_autoptr(GtkSourceSnippetChunk) plainchunk = NULL;
   const gchar *snippet_text = NULL;
   const gchar *snippet_new_text = NULL;
   const gchar *text;
@@ -156,7 +208,7 @@ ide_lsp_completion_item_get_snippet (IdeLspCompletionItem *self)
         {
           g_autoptr(GError) error = NULL;
 
-          if ((snippet = ide_snippet_parser_parse_one (snippet_new_text, -1, &error)))
+          if ((snippet = gtk_source_snippet_new_parsed (snippet_new_text, &error)))
             return g_steal_pointer (&snippet);
 
           g_warning ("Failed to parse snippet: %s: %s",
@@ -166,7 +218,7 @@ ide_lsp_completion_item_get_snippet (IdeLspCompletionItem *self)
         {
           g_autoptr(GError) error = NULL;
 
-          if ((snippet = ide_snippet_parser_parse_one (snippet_text, -1, &error)))
+          if ((snippet = gtk_source_snippet_new_parsed (snippet_text, &error)))
             return g_steal_pointer (&snippet);
 
           g_warning ("Failed to parse snippet: %s: %s",
@@ -174,11 +226,11 @@ ide_lsp_completion_item_get_snippet (IdeLspCompletionItem *self)
         }
     }
 
-  snippet = ide_snippet_new (NULL, NULL);
-  plainchunk = ide_snippet_chunk_new ();
-  ide_snippet_chunk_set_text (plainchunk, text);
-  ide_snippet_chunk_set_text_set (plainchunk, TRUE);
-  ide_snippet_add_chunk (snippet, plainchunk);
+  snippet = gtk_source_snippet_new (NULL, NULL);
+  plainchunk = gtk_source_snippet_chunk_new ();
+  gtk_source_snippet_chunk_set_text (plainchunk, text);
+  gtk_source_snippet_chunk_set_text_set (plainchunk, TRUE);
+  gtk_source_snippet_add_chunk (snippet, plainchunk);
 
   return g_steal_pointer (&snippet);
 }
@@ -192,8 +244,6 @@ ide_lsp_completion_item_get_snippet (IdeLspCompletionItem *self)
  * Obtain an array of all additional text edits to be applied to the project.
  *
  * Returns: (transfer full) (element-type IdeTextEdit) (nullable): a #GPtrArray of #IdeTextEdit
- *
- * Since: 41.0
  */
 GPtrArray *
 ide_lsp_completion_item_get_additional_text_edits (IdeLspCompletionItem *self,
diff --git a/src/libide/lsp/ide-lsp-completion-provider.c b/src/libide/lsp/ide-lsp-completion-provider.c
index 3f1e80792..01845bc3d 100644
--- a/src/libide/lsp/ide-lsp-completion-provider.c
+++ b/src/libide/lsp/ide-lsp-completion-provider.c
@@ -35,15 +35,17 @@
 typedef struct
 {
   IdeLspClient  *client;
-  gchar         *word;
-  gchar        **trigger_chars;
+  char          *word;
+  char         **trigger_chars;
+  char          *refilter_word;
+  guint          has_loaded : 1;
 } IdeLspCompletionProviderPrivate;
 
-static void provider_iface_init (IdeCompletionProviderInterface *iface);
+static void provider_iface_init (GtkSourceCompletionProviderInterface *iface);
 
 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLspCompletionProvider, ide_lsp_completion_provider, IDE_TYPE_OBJECT,
                                   G_ADD_PRIVATE (IdeLspCompletionProvider)
-                                  G_IMPLEMENT_INTERFACE (IDE_TYPE_COMPLETION_PROVIDER, provider_iface_init))
+                                  G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_COMPLETION_PROVIDER, 
provider_iface_init))
 
 enum {
   PROP_0,
@@ -53,6 +55,11 @@ enum {
 
 static GParamSpec *properties [N_PROPS];
 
+static void
+ide_lsp_completion_provider_real_load (IdeLspCompletionProvider *self)
+{
+}
+
 static void
 ide_lsp_completion_provider_finalize (GObject *object)
 {
@@ -113,6 +120,8 @@ ide_lsp_completion_provider_class_init (IdeLspCompletionProviderClass *klass)
   object_class->get_property = ide_lsp_completion_provider_get_property;
   object_class->set_property = ide_lsp_completion_provider_set_property;
 
+  klass->load = ide_lsp_completion_provider_real_load;
+
   properties [PROP_CLIENT] =
     g_param_spec_object ("client",
                          "Client",
@@ -208,8 +217,8 @@ ide_lsp_completion_provider_set_client (IdeLspCompletionProvider *self,
 }
 
 static gint
-ide_lsp_completion_provider_get_priority (IdeCompletionProvider *provider,
-                                          IdeCompletionContext  *context)
+ide_lsp_completion_provider_get_priority (GtkSourceCompletionProvider *provider,
+                                          GtkSourceCompletionContext  *context)
 {
   return IDE_LSP_COMPLETION_PROVIDER_PRIORITY;
 }
@@ -251,20 +260,20 @@ ide_lsp_completion_provider_complete_cb (GObject      *object,
 }
 
 static void
-ide_lsp_completion_provider_populate_async (IdeCompletionProvider *provider,
-                                            IdeCompletionContext  *context,
-                                            GCancellable          *cancellable,
-                                            GAsyncReadyCallback    callback,
-                                            gpointer               user_data)
+ide_lsp_completion_provider_populate_async (GtkSourceCompletionProvider *provider,
+                                            GtkSourceCompletionContext  *context,
+                                            GCancellable                *cancellable,
+                                            GAsyncReadyCallback          callback,
+                                            gpointer                     user_data)
 {
   IdeLspCompletionProvider *self = (IdeLspCompletionProvider *)provider;
   IdeLspCompletionProviderPrivate *priv = ide_lsp_completion_provider_get_instance_private (self);
-  IdeCompletionActivation activation;
+  GtkSourceCompletionActivation activation;
   g_autoptr(IdeTask) task = NULL;
   g_autoptr(GVariant) params = NULL;
-  g_autofree gchar *uri = NULL;
+  g_autofree char *uri = NULL;
   GtkTextIter iter, end;
-  GtkTextBuffer *buffer;
+  GtkSourceBuffer *buffer;
   gint trigger_kind;
   gint line;
   gint column;
@@ -272,7 +281,16 @@ ide_lsp_completion_provider_populate_async (IdeCompletionProvider *provider,
   IDE_ENTRY;
 
   g_assert (IDE_IS_LSP_COMPLETION_PROVIDER (self));
-  g_assert (IDE_IS_COMPLETION_CONTEXT (context));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
+
+  if (!priv->has_loaded)
+    {
+      priv->has_loaded = TRUE;
+      IDE_LSP_COMPLETION_PROVIDER_GET_CLASS (self)->load (self);
+    }
+
+  g_clear_pointer (&priv->refilter_word, g_free);
+  g_clear_pointer (&priv->word, g_free);
 
   task = ide_task_new (self, cancellable, callback, user_data);
   ide_task_set_source_tag (task, ide_lsp_completion_provider_populate_async);
@@ -286,19 +304,18 @@ ide_lsp_completion_provider_populate_async (IdeCompletionProvider *provider,
       IDE_EXIT;
     }
 
-  ide_completion_context_get_bounds (context, &iter, &end);
+  gtk_source_completion_context_get_bounds (context, &iter, &end);
 
-  activation = ide_completion_context_get_activation (context);
+  activation = gtk_source_completion_context_get_activation (context);
 
-  if (activation == IDE_COMPLETION_TRIGGERED)
+  if (activation == GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE)
     trigger_kind = 2;
   else
     trigger_kind = 1;
 
-  g_clear_pointer (&priv->word, g_free);
-  priv->word = ide_completion_context_get_word (context);
+  priv->word = gtk_source_completion_context_get_word (context);
 
-  buffer = ide_completion_context_get_buffer (context);
+  buffer = gtk_source_completion_context_get_buffer (context);
   uri = ide_buffer_dup_uri (IDE_BUFFER (buffer));
 
   line = gtk_text_iter_get_line (&iter);
@@ -328,15 +345,15 @@ ide_lsp_completion_provider_populate_async (IdeCompletionProvider *provider,
 }
 
 static GListModel *
-ide_lsp_completion_provider_populate_finish (IdeCompletionProvider  *provider,
-                                             GAsyncResult           *result,
-                                             GError                **error)
+ide_lsp_completion_provider_populate_finish (GtkSourceCompletionProvider  *provider,
+                                             GAsyncResult                 *result,
+                                             GError                      **error)
 {
   GListModel *ret;
 
   IDE_ENTRY;
 
-  g_assert (IDE_IS_COMPLETION_PROVIDER (provider));
+  g_assert (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider));
   g_assert (IDE_IS_TASK (result));
 
   ret = ide_task_propagate_object (IDE_TASK (result), error);
@@ -344,45 +361,47 @@ ide_lsp_completion_provider_populate_finish (IdeCompletionProvider  *provider,
   IDE_RETURN (ret);
 }
 
-static gboolean
-ide_lsp_completion_provider_refilter (IdeCompletionProvider *provider,
-                                      IdeCompletionContext  *context,
-                                      GListModel            *model)
+static void
+ide_lsp_completion_provider_refilter (GtkSourceCompletionProvider *provider,
+                                      GtkSourceCompletionContext  *context,
+                                      GListModel                  *model)
 {
+  IdeLspCompletionProvider *self = (IdeLspCompletionProvider *)provider;
+  IdeLspCompletionProviderPrivate *priv = ide_lsp_completion_provider_get_instance_private (self);
   IdeLspCompletionResults *results = (IdeLspCompletionResults *)model;
-  g_autofree gchar *word = NULL;
 
-  g_assert (IDE_IS_LSP_COMPLETION_PROVIDER (provider));
-  g_assert (IDE_IS_COMPLETION_CONTEXT (context));
+  g_assert (IDE_IS_LSP_COMPLETION_PROVIDER (self));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
   g_assert (IDE_IS_LSP_COMPLETION_RESULTS (results));
 
-  word = ide_completion_context_get_word (context);
-  ide_lsp_completion_results_refilter (results, word);
+  g_clear_pointer (&priv->refilter_word, g_free);
+  priv->refilter_word = gtk_source_completion_context_get_word (context);
 
-  return TRUE;
+  ide_lsp_completion_results_refilter (results, priv->refilter_word);
 }
 
 static void
-ide_lsp_completion_provider_display_proposal (IdeCompletionProvider   *provider,
-                                              IdeCompletionListBoxRow *row,
-                                              IdeCompletionContext    *context,
-                                              const gchar             *typed_text,
-                                              IdeCompletionProposal   *proposal)
+ide_lsp_completion_provider_display (GtkSourceCompletionProvider *provider,
+                                     GtkSourceCompletionContext  *context,
+                                     GtkSourceCompletionProposal *proposal,
+                                     GtkSourceCompletionCell     *cell)
 {
   IdeLspCompletionItem *item = (IdeLspCompletionItem *)proposal;
-  g_autofree gchar *markup = NULL;
+  IdeLspCompletionProvider *self = (IdeLspCompletionProvider *)provider;
+  IdeLspCompletionProviderPrivate *priv = ide_lsp_completion_provider_get_instance_private (self);
+  const char *typed_text;
 
   g_assert (IDE_IS_LSP_COMPLETION_PROVIDER (provider));
-  g_assert (IDE_IS_COMPLETION_LIST_BOX_ROW (row));
-  g_assert (IDE_IS_COMPLETION_CONTEXT (context));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
   g_assert (IDE_IS_LSP_COMPLETION_ITEM (proposal));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CELL (cell));
 
-  markup = ide_lsp_completion_item_get_markup (item, typed_text);
+  if (priv->refilter_word)
+    typed_text = priv->refilter_word;
+  else
+    typed_text = priv->word;
 
-  ide_completion_list_box_row_set_icon_name (row, ide_lsp_completion_item_get_icon_name (item));
-  ide_completion_list_box_row_set_left (row, NULL);
-  ide_completion_list_box_row_set_center_markup (row, markup);
-  ide_completion_list_box_row_set_right (row, NULL);
+  ide_lsp_completion_item_display (item, cell, typed_text);
 }
 
 static void
@@ -406,42 +425,40 @@ ide_lsp_completion_provider_apply_additional_edits_cb (GObject      *object,
 }
 
 static void
-ide_lsp_completion_provider_activate_proposal (IdeCompletionProvider *provider,
-                                               IdeCompletionContext  *completion_context,
-                                               IdeCompletionProposal *proposal,
-                                               const GdkEventKey     *key)
+ide_lsp_completion_provider_activate (GtkSourceCompletionProvider *provider,
+                                      GtkSourceCompletionContext  *context,
+                                      GtkSourceCompletionProposal *proposal)
 {
-  g_autoptr(IdeSnippet) snippet = NULL;
-  IdeSnippetChunk *chunk;
-  GtkTextBuffer *buffer;
-  GtkTextView *view;
-  GtkTextIter begin, end;
   g_autoptr(GPtrArray) additional_text_edits = NULL;
-  IdeBufferManager *buffer_manager;
-  const gchar *text = NULL;
+  g_autoptr(GtkSourceSnippet) snippet = NULL;
+  GtkSourceSnippetChunk *chunk;
+  GtkSourceBuffer *buffer;
+  GtkSourceView *view;
+  GtkTextIter begin, end;
+  const char *text = NULL;
 
-  g_assert (IDE_IS_COMPLETION_PROVIDER (provider));
-  g_assert (IDE_IS_COMPLETION_CONTEXT (completion_context));
+  g_assert (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
   g_assert (IDE_IS_LSP_COMPLETION_ITEM (proposal));
 
-  buffer = ide_completion_context_get_buffer (completion_context);
-
+  buffer = gtk_source_completion_context_get_buffer (context);
   g_assert (IDE_IS_BUFFER (buffer));
 
-  view = ide_completion_context_get_view (completion_context);
+  view = gtk_source_completion_context_get_view (context);
+  g_assert (IDE_IS_SOURCE_VIEW (view));
 
   snippet = ide_lsp_completion_item_get_snippet (IDE_LSP_COMPLETION_ITEM (proposal));
-  if ((chunk = ide_snippet_get_nth_chunk (snippet, 0)))
-    text = ide_snippet_chunk_get_text (chunk);
+  if ((chunk = gtk_source_snippet_get_nth_chunk (snippet, 0)))
+    text = gtk_source_snippet_chunk_get_text (chunk);
 
-  gtk_text_buffer_begin_user_action (buffer);
-  if (ide_completion_context_get_bounds (completion_context, &begin, &end))
+  gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
+  if (gtk_source_completion_context_get_bounds (context, &begin, &end))
     {
-      gtk_text_buffer_delete (buffer, &begin, &end);
-      ide_completion_remove_common_prefix (ide_completion_context_get_completion (completion_context), 
&begin, text);
+      gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &begin, &end);
+      ide_text_util_remove_common_prefix (&begin, text);
     }
-  ide_source_view_push_snippet (IDE_SOURCE_VIEW (view), snippet, &begin);
-  gtk_text_buffer_end_user_action (buffer);
+  gtk_source_view_push_snippet (GTK_SOURCE_VIEW (view), snippet, &begin);
+  gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
 
   additional_text_edits =
     ide_lsp_completion_item_get_additional_text_edits (IDE_LSP_COMPLETION_ITEM (proposal),
@@ -449,35 +466,17 @@ ide_lsp_completion_provider_activate_proposal (IdeCompletionProvider *provider,
   IDE_PTR_ARRAY_SET_FREE_FUNC (additional_text_edits, g_object_unref);
 
   if (additional_text_edits != NULL)
-    {
-      IdeContext *context = ide_object_get_context (IDE_OBJECT (provider));
-
-      g_return_if_fail (context != NULL);
-
-      buffer_manager = ide_buffer_manager_from_context (context);
-
-      ide_buffer_manager_apply_edits_async (buffer_manager,
-                                            IDE_PTR_ARRAY_STEAL_FULL (&additional_text_edits),
-                                            NULL,
-                                            ide_lsp_completion_provider_apply_additional_edits_cb,
-                                            NULL);
-    }
-}
-
-static gchar *
-ide_lsp_completion_provider_get_comment (IdeCompletionProvider *provider,
-                                         IdeCompletionProposal *proposal)
-{
-  g_assert (IDE_IS_COMPLETION_PROVIDER (provider));
-  g_assert (IDE_IS_LSP_COMPLETION_ITEM (proposal));
-
-  return g_strdup (ide_lsp_completion_item_get_detail (IDE_LSP_COMPLETION_ITEM (proposal)));
+    ide_buffer_manager_apply_edits_async (ide_buffer_manager_from_context (ide_object_get_context 
(IDE_OBJECT (provider))),
+                                          IDE_PTR_ARRAY_STEAL_FULL (&additional_text_edits),
+                                          NULL,
+                                          ide_lsp_completion_provider_apply_additional_edits_cb,
+                                          NULL);
 }
 
 static gboolean
-ide_lsp_completion_provider_is_trigger (IdeCompletionProvider *provider,
-                                        const GtkTextIter     *iter,
-                                        gunichar               ch)
+ide_lsp_completion_provider_is_trigger (GtkSourceCompletionProvider *provider,
+                                        const GtkTextIter           *iter,
+                                        gunichar                     ch)
 {
   IdeLspCompletionProvider *self = (IdeLspCompletionProvider *)provider;
   IdeLspCompletionProviderPrivate *priv = ide_lsp_completion_provider_get_instance_private (self);
@@ -489,7 +488,7 @@ ide_lsp_completion_provider_is_trigger (IdeCompletionProvider *provider,
     {
       for (guint i = 0; priv->trigger_chars[i]; i++)
         {
-          const gchar *trigger = priv->trigger_chars[i];
+          const char *trigger = priv->trigger_chars[i];
 
           /* Technically, since these are strings they can be more than
            * one character long. But I haven't seen anything actually
@@ -504,14 +503,13 @@ ide_lsp_completion_provider_is_trigger (IdeCompletionProvider *provider,
 }
 
 static void
-provider_iface_init (IdeCompletionProviderInterface *iface)
+provider_iface_init (GtkSourceCompletionProviderInterface *iface)
 {
   iface->get_priority = ide_lsp_completion_provider_get_priority;
   iface->populate_async = ide_lsp_completion_provider_populate_async;
   iface->populate_finish = ide_lsp_completion_provider_populate_finish;
   iface->refilter = ide_lsp_completion_provider_refilter;
-  iface->display_proposal = ide_lsp_completion_provider_display_proposal;
-  iface->activate_proposal = ide_lsp_completion_provider_activate_proposal;
-  iface->get_comment = ide_lsp_completion_provider_get_comment;
+  iface->display = ide_lsp_completion_provider_display;
+  iface->activate = ide_lsp_completion_provider_activate;
   iface->is_trigger = ide_lsp_completion_provider_is_trigger;
 }
diff --git a/src/libide/lsp/ide-lsp-completion-results.c b/src/libide/lsp/ide-lsp-completion-results.c
index 2eef146eb..30b53cdff 100644
--- a/src/libide/lsp/ide-lsp-completion-results.c
+++ b/src/libide/lsp/ide-lsp-completion-results.c
@@ -18,7 +18,7 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#define G_LOG_DOMAIN "ide-lsp-completion-results.h"
+#define G_LOG_DOMAIN "ide-lsp-completion-results"
 
 #include "config.h"
 
@@ -43,7 +43,7 @@ typedef struct
 static void list_model_iface_init (GListModelInterface *iface);
 
 G_DEFINE_FINAL_TYPE_WITH_CODE (IdeLspCompletionResults, ide_lsp_completion_results, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
+                               G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
 
 static void
 ide_lsp_completion_results_finalize (GObject *object)
@@ -116,7 +116,7 @@ ide_lsp_completion_results_get_n_items (GListModel *model)
 
 static gpointer
 ide_lsp_completion_results_get_item (GListModel *model,
-                                          guint       position)
+                                     guint       position)
 {
   IdeLspCompletionResults *self = (IdeLspCompletionResults *)model;
   g_autoptr(GVariant) child = NULL;
@@ -148,7 +148,7 @@ compare_items (const Item *a,
 
 void
 ide_lsp_completion_results_refilter (IdeLspCompletionResults *self,
-                                          const gchar                  *typed_text)
+                                     const char              *typed_text)
 {
   g_autofree gchar *query = NULL;
   GVariantIter iter;
@@ -191,7 +191,7 @@ ide_lsp_completion_results_refilter (IdeLspCompletionResults *self,
       if (!g_variant_lookup (node, "label", "&s", &label))
         continue;
 
-      if (ide_completion_fuzzy_match (label, query, &priority))
+      if (gtk_source_completion_fuzzy_match (label, query, &priority))
         {
           Item item = { .index = index, .priority = priority };
           g_array_append_val (self->items, item);
diff --git a/src/libide/lsp/ide-lsp-hover-provider.c b/src/libide/lsp/ide-lsp-hover-provider.c
index 43ac69e32..f5e3ed704 100644
--- a/src/libide/lsp/ide-lsp-hover-provider.c
+++ b/src/libide/lsp/ide-lsp-hover-provider.c
@@ -23,7 +23,9 @@
 #include "config.h"
 
 #include <jsonrpc-glib.h>
+
 #include <libide-code.h>
+#include <libide-gui.h>
 #include <libide-sourceview.h>
 #include <libide-threading.h>
 
@@ -37,24 +39,23 @@
  * The #IdeLspHoverProvider provides integration with language servers
  * that support hover requests. This can display markup in the interactive
  * tooltip that is displayed in the editor.
- *
- * Since: 3.30
  */
 
 typedef struct
 {
   IdeLspClient *client;
-  gchar *category;
-  gint priority;
+  char *category;
+  int priority;
+  guint did_prepare : 1;
 } IdeLspHoverProviderPrivate;
 
-static void hover_provider_iface_init (IdeHoverProviderInterface *iface);
+static void hover_provider_iface_init (GtkSourceHoverProviderInterface *iface);
 
 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeLspHoverProvider,
                                   ide_lsp_hover_provider,
                                   IDE_TYPE_OBJECT,
                                   G_ADD_PRIVATE (IdeLspHoverProvider)
-                                  G_IMPLEMENT_INTERFACE (IDE_TYPE_HOVER_PROVIDER, hover_provider_iface_init))
+                                  G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_HOVER_PROVIDER, 
hover_provider_iface_init))
 
 enum {
   PROP_0,
@@ -85,7 +86,7 @@ parse_marked_string (GVariant *v)
   if (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING))
     {
       gsize len = 0;
-      const gchar *str = g_variant_get_string (v, &len);
+      g_autofree char *str = g_strstrip (g_variant_dup_string (v, &len));
 
       if (str && *str == '\0')
         return NULL;
@@ -99,7 +100,7 @@ parse_marked_string (GVariant *v)
 
   if (g_variant_is_of_type (v, G_VARIANT_TYPE_DICTIONARY))
     {
-      const gchar *value = "";
+      const char *value = "";
 
       g_variant_lookup (v, "value", "&s", &value);
       if (!ide_str_empty0 (value))
@@ -120,21 +121,21 @@ parse_marked_string (GVariant *v)
             g_string_append (gstr, g_variant_get_string (asv, NULL));
           else if (g_variant_is_of_type (asv, G_VARIANT_TYPE_VARDICT))
             {
-              const gchar *lang = "";
-              const gchar *value = "";
+              const char *lang = "";
+              const char *value = "";
 
               g_variant_lookup (asv, "language", "&s", &lang);
               g_variant_lookup (asv, "value", "&s", &value);
 
-    #if 0
+#if 0
               if (!ide_str_empty0 (lang) && !ide_str_empty0 (value))
                 g_string_append_printf (str, "```%s\n%s\n```", lang, value);
               else if (!ide_str_empty0 (value))
                 g_string_append (str, value);
-    #else
+#else
               if (!ide_str_empty0 (value))
                 g_string_append_printf (gstr, "```\n%s\n```\n", value);
-    #endif
+#endif
             }
 
           g_variant_unref (item);
@@ -149,6 +150,12 @@ parse_marked_string (GVariant *v)
   return NULL;
 }
 
+static void
+ide_lsp_hover_provider_real_prepare (IdeLspHoverProvider *self)
+{
+  g_assert (IDE_IS_LSP_HOVER_PROVIDER (self));
+}
+
 static void
 ide_lsp_hover_provider_dispose (GObject *object)
 {
@@ -167,9 +174,9 @@ ide_lsp_hover_provider_dispose (GObject *object)
 
 static void
 ide_lsp_hover_provider_get_property (GObject    *object,
-                                          guint       prop_id,
-                                          GValue     *value,
-                                          GParamSpec *pspec)
+                                     guint       prop_id,
+                                     GValue     *value,
+                                     GParamSpec *pspec)
 {
   IdeLspHoverProvider *self = IDE_LSP_HOVER_PROVIDER (object);
   IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
@@ -195,9 +202,9 @@ ide_lsp_hover_provider_get_property (GObject    *object,
 
 static void
 ide_lsp_hover_provider_set_property (GObject      *object,
-                                          guint         prop_id,
-                                          const GValue *value,
-                                          GParamSpec   *pspec)
+                                     guint         prop_id,
+                                     const GValue *value,
+                                     GParamSpec   *pspec)
 {
   IdeLspHoverProvider *self = IDE_LSP_HOVER_PROVIDER (object);
   IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
@@ -231,13 +238,13 @@ ide_lsp_hover_provider_class_init (IdeLspHoverProviderClass *klass)
   object_class->get_property = ide_lsp_hover_provider_get_property;
   object_class->set_property = ide_lsp_hover_provider_set_property;
 
+  klass->prepare = ide_lsp_hover_provider_real_prepare;
+
   /**
    * IdeLspHoverProvider:client:
    *
    * The "client" property is the #IdeLspClient that should be used to
    * communicate with the Language Server peer process.
-   *
-   * Since: 3.30
    */
   properties [PROP_CLIENT] =
     g_param_spec_object ("client",
@@ -251,8 +258,6 @@ ide_lsp_hover_provider_class_init (IdeLspHoverProviderClass *klass)
    *
    * The "category" property is the category name to use when displaying
    * the hover contents.
-   *
-   * Since: 3.30
    */
   properties [PROP_CATEGORY] =
     g_param_spec_string ("category",
@@ -280,18 +285,17 @@ ide_lsp_hover_provider_init (IdeLspHoverProvider *self)
 
 static void
 ide_lsp_hover_provider_hover_cb (GObject      *object,
-                                      GAsyncResult *result,
-                                      gpointer      user_data)
+                                 GAsyncResult *result,
+                                 gpointer      user_data)
 {
   IdeLspClient *client = (IdeLspClient *)object;
-  IdeLspHoverProvider *self;
-  IdeLspHoverProviderPrivate *priv;
   g_autoptr(GVariant) reply = NULL;
   g_autoptr(GVariant) contents = NULL;
   g_autoptr(IdeMarkedContent) marked = NULL;
   g_autoptr(IdeTask) task = user_data;
   g_autoptr(GError) error = NULL;
-  IdeHoverContext *context;
+  GtkSourceHoverDisplay *display;
+  IdeLspHoverProvider *self;
 
   IDE_ENTRY;
 
@@ -300,9 +304,10 @@ ide_lsp_hover_provider_hover_cb (GObject      *object,
   g_assert (IDE_IS_TASK (task));
 
   self = ide_task_get_source_object (task);
-  priv = ide_lsp_hover_provider_get_instance_private (self);
+  display = ide_task_get_task_data (task);
 
   g_assert (IDE_IS_LSP_HOVER_PROVIDER (self));
+  g_assert (GTK_SOURCE_IS_HOVER_DISPLAY (display));
 
   if (!ide_lsp_client_call_finish (client, result, &reply, &error))
     {
@@ -329,15 +334,7 @@ ide_lsp_hover_provider_hover_cb (GObject      *object,
       IDE_EXIT;
     }
 
-  context = ide_task_get_task_data (task);
-
-  g_assert (context != NULL);
-  g_assert (IDE_IS_HOVER_CONTEXT (context));
-
-  ide_hover_context_add_content (context,
-                                 priv->priority,
-                                 priv->category,
-                                 marked);
+  gtk_source_hover_display_append (display, ide_marked_view_new (marked));
 
   ide_task_return_boolean (task, TRUE);
 
@@ -345,33 +342,40 @@ ide_lsp_hover_provider_hover_cb (GObject      *object,
 }
 
 static void
-ide_lsp_hover_provider_hover_async (IdeHoverProvider    *provider,
-                                         IdeHoverContext     *context,
-                                         const GtkTextIter   *iter,
-                                         GCancellable        *cancellable,
-                                         GAsyncReadyCallback  callback,
-                                         gpointer             user_data)
+ide_lsp_hover_provider_populate_async (GtkSourceHoverProvider *provider,
+                                       GtkSourceHoverContext  *context,
+                                       GtkSourceHoverDisplay  *display,
+                                       GCancellable           *cancellable,
+                                       GAsyncReadyCallback     callback,
+                                       gpointer                user_data)
 {
   IdeLspHoverProvider *self = (IdeLspHoverProvider *)provider;
   IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
   g_autoptr(IdeTask) task = NULL;
   g_autoptr(GVariant) params = NULL;
-  g_autofree gchar *uri = NULL;
+  g_autofree char *uri = NULL;
   IdeBuffer *buffer;
-  gint line;
-  gint column;
+  GtkTextIter iter;
+  int line;
+  int column;
 
   IDE_ENTRY;
 
   g_assert (IDE_IS_MAIN_THREAD ());
   g_assert (IDE_IS_LSP_HOVER_PROVIDER (self));
-  g_assert (IDE_IS_HOVER_CONTEXT (context));
-  g_assert (iter != NULL);
+  g_assert (GTK_SOURCE_IS_HOVER_CONTEXT (context));
+  g_assert (GTK_SOURCE_IS_HOVER_DISPLAY (display));
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = ide_task_new (self, cancellable, callback, user_data);
-  ide_task_set_task_data (task, g_object_ref (context), g_object_unref);
-  ide_task_set_source_tag (task, ide_lsp_hover_provider_hover_async);
+  ide_task_set_task_data (task, g_object_ref (display), g_object_unref);
+  ide_task_set_source_tag (task, ide_lsp_hover_provider_populate_async);
+
+  if (!priv->did_prepare)
+    {
+      priv->did_prepare = TRUE;
+      IDE_LSP_HOVER_PROVIDER_GET_CLASS (self)->prepare (self);
+    }
 
   if (priv->client == NULL)
     {
@@ -382,10 +386,12 @@ ide_lsp_hover_provider_hover_async (IdeHoverProvider    *provider,
       return;
     }
 
-  buffer = IDE_BUFFER (gtk_text_iter_get_buffer (iter));
+  buffer = IDE_BUFFER (gtk_source_hover_context_get_buffer (context));
   uri = ide_buffer_dup_uri (buffer);
-  line = gtk_text_iter_get_line (iter);
-  column = gtk_text_iter_get_line_offset (iter);
+
+  gtk_source_hover_context_get_iter (context, &iter);
+  line = gtk_text_iter_get_line (&iter);
+  column = gtk_text_iter_get_line_offset (&iter);
 
   params = JSONRPC_MESSAGE_NEW (
     "textDocument", "{",
@@ -400,19 +406,19 @@ ide_lsp_hover_provider_hover_async (IdeHoverProvider    *provider,
   g_assert (IDE_IS_LSP_CLIENT (priv->client));
 
   ide_lsp_client_call_async (priv->client,
-                                  "textDocument/hover",
-                                  params,
-                                  cancellable,
-                                  ide_lsp_hover_provider_hover_cb,
-                                  g_steal_pointer (&task));
+                             "textDocument/hover",
+                             params,
+                             cancellable,
+                             ide_lsp_hover_provider_hover_cb,
+                             g_steal_pointer (&task));
 
   IDE_EXIT;
 }
 
 static gboolean
-ide_lsp_hover_provider_hover_finish (IdeHoverProvider  *provider,
-                                          GAsyncResult      *result,
-                                          GError           **error)
+ide_lsp_hover_provider_populate_finish (GtkSourceHoverProvider  *provider,
+                                        GAsyncResult            *result,
+                                        GError                 **error)
 {
   gboolean ret;
 
@@ -427,28 +433,10 @@ ide_lsp_hover_provider_hover_finish (IdeHoverProvider  *provider,
 }
 
 static void
-ide_lsp_hover_provider_real_load (IdeHoverProvider *provider,
-                                       IdeSourceView    *view)
-{
-  IdeLspHoverProvider *self = (IdeLspHoverProvider *)provider;
-
-  IDE_ENTRY;
-
-  g_assert (IDE_IS_MAIN_THREAD ());
-  g_assert (IDE_IS_LSP_HOVER_PROVIDER (self));
-
-  if (IDE_LSP_HOVER_PROVIDER_GET_CLASS (self)->prepare)
-    IDE_LSP_HOVER_PROVIDER_GET_CLASS (self)->prepare (self);
-
-  IDE_EXIT;
-}
-
-static void
-hover_provider_iface_init (IdeHoverProviderInterface *iface)
+hover_provider_iface_init (GtkSourceHoverProviderInterface *iface)
 {
-  iface->load = ide_lsp_hover_provider_real_load;
-  iface->hover_async = ide_lsp_hover_provider_hover_async;
-  iface->hover_finish = ide_lsp_hover_provider_hover_finish;
+  iface->populate_async = ide_lsp_hover_provider_populate_async;
+  iface->populate_finish = ide_lsp_hover_provider_populate_finish;
 }
 
 /**
@@ -458,8 +446,6 @@ hover_provider_iface_init (IdeHoverProviderInterface *iface)
  * Gets the client that is used for communication.
  *
  * Returns: (transfer none) (nullable): an #IdeLspClient or %NULL
- *
- * Since: 3.30
  */
 IdeLspClient *
 ide_lsp_hover_provider_get_client (IdeLspHoverProvider *self)
@@ -477,12 +463,10 @@ ide_lsp_hover_provider_get_client (IdeLspHoverProvider *self)
  * @client: an #IdeLspClient
  *
  * Sets the client to be used to query for hover information.
- *
- * Since: 3.30
  */
 void
 ide_lsp_hover_provider_set_client (IdeLspHoverProvider *self,
-                                        IdeLspClient        *client)
+                                   IdeLspClient        *client)
 {
   IdeLspHoverProviderPrivate *priv = ide_lsp_hover_provider_get_instance_private (self);
 
diff --git a/src/libide/lsp/ide-lsp-search-result.c b/src/libide/lsp/ide-lsp-search-result.c
index cf300f11f..ddf22a552 100644
--- a/src/libide/lsp/ide-lsp-search-result.c
+++ b/src/libide/lsp/ide-lsp-search-result.c
@@ -18,9 +18,12 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
+#define G_LOG_DOMAIN "ide-lsp-search-result"
+
 #include "config.h"
 
 #include "ide-lsp-search-result.h"
+
 #include <libide-core.h>
 #include <libide-editor.h>
 
@@ -109,17 +112,14 @@ ide_lsp_search_result_activate (IdeSearchResult *result,
 
   IdeLspSearchResult *self = (IdeLspSearchResult *)result;
   IdeWorkspace *workspace;
-  IdeSurface *editor;
 
   g_assert (IDE_IS_LSP_SEARCH_RESULT (self));
   g_assert (GTK_IS_WIDGET (last_focus));
 
-  if (!last_focus)
+  if (!last_focus || !(workspace = ide_widget_get_workspace (last_focus)))
     return;
 
-  if ((workspace = ide_widget_get_workspace (last_focus)) &&
-      (editor = ide_workspace_get_surface_by_name (workspace, "editor")))
-    ide_editor_surface_focus_location (IDE_EDITOR_SURFACE (editor), self->location);
+  ide_editor_focus_location (workspace, NULL, self->location);
 }
 
 static void
diff --git a/src/libide/lsp/ide-lsp-service.c b/src/libide/lsp/ide-lsp-service.c
index 5153cddf3..4acaed6d3 100644
--- a/src/libide/lsp/ide-lsp-service.c
+++ b/src/libide/lsp/ide-lsp-service.c
@@ -28,8 +28,6 @@
  * SECTION:ide-lsp-service
  * @title: IdeLspService
  * @short_description: Service integration for LSPs
- *
- * Since: 42.0
  */
 
 typedef struct
@@ -199,6 +197,7 @@ ide_lsp_service_real_create_launcher (IdeLspService    *self,
 
   IDE_ENTRY;
 
+  g_assert (IDE_IS_MAIN_THREAD ());
   g_assert (IDE_IS_LSP_SERVICE (self));
   g_assert (IDE_IS_PIPELINE (pipeline));
 
@@ -228,11 +227,16 @@ ide_lsp_service_real_create_launcher (IdeLspService    *self,
 
       if (ide_runtime_contains_program_in_path (host, priv->program, NULL))
         {
-          if ((launcher = ide_runtime_create_launcher (host, NULL)))
+          g_autoptr(IdeRunContext) run_context = NULL;
+
+          run_context = ide_run_context_new ();
+          ide_runtime_prepare_to_build (host, pipeline, run_context);
+          ide_run_context_append_argv (run_context, priv->program);
+          ide_run_context_set_cwd (run_context, srcdir);
+
+          if ((launcher = ide_run_context_end (run_context, NULL)))
             {
               ide_subprocess_launcher_set_flags (launcher, flags);
-              ide_subprocess_launcher_push_argv (launcher, priv->program);
-              ide_subprocess_launcher_set_cwd (launcher, srcdir);
               IDE_RETURN (g_steal_pointer (&launcher));
             }
         }
@@ -248,11 +252,16 @@ ide_lsp_service_real_create_launcher (IdeLspService    *self,
 
               if (g_file_test (path, G_FILE_TEST_IS_EXECUTABLE))
                 {
-                  if ((launcher = ide_runtime_create_launcher (host, NULL)))
+                  g_autoptr(IdeRunContext) run_context = NULL;
+
+                  run_context = ide_run_context_new ();
+                  ide_runtime_prepare_to_build (host, pipeline, run_context);
+                  ide_run_context_append_argv (run_context, path);
+                  ide_run_context_set_cwd (run_context, srcdir);
+
+                  if ((launcher = ide_run_context_end (run_context, NULL)))
                     {
-                      ide_subprocess_launcher_push_argv (launcher, path);
                       ide_subprocess_launcher_set_flags (launcher, flags);
-                      ide_subprocess_launcher_set_cwd (launcher, srcdir);
                       IDE_RETURN (g_steal_pointer (&launcher));
                     }
                 }
diff --git a/src/libide/lsp/meson.build b/src/libide/lsp/meson.build
index 620170d74..f623287d5 100644
--- a/src/libide/lsp/meson.build
+++ b/src/libide/lsp/meson.build
@@ -91,7 +91,6 @@ libide_lsp_sources = libide_lsp_public_sources + libide_lsp_private_sources + li
 libide_lsp_deps = [
   libgio_dep,
   libjsonrpc_glib_dep,
-  libdazzle_dep,
 
   libide_code_dep,
   libide_core_dep,


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