[gnome-builder] auto-indent: add a very minimal python indenter
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] auto-indent: add a very minimal python indenter
- Date: Wed, 22 Oct 2014 00:28:00 +0000 (UTC)
commit 8eb03cbd50348943a0d12d7a94c2f3f6851a4253
Author: Christian Hergert <christian hergert me>
Date: Tue Oct 21 17:27:38 2014 -0700
auto-indent: add a very minimal python indenter
src/auto-indent/gb-source-auto-indenter-python.c | 246 ++++++++++++++++++++++
src/auto-indent/gb-source-auto-indenter-python.h | 56 +++++
src/editor/gb-source-view.c | 3 +
src/gnome-builder.mk | 2 +
4 files changed, 307 insertions(+), 0 deletions(-)
---
diff --git a/src/auto-indent/gb-source-auto-indenter-python.c
b/src/auto-indent/gb-source-auto-indenter-python.c
new file mode 100644
index 0000000..49ffd9b
--- /dev/null
+++ b/src/auto-indent/gb-source-auto-indenter-python.c
@@ -0,0 +1,246 @@
+/* gb-source-auto-indenter-python.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "python-indent"
+
+#include "gb-log.h"
+#include "gb-source-auto-indenter-python.h"
+
+/*
+ * TODO:
+ *
+ * This module is very naive. It only checks for a line ending in : to
+ * indent. If you'd like to own this, go for it!
+ *
+ * I suggest adding something like auto indentation to a matching (
+ * for the case when () is used to extend to the next line.
+ */
+
+G_DEFINE_TYPE (GbSourceAutoIndenterPython,
+ gb_source_auto_indenter_python,
+ GB_TYPE_SOURCE_AUTO_INDENTER)
+
+GbSourceAutoIndenter *
+gb_source_auto_indenter_python_new (void)
+{
+ return g_object_new (GB_TYPE_SOURCE_AUTO_INDENTER_PYTHON, NULL);
+}
+
+static gboolean
+in_pydoc (const GtkTextIter *iter)
+{
+ /* TODO: implement this */
+ return FALSE;
+}
+
+static gchar *
+copy_indent (GbSourceAutoIndenterPython *python,
+ GtkTextIter *begin,
+ GtkTextIter *end,
+ GtkTextIter *copy)
+{
+ GString *str;
+
+ str = g_string_new (NULL);
+
+ gtk_text_iter_set_line_offset (copy, 0);
+
+ while (!gtk_text_iter_ends_line (copy))
+ {
+ gunichar ch;
+
+ ch = gtk_text_iter_get_char (copy);
+
+ if (!g_unichar_isspace (ch))
+ break;
+
+ g_string_append_unichar (str, ch);
+
+ if (gtk_text_iter_ends_line (copy) ||
+ !gtk_text_iter_forward_char (copy))
+ break;
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+static gchar *
+copy_indent_minus_tab (GbSourceAutoIndenterPython *python,
+ GtkTextView *view,
+ GtkTextIter *begin,
+ GtkTextIter *end,
+ GtkTextIter *copy)
+{
+ GString *str;
+ gchar *copied;
+ guint tab_width = 4;
+
+ copied = copy_indent (python, begin, end, copy);
+ str = g_string_new (copied);
+ g_free (copied);
+
+ if (GTK_SOURCE_IS_VIEW (view))
+ tab_width = gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (view));
+
+ if (tab_width <= str->len)
+ g_string_truncate (str, str->len - tab_width);
+
+ return g_string_free (str, FALSE);
+}
+
+static gchar *
+indent_colon (GbSourceAutoIndenterPython *python,
+ GtkTextView *view,
+ GtkTextIter *begin,
+ GtkTextIter *end,
+ GtkTextIter *iter)
+{
+ GString *str;
+ gint indent_width = -1;
+ guint tab_width = 4;
+ guint i;
+ gchar *ret;
+
+ /* this is super naive. we don't even walk back to handle multi-line
+ * function parameter lists!
+ */
+
+ ret = copy_indent (python, begin, end, iter);
+ str = g_string_new (ret);
+ g_free (ret);
+
+ /* force spaces for now, cause anything else is evil in python */
+
+ if (GTK_SOURCE_IS_VIEW (view))
+ indent_width = gtk_source_view_get_indent_width (GTK_SOURCE_VIEW (view));
+
+ if (indent_width == -1)
+ if (GTK_SOURCE_IS_VIEW (view))
+ tab_width = gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (view));
+
+ for (i = 0; i < tab_width; i++)
+ g_string_append (str, " ");
+
+ return g_string_free (str, FALSE);
+}
+
+static gboolean
+is_return_line (const GtkTextIter *line)
+{
+ GtkTextIter iter = *line;
+ GtkTextIter end;
+ gchar *text;
+ gboolean ret;
+
+ gtk_text_iter_set_line_offset (&iter, 0);
+
+ while (!gtk_text_iter_ends_line (&iter))
+ {
+ gunichar ch;
+
+ ch = gtk_text_iter_get_char (&iter);
+ if (!g_unichar_isspace (ch))
+ {
+ if (ch != 'r')
+ return FALSE;
+ break;
+ }
+
+ if (!gtk_text_iter_forward_char (&iter))
+ return FALSE;
+ }
+
+ end = iter;
+
+ if (!gtk_text_iter_forward_chars (&end, 6))
+ return FALSE;
+
+ text = gtk_text_iter_get_slice (&iter, &end);
+ ret = (g_strcmp0 (text, "return") == 0);
+ g_free (text);
+
+ return ret;
+}
+
+static gchar *
+gb_source_auto_indenter_python_format (GbSourceAutoIndenter *indenter,
+ GtkTextView *text_view,
+ GtkTextBuffer *buffer,
+ GtkTextIter *begin,
+ GtkTextIter *end,
+ gint *cursor_offset,
+ GdkEventKey *event)
+{
+ GbSourceAutoIndenterPython *python = (GbSourceAutoIndenterPython *)indenter;
+ GtkTextIter iter = *begin;
+ gunichar ch;
+
+ /* move to the last character of the last line */
+ if (!gtk_text_iter_backward_char (&iter) ||
+ !gtk_text_iter_backward_char (&iter))
+ return NULL;
+
+ /* get the last character */
+ ch = gtk_text_iter_get_char (&iter);
+
+ switch (ch)
+ {
+ case ':':
+ return indent_colon (python, text_view, begin, end, &iter);
+
+ default:
+ if (in_pydoc (&iter))
+ return copy_indent (python, begin, end, &iter);
+
+ if (is_return_line (&iter))
+ return copy_indent_minus_tab (python, text_view, begin, end, &iter);
+
+ return copy_indent (python, begin, end, &iter);
+ }
+
+ return NULL;
+}
+
+static gboolean
+gb_source_auto_indenter_python_is_trigger (GbSourceAutoIndenter *indenter,
+ GdkEventKey *event)
+{
+ switch (event->keyval)
+ {
+ case GDK_KEY_KP_Enter:
+ case GDK_KEY_Return:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+static void
+gb_source_auto_indenter_python_class_init (GbSourceAutoIndenterPythonClass *klass)
+{
+ GbSourceAutoIndenterClass *indent_class = GB_SOURCE_AUTO_INDENTER_CLASS (klass);
+
+ indent_class->is_trigger = gb_source_auto_indenter_python_is_trigger;
+ indent_class->format = gb_source_auto_indenter_python_format;
+}
+
+static void
+gb_source_auto_indenter_python_init (GbSourceAutoIndenterPython *self)
+{
+}
diff --git a/src/auto-indent/gb-source-auto-indenter-python.h
b/src/auto-indent/gb-source-auto-indenter-python.h
new file mode 100644
index 0000000..c8a4200
--- /dev/null
+++ b/src/auto-indent/gb-source-auto-indenter-python.h
@@ -0,0 +1,56 @@
+/* gb-source-auto-indenter-python.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_SOURCE_AUTO_INDENTER_PYTHON_H
+#define GB_SOURCE_AUTO_INDENTER_PYTHON_H
+
+#include "gb-source-auto-indenter.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_SOURCE_AUTO_INDENTER_PYTHON (gb_source_auto_indenter_python_get_type())
+#define GB_SOURCE_AUTO_INDENTER_PYTHON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_SOURCE_AUTO_INDENTER_PYTHON, GbSourceAutoIndenterPython))
+#define GB_SOURCE_AUTO_INDENTER_PYTHON_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_SOURCE_AUTO_INDENTER_PYTHON, GbSourceAutoIndenterPython const))
+#define GB_SOURCE_AUTO_INDENTER_PYTHON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GB_TYPE_SOURCE_AUTO_INDENTER_PYTHON, GbSourceAutoIndenterPythonClass))
+#define GB_IS_SOURCE_AUTO_INDENTER_PYTHON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GB_TYPE_SOURCE_AUTO_INDENTER_PYTHON))
+#define GB_IS_SOURCE_AUTO_INDENTER_PYTHON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GB_TYPE_SOURCE_AUTO_INDENTER_PYTHON))
+#define GB_SOURCE_AUTO_INDENTER_PYTHON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GB_TYPE_SOURCE_AUTO_INDENTER_PYTHON, GbSourceAutoIndenterPythonClass))
+
+typedef struct _GbSourceAutoIndenterPython GbSourceAutoIndenterPython;
+typedef struct _GbSourceAutoIndenterPythonClass GbSourceAutoIndenterPythonClass;
+typedef struct _GbSourceAutoIndenterPythonPrivate GbSourceAutoIndenterPythonPrivate;
+
+struct _GbSourceAutoIndenterPython
+{
+ GbSourceAutoIndenter parent;
+
+ /*< private >*/
+ GbSourceAutoIndenterPythonPrivate *priv;
+};
+
+struct _GbSourceAutoIndenterPythonClass
+{
+ GbSourceAutoIndenterClass parent;
+};
+
+GType gb_source_auto_indenter_python_get_type (void);
+GbSourceAutoIndenter *gb_source_auto_indenter_python_new (void);
+
+G_END_DECLS
+
+#endif /* GB_SOURCE_AUTO_INDENTER_PYTHON_H */
diff --git a/src/editor/gb-source-view.c b/src/editor/gb-source-view.c
index 99c1b4b..13849c9 100644
--- a/src/editor/gb-source-view.c
+++ b/src/editor/gb-source-view.c
@@ -24,6 +24,7 @@
#include "gb-animation.h"
#include "gb-source-auto-indenter.h"
#include "gb-source-auto-indenter-c.h"
+#include "gb-source-auto-indenter-python.h"
#include "gb-source-auto-indenter-xml.h"
#include "gb-box-theatric.h"
#include "gb-cairo.h"
@@ -890,6 +891,8 @@ on_language_set (GtkSourceBuffer *buffer,
if (g_str_equal (lang_id, "c") || g_str_equal (lang_id, "chdr"))
auto_indenter = gb_source_auto_indenter_c_new ();
+ else if (g_str_equal (lang_id, "python"))
+ auto_indenter = gb_source_auto_indenter_python_new ();
else if (g_str_equal (lang_id, "xml"))
auto_indenter = gb_source_auto_indenter_xml_new ();
}
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index c14c415..eb2b730 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -13,6 +13,8 @@ libgnome_builder_la_SOURCES = \
src/auto-indent/gb-source-auto-indenter.h \
src/auto-indent/gb-source-auto-indenter-c.c \
src/auto-indent/gb-source-auto-indenter-c.h \
+ src/auto-indent/gb-source-auto-indenter-python.c \
+ src/auto-indent/gb-source-auto-indenter-python.h \
src/auto-indent/gb-source-auto-indenter-xml.c \
src/auto-indent/gb-source-auto-indenter-xml.h \
src/commands/gb-command.c \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]