[gnome-builder] git: update buffer change flags when settling buffer



commit c6e88608a10ff86714dd73d60fb83e873d7bbedc
Author: Christian Hergert <chergert redhat com>
Date:   Mon Feb 18 11:36:10 2019 -0800

    git: update buffer change flags when settling buffer
    
    This ensures that the buffer has up to date information when trimming line
    whitespace upon a save request.
    
    Fixes #817

 src/plugins/git/gbp-git-buffer-addin.c          | 52 +++++++++++++++++++
 src/plugins/git/gbp-git-buffer-change-monitor.c | 66 +++++++++++++++++++++++++
 src/plugins/git/gbp-git-buffer-change-monitor.h | 11 ++++-
 3 files changed, 127 insertions(+), 2 deletions(-)
---
diff --git a/src/plugins/git/gbp-git-buffer-addin.c b/src/plugins/git/gbp-git-buffer-addin.c
index 7d7038477..274366e88 100644
--- a/src/plugins/git/gbp-git-buffer-addin.c
+++ b/src/plugins/git/gbp-git-buffer-addin.c
@@ -101,12 +101,64 @@ gbp_git_buffer_addin_unload (IdeBufferAddin *addin,
     }
 }
 
+static void
+gbp_git_buffer_addin_settle_cb (GObject      *object,
+                                GAsyncResult *result,
+                                gpointer      user_data)
+{
+  GbpGitBufferChangeMonitor *monitor = (GbpGitBufferChangeMonitor *)object;
+  g_autoptr(IdeTask) task = user_data;
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (GBP_IS_GIT_BUFFER_CHANGE_MONITOR (monitor));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (IDE_IS_TASK (task));
+
+  gbp_git_buffer_change_monitor_wait_finish (monitor, result, NULL);
+  ide_task_return_boolean (task, TRUE);
+}
+
+static void
+gbp_git_buffer_addin_settle_async (IdeBufferAddin      *addin,
+                                   GCancellable        *cancellable,
+                                   GAsyncReadyCallback  callback,
+                                   gpointer             user_data)
+{
+  GbpGitBufferAddin *self = (GbpGitBufferAddin *)addin;
+  g_autoptr(IdeTask) task = NULL;
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (IDE_IS_BUFFER_ADDIN (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = ide_task_new (self, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, gbp_git_buffer_addin_settle_async);
+
+  if (self->monitor == NULL)
+    ide_task_return_boolean (task, TRUE);
+  else
+    gbp_git_buffer_change_monitor_wait_async (self->monitor,
+                                              cancellable,
+                                              gbp_git_buffer_addin_settle_cb,
+                                              g_steal_pointer (&task));
+}
+
+static gboolean
+gbp_git_buffer_addin_settle_finish (IdeBufferAddin  *addin,
+                                    GAsyncResult    *result,
+                                    GError         **error)
+{
+  return ide_task_propagate_boolean (IDE_TASK (result), error);
+}
+
 static void
 buffer_addin_iface_init (IdeBufferAddinInterface *iface)
 {
   iface->file_loaded = gbp_git_buffer_addin_file_laoded;
   iface->file_saved = gbp_git_buffer_addin_file_saved;
   iface->unload = gbp_git_buffer_addin_unload;
+  iface->settle_async = gbp_git_buffer_addin_settle_async;
+  iface->settle_finish = gbp_git_buffer_addin_settle_finish;
 }
 
 G_DEFINE_TYPE_WITH_CODE (GbpGitBufferAddin, gbp_git_buffer_addin, G_TYPE_OBJECT,
diff --git a/src/plugins/git/gbp-git-buffer-change-monitor.c b/src/plugins/git/gbp-git-buffer-change-monitor.c
index 1f1b0c4f8..0aa4664f6 100644
--- a/src/plugins/git/gbp-git-buffer-change-monitor.c
+++ b/src/plugins/git/gbp-git-buffer-change-monitor.c
@@ -91,6 +91,8 @@ struct _GbpGitBufferChangeMonitor
   GgitBlob               *cached_blob;
   LineCache              *cache;
 
+  GQueue                  wait_tasks;
+
   guint                   changed_timeout;
 
   guint                   state_dirty : 1;
@@ -150,6 +152,25 @@ diff_task_free (gpointer data)
     }
 }
 
+static void
+complete_wait_tasks (GbpGitBufferChangeMonitor *self,
+                     GParamSpec                *pspec,
+                     IdeTask                   *calculate_task)
+{
+  gpointer taskptr;
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (GBP_IS_GIT_BUFFER_CHANGE_MONITOR (self));
+  g_assert (IDE_IS_TASK (calculate_task));
+
+  while ((taskptr = g_queue_pop_head (&self->wait_tasks)))
+    {
+      g_autoptr(IdeTask) task = taskptr;
+
+      ide_task_return_boolean (task, TRUE);
+    }
+}
+
 static LineCache *
 gbp_git_buffer_change_monitor_calculate_finish (GbpGitBufferChangeMonitor  *self,
                                                 GAsyncResult               *result,
@@ -207,6 +228,12 @@ gbp_git_buffer_change_monitor_calculate_async (GbpGitBufferChangeMonitor *self,
   task = ide_task_new (self, cancellable, callback, user_data);
   ide_task_set_source_tag (task, gbp_git_buffer_change_monitor_calculate_async);
 
+  g_signal_connect_object (task,
+                           "notify::completed",
+                           G_CALLBACK (complete_wait_tasks),
+                           self,
+                           G_CONNECT_SWAPPED);
+
   buffer = ide_buffer_change_monitor_get_buffer (IDE_BUFFER_CHANGE_MONITOR (self));
   g_assert (IDE_IS_BUFFER (buffer));
 
@@ -922,3 +949,42 @@ gbp_git_buffer_change_monitor_init (GbpGitBufferChangeMonitor *self)
                                    self,
                                    G_CONNECT_SWAPPED | G_CONNECT_AFTER);
 }
+
+void
+gbp_git_buffer_change_monitor_wait_async (GbpGitBufferChangeMonitor *self,
+                                          GCancellable              *cancellable,
+                                          GAsyncReadyCallback        callback,
+                                          gpointer                   user_data)
+{
+  g_autoptr(IdeTask) task = NULL;
+
+  g_return_if_fail (IDE_IS_MAIN_THREAD ());
+  g_return_if_fail (GBP_IS_GIT_BUFFER_CHANGE_MONITOR (self));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = ide_task_new (self, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, gbp_git_buffer_change_monitor_wait_async);
+
+  if (!self->state_dirty && !self->in_calculation)
+    {
+      ide_task_return_boolean (task, TRUE);
+      return;
+    }
+
+  g_queue_push_tail (&self->wait_tasks, g_steal_pointer (&task));
+
+  if (!self->in_calculation)
+    gbp_git_buffer_change_monitor_recalculate (self);
+}
+
+gboolean
+gbp_git_buffer_change_monitor_wait_finish (GbpGitBufferChangeMonitor  *self,
+                                           GAsyncResult               *result,
+                                           GError                    **error)
+{
+  g_return_val_if_fail (IDE_IS_MAIN_THREAD (), FALSE);
+  g_return_val_if_fail (GBP_IS_GIT_BUFFER_CHANGE_MONITOR (self), FALSE);
+  g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
+
+  return ide_task_propagate_boolean (IDE_TASK (result), error);
+}
diff --git a/src/plugins/git/gbp-git-buffer-change-monitor.h b/src/plugins/git/gbp-git-buffer-change-monitor.h
index 9c29d940d..c5e620d7d 100644
--- a/src/plugins/git/gbp-git-buffer-change-monitor.h
+++ b/src/plugins/git/gbp-git-buffer-change-monitor.h
@@ -29,7 +29,14 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (GbpGitBufferChangeMonitor, gbp_git_buffer_change_monitor, GBP, 
GIT_BUFFER_CHANGE_MONITOR, IdeBufferChangeMonitor)
 
-void gbp_git_buffer_change_monitor_set_repository (GbpGitBufferChangeMonitor *self,
-                                                   GgitRepository            *repository);
+void     gbp_git_buffer_change_monitor_set_repository (GbpGitBufferChangeMonitor  *self,
+                                                       GgitRepository             *repository);
+void     gbp_git_buffer_change_monitor_wait_async     (GbpGitBufferChangeMonitor  *self,
+                                                       GCancellable               *cancellable,
+                                                       GAsyncReadyCallback         callback,
+                                                       gpointer                    user_data);
+gboolean gbp_git_buffer_change_monitor_wait_finish    (GbpGitBufferChangeMonitor  *self,
+                                                       GAsyncResult               *result,
+                                                       GError                    **error);
 
 G_END_DECLS


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