[gnome-builder/wip/symbol-tree] symbol-tree: jump to symbol when activated



commit 1e0fbcd6ecb27c2db8ada7a636006d737c3a59e9
Author: Christian Hergert <christian hergert me>
Date:   Thu Jun 18 19:38:52 2015 -0700

    symbol-tree: jump to symbol when activated

 libide/clang/ide-clang-private.h          |   15 ++++----
 libide/clang/ide-clang-symbol-node.c      |   55 ++++++++++++++++++++++++++---
 libide/clang/ide-clang-symbol-tree.c      |    7 +++-
 libide/clang/ide-clang-symbol-tree.h      |    2 +-
 libide/clang/ide-clang-translation-unit.c |    4 ++
 libide/ide-file.c                         |   10 +++++-
 libide/ide-symbol-node.c                  |   10 +++++-
 libide/ide-symbol-node.h                  |   15 +++++---
 plugins/symbol-tree/symbol-tree-builder.c |   40 +++++++++++++++++++++
 9 files changed, 136 insertions(+), 22 deletions(-)
---
diff --git a/libide/clang/ide-clang-private.h b/libide/clang/ide-clang-private.h
index 496b9f2..6505e0f 100644
--- a/libide/clang/ide-clang-private.h
+++ b/libide/clang/ide-clang-private.h
@@ -30,13 +30,14 @@
 
 G_BEGIN_DECLS
 
