[gedit-code-assistance/wip/indent] Load indent backends



commit 824bda65e8ed681e6797278f1ccd4ef908d8f095
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Sun Apr 6 21:11:37 2014 +0200

    Load indent backends

 Makefile.am                               |    1 +
 configure.ac                              |   17 +
 indentbackends/Makefile.am                |   11 +
 indentbackends/c/Makefile.am              |   22 +
 indentbackends/c/gca-c-backend.vala       |  225 +++++++++
 indentbackends/c/gcaindentbackendc.plugin |   11 +
 src/Makefile.am                           |   19 +-
 src/gca-backend-manager.vala              |   77 +++
 src/gca-indent-backend.vala               |  103 ++++
 src/gca-plugin.vala                       |    2 +-
 src/gca-view.vala                         |  202 ++++++++-
 vapi/Makefile.am                          |    3 +-
 vapi/config.vapi                          |   11 +
 vapi/gtksourceview-3.0.vapi               |  728 +++++++++++++++++++++++++++++
 14 files changed, 1412 insertions(+), 20 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 155b36f..c27c8b0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,6 +35,7 @@ geditcodeassistanceplugindir = $(GEDIT_PLUGIN_DIR)
 include data/Makefile.am
 include src/Makefile.am
 include vapi/Makefile.am
+include indentbackends/Makefile.am
 
 dist-hook-changelog:
        @if test -d "$(srcdir)/.git"; \
diff --git a/configure.ac b/configure.ac
index 7bae58a..2f19f7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,12 +70,29 @@ fi
 GEDIT_PLUGIN_DIR="$geditlibdir/gedit/plugins"
 GEDIT_DATA_DIR="$geditdatadir/gedit/plugins"
 
+GCA_INDENT_BACKENDS_LIBS_DIR="$GEDIT_PLUGIN_DIR/gca/indent-backends"
+GCA_INDENT_BACKENDS_DATA_DIR="$GEDIT_DATA_DIR/gca/indent-backends"
+
+GCA_LIBS_DIR="$GEDIT_PLUGIN_DIR/gca"
+AC_SUBST(GCA_LIBS_DIR)
+
+GCA_DATA_DIR="$GEDIT_DATA_DIR/gca"
+AC_SUBST(GCA_DATA_DIR)
+
 AC_SUBST(GEDIT_PLUGIN_DIR)
 AC_SUBST(GEDIT_DATA_DIR)
 
 AC_SUBST(GEDIT_CFLAGS)
 AC_SUBST(GEDIT_LIBS)
 
