[gnome-builder/auto-indent] editor: more indentation work.
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/auto-indent] editor: more indentation work.
- Date: Wed, 17 Sep 2014 00:52:51 +0000 (UTC)
commit 9a9f46a288342d2ab9104429883dcd48871cacb6
Author: Christian Hergert <christian hergert me>
Date: Tue Sep 16 17:52:41 2014 -0700
editor: more indentation work.
src/editor/gb-source-auto-indenter-c.c | 124 +++++++++++++++++++++++++-------
1 files changed, 99 insertions(+), 25 deletions(-)
---
diff --git a/src/editor/gb-source-auto-indenter-c.c b/src/editor/gb-source-auto-indenter-c.c
index 90b2f52..c93fda7 100644
--- a/src/editor/gb-source-auto-indenter-c.c
+++ b/src/editor/gb-source-auto-indenter-c.c
@@ -25,13 +25,14 @@
struct _GbSourceAutoIndenterCPrivate
{
- guint brace_indent;
+ gint scope_indent; /* after { */
+ gint condition_indent; /* for, if, while, switch, etc */
};
enum
{
PROP_0,
- PROP_BRACE_INDENT,
+ PROP_SCOPE_INDENT,
LAST_PROP
};
@@ -54,12 +55,10 @@ build_indent (GbSourceAutoIndenterC *c,
{
GtkTextIter iter;
gunichar ch;
- guint i;
- gtk_text_iter_assign (&iter, matching_line);
- while (!gtk_text_iter_starts_line (&iter))
- if (!gtk_text_iter_backward_char (&iter))
- goto fallback;
+ gtk_text_buffer_get_iter_at_line (gtk_text_iter_get_buffer (matching_line),
+ &iter,
+ gtk_text_iter_get_line (matching_line));
do {
ch = gtk_text_iter_get_char (&iter);
@@ -74,10 +73,9 @@ build_indent (GbSourceAutoIndenterC *c,
break;
}
} while (gtk_text_iter_forward_char (&iter) &&
- gtk_text_iter_get_line_offset (&iter) <= line_offset);
+ gtk_text_iter_compare (&iter, matching_line) <= 0);
-fallback:
- for (i = str->len; i <= line_offset; i++)
+ while (str->len < line_offset)
g_string_append_c (str, ' ');
}
@@ -120,12 +118,49 @@ backward_find_matching_char (GtkTextIter *iter,
return FALSE;
}
+static gboolean
+line_is_space (GtkTextIter *iter)
+{
+ GtkTextIter begin;
+
+ gtk_text_buffer_get_iter_at_line (gtk_text_iter_get_buffer (iter),
+ &begin,
+ gtk_text_iter_get_line (iter));
+
+ while (!gtk_text_iter_equal (iter, &begin))
+ {
+ gunichar ch;
+
+ if (!gtk_text_iter_forward_char (&begin))
+ break;
+
+ ch = gtk_text_iter_get_char (&begin);
+
+ switch (ch) {
+ case '\t':
+ case ' ':
+ break;
+ default:
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+backward_find_stmt_expr (GtkTextIter *iter)
+{
+ return FALSE;
+}
+
static gchar *
gb_source_auto_indenter_c_query (GbSourceAutoIndenter *indenter,
GtkTextView *view,
GtkTextBuffer *buffer,
GtkTextIter *iter)
{
+ GbSourceAutoIndenterCPrivate *priv;
GbSourceAutoIndenterC *c = (GbSourceAutoIndenterC *)indenter;
GtkTextIter cur;
gunichar ch;
@@ -136,8 +171,16 @@ gb_source_auto_indenter_c_query (GbSourceAutoIndenter *indenter,
g_return_val_if_fail (GB_IS_SOURCE_AUTO_INDENTER_C (c), NULL);
+ priv = c->priv;
+
+ /*
+ * Save our current iter position to restore it later.
+ */
gtk_text_iter_assign (&cur, iter);
+ /*
+ * Create the buffer for our indentation string.
+ */
str = g_string_new (NULL);
/*
@@ -154,6 +197,22 @@ gb_source_auto_indenter_c_query (GbSourceAutoIndenter *indenter,
ch = gtk_text_iter_get_char (iter);
/*
+ * We just started a new scope. Try to find the indentation of the previous
+ * scope and our indentation past it.
+ */
+ if (ch == '{')
+ {
+ if (line_is_space (iter))
+ {
+ guint offset;
+
+ offset = gtk_text_iter_get_line_offset (iter);
+ build_indent (c, offset + priv->scope_indent, iter, str);
+ GOTO (cleanup);
+ }
+ }
+
+ /*
* If we just placed a terminating parenthesis, we need to work our way back
* to it's match. That way we can peak at what it was and determine
* indentation from that.
@@ -184,6 +243,20 @@ gb_source_auto_indenter_c_query (GbSourceAutoIndenter *indenter,
*/
if (ch == ';')
{
+ guint offset;
+
+ if (!backward_find_stmt_expr (iter))
+ {
+ gtk_text_iter_assign (iter, &cur);
+ build_indent (c, 0, iter, str);
+ }
+ else
+ {
+ offset = gtk_text_iter_get_line_offset (iter);
+ build_indent (c, offset, iter, str);
+ }
+
+ GOTO (cleanup);
}
cleanup:
@@ -203,8 +276,8 @@ gb_source_auto_indenter_c_get_property (GObject *object,
GbSourceAutoIndenterC *c = GB_SOURCE_AUTO_INDENTER_C (object);
switch (prop_id) {
- case PROP_BRACE_INDENT:
- g_value_set_uint (value, c->priv->brace_indent);
+ case PROP_SCOPE_INDENT:
+ g_value_set_uint (value, c->priv->scope_indent);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -220,8 +293,8 @@ gb_source_auto_indenter_c_set_property (GObject *object,
GbSourceAutoIndenterC *c = GB_SOURCE_AUTO_INDENTER_C (object);
switch (prop_id) {
- case PROP_BRACE_INDENT:
- c->priv->brace_indent = g_value_get_uint (value);
+ case PROP_SCOPE_INDENT:
+ c->priv->scope_indent = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -241,16 +314,16 @@ gb_source_auto_indenter_c_class_init (GbSourceAutoIndenterCClass *klass)
indenter_class->query = gb_source_auto_indenter_c_query;
- gParamSpecs [PROP_BRACE_INDENT] =
- g_param_spec_uint ("brace-indent",
- _("Name"),
- _("Name"),
- 0,
- 32,
- 2,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_BRACE_INDENT,
- gParamSpecs [PROP_BRACE_INDENT]);
+ gParamSpecs [PROP_SCOPE_INDENT] =
+ g_param_spec_int ("scope-indent",
+ _("Name"),
+ _("Name"),
+ -32,
+ 32,
+ 2,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_SCOPE_INDENT,
+ gParamSpecs [PROP_SCOPE_INDENT]);
}
static void
@@ -258,5 +331,6 @@ gb_source_auto_indenter_c_init (GbSourceAutoIndenterC *c)
{
c->priv = gb_source_auto_indenter_c_get_instance_private (c);
- c->priv->brace_indent = 2;
+ c->priv->condition_indent = 2;
+ c->priv->scope_indent = 2;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]