[gnome-builder] indenter: add fallback when no indenter is supplied



commit 29bf2ade5ec3bf093e9ed5f374f6aae75de702e1
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jul 7 15:47:40 2017 -0700

    indenter: add fallback when no indenter is supplied
    
    We can have a very simple indenter as a fallback for the
    interface. Just pass NULL for @self in those cases.
    
    This tries to mimic GtkSourceView in that it just copies the
    previous lines indentation (when possible). No indentation
    is performed if we land on the first line of the buffer.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=784633

 libide/sourceview/ide-indenter.c |   90 +++++++++++++++++++++++++++++++++----
 1 files changed, 80 insertions(+), 10 deletions(-)
---
diff --git a/libide/sourceview/ide-indenter.c b/libide/sourceview/ide-indenter.c
index 4016d47..011cf08 100644
--- a/libide/sourceview/ide-indenter.c
+++ b/libide/sourceview/ide-indenter.c
@@ -19,7 +19,9 @@
 #define G_LOG_DOMAIN "ide-indenter"
 
 #include "ide-context.h"
-#include "ide-indenter.h"
+#include "ide-debug.h"
+
+#include "sourceview/ide-indenter.h"
 
 G_DEFINE_INTERFACE (IdeIndenter, ide_indenter, IDE_TYPE_OBJECT)
 
@@ -48,6 +50,51 @@ ide_indenter_default_init (IdeIndenterInterface *iface)
   iface->is_trigger = ide_indenter_default_is_trigger;
 }
 
+static gchar *
+ide_indenter_mimic_source_view (GtkTextView *text_view,
+                                GtkTextIter *begin,
+                                GtkTextIter *end,
+                                gint        *cursor_offset,
+                                GdkEventKey *event)
+{
+  GtkTextIter copy_begin;
+  GtkTextIter copy_end;
+  gchar *ret;
+
+  IDE_ENTRY;
+
+  g_assert (GTK_IS_TEXT_VIEW (text_view));
+  g_assert (begin != NULL);
+  g_assert (end != NULL);
+  g_assert (cursor_offset != NULL);
+  g_assert (event != NULL);
+
+  *cursor_offset = 0;
+  *begin = *end;
+
+  if (event->keyval != GDK_KEY_Return &&
+      event->keyval != GDK_KEY_KP_Enter)
+    IDE_RETURN (NULL);
+
+  copy_begin = *end;
+
+  /* We might already be at the beginning of the file */
+  if (!gtk_text_iter_backward_char (&copy_begin))
+    IDE_RETURN (NULL);
+
+  gtk_text_iter_set_line_offset (&copy_begin, 0);
+  copy_end = copy_begin;
+  while (g_unichar_isspace (gtk_text_iter_get_char (&copy_end)))
+    {
+      if (!gtk_text_iter_forward_char (&copy_end))
+        break;
+    }
+
+  ret = gtk_text_iter_get_slice (&copy_begin, &copy_end);
+
+  IDE_RETURN (ret);
+}
+
 /**
  * ide_indenter_format:
  * @text_view: A #GtkTextView
@@ -65,7 +112,11 @@ ide_indenter_default_init (IdeIndenterInterface *iface)
  * @cursor_offset may be set to jump the cursor starting from @end. Negative
  * values are allowed.
  *
- * Returns: (nullable) (transfer full): A string containing the replacement text, or %NULL.
+ * If @self is %NULL, the fallback indenter is used, which tries to mimic the
+ * indentation style of #GtkSourceView.
+ *
+ * Returns: (nullable) (transfer full): A string containing the replacement
+ *   text, or %NULL.
  */
 gchar *
 ide_indenter_format (IdeIndenter *self,
@@ -75,14 +126,17 @@ ide_indenter_format (IdeIndenter *self,
                      gint        *cursor_offset,
                      GdkEventKey *event)
 {
-  g_return_val_if_fail (IDE_IS_INDENTER (self), NULL);
+  g_return_val_if_fail (!self || IDE_IS_INDENTER (self), NULL);
   g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), NULL);
-  g_return_val_if_fail (begin, NULL);
-  g_return_val_if_fail (end, NULL);
-  g_return_val_if_fail (cursor_offset, NULL);
-  g_return_val_if_fail (event, NULL);
+  g_return_val_if_fail (begin != NULL, NULL);
+  g_return_val_if_fail (end != NULL, NULL);
+  g_return_val_if_fail (cursor_offset != NULL, NULL);
+  g_return_val_if_fail (event != NULL, NULL);
 
-  return IDE_INDENTER_GET_IFACE (self)->format (self, text_view, begin, end, cursor_offset, event);
+  if (self == NULL)
+    return ide_indenter_mimic_source_view (text_view, begin, end, cursor_offset, event);
+  else
+    return IDE_INDENTER_GET_IFACE (self)->format (self, text_view, begin, end, cursor_offset, event);
 }
 
 /**
@@ -93,14 +147,30 @@ ide_indenter_format (IdeIndenter *self,
  * Determines if @event should trigger an indentation request. If %TRUE is
  * returned then ide_indenter_format() will be called.
  *
+ * If @self is %NULL, the fallback indenter is used, which tries to mimic
+ * the default indentation style of #GtkSourceView.
+ *
  * Returns: %TRUE if @event should trigger an indentation request.
  */
 gboolean
 ide_indenter_is_trigger (IdeIndenter *self,
                          GdkEventKey *event)
 {
-  g_return_val_if_fail (IDE_IS_INDENTER (self), FALSE);
-  g_return_val_if_fail (event, FALSE);
+  g_return_val_if_fail (!self || IDE_IS_INDENTER (self), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (self == NULL)
+    {
+      switch (event->keyval)
+        {
+        case GDK_KEY_KP_Enter:
+        case GDK_KEY_Return:
+          return TRUE;
+
+        default:
+          return FALSE;
+        }
+    }
 
   return IDE_INDENTER_GET_IFACE (self)->is_trigger (self, event);
 }


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