+AC_SUBST(GCA_INDENT_BACKENDS_LIBS_DIR)
+AC_SUBST(GCA_INDENT_BACKENDS_DATA_DIR)
+
+AC_DEFINE_UNQUOTED([GCA_INDENT_BACKENDS_DIR], "$GCA_INDENT_BACKENDS_LIBS_DIR", [Indent Backends dir])
+AC_DEFINE_UNQUOTED([GCA_INDENT_BACKENDS_DATA_DIR], "$GCA_INDENT_BACKENDS_DATA_DIR", [Indent Backends data 
dir])
+AC_DEFINE_UNQUOTED([GCA_LIBS_DIR], "$GCA_LIBS_DIR", [Library dir])
+AC_DEFINE_UNQUOTED([GCA_DATA_DIR], "$GCA_DATA_DIR", [Data dir])
+
 AC_CONFIG_FILES([
 Makefile
 data/codeassistance.plugin
diff --git a/indentbackends/Makefile.am b/indentbackends/Makefile.am
new file mode 100644
index 0000000..6874e59
--- /dev/null
+++ b/indentbackends/Makefile.am
@@ -0,0 +1,11 @@
+plugindir = $(GCA_INDENT_BACKENDS_LIBS_DIR)
+
+plugin_in_files               =
+plugin_LTLIBRARIES            =
+
+include indentbackends/c/Makefile.am
+
+plugin_DATA = $(plugin_in_files)
+
+EXTRA_DIST +=                                                                  \
+       $(plugin_in_files)
diff --git a/indentbackends/c/Makefile.am b/indentbackends/c/Makefile.am
new file mode 100644
index 0000000..6862fa6
--- /dev/null
+++ b/indentbackends/c/Makefile.am
@@ -0,0 +1,22 @@
+plugin_LTLIBRARIES += indentbackends/c/libgcaindentbackendc.la
+
+indentbackends_c_libgcaindentbackendc_la_SOURCES =                     \
+       indentbackends/c/gca-c-backend.vala
+
+indentbackends_c_libgcaindentbackendc_la_CFLAGS = $(GEDIT_CFLAGS) -I$(top_srcdir)/src
+indentbackends_c_libgcaindentbackendc_la_LIBADD = $(GEDIT_LIBS)
+indentbackends_c_libgcaindentbackendc_la_LDFLAGS = -module -avoid-version
+
+indentbackends_c_libgcaindentbackendc_la_VALAFLAGS =           \
+       --vapidir $(builddir)/vapi                              \
+       --vapidir $(builddir)/src                               \
+       --pkg gca                                               \
+       --pkg gio-unix-2.0                                      \
+       --pkg gee-0.8                                           \
+       --pkg gca-utils                                         \
+       --pkg gedit                                             \
+       --pkg libpeas-1.0                                       \
+       --target-glib=2.36                                      \
+       --thread
+
+plugin_in_files += indentbackends/c/gcaindentbackendc.plugin
diff --git a/indentbackends/c/gca-c-backend.vala b/indentbackends/c/gca-c-backend.vala
new file mode 100644
index 0000000..ea3bb5e
--- /dev/null
+++ b/indentbackends/c/gca-c-backend.vala
@@ -0,0 +1,225 @@
+/*
+ * This file is part of gedit-code-assistant.
+ *
+ * Copyright (C) 2014 - Ignacio Casal Quinteiro
+ *
+ * gedit-code-assistant 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.
+ *
+ * gedit-code-assistant 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 gedit-code-assistant.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Gca.C
+{
+
+class Backend : Object, Gca.IndentBackend
+{
+       private unowned Gedit.View d_view;
+
+       void register_backend(Gedit.View view)
+       {
+               d_view = view;
+       }
+
+       void unregister_backend()
+       {
+               d_view = null;
+       }
+
+       string[] get_triggers()
+       {
+               return { "0{", "0}", "0#", ":" };
+       }
+
+       bool move_to_no_space(ref Gtk.TextIter place, bool forward)
+       {
+               if (place.is_end() && !place.forward_chars(forward ? 1 : -1))
+               {
+                       return false;
+               }
+
+               bool moved = true;
+
+               var c = place.get_char();
+               while (c.isspace())
+               {
+                       if (!place.forward_chars(forward ? 1 : -1))
+                       {
+                               moved = false;
+                               break;
+                       }
+
+                       c = place.get_char();
+               }
+
+               return moved;
+       }
+
+       bool find_open_char(ref Gtk.TextIter place, unichar open, unichar close, bool skip_first)
+       {
+               var copy = place;
+               int counter = 0;
+               bool moved = false;
+
+               do
+               {
+                       var c = copy.get_char();
+
+                       if (c == close || skip_first)
+                       {
+                               counter--;
+                               skip_first = false;
+                       }
+
+                       if (c == open && counter != 0)
+                       {
+                               counter++;
+                       }
+
+                       if (counter == 0)
+                       {
+                               place = copy;
+                               moved = true;
+                               break;
+                       }
+               } while (copy.backward_char());
+
+               return moved;
+       }
+
+       unichar get_first_char_in_line(Gtk.TextIter place)
+       {
+               place.set_line_offset(0);
+               unichar c = place.get_char();
+
+               while (c.isspace() && !place.ends_line())
+               {
+                       if (!place.forward_char())
+                       {
+                               break;
+                       }
+
+                       c = place.get_char();
+               }
+
+               return c;
+       }
+
+       uint get_indent(Gedit.Document document, Gtk.TextIter place)
+       {
+               uint amount = 0;
+               var iter = place;
+
+               // if we are in the first line then 0 is fine
+               if (iter.get_line() == 0)
+               {
+                       return 0;
+               }
+
+               // move to the beginning to get some context from previous lines
+               iter.set_line_offset(0);
+
+               if (!move_to_no_space(ref iter, false))
+               {
+                       return 0;
+               }
+
+               if (document.iter_has_context_class(iter, "comment"))
+               {
+                       if (!document.iter_backward_to_context_class_toggle(ref iter, "comment"))
+                       {
+                               return 0;
+                       }
+                       else
+                       {
+                               // align with the start of the comment
+                               amount = get_line_indents(d_view, iter);
+                       }
+               }
+
+               var c = iter.get_char();
+
+               if (c == ';')
+               {
+                       // hello(param1,
+                       //       param2);
+                       var copy = iter;
+                       if (copy.backward_char() && copy.get_char() == ')')
+                       {
+                               if (find_open_char(ref copy, '(', ')', false))
+                               {
+                                       amount = get_line_indents(d_view, copy);
+                               }
+                               else
+                               {
+                                       // fallback to try to use the current place
+                                       amount = get_line_indents(d_view, iter);
+                               }
+                       }
+                       else
+                       {
+                               // hello;
+                               amount = get_line_indents(d_view, iter);
+                       }
+               }
+               else if (c == ')')
+               {
+                       var copy = iter;
+                       if (find_open_char(ref copy, '(', ')', false))
+                       {
+                               amount = get_line_indents(d_view, copy);
+
+                               if (get_first_char_in_line(place) != '{')
+                               {
+                                       amount += get_indent_width(d_view);
+                               }
+                       }
+               }
+               else if (c == '{')
+               {
+                       amount = get_line_indents(d_view, iter);
+                       amount += get_indent_width(d_view);
+               }
+
+               if (get_first_char_in_line(place) == '}')
+               {
+                       var copy = place;
+
+                       // we know the line starts with } so move the iter to the beginning
+                       // of the line to search of the opener {
+                       copy.set_line_offset(0);
+
+                       if (find_open_char(ref copy, '{', '}', true))
+                       {
+                               amount = get_line_indents(d_view, copy);
+                       }
+               }
+               else if (get_first_char_in_line(place) == '#')
+               {
+                       amount = 0;
+               }
+
+               return amount;
+       }
+}
+
+}
+
+[ModuleInit]
+public void peas_register_types(TypeModule module)
+{
+       Peas.ObjectModule mod = module as Peas.ObjectModule;
+
+       mod.register_extension_type(typeof(Gca.IndentBackend),
+                                   typeof(Gca.C.Backend));
+}
+
+/* vi:ex:ts=4 */
diff --git a/indentbackends/c/gcaindentbackendc.plugin b/indentbackends/c/gcaindentbackendc.plugin
new file mode 100644
index 0000000..21e2829
--- /dev/null
+++ b/indentbackends/c/gcaindentbackendc.plugin
@@ -0,0 +1,11 @@
+[Plugin]
+Module=gcaindentbackendc
+IAge=3
+Name=Code Assistance C Indent Backend
+Hidden=yes
+Builtin=yes
+Description=Code assistance indent backend for C
+Authors=Ignacio Casal Quinteiro <icq gnome org>
+Copyright=Copyright © 2014 Ignacio Casal Quinteiro
+Website=http://www.gedit.org
+X-Languages=c
diff --git a/src/Makefile.am b/src/Makefile.am
index 9fc00ab..0e2bd62 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,7 +27,8 @@ gedit_plugin_vala_sources =                                   \
        src/gca-diagnostic-message.vala                         \
        src/gca-dbus.vala                                       \
        src/gca-remote-service.vala                             \
-       src/gca-log.vala
+       src/gca-log.vala                                        \
+       src/gca-indent-backend.vala
 
 gedit_plugin_libcodeassistance_NOINSTHFILES =                  \
        src/gca-utils-c.h
@@ -40,18 +41,19 @@ src_libcodeassistance_la_SOURCES =          \
 
 src_libcodeassistance_la_VALAFLAGS =                           \
        --vapidir $(builddir)/vapi                              \
-       --vapi src/libcodeassistance-internal.vapi              \
+       --header src/gca.h                                      \
+       --vapi src/gca.vapi                                     \
        --library libcodeassistance                             \
        --pkg gio-unix-2.0                                      \
        --pkg gee-0.8                                           \
        --pkg gca-utils                                         \
        --pkg gedit                                             \
        --pkg libpeas-1.0                                       \
+       --pkg gobject-introspection-1.0                         \
+       --pkg config                                            \
        --target-glib=2.36                                      \
        --thread
 
-noinst_DATA = src/libcodeassistance-internal.vapi
-
 if ENABLE_DEBUG
 src_libcodeassistance_la_VALAFLAGS += --debug
 endif
@@ -59,13 +61,20 @@ endif
 src_libcodeassistance_la_CFLAGS = $(GEDIT_CFLAGS) -I$(top_srcdir) -w
 src_libcodeassistance_la_LDFLAGS = -module -shared -avoid-version $(GEDIT_LIBS)
 
+vapidir = $(datadir)/vala/vapi
+dist_vapi_DATA =       \
+       src/gca.vapi
+
+gcahdir = $(prefix)/include/gedit-$(GEDIT_API_VERSION)/gca
+gcah_HEADERS = src/gca.h
+
 CLEANFILES +=                                                  \
        $(gedit_plugin_vala_sources:.vala=.c)                   \
        $(srcdir)/src_libcodeassistance_la_vala.stamp
 
 GITIGNOREFILES +=                                              \
        src/$(DEPDIR)                                           \
-       src/libcodeassistance-internal.vapi                     \
+       src/gca.vapi                    \
        src/*.lo                                                \
        src/*.o                                                 \
        src/.libs                                               \
diff --git a/src/gca-backend-manager.vala b/src/gca-backend-manager.vala
index 9c7b859..3084d92 100644
--- a/src/gca-backend-manager.vala
+++ b/src/gca-backend-manager.vala
@@ -26,6 +26,19 @@ class BackendManager
        private Gee.HashMap<string, Backend?> d_backends;
        private Gee.HashMap<string, string> d_language_mapping;
        private Settings? d_settings;
+       private Gee.HashMap<string, IndentBackendInfo> d_indent_backends;
+       private Peas.Engine d_engine;
+
+       class IndentBackendInfo : Object
+       {
+               public IndentBackend ?backend { get; set; }
+               public Peas.PluginInfo info { get; set; }
+
+               public IndentBackendInfo(Peas.PluginInfo info)
+               {
+                       Object(info: info);
+               }
+       }
 
        private BackendManager()
        {
@@ -49,6 +62,52 @@ class BackendManager
                                update_language_mapping();
                        });
                }
+
+               d_indent_backends = new Gee.HashMap<string, IndentBackendInfo>();
+
+               d_engine = new Peas.Engine();
+
+               d_engine.add_search_path(Gca.Config.GCA_INDENT_BACKENDS_DIR,
+                                        Gca.Config.GCA_INDENT_BACKENDS_DATA_DIR);
+
+               d_engine.enable_loader("python3");
+
+               // require the gca gir
+               string tpdir = Path.build_filename(Gca.Config.GCA_LIBS_DIR,
+                                                  "girepository-1.0");
+
+               var repo = GI.Repository.get_default();
+
+               try
+               {
+                       repo.require_private(tpdir, "Gca", "3.0", 0);
+               }
+               catch (Error error)
+               {
+                       warning("Could not load Gca typelib: %s", error.message);
+               }
+
+               register_backends();
+       }
+
+       private void register_backends()
+       {
+               foreach (Peas.PluginInfo info in d_engine.get_plugin_list())
+               {
+                       string? langs = info.get_external_data("Languages");
+
+                       if (langs == null)
+                       {
+                               continue;
+                       }
+
+                       IndentBackendInfo binfo = new IndentBackendInfo(info);
+
+                       foreach (string lang in langs.split(","))
+                       {
+                               d_indent_backends[lang] = binfo;
+                       }
+               }
        }
 
        private void update_language_mapping()
@@ -112,6 +171,24 @@ class BackendManager
                return backend;
        }
 
+       public async IndentBackend? indent_backend(string language)
+       {
+               if (!d_indent_backends.has_key(language))
+               {
+                       return null;
+               }
+
+               IndentBackendInfo info = d_indent_backends[language];
+
+               if (info.backend == null)
+               {
+                       d_engine.load_plugin(info.info);
+                       info.backend = (Gca.IndentBackend)d_engine.create_extension(info.info, 
typeof(Gca.IndentBackend));
+               }
+
+               return info.backend;
+       }
+
        public static BackendManager instance
        {
                get
diff --git a/src/gca-indent-backend.vala b/src/gca-indent-backend.vala
new file mode 100644
index 0000000..effcfb9
--- /dev/null
+++ b/src/gca-indent-backend.vala
@@ -0,0 +1,103 @@
+/*
+ * This file is part of gedit-code-assistant.
+ *
+ * Copyright (C) 2014 - Ignacio Casal Quinteiro
+ *
+ * gedit-code-assistant 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.
+ *
+ * gedit-code-assistant 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 gedit-code-assistant.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Gca
+{
+
+public interface IndentBackend : Object
+{
+       public abstract void register_backend(Gedit.View view);
+       public abstract void unregister_backend();
+
+       /* These are the chars that trigger an extra indentation, i.e { */
+       public abstract string[] get_triggers();
+       /* It returns the indentation level */
+       public abstract uint get_indent(Gedit.Document document, Gtk.TextIter place);
+
+       public uint get_indent_width(Gedit.View view)
+       {
+               return view.indent_width < 0 ? view.tab_width : view.indent_width;
+       }
+
+       public uint get_line_indents(Gedit.View view, Gtk.TextIter place)
+       {
+               var start = place;
+               start.set_line_offset(0);
+
+               var c = start.get_char();
+
+               while (c.isspace() && c != '\n' && c != '\r')
+               {
+                       if (!start.forward_char())
+                       {
+                               break;
+                       }
+
+                       c = start.get_char();
+               }
+
+               return get_amount_indents_from_position(view, start);
+       }
+
+       public uint get_amount_indents_from_position(Gedit.View view, Gtk.TextIter place)
+       {
+               var indent_width = get_indent_width(view);
+
+               var start = place;
+               start.set_line_offset(0);
+
+               int rest = 0;
+               uint amount = 0;
+               var c = start.get_char();
+               while (start.compare(place) < 0)
+               {
+                       if (c == '\t')
+                       {
+                               if (rest != 0)
+                               {
+                                       rest = 0;
+                               }
+                               amount += indent_width;
+                       }
+                       else
+                       {
+                               rest++;
+                       }
+
+                       if (rest == indent_width)
+                       {
+                               amount += indent_width;
+                               rest = 0;
+                       }
+
+                       if (!start.forward_char())
+                       {
+                               break;
+                       }
+
+                       c = start.get_char();
+               }
+
+               return amount + rest;
+       }
+}
+
+}
+
+/* vi:ex:ts=4 */
diff --git a/src/gca-plugin.vala b/src/gca-plugin.vala
index bbfd370..f7aeba9 100644
--- a/src/gca-plugin.vala
+++ b/src/gca-plugin.vala
@@ -18,7 +18,7 @@
  */
 
 //[ModuleInit]
