[gnome-builder/wip/chergert/hover] symbol-tree: add hover provider to display symbol info
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/hover] symbol-tree: add hover provider to display symbol info
- Date: Wed, 4 Jul 2018 08:40:47 +0000 (UTC)
commit 6446c25ceb2d5ada47754790f1a6a2d3f1d98cbf
Author: Christian Hergert <chergert redhat com>
Date: Tue Jul 3 08:29:52 2018 -0700
symbol-tree: add hover provider to display symbol info
This adds a new hover provider that will display the name of the
symbol for the type being hovered. It also provides links to the
definition, declaration, and canonical location if provided by
the symbol resolver.
The user can click on the link to be taken to directly to the
source location.
.../symbol-tree/gbp-symbol-hover-provider.c | 222 +++++++++++++++++++++
.../symbol-tree/gbp-symbol-hover-provider.h | 29 +++
src/plugins/symbol-tree/meson.build | 1 +
src/plugins/symbol-tree/symbol-tree-plugin.c | 4 +
4 files changed, 256 insertions(+)
---
diff --git a/src/plugins/symbol-tree/gbp-symbol-hover-provider.c
b/src/plugins/symbol-tree/gbp-symbol-hover-provider.c
new file mode 100644
index 000000000..147582a80
--- /dev/null
+++ b/src/plugins/symbol-tree/gbp-symbol-hover-provider.c
@@ -0,0 +1,222 @@
+/* gbp-symbol-hover-provider.c
+ *
+ * Copyright 2018 Christian Hergert <chergert redhat com>
+ *
+ * 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 "config.h"
+
+#define G_LOG_DOMAIN "gbp-symbol-hover-provider"
+
+#include <glib/gi18n.h>
+
+#include "gbp-symbol-hover-provider.h"
+
+struct _GbpSymbolHoverProvider
+{
+ GObject parent_instance;
+};
+
+static gboolean
+on_activate_link (GbpSymbolHoverProvider *self,
+ const gchar *uristr,
+ GtkLabel *label)
+{
+ IdeWorkbench *workbench;
+ g_autoptr(IdeUri) uri = NULL;
+
+ g_assert (GBP_IS_SYMBOL_HOVER_PROVIDER (self));
+ g_assert (uristr != NULL);
+ g_assert (GTK_IS_LABEL (label));
+
+ workbench = ide_widget_get_workbench (GTK_WIDGET (label));
+ uri = ide_uri_new (uristr, 0, NULL);
+
+ if (!uri || !workbench)
+ return FALSE;
+
+ ide_workbench_open_uri_async (workbench,
+ uri,
+ "editor",
+ IDE_WORKBENCH_OPEN_FLAGS_NONE,
+ NULL, NULL, NULL);
+
+ return TRUE;
+}
+
+static void
+gbp_symbol_hover_provider_get_symbol_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeBuffer *buffer = (IdeBuffer *)object;
+ GbpSymbolHoverProvider *self;
+ g_autoptr(IdeTask) task = user_data;
+ g_autoptr(IdeSymbol) symbol = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GString) str = NULL;
+ g_autoptr(IdeMarkedContent) content = NULL;
+ g_autofree gchar *tt = NULL;
+ IdeHoverContext *context;
+ const gchar *name;
+ GtkWidget *box;
+ struct {
+ const gchar *kind;
+ IdeSourceLocation *loc;
+ } loc[3] = {
+ { _("Declaration"), NULL },
+ { _("Definition"), NULL },
+ { _("Canonincal"), NULL },
+ };
+
+ g_assert (IDE_IS_BUFFER (buffer));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (IDE_IS_TASK (task));
+
+ if (!(symbol = ide_buffer_get_symbol_at_location_finish (buffer, result, &error)))
+ {
+ ide_task_return_boolean (task, TRUE);
+ return;
+ }
+
+ self = ide_task_get_source_object (task);
+ context = ide_task_get_task_data (task);
+
+ g_assert (GBP_IS_SYMBOL_HOVER_PROVIDER (self));
+ g_assert (context != NULL);
+ g_assert (IDE_IS_HOVER_CONTEXT (context));
+
+ loc[0].loc = ide_symbol_get_declaration_location (symbol);
+ loc[1].loc = ide_symbol_get_definition_location (symbol);
+ loc[2].loc = ide_symbol_get_canonical_location (symbol);
+
+ if (!loc[0].loc && !loc[1].loc && !loc[2].loc)
+ {
+ ide_task_return_boolean (task, TRUE);
+ return;
+ }
+
+ box = g_object_new (GTK_TYPE_BOX,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "visible", TRUE,
+ NULL);
+
+ name = ide_symbol_get_name (symbol);
+ if (!name || !*name)
+ name = _("Unnamed Symbol");
+
+ tt = g_strdup_printf ("<tt><span size='smaller'>%s</span></tt>", name);
+ gtk_container_add (GTK_CONTAINER (box),
+ g_object_new (GTK_TYPE_LABEL,
+ "visible", TRUE,
+ "xalign", 0.0f,
+ "margin-bottom", 3,
+ "use-markup", TRUE,
+ "label", tt,
+ NULL));
+
+
+ for (guint i = 0; i < G_N_ELEMENTS (loc); i++)
+ {
+ if (loc[i].loc != NULL)
+ {
+ GtkWidget *label;
+ g_autoptr(IdeUri) uri = ide_source_location_get_uri (loc[i].loc);
+ g_autoptr(GFile) file = ide_uri_to_file (uri);
+ g_autofree gchar *uristr = ide_uri_to_string (uri, 0);
+ g_autofree gchar *base = g_file_get_basename (file);
+ g_autofree gchar *escaped = g_markup_escape_text (uristr, -1);
+ g_autofree gchar *markup = g_strdup_printf ("<span size='smaller'>%s: <a href='%s'>%s</a></span>",
+ loc[i].kind, escaped, base);
+
+ label = g_object_new (GTK_TYPE_LABEL,
+ "visible", TRUE,
+ "margin-left", 6,
+ "xalign", 0.0f,
+ "use-markup", TRUE,
+ "label", markup,
+ NULL);
+ g_signal_connect_object (label,
+ "activate-link",
+ G_CALLBACK (on_activate_link),
+ self,
+ G_CONNECT_SWAPPED);
+ gtk_container_add (GTK_CONTAINER (box), label);
+ }
+ }
+
+ ide_hover_context_add_widget (context, _("Symbol"), box);
+ ide_task_return_boolean (task, TRUE);
+}
+
+static void
+gbp_symbol_hover_provider_hover_async (IdeHoverProvider *provider,
+ IdeHoverContext *context,
+ const GtkTextIter *iter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GbpSymbolHoverProvider *self = (GbpSymbolHoverProvider *)provider;
+ g_autoptr(IdeTask) task = NULL;
+ IdeBuffer *buffer;
+
+ g_assert (GBP_IS_SYMBOL_HOVER_PROVIDER (self));
+ g_assert (IDE_IS_HOVER_CONTEXT (context));
+ g_assert (iter != NULL);
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_source_tag (task, gbp_symbol_hover_provider_hover_async);
+ ide_task_set_task_data (task, g_object_ref (context), g_object_unref);
+
+ buffer = IDE_BUFFER (gtk_text_iter_get_buffer (iter));
+ ide_buffer_get_symbol_at_location_async (buffer,
+ iter,
+ cancellable,
+ gbp_symbol_hover_provider_get_symbol_cb,
+ g_steal_pointer (&task));
+}
+
+static gboolean
+gbp_symbol_hover_provider_hover_finish (IdeHoverProvider *provider,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_assert (GBP_IS_SYMBOL_HOVER_PROVIDER (provider));
+ g_assert (IDE_IS_TASK (result));
+
+ return ide_task_propagate_boolean (IDE_TASK (result), error);
+}
+
+static void
+hover_provider_iface_init (IdeHoverProviderInterface *iface)
+{
+ iface->hover_async = gbp_symbol_hover_provider_hover_async;
+ iface->hover_finish = gbp_symbol_hover_provider_hover_finish;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GbpSymbolHoverProvider, gbp_symbol_hover_provider, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_HOVER_PROVIDER, hover_provider_iface_init))
+
+static void
+gbp_symbol_hover_provider_class_init (GbpSymbolHoverProviderClass *klass)
+{
+}
+
+static void
+gbp_symbol_hover_provider_init (GbpSymbolHoverProvider *self)
+{
+}
diff --git a/src/plugins/symbol-tree/gbp-symbol-hover-provider.h
b/src/plugins/symbol-tree/gbp-symbol-hover-provider.h
new file mode 100644
index 000000000..8ff472a9d
--- /dev/null
+++ b/src/plugins/symbol-tree/gbp-symbol-hover-provider.h
@@ -0,0 +1,29 @@
+/* gbp-symbol-hover-provider.h
+ *
+ * Copyright 2018 Christian Hergert <chergert redhat com>
+ *
+ * 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/>.
+ */
+
+#pragma once
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_SYMBOL_HOVER_PROVIDER (gbp_symbol_hover_provider_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpSymbolHoverProvider, gbp_symbol_hover_provider, GBP, SYMBOL_HOVER_PROVIDER, GObject)
+
+G_END_DECLS
diff --git a/src/plugins/symbol-tree/meson.build b/src/plugins/symbol-tree/meson.build
index 7db64e259..a085ab773 100644
--- a/src/plugins/symbol-tree/meson.build
+++ b/src/plugins/symbol-tree/meson.build
@@ -7,6 +7,7 @@ symbol_tree_resources = gnome.compile_resources(
)
symbol_tree_sources = [
+ 'gbp-symbol-hover-provider.c',
'gbp-symbol-layout-stack-addin.c',
'gbp-symbol-layout-stack-addin.h',
'gbp-symbol-menu-button.c',
diff --git a/src/plugins/symbol-tree/symbol-tree-plugin.c b/src/plugins/symbol-tree/symbol-tree-plugin.c
index 4c0754bfb..9b9d5cb92 100644
--- a/src/plugins/symbol-tree/symbol-tree-plugin.c
+++ b/src/plugins/symbol-tree/symbol-tree-plugin.c
@@ -20,6 +20,7 @@
#include <ide.h>
#include "gbp-symbol-layout-stack-addin.h"
+#include "gbp-symbol-hover-provider.h"
void
gbp_symbol_tree_register_types (PeasObjectModule *module)
@@ -27,4 +28,7 @@ gbp_symbol_tree_register_types (PeasObjectModule *module)
peas_object_module_register_extension_type (module,
IDE_TYPE_LAYOUT_STACK_ADDIN,
GBP_TYPE_SYMBOL_LAYOUT_STACK_ADDIN);
+ peas_object_module_register_extension_type (module,
+ IDE_TYPE_HOVER_PROVIDER,
+ GBP_TYPE_SYMBOL_HOVER_PROVIDER);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]