[gnome-builder/wip/ggit] ggit: start on playing with using libgit2-glib for diff parsing.
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/ggit] ggit: start on playing with using libgit2-glib for diff parsing.
- Date: Sat, 27 Sep 2014 02:16:51 +0000 (UTC)
commit c6e35ba4df21b95013456d0aff2b18a342423d11
Author: Christian Hergert <christian hergert me>
Date: Fri Sep 26 19:16:07 2014 -0700
ggit: start on playing with using libgit2-glib for diff parsing.
build/autotools/autoconf.d/50_dependencies.post-am | 1 +
src/editor/gb-editor-commands.c | 2 -
src/editor/gb-editor-tab.c | 3 +
src/editor/gb-source-change-monitor.c | 620 ++++++++------------
src/editor/gb-source-change-monitor.h | 5 +-
src/gnome-builder.mk | 2 +
src/main.c | 2 +
7 files changed, 246 insertions(+), 389 deletions(-)
---
diff --git a/build/autotools/autoconf.d/50_dependencies.post-am
b/build/autotools/autoconf.d/50_dependencies.post-am
index bacadc1..a927b6b 100644
--- a/build/autotools/autoconf.d/50_dependencies.post-am
+++ b/build/autotools/autoconf.d/50_dependencies.post-am
@@ -2,3 +2,4 @@ PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 3.13.9)
PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.40.0)
PKG_CHECK_MODULES(GTKSOURCEVIEW, gtksourceview-3.0 >= 3.13.91)
PKG_CHECK_MODULES(DEVHELP, libdevhelp-3.0 >= 3.13.90)
+PKG_CHECK_MODULES(GGIT, libgit2-glib-1.0 >= 0.0.22)
diff --git a/src/editor/gb-editor-commands.c b/src/editor/gb-editor-commands.c
index 15df339..ebaaae5 100644
--- a/src/editor/gb-editor-commands.c
+++ b/src/editor/gb-editor-commands.c
@@ -396,7 +396,6 @@ on_load_cb (GtkSourceFileLoader *loader,
gtk_text_buffer_select_range (GTK_TEXT_BUFFER (tab->priv->document),
&begin, &begin);
- gb_source_change_monitor_reset (tab->priv->change_monitor);
gtk_source_gutter_renderer_set_visible (tab->priv->change_renderer, TRUE);
g_object_unref (tab);
@@ -463,7 +462,6 @@ on_save_cb (GtkSourceFileSaver *saver,
{
gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (tab->priv->document),
FALSE);
- gb_source_change_monitor_saved (tab->priv->change_monitor);
gtk_widget_queue_draw (GTK_WIDGET (tab->priv->source_view));
}
diff --git a/src/editor/gb-editor-tab.c b/src/editor/gb-editor-tab.c
index 8fae8fc..0d00e04 100644
--- a/src/editor/gb-editor-tab.c
+++ b/src/editor/gb-editor-tab.c
@@ -1060,6 +1060,9 @@ gb_editor_tab_constructed (GObject *object)
priv->source_view, "show-shadow",
G_BINDING_SYNC_CREATE);
+ g_object_bind_property (priv->file, "location",
+ priv->change_monitor, "file",
+ G_BINDING_SYNC_CREATE);
g_object_bind_property_full (priv->file, "location", tab, "title",
G_BINDING_SYNC_CREATE, transform_file_to_title,
NULL, tab, NULL);
diff --git a/src/editor/gb-source-change-monitor.c b/src/editor/gb-source-change-monitor.c
index 861b830..eb91866 100644
--- a/src/editor/gb-source-change-monitor.c
+++ b/src/editor/gb-source-change-monitor.c
@@ -19,28 +19,29 @@
#define G_LOG_DOMAIN "change-monitor"
#include <glib/gi18n.h>
+#include <gtksourceview/gtksource.h>
+#include <libgit2-glib/ggit.h>
#include "gb-log.h"
#include "gb-source-change-monitor.h"
+#define PARSE_TIMEOUT_MSEC 1000
+
struct _GbSourceChangeMonitorPrivate
{
- GtkTextBuffer *buffer;
- GArray *state;
-
- guint delete_range_before_handler;
- guint delete_range_after_handler;
- guint insert_text_before_handler;
- guint insert_text_after_handler;
-
- guint insert_begin_line;
- guint insert_begin_offset;
+ GtkTextBuffer *buffer;
+ GFile *file;
+ GgitRepository *repo;
+ GHashTable *state;
+ guint changed_handler;
+ guint parse_timeout;
};
enum
{
PROP_0,
PROP_BUFFER,
+ PROP_FILE,
LAST_PROP
};
@@ -50,381 +51,208 @@ G_DEFINE_TYPE_WITH_PRIVATE (GbSourceChangeMonitor,
static GParamSpec *gParamSpecs [LAST_PROP];
-
-static void
-gb_source_change_monitor_insert (GbSourceChangeMonitor *monitor,
- guint line,
- GbSourceChangeFlags flags)
+GbSourceChangeFlags
+gb_source_change_monitor_get_line (GbSourceChangeMonitor *monitor,
+ guint lineno)
{
- guint8 byte = (guint8)flags;
+ g_return_val_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor), 0);
- g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
+ if (monitor->priv->state)
+ {
+ gpointer value;
+
+ value = g_hash_table_lookup (monitor->priv->state,
+ GINT_TO_POINTER (lineno));
+ return GPOINTER_TO_INT (value);
+ }
- if (line == monitor->priv->state->len)
- g_array_append_val (monitor->priv->state, byte);
- else
- g_array_insert_val (monitor->priv->state, line, byte);
+ return GB_SOURCE_CHANGE_NONE;
}
-static void
-gb_source_change_monitor_remove (GbSourceChangeMonitor *monitor,
- guint line)
+static gboolean
+on_parse_timeout (GbSourceChangeMonitor *monitor)
{
- g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
- g_return_if_fail (line < monitor->priv->state->len);
+ GbSourceChangeMonitorPrivate *priv;
+ GgitOId *entry_oid = NULL;
+ GgitOId *oid = NULL;
+ GgitObject *blob = NULL;
+ GgitObject *commit = NULL;
+ GgitRef *head = NULL;
+ GgitTree *tree = NULL;
+ GgitTreeEntry *entry = NULL;
+ GFile *workdir = NULL;
+ GError *error = NULL;
+ gchar *relpath = NULL;
- g_array_remove_index (monitor->priv->state, line);
-}
+ ENTRY;
-static void
-gb_source_change_monitor_set_line (GbSourceChangeMonitor *monitor,
- guint line,
- GbSourceChangeFlags flags)
-{
- GbSourceChangeFlags old_flags;
+ g_assert (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
- g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
- g_return_if_fail (line < monitor->priv->state->len);
+ priv = monitor->priv;
- old_flags = g_array_index (monitor->priv->state, guint8, line);
+ /*
+ * First, disable this so any side-effects cause a new parse to occur.
+ */
+ priv->parse_timeout = 0;
/*
- * Don't allow ourselves to go from "added" to "changed" unless we
- * previously did not have a dirty bit.
+ * We are about to invalidate everything, so just clear out the hash table.
*/
- if (((old_flags & GB_SOURCE_CHANGE_ADDED) != 0) &&
- ((old_flags & GB_SOURCE_CHANGE_DIRTY) != 0))
- {
- flags &= ~GB_SOURCE_CHANGE_CHANGED;
- flags |= GB_SOURCE_CHANGE_ADDED;
- }
+ g_hash_table_remove_all (priv->state);
- g_array_index (monitor->priv->state, guint8, line) = (guint8)flags;
-}
+ /*
+ * Double check we have everything we need.
+ */
+ if (!priv->repo)
+ RETURN (G_SOURCE_REMOVE);
-static void
-gb_source_change_monitor_ensure_bounds (GbSourceChangeMonitor *monitor)
-{
- GbSourceChangeMonitorPrivate *priv;
- GtkTextIter begin;
- GtkTextIter end;
- guint line;
+ /*
+ * Work our way through ggit to get to the original blog we care about.
+ */
+ head = ggit_repository_get_head (priv->repo, &error);
+ if (!head)
+ GOTO (cleanup);
- g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
+ oid = ggit_ref_get_target (head);
+ if (!oid)
+ GOTO (cleanup);
- priv = monitor->priv;
+ commit = ggit_repository_lookup (priv->repo, oid, GGIT_TYPE_COMMIT, &error);
+ if (!commit)
+ GOTO (cleanup);
- gtk_text_buffer_get_bounds (priv->buffer, &begin, &end);
+ tree = ggit_commit_get_tree (GGIT_COMMIT (commit));
+ if (!tree)
+ GOTO (cleanup);
- line = gtk_text_iter_get_line (&end);
+ workdir = ggit_repository_get_workdir (priv->repo);
+ if (!workdir)
+ GOTO (cleanup);
- if (line + 1 > priv->state->len)
- g_array_set_size (priv->state, line + 1);
-}
+ relpath = g_file_get_relative_path (workdir, priv->file);
+ if (!relpath)
+ GOTO (cleanup);
-static void
-get_line_mutation (const GtkTextIter *begin,
- const GtkTextIter *end,
- guint line,
- gboolean *delete_line,
- gboolean *is_changed)
-{
- guint begin_line;
- guint begin_offset;
- guint end_line;
- guint end_offset;
+ entry = ggit_tree_get_by_path (tree, relpath, &error);
+ if (!entry)
+ GOTO (cleanup);
- ENTRY;
+ entry_oid = ggit_tree_entry_get_id (entry);
+ if (!entry_oid)
+ GOTO (cleanup);
- begin_line = gtk_text_iter_get_line (begin);
- begin_offset = gtk_text_iter_get_line_offset (begin);
- end_line = gtk_text_iter_get_line (end);
- end_offset = gtk_text_iter_get_line_offset (end);
+ blob = ggit_repository_lookup (priv->repo, entry_oid, GGIT_TYPE_BLOB, &error);
+ if (!blob)
+ GOTO (cleanup);
- if (begin_line == end_line)
- {
- *delete_line = FALSE;
- *is_changed = TRUE;
- EXIT;
- }
- else if ((line == begin_line) &&
- gtk_text_iter_starts_line (begin) &&
- gtk_text_iter_starts_line (end))
- {
- *delete_line = TRUE;
- *is_changed = FALSE;
- EXIT;
- }
- else if ((line == begin_line) &&
- ((begin_line + 1) == end_line) &&
- gtk_text_iter_ends_line (begin) &&
- gtk_text_iter_starts_line (end))
- {
- *delete_line = FALSE;
- *is_changed = FALSE;
- EXIT;
- }
- else if ((begin_offset != 0) && (line == begin_line))
- {
- *delete_line = FALSE;
- *is_changed = TRUE;
- EXIT;
- }
- else if ((line == end_line) && (end_offset == 0))
- {
- *delete_line = FALSE;
- *is_changed = FALSE;
- EXIT;
- }
- else if ((begin_offset == 0) && (line == begin_line) && (begin_line != end_line))
- {
- *delete_line = TRUE;
- *is_changed = FALSE;
- EXIT;
- }
- else if ((line != begin_line) && (line != end_line))
- {
- *delete_line = TRUE;
- *is_changed = FALSE;
- EXIT;
- }
- else if ((line != begin_line) && (line == end_line) && (begin_offset != 0))
- {
- *delete_line = TRUE;
- *is_changed = FALSE;
- EXIT;
- }
- else if ((line != begin_line) && (line == end_line) && (begin_offset == 0))
+cleanup:
+ if (error)
{
- *delete_line = FALSE;
- *is_changed = TRUE;
- EXIT;
- }
- else
- {
- g_warning ("Unknown outcome: begin=%d:%d line=%d end_line=%d:%d",
- begin_line, begin_offset, line, end_line, end_offset);
-
- *is_changed = TRUE;
- *delete_line = FALSE;
- EXIT;
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
}
-
- EXIT;
+ g_clear_object (&blob);
+ g_clear_object (&commit);
+ g_clear_object (&entry);
+ g_clear_object (&entry_oid);
+ g_clear_object (&head);
+ g_clear_object (&oid);
+ g_clear_object (&tree);
+ g_clear_object (&workdir);
+ g_clear_pointer (&relpath, g_free);
+
+ RETURN (G_SOURCE_REMOVE);
}
static void
-on_delete_range_before_cb (GbSourceChangeMonitor *monitor,
- GtkTextIter *begin,
- GtkTextIter *end,
- GtkTextBuffer *buffer)
+gb_source_change_monitor_queue_parse (GbSourceChangeMonitor *monitor)
{
- GArray *ar;
- guint begin_line;
- guint end_line;
- guint i;
+ GbSourceChangeMonitorPrivate *priv;
g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
- g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
-
- if (gtk_text_iter_compare (begin, end) == 0)
- return;
-
- begin_line = gtk_text_iter_get_line (begin);
- end_line = gtk_text_iter_get_line (end);
- ar = g_array_new (FALSE, FALSE, sizeof (guint));
+ priv = monitor->priv;
- for (i = begin_line; i <= end_line; i++)
+ if (priv->parse_timeout)
{
- gboolean delete_line;
- gboolean is_changed;
-
- get_line_mutation (begin, end, i, &delete_line, &is_changed);
-
- if (delete_line)
- g_array_append_val (ar, i);
- else if (is_changed)
- gb_source_change_monitor_set_line (monitor, i,
- (GB_SOURCE_CHANGE_CHANGED |
- GB_SOURCE_CHANGE_DIRTY));
+ g_source_remove (priv->parse_timeout);
+ priv->parse_timeout = 0;
}
- for (i = ar->len; i > 0; i--)
- {
- guint line;
-
- line = g_array_index (ar, guint, i - 1);
- gb_source_change_monitor_remove (monitor, line);
- }
-
- g_array_unref (ar);
+ priv->parse_timeout = g_timeout_add (PARSE_TIMEOUT_MSEC,
+ (GSourceFunc)on_parse_timeout,
+ monitor);
}
static void
-on_delete_range_after_cb (GbSourceChangeMonitor *monitor,
- GtkTextIter *begin,
- GtkTextIter *end,
- GtkTextBuffer *buffer)
+on_change_cb (GbSourceChangeMonitor *monitor,
+ GtkTextBuffer *buffer)
{
g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+
+ gb_source_change_monitor_queue_parse (monitor);
}
static void
-on_insert_text_before_cb (GbSourceChangeMonitor *monitor,
- GtkTextIter *location,
- gchar *text,
- gint len,
- GtkTextBuffer *buffer)
+discover_repository (GbSourceChangeMonitor *monitor)
{
GbSourceChangeMonitorPrivate *priv;
- GtkTextIter begin;
- GtkTextIter end;
-
- g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
- g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
-
- priv = monitor->priv;
- priv->insert_begin_line = gtk_text_iter_get_line (location);
- priv->insert_begin_offset = gtk_text_iter_get_line_offset (location);
+ ENTRY;
- gtk_text_buffer_get_bounds (buffer, &begin, &end);
+ g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
/*
- * WORKAROUND:
+ * TODO: This makes a lot of assumptions.
+ * - that we are local
+ * - that checking disk is free
+ * - that we don't need to cache anything.
*
- * Mark the first line as added if we are typing our first character.
- * We should consider removing this GSignal handler after it has
- * hit this to save on signal emission.
+ * and all of those are probably wrong.
*/
- if (G_UNLIKELY (gtk_text_iter_compare (&begin, &end) == 0))
- gb_source_change_monitor_set_line (monitor, 0,
- (GB_SOURCE_CHANGE_ADDED |
- GB_SOURCE_CHANGE_DIRTY));
-}
-
-static void
-on_insert_text_after_cb (GbSourceChangeMonitor *monitor,
- GtkTextIter *location,
- gchar *text,
- gint len,
- GtkTextBuffer *buffer)
-{
- GbSourceChangeMonitorPrivate *priv;
- GbSourceChangeFlags flags = 0;
- guint line;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
- g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
priv = monitor->priv;
- line = gtk_text_iter_get_line (location);
+ g_clear_object (&priv->repo);
- if (g_strcmp0 (text, "\n") == 0)
+ if (priv->file)
{
- flags = (GB_SOURCE_CHANGE_ADDED | GB_SOURCE_CHANGE_DIRTY);
- if (priv->insert_begin_offset == 0)
- gb_source_change_monitor_insert (monitor, line-1, flags);
- else
- gb_source_change_monitor_insert (monitor, line, flags);
- }
- else if (strchr (text, '\n') == NULL)
- {
- flags = (GB_SOURCE_CHANGE_CHANGED | GB_SOURCE_CHANGE_DIRTY);
- gb_source_change_monitor_set_line (monitor, line, flags);
- }
- else
- {
- GtkTextIter end;
- GtkTextIter iter;
- guint last_line;
-
- len = g_utf8_strlen (text, len);
+ GFile *repo_file;
+ GError *error = NULL;
- gtk_text_iter_assign (&iter, location);
- gtk_text_iter_assign (&end, location);
- gtk_text_iter_backward_chars (&iter, len);
+ repo_file = ggit_repository_discover (priv->file, &error);
- last_line = gtk_text_iter_get_line (&iter);
+ TRACE;
- while (gtk_text_iter_compare (&iter, &end) <= 0)
+ if (!repo_file)
{
- line = gtk_text_iter_get_line (&iter);
-
- if (line != last_line)
- {
- flags = (GB_SOURCE_CHANGE_ADDED | GB_SOURCE_CHANGE_DIRTY);
- gb_source_change_monitor_insert (monitor, line, flags);
- last_line = line;
- }
-
- if (!gtk_text_iter_forward_char (&iter))
- break;
+ g_message ("%s", error->message);
+ g_clear_error (&error);
+ EXIT;
}
- }
-
- gb_source_change_monitor_ensure_bounds (monitor);
-
- EXIT;
-}
-
-GbSourceChangeFlags
-gb_source_change_monitor_get_line (GbSourceChangeMonitor *monitor,
- guint lineno)
-{
- g_return_val_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor), 0);
-
- if (lineno < monitor->priv->state->len)
- return monitor->priv->state->data [lineno];
-
- g_warning ("No such line: %u", lineno);
-
- return 0;
-}
-void
-gb_source_change_monitor_saved (GbSourceChangeMonitor *monitor)
-{
- GbSourceChangeMonitorPrivate *priv;
- GbSourceChangeFlags flags;
- guint i;
+ priv->repo = ggit_repository_open (repo_file, &error);
+ TRACE;
- g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
+ if (!priv->repo)
+ {
+ g_message ("%s", error->message);
+ g_clear_error (&error);
+ }
+ else
+ {
+ gchar *uri;
- priv = monitor->priv;
+ uri = g_file_get_uri (repo_file);
+ g_message ("Discovered Git repository at \"%s\"", uri);
+ g_free (uri);
+ }
- for (i = 0; i < priv->state->len; i++)
- {
- flags = g_array_index (priv->state, guint8, i);
- flags &= ~GB_SOURCE_CHANGE_DIRTY;
- g_array_index (priv->state, guint8, i) = flags;
+ g_clear_object (&repo_file);
}
-}
-
-void
-gb_source_change_monitor_reset (GbSourceChangeMonitor *monitor)
-{
- GbSourceChangeMonitorPrivate *priv;
- GtkTextIter begin;
- GtkTextIter end;
- guint line;
- g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
-
- priv = monitor->priv;
-
- if (priv->buffer)
- {
- gtk_text_buffer_get_bounds (priv->buffer, &begin, &end);
- line = gtk_text_iter_get_line (&end);
- g_array_set_size (priv->state, line + 1);
- memset (priv->state->data, 0, priv->state->len);
- }
+ EXIT;
}
GtkTextBuffer *
@@ -437,8 +265,7 @@ gb_source_change_monitor_get_buffer (GbSourceChangeMonitor *monitor)
static void
gb_source_change_monitor_set_buffer (GbSourceChangeMonitor *monitor,
- GtkTextBuffer *buffer,
- gboolean notify)
+ GtkTextBuffer *buffer)
{
GbSourceChangeMonitorPrivate *priv;
@@ -451,54 +278,53 @@ gb_source_change_monitor_set_buffer (GbSourceChangeMonitor *monitor,
if (priv->buffer)
{
- g_signal_handler_disconnect (priv->buffer,
- priv->delete_range_before_handler);
- g_signal_handler_disconnect (priv->buffer,
- priv->delete_range_after_handler);
- g_signal_handler_disconnect (priv->buffer,
- priv->insert_text_before_handler);
- g_signal_handler_disconnect (priv->buffer,
- priv->insert_text_after_handler);
- priv->delete_range_before_handler = 0;
- priv->delete_range_after_handler = 0;
- priv->insert_text_before_handler = 0;
- priv->insert_text_after_handler = 0;
+ g_signal_handler_disconnect (priv->buffer, priv->changed_handler);
+ priv->changed_handler = 0;
g_clear_object (&priv->buffer);
}
if (buffer)
{
priv->buffer = g_object_ref (buffer);
- priv->delete_range_before_handler =
+ priv->changed_handler =
g_signal_connect_object (priv->buffer,
- "delete-range",
- G_CALLBACK (on_delete_range_before_cb),
+ "changed",
+ G_CALLBACK (on_change_cb),
monitor,
G_CONNECT_SWAPPED);
- priv->delete_range_after_handler =
- g_signal_connect_object (priv->buffer,
- "delete-range",
- G_CALLBACK (on_delete_range_after_cb),
- monitor,
- (G_CONNECT_SWAPPED | G_CONNECT_AFTER));
- priv->insert_text_before_handler =
- g_signal_connect_object (priv->buffer,
- "insert-text",
- G_CALLBACK (on_insert_text_before_cb),
- monitor,
- G_CONNECT_SWAPPED);
- priv->insert_text_after_handler =
- g_signal_connect_object (priv->buffer,
- "insert-text",
- G_CALLBACK (on_insert_text_after_cb),
- monitor,
- (G_CONNECT_SWAPPED | G_CONNECT_AFTER));
-
- gb_source_change_monitor_ensure_bounds (monitor);
}
- if (notify)
- g_object_notify_by_pspec (G_OBJECT (monitor), gParamSpecs [PROP_BUFFER]);
+ EXIT;
+}
+
+GFile *
+gb_source_change_monitor_get_file (GbSourceChangeMonitor *monitor)
+{
+ g_return_val_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor), NULL);
+
+ return monitor->priv->file;
+}
+
+void
+gb_source_change_monitor_set_file (GbSourceChangeMonitor *monitor,
+ GFile *file)
+{
+ GbSourceChangeMonitorPrivate *priv;
+
+ ENTRY;
+
+ g_return_if_fail (GB_IS_SOURCE_CHANGE_MONITOR (monitor));
+ g_return_if_fail (!file || G_IS_FILE (file));
+
+ priv = monitor->priv;
+
+ if (file == priv->file)
+ EXIT;
+
+ g_clear_object (&priv->file);
+ monitor->priv->file = file ? g_object_ref (file) : NULL;
+ discover_repository (monitor);
+ g_object_notify_by_pspec (G_OBJECT (monitor), gParamSpecs [PROP_FILE]);
EXIT;
}
@@ -506,10 +332,20 @@ gb_source_change_monitor_set_buffer (GbSourceChangeMonitor *monitor,
static void
gb_source_change_monitor_dispose (GObject *object)
{
+ GbSourceChangeMonitor *monitor = (GbSourceChangeMonitor *)object;
+
ENTRY;
- gb_source_change_monitor_set_buffer (GB_SOURCE_CHANGE_MONITOR (object),
- NULL, FALSE);
+ gb_source_change_monitor_set_buffer (monitor, NULL);
+ gb_source_change_monitor_set_file (monitor, NULL);
+
+ g_clear_object (&monitor->priv->repo);
+
+ if (monitor->priv->parse_timeout)
+ {
+ g_source_remove (monitor->priv->parse_timeout);
+ monitor->priv->parse_timeout = 0;
+ }
G_OBJECT_CLASS (gb_source_change_monitor_parent_class)->dispose (object);
@@ -519,17 +355,11 @@ gb_source_change_monitor_dispose (GObject *object)
static void
gb_source_change_monitor_finalize (GObject *object)
{
- GbSourceChangeMonitorPrivate *priv;
+ GbSourceChangeMonitorPrivate *priv = GB_SOURCE_CHANGE_MONITOR (object)->priv;
- ENTRY;
-
- priv = GB_SOURCE_CHANGE_MONITOR (object)->priv;
-
- g_clear_pointer (&priv->state, g_array_unref);
+ g_clear_pointer (&priv->state, g_hash_table_unref);
G_OBJECT_CLASS (gb_source_change_monitor_parent_class)->finalize (object);
-
- EXIT;
}
static void
@@ -540,14 +370,21 @@ gb_source_change_monitor_get_property (GObject *object,
{
GbSourceChangeMonitor *monitor = GB_SOURCE_CHANGE_MONITOR (object);
- switch (prop_id) {
- case PROP_BUFFER:
- g_value_set_object (value,
- gb_source_change_monitor_get_buffer (monitor));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ g_value_set_object (value,
+ gb_source_change_monitor_get_buffer (monitor));
+ break;
+
+ case PROP_FILE:
+ g_value_set_object (value,
+ gb_source_change_monitor_get_file (monitor));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
@@ -558,15 +395,20 @@ gb_source_change_monitor_set_property (GObject *object,
{
GbSourceChangeMonitor *monitor = GB_SOURCE_CHANGE_MONITOR (object);
- switch (prop_id) {
- case PROP_BUFFER:
- gb_source_change_monitor_set_buffer (monitor,
- g_value_get_object (value),
- TRUE);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ gb_source_change_monitor_set_buffer (monitor,
+ g_value_get_object (value));
+ break;
+
+ case PROP_FILE:
+ gb_source_change_monitor_set_file (monitor, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
@@ -590,17 +432,23 @@ gb_source_change_monitor_class_init (GbSourceChangeMonitorClass *klass)
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_BUFFER,
gParamSpecs [PROP_BUFFER]);
+
+ gParamSpecs [PROP_FILE] =
+ g_param_spec_object ("file",
+ _("File"),
+ _("The file for the buffer."),
+ G_TYPE_FILE,
+ (G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_FILE,
+ gParamSpecs [PROP_FILE]);
}
static void
gb_source_change_monitor_init (GbSourceChangeMonitor *monitor)
{
ENTRY;
-
monitor->priv = gb_source_change_monitor_get_instance_private (monitor);
-
- monitor->priv->state = g_array_new (FALSE, TRUE, sizeof (guint8));
- g_array_set_size (monitor->priv->state, 1);
-
+ monitor->priv->state = g_hash_table_new (g_direct_hash, g_direct_equal);
EXIT;
}
diff --git a/src/editor/gb-source-change-monitor.h b/src/editor/gb-source-change-monitor.h
index 04f1ad1..56805b5 100644
--- a/src/editor/gb-source-change-monitor.h
+++ b/src/editor/gb-source-change-monitor.h
@@ -37,6 +37,7 @@ 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,
@@ -57,9 +58,11 @@ struct _GbSourceChangeMonitorClass
GType gb_source_change_monitor_get_type (void) G_GNUC_CONST;
GbSourceChangeMonitor *gb_source_change_monitor_new (GtkTextBuffer *buffer);
+GFile *gb_source_change_monitor_get_file (GbSourceChangeMonitor *monitor);
+void gb_source_change_monitor_set_file (GbSourceChangeMonitor *monitor,
+ GFile *file);
GbSourceChangeFlags gb_source_change_monitor_get_line (GbSourceChangeMonitor *monitor,
guint lineno);
-void gb_source_change_monitor_reset (GbSourceChangeMonitor *monitor);
void gb_source_change_monitor_saved (GbSourceChangeMonitor *monitor);
G_END_DECLS
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index 3fc3f49..31b5c97 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -113,6 +113,7 @@ libgnome_builder_la_SOURCES = \
libgnome_builder_la_LIBADD = \
$(DEVHELP_LIBS) \
+ $(GGIT_LIBS) \
$(GIO_LIBS) \
$(GTKSOURCEVIEW_LIBS) \
$(GTK_LIBS) \
@@ -121,6 +122,7 @@ libgnome_builder_la_LIBADD = \
libgnome_builder_la_CFLAGS = \
$(DEVHELP_CFLAGS) \
+ $(GGIT_CFLAGS) \
$(GIO_CFLAGS) \
$(GTKSOURCEVIEW_CFLAGS) \
$(GTK_CFLAGS) \
diff --git a/src/main.c b/src/main.c
index 3a43423..4834713 100644
--- a/src/main.c
+++ b/src/main.c
@@ -19,6 +19,7 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <libgit2-glib/ggit.h>
#include "gb-application.h"
#include "gb-log.h"
@@ -34,6 +35,7 @@ main (int argc,
g_set_application_name (_("Builder"));
gb_log_init (TRUE, NULL);
+ ggit_init ();
app = g_object_new (GB_TYPE_APPLICATION,
"application-id", "org.gnome.Builder",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]