-public static void peas_register_types(TypeModule module)
+internal void peas_register_types(TypeModule module)
 {
        Peas.ObjectModule mod = module as Peas.ObjectModule;
 
diff --git a/src/gca-view.vala b/src/gca-view.vala
index b511b7e..bca9c57 100644
--- a/src/gca-view.vala
+++ b/src/gca-view.vala
@@ -35,6 +35,7 @@ class View : Object
        private unowned Gedit.View d_view;
        private Document d_document;
        private Backend d_backend;
+       private IndentBackend d_indent_backend;
        private ScrollbarMarker? d_scrollbar_marker;
        private uint d_timeout;
 
@@ -48,6 +49,7 @@ class View : Object
                d_view = view;
 
                d_view.notify["buffer"].connect(on_notify_buffer);
+               d_view.event_after.connect(on_event_after);
 
                connect_document(d_view.buffer as Gedit.Document);
 
@@ -81,6 +83,7 @@ class View : Object
        public void deactivate()
        {
                d_view.notify["buffer"].disconnect(on_notify_buffer);
+               d_view.event_after.disconnect(on_event_after);
 
                disconnect_document();
 
@@ -111,7 +114,7 @@ class View : Object
                d_document.changed.disconnect(on_document_changed);
                d_document.path_changed.disconnect(on_document_path_changed);
 
-               unregister_backend();
+               unregister_backends();
 
                d_document = null;
        }
@@ -134,7 +137,7 @@ class View : Object
                d_document.changed.connect(on_document_changed);
                d_document.path_changed.connect(on_document_path_changed);
 
-               update_backend();
+               update_backends();
        }
 
        private void on_document_path_changed(string? prevpath)
@@ -173,9 +176,9 @@ class View : Object
                reparse();
        }
 
-       private void update_backend()
+       private void update_backends()
        {
-               unregister_backend();
+               unregister_backends();
 
                /* Update the backend according to the current language on the buffer */
                if (d_document != null && d_document.document.language != null)
@@ -186,23 +189,32 @@ class View : Object
                                var backend = manager.backend.end(res);
                                register_backend(backend);
                        });
+
+                       manager.indent_backend.begin(d_document.document.language.id, (obj, res) => {
+                               var backend = manager.indent_backend.end(res);
+                               register_indent_backend(backend);
+                       });
                }
        }
 
-       private void unregister_backend()
+       private void unregister_backends()
        {
-               if (d_backend == null)
+               if (d_backend != null)
                {
-                       return;
+                       foreach (var service in d_services)
+                       {
+                               service.destroy();
+                       }
+
+                       d_backend.unregister(this);
+                       d_backend = null;
                }
 
-               foreach (var service in d_services)
+               if (d_indent_backend != null)
                {
-                       service.destroy();
+                       d_indent_backend.unregister_backend();
+                       d_indent_backend = null;
                }
-
-               d_backend.unregister(this);
-               d_backend = null;
        }
 
        private void register_backend(Backend? backend)
@@ -218,6 +230,18 @@ class View : Object
                on_document_changed();
        }
 
