[gnome-builder/wip/ggit] change-monitor: wire up diff callback using libgit2-glib.
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/ggit] change-monitor: wire up diff callback using libgit2-glib.
- Date: Mon, 29 Sep 2014 05:51:59 +0000 (UTC)
commit 4c9324d4db4bd4ffbd76af01ad1451353182274e
Author: Christian Hergert <christian hergert me>
Date: Sun Sep 28 22:51:44 2014 -0700
change-monitor: wire up diff callback using libgit2-glib.
This seems to mostly get things working using libgit2-glib instead of
the built in monitor for the file.
What we might consider doing next is when opening the file, determine
which version to use. We can keep the old version around for files that
are not yet in a source tree and this around for files that are in a
source tree.
Further refactoring necessary.
src/editor/gb-source-change-gutter-renderer.c | 24 ++++-
src/editor/gb-source-change-monitor.c | 117 ++++++++++++++++++++++++-
src/editor/gb-source-change-monitor.h | 7 +-
3 files changed, 138 insertions(+), 10 deletions(-)
---
diff --git a/src/editor/gb-source-change-gutter-renderer.c b/src/editor/gb-source-change-gutter-renderer.c
index 882f1cf..2d3598b 100644
--- a/src/editor/gb-source-change-gutter-renderer.c
+++ b/src/editor/gb-source-change-gutter-renderer.c
@@ -48,6 +48,18 @@ gb_source_change_gutter_renderer_get_change_monitor (GbSourceChangeGutterRendere
}
static void
+on_changed (GbSourceChangeMonitor *monitor,
+ GbSourceChangeGutterRenderer *renderer)
+{
+ GtkTextView *text_view;
+
+ g_return_val_if_fail (GB_IS_SOURCE_CHANGE_GUTTER_RENDERER (renderer), NULL);
+
+ text_view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (renderer));
+ gtk_widget_queue_draw (GTK_WIDGET (text_view));
+}
+
+static void
gb_source_change_gutter_renderer_set_change_monitor (GbSourceChangeGutterRenderer *renderer,
GbSourceChangeMonitor *monitor)
{
@@ -60,6 +72,9 @@ gb_source_change_gutter_renderer_set_change_monitor (GbSourceChangeGutterRendere
if (priv->change_monitor)
{
+ g_signal_handlers_disconnect_by_func (priv->change_monitor,
+ G_CALLBACK (on_changed),
+ renderer);
g_object_remove_weak_pointer (G_OBJECT (monitor),
(gpointer *)&priv->change_monitor);
priv->change_monitor = NULL;
@@ -70,6 +85,10 @@ gb_source_change_gutter_renderer_set_change_monitor (GbSourceChangeGutterRendere
priv->change_monitor = monitor;
g_object_add_weak_pointer (G_OBJECT (monitor),
(gpointer *)&priv->change_monitor);
+ g_signal_connect (priv->change_monitor,
+ "changed",
+ G_CALLBACK (on_changed),
+ renderer);
}
}
@@ -108,11 +127,6 @@ gb_source_change_gutter_renderer_draw (GtkSourceGutterRenderer *renderer,
if ((flags & GB_SOURCE_CHANGE_CHANGED) != 0)
gdk_rgba_parse (&rgba, "#fcaf3e");
- if ((flags & GB_SOURCE_CHANGE_DIRTY) == 0)
- {
- gdk_rgba_parse (&rgba, "rgb(179,208,238)");
- }
-
gdk_cairo_rectangle (cr, cell_area);
gdk_cairo_set_source_rgba (cr, &rgba);
cairo_fill (cr);
diff --git a/src/editor/gb-source-change-monitor.c b/src/editor/gb-source-change-monitor.c
index 5fe80ee..4d21994 100644
--- a/src/editor/gb-source-change-monitor.c
+++ b/src/editor/gb-source-change-monitor.c
@@ -25,7 +25,9 @@
#include "gb-log.h"
#include "gb-source-change-monitor.h"
-#define PARSE_TIMEOUT_MSEC 1000
+#define PARSE_TIMEOUT_MSEC 100
+#define GB_SOURCE_CHANGE_DELETED (1 << 3)
+#define GB_SOURCE_CHANGE_MASK (0x7)
struct _GbSourceChangeMonitorPrivate
{
@@ -45,11 +47,18 @@ enum
LAST_PROP
};
+enum
+{
+ CHANGED,
+ LAST_SIGNAL
+};
+
G_DEFINE_TYPE_WITH_PRIVATE (GbSourceChangeMonitor,
gb_source_change_monitor,
G_TYPE_OBJECT)
static GParamSpec *gParamSpecs [LAST_PROP];
+static guint gSignals [LAST_SIGNAL];
GbSourceChangeFlags
gb_source_change_monitor_get_line (GbSourceChangeMonitor *monitor,
@@ -57,22 +66,95 @@ gb_source_change_monitor_get_line (GbSourceChangeMonitor *monitor,
{
g_return_val_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor), 0);
+ /*
+ * We store line numbers as 1 based to simply the diff code.
+ */
+ lineno++;
+
if (monitor->priv->state)
{
gpointer value;
value = g_hash_table_lookup (monitor->priv->state,
GINT_TO_POINTER (lineno));
- return GPOINTER_TO_INT (value);
+ return (GPOINTER_TO_INT (value) & GB_SOURCE_CHANGE_MASK);
}
return GB_SOURCE_CHANGE_NONE;
}
+static gint
+diff_line_cb (GgitDiffDelta *delta,
+ GgitDiffHunk *hunk,
+ GgitDiffLine *line,
+ gpointer user_data)
+{
+ GgitDiffLineType type;
+ GHashTable *hash = user_data;
+ gint new_lineno;
+ gint old_lineno;
+ gint adjust;
+
+ g_return_val_if_fail (delta, GGIT_ERROR_GIT_ERROR);
+ g_return_val_if_fail (hunk, GGIT_ERROR_GIT_ERROR);
+ g_return_val_if_fail (line, GGIT_ERROR_GIT_ERROR);
+ g_return_val_if_fail (hash, GGIT_ERROR_GIT_ERROR);
+
+ type = ggit_diff_line_get_origin (line);
+
+ if ((type != GGIT_DIFF_LINE_ADDITION) && (type != GGIT_DIFF_LINE_DELETION))
+ return 0;
+
+ new_lineno = ggit_diff_line_get_new_lineno (line);
+ old_lineno = ggit_diff_line_get_old_lineno (line);
+
+ switch (type)
+ {
+ case GGIT_DIFF_LINE_ADDITION:
+ if (g_hash_table_lookup (hash, GINT_TO_POINTER (new_lineno)))
+ g_hash_table_replace (hash,
+ GINT_TO_POINTER (new_lineno),
+ GINT_TO_POINTER (GB_SOURCE_CHANGE_CHANGED));
+ else
+ g_hash_table_insert (hash,
+ GINT_TO_POINTER (new_lineno),
+ GINT_TO_POINTER (GB_SOURCE_CHANGE_ADDED));
+ break;
+
+ case GGIT_DIFF_LINE_DELETION:
+ adjust = (ggit_diff_hunk_get_new_start (hunk) -
+ ggit_diff_hunk_get_old_start (hunk));
+ old_lineno += adjust;
+ if (g_hash_table_lookup (hash, GINT_TO_POINTER (old_lineno)))
+ g_hash_table_replace (hash,
+ GINT_TO_POINTER (old_lineno),
+ GINT_TO_POINTER (GB_SOURCE_CHANGE_CHANGED));
+ else
+ g_hash_table_insert (hash,
+ GINT_TO_POINTER (old_lineno),
+ GINT_TO_POINTER (GB_SOURCE_CHANGE_DELETED));
+ break;
+
+ case GGIT_DIFF_LINE_CONTEXT:
+ case GGIT_DIFF_LINE_CONTEXT_EOFNL:
+ case GGIT_DIFF_LINE_ADD_EOFNL:
+ case GGIT_DIFF_LINE_DEL_EOFNL:
+ case GGIT_DIFF_LINE_FILE_HDR:
+ case GGIT_DIFF_LINE_HUNK_HDR:
+ case GGIT_DIFF_LINE_BINARY:
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static gboolean
on_parse_timeout (GbSourceChangeMonitor *monitor)
{
GbSourceChangeMonitorPrivate *priv;
+ GtkTextIter begin;
+ GtkTextIter end;
GgitOId *entry_oid = NULL;
GgitOId *oid = NULL;
GgitObject *blob = NULL;
@@ -83,6 +165,13 @@ on_parse_timeout (GbSourceChangeMonitor *monitor)
GFile *workdir = NULL;
GError *error = NULL;
gchar *relpath = NULL;
+ gchar *text = NULL;
+
+ /*
+ * TODO: Move this to a worker thread!
+ * We probably want to generate the ghashtable and then pass back that
+ * new state to the main thread via an async worker func/cb.
+ */
ENTRY;
@@ -145,6 +234,18 @@ on_parse_timeout (GbSourceChangeMonitor *monitor)
if (!blob)
GOTO (cleanup);
+ gtk_text_buffer_get_bounds (priv->buffer, &begin, &end);
+ text = gtk_text_buffer_get_text (priv->buffer, &begin, &end, TRUE);
+
+ ggit_diff_blob_to_buffer (GGIT_BLOB (blob), relpath, (const guint8 *)text,
+ -1, relpath, NULL, NULL, NULL, diff_line_cb,
+ (gpointer *)priv->state, &error);
+
+ if (error)
+ GOTO (cleanup);
+
+ g_signal_emit (monitor, gSignals [CHANGED], 0);
+
cleanup:
if (error)
{
@@ -152,6 +253,7 @@ cleanup:
g_clear_error (&error);
}
+ g_clear_pointer (&text, g_free);
g_clear_object (&blob);
g_clear_pointer (&entry_oid, ggit_oid_free);
g_clear_pointer (&entry, ggit_tree_entry_unref);
@@ -443,6 +545,17 @@ gb_source_change_monitor_class_init (GbSourceChangeMonitorClass *klass)
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_FILE,
gParamSpecs [PROP_FILE]);
+
+ gSignals [CHANGED] =
+ g_signal_new ("changed",
+ GB_TYPE_SOURCE_CHANGE_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GbSourceChangeMonitorClass, changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
}
static void
diff --git a/src/editor/gb-source-change-monitor.h b/src/editor/gb-source-change-monitor.h
index b1bebe9..522ac9a 100644
--- a/src/editor/gb-source-change-monitor.h
+++ b/src/editor/gb-source-change-monitor.h
@@ -38,9 +38,8 @@ typedef struct _GbSourceChangeMonitorPrivate GbSourceChangeMonitorPrivate;
typedef enum
{
GB_SOURCE_CHANGE_NONE = 0,
- GB_SOURCE_CHANGE_DIRTY = 1 << 0,
- GB_SOURCE_CHANGE_ADDED = 1 << 1,
- GB_SOURCE_CHANGE_CHANGED = 1 << 2,
+ GB_SOURCE_CHANGE_ADDED = 1 << 0,
+ GB_SOURCE_CHANGE_CHANGED = 1 << 1,
} GbSourceChangeFlags;
struct _GbSourceChangeMonitor
@@ -54,6 +53,8 @@ struct _GbSourceChangeMonitor
struct _GbSourceChangeMonitorClass
{
GObjectClass parent_class;
+
+ void (*changed) (GbSourceChangeMonitor *monitor);
};
GType gb_source_change_monitor_get_type (void) G_GNUC_CONST;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]