[gnome-builder] python: unindent else/elif similar to VIM python mode
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] python: unindent else/elif similar to VIM python mode
- Date: Sun, 11 Jan 2015 11:34:10 +0000 (UTC)
commit 5ee8605bdf7f803cb38f2c6942056a5f13138c0c
Author: Christian Hergert <christian hergert me>
Date: Sun Jan 11 03:33:59 2015 -0800
python: unindent else/elif similar to VIM python mode
src/auto-indent/gb-source-auto-indenter-python.c | 96 ++++++++++++++++++++-
1 files changed, 91 insertions(+), 5 deletions(-)
---
diff --git a/src/auto-indent/gb-source-auto-indenter-python.c
b/src/auto-indent/gb-source-auto-indenter-python.c
index 5d923b9..29fb196 100644
--- a/src/auto-indent/gb-source-auto-indenter-python.c
+++ b/src/auto-indent/gb-source-auto-indenter-python.c
@@ -86,6 +86,31 @@ line_starts_with (GtkTextIter *line,
return ret;
}
+static gboolean
+line_ends_with (const GtkTextIter *iter,
+ const gchar *suffix)
+{
+ GtkTextIter begin = *iter;
+ GtkTextIter end;
+ gboolean ret = FALSE;
+
+ while (!gtk_text_iter_ends_line (&begin))
+ gtk_text_iter_forward_char (&begin);
+
+ end = begin;
+
+ if (gtk_text_iter_backward_chars (&begin, strlen (suffix)))
+ {
+ gchar *slice;
+
+ slice = gtk_text_iter_get_slice (&begin, &end);
+ ret = g_str_equal (slice, suffix);
+ g_free (slice);
+ }
+
+ return ret;
+}
+
static gchar *
copy_indent (GbSourceAutoIndenterPython *python,
GtkTextIter *begin,
@@ -366,7 +391,6 @@ indent_colon (GbSourceAutoIndenterPython *python,
gchar *slice;
slice = gtk_text_iter_get_slice (iter, ©);
- g_print ("SLICE: %s\n", slice);
if (g_strcmp0 (slice, "def ") == 0)
offset += tab_width;
g_free (slice);
@@ -484,10 +508,6 @@ indent_for_pair (GbSourceAutoIndenterPython *python,
copy = *iter;
- g_print ("Indent for pair\n");
-
- g_print (" '%c' '%c'\n", prev_ch, ch);
-
if ((prev_ch == '{' && ch == '}') ||
(prev_ch == '[' && ch == ']') ||
(prev_ch == '(' && ch == ')'))
@@ -513,6 +533,61 @@ indent_for_pair (GbSourceAutoIndenterPython *python,
}
static gchar *
+maybe_unindent_else_or_elif (GbSourceAutoIndenterPython *python,
+ GtkTextIter *begin,
+ GtkTextIter *end)
+{
+ GtkTextIter copy = *begin;
+ gboolean matches;
+ gchar *slice;
+
+ gtk_text_iter_backward_chars (©, 4);
+ slice = gtk_text_iter_get_slice (©, begin);
+ matches = g_str_equal (slice, "else") || g_str_equal (slice, "elif");
+
+ /* paranoia check to make sure this isn't part of a word. */
+ if (matches)
+ matches = (!gtk_text_iter_backward_char (©) ||
+ g_unichar_isspace (gtk_text_iter_get_char (©)));
+
+ if (matches)
+ {
+ /*
+ * TODO: This doesn't handle unindent properly for multi line
+ * if or while statements.
+ */
+ while (!(line_starts_with (©, "if ") || line_starts_with (©, "while ")) ||
+ !line_ends_with (©, ":"))
+ {
+ guint if_line;
+
+ if (!(if_line = gtk_text_iter_get_line (©)))
+ break;
+
+ gtk_text_iter_set_line_offset (©, 0);
+ gtk_text_iter_set_line (©, if_line - 1);
+
+ while (g_unichar_isspace (gtk_text_iter_get_char (©)) &&
+ !gtk_text_iter_ends_line (©))
+ if (!gtk_text_iter_forward_char (©))
+ break;
+ }
+
+ if ((line_starts_with (©, "if ") || line_starts_with (©, "while ")) &&
+ line_ends_with (©, ":"))
+ {
+ gtk_text_iter_set_line_offset (begin,
+ gtk_text_iter_get_line_offset (©));
+ return slice;
+ }
+ }
+
+ g_free (slice);
+
+ return NULL;
+}
+
+static gchar *
gb_source_auto_indenter_python_format (GbSourceAutoIndenter *indenter,
GtkTextView *text_view,
GtkTextBuffer *buffer,
@@ -526,6 +601,15 @@ gb_source_auto_indenter_python_format (GbSourceAutoIndenter *indenter,
gunichar ch;
gint line;
+ /* possibly trying to adjust "else" or "elif". we always return in this
+ * block, since we don't want to process anything else.
+ */
+ gtk_text_iter_backward_char (&iter);
+ ch = gtk_text_iter_get_char (&iter);
+ if (ch == 'e' || ch == 'f')
+ return maybe_unindent_else_or_elif (python, begin, end);
+
+ iter = *begin;
line = gtk_text_iter_get_line (&iter);
/* move to the last character of the last line */
@@ -621,6 +705,8 @@ gb_source_auto_indenter_python_is_trigger (GbSourceAutoIndenter *indenter,
{
switch (event->keyval)
{
+ case GDK_KEY_e:
+ case GDK_KEY_f:
case GDK_KEY_KP_Enter:
case GDK_KEY_Return:
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]