+       private void register_indent_backend(IndentBackend? backend)
+       {
+               d_indent_backend = backend;
+
+               if (d_indent_backend == null)
+               {
+                       return;
+               }
+
+               d_indent_backend.register_backend(d_view);
+       }
+
        private void on_notify_buffer()
        {
                disconnect_document();
@@ -226,7 +250,159 @@ class View : Object
 
        private void on_notify_language()
        {
-               update_backend();
+               update_backends();
+       }
+
+       private unichar get_introduced_char(Gtk.TextBuffer buf, ref Gtk.TextIter cur)
+       {
+               unichar c = 0;
+
+               var start = cur;
+
+               if (start.backward_char())
+               {
+                       c = start.get_char();
+               }
+
+               cur = start;
+
+               return c;
+       }
+
+       private bool is_whitespaces(Gtk.TextBuffer buf, Gtk.TextIter cur)
+       {
+               // Check the first char is not space
+               if (cur.get_line_offset() == 0)
+               {
+                       return true;
+               }
+
+               bool check = true;
+               var start = cur;
+
+               start.set_line_offset(0);
+               var c = start.get_char();
+
+               while (start.compare(cur) < 0)
+               {
+                       if (!c.isspace())
+                       {
+                               check = false;
+                               break;
+                       }
+               
+                       if (!start.forward_char())
+                       {
+                               check = false;
+                               break;
+                       }
+
+                       c = start.get_char();
+               }
+       
+               return check;
+       }
+
+       private string get_indent_string_from_indent_level(uint level)
+       {
+               string indent = "";
+
+               if (d_view.insert_spaces_instead_of_tabs)
+               {
+                       indent = string.nfill(level, ' ');
+               }
+               else
+               {
+                       var indent_width = d_indent_backend.get_indent_width(d_view);
+                       uint tabs = level / indent_width;
+                       uint spaces = level % indent_width;
+
+                       indent = string.nfill(tabs, '\t').concat(string.nfill(spaces, ' '));
+               }
+
+               return indent;
+       }
+
+       private void on_event_after(Gtk.Widget widget, Gdk.Event event)
+       {
+               if (d_document == null ||
+                   d_indent_backend == null ||
+                   event.type != Gdk.EventType.KEY_PRESS ||
+                   (event.key.state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.MOD1_MASK)) != 0)
+               {
+                       return;
+               }
+
+               var buf = d_document.document;
+               var insert = buf.get_insert();
+
+               Gtk.TextIter cur;
+               buf.get_iter_at_mark(out cur, insert);
+
+               bool indent = false;
+
+               if (event.key.keyval == Gdk.Key.Return || event.key.keyval == Gdk.Key.KP_Enter)
+               {
+                       indent = true;
+               }
+               else
+               {
+                       /* NOTE: for the future we could make the triggers real regexes
+                        * although this way worked for vim so it may as well work for us
+                        */
+                       var copy = cur;
+                       var introduced_char = get_introduced_char(buf, ref copy);
+
+                       foreach (var trigger in d_indent_backend.get_triggers())
+                       {
+                               // get the last char to validate with the key pressed
+                               var c = trigger.get_char(trigger.length - 1);
+                               if (c != introduced_char || event.key.keyval != Gdk.unicode_to_keyval(c))
+                               {
+                                       continue;
+                               }
+
+                               if (trigger.get_char(0) == '0' && !is_whitespaces(buf, copy))
+                               {
+                                       break;
+                               }
+
+                               indent = true;
+                               break;
+                       }
+               }
+
+               if (indent)
+               {
+                       uint indent_level;
+
+                       indent_level = d_indent_backend.get_indent(buf, cur);
+
+                       print("indent level: %u\n", indent_level);
+
+                       var start = cur;
+                       start.set_line_offset(0);
+                       var end = start;
+
+                       var c = end.get_char();
+                       while (c.isspace())
+                       {
+                               if (!end.forward_char() || end.ends_line())
+                               {
+                                       break;
+                               }
+
+                               c = end.get_char();
+                       }
+
+                       var indent_string = get_indent_string_from_indent_level(indent_level);
+
+                       buf.begin_user_action();
+                       buf.delete(ref start, ref end);
+
+                       buf.insert(ref start, indent_string, -1);
+                       buf.end_user_action();
+               }
        }
 }
 
diff --git a/vapi/Makefile.am b/vapi/Makefile.am
index 20fdf3e..7b72cd4 100644
--- a/vapi/Makefile.am
+++ b/vapi/Makefile.am
@@ -1,4 +1,5 @@
 EXTRA_DIST +=                                  \
-       vapi/gca-utils.vapi
+       vapi/gca-utils.vapi                     \
+       vapi/gtksourceview-3.0.vapi
 
 GITIGNOREDEPS += vapi/Makefile.am