-IdeClangTranslationUnit *_ide_clang_translation_unit_new     (IdeContext        *context,
-                                                              CXTranslationUnit  tu,
-                                                              GFile             *file,
-                                                              IdeHighlightIndex *index,
-                                                              gint64             serial);
-void                     _ide_clang_dispose_string           (CXString          *str);
-IdeSymbolNode           *_ide_clang_symbol_node_new          (CXCursor           cursor);
+IdeClangTranslationUnit *_ide_clang_translation_unit_new     (IdeContext         *context,
+                                                              CXTranslationUnit   tu,
+                                                              GFile              *file,
+                                                              IdeHighlightIndex  *index,
+                                                              gint64              serial);
+void                     _ide_clang_dispose_string           (CXString           *str);
+IdeSymbolNode           *_ide_clang_symbol_node_new          (IdeContext         *context,
+                                                              CXCursor            cursor);
 CXCursor                 _ide_clang_symbol_node_get_cursor   (IdeClangSymbolNode *self);
 GArray                  *_ide_clang_symbol_node_get_children (IdeClangSymbolNode *self);
 void                     _ide_clang_symbol_node_set_children (IdeClangSymbolNode *self,
diff --git a/libide/clang/ide-clang-symbol-node.c b/libide/clang/ide-clang-symbol-node.c
index cfb25e7..79d831f 100644
--- a/libide/clang/ide-clang-symbol-node.c
+++ b/libide/clang/ide-clang-symbol-node.c
@@ -17,8 +17,10 @@
  */
 
 #include <clang-c/Index.h>
+#include <gio/gio.h>
 
 #include "ide-clang-symbol-node.h"
+#include "ide-file.h"
 #include "ide-symbol.h"
 
 struct _IdeClangSymbolNode
@@ -122,21 +124,19 @@ get_symbol_kind (CXCursor        cursor,
 }
 
 IdeClangSymbolNode *
-_ide_clang_symbol_node_new (CXCursor cursor)
+_ide_clang_symbol_node_new (IdeContext *context,
+                            CXCursor    cursor)
 {
   IdeClangSymbolNode *self;
   IdeSymbolFlags flags = 0;
   IdeSymbolKind kind;
   CXString cxname;
 
-  /*
-   * TODO: Create IdeSourceLocation for cursor.
-   */
-
   kind = get_symbol_kind (cursor, &flags);
   cxname = clang_getCursorSpelling (cursor);
 
   self = g_object_new (IDE_TYPE_CLANG_SYMBOL_NODE,
+                       "context", context,
                        "kind", kind,
                        "flags", flags,
                        "name", clang_getCString (cxname),
@@ -157,9 +157,54 @@ _ide_clang_symbol_node_get_cursor (IdeClangSymbolNode *self)
   return self->cursor;
 }
 
+static IdeSourceLocation *
+ide_clang_symbol_node_get_location (IdeSymbolNode *symbol_node)
+{
+  IdeClangSymbolNode *self = (IdeClangSymbolNode *)symbol_node;
+  IdeSourceLocation *ret;
+  IdeContext *context;
+  const gchar *filename;
+  CXString cxfilename;
+  CXSourceLocation cxloc;
+  CXFile file;
+  GFile *gfile;
+  IdeFile *ifile;
+  guint line = 0;
+  guint line_offset = 0;
+
+  g_return_val_if_fail (IDE_IS_CLANG_SYMBOL_NODE (self), NULL);
+
+  cxloc = clang_getCursorLocation (self->cursor);
+  clang_getFileLocation (cxloc, &file, &line, &line_offset, NULL);
+  cxfilename = clang_getFileName (file);
+  filename = clang_getCString (cxfilename);
+
+  /*
+   * TODO: Remove IdeFile from all this junk.
+   */
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+  gfile = g_file_new_for_path (filename);
+  ifile = g_object_new (IDE_TYPE_FILE,
+                        "file", gfile,
+                        "context", context,
+                        NULL);
+
+  ret = ide_source_location_new (ifile, line-1, line_offset-1, 0);
+
+  g_clear_object (&ifile);
+  g_clear_object (&gfile);
+  clang_disposeString (cxfilename);
+
+  return ret;
+}
+
 static void
 ide_clang_symbol_node_class_init (IdeClangSymbolNodeClass *klass)
 {
+  IdeSymbolNodeClass *node_class = IDE_SYMBOL_NODE_CLASS (klass);
+
+  node_class->get_location = ide_clang_symbol_node_get_location;
 }
 
 static void
diff --git a/libide/clang/ide-clang-symbol-tree.c b/libide/clang/ide-clang-symbol-tree.c
index 3276571..8ea22cd 100644
--- a/libide/clang/ide-clang-symbol-tree.c
+++ b/libide/clang/ide-clang-symbol-tree.c
@@ -42,7 +42,7 @@ typedef struct
 
 static void symbol_tree_iface_init (IdeSymbolTreeInterface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (IdeClangSymbolTree, ide_clang_symbol_tree, G_TYPE_OBJECT,
+G_DEFINE_TYPE_WITH_CODE (IdeClangSymbolTree, ide_clang_symbol_tree, IDE_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (IDE_TYPE_SYMBOL_TREE, symbol_tree_iface_init))
 
 enum {
@@ -188,11 +188,14 @@ ide_clang_symbol_tree_get_nth_child (IdeSymbolTree *symbol_tree,
                                      guint          nth)
 {
   IdeClangSymbolTree *self = (IdeClangSymbolTree *)symbol_tree;
+  IdeContext *context;
   GArray *children;
 
   g_return_val_if_fail (IDE_IS_CLANG_SYMBOL_TREE (self), NULL);
   g_return_val_if_fail (!parent || IDE_IS_SYMBOL_NODE (parent), NULL);
 
+  context = ide_object_get_context (IDE_OBJECT (self));
+
   if (parent == NULL)
     children = self->children;
   else
@@ -205,7 +208,7 @@ ide_clang_symbol_tree_get_nth_child (IdeSymbolTree *symbol_tree,
       CXCursor cursor;
 
       cursor = g_array_index (children, CXCursor, nth);
-      return _ide_clang_symbol_node_new (cursor);
+      return _ide_clang_symbol_node_new (context, cursor);
     }
 
   g_warning ("nth child %u is out of bounds", nth);
diff --git a/libide/clang/ide-clang-symbol-tree.h b/libide/clang/ide-clang-symbol-tree.h
index f4376ad..fb879a3 100644
--- a/libide/clang/ide-clang-symbol-tree.h
+++ b/libide/clang/ide-clang-symbol-tree.h
@@ -27,7 +27,7 @@ G_BEGIN_DECLS
 
 #define IDE_TYPE_CLANG_SYMBOL_TREE (ide_clang_symbol_tree_get_type())
 
-G_DECLARE_FINAL_TYPE (IdeClangSymbolTree, ide_clang_symbol_tree, IDE, CLANG_SYMBOL_TREE, GObject)
+G_DECLARE_FINAL_TYPE (IdeClangSymbolTree, ide_clang_symbol_tree, IDE, CLANG_SYMBOL_TREE, IdeObject)
 
 GFile *ide_clang_symbol_tree_get_file (IdeClangSymbolTree *self);
 
diff --git a/libide/clang/ide-clang-translation-unit.c b/libide/clang/ide-clang-translation-unit.c
index e452f4a..22b95be 100644
--- a/libide/clang/ide-clang-translation-unit.c
+++ b/libide/clang/ide-clang-translation-unit.c
@@ -1080,13 +1080,17 @@ ide_clang_translation_unit_get_symbol_tree_async (IdeClangTranslationUnit *self,
 {
   g_autoptr(GTask) task = NULL;
   IdeSymbolTree *symbol_tree;
+  IdeContext *context;
 
   g_return_if_fail (IDE_IS_CLANG_TRANSLATION_UNIT (self));
   g_return_if_fail (G_IS_FILE (file));
   g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
 
   task = g_task_new (self, cancellable, callback, user_data);
+
+  context = ide_object_get_context (IDE_OBJECT (self));
   symbol_tree = g_object_new (IDE_TYPE_CLANG_SYMBOL_TREE,
+                              "context", context,
                               "native", self->native,
                               "file", file,
                               NULL);
diff --git a/libide/ide-file.c b/libide/ide-file.c
index 33ee045..6affa20 100644
--- a/libide/ide-file.c
+++ b/libide/ide-file.c
@@ -120,7 +120,6 @@ static void
 ide_file_create_language (IdeFile *self)
 {
   g_assert (IDE_IS_FILE (self));
-  g_assert (self->path);
 
   if (g_once_init_enter (&self->language))
     {
@@ -268,6 +267,14 @@ ide_file_get_path (IdeFile *self)
 {
   g_return_val_if_fail (IDE_IS_FILE (self), NULL);
 
+  if (g_once_init_enter (&self->path))
+    {
+      gchar *path;
+
+      path = g_file_get_path (self->file);
+      g_once_init_leave (&self->path, path);
+    }
+
   return self->path;
 }
 
@@ -278,6 +285,7 @@ ide_file_set_path (IdeFile     *self,
   g_return_if_fail (IDE_IS_FILE (self));
   g_return_if_fail (!self->path);
 
+  g_clear_pointer (&self->path, g_free);
   self->path = g_strdup (path);
 }
 
diff --git a/libide/ide-symbol-node.c b/libide/ide-symbol-node.c
index 9e1b02a..f52d67e 100644
--- a/libide/ide-symbol-node.c
+++ b/libide/ide-symbol-node.c
@@ -29,7 +29,7 @@ typedef struct
   IdeSymbolKind   kind;
 } IdeSymbolNodePrivate;
 
-G_DEFINE_TYPE_WITH_PRIVATE (IdeSymbolNode, ide_symbol_node, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (IdeSymbolNode, ide_symbol_node, IDE_TYPE_OBJECT)
 
 enum {
   PROP_0,
@@ -176,3 +176,11 @@ ide_symbol_node_get_kind (IdeSymbolNode *self)
 
   return priv->kind;
 }
+
+IdeSourceLocation *
+ide_symbol_node_get_location (IdeSymbolNode *self)
+{
+  g_return_val_if_fail (IDE_IS_SYMBOL_NODE (self), NULL);
+
+  return IDE_SYMBOL_NODE_GET_CLASS (self)->get_location (self);
+}
diff --git a/libide/ide-symbol-node.h b/libide/ide-symbol-node.h
index feb2afe..771b25d 100644
--- a/libide/ide-symbol-node.h
+++ b/libide/ide-symbol-node.h
@@ -19,22 +19,27 @@
 #ifndef IDE_SYMBOL_NODE_H
 #define IDE_SYMBOL_NODE_H
 
+#include "ide-object.h"
 #include "ide-symbol.h"
+#include "ide-source-location.h"
 
 G_BEGIN_DECLS
 
 #define IDE_TYPE_SYMBOL_NODE (ide_symbol_node_get_type())
 
-G_DECLARE_DERIVABLE_TYPE (IdeSymbolNode, ide_symbol_node, IDE, SYMBOL_NODE, GObject)
+G_DECLARE_DERIVABLE_TYPE (IdeSymbolNode, ide_symbol_node, IDE, SYMBOL_NODE, IdeObject)
 
 struct _IdeSymbolNodeClass
 {
-  GObjectClass parent;
+  IdeObjectClass parent;
+
+  IdeSourceLocation *(*get_location) (IdeSymbolNode *self);
 };
 
-IdeSymbolKind   ide_symbol_node_get_kind  (IdeSymbolNode *self);
-IdeSymbolFlags  ide_symbol_node_get_flags (IdeSymbolNode *self);
-const gchar    *ide_symbol_node_get_name  (IdeSymbolNode *self);
+IdeSymbolKind      ide_symbol_node_get_kind     (IdeSymbolNode *self);
+IdeSymbolFlags     ide_symbol_node_get_flags    (IdeSymbolNode *self);
+const gchar       *ide_symbol_node_get_name     (IdeSymbolNode *self);
+IdeSourceLocation *ide_symbol_node_get_location (IdeSymbolNode *self);
 
 G_END_DECLS
 
diff --git a/plugins/symbol-tree/symbol-tree-builder.c b/plugins/symbol-tree/symbol-tree-builder.c
index 2b45827..4e51f63 100644
--- a/plugins/symbol-tree/symbol-tree-builder.c
+++ b/plugins/symbol-tree/symbol-tree-builder.c
@@ -19,6 +19,8 @@
 #include <glib/gi18n.h>
 
 #include "gb-tree.h"
+#include "gb-view-grid.h"
+#include "gb-workbench.h"
 
 #include "symbol-tree-builder.h"
 
@@ -118,12 +120,50 @@ symbol_tree_builder_build_node (GbTreeBuilder *builder,
     }
 }
 
+static gboolean
+symbol_tree_builder_node_activated (GbTreeBuilder *builder,
+                                    GbTreeNode    *node)
+{
+  SymbolTreeBuilder *self = (SymbolTreeBuilder *)builder;
+  GtkWidget *workbench;
+  GtkWidget *view_grid;
+  GtkWidget *stack;
+  GbTree *tree;
+  GObject *item;
+
+  g_assert (SYMBOL_IS_TREE_BUILDER (self));
+
+  tree = gb_tree_builder_get_tree (builder);
+  workbench = gtk_widget_get_ancestor (GTK_WIDGET (tree), GB_TYPE_WORKBENCH);
+  view_grid = gb_workbench_get_view_grid (GB_WORKBENCH (workbench));
+  stack = gb_view_grid_get_last_focus (GB_VIEW_GRID (view_grid));
+
+  item = gb_tree_node_get_item (node);
+
+  if (IDE_IS_SYMBOL_NODE (item))
+    {
+      g_autoptr(IdeSourceLocation) location = NULL;
+
+      location = ide_symbol_node_get_location (IDE_SYMBOL_NODE (item));
+      if (location != NULL)
+        {
+          gb_view_stack_focus_location (GB_VIEW_STACK (stack), location);
+          return TRUE;
+        }
+    }
+
+  g_warning ("IdeSymbolNode did not create a source location");
+
+  return FALSE;
+}
+
 static void
 symbol_tree_builder_class_init (SymbolTreeBuilderClass *klass)
 {
   GbTreeBuilderClass *builder_class = GB_TREE_BUILDER_CLASS (klass);
 
   builder_class->build_node = symbol_tree_builder_build_node;
+  builder_class->node_activated = symbol_tree_builder_node_activated;
 }
 
 static void


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