[gnome-builder] auto-indent: auto insert matching {}. do right thing on \n.
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] auto-indent: auto insert matching {}. do right thing on \n.
- Date: Sun, 21 Sep 2014 02:01:38 +0000 (UTC)
commit 171b10c6f76c9f02698c7c661331913afe36b7ca
Author: Christian Hergert <christian hergert me>
Date: Sat Sep 20 19:00:39 2014 -0700
auto-indent: auto insert matching {}. do right thing on \n.
Start with
{|}
Upon return, be like:
{
|
}
src/editor/gb-source-auto-indenter-c.c | 59 ++++++++++++++++++++++++++++++++
src/editor/gb-source-auto-indenter.c | 10 +++++
src/editor/gb-source-auto-indenter.h | 5 +++
src/editor/gb-source-view.c | 16 ++++++++-
4 files changed, 89 insertions(+), 1 deletions(-)
---
diff --git a/src/editor/gb-source-auto-indenter-c.c b/src/editor/gb-source-auto-indenter-c.c
index 2dde2bd..a27c8f4 100644
--- a/src/editor/gb-source-auto-indenter-c.c
+++ b/src/editor/gb-source-auto-indenter-c.c
@@ -904,6 +904,27 @@ maybe_align_parameters (GbSourceAutoIndenterC *c,
RETURN (ret);
}
+static gchar *
+maybe_add_brace (GbSourceAutoIndenterC *c,
+ GtkTextIter *begin,
+ GtkTextIter *end,
+ gint *cursor_offset)
+{
+ GtkTextIter iter;
+
+ gtk_text_iter_assign (&iter, begin);
+
+ if (gtk_text_iter_backward_char (&iter) &&
+ (gtk_text_iter_get_char (&iter) == '{') &&
+ (gtk_text_iter_get_char (begin) != '}'))
+ {
+ *cursor_offset = -1;
+ return g_strdup ("}");
+ }
+
+ return NULL;
+}
+
static gboolean
gb_source_auto_indenter_c_is_trigger (GbSourceAutoIndenter *indenter,
GdkEventKey *event)
@@ -911,6 +932,7 @@ gb_source_auto_indenter_c_is_trigger (GbSourceAutoIndenter *indenter,
switch (event->keyval) {
case GDK_KEY_KP_Enter:
case GDK_KEY_Return:
+ case GDK_KEY_braceleft:
case GDK_KEY_braceright:
case GDK_KEY_colon:
case GDK_KEY_numbersign:
@@ -929,6 +951,7 @@ gb_source_auto_indenter_c_format (GbSourceAutoIndenter *indenter,
GtkTextBuffer *buffer,
GtkTextIter *begin,
GtkTextIter *end,
+ gint *cursor_offset,
GdkEventKey *event)
{
GbSourceAutoIndenterC *c = (GbSourceAutoIndenterC *)indenter;
@@ -943,11 +966,47 @@ gb_source_auto_indenter_c_format (GbSourceAutoIndenter *indenter,
gtk_text_iter_assign (&begin_copy, begin);
ret = gb_source_auto_indenter_c_indent (c, view, buffer, begin);
gtk_text_iter_assign (begin, &begin_copy);
+
+ /*
+ * If we are inserting a newline right before a closing brace (for example
+ * after {<cursor>}, we need to indent and then maybe unindent the }.
+ */
+ if (gtk_text_iter_get_char (begin) == '}')
+ {
+ GtkTextIter iter;
+ GString *str;
+ gchar *tmp = ret;
+ guint offset;
+
+ str = g_string_new (NULL);
+
+ gtk_text_iter_assign (&iter, begin);
+ gtk_text_iter_backward_char (&iter);
+ gtk_text_iter_backward_char (&iter);
+ offset = gtk_text_iter_get_line_offset (&iter);
+ build_indent (c, offset, &iter, str);
+ g_string_prepend (str, "\n");
+ g_string_prepend (str, ret);
+
+ *cursor_offset = -(str->len - strlen (ret));
+
+ ret = g_string_free (str, FALSE);
+ g_free (tmp);
+ }
+
+ break;
+
+ case GDK_KEY_braceleft:
+ /*
+ * If we are starting a new scope, maybe add a match closing brace.
+ */
+ ret = maybe_add_brace (c, begin, end, cursor_offset);
break;
case GDK_KEY_braceright:
/*
* Probably need to unindent this line.
+ * TODO: Maybe overwrite character.
*/
ret = maybe_unindent_brace (c, begin, end);
break;
diff --git a/src/editor/gb-source-auto-indenter.c b/src/editor/gb-source-auto-indenter.c
index 58ace44..e8d63ec 100644
--- a/src/editor/gb-source-auto-indenter.c
+++ b/src/editor/gb-source-auto-indenter.c
@@ -71,8 +71,11 @@ gb_source_auto_indenter_format (GbSourceAutoIndenter *indenter,
GtkTextBuffer *buffer,
GtkTextIter *begin,
GtkTextIter *end,
+ gint *cursor_offset,
GdkEventKey *event)
{
+ gint dummy;
+
g_return_val_if_fail (GB_IS_SOURCE_AUTO_INDENTER (indenter), NULL);
g_return_val_if_fail (GTK_IS_TEXT_VIEW (view), NULL);
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
@@ -80,11 +83,17 @@ gb_source_auto_indenter_format (GbSourceAutoIndenter *indenter,
g_return_val_if_fail (end, NULL);
g_return_val_if_fail (event, NULL);
+ if (cursor_offset)
+ *cursor_offset = 0;
+ else
+ cursor_offset = &dummy;
+
return GB_SOURCE_AUTO_INDENTER_GET_CLASS (indenter)->format (indenter,
view,
buffer,
begin,
end,
+ cursor_offset,
event);
}
@@ -94,6 +103,7 @@ gb_source_auto_indenter_real_format (GbSourceAutoIndenter *indenter,
GtkTextBuffer *buffer,
GtkTextIter *begin,
GtkTextIter *end,
+ gint *cursor_offset,
GdkEventKey *event)
{
return NULL;
diff --git a/src/editor/gb-source-auto-indenter.h b/src/editor/gb-source-auto-indenter.h
index 7d4bebd..d1de838 100644
--- a/src/editor/gb-source-auto-indenter.h
+++ b/src/editor/gb-source-auto-indenter.h
@@ -48,6 +48,9 @@ struct _GbSourceAutoIndenterClass
{
GObjectClass parent_class;
+ /*
+ * TODO: Remove "query".
+ */
gchar *(*query) (GbSourceAutoIndenter *indenter,
GtkTextView *view,
GtkTextBuffer *buffer,
@@ -58,6 +61,7 @@ struct _GbSourceAutoIndenterClass
GtkTextBuffer *buffer,
GtkTextIter *begin,
GtkTextIter *end,
+ gint *cursor_offset,
GdkEventKey *trigger);
gboolean (*is_trigger) (GbSourceAutoIndenter *indenter,
@@ -78,6 +82,7 @@ gchar *gb_source_auto_indenter_format (GbSourceAutoIndenter *indenter,
GtkTextBuffer *buffer,
GtkTextIter *begin,
GtkTextIter *end,
+ gint *cursor_offset,
GdkEventKey *event);
G_END_DECLS
diff --git a/src/editor/gb-source-view.c b/src/editor/gb-source-view.c
index a6176c3..12e8d4a 100644
--- a/src/editor/gb-source-view.c
+++ b/src/editor/gb-source-view.c
@@ -986,6 +986,7 @@ gb_source_view_key_press_event (GtkWidget *widget,
GtkTextIter begin;
GtkTextIter end;
gchar *indent;
+ gint cursor_offset = 0;
/*
* Insert into the buffer so the auto-indenter can see it. If
@@ -1007,16 +1008,29 @@ gb_source_view_key_press_event (GtkWidget *widget,
indent = gb_source_auto_indenter_format (priv->auto_indenter,
GTK_TEXT_VIEW (view),
priv->buffer, &begin, &end,
- event);
+ &cursor_offset, event);
if (indent)
{
+ /*
+ * Insert the indention text.
+ */
gtk_text_buffer_begin_user_action (priv->buffer);
if (!gtk_text_iter_equal (&begin, &end))
gtk_text_buffer_delete (priv->buffer, &begin, &end);
gtk_text_buffer_insert (priv->buffer, &begin, indent, -1);
g_free (indent);
gtk_text_buffer_end_user_action (priv->buffer);
+
+ /*
+ * Place the cursor, as it could be somewhere within our indent text.
+ */
+ gtk_text_buffer_get_iter_at_mark (priv->buffer, &begin, insert);
+ if (cursor_offset > 0)
+ gtk_text_iter_forward_chars (&begin, cursor_offset);
+ else if (cursor_offset < 0)
+ gtk_text_iter_backward_chars (&begin, ABS (cursor_offset));
+ gtk_text_buffer_select_range (priv->buffer, &begin, &begin);
}
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]