diff --git a/vapi/config.vapi b/vapi/config.vapi
new file mode 100644
index 0000000..0c8235b
--- /dev/null
+++ b/vapi/config.vapi
@@ -0,0 +1,11 @@
+[CCode(cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")]
+namespace Gca.Config
+{
+       public const string GCA_INDENT_BACKENDS_DIR;
+       public const string GCA_INDENT_BACKENDS_DATA_DIR;
+       public const string GCA_LIBS_DIR;
+       public const string GCA_DATA_DIR;
+}
+
+// ex:ts=4 noet
+
diff --git a/vapi/gtksourceview-3.0.vapi b/vapi/gtksourceview-3.0.vapi
new file mode 100644
index 0000000..f082fed
--- /dev/null
+++ b/vapi/gtksourceview-3.0.vapi
@@ -0,0 +1,728 @@
+/* gtksourceview-3.0.vapi generated by vapigen, do not modify. */
+
+[CCode (cprefix = "Gtk", gir_namespace = "GtkSource", gir_version = "3.0", lower_case_cprefix = "gtk_")]
+namespace Gtk {
+       namespace SourceUtils {
+               [CCode (cheader_filename = "gtksourceview/gtksource.h")]
+               public static string escape_search_text (string text);
+               [CCode (cheader_filename = "gtksourceview/gtksource.h")]
+               public static string unescape_search_text (string text);
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_buffer_get_type ()")]
+       [GIR (name = "Buffer")]
+       public class SourceBuffer : Gtk.TextBuffer {
+               [CCode (has_construct_function = false)]
+               public SourceBuffer (Gtk.TextTagTable? table);
+               public bool backward_iter_to_source_mark (Gtk.TextIter iter, string? category);
+               public void begin_not_undoable_action ();
+               public void change_case (Gtk.SourceChangeCaseType case_type, Gtk.TextIter start, Gtk.TextIter 
end);
+               public unowned Gtk.SourceMark create_source_mark (string? name, string category, Gtk.TextIter 
where);
+               public void end_not_undoable_action ();
+               public void ensure_highlight (Gtk.TextIter start, Gtk.TextIter end);
+               public bool forward_iter_to_source_mark (Gtk.TextIter iter, string? category);
+               [CCode (array_length = false, array_null_terminated = true)]
+               public string[] get_context_classes_at_iter (Gtk.TextIter iter);
+               public bool get_highlight_matching_brackets ();
+               public bool get_highlight_syntax ();
+               public unowned Gtk.SourceLanguage get_language ();
+               public int get_max_undo_levels ();
+               public GLib.SList<weak Gtk.SourceMark> get_source_marks_at_iter (Gtk.TextIter iter, string? 
category);
+               public GLib.SList<weak Gtk.SourceMark> get_source_marks_at_line (int line, string? category);
+               public unowned Gtk.SourceStyleScheme get_style_scheme ();
+               public unowned Gtk.SourceUndoManager get_undo_manager ();
+               public bool iter_backward_to_context_class_toggle (ref Gtk.TextIter iter, string 
context_class);
+               public bool iter_forward_to_context_class_toggle (ref Gtk.TextIter iter, string 
context_class);
+               public bool iter_has_context_class (Gtk.TextIter iter, string context_class);
+               public void remove_source_marks (Gtk.TextIter start, Gtk.TextIter end, string? category);
+               public void set_highlight_matching_brackets (bool highlight);
+               public void set_highlight_syntax (bool highlight);
+               public void set_language (Gtk.SourceLanguage? language);
+               public void set_max_undo_levels (int max_undo_levels);
+               public void set_style_scheme (Gtk.SourceStyleScheme? scheme);
+               public void set_undo_manager (Gtk.SourceUndoManager? manager);
+               [CCode (has_construct_function = false)]
+               public SourceBuffer.with_language (Gtk.SourceLanguage language);
+               [NoAccessorMethod]
+               public bool can_redo { get; }
+               [NoAccessorMethod]
+               public bool can_undo { get; }
+               public bool highlight_matching_brackets { get; set; }
+               public bool highlight_syntax { get; set; }
+               public Gtk.SourceLanguage language { get; set; }
+               public int max_undo_levels { get; set; }
+               public Gtk.SourceStyleScheme style_scheme { get; set; }
+               public Gtk.SourceUndoManager undo_manager { get; set construct; }
+               public virtual signal void bracket_matched (Gtk.TextIter iter, Gtk.SourceBracketMatchType 
state);
+               public signal void highlight_updated (Gtk.TextIter start, Gtk.TextIter end);
+               [HasEmitter]
+               public virtual signal void redo ();
+               public signal void source_mark_updated (Gtk.TextMark mark);
+               [HasEmitter]
+               public virtual signal void undo ();
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_completion_get_type 
()")]
+       [GIR (name = "Completion")]
+       public class SourceCompletion : GLib.Object {
+               [CCode (has_construct_function = false)]
+               protected SourceCompletion ();
+               public bool add_provider (Gtk.SourceCompletionProvider provider) throws GLib.Error;
+               public void block_interactive ();
+               public unowned Gtk.SourceCompletionContext create_context (Gtk.TextIter? position);
+               public unowned Gtk.SourceCompletionInfo get_info_window ();
+               public unowned GLib.List<Gtk.SourceCompletionProvider> get_providers ();
+               public unowned Gtk.SourceView get_view ();
+               [Deprecated (since = "3.8")]
+               public void move_window (Gtk.TextIter iter);
+               [NoWrapper]
+               public virtual bool proposal_activated (Gtk.SourceCompletionProvider provider, 
Gtk.SourceCompletionProposal proposal);
+               public bool remove_provider (Gtk.SourceCompletionProvider provider) throws GLib.Error;
+               [CCode (cname = "gtk_source_completion_show")]
+               public bool start (GLib.List<Gtk.SourceCompletionProvider>? providers, 
Gtk.SourceCompletionContext context);
+               public void unblock_interactive ();
+               [NoAccessorMethod]
+               public uint accelerators { get; set construct; }
+               [NoAccessorMethod]
+               public uint auto_complete_delay { get; set construct; }
+               [NoAccessorMethod]
+               public uint proposal_page_size { get; set construct; }
+               [NoAccessorMethod]
+               public uint provider_page_size { get; set construct; }
+               [NoAccessorMethod]
+               public bool remember_info_visibility { get; set construct; }
+               [NoAccessorMethod]
+               public bool select_on_show { get; set construct; }
+               [NoAccessorMethod]
+               public bool show_headers { get; set construct; }
+               [NoAccessorMethod]
+               public bool show_icons { get; set construct; }
+               public Gtk.SourceView view { get; construct; }
+               public virtual signal void activate_proposal ();
+               [HasEmitter]
+               public virtual signal void hide ();
+               public virtual signal void move_cursor (Gtk.ScrollStep step, int num);
+               public virtual signal void move_page (Gtk.ScrollStep step, int num);
+               public virtual signal void populate_context (Gtk.SourceCompletionContext context);
+               public virtual signal void show ();
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_completion_context_get_type ()")]
+       [GIR (name = "CompletionContext")]
+       public class SourceCompletionContext : GLib.InitiallyUnowned {
+               [CCode (has_construct_function = false)]
+               protected SourceCompletionContext ();
+               public void add_proposals (Gtk.SourceCompletionProvider provider, 
GLib.List<Gtk.SourceCompletionProposal>? proposals, bool finished);
+               public Gtk.SourceCompletionActivation get_activation ();
+               public Gtk.TextIter get_iter ();
+               [NoAccessorMethod]
+               public Gtk.SourceCompletionActivation activation { get; set; }
+               [NoAccessorMethod]
+               public Gtk.SourceCompletion completion { owned get; construct; }
+               [NoAccessorMethod]
+               public Gtk.TextIter iter { get; set; }
+               public virtual signal void cancelled ();
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_completion_info_get_type ()")]
+       [GIR (name = "CompletionInfo")]
+       public class SourceCompletionInfo : Gtk.Window, Atk.Implementor, Gtk.Buildable {
+               [CCode (has_construct_function = false)]
+               public SourceCompletionInfo ();
+               [Deprecated (since = "3.8")]
+               public unowned Gtk.Widget get_widget ();
+               public void move_to_iter (Gtk.TextView view, Gtk.TextIter? iter);
+               [Deprecated (since = "3.8")]
+               public void set_widget (Gtk.Widget? widget);
+               [Deprecated (since = "3.10")]
+               public virtual signal void before_show ();
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_completion_item_get_type ()")]
+       [GIR (name = "CompletionItem")]
+       public class SourceCompletionItem : GLib.Object, Gtk.SourceCompletionProposal {
+               [CCode (has_construct_function = false)]
+               public SourceCompletionItem (string label, string text, Gdk.Pixbuf? icon, string? info);
+               [CCode (has_construct_function = false)]
+               [Deprecated (since = "3.10")]
+               public SourceCompletionItem.from_stock (string? label, string text, string stock, string? 
info);
+               [CCode (has_construct_function = false)]
+               public SourceCompletionItem.with_markup (string markup, string text, Gdk.Pixbuf? icon, 
string? info);
+               [NoAccessorMethod]
+               public Gdk.Pixbuf icon { owned get; set; }
+               [NoAccessorMethod]
+               public string info { owned get; set; }
+               [NoAccessorMethod]
+               public string label { owned get; set; }
+               [NoAccessorMethod]
+               public string markup { owned get; set; }
+               [NoAccessorMethod]
+               public string text { owned get; set; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_completion_words_get_type ()")]
+       [GIR (name = "CompletionWords")]
+       public class SourceCompletionWords : GLib.Object, Gtk.SourceCompletionProvider {
+               [CCode (has_construct_function = false)]
+               public SourceCompletionWords (string? name, Gdk.Pixbuf? icon);
+               public void register (Gtk.TextBuffer buffer);
+               public void unregister (Gtk.TextBuffer buffer);
+               [NoAccessorMethod]
+               public Gtk.SourceCompletionActivation activation { get; set construct; }
+               [NoAccessorMethod]
+               public Gdk.Pixbuf icon { owned get; set construct; }
+               [NoAccessorMethod]
+               public int interactive_delay { get; set construct; }
+               [NoAccessorMethod]
+               public uint minimum_word_size { get; set construct; }
+               [NoAccessorMethod]
+               public string name { owned get; set construct; }
+               [NoAccessorMethod]
+               public int priority { get; set construct; }
+               [NoAccessorMethod]
+               public uint proposals_batch_size { get; set construct; }
+               [NoAccessorMethod]
+               public uint scan_batch_size { get; set construct; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_gutter_get_type ()")]
+       [GIR (name = "Gutter")]
+       public class SourceGutter : GLib.Object {
+               [CCode (has_construct_function = false)]
+               protected SourceGutter ();
+               [Deprecated (since = "3.12")]
+               public void get_padding (int xpad, int ypad);
+               public unowned Gtk.SourceGutterRenderer get_renderer_at_pos (int x, int y);
+               [Deprecated (since = "3.12")]
+               public unowned Gdk.Window get_window ();
+               public bool insert (Gtk.SourceGutterRenderer renderer, int position);
+               public void queue_draw ();
+               public void remove (Gtk.SourceGutterRenderer renderer);
+               public void reorder (Gtk.SourceGutterRenderer renderer, int position);
+               [Deprecated (since = "3.12")]
+               public void set_padding (int xpad, int ypad);
+               [NoAccessorMethod]
+               public Gtk.SourceView view { owned get; construct; }
+               [NoAccessorMethod]
+               public Gtk.TextWindowType window_type { get; construct; }
+               [Deprecated (since = "3.12")]
+               [NoAccessorMethod]
+               public int xpad { get; set construct; }
+               [Deprecated (since = "3.12")]
+               [NoAccessorMethod]
+               public int ypad { get; set construct; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_gutter_renderer_get_type ()")]
+       [GIR (name = "GutterRenderer")]
+       public abstract class SourceGutterRenderer : GLib.InitiallyUnowned {
+               [CCode (has_construct_function = false)]
+               protected SourceGutterRenderer ();
+               public virtual void begin (Cairo.Context cr, Gdk.Rectangle background_area, Gdk.Rectangle 
cell_area, Gtk.TextIter start, Gtk.TextIter end);
+               [NoWrapper]
+               public virtual void change_buffer (Gtk.TextBuffer old_buffer);
+               [NoWrapper]
+               public virtual void change_view (Gtk.TextView old_view);
+               public virtual void draw (Cairo.Context cr, Gdk.Rectangle background_area, Gdk.Rectangle 
cell_area, Gtk.TextIter start, Gtk.TextIter end, Gtk.SourceGutterRendererState state);
+               public virtual void end ();
+               public void get_alignment (out float xalign, out float yalign);
+               public Gtk.SourceGutterRendererAlignmentMode get_alignment_mode ();
+               public bool get_background (out Gdk.RGBA color);
+               public void get_padding (out int xpad, out int ypad);
+               public int get_size ();
+               public unowned Gtk.TextView get_view ();
+               public bool get_visible ();
+               public Gtk.TextWindowType get_window_type ();
+               public void set_alignment (float xalign, float yalign);
+               public void set_alignment_mode (Gtk.SourceGutterRendererAlignmentMode mode);
+               public void set_background (Gdk.RGBA? color);
+               public void set_padding (int xpad, int ypad);
+               public void set_size (int size);
+               public void set_visible (bool visible);
+               public Gtk.SourceGutterRendererAlignmentMode alignment_mode { get; set construct; }
+               [NoAccessorMethod]
+               public Gdk.RGBA background_rgba { get; set; }
+               [NoAccessorMethod]
+               public bool background_set { get; set construct; }
+               public int size { get; set construct; }
+               public Gtk.TextView view { get; }
+               public bool visible { get; set construct; }
+               public Gtk.TextWindowType window_type { get; }
+               [NoAccessorMethod]
+               public float xalign { get; set construct; }
+               [NoAccessorMethod]
+               public int xpad { get; set construct; }
+               [NoAccessorMethod]
+               public float yalign { get; set construct; }
+               [NoAccessorMethod]
+               public int ypad { get; set construct; }
+               [HasEmitter]
+               public virtual signal void activate (Gtk.TextIter iter, Cairo.RectangleInt area, Gdk.Event 
event);
+               [HasEmitter]
+               public virtual signal bool query_activatable (Gtk.TextIter iter, Cairo.RectangleInt area, 
Gdk.Event event);
+               [HasEmitter]
+               public virtual signal void query_data (Gtk.TextIter start, Gtk.TextIter end, 
Gtk.SourceGutterRendererState state);
+               [HasEmitter]
+               public virtual signal bool query_tooltip (Gtk.TextIter iter, Cairo.RectangleInt area, int x, 
int y, Gtk.Tooltip tooltip);
+               [HasEmitter]
+               public virtual signal void queue_draw ();
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_gutter_renderer_pixbuf_get_type ()")]
+       [GIR (name = "GutterRendererPixbuf")]
+       public class SourceGutterRendererPixbuf : Gtk.SourceGutterRenderer {
+               [CCode (has_construct_function = false, type = "GtkSourceGutterRenderer*")]
+               public SourceGutterRendererPixbuf ();
+               public unowned GLib.Icon get_gicon ();
+               public unowned string get_icon_name ();
+               public unowned Gdk.Pixbuf get_pixbuf ();
+               [Deprecated (since = "3.10")]
+               public unowned string get_stock_id ();
+               public void set_gicon (GLib.Icon? icon);
+               public void set_icon_name (string? icon_name);
+               public void set_pixbuf (Gdk.Pixbuf? pixbuf);
+               [Deprecated (since = "3.10")]
+               public void set_stock_id (string? stock_id);
+               public GLib.Icon gicon { get; set; }
+               public string icon_name { get; set; }
+               public Gdk.Pixbuf pixbuf { get; set; }
+               [Deprecated (since = "3.10")]
+               public string stock_id { get; set; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_gutter_renderer_text_get_type ()")]
+       [GIR (name = "GutterRendererText")]
+       public class SourceGutterRendererText : Gtk.SourceGutterRenderer {
+               [CCode (has_construct_function = false, type = "GtkSourceGutterRenderer*")]
+               public SourceGutterRendererText ();
+               public void measure (string text, int width, int height);
+               public void measure_markup (string markup, int width, int height);
+               public void set_markup (string markup, int length);
+               public void set_text (string text, int length);
+               [NoAccessorMethod]
+               public string markup { owned get; set construct; }
+               [NoAccessorMethod]
+               public string text { owned get; set construct; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_language_get_type ()")]
+       [GIR (name = "Language")]
+       public class SourceLanguage : GLib.Object {
+               [CCode (has_construct_function = false)]
+               protected SourceLanguage ();
+               [CCode (array_length = false, array_null_terminated = true)]
+               public string[] get_globs ();
+               public bool get_hidden ();
+               public unowned string get_id ();
+               public unowned string get_metadata (string name);
+               [CCode (array_length = false, array_null_terminated = true)]
+               public string[] get_mime_types ();
+               public unowned string get_name ();
+               public unowned string get_section ();
+               public unowned string get_style_fallback (string style_id);
+               [CCode (array_length = false, array_null_terminated = true)]
+               public string[] get_style_ids ();
+               public unowned string get_style_name (string style_id);
+               public bool hidden { get; }
+               public string id { get; }
+               public string name { get; }
+               public string section { get; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_language_manager_get_type ()")]
+       [GIR (name = "LanguageManager")]
+       public class SourceLanguageManager : GLib.Object {
+               [CCode (has_construct_function = false)]
+               public SourceLanguageManager ();
+               public static unowned Gtk.SourceLanguageManager get_default ();
+               public unowned Gtk.SourceLanguage get_language (string id);
+               [CCode (array_length = false, array_null_terminated = true)]
+               public unowned string[] get_language_ids ();
+               [CCode (array_length = false, array_null_terminated = true)]
+               public unowned string[] get_search_path ();
+               public unowned Gtk.SourceLanguage guess_language (string? filename, string? content_type);
+               public void set_search_path ([CCode (array_length = false, array_null_terminated = true)] 
string[]? dirs);
+               [CCode (array_length = false, array_null_terminated = true)]
+               public string[] language_ids { get; }
+               [CCode (array_length = false, array_null_terminated = true)]
+               public string[] search_path { get; set; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_mark_get_type ()")]
+       [GIR (name = "Mark")]
+       public class SourceMark : Gtk.TextMark {
+               [CCode (has_construct_function = false)]
+               public SourceMark (string name, string category);
+               public unowned string get_category ();
+               public unowned Gtk.SourceMark next (string? category);
+               public unowned Gtk.SourceMark prev (string category);
+               public string category { get; construct; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_mark_attributes_get_type ()")]
+       [GIR (name = "MarkAttributes")]
+       public class SourceMarkAttributes : GLib.Object {
+               [CCode (has_construct_function = false)]
+               public SourceMarkAttributes ();
+               public bool get_background (out Gdk.RGBA background);
+               public unowned GLib.Icon get_gicon ();
+               public unowned string get_icon_name ();
+               public unowned Gdk.Pixbuf get_pixbuf ();
+               [Deprecated (since = "3.10")]
+               public unowned string get_stock_id ();
+               public string get_tooltip_markup (Gtk.SourceMark mark);
+               public string get_tooltip_text (Gtk.SourceMark mark);
+               public unowned Gdk.Pixbuf render_icon (Gtk.Widget widget, int size);
+               public void set_background (Gdk.RGBA background);
+               public void set_gicon (GLib.Icon gicon);
+               public void set_icon_name (string icon_name);
+               public void set_pixbuf (Gdk.Pixbuf pixbuf);
+               [Deprecated (since = "3.10")]
+               public void set_stock_id (string stock_id);
+               [NoAccessorMethod]
+               public Gdk.RGBA background { get; set; }
+               public GLib.Icon gicon { get; set; }
+               public string icon_name { get; set; }
+               public Gdk.Pixbuf pixbuf { get; set; }
+               [Deprecated (since = "3.10")]
+               public string stock_id { get; set; }
+               public signal string query_tooltip_markup (Gtk.SourceMark mark);
+               public signal string query_tooltip_text (Gtk.SourceMark mark);
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_print_compositor_get_type ()")]
+       [GIR (name = "PrintCompositor")]
+       public class SourcePrintCompositor : GLib.Object {
+               [CCode (has_construct_function = false)]
+               public SourcePrintCompositor (Gtk.SourceBuffer buffer);
+               public void draw_page (Gtk.PrintContext context, int page_nr);
+               [CCode (has_construct_function = false)]
+               public SourcePrintCompositor.from_view (Gtk.SourceView view);
+               public string get_body_font_name ();
+               public double get_bottom_margin (Gtk.Unit unit);
+               public unowned Gtk.SourceBuffer get_buffer ();
+               public string get_footer_font_name ();
+               public string get_header_font_name ();
+               public bool get_highlight_syntax ();
+               public double get_left_margin (Gtk.Unit unit);
+               public string get_line_numbers_font_name ();
+               public int get_n_pages ();
+               public double get_pagination_progress ();
+               public bool get_print_footer ();
+               public bool get_print_header ();
+               public uint get_print_line_numbers ();
+               public double get_right_margin (Gtk.Unit unit);
+               public uint get_tab_width ();
+               public double get_top_margin (Gtk.Unit unit);
+               public Gtk.WrapMode get_wrap_mode ();
+               public bool paginate (Gtk.PrintContext context);
+               public void set_body_font_name (string font_name);
+               public void set_bottom_margin (double margin, Gtk.Unit unit);
+               public void set_footer_font_name (string? font_name);
+               public void set_footer_format (bool separator, string? left, string? center, string? right);
+               public void set_header_font_name (string? font_name);
+               public void set_header_format (bool separator, string? left, string? center, string? right);
+               public void set_highlight_syntax (bool highlight);
+               public void set_left_margin (double margin, Gtk.Unit unit);
+               public void set_line_numbers_font_name (string? font_name);
+               public void set_print_footer (bool print);
+               public void set_print_header (bool print);
+               public void set_print_line_numbers (uint interval);
+               public void set_right_margin (double margin, Gtk.Unit unit);
+               public void set_tab_width (uint width);
+               public void set_top_margin (double margin, Gtk.Unit unit);
+               public void set_wrap_mode (Gtk.WrapMode wrap_mode);
+               public string body_font_name { owned get; set; }
+               public Gtk.SourceBuffer buffer { get; construct; }
+               public string footer_font_name { owned get; set; }
+               public string header_font_name { owned get; set; }
+               public bool highlight_syntax { get; set; }
+               public string line_numbers_font_name { owned get; set; }
+               public int n_pages { get; }
+               public bool print_footer { get; set; }
+               public bool print_header { get; set; }
+               public uint print_line_numbers { get; set; }
+               public uint tab_width { get; set; }
+               public Gtk.WrapMode wrap_mode { get; set; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_search_context_get_type 
()")]
+       [GIR (name = "SearchContext")]
+       public class SourceSearchContext : GLib.Object {
+               [CCode (has_construct_function = false)]
+               public SourceSearchContext (Gtk.SourceBuffer buffer, Gtk.SourceSearchSettings? settings);
+               public bool backward (Gtk.TextIter iter, out Gtk.TextIter match_start, out Gtk.TextIter 
match_end);
+               public async bool backward_async (Gtk.TextIter iter, GLib.Cancellable? cancellable, out 
Gtk.TextIter match_start, out Gtk.TextIter match_end) throws GLib.Error;
+               public bool forward (Gtk.TextIter iter, out Gtk.TextIter match_start, out Gtk.TextIter 
match_end);
+               public async bool forward_async (Gtk.TextIter iter, GLib.Cancellable? cancellable, out 
Gtk.TextIter match_start, out Gtk.TextIter match_end) throws GLib.Error;
+               public unowned Gtk.SourceBuffer get_buffer ();
+               public bool get_highlight ();
+               public int get_occurrence_position (Gtk.TextIter match_start, Gtk.TextIter match_end);
+               public int get_occurrences_count ();
+               public GLib.Error? get_regex_error ();
+               public unowned Gtk.SourceSearchSettings get_settings ();
+               public bool replace (Gtk.TextIter match_start, Gtk.TextIter match_end, string replace, int 
replace_length) throws GLib.Error;
+               public uint replace_all (string replace, int replace_length) throws GLib.Error;
+               public void set_highlight (bool highlight);
+               public void set_settings (Gtk.SourceSearchSettings? settings);
+               public Gtk.SourceBuffer buffer { get; construct; }
+               public bool highlight { get; set construct; }
+               public int occurrences_count { get; }
+               public GLib.Error? regex_error { owned get; }
+               public Gtk.SourceSearchSettings settings { get; set construct; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_search_settings_get_type ()")]
+       [GIR (name = "SearchSettings")]
+       public class SourceSearchSettings : GLib.Object {
+               [CCode (has_construct_function = false)]
+               public SourceSearchSettings ();
+               public bool get_at_word_boundaries ();
+               public bool get_case_sensitive ();
+               public bool get_regex_enabled ();
+               public unowned string get_search_text ();
+               public bool get_wrap_around ();
+               public void set_at_word_boundaries (bool at_word_boundaries);
+               public void set_case_sensitive (bool case_sensitive);
+               public void set_regex_enabled (bool regex_enabled);
+               public void set_search_text (string? search_text);
+               public void set_wrap_around (bool wrap_around);
+               public bool at_word_boundaries { get; set construct; }
+               public bool case_sensitive { get; set construct; }
+               public bool regex_enabled { get; set construct; }
+               public string search_text { get; set construct; }
+               public bool wrap_around { get; set construct; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_style_get_type ()")]
+       [GIR (name = "Style")]
+       public class SourceStyle : GLib.Object {
+               [CCode (has_construct_function = false)]
+               protected SourceStyle ();
+               public Gtk.SourceStyle copy ();
+               [NoAccessorMethod]
+               public string background { owned get; construct; }
+               [NoAccessorMethod]
+               public bool background_set { get; construct; }
+               [NoAccessorMethod]
+               public bool bold { get; construct; }
+               [NoAccessorMethod]
+               public bool bold_set { get; construct; }
+               [NoAccessorMethod]
+               public string foreground { owned get; construct; }
+               [NoAccessorMethod]
+               public bool foreground_set { get; construct; }
+               [NoAccessorMethod]
+               public bool italic { get; construct; }
+               [NoAccessorMethod]
+               public bool italic_set { get; construct; }
+               [NoAccessorMethod]
+               public string line_background { owned get; construct; }
+               [NoAccessorMethod]
+               public bool line_background_set { get; construct; }
+               [NoAccessorMethod]
+               public string scale { owned get; construct; }
+               [NoAccessorMethod]
+               public bool scale_set { get; construct; }
+               [NoAccessorMethod]
+               public bool strikethrough { get; construct; }
+               [NoAccessorMethod]
+               public bool strikethrough_set { get; construct; }
+               [NoAccessorMethod]
+               public bool underline { get; construct; }
+               [NoAccessorMethod]
+               public bool underline_set { get; construct; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_style_scheme_get_type 
()")]
+       [GIR (name = "StyleScheme")]
+       public class SourceStyleScheme : GLib.Object {
+               [CCode (has_construct_function = false)]
+               protected SourceStyleScheme ();
+               [CCode (array_length = false, array_null_terminated = true)]
+               public unowned string[] get_authors ();
+               public unowned string get_description ();
+               public unowned string get_filename ();
+               public unowned string get_id ();
+               public unowned string get_name ();
+               public unowned Gtk.SourceStyle get_style (string style_id);
+               public string description { get; }
+               public string filename { get; }
+               public string id { get; construct; }
+               public string name { get; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_style_scheme_manager_get_type ()")]
+       [GIR (name = "StyleSchemeManager")]
+       public class SourceStyleSchemeManager : GLib.Object {
+               [CCode (has_construct_function = false)]
+               public SourceStyleSchemeManager ();
+               public void append_search_path (string path);
+               public void force_rescan ();
+               public static unowned Gtk.SourceStyleSchemeManager get_default ();
+               public unowned Gtk.SourceStyleScheme get_scheme (string scheme_id);
+               [CCode (array_length = false, array_null_terminated = true)]
+               public unowned string[] get_scheme_ids ();
+               [CCode (array_length = false, array_null_terminated = true)]
+               public unowned string[] get_search_path ();
+               public void prepend_search_path (string path);
+               public void set_search_path ([CCode (array_length = false, array_null_terminated = true)] 
string[]? path);
+               [CCode (array_length = false, array_null_terminated = true)]
+               public string[] scheme_ids { get; }
+               [CCode (array_length = false, array_null_terminated = true)]
+               public string[] search_path { get; set; }
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_view_get_type ()")]
+       [GIR (name = "View")]
+       public class SourceView : Gtk.TextView, Atk.Implementor, Gtk.Buildable, Gtk.Scrollable {
+               [CCode (has_construct_function = false, type = "GtkWidget*")]
+               public SourceView ();
+               public bool get_auto_indent ();
+               public unowned Gtk.SourceCompletion get_completion ();
+               public Gtk.SourceDrawSpacesFlags get_draw_spaces ();
+               public unowned Gtk.SourceGutter get_gutter (Gtk.TextWindowType window_type);
+               public bool get_highlight_current_line ();
+               public bool get_indent_on_tab ();
+               public int get_indent_width ();
+               public bool get_insert_spaces_instead_of_tabs ();
+               public unowned Gtk.SourceMarkAttributes get_mark_attributes (string category, int priority);
+               public uint get_right_margin_position ();
+               public bool get_show_line_marks ();
+               public bool get_show_line_numbers ();
+               public bool get_show_right_margin ();
+               public Gtk.SourceSmartHomeEndType get_smart_home_end ();
+               public uint get_tab_width ();
+               public uint get_visual_column (Gtk.TextIter iter);
+               public void set_auto_indent (bool enable);
+               public void set_draw_spaces (Gtk.SourceDrawSpacesFlags flags);
+               public void set_highlight_current_line (bool hl);
+               public void set_indent_on_tab (bool enable);
+               public void set_indent_width (int width);
+               public void set_insert_spaces_instead_of_tabs (bool enable);
+               public void set_mark_attributes (string category, Gtk.SourceMarkAttributes attributes, int 
priority);
+               public void set_right_margin_position (uint pos);
+               public void set_show_line_marks (bool show);
+               public void set_show_line_numbers (bool show);
+               public void set_show_right_margin (bool show);
+               public void set_smart_home_end (Gtk.SourceSmartHomeEndType smart_he);
+               public void set_tab_width (uint width);
+               [CCode (has_construct_function = false, type = "GtkWidget*")]
+               public SourceView.with_buffer (Gtk.SourceBuffer buffer);
+               public bool auto_indent { get; set; }
+               public Gtk.SourceCompletion completion { get; }
+               public Gtk.SourceDrawSpacesFlags draw_spaces { get; set; }
+               public bool highlight_current_line { get; set; }
+               public bool indent_on_tab { get; set; }
+               public int indent_width { get; set; }
+               public bool insert_spaces_instead_of_tabs { get; set; }
+               public uint right_margin_position { get; set; }
+               public bool show_line_marks { get; set; }
+               public bool show_line_numbers { get; set; }
+               public bool show_right_margin { get; set; }
+               public Gtk.SourceSmartHomeEndType smart_home_end { get; set; }
+               public uint tab_width { get; set; }
+               public virtual signal void line_mark_activated (Gtk.TextIter iter, Gdk.Event event);
+               public virtual signal void move_lines (bool copy, int step);
+               public virtual signal void move_words (int step);
+               public virtual signal void redo ();
+               public virtual signal void show_completion ();
+               public virtual signal void undo ();
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_completion_proposal_get_type ()")]
+       [GIR (name = "CompletionProposal")]
+       public interface SourceCompletionProposal : GLib.Object {
+               public virtual bool equal (Gtk.SourceCompletionProposal other);
+               public virtual unowned Gdk.Pixbuf get_icon ();
+               public abstract string get_info ();
+               public abstract string get_label ();
+               public abstract string get_markup ();
+               public abstract string get_text ();
+               public virtual uint hash ();
+               [HasEmitter]
+               public virtual signal void changed ();
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = 
"gtk_source_completion_provider_get_type ()")]
+       [GIR (name = "CompletionProvider")]
+       public interface SourceCompletionProvider : GLib.Object {
+               public virtual bool activate_proposal (Gtk.SourceCompletionProposal proposal, Gtk.TextIter 
iter);
+               public virtual Gtk.SourceCompletionActivation get_activation ();
+               public virtual unowned Gdk.Pixbuf? get_icon ();
+               public virtual unowned Gtk.Widget? get_info_widget (Gtk.SourceCompletionProposal proposal);
+               public virtual int get_interactive_delay ();
+               public virtual string get_name ();
+               public virtual int get_priority ();
+               public virtual bool get_start_iter (Gtk.SourceCompletionContext context, 
Gtk.SourceCompletionProposal proposal, Gtk.TextIter iter);
+               public virtual bool match (Gtk.SourceCompletionContext context);
+               public virtual void populate (Gtk.SourceCompletionContext context);
+               public virtual void update_info (Gtk.SourceCompletionProposal proposal, 
Gtk.SourceCompletionInfo info);
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", type_id = "gtk_source_undo_manager_get_type 
()")]
+       [GIR (name = "UndoManager")]
+       public interface SourceUndoManager : GLib.Object {
+               public abstract void begin_not_undoable_action ();
+               public abstract bool can_redo ();
+               public abstract bool can_undo ();
+               public abstract void end_not_undoable_action ();
+               public abstract void redo ();
+               public abstract void undo ();
+               [HasEmitter]
+               public virtual signal void can_redo_changed ();
+               [HasEmitter]
+               public virtual signal void can_undo_changed ();
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", cprefix = "GTK_SOURCE_BRACKET_MATCH_", 
type_id = "gtk_source_bracket_match_type_get_type ()")]
+       [GIR (name = "BracketMatchType")]
+       public enum SourceBracketMatchType {
+               NONE,
+               OUT_OF_RANGE,
+               NOT_FOUND,
+               FOUND
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", cprefix = "GTK_SOURCE_CHANGE_CASE_", type_id 
= "gtk_source_change_case_type_get_type ()")]
+       [GIR (name = "ChangeCaseType")]
+       public enum SourceChangeCaseType {
+               LOWER,
+               UPPER,
+               TOGGLE,
+               TITLE
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", cprefix = 
"GTK_SOURCE_COMPLETION_ACTIVATION_", type_id = "gtk_source_completion_activation_get_type ()")]
+       [Flags]
+       [GIR (name = "CompletionActivation")]
+       public enum SourceCompletionActivation {
+               NONE,
+               INTERACTIVE,
+               USER_REQUESTED
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", cprefix = "GTK_SOURCE_DRAW_SPACES_", type_id 
= "gtk_source_draw_spaces_flags_get_type ()")]
+       [Flags]
+       [GIR (name = "DrawSpacesFlags")]
+       public enum SourceDrawSpacesFlags {
+               SPACE,
+               TAB,
+               NEWLINE,
+               NBSP,
+               LEADING,
+               TEXT,
+               TRAILING,
+               ALL
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", cprefix = 
"GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_", type_id = "gtk_source_gutter_renderer_alignment_mode_get_type 
()")]
+       [GIR (name = "GutterRendererAlignmentMode")]
+       public enum SourceGutterRendererAlignmentMode {
+               CELL,
+               FIRST,
+               LAST
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", cprefix = 
"GTK_SOURCE_GUTTER_RENDERER_STATE_", type_id = "gtk_source_gutter_renderer_state_get_type ()")]
+       [Flags]
+       [GIR (name = "GutterRendererState")]
+       public enum SourceGutterRendererState {
+               NORMAL,
+               CURSOR,
+               PRELIT,
+               SELECTED
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", cprefix = "GTK_SOURCE_SMART_HOME_END_", 
type_id = "gtk_source_smart_home_end_type_get_type ()")]
+       [GIR (name = "SmartHomeEndType")]
+       public enum SourceSmartHomeEndType {
+               DISABLED,
+               BEFORE,
+               AFTER,
+               ALWAYS
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", cprefix = "GTK_SOURCE_VIEW_GUTTER_POSITION_", 
type_id = "gtk_source_view_gutter_position_get_type ()")]
+       [GIR (name = "ViewGutterPosition")]
+       public enum SourceViewGutterPosition {
+               LINES,
+               MARKS
+       }
+       [CCode (cheader_filename = "gtksourceview/gtksource.h", cprefix = "GTK_SOURCE_COMPLETION_ERROR_")]
+       [GIR (name = "CompletionError")]
+       public errordomain SourceCompletionError {
+               ALREADY_BOUND,
+               NOT_BOUND;
+               [CCode (cname = "gtk_source_completion_error_quark")]
+               public static GLib.Quark uark ();
+       }
+}


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