[gedit/wip/snipfix: 1/3] [snippets] Cleanup imports, unused variables



commit 337c3d2e54d873f3868e3fe7e4dd696549183aa3
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Sat Apr 12 13:14:16 2014 +0200

    [snippets] Cleanup imports, unused variables

 plugins/snippets/snippets/__init__.py           |    2 +-
 plugins/snippets/snippets/appactivatable.py     |  106 +-
 plugins/snippets/snippets/completion.py         |  228 ++--
 plugins/snippets/snippets/document.py           | 1569 ++++++++++-----------
 plugins/snippets/snippets/exporter.py           |  132 +-
 plugins/snippets/snippets/helper.py             |  247 ++--
 plugins/snippets/snippets/importer.py           |  144 +-
 plugins/snippets/snippets/languagemanager.py    |   18 +-
 plugins/snippets/snippets/library.py            | 1477 ++++++++++----------
 plugins/snippets/snippets/manager.py            | 1728 +++++++++++------------
 plugins/snippets/snippets/parser.py             |  335 +++---
 plugins/snippets/snippets/placeholder.py        | 1000 +++++++-------
 plugins/snippets/snippets/shareddata.py         |    3 +
 plugins/snippets/snippets/snippet.py            |  619 ++++----
 plugins/snippets/snippets/substitutionparser.py |  250 ++--
 plugins/snippets/snippets/windowactivatable.py  |  218 ++--
 16 files changed, 4023 insertions(+), 4053 deletions(-)
---
diff --git a/plugins/snippets/snippets/__init__.py b/plugins/snippets/snippets/__init__.py
index 305d4c8..c161df8 100644
--- a/plugins/snippets/snippets/__init__.py
+++ b/plugins/snippets/snippets/__init__.py
@@ -19,4 +19,4 @@ from .appactivatable import AppActivatable
 from .windowactivatable import WindowActivatable
 from .document import Document
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/appactivatable.py b/plugins/snippets/snippets/appactivatable.py
index 5542211..aae3686 100644
--- a/plugins/snippets/snippets/appactivatable.py
+++ b/plugins/snippets/snippets/appactivatable.py
@@ -15,39 +15,35 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-import sys
 import os
-import shutil
-import gettext
 
 from gi.repository import Gedit, Gtk, Gdk, GObject, Gio, GLib
 import platform
 
 from .library import Library
-from .manager import Manager
 from .shareddata import SharedData
 
 class AppActivatable(GObject.Object, Gedit.AppActivatable):
-        __gtype_name__ = "GeditSnippetsAppActivatable"
+    __gtype_name__ = "GeditSnippetsAppActivatable"
 
-        app = GObject.property(type=Gedit.App)
+    app = GObject.property(type=Gedit.App)
 
-        def __init__(self):
-                GObject.Object.__init__(self)
+    def __init__(self):
+        GObject.Object.__init__(self)
 
-        def do_activate(self):
-                # Initialize snippets library
-                library = Library()
+    def do_activate(self):
+        # Initialize snippets library
+        library = Library()
 
-                if platform.system() == 'Windows':
-                        snippetsdir = os.path.expanduser('~/gedit/snippets')
-                else:
-                        snippetsdir = os.path.join(GLib.get_user_config_dir(), 'gedit/snippets')
+        if platform.system() == 'Windows':
+            snippetsdir = os.path.expanduser('~/gedit/snippets')
+        else:
+            snippetsdir = os.path.join(GLib.get_user_config_dir(), 'gedit/snippets')
 
-                library.set_dirs(snippetsdir, self.system_dirs())
+        library.set_dirs(snippetsdir, self.system_dirs())
 
-                self.css = Gtk.CssProvider()
-                self.css.load_from_data("""
+        self.css = Gtk.CssProvider()
+        self.css.load_from_data("""
 .gedit-snippet-manager-paned {
   border-style: solid;
   border-color: @borders;
@@ -76,55 +72,55 @@ class AppActivatable(GObject.Object, Gedit.AppActivatable):
   border-right-width: 0;
 }
 """.encode('utf-8'))
-                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
-                                                         self.css, 600)
+        Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+                             self.css, 600)
 
-                action = Gio.SimpleAction(name="snippets")
-                action.connect('activate', self.on_action_snippets_activate)
-                self.app.add_action(action)
+        action = Gio.SimpleAction(name="snippets")
+        action.connect('activate', self.on_action_snippets_activate)
+        self.app.add_action(action)
 
-                item = Gio.MenuItem.new(_("Manage _Snippets..."), "app.snippets")
-                self.menu = self.extend_menu("preferences-section")
-                self.menu.append_menu_item(item)
+        item = Gio.MenuItem.new(_("Manage _Snippets..."), "app.snippets")
+        self.menu = self.extend_menu("preferences-section")
+        self.menu.append_menu_item(item)
 
-        def do_deactivate(self):
-                self.app.remove_action("snippets")
-                self.menu = None
-                Gtk.StyleContext.remove_provider_for_screen(Gdk.Screen.get_default(),
-                                                            self.css)
+    def do_deactivate(self):
+        self.app.remove_action("snippets")
+        self.menu = None
+        Gtk.StyleContext.remove_provider_for_screen(Gdk.Screen.get_default(),
+                                self.css)
 
-        def system_dirs(self):
-                if platform.system() != 'Windows':
-                        if 'XDG_DATA_DIRS' in os.environ:
-                                datadirs = os.environ['XDG_DATA_DIRS']
-                        else:
-                                datadirs = '/usr/local/share' + os.pathsep + '/usr/share'
+    def system_dirs(self):
+        if platform.system() != 'Windows':
+            if 'XDG_DATA_DIRS' in os.environ:
+                datadirs = os.environ['XDG_DATA_DIRS']
+            else:
+                datadirs = '/usr/local/share' + os.pathsep + '/usr/share'
 
-                        dirs = []
+            dirs = []
 
-                        for d in datadirs.split(os.pathsep):
-                                d = os.path.join(d, 'gedit', 'plugins', 'snippets')
+            for d in datadirs.split(os.pathsep):
+                d = os.path.join(d, 'gedit', 'plugins', 'snippets')
 
-                                if os.path.isdir(d):
-                                        dirs.append(d)
+                if os.path.isdir(d):
+                    dirs.append(d)
 
-                dirs.append(self.plugin_info.get_data_dir())
-                return dirs
+        dirs.append(self.plugin_info.get_data_dir())
+        return dirs
 
-        def accelerator_activated(self, group, obj, keyval, mod):
-                activatable = SharedData().lookup_window_activatable(obj)
+    def accelerator_activated(self, group, obj, keyval, mod):
+        activatable = SharedData().lookup_window_activatable(obj)
 
-                ret = False
+        ret = False
 
-                if activatable:
-                        ret = activatable.accelerator_activated(keyval, mod)
+        if activatable:
+            ret = activatable.accelerator_activated(keyval, mod)
 
-                return ret
+        return ret
 
-        def create_configure_dialog(self):
-                SharedData().show_manager(self.app.get_active_window(), self.plugin_info.get_data_dir())
+    def create_configure_dialog(self):
+        SharedData().show_manager(self.app.get_active_window(), self.plugin_info.get_data_dir())
 
-        def on_action_snippets_activate(self, action, parameter):
-                self.create_configure_dialog()
+    def on_action_snippets_activate(self, action, parameter):
+        self.create_configure_dialog()
 
-# vi:ex:ts=8:et
+# vi:ex:ts=4:et
diff --git a/plugins/snippets/snippets/completion.py b/plugins/snippets/snippets/completion.py
index d48a6a8..55d3a65 100644
--- a/plugins/snippets/snippets/completion.py
+++ b/plugins/snippets/snippets/completion.py
@@ -22,166 +22,166 @@ from .languagemanager import get_language_manager
 from .snippet import Snippet
 
 class Proposal(GObject.Object, GtkSource.CompletionProposal):
-        __gtype_name__ = "GeditSnippetsProposal"
+    __gtype_name__ = "GeditSnippetsProposal"
 
-        def __init__(self, snippet):
-                GObject.Object.__init__(self)
-                self._snippet = Snippet(snippet)
+    def __init__(self, snippet):
+        GObject.Object.__init__(self)
+        self._snippet = Snippet(snippet)
 
-        def snippet(self):
-                return self._snippet.data
+    def snippet(self):
+        return self._snippet.data
 
-        # Interface implementation
-        def do_get_markup(self):
-                return self._snippet.display()
+    # Interface implementation
+    def do_get_markup(self):
+        return self._snippet.display()
 
-        def do_get_info(self):
-                return self._snippet.data['text']
+    def do_get_info(self):
+        return self._snippet.data['text']
 
 class Provider(GObject.Object, GtkSource.CompletionProvider):
-        __gtype_name__ = "GeditSnippetsProvider"
+    __gtype_name__ = "GeditSnippetsProvider"
 
-        def __init__(self, name, language_id, handler):
-                GObject.Object.__init__(self)
+    def __init__(self, name, language_id, handler):
+        GObject.Object.__init__(self)
 
-                self.name = name
-                self.info_widget = None
-                self.proposals = []
-                self.language_id = language_id
-                self.handler = handler
-                self.info_widget = None
-                self.mark = None
+        self.name = name
+        self.info_widget = None
+        self.proposals = []
+        self.language_id = language_id
+        self.handler = handler
+        self.info_widget = None
+        self.mark = None
 
-                theme = Gtk.IconTheme.get_default()
-                f, w, h = Gtk.icon_size_lookup(Gtk.IconSize.MENU)
+        theme = Gtk.IconTheme.get_default()
+        f, w, h = Gtk.icon_size_lookup(Gtk.IconSize.MENU)
 
-                try:
-                        self.icon = theme.load_icon(Gtk.STOCK_JUSTIFY_LEFT, w, 0)
-                except:
-                        self.icon = None
+        try:
+            self.icon = theme.load_icon(Gtk.STOCK_JUSTIFY_LEFT, w, 0)
+        except:
+            self.icon = None
 
-        def __del__(self):
-                if self.mark:
-                        self.mark.get_buffer().delete_mark(self.mark)
+    def __del__(self):
+        if self.mark:
+            self.mark.get_buffer().delete_mark(self.mark)
 
-        def set_proposals(self, proposals):
-                self.proposals = proposals
+    def set_proposals(self, proposals):
+        self.proposals = proposals
 
-        def mark_position(self, it):
-                if not self.mark:
-                        self.mark = it.get_buffer().create_mark(None, it, True)
-                else:
-                        self.mark.get_buffer().move_mark(self.mark, it)
+    def mark_position(self, it):
+        if not self.mark:
+            self.mark = it.get_buffer().create_mark(None, it, True)
+        else:
+            self.mark.get_buffer().move_mark(self.mark, it)
 
-        def get_word(self, context):
-                it = context.get_iter()
+    def get_word(self, context):
+        it = context.get_iter()
 
-                if it.starts_word() or it.starts_line() or not it.ends_word():
-                        return None
+        if it.starts_word() or it.starts_line() or not it.ends_word():
+            return None
 
-                start = it.copy()
+        start = it.copy()
 
-                if start.backward_word_start():
-                        self.mark_position(start)
-                        return start.get_text(it)
-                else:
-                        return None
+        if start.backward_word_start():
+            self.mark_position(start)
+            return start.get_text(it)
+        else:
+            return None
 
-        def do_get_start_iter(self, context, proposal, iter):
-                if not self.mark or self.mark.get_deleted():
-                        return False
+    def do_get_start_iter(self, context, proposal, iter):
+        if not self.mark or self.mark.get_deleted():
+            return False
 
-                iter.assign(self.mark.get_buffer().get_iter_at_mark(self.mark))
+        iter.assign(self.mark.get_buffer().get_iter_at_mark(self.mark))
 
-                return True
+        return True
 
-        def do_match(self, context):
-                return True
+    def do_match(self, context):
+        return True
 
-        def get_proposals(self, word):
-                if self.proposals:
-                        proposals = self.proposals
-                else:
-                        proposals = Library().get_snippets(None)
+    def get_proposals(self, word):
+        if self.proposals:
+            proposals = self.proposals
+        else:
+            proposals = Library().get_snippets(None)
 
-                        if self.language_id:
-                                proposals += Library().get_snippets(self.language_id)
+            if self.language_id:
+                proposals += Library().get_snippets(self.language_id)
 
-                # Filter based on the current word
-                if word:
-                        proposals = (x for x in proposals if x['tag'].startswith(word))
+        # Filter based on the current word
+        if word:
+            proposals = (x for x in proposals if x['tag'].startswith(word))
 
-                return [Proposal(x) for x in proposals]
+        return [Proposal(x) for x in proposals]
 
-        def do_populate(self, context):
-                proposals = self.get_proposals(self.get_word(context))
-                context.add_proposals(self, proposals, True)
+    def do_populate(self, context):
+        proposals = self.get_proposals(self.get_word(context))
+        context.add_proposals(self, proposals, True)
 
-        def do_get_name(self):
-                return self.name
+    def do_get_name(self):
+        return self.name
 
-        def do_activate_proposal(self, proposal, piter):
-                return self.handler(proposal, piter)
+    def do_activate_proposal(self, proposal, piter):
+        return self.handler(proposal, piter)
 
-        def do_get_info_widget(self, proposal):
-                if not self.info_widget:
-                        view = Gedit.View.new_with_buffer(Gedit.Document())
-                        manager = get_language_manager()
+    def do_get_info_widget(self, proposal):
+        if not self.info_widget:
+            view = Gedit.View.new_with_buffer(Gedit.Document())
+            manager = get_language_manager()
 
-                        lang = manager.get_language('snippets')
-                        view.get_buffer().set_language(lang)
+            lang = manager.get_language('snippets')
+            view.get_buffer().set_language(lang)
 
-                        sw = Gtk.ScrolledWindow()
-                        sw.add(view)
-                        sw.show_all()
+            sw = Gtk.ScrolledWindow()
+            sw.add(view)
+            sw.show_all()
 
-                        # Fixed size
-                        sw.set_size_request(300, 200)
+            # Fixed size
+            sw.set_size_request(300, 200)
 
-                        self.info_view = view
-                        self.info_widget = sw
+            self.info_view = view
+            self.info_widget = sw
 
-                return self.info_widget
+        return self.info_widget
 
-        def do_update_info(self, proposal, info):
-                buf = self.info_view.get_buffer()
+    def do_update_info(self, proposal, info):
+        buf = self.info_view.get_buffer()
 
-                buf.set_text(proposal.get_info())
-                buf.move_mark(buf.get_insert(), buf.get_start_iter())
-                buf.move_mark(buf.get_selection_bound(), buf.get_start_iter())
-                self.info_view.scroll_to_iter(buf.get_start_iter(), 0.0, False, 0.5, 0.5)
+        buf.set_text(proposal.get_info())
+        buf.move_mark(buf.get_insert(), buf.get_start_iter())
+        buf.move_mark(buf.get_selection_bound(), buf.get_start_iter())
+        self.info_view.scroll_to_iter(buf.get_start_iter(), 0.0, False, 0.5, 0.5)
 
-        def do_get_icon(self):
-                return self.icon
+    def do_get_icon(self):
+        return self.icon
 
-        def do_get_activation(self):
-                return GtkSource.CompletionActivation.USER_REQUESTED
+    def do_get_activation(self):
+        return GtkSource.CompletionActivation.USER_REQUESTED
 
 class Defaults(GObject.Object, GtkSource.CompletionProvider):
-        __gtype_name__ = "GeditSnippetsDefaultsProvider"
+    __gtype_name__ = "GeditSnippetsDefaultsProvider"
 
-        def __init__(self, handler):
-                GObject.Object.__init__(self)
+    def __init__(self, handler):
+        GObject.Object.__init__(self)
 
-                self.handler = handler
-                self.proposals = []
+        self.handler = handler
+        self.proposals = []
 
-        def set_defaults(self, defaults):
-                self.proposals = []
+    def set_defaults(self, defaults):
+        self.proposals = []
 
-                for d in defaults:
-                        self.proposals.append(GtkSource.CompletionItem.new(d, d, None, None))
+        for d in defaults:
+            self.proposals.append(GtkSource.CompletionItem.new(d, d, None, None))
 
-        def do_get_name(self):
-                return ""
+    def do_get_name(self):
+        return ""
 
-        def do_activate_proposal(self, proposal, piter):
-                return self.handler(proposal, piter)
+    def do_activate_proposal(self, proposal, piter):
+        return self.handler(proposal, piter)
 
-        def do_populate(self, context):
-                context.add_proposals(self, self.proposals, True)
+    def do_populate(self, context):
+        context.add_proposals(self, self.proposals, True)
 
-        def do_get_activation(self):
-                return GtkSource.CompletionActivation.NONE
+    def do_get_activation(self):
+        return GtkSource.CompletionActivation.NONE
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/document.py b/plugins/snippets/snippets/document.py
index 27c155c..ab41ecc 100644
--- a/plugins/snippets/snippets/document.py
+++ b/plugins/snippets/snippets/document.py
@@ -18,1067 +18,1062 @@
 import os
 import re
 
-from gi.repository import Gtk, Gdk, Gio, GLib, GtkSource, Gedit
+from gi.repository import Gtk, Gdk, Gio, GLib, Gedit, GObject
 
 from .library import Library
 from .snippet import Snippet
-from .placeholder import *
+from .placeholder import PlaceholderEnd
 from . import completion
 from .signals import Signals
 from .shareddata import SharedData
 from . import helper
 
 class DynamicSnippet(dict):
-        def __init__(self, text):
-                self['text'] = text
-                self.valid = True
+    def __init__(self, text):
+        self['text'] = text
+        self.valid = True
 
 class Document(GObject.Object, Gedit.ViewActivatable, Signals):
-        TAB_KEY_VAL = (Gdk.KEY_Tab, Gdk.KEY_ISO_Left_Tab)
-        SPACE_KEY_VAL = (Gdk.KEY_space,)
+    TAB_KEY_VAL = (Gdk.KEY_Tab, Gdk.KEY_ISO_Left_Tab)
+    SPACE_KEY_VAL = (Gdk.KEY_space,)
 
-        view = GObject.property(type=Gedit.View)
+    view = GObject.property(type=Gedit.View)
 
-        def __init__(self):
-                GObject.Object.__init__(self)
-                Signals.__init__(self)
+    def __init__(self):
+        GObject.Object.__init__(self)
+        Signals.__init__(self)
 
-                self.placeholders = []
-                self.active_snippets = []
-                self.active_placeholder = None
-
-                self.ordered_placeholders = []
-                self.update_placeholders = []
-                self.jump_placeholders = []
-                self.language_id = 0
-                self.timeout_update_id = 0
-
-                self.provider = completion.Provider(_('Snippets'), self.language_id, 
self.on_proposal_activated)
-                self.defaults_provider = completion.Defaults(self.on_default_activated)
-
-        def do_activate(self):
-                # Always have a reference to the global snippets
-                Library().ref(None)
-
-                buf = self.view.get_buffer()
+        self.placeholders = []
+        self.active_snippets = []
+        self.active_placeholder = None
 
-                self.connect_signal(self.view, 'key-press-event', self.on_view_key_press)
-                self.connect_signal(buf, 'notify::language', self.on_notify_language)
-                self.connect_signal(self.view, 'drag-data-received', self.on_drag_data_received)
+        self.ordered_placeholders = []
+        self.update_placeholders = []
+        self.jump_placeholders = []
+        self.language_id = 0
+        self.timeout_update_id = 0
 
-                self.connect_signal_after(self.view, 'draw', self.on_draw)
+        self.provider = completion.Provider(_('Snippets'), self.language_id, self.on_proposal_activated)
+        self.defaults_provider = completion.Defaults(self.on_default_activated)
 
-                self.update_language()
+    def do_activate(self):
+        # Always have a reference to the global snippets
+        Library().ref(None)
 
-                completion = self.view.get_completion()
+        buf = self.view.get_buffer()
 
-                completion.add_provider(self.provider)
-                completion.add_provider(self.defaults_provider)
+        self.connect_signal(self.view, 'key-press-event', self.on_view_key_press)
+        self.connect_signal(buf, 'notify::language', self.on_notify_language)
+        self.connect_signal(self.view, 'drag-data-received', self.on_drag_data_received)
 
-                self.connect_signal(completion, 'hide', self.on_completion_hide)
+        self.connect_signal_after(self.view, 'draw', self.on_draw)
 
-                SharedData().register_controller(self.view, self)
+        self.update_language()
 
-        def do_deactivate(self):
-                if self.timeout_update_id != 0:
-                        GLib.source_remove(self.timeout_update_id)
-                        self.timeout_update_id = 0
+        completion = self.view.get_completion()
 
-                        del self.update_placeholders[:]
-                        del self.jump_placeholders[:]
+        completion.add_provider(self.provider)
+        completion.add_provider(self.defaults_provider)
 
-                # Always release the reference to the global snippets
-                Library().unref(None)
-                self.active_placeholder = None
-
-                self.disconnect_signals(self.view)
-                self.disconnect_signals(self.view.get_buffer())
-
-                # Remove all active snippets
-                for snippet in list(self.active_snippets):
-                        self.deactivate_snippet(snippet, True)
+        self.connect_signal(completion, 'hide', self.on_completion_hide)
 
-                completion = self.view.get_completion()
+        SharedData().register_controller(self.view, self)
 
-                if completion:
-                        completion.remove_provider(self.provider)
-                        completion.remove_provider(self.defaults_provider)
+    def do_deactivate(self):
+        if self.timeout_update_id != 0:
+            GLib.source_remove(self.timeout_update_id)
+            self.timeout_update_id = 0
 
-                if self.language_id != 0:
-                        Library().unref(self.language_id)
+            del self.update_placeholders[:]
+            del self.jump_placeholders[:]
 
-                SharedData().unregister_controller(self.view, self)
+        # Always release the reference to the global snippets
+        Library().unref(None)
+        self.active_placeholder = None
 
-        # Call this whenever the language in the view changes. This makes sure that
-        # the correct language is used when finding snippets
-        def update_language(self):
-                lang = self.view.get_buffer().get_language()
+        self.disconnect_signals(self.view)
+        self.disconnect_signals(self.view.get_buffer())
 
-                if lang == None and self.language_id == None:
-                        return
-                elif lang and lang.get_id() == self.language_id:
-                        return
+        # Remove all active snippets
+        for snippet in list(self.active_snippets):
+            self.deactivate_snippet(snippet, True)
 
-                langid = self.language_id
-
-                if lang:
-                        self.language_id = lang.get_id()
-                else:
-                        self.language_id = None
+        completion = self.view.get_completion()
 
-                if langid != 0:
-                        Library().unref(langid)
+        if completion:
+            completion.remove_provider(self.provider)
+            completion.remove_provider(self.defaults_provider)
 
-                Library().ref(self.language_id)
-                self.provider.language_id = self.language_id
+        if self.language_id != 0:
+            Library().unref(self.language_id)
 
-                SharedData().update_state(self.view.get_toplevel())
+        SharedData().unregister_controller(self.view, self)
 
-        def accelerator_activate(self, keyval, mod):
-                if not self.view or not self.view.get_editable():
-                        return False
+    # Call this whenever the language in the view changes. This makes sure that
+    # the correct language is used when finding snippets
+    def update_language(self):
+        lang = self.view.get_buffer().get_language()
 
-                accelerator = Gtk.accelerator_name(keyval, mod)
-                snippets = Library().from_accelerator(accelerator, \
-                                self.language_id)
+        if lang == None and self.language_id == None:
+            return
+        elif lang and lang.get_id() == self.language_id:
+            return
 
-                if len(snippets) == 0:
-                        return False
-                elif len(snippets) == 1:
-                        self.apply_snippet(snippets[0])
-                else:
-                        # Do the fancy completion dialog
-                        self.provider.set_proposals(snippets)
-                        cm = self.view.get_completion()
-                        cm.show([self.provider], cm.create_context(None))
+        langid = self.language_id
 
-                return True
+        if lang:
+            self.language_id = lang.get_id()
+        else:
+            self.language_id = None
 
-        def first_snippet_inserted(self):
-                buf = self.view.get_buffer()
+        if langid != 0:
+            Library().unref(langid)
 
-                self.connect_signal(buf, 'changed', self.on_buffer_changed)
-                self.connect_signal(buf, 'cursor-moved', self.on_buffer_cursor_moved)
-                self.connect_signal_after(buf, 'insert-text', self.on_buffer_insert_text)
+        Library().ref(self.language_id)
+        self.provider.language_id = self.language_id
 
-        def last_snippet_removed(self):
-                buf = self.view.get_buffer()
-                self.disconnect_signal(buf, 'changed')
-                self.disconnect_signal(buf, 'cursor-moved')
-                self.disconnect_signal(buf, 'insert-text')
+        SharedData().update_state(self.view.get_toplevel())
 
-        def current_placeholder(self):
-                buf = self.view.get_buffer()
+    def accelerator_activate(self, keyval, mod):
+        if not self.view or not self.view.get_editable():
+            return False
 
-                piter = buf.get_iter_at_mark(buf.get_insert())
-                found = []
+        accelerator = Gtk.accelerator_name(keyval, mod)
+        snippets = Library().from_accelerator(accelerator, \
+                self.language_id)
 
-                for placeholder in self.placeholders:
-                        begin = placeholder.begin_iter()
-                        end = placeholder.end_iter()
+        if len(snippets) == 0:
+            return False
+        elif len(snippets) == 1:
+            self.apply_snippet(snippets[0])
+        else:
+            # Do the fancy completion dialog
+            self.provider.set_proposals(snippets)
+            cm = self.view.get_completion()
+            cm.show([self.provider], cm.create_context(None))
 
-                        if piter.compare(begin) >= 0 and piter.compare(end) <= 0:
-                                found.append(placeholder)
+        return True
 
-                if self.active_placeholder in found:
-                        return self.active_placeholder
-                elif len(found) > 0:
-                        return found[0]
-                else:
-                        return None
+    def first_snippet_inserted(self):
+        buf = self.view.get_buffer()
 
-        def advance_placeholder(self, direction):
-                # Returns (CurrentPlaceholder, NextPlaceholder), depending on direction
-                buf = self.view.get_buffer()
+        self.connect_signal(buf, 'changed', self.on_buffer_changed)
+        self.connect_signal(buf, 'cursor-moved', self.on_buffer_cursor_moved)
+        self.connect_signal_after(buf, 'insert-text', self.on_buffer_insert_text)
 
-                piter = buf.get_iter_at_mark(buf.get_insert())
-                found = current = next = None
-                length = len(self.placeholders)
+    def last_snippet_removed(self):
+        buf = self.view.get_buffer()
+        self.disconnect_signal(buf, 'changed')
+        self.disconnect_signal(buf, 'cursor-moved')
+        self.disconnect_signal(buf, 'insert-text')
 
-                placeholders = list(self.placeholders)
+    def current_placeholder(self):
+        buf = self.view.get_buffer()
 
-                if self.active_placeholder:
-                        begin = self.active_placeholder.begin_iter()
-                        end = self.active_placeholder.end_iter()
+        piter = buf.get_iter_at_mark(buf.get_insert())
+        found = []
+
+        for placeholder in self.placeholders:
+            begin = placeholder.begin_iter()
+            end = placeholder.end_iter()
+
+            if piter.compare(begin) >= 0 and piter.compare(end) <= 0:
+                found.append(placeholder)
+
+        if self.active_placeholder in found:
+            return self.active_placeholder
+        elif len(found) > 0:
+            return found[0]
+        else:
+            return None
+
+    def advance_placeholder(self, direction):
+        # Returns (CurrentPlaceholder, NextPlaceholder), depending on direction
+        buf = self.view.get_buffer()
+
+        piter = buf.get_iter_at_mark(buf.get_insert())
+        found = current = next = None
+        length = len(self.placeholders)
+
+        placeholders = list(self.placeholders)
+
+        if self.active_placeholder:
+            begin = self.active_placeholder.begin_iter()
+            end = self.active_placeholder.end_iter()
+
+            if piter.compare(begin) >= 0 and piter.compare(end) <= 0:
+                current = self.active_placeholder
+                currentIndex = placeholders.index(self.active_placeholder)
+
+        if direction == 1:
+            # w = piter, x = begin, y = end, z = found
+            nearest = lambda w, x, y, z: (w.compare(x) <= 0 and (not z or \
+                    x.compare(z.begin_iter()) < 0))
+            indexer = lambda x: x < length - 1
+        else:
+            # w = piter, x = begin, y = end, z = prev
+            nearest = lambda w, x, y, z: (w.compare(x) >= 0 and (not z or \
+                    x.compare(z.begin_iter()) >= 0))
+            indexer = lambda x: x > 0
+
+        for index in range(0, length):
+            placeholder = placeholders[index]
+            begin = placeholder.begin_iter()
+            end = placeholder.end_iter()
+
+            # Find the nearest placeholder
+            if nearest(piter, begin, end, found):
+                found = placeholder
+
+            # Find the current placeholder
+            if piter.compare(begin) >= 0 and \
+                    piter.compare(end) <= 0 and \
+                    current == None:
+                currentIndex = index
+                current = placeholder
+
+        if current and current != found and \
+           (current.begin_iter().compare(found.begin_iter()) == 0 or \
+            current.end_iter().compare(found.begin_iter()) == 0) and \
+           self.active_placeholder and \
+           current.begin_iter().compare(self.active_placeholder.begin_iter()) == 0:
+            # if current and found are at the same place, then
+            # resolve the 'hugging' problem
+            current = self.active_placeholder
+            currentIndex = placeholders.index(current)
 
-                        if piter.compare(begin) >= 0 and piter.compare(end) <= 0:
-                                current = self.active_placeholder
-                                currentIndex = placeholders.index(self.active_placeholder)
+        if current:
+            if indexer(currentIndex):
+                next = placeholders[currentIndex + direction]
+        elif found:
+            next = found
+        elif length > 0:
+            next = self.placeholders[0]
 
-                if direction == 1:
-                        # w = piter, x = begin, y = end, z = found
-                        nearest = lambda w, x, y, z: (w.compare(x) <= 0 and (not z or \
-                                        x.compare(z.begin_iter()) < 0))
-                        indexer = lambda x: x < length - 1
-                else:
-                        # w = piter, x = begin, y = end, z = prev
-                        nearest = lambda w, x, y, z: (w.compare(x) >= 0 and (not z or \
-                                        x.compare(z.begin_iter()) >= 0))
-                        indexer = lambda x: x > 0
-
-                for index in range(0, length):
-                        placeholder = placeholders[index]
-                        begin = placeholder.begin_iter()
-                        end = placeholder.end_iter()
-
-                        # Find the nearest placeholder
-                        if nearest(piter, begin, end, found):
-                                foundIndex = index
-                                found = placeholder
+        return current, next
 
-                        # Find the current placeholder
-                        if piter.compare(begin) >= 0 and \
-                                        piter.compare(end) <= 0 and \
-                                        current == None:
-                                currentIndex = index
-                                current = placeholder
+    def next_placeholder(self):
+        return self.advance_placeholder(1)
 
-                if current and current != found and \
-                   (current.begin_iter().compare(found.begin_iter()) == 0 or \
-                    current.end_iter().compare(found.begin_iter()) == 0) and \
-                   self.active_placeholder and \
-                   current.begin_iter().compare(self.active_placeholder.begin_iter()) == 0:
-                        # if current and found are at the same place, then
-                        # resolve the 'hugging' problem
-                        current = self.active_placeholder
-                        currentIndex = placeholders.index(current)
+    def previous_placeholder(self):
+        return self.advance_placeholder(-1)
 
-                if current:
-                        if indexer(currentIndex):
-                                next = placeholders[currentIndex + direction]
-                elif found:
-                        next = found
-                elif length > 0:
-                        next = self.placeholders[0]
+    def cursor_on_screen(self):
+        buf = self.view.get_buffer()
+        self.view.scroll_mark_onscreen(buf.get_insert())
 
-                return current, next
+    def set_active_placeholder(self, placeholder):
+        self.active_placeholder = placeholder
 
-        def next_placeholder(self):
-                return self.advance_placeholder(1)
+    def goto_placeholder(self, current, next):
+        last = None
 
-        def previous_placeholder(self):
-                return self.advance_placeholder(-1)
+        if current:
+            # Signal this placeholder to end action
+            self.view.get_completion().hide()
+            current.leave()
 
-        def cursor_on_screen(self):
-                buf = self.view.get_buffer()
-                self.view.scroll_mark_onscreen(buf.get_insert())
+            if current.__class__ == PlaceholderEnd:
+                last = current
 
-        def set_active_placeholder(self, placeholder):
-                self.active_placeholder = placeholder
+        self.set_active_placeholder(next)
 
-        def goto_placeholder(self, current, next):
-                last = None
+        if next:
+            next.enter()
 
-                if current:
-                        # Signal this placeholder to end action
-                        self.view.get_completion().hide()
-                        current.leave()
+            if next.__class__ == PlaceholderEnd:
+                last = next
+            elif len(next.defaults) > 1 and next.get_text() == next.default:
+                self.defaults_provider.set_defaults(next.defaults)
 
-                        if current.__class__ == PlaceholderEnd:
-                                last = current
+                cm = self.view.get_completion()
+                cm.show([self.defaults_provider], cm.create_context(None))
 
-                self.set_active_placeholder(next)
+        if last:
+            # This is the end of the placeholder, remove the snippet etc
+            for snippet in list(self.active_snippets):
+                if snippet.placeholders[0] == last:
+                    self.deactivate_snippet(snippet)
+                    break
 
-                if next:
-                        next.enter()
+        self.cursor_on_screen()
 
-                        if next.__class__ == PlaceholderEnd:
-                                last = next
-                        elif len(next.defaults) > 1 and next.get_text() == next.default:
-                                self.defaults_provider.set_defaults(next.defaults)
+        return next != None
 
-                                cm = self.view.get_completion()
-                                cm.show([self.defaults_provider], cm.create_context(None))
+    def skip_to_next_placeholder(self):
+        (current, next) = self.next_placeholder()
+        return self.goto_placeholder(current, next)
 
-                if last:
-                        # This is the end of the placeholder, remove the snippet etc
-                        for snippet in list(self.active_snippets):
-                                if snippet.placeholders[0] == last:
-                                        self.deactivate_snippet(snippet)
-                                        break
+    def skip_to_previous_placeholder(self):
+        (current, prev) = self.previous_placeholder()
+        return self.goto_placeholder(current, prev)
 
-                self.cursor_on_screen()
+    def string_in_native_doc_encoding(self, buf, s):
+        enc = buf.get_encoding()
 
-                return next != None
+        if not enc or enc.get_charset() == 'UTF-8':
+            return s
 
-        def skip_to_next_placeholder(self):
-                (current, next) = self.next_placeholder()
-                return self.goto_placeholder(current, next)
+        try:
+            cv = GLib.convert(s, -1, enc.get_charset(), 'UTF-8')
+            return cv[0]
+        except GLib.GError:
+            pass
 
-        def skip_to_previous_placeholder(self):
-                (current, prev) = self.previous_placeholder()
-                return self.goto_placeholder(current, prev)
+        return s
 
-        def string_in_native_doc_encoding(self, buf, s):
-                enc = buf.get_encoding()
+    def env_get_selected_text(self, buf):
+        bounds = buf.get_selection_bounds()
 
-                if not enc or enc.get_charset() == 'UTF-8':
-                        return s
+        if bounds:
+            u8 = buf.get_text(bounds[0], bounds[1], False)
 
-                try:
-                        cv = GLib.convert(s, -1, enc.get_charset(), 'UTF-8')
-                        return cv[0]
-                except GLib.GError:
-                        pass
+            return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)}
+        else:
+            return ''
 
-                return s
+    def env_get_current_word(self, buf):
+        start, end = helper.buffer_word_boundary(buf)
 
-        def env_get_selected_text(self, buf):
-                bounds = buf.get_selection_bounds()
+        u8 = buf.get_text(start, end, False)
 
-                if bounds:
-                        u8 = buf.get_text(bounds[0], bounds[1], False)
+        return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)}
 
-                        return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)}
-                else:
-                        return ''
+    def env_get_current_line(self, buf):
+        start, end = helper.buffer_line_boundary(buf)
 
-        def env_get_current_word(self, buf):
-                start, end = buffer_word_boundary(buf)
-                enc = buf.get_encoding()
+        u8 = buf.get_text(start, end, False)
 
-                u8 = buf.get_text(start, end, False)
+        return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)}
 
-                return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)}
+    def env_get_current_line_number(self, buf):
+        start, end = helper.buffer_line_boundary(buf)
 
-        def env_get_current_line(self, buf):
-                start, end = buffer_line_boundary(buf)
+        return str(start.get_line() + 1)
 
-                u8 = buf.get_text(start, end, False)
+    def location_uri_for_env(self, location):
+        if not location:
+            return {'utf8': '', 'noenc': ''}
 
-                return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)}
+        u8 = location.get_parse_name()
 
-        def env_get_current_line_number(self, buf):
-                start, end = buffer_line_boundary(buf)
+        if location.has_uri_scheme('file'):
+            u8 = "file://" + u8
 
-                return str(start.get_line() + 1)
+        return {'utf8': u8, 'noenc': location.get_uri()}
 
-        def location_uri_for_env(self, location):
-                if not location:
-                        return {'utf8': '', 'noenc': ''}
+    def location_name_for_env(self, location):
+        if location:
+            try:
+                info = location.query_info("standard::display-name", 0, None)
+                display_name = info.get_display_name()
+            except:
+                display_name = ''
 
-                u8 = location.get_parse_name()
+            return {'utf8': display_name,
+                'noenc': location.get_basename()}
+        else:
+            return ''
 
-                if location.has_uri_scheme('file'):
-                        u8 = "file://" + u8
+    def location_scheme_for_env(self, location):
+        if location:
+            return location.get_uri_scheme()
+        else:
+            return ''
 
-                return {'utf8': u8, 'noenc': location.get_uri()}
+    def location_path_for_env(self, location):
+        if location and location.has_uri_scheme('file'):
+            return {'utf8': location.get_parse_name(),
+                'noenc': location.get_path()}
+        else:
+            return ''
 
-        def location_name_for_env(self, location):
-                if location:
-                        try:
-                                info = location.query_info("standard::display-name", 0, None)
-                                display_name = info.get_display_name()
-                        except:
-                                display_name = ''
+    def location_dir_for_env(self, location):
+        if location:
+            parent = location.get_parent()
 
-                        return {'utf8': display_name,
-                                'noenc': location.get_basename()}
-                else:
-                        return ''
+            if parent and parent.has_uri_scheme('file'):
+                return {'utf8': parent.get_parse_name(),
+                    'noenc': parent.get_path()}
 
-        def location_scheme_for_env(self, location):
-                if location:
-                        return location.get_uri_scheme()
-                else:
-                        return ''
+        return ''
 
-        def location_path_for_env(self, location):
-                if location and location.has_uri_scheme('file'):
-                        return {'utf8': location.get_parse_name(),
-                                'noenc': location.get_path()}
-                else:
-                        return ''
+    def env_add_for_location(self, environ, location, prefix):
+        parts = {'URI': self.location_uri_for_env,
+             'NAME': self.location_name_for_env,
+             'SCHEME': self.location_scheme_for_env,
+             'PATH': self.location_path_for_env,
+             'DIR': self.location_dir_for_env}
 
-        def location_dir_for_env(self, location):
-                if location:
-                        parent = location.get_parent()
+        for k in parts:
+            v = parts[k](location)
+            key = prefix + '_' + k
 
-                        if parent and parent.has_uri_scheme('file'):
-                                return {'utf8': parent.get_parse_name(),
-                                        'noenc': parent.get_path()}
+            if isinstance(v, dict):
+                environ['utf8'][key] = v['utf8']
+                environ['noenc'][key] = v['noenc']
+            else:
+                environ['utf8'][key] = v
+                environ['noenc'][key] = str(v)
 
-                return ''
+        return environ
 
-        def env_add_for_location(self, environ, location, prefix):
-                parts = {'URI': self.location_uri_for_env,
-                         'NAME': self.location_name_for_env,
-                         'SCHEME': self.location_scheme_for_env,
-                         'PATH': self.location_path_for_env,
-                         'DIR': self.location_dir_for_env}
+    def env_get_document_type(self, buf):
+        typ = buf.get_mime_type()
 
-                for k in parts:
-                        v = parts[k](location)
-                        key = prefix + '_' + k
+        if typ:
+            return typ
+        else:
+            return ''
 
-                        if isinstance(v, dict):
-                                environ['utf8'][key] = v['utf8']
-                                environ['noenc'][key] = v['noenc']
-                        else:
-                                environ['utf8'][key] = v
-                                environ['noenc'][key] = str(v)
+    def env_get_documents_uri(self, buf):
+        toplevel = self.view.get_toplevel()
 
-                return environ
+        documents_uri = {'utf8': [], 'noenc': []}
 
-        def env_get_document_type(self, buf):
-                typ = buf.get_mime_type()
+        if isinstance(toplevel, Gedit.Window):
+            for doc in toplevel.get_documents():
+                r = self.location_uri_for_env(doc.get_location())
 
-                if typ:
-                        return typ
+                if isinstance(r, dict):
+                    documents_uri['utf8'].append(r['utf8'])
+                    documents_uri['noenc'].append(r['noenc'])
                 else:
-                        return ''
-
-        def env_get_documents_uri(self, buf):
-                toplevel = self.view.get_toplevel()
-
-                documents_uri = {'utf8': [], 'noenc': []}
+                    documents_uri['utf8'].append(r)
+                    documents_uri['noenc'].append(str(r))
 
-                if isinstance(toplevel, Gedit.Window):
-                        for doc in toplevel.get_documents():
-                                r = self.location_uri_for_env(doc.get_location())
+        return {'utf8': ' '.join(documents_uri['utf8']),
+            'noenc': ' '.join(documents_uri['noenc'])}
 
-                                if isinstance(r, dict):
-                                        documents_uri['utf8'].append(r['utf8'])
-                                        documents_uri['noenc'].append(r['noenc'])
-                                else:
-                                        documents_uri['utf8'].append(r)
-                                        documents_uri['noenc'].append(str(r))
+    def env_get_documents_path(self, buf):
+        toplevel = self.view.get_toplevel()
 
-                return {'utf8': ' '.join(documents_uri['utf8']),
-                        'noenc': ' '.join(documents_uri['noenc'])}
+        documents_path = {'utf8': [], 'noenc': []}
 
-        def env_get_documents_path(self, buf):
-                toplevel = self.view.get_toplevel()
+        if isinstance(toplevel, Gedit.Window):
+            for doc in toplevel.get_documents():
+                r = self.location_path_for_env(doc.get_location())
 
-                documents_path = {'utf8': [], 'noenc': []}
+                if isinstance(r, dict):
+                    documents_path['utf8'].append(r['utf8'])
+                    documents_path['noenc'].append(r['noenc'])
+                else:
+                    documents_path['utf8'].append(r)
+                    documents_path['noenc'].append(str(r))
 
-                if isinstance(toplevel, Gedit.Window):
-                        for doc in toplevel.get_documents():
-                                r = self.location_path_for_env(doc.get_location())
+        return {'utf8': ' '.join(documents_path['utf8']),
+            'noenc': ' '.join(documents_path['noenc'])}
 
-                                if isinstance(r, dict):
-                                        documents_path['utf8'].append(r['utf8'])
-                                        documents_path['noenc'].append(r['noenc'])
-                                else:
-                                        documents_path['utf8'].append(r)
-                                        documents_path['noenc'].append(str(r))
+    def get_environment(self):
+        buf = self.view.get_buffer()
+        environ = {'utf8': {}, 'noenc': {}}
 
-                return {'utf8': ' '.join(documents_path['utf8']),
-                        'noenc': ' '.join(documents_path['noenc'])}
+        for k in os.environ:
+            # Get the original environment, as utf-8
+            v = os.environ[k]
+            environ['noenc'][k] = v
+            environ['utf8'][k] = os.environ[k].encode('utf-8')
 
-        def get_environment(self):
-                buf = self.view.get_buffer()
-                environ = {'utf8': {}, 'noenc': {}}
+        variables = {'GEDIT_SELECTED_TEXT': self.env_get_selected_text,
+                 'GEDIT_CURRENT_WORD': self.env_get_current_word,
+                 'GEDIT_CURRENT_LINE': self.env_get_current_line,
+                 'GEDIT_CURRENT_LINE_NUMBER': self.env_get_current_line_number,
+                 'GEDIT_CURRENT_DOCUMENT_TYPE': self.env_get_document_type,
+                 'GEDIT_DOCUMENTS_URI': self.env_get_documents_uri,
+                 'GEDIT_DOCUMENTS_PATH': self.env_get_documents_path}
 
-                for k in os.environ:
-                        # Get the original environment, as utf-8
-                        v = os.environ[k]
-                        environ['noenc'][k] = v
-                        environ['utf8'][k] = os.environ[k].encode('utf-8')
+        for var in variables:
+            v = variables[var](buf)
 
-                variables = {'GEDIT_SELECTED_TEXT': self.env_get_selected_text,
-                             'GEDIT_CURRENT_WORD': self.env_get_current_word,
-                             'GEDIT_CURRENT_LINE': self.env_get_current_line,
-                             'GEDIT_CURRENT_LINE_NUMBER': self.env_get_current_line_number,
-                             'GEDIT_CURRENT_DOCUMENT_TYPE': self.env_get_document_type,
-                             'GEDIT_DOCUMENTS_URI': self.env_get_documents_uri,
-                             'GEDIT_DOCUMENTS_PATH': self.env_get_documents_path}
+            if isinstance(v, dict):
+                environ['utf8'][var] = v['utf8']
+                environ['noenc'][var] = v['noenc']
+            else:
+                environ['utf8'][var] = v
+                environ['noenc'][var] = str(v)
 
-                for var in variables:
-                        v = variables[var](buf)
+        self.env_add_for_location(environ, buf.get_location(), 'GEDIT_CURRENT_DOCUMENT')
 
-                        if isinstance(v, dict):
-                                environ['utf8'][var] = v['utf8']
-                                environ['noenc'][var] = v['noenc']
-                        else:
-                                environ['utf8'][var] = v
-                                environ['noenc'][var] = str(v)
+        return environ
 
-                self.env_add_for_location(environ, buf.get_location(), 'GEDIT_CURRENT_DOCUMENT')
+    def uses_current_word(self, snippet):
+        matches = re.findall('(\\\\*)\\$GEDIT_CURRENT_WORD', snippet['text'])
 
-                return environ
+        for match in matches:
+            if len(match) % 2 == 0:
+                return True
 
-        def uses_current_word(self, snippet):
-                matches = re.findall('(\\\\*)\\$GEDIT_CURRENT_WORD', snippet['text'])
+        return False
 
-                for match in matches:
-                        if len(match) % 2 == 0:
-                                return True
+    def uses_current_line(self, snippet):
+        matches = re.findall('(\\\\*)\\$GEDIT_CURRENT_LINE', snippet['text'])
 
-                return False
+        for match in matches:
+            if len(match) % 2 == 0:
+                return True
 
-        def uses_current_line(self, snippet):
-                matches = re.findall('(\\\\*)\\$GEDIT_CURRENT_LINE', snippet['text'])
+        return False
 
-                for match in matches:
-                        if len(match) % 2 == 0:
-                                return True
+    def apply_snippet(self, snippet, start = None, end = None, environ = {}):
+        if not snippet.valid:
+            return False
 
-                return False
+        # Set environmental variables
+        env = self.get_environment()
 
-        def apply_snippet(self, snippet, start = None, end = None, environ = {}):
-                if not snippet.valid:
-                        return False
+        if environ:
+            for k in environ['utf8']:
+                env['utf8'][k] = environ['utf8'][k]
 
-                # Set environmental variables
-                env = self.get_environment()
+            for k in environ['noenc']:
+                env['noenc'][k] = environ['noenc'][k]
 
-                if environ:
-                        for k in environ['utf8']:
-                                env['utf8'][k] = environ['utf8'][k]
+        buf = self.view.get_buffer()
+        s = Snippet(snippet, env)
 
-                        for k in environ['noenc']:
-                                env['noenc'][k] = environ['noenc'][k]
+        if not start:
+            start = buf.get_iter_at_mark(buf.get_insert())
 
-                buf = self.view.get_buffer()
-                s = Snippet(snippet, env)
+        if not end:
+            end = buf.get_iter_at_mark(buf.get_selection_bound())
 
-                if not start:
-                        start = buf.get_iter_at_mark(buf.get_insert())
+        if start.equal(end) and self.uses_current_word(s):
+            # There is no tab trigger and no selection and the snippet uses
+            # the current word. Set start and end to the word boundary so that
+            # it will be removed
+            start, end = helper.buffer_word_boundary(buf)
+        elif start.equal(end) and self.uses_current_line(s):
+            # There is no tab trigger and no selection and the snippet uses
+            # the current line. Set start and end to the line boundary so that
+            # it will be removed
+            start, end = helper.buffer_line_boundary(buf)
 
-                if not end:
-                        end = buf.get_iter_at_mark(buf.get_selection_bound())
+        # You know, we could be in an end placeholder
+        (current, next) = self.next_placeholder()
+        if current and current.__class__ == PlaceholderEnd:
+            self.goto_placeholder(current, None)
 
-                if start.equal(end) and self.uses_current_word(s):
-                        # There is no tab trigger and no selection and the snippet uses
-                        # the current word. Set start and end to the word boundary so that
-                        # it will be removed
-                        start, end = buffer_word_boundary(buf)
-                elif start.equal(end) and self.uses_current_line(s):
-                        # There is no tab trigger and no selection and the snippet uses
-                        # the current line. Set start and end to the line boundary so that
-                        # it will be removed
-                        start, end = buffer_line_boundary(buf)
+        buf.begin_user_action()
 
-                # You know, we could be in an end placeholder
-                (current, next) = self.next_placeholder()
-                if current and current.__class__ == PlaceholderEnd:
-                        self.goto_placeholder(current, None)
+        # Remove the tag, selection or current word
+        buf.delete(start, end)
 
-                buf.begin_user_action()
+        # Insert the snippet
+        if len(self.active_snippets) == 0:
+            self.first_snippet_inserted()
 
-                # Remove the tag, selection or current word
-                buf.delete(start, end)
+        sn = s.insert_into(self, start)
+        self.active_snippets.append(sn)
 
-                # Insert the snippet
-                holders = len(self.placeholders)
+        # Put cursor at first tab placeholder
+        keys = [x for x in sn.placeholders.keys() if x > 0]
 
-                if len(self.active_snippets) == 0:
-                        self.first_snippet_inserted()
+        if len(keys) == 0:
+            if 0 in sn.placeholders:
+                self.goto_placeholder(self.active_placeholder, sn.placeholders[0])
+            else:
+                buf.place_cursor(sn.begin_iter())
+        else:
+            self.goto_placeholder(self.active_placeholder, sn.placeholders[keys[0]])
 
-                sn = s.insert_into(self, start)
-                self.active_snippets.append(sn)
+        if sn in self.active_snippets:
+            # Check if we can get end_iter in view without moving the
+            # current cursor position out of view
+            cur = buf.get_iter_at_mark(buf.get_insert())
+            last = sn.end_iter()
 
-                # Put cursor at first tab placeholder
-                keys = [x for x in sn.placeholders.keys() if x > 0]
+            curloc = self.view.get_iter_location(cur)
+            lastloc = self.view.get_iter_location(last)
 
-                if len(keys) == 0:
-                        if 0 in sn.placeholders:
-                                self.goto_placeholder(self.active_placeholder, sn.placeholders[0])
-                        else:
-                                buf.place_cursor(sn.begin_iter())
-                else:
-                        self.goto_placeholder(self.active_placeholder, sn.placeholders[keys[0]])
+            if (lastloc.y + lastloc.height) - curloc.y <= \
+               self.view.get_visible_rect().height:
+                self.view.scroll_mark_onscreen(sn.end_mark)
 
-                if sn in self.active_snippets:
-                        # Check if we can get end_iter in view without moving the
-                        # current cursor position out of view
-                        cur = buf.get_iter_at_mark(buf.get_insert())
-                        last = sn.end_iter()
+        buf.end_user_action()
+        self.view.grab_focus()
 
-                        curloc = self.view.get_iter_location(cur)
-                        lastloc = self.view.get_iter_location(last)
+        return True
 
-                        if (lastloc.y + lastloc.height) - curloc.y <= \
-                           self.view.get_visible_rect().height:
-                                self.view.scroll_mark_onscreen(sn.end_mark)
+    def get_tab_tag(self, buf, end = None):
+        if not end:
+            end = buf.get_iter_at_mark(buf.get_insert())
 
-                buf.end_user_action()
-                self.view.grab_focus()
+        start = end.copy()
+        word = None
+        first = True
 
-                return True
+        # Move start backward as long as there is a valid character
+        while start.backward_char():
+            c = start.get_char()
 
-        def get_tab_tag(self, buf, end = None):
-                if not end:
-                        end = buf.get_iter_at_mark(buf.get_insert())
+            if not helper.is_tab_trigger_character(c):
+                # Check this for a single special char
+                if first and helper.is_tab_trigger(c):
+                    break
 
-                start = end.copy()
-                word = None
-                first = True
+                # Make sure first char is valid
+                while not start.equal(end) and \
+                      not helper.is_first_tab_trigger_character(start.get_char()):
+                    start.forward_char()
 
-                # Move start backward as long as there is a valid character
-                while start.backward_char():
-                        c = start.get_char()
+                break
 
-                        if not helper.is_tab_trigger_character(c):
-                                # Check this for a single special char
-                                if first and helper.is_tab_trigger(c):
-                                        break
+            first = False
 
-                                # Make sure first char is valid
-                                while not start.equal(end) and \
-                                      not helper.is_first_tab_trigger_character(start.get_char()):
-                                        start.forward_char()
+        if not start.equal(end):
+            word = buf.get_text(start, end, False)
 
-                                break
+            if word and word != '':
+                return (word, start, end)
 
-                        first = False
+        return (None, None, None)
 
-                if not start.equal(end):
-                        word = buf.get_text(start, end, False)
+    def parse_and_run_snippet(self, data, iter):
+        if not self.view.get_editable():
+            return
 
-                        if word and word != '':
-                                return (word, start, end)
+        self.apply_snippet(DynamicSnippet(data), iter, iter)
 
-                return (None, None, None)
+    def run_snippet_trigger(self, trigger, bounds):
+        if not self.view:
+            return False
 
-        def parse_and_run_snippet(self, data, iter):
-                if not self.view.get_editable():
-                        return
+        if not self.view.get_editable():
+            return False
 
-                self.apply_snippet(DynamicSnippet(data), iter, iter)
+        buf = self.view.get_buffer()
 
-        def run_snippet_trigger(self, trigger, bounds):
-                if not self.view:
-                        return False
+        if buf.get_has_selection():
+            return False
 
-                if not self.view.get_editable():
-                        return False
+        snippets = Library().from_tag(trigger, self.language_id)
 
-                buf = self.view.get_buffer()
+        if snippets:
+            if len(snippets) == 1:
+                return self.apply_snippet(snippets[0], bounds[0], bounds[1])
+            else:
+                # Do the fancy completion dialog
+                self.provider.set_proposals(snippets)
+                cm = self.view.get_completion()
 
-                if buf.get_has_selection():
-                        return False
+                cm.show([self.provider], cm.create_context(None))
+                return True
 
-                snippets = Library().from_tag(trigger, self.language_id)
+        return False
 
-                if snippets:
-                        if len(snippets) == 1:
-                                return self.apply_snippet(snippets[0], bounds[0], bounds[1])
-                        else:
-                                # Do the fancy completion dialog
-                                self.provider.set_proposals(snippets)
-                                cm = self.view.get_completion()
+    def run_snippet(self):
+        if not self.view:
+            return False
 
-                                cm.show([self.provider], cm.create_context(None))
-                                return True
+        if not self.view.get_editable():
+            return False
 
-                return False
+        buf = self.view.get_buffer()
 
-        def run_snippet(self):
-                if not self.view:
-                        return False
+        # get the word preceding the current insertion position
+        (word, start, end) = self.get_tab_tag(buf)
 
-                if not self.view.get_editable():
-                        return False
+        if not word:
+            return self.skip_to_next_placeholder()
 
-                buf = self.view.get_buffer()
+        if not self.run_snippet_trigger(word, (start, end)):
+            return self.skip_to_next_placeholder()
+        else:
+            return True
 
-                # get the word preceding the current insertion position
-                (word, start, end) = self.get_tab_tag(buf)
+    def deactivate_snippet(self, snippet, force = False):
+        remove = []
+        ordered_remove = []
 
-                if not word:
-                        return self.skip_to_next_placeholder()
+        for tabstop in snippet.placeholders:
+            if tabstop == -1:
+                placeholders = snippet.placeholders[-1]
+            else:
+                placeholders = [snippet.placeholders[tabstop]]
 
-                if not self.run_snippet_trigger(word, (start, end)):
-                        return self.skip_to_next_placeholder()
-                else:
-                        return True
+            for placeholder in placeholders:
+                if placeholder in self.placeholders:
+                    if placeholder in self.update_placeholders:
+                        placeholder.update_contents()
 
-        def deactivate_snippet(self, snippet, force = False):
-                buf = self.view.get_buffer()
-                remove = []
-                ordered_remove = []
+                        self.update_placeholders.remove(placeholder)
+                    elif placeholder in self.jump_placeholders:
+                        placeholder[0].leave()
 
-                for tabstop in snippet.placeholders:
-                        if tabstop == -1:
-                                placeholders = snippet.placeholders[-1]
-                        else:
-                                placeholders = [snippet.placeholders[tabstop]]
+                    remove.append(placeholder)
+                elif placeholder in self.ordered_placeholders:
+                    ordered_remove.append(placeholder)
 
-                        for placeholder in placeholders:
-                                if placeholder in self.placeholders:
-                                        if placeholder in self.update_placeholders:
-                                                placeholder.update_contents()
+        for placeholder in remove:
+            if placeholder == self.active_placeholder:
+                self.active_placeholder = None
 
-                                                self.update_placeholders.remove(placeholder)
-                                        elif placeholder in self.jump_placeholders:
-                                                placeholder[0].leave()
+            self.placeholders.remove(placeholder)
+            self.ordered_placeholders.remove(placeholder)
 
-                                        remove.append(placeholder)
-                                elif placeholder in self.ordered_placeholders:
-                                        ordered_remove.append(placeholder)
+            placeholder.remove(force)
 
-                for placeholder in remove:
-                        if placeholder == self.active_placeholder:
-                                self.active_placeholder = None
+        for placeholder in ordered_remove:
+            self.ordered_placeholders.remove(placeholder)
+            placeholder.remove(force)
 
-                        self.placeholders.remove(placeholder)
-                        self.ordered_placeholders.remove(placeholder)
+        snippet.deactivate()
+        self.active_snippets.remove(snippet)
 
-                        placeholder.remove(force)
+        if len(self.active_snippets) == 0:
+            self.last_snippet_removed()
 
-                for placeholder in ordered_remove:
-                        self.ordered_placeholders.remove(placeholder)
-                        placeholder.remove(force)
+        self.view.queue_draw()
 
-                snippet.deactivate()
-                self.active_snippets.remove(snippet)
+    def update_snippet_contents(self):
+        self.timeout_update_id = 0
 
-                if len(self.active_snippets) == 0:
-                        self.last_snippet_removed()
+        for placeholder in self.update_placeholders:
+            placeholder.update_contents()
 
-                self.view.queue_draw()
+        for placeholder in self.jump_placeholders:
+            self.goto_placeholder(placeholder[0], placeholder[1])
 
-        def update_snippet_contents(self):
-                self.timeout_update_id = 0
+        del self.update_placeholders[:]
+        del self.jump_placeholders[:]
 
-                for placeholder in self.update_placeholders:
-                        placeholder.update_contents()
+        return False
 
-                for placeholder in self.jump_placeholders:
-                        self.goto_placeholder(placeholder[0], placeholder[1])
+    def on_buffer_cursor_moved(self, buf):
+        piter = buf.get_iter_at_mark(buf.get_insert())
 
-                del self.update_placeholders[:]
-                del self.jump_placeholders[:]
+        # Check for all snippets if the cursor is outside its scope
+        for snippet in list(self.active_snippets):
+            if snippet.begin_mark.get_deleted() or snippet.end_mark.get_deleted():
+                self.deactivate(snippet)
+            else:
+                begin = snippet.begin_iter()
+                end = snippet.end_iter()
 
-                return False
+                if piter.compare(begin) < 0 or piter.compare(end) > 0:
+                    # Oh no! Remove the snippet this instant!!
+                    self.deactivate_snippet(snippet)
 
-        def on_buffer_cursor_moved(self, buf):
-                piter = buf.get_iter_at_mark(buf.get_insert())
+        current = self.current_placeholder()
 
-                # Check for all snippets if the cursor is outside its scope
-                for snippet in list(self.active_snippets):
-                        if snippet.begin_mark.get_deleted() or snippet.end_mark.get_deleted():
-                                self.deactivate(snippet)
-                        else:
-                                begin = snippet.begin_iter()
-                                end = snippet.end_iter()
+        if current != self.active_placeholder:
+            self.jump_placeholders.append((self.active_placeholder, current))
 
-                                if piter.compare(begin) < 0 or piter.compare(end) > 0:
-                                        # Oh no! Remove the snippet this instant!!
-                                        self.deactivate_snippet(snippet)
+            if self.timeout_update_id == 0:
+                self.timeout_update_id = GLib.timeout_add(0,
+                        self.update_snippet_contents)
 
-                current = self.current_placeholder()
+    def on_buffer_changed(self, buf):
+        current = self.current_placeholder()
 
-                if current != self.active_placeholder:
-                        self.jump_placeholders.append((self.active_placeholder, current))
+        if current:
+            if not current in self.update_placeholders:
+                self.update_placeholders.append(current)
 
-                        if self.timeout_update_id == 0:
-                                self.timeout_update_id = GLib.timeout_add(0,
-                                                self.update_snippet_contents)
+            if self.timeout_update_id == 0:
+                self.timeout_update_id = GLib.timeout_add(0, \
+                        self.update_snippet_contents)
 
-        def on_buffer_changed(self, buf):
-                current = self.current_placeholder()
+    def on_buffer_insert_text(self, buf, piter, text, length):
+        ctx = helper.get_buffer_context(buf)
 
-                if current:
-                        if not current in self.update_placeholders:
-                                self.update_placeholders.append(current)
+        # do nothing special if there is no context and no active
+        # placeholder
+        if (not ctx) and (not self.active_placeholder):
+            return
 
-                        if self.timeout_update_id == 0:
-                                self.timeout_update_id = GLib.timeout_add(0, \
-                                                self.update_snippet_contents)
+        if not ctx:
+            ctx = self.active_placeholder
 
-        def on_buffer_insert_text(self, buf, piter, text, length):
-                ctx = get_buffer_context(buf)
+        if not ctx in self.ordered_placeholders:
+            return
 
-                # do nothing special if there is no context and no active
-                # placeholder
-                if (not ctx) and (not self.active_placeholder):
-                        return
+        # move any marks that were incorrectly moved by this insertion
+        # back to where they belong
+        begin = ctx.begin_iter()
+        end = ctx.end_iter()
+        idx = self.ordered_placeholders.index(ctx)
 
-                if not ctx:
-                        ctx = self.active_placeholder
+        for placeholder in self.ordered_placeholders:
+            if placeholder == ctx:
+                continue
 
-                if not ctx in self.ordered_placeholders:
-                        return
+            ob = placeholder.begin_iter()
+            oe = placeholder.end_iter()
 
-                # move any marks that were incorrectly moved by this insertion
-                # back to where they belong
-                begin = ctx.begin_iter()
-                end = ctx.end_iter()
-                idx = self.ordered_placeholders.index(ctx)
+            if ob.compare(begin) == 0 and ((not oe) or oe.compare(end) == 0):
+                oidx = self.ordered_placeholders.index(placeholder)
 
-                for placeholder in self.ordered_placeholders:
-                        if placeholder == ctx:
-                                continue
+                if oidx > idx and ob:
+                    buf.move_mark(placeholder.begin, end)
+                elif oidx < idx and oe:
+                    buf.move_mark(placeholder.end, begin)
+            elif ob.compare(begin) >= 0 and ob.compare(end) < 0 and (oe and oe.compare(end) >= 0):
+                buf.move_mark(placeholder.begin, end)
+            elif (oe and oe.compare(begin) > 0) and ob.compare(begin) <= 0:
+                buf.move_mark(placeholder.end, begin)
 
-                        ob = placeholder.begin_iter()
-                        oe = placeholder.end_iter()
+    def on_notify_language(self, buf, spec):
+        self.update_language()
 
-                        if ob.compare(begin) == 0 and ((not oe) or oe.compare(end) == 0):
-                                oidx = self.ordered_placeholders.index(placeholder)
+    def on_view_key_press(self, view, event):
+        library = Library()
 
-                                if oidx > idx and ob:
-                                        buf.move_mark(placeholder.begin, end)
-                                elif oidx < idx and oe:
-                                        buf.move_mark(placeholder.end, begin)
-                        elif ob.compare(begin) >= 0 and ob.compare(end) < 0 and (oe and oe.compare(end) >= 
0):
-                                buf.move_mark(placeholder.begin, end)
-                        elif (oe and oe.compare(begin) > 0) and ob.compare(begin) <= 0:
-                                buf.move_mark(placeholder.end, begin)
+        state = event.get_state()
 
-        def on_notify_language(self, buf, spec):
-                self.update_language()
+        if not self.view.get_editable():
+            return False
 
-        def on_view_key_press(self, view, event):
-                library = Library()
+        if not (state & Gdk.ModifierType.CONTROL_MASK) and \
+                not (state & Gdk.ModifierType.MOD1_MASK) and \
+                event.keyval in self.TAB_KEY_VAL:
+            if not state & Gdk.ModifierType.SHIFT_MASK:
+                return self.run_snippet()
+            else:
+                return self.skip_to_previous_placeholder()
+        elif not library.loaded and \
+                library.valid_accelerator(event.keyval, state):
+            library.ensure_files()
+            library.ensure(self.language_id)
+            self.accelerator_activate(event.keyval, \
+                    state & Gtk.accelerator_get_default_mod_mask())
 
-                state = event.get_state()
+        return False
 
-                if not self.view.get_editable():
-                        return False
+    def path_split(self, path, components=[]):
+        head, tail = os.path.split(path)
 
-                if not (state & Gdk.ModifierType.CONTROL_MASK) and \
-                                not (state & Gdk.ModifierType.MOD1_MASK) and \
-                                event.keyval in self.TAB_KEY_VAL:
-                        if not state & Gdk.ModifierType.SHIFT_MASK:
-                                return self.run_snippet()
-                        else:
-                                return self.skip_to_previous_placeholder()
-                elif not library.loaded and \
-                                library.valid_accelerator(event.keyval, state):
-                        library.ensure_files()
-                        library.ensure(self.language_id)
-                        self.accelerator_activate(event.keyval, \
-                                        state & Gtk.accelerator_get_default_mod_mask())
-
-                return False
-
-        def path_split(self, path, components=[]):
-                head, tail = os.path.split(path)
-
-                if not tail and head:
-                        return [head] + components
-                elif tail:
-                        return self.path_split(head, [tail] + components)
-                else:
-                        return components
+        if not tail and head:
+            return [head] + components
+        elif tail:
+            return self.path_split(head, [tail] + components)
+        else:
+            return components
 
-        def apply_uri_snippet(self, snippet, mime, uri):
-                # Remove file scheme
-                gfile = Gio.file_new_for_uri(uri)
+    def apply_uri_snippet(self, snippet, mime, uri):
+        # Remove file scheme
+        gfile = Gio.file_new_for_uri(uri)
 
-                environ = {'utf8': {'GEDIT_DROP_DOCUMENT_TYPE': mime.encode('utf-8')},
-                           'noenc': {'GEDIT_DROP_DOCUMENT_TYPE': mime}}
+        environ = {'utf8': {'GEDIT_DROP_DOCUMENT_TYPE': mime.encode('utf-8')},
+               'noenc': {'GEDIT_DROP_DOCUMENT_TYPE': mime}}
 
-                self.env_add_for_location(environ, gfile, 'GEDIT_DROP_DOCUMENT')
+        self.env_add_for_location(environ, gfile, 'GEDIT_DROP_DOCUMENT')
 
-                buf = self.view.get_buffer()
-                location = buf.get_location()
+        buf = self.view.get_buffer()
+        location = buf.get_location()
 
-                relpath = location.get_relative_path(gfile)
+        relpath = location.get_relative_path(gfile)
 
-                # CHECK: what is the encoding of relpath?
-                environ['utf8']['GEDIT_DROP_DOCUMENT_RELATIVE_PATH'] = relpath.encode('utf-8')
-                environ['noenc']['GEDIT_DROP_DOCUMENT_RELATIVE_PATH'] = relpath
+        # CHECK: what is the encoding of relpath?
+        environ['utf8']['GEDIT_DROP_DOCUMENT_RELATIVE_PATH'] = relpath.encode('utf-8')
+        environ['noenc']['GEDIT_DROP_DOCUMENT_RELATIVE_PATH'] = relpath
 
-                mark = buf.get_mark('gtk_drag_target')
+        mark = buf.get_mark('gtk_drag_target')
 
-                if not mark:
-                        mark = buf.get_insert()
+        if not mark:
+            mark = buf.get_insert()
 
-                piter = buf.get_iter_at_mark(mark)
-                self.apply_snippet(snippet, piter, piter, environ)
+        piter = buf.get_iter_at_mark(mark)
+        self.apply_snippet(snippet, piter, piter, environ)
 
-        def in_bounds(self, x, y):
-                rect = self.view.get_visible_rect()
-                rect.x, rect.y = self.view.buffer_to_window_coords(Gtk.TextWindowType.WIDGET, rect.x, rect.y)
+    def in_bounds(self, x, y):
+        rect = self.view.get_visible_rect()
+        rect.x, rect.y = self.view.buffer_to_window_coords(Gtk.TextWindowType.WIDGET, rect.x, rect.y)
 
-                return not (x < rect.x or x > rect.x + rect.width or y < rect.y or y > rect.y + rect.height)
+        return not (x < rect.x or x > rect.x + rect.width or y < rect.y or y > rect.y + rect.height)
 
-        def on_drag_data_received(self, view, context, x, y, data, info, timestamp):
-                if not self.view.get_editable():
-                        return
+    def on_drag_data_received(self, view, context, x, y, data, info, timestamp):
+        if not self.view.get_editable():
+            return
 
-                uris = drop_get_uris(data)
-                if not uris:
-                        return
+        uris = helper.drop_get_uris(data)
+        if not uris:
+            return
 
-                if not self.in_bounds(x, y):
-                        return
+        if not self.in_bounds(x, y):
+            return
 
-                uris.reverse()
-                stop = False
+        uris.reverse()
+        stop = False
 
-                for uri in uris:
-                        try:
-                                mime = Gio.content_type_guess(uri)
-                        except:
-                                mime = None
+        for uri in uris:
+            try:
+                mime = Gio.content_type_guess(uri)
+            except:
+                mime = None
 
-                        if not mime:
-                                continue
+            if not mime:
+                continue
 
-                        snippets = Library().from_drop_target(mime, self.language_id)
+            snippets = Library().from_drop_target(mime, self.language_id)
 
-                        if snippets:
-                                stop = True
-                                self.apply_uri_snippet(snippets[0], mime, uri)
+            if snippets:
+                stop = True
+                self.apply_uri_snippet(snippets[0], mime, uri)
 
-                if stop:
-                        context.finish(True, False, timestamp)
-                        view.stop_emission('drag-data-received')
-                        view.get_toplevel().present()
-                        view.grab_focus()
+        if stop:
+            context.finish(True, False, timestamp)
+            view.stop_emission('drag-data-received')
+            view.get_toplevel().present()
+            view.grab_focus()
 
-        def find_uri_target(self, context):
-                lst = Gtk.target_list_add_uri_targets((), 0)
+    def find_uri_target(self, context):
+        lst = Gtk.target_list_add_uri_targets((), 0)
 
-                return self.view.drag_dest_find_target(context, lst)
+        return self.view.drag_dest_find_target(context, lst)
 
-        def on_completion_hide(self, completion):
-                self.provider.set_proposals(None)
+    def on_completion_hide(self, completion):
+        self.provider.set_proposals(None)
 
-        def on_proposal_activated(self, proposal, piter):
-                if not self.view.get_editable():
-                        return False
+    def on_proposal_activated(self, proposal, piter):
+        if not self.view.get_editable():
+            return False
 
-                buf = self.view.get_buffer()
-                bounds = buf.get_selection_bounds()
+        buf = self.view.get_buffer()
+        bounds = buf.get_selection_bounds()
 
-                if bounds:
-                        self.apply_snippet(proposal.snippet(), None, None)
-                else:
-                        (word, start, end) = self.get_tab_tag(buf, piter)
-                        self.apply_snippet(proposal.snippet(), start, end)
+        if bounds:
+            self.apply_snippet(proposal.snippet(), None, None)
+        else:
+            (word, start, end) = self.get_tab_tag(buf, piter)
+            self.apply_snippet(proposal.snippet(), start, end)
 
-                return True
+        return True
 
-        def on_default_activated(self, proposal, piter):
-                buf = self.view.get_buffer()
-                bounds = buf.get_selection_bounds()
+    def on_default_activated(self, proposal, piter):
+        buf = self.view.get_buffer()
+        bounds = buf.get_selection_bounds()
 
-                if bounds:
-                        buf.begin_user_action()
-                        buf.delete(bounds[0], bounds[1])
-                        buf.insert(bounds[0], proposal.props.label)
-                        buf.end_user_action()
+        if bounds:
+            buf.begin_user_action()
+            buf.delete(bounds[0], bounds[1])
+            buf.insert(bounds[0], proposal.props.label)
+            buf.end_user_action()
 
-                        return True
-                else:
-                        return False
+            return True
+        else:
+            return False
 
-        def iter_coords(self, piter):
-                rect = self.view.get_iter_location(piter)
-                rect.x, rect.y = self.view.buffer_to_window_coords(Gtk.TextWindowType.TEXT, rect.x, rect.y)
+    def iter_coords(self, piter):
+        rect = self.view.get_iter_location(piter)
+        rect.x, rect.y = self.view.buffer_to_window_coords(Gtk.TextWindowType.TEXT, rect.x, rect.y)
 
-                return rect
+        return rect
 
-        def placeholder_in_area(self, placeholder, area):
-                start = placeholder.begin_iter()
-                end = placeholder.end_iter()
+    def placeholder_in_area(self, placeholder, area):
+        start = placeholder.begin_iter()
+        end = placeholder.end_iter()
 
-                if not start or not end:
-                        return False
+        if not start or not end:
+            return False
 
-                # Test if start is before bottom, and end is after top
-                start_rect = self.iter_coords(start)
-                end_rect = self.iter_coords(end)
+        # Test if start is before bottom, and end is after top
+        start_rect = self.iter_coords(start)
+        end_rect = self.iter_coords(end)
 
-                return start_rect.y <= area.y + area.height and \
-                       end_rect.y + end_rect.height >= area.y
+        return start_rect.y <= area.y + area.height and \
+               end_rect.y + end_rect.height >= area.y
 
-        def draw_placeholder_rect(self, ctx, placeholder):
-                start = placeholder.begin_iter()
-                start_rect = self.iter_coords(start)
-                start_line = start.get_line()
+    def draw_placeholder_rect(self, ctx, placeholder):
+        start = placeholder.begin_iter()
+        start_rect = self.iter_coords(start)
+        start_line = start.get_line()
 
-                end = placeholder.end_iter()
-                end_rect = self.iter_coords(end)
-                end_line = end.get_line()
+        end = placeholder.end_iter()
+        end_rect = self.iter_coords(end)
+        end_line = end.get_line()
 
-                line = start.copy()
-                line.set_line_offset(0)
-                geom = self.view.get_window(Gtk.TextWindowType.TEXT).get_geometry()
+        line = start.copy()
+        line.set_line_offset(0)
+        geom = self.view.get_window(Gtk.TextWindowType.TEXT).get_geometry()
 
-                ctx.translate(0.5, 0.5)
+        ctx.translate(0.5, 0.5)
 
-                while line.get_line() <= end_line:
-                        ypos, height = self.view.get_line_yrange(line)
-                        x_, ypos = self.view.window_to_buffer_coords(Gtk.TextWindowType.TEXT, 0, ypos)
+        while line.get_line() <= end_line:
+            ypos, height = self.view.get_line_yrange(line)
+            x_, ypos = self.view.window_to_buffer_coords(Gtk.TextWindowType.TEXT, 0, ypos)
 
-                        if line.get_line() == start_line and line.get_line() == end_line:
-                                # Simply draw a box, both are on the same line
-                                ctx.rectangle(start_rect.x, start_rect.y, end_rect.x - start_rect.x, 
start_rect.height - 1)
-                                ctx.stroke()
-                        elif line.get_line() == start_line or line.get_line() == end_line:
-                                if line.get_line() == start_line:
-                                        rect = start_rect
-                                else:
-                                        rect = end_rect
+            if line.get_line() == start_line and line.get_line() == end_line:
+                # Simply draw a box, both are on the same line
+                ctx.rectangle(start_rect.x, start_rect.y, end_rect.x - start_rect.x, start_rect.height - 1)
+                ctx.stroke()
+            elif line.get_line() == start_line or line.get_line() == end_line:
+                if line.get_line() == start_line:
+                    rect = start_rect
+                else:
+                    rect = end_rect
 
-                                ctx.move_to(0, rect.y + rect.height - 1)
-                                ctx.rel_line_to(rect.x, 0)
-                                ctx.rel_line_to(0, -rect.height + 1)
-                                ctx.rel_line_to(geom[2], 0)
-                                ctx.stroke()
+                ctx.move_to(0, rect.y + rect.height - 1)
+                ctx.rel_line_to(rect.x, 0)
+                ctx.rel_line_to(0, -rect.height + 1)
+                ctx.rel_line_to(geom[2], 0)
+                ctx.stroke()
 
-                        if not line.forward_line():
-                                break
+            if not line.forward_line():
+                break
 
-        def draw_placeholder_bar(self, ctx, placeholder):
-                start = placeholder.begin_iter()
-                start_rect = self.iter_coords(start)
+    def draw_placeholder_bar(self, ctx, placeholder):
+        start = placeholder.begin_iter()
+        start_rect = self.iter_coords(start)
 
-                ctx.translate(0.5, 0.5)
-                extend_width = 2.5
+        ctx.translate(0.5, 0.5)
+        extend_width = 2.5
 
-                ctx.move_to(start_rect.x - extend_width, start_rect.y)
-                ctx.rel_line_to(extend_width * 2, 0)
+        ctx.move_to(start_rect.x - extend_width, start_rect.y)
+        ctx.rel_line_to(extend_width * 2, 0)
 
-                ctx.move_to(start_rect.x, start_rect.y)
-                ctx.rel_line_to(0, start_rect.height - 1)
+        ctx.move_to(start_rect.x, start_rect.y)
+        ctx.rel_line_to(0, start_rect.height - 1)
 
-                ctx.rel_move_to(-extend_width, 0)
-                ctx.rel_line_to(extend_width * 2, 0)
-                ctx.stroke()
+        ctx.rel_move_to(-extend_width, 0)
+        ctx.rel_line_to(extend_width * 2, 0)
+        ctx.stroke()
 
-        def draw_placeholder(self, ctx, placeholder):
-                if isinstance(placeholder, PlaceholderEnd):
-                        return
+    def draw_placeholder(self, ctx, placeholder):
+        if isinstance(placeholder, PlaceholderEnd):
+            return
 
-                col = self.view.get_style_context().get_color(Gtk.StateFlags.INSENSITIVE)
-                col.alpha = 0.5
-                Gdk.cairo_set_source_rgba(ctx, col)
+        col = self.view.get_style_context().get_color(Gtk.StateFlags.INSENSITIVE)
+        col.alpha = 0.5
+        Gdk.cairo_set_source_rgba(ctx, col)
 
-                if placeholder.tabstop > 0:
-                        ctx.set_dash([], 0)
-                else:
-                        ctx.set_dash([2], 0)
+        if placeholder.tabstop > 0:
+            ctx.set_dash([], 0)
+        else:
+            ctx.set_dash([2], 0)
 
-                start = placeholder.begin_iter()
-                end = placeholder.end_iter()
+        start = placeholder.begin_iter()
+        end = placeholder.end_iter()
 
-                if start.equal(end):
-                        self.draw_placeholder_bar(ctx, placeholder)
-                else:
-                        self.draw_placeholder_rect(ctx, placeholder)
+        if start.equal(end):
+            self.draw_placeholder_bar(ctx, placeholder)
+        else:
+            self.draw_placeholder_rect(ctx, placeholder)
 
-        def on_draw(self, view, ctx):
-                window = view.get_window(Gtk.TextWindowType.TEXT)
+    def on_draw(self, view, ctx):
+        window = view.get_window(Gtk.TextWindowType.TEXT)
 
-                if not Gtk.cairo_should_draw_window(ctx, window):
-                        return False
+        if not Gtk.cairo_should_draw_window(ctx, window):
+            return False
 
-                # Draw something
-                ctx.set_line_width(1.0)
+        # Draw something
+        ctx.set_line_width(1.0)
 
-                Gtk.cairo_transform_to_window(ctx, view, window)
+        Gtk.cairo_transform_to_window(ctx, view, window)
 
-                clipped, clip = Gdk.cairo_get_clip_rectangle(ctx)
+        clipped, clip = Gdk.cairo_get_clip_rectangle(ctx)
 
-                if not clipped:
-                        return False
+        if not clipped:
+            return False
 
-                for placeholder in self.ordered_placeholders:
-                        if not self.placeholder_in_area(placeholder, clip):
-                                continue
+        for placeholder in self.ordered_placeholders:
+            if not self.placeholder_in_area(placeholder, clip):
+                continue
 
-                        ctx.save()
-                        self.draw_placeholder(ctx, placeholder)
-                        ctx.restore()
+            ctx.save()
+            self.draw_placeholder(ctx, placeholder)
+            ctx.restore()
 
-                return False
+        return False
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/exporter.py b/plugins/snippets/snippets/exporter.py
index 185215e..c99eced 100644
--- a/plugins/snippets/snippets/exporter.py
+++ b/plugins/snippets/snippets/exporter.py
@@ -17,100 +17,98 @@
 
 import os
 import tempfile
-import sys
 import shutil
 
-from .library import *
 import xml.etree.ElementTree as et
-from .helper import *
+from . import helper
 
 class Exporter:
-        def __init__(self, filename, snippets):
-                self.filename = filename
-                self.set_snippets(snippets)
+    def __init__(self, filename, snippets):
+        self.filename = filename
+        self.set_snippets(snippets)
 
-        def set_snippets(self, snippets):
-                self.snippets = {}
+    def set_snippets(self, snippets):
+        self.snippets = {}
 
-                for snippet in snippets:
-                        lang = snippet.language()
+        for snippet in snippets:
+            lang = snippet.language()
 
-                        if lang in self.snippets:
-                                self.snippets[lang].append(snippet)
-                        else:
-                                self.snippets[lang] = [snippet]
+            if lang in self.snippets:
+                self.snippets[lang].append(snippet)
+            else:
+                self.snippets[lang] = [snippet]
 
-        def export_xml(self, dirname, language, snippets):
-                # Create the root snippets node
-                root = et.Element('snippets')
+    def export_xml(self, dirname, language, snippets):
+        # Create the root snippets node
+        root = et.Element('snippets')
 
-                # Create filename based on language
-                if language:
-                        filename = os.path.join(dirname, language + '.xml')
+        # Create filename based on language
+        if language:
+            filename = os.path.join(dirname, language + '.xml')
 
-                        # Set the language attribute
-                        root.attrib['language'] = language
-                else:
-                        filename = os.path.join(dirname, 'global.xml')
+            # Set the language attribute
+            root.attrib['language'] = language
+        else:
+            filename = os.path.join(dirname, 'global.xml')
 
-                # Add all snippets to the root node
-                for snippet in snippets:
-                        root.append(snippet.to_xml())
+        # Add all snippets to the root node
+        for snippet in snippets:
+            root.append(snippet.to_xml())
 
-                # Write xml
-                write_xml(root, filename, ('text', 'accelerator'))
+        # Write xml
+        helper.write_xml(root, filename, ('text', 'accelerator'))
 
-        def export_archive(self, cmd):
-                dirname = tempfile.mkdtemp()
+    def export_archive(self, cmd):
+        dirname = tempfile.mkdtemp()
 
-                # Save current working directory and change to temporary directory
-                curdir = os.getcwd()
+        # Save current working directory and change to temporary directory
+        curdir = os.getcwd()
 
-                try:
-                        os.chdir(dirname)
+        try:
+            os.chdir(dirname)
 
-                        # Write snippet xml files
-                        for language, snippets in self.snippets.items():
-                                self.export_xml(dirname, language , snippets)
+            # Write snippet xml files
+            for language, snippets in self.snippets.items():
+                self.export_xml(dirname, language , snippets)
 
-                        # Archive files
-                        status = os.system('%s "%s" *.xml' % (cmd, self.filename))
-                finally:
-                        os.chdir(curdir)
+            # Archive files
+            status = os.system('%s "%s" *.xml' % (cmd, self.filename))
+        finally:
+            os.chdir(curdir)
 
-                if status != 0:
-                        return _('The archive "%s" could not be created' % self.filename)
+        if status != 0:
+            return _('The archive "%s" could not be created' % self.filename)
 
-                # Remove the temporary directory
-                shutil.rmtree(dirname)
+        # Remove the temporary directory
+        shutil.rmtree(dirname)
 
-        def export_targz(self):
-                self.export_archive('tar -c --gzip -f')
+    def export_targz(self):
+        self.export_archive('tar -c --gzip -f')
 
-        def export_tarbz2(self):
-                self.export_archive('tar -c --bzip2 -f')
+    def export_tarbz2(self):
+        self.export_archive('tar -c --bzip2 -f')
 
-        def export_tar(self):
-                self.export_archive('tar -cf')
+    def export_tar(self):
+        self.export_archive('tar -cf')
 
-        def run(self):
-                dirname = os.path.dirname(self.filename)
-                if not os.path.exists(dirname):
-                        return _('Target directory "%s" does not exist') % dirname
+    def run(self):
+        dirname = os.path.dirname(self.filename)
+        if not os.path.exists(dirname):
+            return _('Target directory "%s" does not exist') % dirname
 
-                if not os.path.isdir(dirname):
-                        return _('Target directory "%s" is not a valid directory') % dirname
+        if not os.path.isdir(dirname):
+            return _('Target directory "%s" is not a valid directory') % dirname
 
-                (root, ext) = os.path.splitext(self.filename)
+        (root, ext) = os.path.splitext(self.filename)
 
-                actions = {'.tar.gz': self.export_targz,
-                           '.tar.bz2': self.export_tarbz2,
-                           '.tar': self.export_tar}
+        actions = {'.tar.gz': self.export_targz,
+               '.tar.bz2': self.export_tarbz2,
+               '.tar': self.export_tar}
 
-                for k, v in actions.items():
-                        if self.filename.endswith(k):
-                                return v()
+        for k, v in actions.items():
+            if self.filename.endswith(k):
+                return v()
 
-                return self.export_targz()
+        return self.export_targz()
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/helper.py b/plugins/snippets/snippets/helper.py
index 8d84221..2fa3b3f 100644
--- a/plugins/snippets/snippets/helper.py
+++ b/plugins/snippets/snippets/helper.py
@@ -15,191 +15,190 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-import string
 from xml.sax import saxutils
-from xml.etree.ElementTree import *
+import xml.etree.ElementTree as et
 import re
 import codecs
 
-from gi.repository import Gtk, Gdk
+from gi.repository import Gtk
 
 def message_dialog(par, typ, msg):
-        d = Gtk.MessageDialog(par, Gtk.DialogFlags.MODAL, typ, Gtk.ButtonsType.OK, msg)
-        d.set_property('use-markup', True)
+    d = Gtk.MessageDialog(par, Gtk.DialogFlags.MODAL, typ, Gtk.ButtonsType.OK, msg)
+    d.set_property('use-markup', True)
 
-        d.run()
-        d.destroy()
+    d.run()
+    d.destroy()
 
 def compute_indentation(view, piter):
-        line = piter.get_line()
-        start = view.get_buffer().get_iter_at_line(line)
-        end = start.copy()
+    line = piter.get_line()
+    start = view.get_buffer().get_iter_at_line(line)
+    end = start.copy()
 
-        ch = end.get_char()
+    ch = end.get_char()
 
-        while (ch.isspace() and ch != '\r' and ch != '\n' and \
-                        end.compare(piter) < 0):
-                if not end.forward_char():
-                        break;
+    while (ch.isspace() and ch != '\r' and ch != '\n' and \
+            end.compare(piter) < 0):
+        if not end.forward_char():
+            break;
 
-                ch = end.get_char()
+        ch = end.get_char()
 
-        if start.equal(end):
-                return ''
+    if start.equal(end):
+        return ''
 
-        return start.get_slice(end)
+    return start.get_slice(end)
 
 def markup_escape(text):
-        return saxutils.escape(text)
+    return saxutils.escape(text)
 
 def spaces_instead_of_tabs(view, text):
-        if not view.get_insert_spaces_instead_of_tabs():
-                return text
+    if not view.get_insert_spaces_instead_of_tabs():
+        return text
 
-        return text.replace("\t", view.get_tab_width() * ' ')
+    return text.replace("\t", view.get_tab_width() * ' ')
 
 def insert_with_indent(view, piter, text, indentfirst = True, context = None):
-        text = spaces_instead_of_tabs(view, text)
-        lines = text.split('\n')
-        buf = view.get_buffer()
+    text = spaces_instead_of_tabs(view, text)
+    lines = text.split('\n')
+    buf = view.get_buffer()
 
-        buf._snippets_context = context
+    buf._snippets_context = context
 
-        if len(lines) == 1:
-                view.get_buffer().insert(piter, text)
-        else:
-                # Compute indentation
-                indent = compute_indentation(view, piter)
-                text = ''
+    if len(lines) == 1:
+        view.get_buffer().insert(piter, text)
+    else:
+        # Compute indentation
+        indent = compute_indentation(view, piter)
+        text = ''
 
-                for i in range(0, len(lines)):
-                        if indentfirst or i > 0:
-                                text += indent + lines[i] + '\n'
-                        else:
-                                text += lines[i] + '\n'
+        for i in range(0, len(lines)):
+            if indentfirst or i > 0:
+                text += indent + lines[i] + '\n'
+            else:
+                text += lines[i] + '\n'
 
-                buf.insert(piter, text[:-1])
+        buf.insert(piter, text[:-1])
 
-        buf._snippets_context = None
+    buf._snippets_context = None
 
 def get_buffer_context(buf):
-        if hasattr(buf, "_snippets_context"):
-                return buf._snippets_context
-        return None
+    if hasattr(buf, "_snippets_context"):
+        return buf._snippets_context
+    return None
 
 def snippets_debug(*s):
-        return
+    return
 
 def write_xml(node, f, cdata_nodes=()):
-        assert node is not None
+    assert node is not None
 
-        if not hasattr(f, "write"):
-                f = codecs.open(f, "wb", encoding="utf-8")
+    if not hasattr(f, "write"):
+        f = codecs.open(f, "wb", encoding="utf-8")
 
-        # Encoding
-        f.write("<?xml version='1.0' encoding='utf-8'?>\n")
+    # Encoding
+    f.write("<?xml version='1.0' encoding='utf-8'?>\n")
 
-        _write_node(node, f, cdata_nodes)
+    _write_node(node, f, cdata_nodes)
 
 def _write_indent(file, text, indent):
-        file.write('  ' * indent + text)
+    file.write('  ' * indent + text)
 
 def _write_node(node, file, cdata_nodes=(), indent=0):
-        # write XML to file
-        tag = node.tag
-
-        if node is Comment:
-                _write_indent(file, "<!-- %s -->\n" % saxutils.escape(node.text), indent)
-        elif node is ProcessingInstruction:
-                _write_indent(file, "<?%s?>\n" % saxutils.escape(node.text), indent)
-        else:
-                items = node.items()
-
-                if items or node.text or len(node):
-                        _write_indent(file, "<" + tag, indent)
-
-                        if items:
-                                items.sort() # lexical order
-                                for k, v in items:
-                                        file.write(" %s=%s" % (k, saxutils.quoteattr(v)))
-                        if node.text or len(node):
-                                file.write(">")
-                                if node.text and node.text.strip() != "":
-                                        if tag in cdata_nodes:
-                                                file.write(_cdata(node.text))
-                                        else:
-                                                file.write(saxutils.escape(node.text))
-                                else:
-                                        file.write("\n")
-
-                                for n in node:
-                                        _write_node(n, file, cdata_nodes, indent + 1)
-
-                                if not len(node):
-                                        file.write("</" + tag + ">\n")
-                                else:
-                                        _write_indent(file, "</" + tag + ">\n", \
-                                                        indent)
-                        else:
-                                file.write(" />\n")
-
-                if node.tail and node.tail.strip() != "":
-                        file.write(saxutils.escape(node.tail))
+    # write XML to file
+    tag = node.tag
+
+    if node is et.Comment:
+        _write_indent(file, "<!-- %s -->\n" % saxutils.escape(node.text), indent)
+    elif node is et.ProcessingInstruction:
+        _write_indent(file, "<?%s?>\n" % saxutils.escape(node.text), indent)
+    else:
+        items = node.items()
+
+        if items or node.text or len(node):
+            _write_indent(file, "<" + tag, indent)
+
+            if items:
+                items.sort() # lexical order
+                for k, v in items:
+                    file.write(" %s=%s" % (k, saxutils.quoteattr(v)))
+            if node.text or len(node):
+                file.write(">")
+                if node.text and node.text.strip() != "":
+                    if tag in cdata_nodes:
+                        file.write(_cdata(node.text))
+                    else:
+                        file.write(saxutils.escape(node.text))
+                else:
+                    file.write("\n")
+
+                for n in node:
+                    _write_node(n, file, cdata_nodes, indent + 1)
+
+                if not len(node):
+                    file.write("</" + tag + ">\n")
+                else:
+                    _write_indent(file, "</" + tag + ">\n", \
+                            indent)
+            else:
+                file.write(" />\n")
+
+        if node.tail and node.tail.strip() != "":
+            file.write(saxutils.escape(node.tail))
 
 def _cdata(text):
-        return '<![CDATA[' + text.replace(']]>', ']]]]><![CDATA[>') + ']]>'
+    return '<![CDATA[' + text.replace(']]>', ']]]]><![CDATA[>') + ']]>'
 
 def is_tab_trigger(w):
-        if len(w) == 1 and not (w.isalnum() or w.isspace()):
-                return True
+    if len(w) == 1 and not (w.isalnum() or w.isspace()):
+        return True
 
-        if not is_first_tab_trigger_character(w[0]):
-                return False
+    if not is_first_tab_trigger_character(w[0]):
+        return False
 
-        for c in w:
-                if not is_tab_trigger_character(c):
-                        return False
+    for c in w:
+        if not is_tab_trigger_character(c):
+            return False
 
-        return True
+    return True
 
 def is_first_tab_trigger_character(c):
-        return c.isalpha() or c in '_:.'
+    return c.isalpha() or c in '_:.'
 
 def is_tab_trigger_character(c):
-        return c.isalnum() or c in '_:.'
+    return c.isalnum() or c in '_:.'
 
 def buffer_word_boundary(buf):
-        iter = buf.get_iter_at_mark(buf.get_insert())
-        start = iter.copy()
+    iter = buf.get_iter_at_mark(buf.get_insert())
+    start = iter.copy()
 
-        if not iter.starts_word() and (iter.inside_word() or iter.ends_word()):
-                start.backward_word_start()
+    if not iter.starts_word() and (iter.inside_word() or iter.ends_word()):
+        start.backward_word_start()
 
-        if not iter.ends_word() and iter.inside_word():
-                iter.forward_word_end()
+    if not iter.ends_word() and iter.inside_word():
+        iter.forward_word_end()
 
-        return (start, iter)
+    return (start, iter)
 
 def buffer_line_boundary(buf):
-        iter = buf.get_iter_at_mark(buf.get_insert())
-        start = iter.copy()
-        start.set_line_offset(0)
+    iter = buf.get_iter_at_mark(buf.get_insert())
+    start = iter.copy()
+    start.set_line_offset(0)
 
-        if not iter.ends_line():
-                iter.forward_to_line_end()
+    if not iter.ends_line():
+        iter.forward_to_line_end()
 
-        return (start, iter)
+    return (start, iter)
 
 def drop_get_uris(selection):
-        uris = []
-        if selection.targets_include_uri():
-                data = selection.get_data()
-                lines = re.split('\\s*[\\n\\r]+\\s*', data.strip())
+    uris = []
+    if selection.targets_include_uri():
+        data = selection.get_data()
+        lines = re.split('\\s*[\\n\\r]+\\s*', data.strip())
 
-                for line in lines:
-                        if not line.startswith('#'):
-                                uris.append(line)
+        for line in lines:
+            if not line.startswith('#'):
+                uris.append(line)
 
-        return uris
+    return uris
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/importer.py b/plugins/snippets/snippets/importer.py
index 14206f7..6e22dbe 100644
--- a/plugins/snippets/snippets/importer.py
+++ b/plugins/snippets/snippets/importer.py
@@ -21,106 +21,106 @@ import tempfile
 import sys
 import shutil
 
-from .library import *
+from .library import Library
 
 class Importer:
-        def __init__(self, filename):
-                self.filename = filename
+    def __init__(self, filename):
+        self.filename = filename
 
-        def import_destination(self, filename):
-                userdir = Library().userdir
+    def import_destination(self, filename):
+        userdir = Library().userdir
 
-                filename = os.path.basename(filename)
-                (root, ext) = os.path.splitext(filename)
+        filename = os.path.basename(filename)
+        (root, ext) = os.path.splitext(filename)
 
-                filename = os.path.join(userdir, root + ext)
-                i = 1
+        filename = os.path.join(userdir, root + ext)
+        i = 1
 
-                while os.path.exists(filename):
-                        filename = os.path.join(userdir, root + '_' + str(i) + ext)
-                        i += 1
+        while os.path.exists(filename):
+            filename = os.path.join(userdir, root + '_' + str(i) + ext)
+            i += 1
 
-                return (userdir, filename)
+        return (userdir, filename)
 
-        def import_file(self, filename):
-                if not os.path.exists(filename):
-                        return _('File "%s" does not exist') % filename
+    def import_file(self, filename):
+        if not os.path.exists(filename):
+            return _('File "%s" does not exist') % filename
 
-                if not os.path.isfile(filename):
-                        return _('File "%s" is not a valid snippets file') % filename
+        if not os.path.isfile(filename):
+            return _('File "%s" is not a valid snippets file') % filename
 
-                # Find destination for file to copy to
-                destdir, dest = self.import_destination(filename)
+        # Find destination for file to copy to
+        destdir, dest = self.import_destination(filename)
 
-                # Make sure dir exists
-                try:
-                    os.makedirs(destdir)
-                except OSError as e:
-                    if e.errno != errno.EEXIST:
-                        raise
+        # Make sure dir exists
+        try:
+            os.makedirs(destdir)
+        except OSError as e:
+            if e.errno != errno.EEXIST:
+                raise
 
-                # Copy file
-                shutil.copy(filename, dest)
+        # Copy file
+        shutil.copy(filename, dest)
 
-                # Add library
-                if not Library().add_user_library(dest):
-                        return _('Imported file "%s" is not a valid snippets file') % os.path.basename(dest)
+        # Add library
+        if not Library().add_user_library(dest):
+            return _('Imported file "%s" is not a valid snippets file') % os.path.basename(dest)
 
-        def import_xml(self):
-                return self.import_file(self.filename)
+    def import_xml(self):
+        return self.import_file(self.filename)
 
-        def import_archive(self, cmd):
-                dirname = tempfile.mkdtemp()
-                status = os.system('cd %s; %s "%s"' % (dirname, cmd, self.filename))
+    def import_archive(self, cmd):
+        dirname = tempfile.mkdtemp()
+        status = os.system('cd %s; %s "%s"' % (dirname, cmd, self.filename))
 
-                if status != 0:
-                        return _('The archive "%s" could not be extracted' % self.filename)
+        if status != 0:
+            return _('The archive "%s" could not be extracted' % self.filename)
 
-                errors = []
+        errors = []
 
-                # Now import all the files from the archive
-                for f in os.listdir(dirname):
-                        f = os.path.join(dirname, f)
+        # Now import all the files from the archive
+        for f in os.listdir(dirname):
+            f = os.path.join(dirname, f)
 
-                        if os.path.isfile(f):
-                                if self.import_file(f):
-                                        errors.append(os.path.basename(f))
-                        else:
-                                sys.stderr.write('Skipping %s, not a valid snippets file' % 
os.path.basename(f))
+            if os.path.isfile(f):
+                if self.import_file(f):
+                    errors.append(os.path.basename(f))
+            else:
+                sys.stderr.write('Skipping %s, not a valid snippets file' % os.path.basename(f))
 
-                # Remove the temporary directory
-                shutil.rmtree(dirname)
+        # Remove the temporary directory
+        shutil.rmtree(dirname)
 
-                if len(errors) > 0:
-                        return _('The following files could not be imported: %s') % ', '.join(errors)
+        if len(errors) > 0:
+            return _('The following files could not be imported: %s') % ', '.join(errors)
 
-        def import_targz(self):
-                self.import_archive('tar -x --gzip -f')
+    def import_targz(self):
+        self.import_archive('tar -x --gzip -f')
 
-        def import_tarbz2(self):
-                self.import_archive('tar -x --bzip2 -f')
+    def import_tarbz2(self):
+        self.import_archive('tar -x --bzip2 -f')
 
-        def import_tar(self):
-                self.import_archive('tar -xf')
+    def import_tar(self):
+        self.import_archive('tar -xf')
 
-        def run(self):
-                if not os.path.exists(self.filename):
-                        return _('File "%s" does not exist') % self.filename
+    def run(self):
+        if not os.path.exists(self.filename):
+            return _('File "%s" does not exist') % self.filename
 
-                if not os.path.isfile(self.filename):
-                        return _('File "%s" is not a valid snippets archive') % self.filename
+        if not os.path.isfile(self.filename):
+            return _('File "%s" is not a valid snippets archive') % self.filename
 
-                (root, ext) = os.path.splitext(self.filename)
+        (root, ext) = os.path.splitext(self.filename)
 
-                actions = {'.tar.gz': self.import_targz,
-                           '.tar.bz2': self.import_tarbz2,
-                           '.xml': self.import_xml,
-                           '.tar': self.import_tar}
+        actions = {'.tar.gz': self.import_targz,
+               '.tar.bz2': self.import_tarbz2,
+               '.xml': self.import_xml,
+               '.tar': self.import_tar}
 
-                for k, v in actions.items():
-                        if self.filename.endswith(k):
-                                return v()
+        for k, v in actions.items():
+            if self.filename.endswith(k):
+                return v()
 
-                return _('File "%s" is not a valid snippets archive') % self.filename
+        return _('File "%s" is not a valid snippets archive') % self.filename
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/languagemanager.py b/plugins/snippets/snippets/languagemanager.py
index 30b079e..6f74319 100644
--- a/plugins/snippets/snippets/languagemanager.py
+++ b/plugins/snippets/snippets/languagemanager.py
@@ -24,17 +24,17 @@ global manager
 manager = None
 
 def get_language_manager():
-        global manager
+    global manager
 
-        if not manager:
-                dirs = []
+    if not manager:
+        dirs = []
 
-                for d in Library().systemdirs:
-                        dirs.append(os.path.join(d, 'lang'))
+        for d in Library().systemdirs:
+            dirs.append(os.path.join(d, 'lang'))
 
-                manager = GtkSource.LanguageManager()
-                manager.set_search_path(dirs + manager.get_search_path())
+        manager = GtkSource.LanguageManager()
+        manager.set_search_path(dirs + manager.get_search_path())
 
-        return manager
+    return manager
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/library.py b/plugins/snippets/snippets/library.py
index c60695f..92adc3c 100644
--- a/plugins/snippets/snippets/library.py
+++ b/plugins/snippets/snippets/library.py
@@ -18,977 +18,972 @@
 import os
 import weakref
 import sys
-import tempfile
 import re
 
 from gi.repository import Gdk, Gtk
 
 import xml.etree.ElementTree as et
-from .helper import *
+from . import helper
 
 class NamespacedId:
-        def __init__(self, namespace, id):
-                if not id:
-                        self.id = None
-                else:
-                        if namespace:
-                                self.id = namespace + '-'
-                        else:
-                                self.id = 'global-'
+    def __init__(self, namespace, id):
+        if not id:
+            self.id = None
+        else:
+            if namespace:
+                self.id = namespace + '-'
+            else:
+                self.id = 'global-'
 
-                        self.id += id
+            self.id += id
 
 class SnippetData:
-        PROPS = {'tag': '', 'text': '', 'description': 'New snippet',
-                        'accelerator': '', 'drop-targets': ''}
-
-        def __init__(self, node, library):
-                self.priv_id = node.attrib.get('id')
+    PROPS = {'tag': '', 'text': '', 'description': 'New snippet',
+            'accelerator': '', 'drop-targets': ''}
 
-                self.set_library(library)
-                self.valid = False
-                self.set_node(node)
+    def __init__(self, node, library):
+        self.priv_id = node.attrib.get('id')
 
-        def can_modify(self):
-                return (self.library and (isinstance(self.library(), SnippetsUserFile)))
+        self.set_library(library)
+        self.valid = False
+        self.set_node(node)
 
-        def set_library(self, library):
-                if library:
-                        self.library = weakref.ref(library)
-                else:
-                        self.library = None
+    def can_modify(self):
+        return (self.library and (isinstance(self.library(), SnippetsUserFile)))
 
-                self.id = NamespacedId(self.language(), self.priv_id).id
+    def set_library(self, library):
+        if library:
+            self.library = weakref.ref(library)
+        else:
+            self.library = None
 
-        def set_node(self, node):
-                if self.can_modify():
-                        self.node = node
-                else:
-                        self.node = None
+        self.id = NamespacedId(self.language(), self.priv_id).id
 
-                self.init_snippet_data(node)
+    def set_node(self, node):
+        if self.can_modify():
+            self.node = node
+        else:
+            self.node = None
 
-        def init_snippet_data(self, node):
-                if node == None:
-                        return
+        self.init_snippet_data(node)
 
-                self.override = node.attrib.get('override')
+    def init_snippet_data(self, node):
+        if node == None:
+            return
 
-                self.properties = {}
-                props = SnippetData.PROPS.copy()
+        self.override = node.attrib.get('override')
 
-                # Store all properties present
-                for child in node:
-                        if child.tag in props:
-                                del props[child.tag]
+        self.properties = {}
+        props = SnippetData.PROPS.copy()
 
-                                # Normalize accelerator
-                                if child.tag == 'accelerator' and child.text != None:
-                                        keyval, mod = Gtk.accelerator_parse(child.text)
+        # Store all properties present
+        for child in node:
+            if child.tag in props:
+                del props[child.tag]
 
-                                        if Gtk.accelerator_valid(keyval, mod):
-                                                child.text = Gtk.accelerator_name(keyval, mod)
-                                        else:
-                                                child.text = ''
+                # Normalize accelerator
+                if child.tag == 'accelerator' and child.text != None:
+                    keyval, mod = Gtk.accelerator_parse(child.text)
 
-                                if self.can_modify():
-                                        self.properties[child.tag] = child
-                                else:
-                                        self.properties[child.tag] = child.text or ''
+                    if Gtk.accelerator_valid(keyval, mod):
+                        child.text = Gtk.accelerator_name(keyval, mod)
+                    else:
+                        child.text = ''
 
-                # Create all the props that were not found so we stay consistent
-                for prop in props:
-                        if self.can_modify():
-                                child = et.SubElement(node, prop)
+                if self.can_modify():
+                    self.properties[child.tag] = child
+                else:
+                    self.properties[child.tag] = child.text or ''
 
-                                child.text = props[prop]
-                                self.properties[prop] = child
-                        else:
-                                self.properties[prop] = props[prop]
+        # Create all the props that were not found so we stay consistent
+        for prop in props:
+            if self.can_modify():
+                child = et.SubElement(node, prop)
 
-                self.check_validation()
+                child.text = props[prop]
+                self.properties[prop] = child
+            else:
+                self.properties[prop] = props[prop]
+
+        self.check_validation()
 
-        def check_validation(self):
-                if not self['tag'] and not self['accelerator'] and not self['drop-targets']:
-                        return False
+    def check_validation(self):
+        if not self['tag'] and not self['accelerator'] and not self['drop-targets']:
+            return False
 
-                library = Library()
-                keyval, mod = Gtk.accelerator_parse(self['accelerator'])
+        library = Library()
+        keyval, mod = Gtk.accelerator_parse(self['accelerator'])
 
-                self.valid = library.valid_tab_trigger(self['tag']) and \
-                                (not self['accelerator'] or library.valid_accelerator(keyval, mod))
+        self.valid = library.valid_tab_trigger(self['tag']) and \
+                (not self['accelerator'] or library.valid_accelerator(keyval, mod))
 
-        def _format_prop(self, prop, value):
-                if prop == 'drop-targets' and value != '':
-                        return re.split('\\s*[,;]\\s*', value)
-                else:
-                        return value
+    def _format_prop(self, prop, value):
+        if prop == 'drop-targets' and value != '':
+            return re.split('\\s*[,;]\\s*', value)
+        else:
+            return value
 
-        def __getitem__(self, prop):
-                if prop in self.properties:
-                        if self.can_modify():
-                                return self._format_prop(prop, self.properties[prop].text or '')
-                        else:
-                                return self._format_prop(prop, self.properties[prop] or '')
+    def __getitem__(self, prop):
+        if prop in self.properties:
+            if self.can_modify():
+                return self._format_prop(prop, self.properties[prop].text or '')
+            else:
+                return self._format_prop(prop, self.properties[prop] or '')
 
-                return self._format_prop(prop, '')
+        return self._format_prop(prop, '')
 
-        def __setitem__(self, prop, value):
-                if not prop in self.properties:
-                        return
+    def __setitem__(self, prop, value):
+        if not prop in self.properties:
+            return
 
-                if isinstance(value, list):
-                        value = ','.join(value)
+        if isinstance(value, list):
+            value = ','.join(value)
 
-                if not self.can_modify() and self.properties[prop] != value:
-                        # ohoh, this is not can_modify, but it needs to be changed...
-                        # make sure it is transfered to the changes file and set all the
-                        # fields.
-                        # This snippet data container will effectively become the container
-                        # for the newly created node, but transparently to whoever uses
-                        # it
-                        self._override()
+        if not self.can_modify() and self.properties[prop] != value:
+            # ohoh, this is not can_modify, but it needs to be changed...
+            # make sure it is transfered to the changes file and set all the
+            # fields.
+            # This snippet data container will effectively become the container
+            # for the newly created node, but transparently to whoever uses
+            # it
+            self._override()
 
-                if self.can_modify() and self.properties[prop].text != value:
-                        if self.library():
-                                self.library().tainted = True
+        if self.can_modify() and self.properties[prop].text != value:
+            if self.library():
+                self.library().tainted = True
 
-                        oldvalue = self.properties[prop].text
-                        self.properties[prop].text = value
+            oldvalue = self.properties[prop].text
+            self.properties[prop].text = value
 
-                        if prop == 'tag' or prop == 'accelerator' or prop == 'drop-targets':
-                                container = Library().container(self.language())
-                                container.prop_changed(self, prop, oldvalue)
+            if prop == 'tag' or prop == 'accelerator' or prop == 'drop-targets':
+                container = Library().container(self.language())
+                container.prop_changed(self, prop, oldvalue)
 
-                self.check_validation()
+        self.check_validation()
 
-        def language(self):
-                if self.library and self.library():
-                        return self.library().language
-                else:
-                        return None
+    def language(self):
+        if self.library and self.library():
+            return self.library().language
+        else:
+            return None
 
-        def is_override(self):
-                return self.override and Library().overridden[self.override]
+    def is_override(self):
+        return self.override and Library().overridden[self.override]
 
-        def to_xml(self):
-                return self._create_xml()
+    def to_xml(self):
+        return self._create_xml()
 
-        def _create_xml(self, parent=None, update=False, attrib={}):
-                # Create a new node
-                if parent != None:
-                        element = et.SubElement(parent, 'snippet', attrib)
-                else:
-                        element = et.Element('snippet')
+    def _create_xml(self, parent=None, update=False, attrib={}):
+        # Create a new node
+        if parent != None:
+            element = et.SubElement(parent, 'snippet', attrib)
+        else:
+            element = et.Element('snippet')
 
-                # Create all the properties
-                for p in self.properties:
-                        prop = et.SubElement(element, p)
-                        prop.text = self[p]
+        # Create all the properties
+        for p in self.properties:
+            prop = et.SubElement(element, p)
+            prop.text = self[p]
 
-                        if update:
-                                self.properties[p] = prop
+            if update:
+                self.properties[p] = prop
 
-                return element
+        return element
 
-        def _override(self):
-                # Find the user file
-                target = Library().get_user_library(self.language())
+    def _override(self):
+        # Find the user file
+        target = Library().get_user_library(self.language())
 
-                # Create a new node there with override
-                element = self._create_xml(target.root, True, {'override': self.id})
+        # Create a new node there with override
+        element = self._create_xml(target.root, True, {'override': self.id})
 
-                # Create an override snippet data, feed it element so that it stores
-                # all the values and then set the node to None so that it only contains
-                # the values in .properties
-                override = SnippetData(element, self.library())
-                override.set_node(None)
-                override.id = self.id
+        # Create an override snippet data, feed it element so that it stores
+        # all the values and then set the node to None so that it only contains
+        # the values in .properties
+        override = SnippetData(element, self.library())
+        override.set_node(None)
+        override.id = self.id
 
-                # Set our node to the new element
-                self.node = element
+        # Set our node to the new element
+        self.node = element
 
-                # Set the override to our id
-                self.override = self.id
-                self.id = None
+        # Set the override to our id
+        self.override = self.id
+        self.id = None
 
-                # Set the new library
-                self.set_library(target)
+        # Set the new library
+        self.set_library(target)
 
-                # The library is tainted because we added this snippet
-                target.tainted = True
+        # The library is tainted because we added this snippet
+        target.tainted = True
 
-                # Add the override
-                Library().overridden[self.override] = override
+        # Add the override
+        Library().overridden[self.override] = override
 
-        def revert(self, snippet):
-                userlib = self.library()
-                self.set_library(snippet.library())
+    def revert(self, snippet):
+        userlib = self.library()
+        self.set_library(snippet.library())
 
-                userlib.remove(self.node)
+        userlib.remove(self.node)
 
-                self.set_node(None)
+        self.set_node(None)
 
-                # Copy the properties
-                self.properties = snippet.properties
+        # Copy the properties
+        self.properties = snippet.properties
 
-                # Set the id
-                self.id = snippet.id
+        # Set the id
+        self.id = snippet.id
 
-                # Reset the override flag
-                self.override = None
+        # Reset the override flag
+        self.override = None
 
 class SnippetsTreeBuilder(et.TreeBuilder):
-        def __init__(self, start=None, end=None):
-                et.TreeBuilder.__init__(self)
-                self.set_start(start)
-                self.set_end(end)
+    def __init__(self, start=None, end=None):
+        et.TreeBuilder.__init__(self)
+        self.set_start(start)
+        self.set_end(end)
 
-        def set_start(self, start):
-                self._start_cb = start
+    def set_start(self, start):
+        self._start_cb = start
 
-        def set_end(self, end):
-                self._end_cb = end
+    def set_end(self, end):
+        self._end_cb = end
 
-        def start(self, tag, attrs):
-                result = et.TreeBuilder.start(self, tag, attrs)
+    def start(self, tag, attrs):
+        result = et.TreeBuilder.start(self, tag, attrs)
 
-                if self._start_cb:
-                        self._start_cb(result)
+        if self._start_cb:
+            self._start_cb(result)
 
-                return result
+        return result
 
-        def end(self, tag):
-                result = et.TreeBuilder.end(self, tag)
+    def end(self, tag):
+        result = et.TreeBuilder.end(self, tag)
 
-                if self._end_cb:
-                        self._end_cb(result)
+        if self._end_cb:
+            self._end_cb(result)
 
-                return result
+        return result
 
 class LanguageContainer:
-        def __init__(self, language):
-                self.language = language
-                self.snippets = []
-                self.snippets_by_prop = {'tag': {}, 'accelerator': {}, 'drop-targets': {}}
-                self.accel_group = Gtk.AccelGroup()
-                self._refs = 0
+    def __init__(self, language):
+        self.language = language
+        self.snippets = []
+        self.snippets_by_prop = {'tag': {}, 'accelerator': {}, 'drop-targets': {}}
+        self.accel_group = Gtk.AccelGroup()
+        self._refs = 0
 
-        def _add_prop(self, snippet, prop, value=0):
-                if value == 0:
-                        value = snippet[prop]
+    def _add_prop(self, snippet, prop, value=0):
+        if value == 0:
+            value = snippet[prop]
 
-                if not value or value == '':
-                        return
+        if not value or value == '':
+            return
 
-                snippets_debug('Added ', prop ,' ', value, ' to ', str(self.language))
+        helper.snippets_debug('Added ', prop ,' ', value, ' to ', str(self.language))
 
-                if prop == 'accelerator':
-                        keyval, mod = Gtk.accelerator_parse(value)
-                        self.accel_group.connect(keyval, mod, 0, \
-                                        Library().accelerator_activated)
+        if prop == 'accelerator':
+            keyval, mod = Gtk.accelerator_parse(value)
+            self.accel_group.connect(keyval, mod, 0, \
+                    Library().accelerator_activated)
 
-                snippets = self.snippets_by_prop[prop]
+        snippets = self.snippets_by_prop[prop]
 
-                if not isinstance(value, list):
-                        value = [value]
+        if not isinstance(value, list):
+            value = [value]
 
-                for val in value:
-                        if val in snippets:
-                                snippets[val].append(snippet)
-                        else:
-                                snippets[val] = [snippet]
+        for val in value:
+            if val in snippets:
+                snippets[val].append(snippet)
+            else:
+                snippets[val] = [snippet]
 
-        def _remove_prop(self, snippet, prop, value=0):
-                if value == 0:
-                        value = snippet[prop]
+    def _remove_prop(self, snippet, prop, value=0):
+        if value == 0:
+            value = snippet[prop]
 
-                if not value or value == '':
-                        return
+        if not value or value == '':
+            return
 
-                snippets_debug('Removed ', prop, ' ', value, ' from ', str(self.language))
+        helper.snippets_debug('Removed ', prop, ' ', value, ' from ', str(self.language))
 
-                if prop == 'accelerator':
-                        keyval, mod = Gtk.accelerator_parse(value)
-                        self.accel_group.disconnect_key(keyval, mod)
+        if prop == 'accelerator':
+            keyval, mod = Gtk.accelerator_parse(value)
+            self.accel_group.disconnect_key(keyval, mod)
 
-                snippets = self.snippets_by_prop[prop]
+        snippets = self.snippets_by_prop[prop]
 
-                if not isinstance(value, list):
-                        value = [value]
+        if not isinstance(value, list):
+            value = [value]
 
-                for val in value:
-                        try:
-                                snippets[val].remove(snippet)
-                        except:
-                                True
+        for val in value:
+            try:
+                snippets[val].remove(snippet)
+            except:
+                True
 
-        def append(self, snippet):
-                tag = snippet['tag']
-                accelerator = snippet['accelerator']
+    def append(self, snippet):
+        self.snippets.append(snippet)
 
-                self.snippets.append(snippet)
+        self._add_prop(snippet, 'tag')
+        self._add_prop(snippet, 'accelerator')
+        self._add_prop(snippet, 'drop-targets')
 
-                self._add_prop(snippet, 'tag')
-                self._add_prop(snippet, 'accelerator')
-                self._add_prop(snippet, 'drop-targets')
+        return snippet
 
-                return snippet
+    def remove(self, snippet):
+        try:
+            self.snippets.remove(snippet)
+        except:
+            True
 
-        def remove(self, snippet):
-                try:
-                        self.snippets.remove(snippet)
-                except:
-                        True
+        self._remove_prop(snippet, 'tag')
+        self._remove_prop(snippet, 'accelerator')
+        self._remove_prop(snippet, 'drop-targets')
 
-                self._remove_prop(snippet, 'tag')
-                self._remove_prop(snippet, 'accelerator')
-                self._remove_prop(snippet, 'drop-targets')
+    def prop_changed(self, snippet, prop, oldvalue):
+        helper.snippets_debug('PROP CHANGED (', prop, ')', oldvalue)
 
-        def prop_changed(self, snippet, prop, oldvalue):
-                snippets_debug('PROP CHANGED (', prop, ')', oldvalue)
+        self._remove_prop(snippet, prop, oldvalue)
+        self._add_prop(snippet, prop)
 
-                self._remove_prop(snippet, prop, oldvalue)
-                self._add_prop(snippet, prop)
+    def from_prop(self, prop, value):
+        snippets = self.snippets_by_prop[prop]
 
-        def from_prop(self, prop, value):
-                snippets = self.snippets_by_prop[prop]
+        if prop == 'drop-targets':
+            s = []
 
-                if prop == 'drop-targets':
-                        s = []
+            # FIXME: change this to use
+            # gnomevfs.mime_type_get_equivalence when it comes
+            # available
+            for key, val in snippets.items():
+                if not value.startswith(key):
+                    continue
 
-                        # FIXME: change this to use
-                        # gnomevfs.mime_type_get_equivalence when it comes
-                        # available
-                        for key, val in snippets.items():
-                                if not value.startswith(key):
-                                        continue
+                for snippet in snippets[key]:
+                    if not snippet in s:
+                        s.append(snippet)
 
-                                for snippet in snippets[key]:
-                                        if not snippet in s:
-                                                s.append(snippet)
+            return s
+        else:
+            if value in snippets:
+                return snippets[value]
+            else:
+                return []
 
-                        return s
-                else:
-                        if value in snippets:
-                                return snippets[value]
-                        else:
-                                return []
-
-        def ref(self):
-                self._refs += 1
+    def ref(self):
+        self._refs += 1
 
-                return True
+        return True
 
-        def unref(self):
-                if self._refs > 0:
-                        self._refs -= 1
+    def unref(self):
+        if self._refs > 0:
+            self._refs -= 1
 
-                return self._refs != 0
+        return self._refs != 0
 
 class SnippetsSystemFile:
-        def __init__(self, path=None):
-                self.path = path
-                self.loaded = False
-                self.language = None
-                self.ok = True
-                self.need_id = True
-
-        def load_error(self, message):
-                sys.stderr.write("An error occurred loading " + self.path + ":\n")
-                sys.stderr.write(message + "\nSnippets in this file will not be " \
-                                "available, please correct or remove the file.\n")
-
-        def _add_snippet(self, element):
-                if not self.need_id or element.attrib.get('id'):
-                        self.loading_elements.append(element)
-
-        def set_language(self, element):
-                self.language = element.attrib.get('language')
-
-                if self.language:
-                        self.language = self.language.lower()
-
-        def _set_root(self, element):
-                self.set_language(element)
-
-        def _preprocess_element(self, element):
-                if not self.loaded:
-                        if not element.tag == "snippets":
-                                self.load_error("Root element should be `snippets' instead " \
-                                                "of `%s'" % element.tag)
-                                return False
-                        else:
-                                self._set_root(element)
-                                self.loaded = True
-                elif element.tag != 'snippet' and not self.insnippet:
-                        self.load_error("Element should be `snippet' instead of `%s'" \
-                                        % element.tag)
-                        return False
-                else:
-                        self.insnippet = True
-
-                return True
-
-        def _process_element(self, element):
-                if element.tag == 'snippet':
-                        self._add_snippet(element)
-                        self.insnippet = False
-
-                return True
-
-        def ensure(self):
-                if not self.ok or self.loaded:
-                        return
-
-                self.load()
-
-        def parse_xml(self, readsize=16384):
-                if not self.path:
-                        return
+    def __init__(self, path=None):
+        self.path = path
+        self.loaded = False
+        self.language = None
+        self.ok = True
+        self.need_id = True
+
+    def load_error(self, message):
+        sys.stderr.write("An error occurred loading " + self.path + ":\n")
+        sys.stderr.write(message + "\nSnippets in this file will not be " \
+                "available, please correct or remove the file.\n")
+
+    def _add_snippet(self, element):
+        if not self.need_id or element.attrib.get('id'):
+            self.loading_elements.append(element)
+
+    def set_language(self, element):
+        self.language = element.attrib.get('language')
+
+        if self.language:
+            self.language = self.language.lower()
+
+    def _set_root(self, element):
+        self.set_language(element)
+
+    def _preprocess_element(self, element):
+        if not self.loaded:
+            if not element.tag == "snippets":
+                self.load_error("Root element should be `snippets' instead " \
+                        "of `%s'" % element.tag)
+                return False
+            else:
+                self._set_root(element)
+                self.loaded = True
+        elif element.tag != 'snippet' and not self.insnippet:
+            self.load_error("Element should be `snippet' instead of `%s'" \
+                    % element.tag)
+            return False
+        else:
+            self.insnippet = True
 
-                elements = []
+        return True
 
-                builder = SnippetsTreeBuilder( \
-                                lambda node: elements.append((node, True)), \
-                                lambda node: elements.append((node, False)))
+    def _process_element(self, element):
+        if element.tag == 'snippet':
+            self._add_snippet(element)
+            self.insnippet = False
 
-                parser = et.XMLParser(target=builder)
-                self.insnippet = False
+        return True
 
-                try:
-                        f = open(self.path, "r")
-                except IOError:
-                        self.ok = False
-                        return
+    def ensure(self):
+        if not self.ok or self.loaded:
+            return
 
-                while True:
-                        try:
-                                data = f.read(readsize)
-                        except IOError:
-                                self.ok = False
-                                break
+        self.load()
 
-                        if not data:
-                                break
+    def parse_xml(self, readsize=16384):
+        if not self.path:
+            return
 
-                        try:
-                                parser.feed(data)
-                        except Exception:
-                                self.ok = False
-                                break
+        elements = []
 
-                        for element in elements:
-                                yield element
+        builder = SnippetsTreeBuilder( \
+                lambda node: elements.append((node, True)), \
+                lambda node: elements.append((node, False)))
 
-                        del elements[:]
+        parser = et.XMLParser(target=builder)
+        self.insnippet = False
 
-                f.close()
+        try:
+            f = open(self.path, "r")
+        except IOError:
+            self.ok = False
+            return
 
-        def load(self):
-                if not self.ok:
-                        return
+        while True:
+            try:
+                data = f.read(readsize)
+            except IOError:
+                self.ok = False
+                break
 
-                snippets_debug("Loading library (" + str(self.language) + "): " + \
-                                self.path)
+            if not data:
+                break
 
-                self.loaded = False
+            try:
+                parser.feed(data)
+            except Exception:
                 self.ok = False
-                self.loading_elements = []
-
-                for element in self.parse_xml():
-                        if element[1]:
-                                if not self._preprocess_element(element[0]):
-                                        del self.loading_elements[:]
-                                        return
-                        else:
-                                if not self._process_element(element[0]):
-                                        del self.loading_elements[:]
-                                        return
-
-                for element in self.loading_elements:
-                        snippet = Library().add_snippet(self, element)
-
-                del self.loading_elements[:]
-                self.ok = True
-
-        # This function will get the language for a file by just inspecting the
-        # root element of the file. This is provided so that a cache can be built
-        # for which file contains which language.
-        # It returns the name of the language
-        def ensure_language(self):
-                if not self.loaded:
-                        self.ok = False
-
-                        for element in self.parse_xml(256):
-                                if element[1]:
-                                        if element[0].tag == 'snippets':
-                                                self.set_language(element[0])
-                                                self.ok = True
-
-                                        break
-
-        def unload(self):
-                snippets_debug("Unloading library (" + str(self.language) + "): " + \
-                                self.path)
-                self.language = None
-                self.loaded = False
-                self.ok = True
+                break
 
-class SnippetsUserFile(SnippetsSystemFile):
-        def __init__(self, path=None):
-                SnippetsSystemFile.__init__(self, path)
-                self.tainted = False
-                self.need_id = False
+            for element in elements:
+                yield element
 
-        def _set_root(self, element):
-                SnippetsSystemFile._set_root(self, element)
-                self.root = element
+            del elements[:]
 
-        def add_prop(self, node, tag, data):
-                if data[tag]:
-                        prop = et.SubElement(node, tag)
-                        prop.text = data[tag]
+        f.close()
 
-                        return prop
-                else:
-                        return None
+    def load(self):
+        if not self.ok:
+            return
 
-        def new_snippet(self, properties=None):
-                if (not self.ok) or self.root == None:
-                        return None
+        helper.snippets_debug("Loading library (" + str(self.language) + "): " + \
+                self.path)
 
-                element = et.SubElement(self.root, 'snippet')
+        self.loaded = False
+        self.ok = False
+        self.loading_elements = []
 
-                if properties:
-                        for prop in properties:
-                                sub = et.SubElement(element, prop)
-                                sub.text = properties[prop]
+        for element in self.parse_xml():
+            if element[1]:
+                if not self._preprocess_element(element[0]):
+                    del self.loading_elements[:]
+                    return
+            else:
+                if not self._process_element(element[0]):
+                    del self.loading_elements[:]
+                    return
 
-                self.tainted = True
+        for element in self.loading_elements:
+            Library().add_snippet(self, element)
 
-                return Library().add_snippet(self, element)
+        del self.loading_elements[:]
+        self.ok = True
 
-        def set_language(self, element):
-                SnippetsSystemFile.set_language(self, element)
+    # This function will get the language for a file by just inspecting the
+    # root element of the file. This is provided so that a cache can be built
+    # for which file contains which language.
+    # It returns the name of the language
+    def ensure_language(self):
+        if not self.loaded:
+            self.ok = False
 
-                filename = os.path.basename(self.path).lower()
+            for element in self.parse_xml(256):
+                if element[1]:
+                    if element[0].tag == 'snippets':
+                        self.set_language(element[0])
+                        self.ok = True
 
-                if not self.language and filename == "global.xml":
-                        self.modifier = True
-                elif self.language and filename == self.language + ".xml":
-                        self.modifier = True
-                else:
-                        self.modifier = False
+                    break
 
-        def create_root(self, language):
-                if self.loaded:
-                        snippets_debug('Not creating root, already loaded')
-                        return
+    def unload(self):
+        helper.snippets_debug("Unloading library (" + str(self.language) + "): " + \
+                self.path)
+        self.language = None
+        self.loaded = False
+        self.ok = True
 
-                if language:
-                        root = et.Element('snippets', {'language': language})
-                        self.path = os.path.join(Library().userdir, language.lower() + '.xml')
-                else:
-                        root = et.Element('snippets')
-                        self.path = os.path.join(Library().userdir, 'global.xml')
-
-                self._set_root(root)
-                self.loaded = True
-                self.ok = True
-                self.tainted = True
-                self.save()
-
-        def remove(self, element):
-                try:
-                        self.root.remove(element)
-                        self.tainted = True
-                except:
-                        return
-
-                try:
-                        first = self.root[0]
-                except:
-                        # No more elements, this library is useless now
-                        Library().remove_library(self)
-
-        def save(self):
-                if not self.ok or self.root == None or not self.tainted:
-                        return
-
-                path = os.path.dirname(self.path)
-
-                try:
-                        if not os.path.isdir(path):
-                                os.makedirs(path, 0o755)
-                except OSError:
-                        # TODO: this is bad...
-                        sys.stderr.write("Error in making dirs\n")
-
-                try:
-                        write_xml(self.root, self.path, ('text', 'accelerator'))
-                        self.tainted = False
-                except IOError:
-                        # Couldn't save, what to do
-                        sys.stderr.write("Could not save user snippets file to " + \
-                                        self.path + "\n")
-
-        def unload(self):
-                SnippetsSystemFile.unload(self)
-                self.root = None
+class SnippetsUserFile(SnippetsSystemFile):
+    def __init__(self, path=None):
+        SnippetsSystemFile.__init__(self, path)
+        self.tainted = False
+        self.need_id = False
+
+    def _set_root(self, element):
+        SnippetsSystemFile._set_root(self, element)
+        self.root = element
+
+    def add_prop(self, node, tag, data):
+        if data[tag]:
+            prop = et.SubElement(node, tag)
+            prop.text = data[tag]
+
+            return prop
+        else:
+            return None
+
+    def new_snippet(self, properties=None):
+        if (not self.ok) or self.root == None:
+            return None
+
+        element = et.SubElement(self.root, 'snippet')
+
+        if properties:
+            for prop in properties:
+                sub = et.SubElement(element, prop)
+                sub.text = properties[prop]
+
+        self.tainted = True
+
+        return Library().add_snippet(self, element)
+
+    def set_language(self, element):
+        SnippetsSystemFile.set_language(self, element)
+
+        filename = os.path.basename(self.path).lower()
+
+        if not self.language and filename == "global.xml":
+            self.modifier = True
+        elif self.language and filename == self.language + ".xml":
+            self.modifier = True
+        else:
+            self.modifier = False
+
+    def create_root(self, language):
+        if self.loaded:
+            helper.snippets_debug('Not creating root, already loaded')
+            return
+
+        if language:
+            root = et.Element('snippets', {'language': language})
+            self.path = os.path.join(Library().userdir, language.lower() + '.xml')
+        else:
+            root = et.Element('snippets')
+            self.path = os.path.join(Library().userdir, 'global.xml')
+
+        self._set_root(root)
+        self.loaded = True
+        self.ok = True
+        self.tainted = True
+        self.save()
+
+    def remove(self, element):
+        try:
+            self.root.remove(element)
+            self.tainted = True
+        except:
+            return
+
+        try:
+            self.root[0]
+        except:
+            # No more elements, this library is useless now
+            Library().remove_library(self)
+
+    def save(self):
+        if not self.ok or self.root == None or not self.tainted:
+            return
+
+        path = os.path.dirname(self.path)
+
+        try:
+            if not os.path.isdir(path):
+                os.makedirs(path, 0o755)
+        except OSError:
+            # TODO: this is bad...
+            sys.stderr.write("Error in making dirs\n")
+
+        try:
+            helper.write_xml(self.root, self.path, ('text', 'accelerator'))
+            self.tainted = False
+        except IOError:
+            # Couldn't save, what to do
+            sys.stderr.write("Could not save user snippets file to " + \
+                    self.path + "\n")
+
+    def unload(self):
+        SnippetsSystemFile.unload(self)
+        self.root = None
 
 class Singleton(object):
-        _instance = None
+    _instance = None
 
-        def __new__(cls, *args, **kwargs):
-                if not cls._instance:
-                        cls._instance = super(Singleton, cls).__new__(
-                                         cls, *args, **kwargs)
-                        cls._instance.__init_once__()
+    def __new__(cls, *args, **kwargs):
+        if not cls._instance:
+            cls._instance = super(Singleton, cls).__new__(
+                     cls, *args, **kwargs)
+            cls._instance.__init_once__()
 
-                return cls._instance
+        return cls._instance
 
 class Library(Singleton):
-        def __init_once__(self):
-                self._accelerator_activated_cb = []
-                self.loaded = False
-                self.check_buffer = Gtk.TextBuffer()
+    def __init_once__(self):
+        self._accelerator_activated_cb = []
+        self.loaded = False
+        self.check_buffer = Gtk.TextBuffer()
 
-        def set_dirs(self, userdir, systemdirs):
-                self.userdir = userdir
-                self.systemdirs = systemdirs
+    def set_dirs(self, userdir, systemdirs):
+        self.userdir = userdir
+        self.systemdirs = systemdirs
 
-                self.libraries = {}
-                self.containers = {}
-                self.overridden = {}
-                self.loaded_ids = []
+        self.libraries = {}
+        self.containers = {}
+        self.overridden = {}
+        self.loaded_ids = []
 
-                self.loaded = False
+        self.loaded = False
 
-        def add_accelerator_callback(self, cb):
-                self._accelerator_activated_cb.append(cb)
+    def add_accelerator_callback(self, cb):
+        self._accelerator_activated_cb.append(cb)
 
-        def remove_accelerator_callback(self, cb):
-                self._accelerator_activated_cb.remove(cb)
+    def remove_accelerator_callback(self, cb):
+        self._accelerator_activated_cb.remove(cb)
 
-        def accelerator_activated(self, group, obj, keyval, mod):
-                ret = False
+    def accelerator_activated(self, group, obj, keyval, mod):
+        ret = False
 
-                for cb in self._accelerator_activated_cb:
-                        ret = cb(group, obj, keyval, mod)
+        for cb in self._accelerator_activated_cb:
+            ret = cb(group, obj, keyval, mod)
 
-                        if ret:
-                                break
+            if ret:
+                break
 
-                return ret
+        return ret
 
-        def add_snippet(self, library, element):
-                container = self.container(library.language)
-                overrided = self.overrided(library, element)
+    def add_snippet(self, library, element):
+        container = self.container(library.language)
+        overrided = self.overrided(library, element)
 
-                if overrided:
-                        overrided.set_library(library)
-                        snippets_debug('Snippet is overriden: ' + overrided['description'])
-                        return None
+        if overrided:
+            overrided.set_library(library)
+            helper.snippets_debug('Snippet is overriden: ' + overrided['description'])
+            return None
 
-                snippet = SnippetData(element, library)
+        snippet = SnippetData(element, library)
 
-                if snippet.id in self.loaded_ids:
-                        snippets_debug('Not added snippet ' + str(library.language) + \
-                                        '::' + snippet['description'] + ' (duplicate)')
-                        return None
+        if snippet.id in self.loaded_ids:
+            helper.snippets_debug('Not added snippet ' + str(library.language) + \
+                    '::' + snippet['description'] + ' (duplicate)')
+            return None
 
-                snippet = container.append(snippet)
-                snippets_debug('Added snippet ' + str(library.language) + '::' + \
-                                snippet['description'])
+        snippet = container.append(snippet)
+        helper.snippets_debug('Added snippet ' + str(library.language) + '::' + \
+                snippet['description'])
 
-                if snippet and snippet.override:
-                        self.add_override(snippet)
+        if snippet and snippet.override:
+            self.add_override(snippet)
 
-                if snippet.id:
-                        self.loaded_ids.append(snippet.id)
+        if snippet.id:
+            self.loaded_ids.append(snippet.id)
 
-                return snippet
+        return snippet
 
-        def container(self, language):
-                language = self.normalize_language(language)
+    def container(self, language):
+        language = self.normalize_language(language)
 
-                if not language in self.containers:
-                        self.containers[language] = LanguageContainer(language)
+        if not language in self.containers:
+            self.containers[language] = LanguageContainer(language)
 
-                return self.containers[language]
+        return self.containers[language]
 
-        def get_user_library(self, language):
-                target = None
+    def get_user_library(self, language):
+        target = None
 
-                if language in self.libraries:
-                        for library in self.libraries[language]:
-                                if isinstance(library, SnippetsUserFile) and library.modifier:
-                                        target = library
-                                elif not isinstance(library, SnippetsUserFile):
-                                        break
+        if language in self.libraries:
+            for library in self.libraries[language]:
+                if isinstance(library, SnippetsUserFile) and library.modifier:
+                    target = library
+                elif not isinstance(library, SnippetsUserFile):
+                    break
 
-                if not target:
-                        # Create a new user file then
-                        snippets_debug('Creating a new user file for language ' + \
-                                        str(language))
-                        target = SnippetsUserFile()
-                        target.create_root(language)
-                        self.add_library(target)
+        if not target:
+            # Create a new user file then
+            helper.snippets_debug('Creating a new user file for language ' + \
+                    str(language))
+            target = SnippetsUserFile()
+            target.create_root(language)
+            self.add_library(target)
 
-                return target
+        return target
 
-        def new_snippet(self, language, properties=None):
-                language = self.normalize_language(language)
-                library = self.get_user_library(language)
+    def new_snippet(self, language, properties=None):
+        language = self.normalize_language(language)
+        library = self.get_user_library(language)
 
-                return library.new_snippet(properties)
+        return library.new_snippet(properties)
 
-        def revert_snippet(self, snippet):
-                # This will revert the snippet to the one it overrides
-                if not snippet.can_modify() or not snippet.override in self.overridden:
-                        # It can't be reverted, shouldn't happen, but oh..
-                        return
+    def revert_snippet(self, snippet):
+        # This will revert the snippet to the one it overrides
+        if not snippet.can_modify() or not snippet.override in self.overridden:
+            # It can't be reverted, shouldn't happen, but oh..
+            return
 
-                # The snippet in self.overriden only contains the property contents and
-                # the library it belongs to
-                revertto = self.overridden[snippet.override]
-                del self.overridden[snippet.override]
+        # The snippet in self.overriden only contains the property contents and
+        # the library it belongs to
+        revertto = self.overridden[snippet.override]
+        del self.overridden[snippet.override]
 
-                if revertto:
-                        snippet.revert(revertto)
+        if revertto:
+            snippet.revert(revertto)
 
-                        if revertto.id:
-                                self.loaded_ids.append(revertto.id)
+            if revertto.id:
+                self.loaded_ids.append(revertto.id)
 
-        def remove_snippet(self, snippet):
-                if not snippet.can_modify() or snippet.is_override():
-                        return
+    def remove_snippet(self, snippet):
+        if not snippet.can_modify() or snippet.is_override():
+            return
 
-                # Remove from the library
-                userlib = snippet.library()
-                userlib.remove(snippet.node)
+        # Remove from the library
+        userlib = snippet.library()
+        userlib.remove(snippet.node)
 
-                # Remove from the container
-                container = self.containers[userlib.language]
-                container.remove(snippet)
+        # Remove from the container
+        container = self.containers[userlib.language]
+        container.remove(snippet)
 
-        def overrided(self, library, element):
-                id = NamespacedId(library.language, element.attrib.get('id')).id
+    def overrided(self, library, element):
+        id = NamespacedId(library.language, element.attrib.get('id')).id
 
-                if id in self.overridden:
-                        snippet = SnippetData(element, None)
-                        snippet.set_node(None)
+        if id in self.overridden:
+            snippet = SnippetData(element, None)
+            snippet.set_node(None)
 
-                        self.overridden[id] = snippet
-                        return snippet
-                else:
-                        return None
+            self.overridden[id] = snippet
+            return snippet
+        else:
+            return None
 
-        def add_override(self, snippet):
-                snippets_debug('Add override:', snippet.override)
-                if not snippet.override in self.overridden:
-                        self.overridden[snippet.override] = None
+    def add_override(self, snippet):
+        helper.snippets_debug('Add override:', snippet.override)
+        if not snippet.override in self.overridden:
+            self.overridden[snippet.override] = None
 
-        def add_library(self, library):
-                library.ensure_language()
+    def add_library(self, library):
+        library.ensure_language()
 
-                if not library.ok:
-                        snippets_debug('Library in wrong format, ignoring')
-                        return False
+        if not library.ok:
+            helper.snippets_debug('Library in wrong format, ignoring')
+            return False
 
-                snippets_debug('Adding library (' + str(library.language) + '): ' + \
-                                library.path)
-
-                if library.language in self.libraries:
-                        # Make sure all the user files are before the system files
-                        if isinstance(library, SnippetsUserFile):
-                                self.libraries[library.language].insert(0, library)
-                        else:
-                                self.libraries[library.language].append(library)
-                else:
-                        self.libraries[library.language] = [library]
+        helper.snippets_debug('Adding library (' + str(library.language) + '): ' + \
+                library.path)
 
-                return True
+        if library.language in self.libraries:
+            # Make sure all the user files are before the system files
+            if isinstance(library, SnippetsUserFile):
+                self.libraries[library.language].insert(0, library)
+            else:
+                self.libraries[library.language].append(library)
+        else:
+            self.libraries[library.language] = [library]
 
-        def remove_library(self, library):
-                if not library.ok:
-                        return
+        return True
 
-                if library.path and os.path.isfile(library.path):
-                        os.unlink(library.path)
+    def remove_library(self, library):
+        if not library.ok:
+            return
 
-                try:
-                        self.libraries[library.language].remove(library)
-                except KeyError:
-                        True
+        if library.path and os.path.isfile(library.path):
+            os.unlink(library.path)
 
-                container = self.containers[library.language]
+        try:
+            self.libraries[library.language].remove(library)
+        except KeyError:
+            True
+
+        container = self.containers[library.language]
 
-                for snippet in list(container.snippets):
-                        if snippet.library() == library:
-                                container.remove(snippet)
+        for snippet in list(container.snippets):
+            if snippet.library() == library:
+                container.remove(snippet)
 
-        def add_user_library(self, path):
-                library = SnippetsUserFile(path)
-                return self.add_library(library)
+    def add_user_library(self, path):
+        library = SnippetsUserFile(path)
+        return self.add_library(library)
 
-        def add_system_library(self, path):
-                library = SnippetsSystemFile(path)
-                return self.add_library(library)
+    def add_system_library(self, path):
+        library = SnippetsSystemFile(path)
+        return self.add_library(library)
 
-        def find_libraries(self, path, searched, addcb):
-                snippets_debug("Finding in: " + path)
+    def find_libraries(self, path, searched, addcb):
+        helper.snippets_debug("Finding in: " + path)
 
-                if not os.path.isdir(path):
-                        return searched
+        if not os.path.isdir(path):
+            return searched
 
-                files = os.listdir(path)
-                searched.append(path)
+        files = os.listdir(path)
+        searched.append(path)
 
-                for f in files:
-                        f = os.path.realpath(os.path.join(path, f))
+        for f in files:
+            f = os.path.realpath(os.path.join(path, f))
 
-                        # Determine what language this file provides snippets for
-                        if os.path.isfile(f):
-                                addcb(f)
+            # Determine what language this file provides snippets for
+            if os.path.isfile(f):
+                addcb(f)
 
-                return searched
+        return searched
 
-        def normalize_language(self, language):
-                if language:
-                        return language.lower()
+    def normalize_language(self, language):
+        if language:
+            return language.lower()
 
-                return language
+        return language
 
-        def remove_container(self, language):
-                for snippet in self.containers[language].snippets:
-                        if snippet.id in self.loaded_ids:
-                                self.loaded_ids.remove(snippet.id)
+    def remove_container(self, language):
+        for snippet in self.containers[language].snippets:
+            if snippet.id in self.loaded_ids:
+                self.loaded_ids.remove(snippet.id)
 
-                        if snippet.override in self.overridden:
-                                del self.overridden[snippet.override]
+            if snippet.override in self.overridden:
+                del self.overridden[snippet.override]
 
-                del self.containers[language]
+        del self.containers[language]
 
-        def get_accel_group(self, language):
-                language = self.normalize_language(language)
-                container = self.container(language)
+    def get_accel_group(self, language):
+        language = self.normalize_language(language)
+        container = self.container(language)
 
-                self.ensure(language)
-                return container.accel_group
+        self.ensure(language)
+        return container.accel_group
 
-        def save(self, language):
-                language = self.normalize_language(language)
+    def save(self, language):
+        language = self.normalize_language(language)
 
-                if language in self.libraries:
-                        for library in self.libraries[language]:
-                                if isinstance(library, SnippetsUserFile):
-                                        library.save()
-                                else:
-                                        break
+        if language in self.libraries:
+            for library in self.libraries[language]:
+                if isinstance(library, SnippetsUserFile):
+                    library.save()
+                else:
+                    break
 
-        def ref(self, language):
-                language = self.normalize_language(language)
+    def ref(self, language):
+        language = self.normalize_language(language)
 
-                snippets_debug('Ref:', language)
-                self.container(language).ref()
+        helper.snippets_debug('Ref:', language)
+        self.container(language).ref()
 
-        def unref(self, language):
-                language = self.normalize_language(language)
+    def unref(self, language):
+        language = self.normalize_language(language)
 
-                snippets_debug('Unref:', language)
+        helper.snippets_debug('Unref:', language)
 
-                if language in self.containers:
-                        if not self.containers[language].unref() and \
-                                        language in self.libraries:
+        if language in self.containers:
+            if not self.containers[language].unref() and \
+                    language in self.libraries:
 
-                                for library in self.libraries[language]:
-                                        library.unload()
+                for library in self.libraries[language]:
+                    library.unload()
 
-                                self.remove_container(language)
+                self.remove_container(language)
 
-        def ensure(self, language):
-                self.ensure_files()
-                language = self.normalize_language(language)
+    def ensure(self, language):
+        self.ensure_files()
+        language = self.normalize_language(language)
 
-                # Ensure language as well as the global snippets (None)
-                for lang in (None, language):
-                        if lang in self.libraries:
-                                # Ensure the container exists
-                                self.container(lang)
+        # Ensure language as well as the global snippets (None)
+        for lang in (None, language):
+            if lang in self.libraries:
+                # Ensure the container exists
+                self.container(lang)
 
-                                for library in self.libraries[lang]:
-                                        library.ensure()
+                for library in self.libraries[lang]:
+                    library.ensure()
 
-        def ensure_files(self):
-                if self.loaded:
-                        return
+    def ensure_files(self):
+        if self.loaded:
+            return
 
-                searched = []
-                searched = self.find_libraries(self.userdir, searched, \
-                                self.add_user_library)
+        searched = []
+        searched = self.find_libraries(self.userdir, searched, \
+                self.add_user_library)
 
-                for d in self.systemdirs:
-                        searched = self.find_libraries(d, searched, \
-                                        self.add_system_library)
+        for d in self.systemdirs:
+            searched = self.find_libraries(d, searched, \
+                    self.add_system_library)
 
-                self.loaded = True
+        self.loaded = True
 
-        def valid_accelerator(self, keyval, mod):
-                mod &= Gtk.accelerator_get_default_mod_mask()
+    def valid_accelerator(self, keyval, mod):
+        mod &= Gtk.accelerator_get_default_mod_mask()
 
-                return (mod and (Gdk.keyval_to_unicode(keyval) or \
-                                keyval in range(Gdk.KEY_F1, Gdk.KEY_F12 + 1)))
+        return (mod and (Gdk.keyval_to_unicode(keyval) or \
+                keyval in range(Gdk.KEY_F1, Gdk.KEY_F12 + 1)))
 
-        def valid_tab_trigger(self, trigger):
-                if not trigger:
-                        return True
+    def valid_tab_trigger(self, trigger):
+        if not trigger:
+            return True
 
-                return is_tab_trigger(trigger)
+        return helper.is_tab_trigger(trigger)
 
-        # Snippet getters
-        # ===============
-        def _from_prop(self, prop, value, language=None):
-                self.ensure_files()
+    # Snippet getters
+    # ===============
+    def _from_prop(self, prop, value, language=None):
+        self.ensure_files()
 
-                result = []
-                language = self.normalize_language(language)
+        result = []
+        language = self.normalize_language(language)
 
-                if not language in self.containers:
-                        return []
+        if not language in self.containers:
+            return []
 
-                self.ensure(language)
-                result = self.containers[language].from_prop(prop, value)
+        self.ensure(language)
+        result = self.containers[language].from_prop(prop, value)
 
-                if len(result) == 0 and language and None in self.containers:
-                        result = self.containers[None].from_prop(prop, value)
+        if len(result) == 0 and language and None in self.containers:
+            result = self.containers[None].from_prop(prop, value)
 
-                return result
+        return result
 
-        # Get snippets for a given language
-        def get_snippets(self, language=None):
-                self.ensure_files()
-                language = self.normalize_language(language)
+    # Get snippets for a given language
+    def get_snippets(self, language=None):
+        self.ensure_files()
+        language = self.normalize_language(language)
 
-                if not language in self.libraries:
-                        return []
+        if not language in self.libraries:
+            return []
 
-                snippets = []
-                self.ensure(language)
+        self.ensure(language)
 
-                return list(self.containers[language].snippets)
+        return list(self.containers[language].snippets)
 
-        # Get snippets for a given accelerator
-        def from_accelerator(self, accelerator, language=None):
-                return self._from_prop('accelerator', accelerator, language)
+    # Get snippets for a given accelerator
+    def from_accelerator(self, accelerator, language=None):
+        return self._from_prop('accelerator', accelerator, language)
 
-        # Get snippets for a given tag
-        def from_tag(self, tag, language=None):
-                return self._from_prop('tag', tag, language)
+    # Get snippets for a given tag
+    def from_tag(self, tag, language=None):
+        return self._from_prop('tag', tag, language)
 
-        # Get snippets for a given drop target
-        def from_drop_target(self, drop_target, language=None):
-                return self._from_prop('drop-targets', drop_target, language)
+    # Get snippets for a given drop target
+    def from_drop_target(self, drop_target, language=None):
+        return self._from_prop('drop-targets', drop_target, language)
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/manager.py b/plugins/snippets/snippets/manager.py
index afef51f..3eb28e6 100644
--- a/plugins/snippets/snippets/manager.py
+++ b/plugins/snippets/snippets/manager.py
@@ -19,1123 +19,1117 @@ import os
 import tempfile
 import shutil
 
-from gi.repository import Gtk, Gio, Gdk, GtkSource, Gedit, GObject
+from gi.repository import Gtk, Gio, Gdk, GObject
 
 from .snippet import Snippet
-from .helper import *
-from .library import *
-from .importer import *
-from .exporter import *
-from .document import Document
+from . import helper
+from .library import Library
+from .importer import Importer
+from .exporter import Exporter
 from .languagemanager import get_language_manager
 
 class Manager(Gtk.Window, Gtk.Buildable):
-        NAME_COLUMN = 0
-        SORT_COLUMN = 1
-        LANG_COLUMN = 2
-        SNIPPET_COLUMN = 3
-        TARGET_URI = 105
+    NAME_COLUMN = 0
+    SORT_COLUMN = 1
+    LANG_COLUMN = 2
+    SNIPPET_COLUMN = 3
+    TARGET_URI = 105
 
-        __gtype_name__ = "GeditSnippetsManager"
+    __gtype_name__ = "GeditSnippetsManager"
 
-        model = None
-        drag_icons = ('gnome-mime-application-x-tarz', 'gnome-package', 'package')
-        default_export_name = _('Snippets archive') + '.tar.gz'
-        dragging = False
+    model = None
+    drag_icons = ('gnome-mime-application-x-tarz', 'gnome-package', 'package')
+    default_export_name = _('Snippets archive') + '.tar.gz'
+    dragging = False
 
-        def __init__(self):
-                self.snippet = None
-                self._temp_export = None
-                self._size = (0, 0)
+    def __init__(self):
+        self.snippet = None
+        self._temp_export = None
+        self._size = (0, 0)
 
-                self.key_press_id = 0
-                self.dnd_target_list = Gtk.TargetList.new([])
-                self.dnd_target_list.add(Gdk.atom_intern("text/uri-list", True), 0, self.TARGET_URI)
+        self.key_press_id = 0
+        self.dnd_target_list = Gtk.TargetList.new([])
+        self.dnd_target_list.add(Gdk.atom_intern("text/uri-list", True), 0, self.TARGET_URI)
 
-        def get_final_size(self):
-                return self._size
+    def get_final_size(self):
+        return self._size
 
-        def get_language_snippets(self, path, name = None):
-                library = Library()
+    def get_language_snippets(self, path, name = None):
+        library = Library()
 
-                name = self.get_language(path)
-                nodes = library.get_snippets(name)
+        name = self.get_language(path)
+        nodes = library.get_snippets(name)
 
-                return nodes
+        return nodes
 
-        def add_new_snippet_node(self, parent):
-                return self.model.append(parent, ('<i>' + _('Add a new snippet...') + \
-                                '</i>', '', None, None))
+    def add_new_snippet_node(self, parent):
+        return self.model.append(parent, ('<i>' + _('Add a new snippet...') + \
+                '</i>', '', None, None))
 
-        def fill_language(self, piter, expand=True):
-                # Remove all children
-                child = self.model.iter_children(piter)
+    def fill_language(self, piter, expand=True):
+        # Remove all children
+        child = self.model.iter_children(piter)
 
-                while child and self.model.remove(child):
-                        True
+        while child and self.model.remove(child):
+            True
 
-                path = self.model.get_path(piter)
-                nodes = self.get_language_snippets(path)
-                language = self.get_language(path)
+        path = self.model.get_path(piter)
+        nodes = self.get_language_snippets(path)
+        language = self.get_language(path)
 
-                Library().ref(language)
+        Library().ref(language)
 
-                if nodes:
-                        for node in nodes:
-                                self.add_snippet(piter, node)
-                else:
-                        # Add node that tells there are no snippets currently
-                        self.add_new_snippet_node(piter)
-
-                if expand:
-                        self.tree_view.expand_row(path, False)
-
-        def build_model(self, force_reload = False):
-                window = Gio.Application.get_default().get_active_window()
-                if window:
-                        view = window.get_active_view()
-
-                        if not view:
-                                current_lang = None
-                        else:
-                                current_lang = view.get_buffer().get_language()
-                                source_view = self['source_view_snippet']
-
-                else:
-                        current_lang = None
-
-                tree_view = self['tree_view_snippets']
-                expand = None
-
-                if not self.model or force_reload:
-                        self.model = Gtk.TreeStore(str, str, GObject.Object, object)
-                        self.model.set_sort_column_id(self.SORT_COLUMN, Gtk.SortType.ASCENDING)
-
-                        manager = get_language_manager()
-
-                        langs = [manager.get_language(x) for x in manager.get_language_ids()]
-                        langs.sort(key=lambda x: x.get_name())
-
-                        piter = self.model.append(None, (_('Global'), '', None, None))
-
-                        # Add dummy node
-                        self.model.append(piter, ('', '', None, None))
-
-                        nm = None
-
-                        if current_lang:
-                                nm = current_lang.get_name()
-
-                        for lang in langs:
-                                name = lang.get_name()
-                                parent = self.model.append(None, (name, name, lang, None))
-
-                                # Add dummy node
-                                self.model.append(parent, ('', '', None, None))
+        if nodes:
+            for node in nodes:
+                self.add_snippet(piter, node)
+        else:
+            # Add node that tells there are no snippets currently
+            self.add_new_snippet_node(piter)
 
-                                if (nm == name):
-                                        expand = parent
-                else:
-                        if current_lang:
-                                piter = self.model.get_iter_first()
-                                nm = current_lang.get_name()
-
-                                while piter:
-                                        lang = self.model.get_value(piter, \
-                                                        self.SORT_COLUMN)
+        if expand:
+            self.tree_view.expand_row(path, False)
 
-                                        if lang == nm:
-                                                expand = piter
-                                                break;
+    def build_model(self, force_reload = False):
+        window = Gio.Application.get_default().get_active_window()
+        if window:
+            view = window.get_active_view()
 
-                                        piter = self.model.iter_next(piter)
+            if not view:
+                current_lang = None
+            else:
+                current_lang = view.get_buffer().get_language()
+        else:
+            current_lang = None
 
-                tree_view.set_model(self.model)
+        tree_view = self['tree_view_snippets']
+        expand = None
 
-                if not expand:
-                        expand = self.model.get_iter_first()
+        if not self.model or force_reload:
+            self.model = Gtk.TreeStore(str, str, GObject.Object, object)
+            self.model.set_sort_column_id(self.SORT_COLUMN, Gtk.SortType.ASCENDING)
 
-                tree_view.expand_row(self.model.get_path(expand), False)
-                self.select_iter(expand)
+            manager = get_language_manager()
 
-        def get_cell_data_pixbuf_cb(self, column, cell, model, iter, data):
-                lang = model.get_value(iter, self.LANG_COLUMN)
-                snippet = model.get_value(iter, self.SNIPPET_COLUMN)
-
-                if snippet and not snippet.valid:
-                        cell.set_property('icon-name', 'dialog-error')
-                else:
-                        cell.set_property('icon-name', None)
+            langs = [manager.get_language(x) for x in manager.get_language_ids()]
+            langs.sort(key=lambda x: x.get_name())
 
-                cell.set_property('xalign', 1.0)
+            piter = self.model.append(None, (_('Global'), '', None, None))
 
-        def get_cell_data_cb(self, column, cell, model, iter, data):
-                snippet = model.get_value(iter, self.SNIPPET_COLUMN)
+            # Add dummy node
+            self.model.append(piter, ('', '', None, None))
 
-                cell.set_property('editable', snippet != None)
-                cell.set_property('markup', model.get_value(iter, self.NAME_COLUMN))
+            nm = None
 
-        def on_tree_view_drag_data_get(self, widget, context, selection_data, info, time):
-                gfile = Gio.file_new_for_path(self._temp_export)
-                selection_data.set_uris([gfile.get_uri()])
+            if current_lang:
+                nm = current_lang.get_name()
 
-        def on_tree_view_drag_begin(self, widget, context):
-                self.dragging = True
+            for lang in langs:
+                name = lang.get_name()
+                parent = self.model.append(None, (name, name, lang, None))
 
-                if self._temp_export:
-                      shutil.rmtree(os.path.dirname(self._temp_export))
-                      self._temp_export = None
+                # Add dummy node
+                self.model.append(parent, ('', '', None, None))
 
-                if self.dnd_name:
-                        Gtk.drag_set_icon_name(context, self.dnd_name, 0, 0)
+                if (nm == name):
+                    expand = parent
+        else:
+            if current_lang:
+                piter = self.model.get_iter_first()
+                nm = current_lang.get_name()
 
-                dirname = tempfile.mkdtemp()
-                filename = os.path.join(dirname, self.default_export_name)
+                while piter:
+                    lang = self.model.get_value(piter, \
+                            self.SORT_COLUMN)
 
-                # Generate temporary file name
-                self.export_snippets(filename, False)
-                self._temp_export = filename
+                    if lang == nm:
+                        expand = piter
+                        break;
 
-        def on_tree_view_drag_end(self, widget, context):
-                self.dragging = False
+                    piter = self.model.iter_next(piter)
 
-        def on_tree_view_drag_data_received(self, widget, context, x, y, selection, info, timestamp):
-                uris = selection.get_uris()
+        tree_view.set_model(self.model)
 
-                files = [Gio.file_new_for_uri(x) for x in uris]
+        if not expand:
+            expand = self.model.get_iter_first()
 
-                self.import_snippets(files)
+        tree_view.expand_row(self.model.get_path(expand), False)
+        self.select_iter(expand)
 
-        def on_tree_view_drag_motion(self, widget, context, x, y, timestamp):
-                # Return False if we are dragging
-                if self.dragging:
-                        return False
+    def get_cell_data_pixbuf_cb(self, column, cell, model, iter, data):
+        snippet = model.get_value(iter, self.SNIPPET_COLUMN)
 
-                # Check uri target
-                if not Gtk.targets_include_uri(context.targets):
-                        return False
+        if snippet and not snippet.valid:
+            cell.set_property('icon-name', 'dialog-error')
+        else:
+            cell.set_property('icon-name', None)
 
-                # Check action
-                action = None
-                if context.suggested_action == Gdk.DragAction.COPY:
-                        action = Gdk.DragAction.COPY
-                else:
-                        for act in context.actions:
-                                if act == Gdk.DragAction.COPY:
-                                      action = Gdk.DragAction.COPY
-                                      break
-
-                if action == Gdk.DragAction.COPY:
-                        context.drag_status(Gdk.DragAction.COPY, timestamp)
-                        return True
-                else:
-                        return False
+        cell.set_property('xalign', 1.0)
 
-        def build_dnd(self):
-                tv = self.tree_view
+    def get_cell_data_cb(self, column, cell, model, iter, data):
+        snippet = model.get_value(iter, self.SNIPPET_COLUMN)
 
-                # Set it as a drag source for exporting snippets
-                tv.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.DEFAULT | 
Gdk.DragAction.COPY)
-                tv.drag_source_set_target_list(self.dnd_target_list)
+        cell.set_property('editable', snippet != None)
+        cell.set_property('markup', model.get_value(iter, self.NAME_COLUMN))
 
-                # Set it as a drag destination for importing snippets
-                tv.drag_dest_set(Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP,
-                                 [], Gdk.DragAction.DEFAULT | Gdk.DragAction.COPY)
+    def on_tree_view_drag_data_get(self, widget, context, selection_data, info, time):
+        gfile = Gio.file_new_for_path(self._temp_export)
+        selection_data.set_uris([gfile.get_uri()])
 
-                tv.drag_dest_set_target_list(self.dnd_target_list)
+    def on_tree_view_drag_begin(self, widget, context):
+        self.dragging = True
 
-                tv.connect('drag_data_get', self.on_tree_view_drag_data_get)
-                tv.connect('drag_begin', self.on_tree_view_drag_begin)
-                tv.connect('drag_end', self.on_tree_view_drag_end)
-                tv.connect('drag_data_received', self.on_tree_view_drag_data_received)
-                tv.connect('drag_motion', self.on_tree_view_drag_motion)
+        if self._temp_export:
+              shutil.rmtree(os.path.dirname(self._temp_export))
+              self._temp_export = None
 
-                theme = Gtk.IconTheme.get_for_screen(tv.get_screen())
+        if self.dnd_name:
+            Gtk.drag_set_icon_name(context, self.dnd_name, 0, 0)
 
-                self.dnd_name = None
-                for name in self.drag_icons:
-                        icon = theme.lookup_icon(name, Gtk.IconSize.DND, 0)
+        dirname = tempfile.mkdtemp()
+        filename = os.path.join(dirname, self.default_export_name)
 
-                        if icon:
-                                self.dnd_name = name
-                                break
+        # Generate temporary file name
+        self.export_snippets(filename, False)
+        self._temp_export = filename
 
-        def build_tree_view(self):
-                self.tree_view = self['tree_view_snippets']
+    def on_tree_view_drag_end(self, widget, context):
+        self.dragging = False
 
-                self.column = Gtk.TreeViewColumn(None)
+    def on_tree_view_drag_data_received(self, widget, context, x, y, selection, info, timestamp):
+        uris = selection.get_uris()
 
-                self.renderer = Gtk.CellRendererText()
-                self.column.pack_start(self.renderer, False)
-                self.column.set_cell_data_func(self.renderer, self.get_cell_data_cb, None)
+        files = [Gio.file_new_for_uri(u) for u in uris]
 
-                renderer = Gtk.CellRendererPixbuf()
-                self.column.pack_start(renderer, True)
-                self.column.set_cell_data_func(renderer, self.get_cell_data_pixbuf_cb, None)
+        self.import_snippets(files)
 
-                self.tree_view.append_column(self.column)
+    def on_tree_view_drag_motion(self, widget, context, x, y, timestamp):
+        # Return False if we are dragging
+        if self.dragging:
+            return False
 
-                self.renderer.connect('edited', self.on_cell_edited)
-                self.renderer.connect('editing-started', self.on_cell_editing_started)
+        # Check uri target
+        if not Gtk.targets_include_uri(context.targets):
+            return False
 
-                selection = self.tree_view.get_selection()
-                selection.set_mode(Gtk.SelectionMode.MULTIPLE)
-                selection.connect('changed', self.on_tree_view_selection_changed)
+        # Check action
+        action = None
+        if context.suggested_action == Gdk.DragAction.COPY:
+            action = Gdk.DragAction.COPY
+        else:
+            for act in context.actions:
+                if act == Gdk.DragAction.COPY:
+                      action = Gdk.DragAction.COPY
+                      break
 
-                self.build_dnd()
+        if action == Gdk.DragAction.COPY:
+            context.drag_status(Gdk.DragAction.COPY, timestamp)
+            return True
+        else:
+            return False
 
-        def do_parser_finished(self, builder):
-                self.builder = builder
+    def build_dnd(self):
+        tv = self.tree_view
 
-                handlers_dic = {
-                        'on_add_snippet_button_clicked': self.on_add_snippet_button_clicked,
-                        'on_remove_snippet_button_clicked': self.on_remove_snippet_button_clicked,
-                        'on_import_snippets_button_clicked': self.on_import_snippets_button_clicked,
-                        'on_export_snippets_button_clicked': self.on_export_snippets_button_clicked,
-                        'on_entry_tab_trigger_focus_out': self.on_entry_tab_trigger_focus_out,
-                        'on_entry_tab_trigger_changed': self.on_entry_tab_trigger_changed,
-                        'on_entry_accelerator_focus_out': self.on_entry_accelerator_focus_out,
-                        'on_entry_accelerator_focus_in': self.on_entry_accelerator_focus_in,
-                        'on_entry_accelerator_key_press': self.on_entry_accelerator_key_press,
-                        'on_source_view_snippet_focus_out': self.on_source_view_snippet_focus_out,
-                        'on_tree_view_snippets_row_expanded': self.on_tree_view_snippets_row_expanded,
-                        'on_tree_view_snippets_key_press': self.on_tree_view_snippets_key_press}
+        # Set it as a drag source for exporting snippets
+        tv.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.DEFAULT | Gdk.DragAction.COPY)
+        tv.drag_source_set_target_list(self.dnd_target_list)
 
-                self.builder.connect_signals(handlers_dic)
+        # Set it as a drag destination for importing snippets
+        tv.drag_dest_set(Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP,
+                 [], Gdk.DragAction.DEFAULT | Gdk.DragAction.COPY)
 
-                self.build_tree_view()
-                self.build_model()
+        tv.drag_dest_set_target_list(self.dnd_target_list)
 
-                # join treeview and toolbar
-                context = self['scrolled_window_snippets'].get_style_context()
-                context.set_junction_sides(Gtk.JunctionSides.BOTTOM)
-                context = self['toolbar'].get_style_context()
-                context.set_junction_sides(Gtk.JunctionSides.TOP)
-                context.set_junction_sides(Gtk.JunctionSides.BOTTOM)
+        tv.connect('drag_data_get', self.on_tree_view_drag_data_get)
+        tv.connect('drag_begin', self.on_tree_view_drag_begin)
+        tv.connect('drag_end', self.on_tree_view_drag_end)
+        tv.connect('drag_data_received', self.on_tree_view_drag_data_received)
+        tv.connect('drag_motion', self.on_tree_view_drag_motion)
 
-                source_view = self['source_view_snippet']
-                manager = get_language_manager()
-                lang = manager.get_language('snippets')
+        theme = Gtk.IconTheme.get_for_screen(tv.get_screen())
 
-                if lang:
-                        source_view.get_buffer().set_highlight_syntax(True)
-                        source_view.get_buffer().set_language(lang)
+        self.dnd_name = None
+        for name in self.drag_icons:
+            icon = theme.lookup_icon(name, Gtk.IconSize.DND, 0)
 
-                combo = self['combo_drop_targets']
+            if icon:
+                self.dnd_name = name
+                break
 
-                entry = combo.get_child()
-                entry.connect('focus-out-event', self.on_entry_drop_targets_focus_out)
-                entry.connect('drag-data-received', self.on_entry_drop_targets_drag_data_received)
+    def build_tree_view(self):
+        self.tree_view = self['tree_view_snippets']
 
-                lst = entry.drag_dest_get_target_list()
-                lst.add_uri_targets(self.TARGET_URI)
+        self.column = Gtk.TreeViewColumn(None)
 
-        def do_configure_event(self, event):
-                if self.get_realized():
-                        alloc = self.get_allocation()
-                        self._size = (alloc.width, alloc.height)
+        self.renderer = Gtk.CellRendererText()
+        self.column.pack_start(self.renderer, False)
+        self.column.set_cell_data_func(self.renderer, self.get_cell_data_cb, None)
 
-                return Gtk.Dialog.do_configure_event(self, event)
+        renderer = Gtk.CellRendererPixbuf()
+        self.column.pack_start(renderer, True)
+        self.column.set_cell_data_func(renderer, self.get_cell_data_pixbuf_cb, None)
 
-        def __getitem__(self, key):
-                return self.builder.get_object(key)
+        self.tree_view.append_column(self.column)
 
-        def is_filled(self, piter):
-                if not self.model.iter_has_child(piter):
-                        return True
+        self.renderer.connect('edited', self.on_cell_edited)
+        self.renderer.connect('editing-started', self.on_cell_editing_started)
 
-                child = self.model.iter_children(piter)
-                nm = self.model.get_value(child, self.NAME_COLUMN)
-                lang = self.model.get_value(child, self.LANG_COLUMN)
-                snippet = self.model.get_value(child, self.SNIPPET_COLUMN)
+        selection = self.tree_view.get_selection()
+        selection.set_mode(Gtk.SelectionMode.MULTIPLE)
+        selection.connect('changed', self.on_tree_view_selection_changed)
 
-                return (lang or snippet or nm)
+        self.build_dnd()
 
-        def fill_if_needed(self, piter, expand=True):
-                if not self.is_filled(piter):
-                        self.fill_language(piter, expand)
+    def do_parser_finished(self, builder):
+        self.builder = builder
 
-        def find_iter(self, parent, snippet):
-                self.fill_if_needed(parent)
-                piter = self.model.iter_children(parent)
+        handlers_dic = {
+            'on_add_snippet_button_clicked': self.on_add_snippet_button_clicked,
+            'on_remove_snippet_button_clicked': self.on_remove_snippet_button_clicked,
+            'on_import_snippets_button_clicked': self.on_import_snippets_button_clicked,
+            'on_export_snippets_button_clicked': self.on_export_snippets_button_clicked,
+            'on_entry_tab_trigger_focus_out': self.on_entry_tab_trigger_focus_out,
+            'on_entry_tab_trigger_changed': self.on_entry_tab_trigger_changed,
+            'on_entry_accelerator_focus_out': self.on_entry_accelerator_focus_out,
+            'on_entry_accelerator_focus_in': self.on_entry_accelerator_focus_in,
+            'on_entry_accelerator_key_press': self.on_entry_accelerator_key_press,
+            'on_source_view_snippet_focus_out': self.on_source_view_snippet_focus_out,
+            'on_tree_view_snippets_row_expanded': self.on_tree_view_snippets_row_expanded,
+            'on_tree_view_snippets_key_press': self.on_tree_view_snippets_key_press}
 
-                while (piter):
-                        sn = self.model.get_value(piter, self.SNIPPET_COLUMN)
+        self.builder.connect_signals(handlers_dic)
 
-                        if sn == snippet.data:
-                                return piter
+        self.build_tree_view()
+        self.build_model()
 
-                        piter = self.model.iter_next(piter)
+        # join treeview and toolbar
+        context = self['scrolled_window_snippets'].get_style_context()
+        context.set_junction_sides(Gtk.JunctionSides.BOTTOM)
+        context = self['toolbar'].get_style_context()
+        context.set_junction_sides(Gtk.JunctionSides.TOP)
+        context.set_junction_sides(Gtk.JunctionSides.BOTTOM)
 
-                return None
+        source_view = self['source_view_snippet']
+        manager = get_language_manager()
+        lang = manager.get_language('snippets')
 
-        def selected_snippets_state(self):
-                snippets = self.selected_snippets(False)
-                override = False
-                remove = False
-                system = False
+        if lang:
+            source_view.get_buffer().set_highlight_syntax(True)
+            source_view.get_buffer().set_language(lang)
 
-                for snippet in snippets:
-                        if not snippet:
-                                continue
+        combo = self['combo_drop_targets']
 
-                        if snippet.is_override():
-                                override = True
-                        elif snippet.can_modify():
-                                remove = True
-                        else:
-                                system = True
+        entry = combo.get_child()
+        entry.connect('focus-out-event', self.on_entry_drop_targets_focus_out)
+        entry.connect('drag-data-received', self.on_entry_drop_targets_drag_data_received)
 
-                        # No need to continue if both are found
-                        if override and remove:
-                                break
+        lst = entry.drag_dest_get_target_list()
+        lst.add_uri_targets(self.TARGET_URI)
 
-                return (override, remove, system)
+    def do_configure_event(self, event):
+        if self.get_realized():
+            alloc = self.get_allocation()
+            self._size = (alloc.width, alloc.height)
 
-        def update_toolbar_buttons(self):
-                button_add = self['add_snippet_button']
-                button_remove = self['remove_snippet_button']
+        return Gtk.Dialog.do_configure_event(self, event)
 
-                button_add.set_sensitive(self.language_path != None)
-                override, remove, system = self.selected_snippets_state()
+    def __getitem__(self, key):
+        return self.builder.get_object(key)
 
-                if not (override ^ remove) or system:
-                        button_remove.set_sensitive(False)
-                        button_remove.set_icon_name('list-remove-symbolic')
-                else:
-                        button_remove.set_sensitive(True)
+    def is_filled(self, piter):
+        if not self.model.iter_has_child(piter):
+            return True
 
-                        if override:
-                                button_remove.set_icon_name('edit-undo-symbolic')
-                                tooltip = _('Revert selected snippet')
-                        else:
-                                button_remove.set_icon_name('list-remove-symbolic')
-                                tooltip = _('Delete selected snippet')
+        child = self.model.iter_children(piter)
+        nm = self.model.get_value(child, self.NAME_COLUMN)
+        lang = self.model.get_value(child, self.LANG_COLUMN)
+        snippet = self.model.get_value(child, self.SNIPPET_COLUMN)
 
-                        button_remove.set_tooltip_text(tooltip)
+        return (lang or snippet or nm)
 
-        def snippet_changed(self, piter = None):
-                if piter:
-                        node = self.model.get_value(piter, self.SNIPPET_COLUMN)
-                        s = Snippet(node)
-                else:
-                        s = self.snippet
-                        piter = self.find_iter(self.model.get_iter(self.language_path), s)
+    def fill_if_needed(self, piter, expand=True):
+        if not self.is_filled(piter):
+            self.fill_language(piter, expand)
 
-                if piter:
-                        nm = s.display()
+    def find_iter(self, parent, snippet):
+        self.fill_if_needed(parent)
+        piter = self.model.iter_children(parent)
 
-                        self.model.set_value(piter, self.NAME_COLUMN, nm)
-                        self.model.set_value(piter, self.SORT_COLUMN, nm)
-                        self.update_toolbar_buttons()
-                        self.entry_tab_trigger_update_valid()
+        while (piter):
+            sn = self.model.get_value(piter, self.SNIPPET_COLUMN)
 
+            if sn == snippet.data:
                 return piter
 
-        def add_snippet(self, parent, snippet):
-                piter = self.model.append(parent, ('', '', None, snippet))
+            piter = self.model.iter_next(piter)
 
-                return self.snippet_changed(piter)
+        return None
 
-        def snippet_from_iter(self, model, piter):
-                parent = model.iter_parent(piter)
+    def selected_snippets_state(self):
+        snippets = self.selected_snippets(False)
+        override = False
+        remove = False
+        system = False
 
-                if parent:
-                        return model.get_value(piter, self.SNIPPET_COLUMN)
-                else:
-                        return None
+        for snippet in snippets:
+            if not snippet:
+                continue
 
-        def language_snippets(self, model, parent, as_path=False):
-                self.fill_if_needed(parent, False)
-                piter = model.iter_children(parent)
-                snippets = []
+            if snippet.is_override():
+                override = True
+            elif snippet.can_modify():
+                remove = True
+            else:
+                system = True
 
-                if not piter:
-                        return snippets
+            # No need to continue if both are found
+            if override and remove:
+                break
 
-                while piter:
-                        snippet = self.snippet_from_iter(model, piter)
+        return (override, remove, system)
 
-                        if snippet:
-                                if as_path:
-                                        snippets.append(model.get_path(piter))
-                                else:
-                                        snippets.append(snippet)
+    def update_toolbar_buttons(self):
+        button_add = self['add_snippet_button']
+        button_remove = self['remove_snippet_button']
 
-                        piter = model.iter_next(piter)
+        button_add.set_sensitive(self.language_path != None)
+        override, remove, system = self.selected_snippets_state()
 
-                return snippets
+        if not (override ^ remove) or system:
+            button_remove.set_sensitive(False)
+            button_remove.set_icon_name('list-remove-symbolic')
+        else:
+            button_remove.set_sensitive(True)
 
-        def selected_snippets(self, include_languages=True, as_path=False):
-                selection = self.tree_view.get_selection()
-                (model, paths) = selection.get_selected_rows()
-                snippets = []
+            if override:
+                button_remove.set_icon_name('edit-undo-symbolic')
+                tooltip = _('Revert selected snippet')
+            else:
+                button_remove.set_icon_name('list-remove-symbolic')
+                tooltip = _('Delete selected snippet')
 
-                if paths and len(paths) != 0:
-                        for p in paths:
-                                piter = model.get_iter(p)
-                                parent = model.iter_parent(piter)
+            button_remove.set_tooltip_text(tooltip)
 
-                                if not piter:
-                                        continue
+    def snippet_changed(self, piter = None):
+        if piter:
+            node = self.model.get_value(piter, self.SNIPPET_COLUMN)
+            s = Snippet(node)
+        else:
+            s = self.snippet
+            piter = self.find_iter(self.model.get_iter(self.language_path), s)
 
-                                if parent:
-                                        snippet = self.snippet_from_iter(model, piter)
+        if piter:
+            nm = s.display()
 
-                                        if not snippet:
-                                                continue
+            self.model.set_value(piter, self.NAME_COLUMN, nm)
+            self.model.set_value(piter, self.SORT_COLUMN, nm)
+            self.update_toolbar_buttons()
+            self.entry_tab_trigger_update_valid()
 
-                                        if as_path:
-                                                snippets.append(p)
-                                        else:
-                                                snippets.append(snippet)
-                                elif include_languages:
-                                        snippets += self.language_snippets(model, piter, as_path)
+        return piter
 
-                return snippets
+    def add_snippet(self, parent, snippet):
+        piter = self.model.append(parent, ('', '', None, snippet))
 
-        def selected_snippet(self):
-                selection = self.tree_view.get_selection()
-                (model, paths) = selection.get_selected_rows()
+        return self.snippet_changed(piter)
 
-                if len(paths) == 1:
-                        piter = model.get_iter(paths[0])
-                        parent = model.iter_parent(piter)
-                        snippet = self.snippet_from_iter(model, piter)
+    def snippet_from_iter(self, model, piter):
+        parent = model.iter_parent(piter)
 
-                        return parent, piter, snippet
-                else:
-                        return None, None, None
+        if parent:
+            return model.get_value(piter, self.SNIPPET_COLUMN)
+        else:
+            return None
 
-        def selection_changed(self):
-                if not self.snippet:
-                        sens = False
+    def language_snippets(self, model, parent, as_path=False):
+        self.fill_if_needed(parent, False)
+        piter = model.iter_children(parent)
+        snippets = []
 
-                        self['entry_tab_trigger'].set_text('')
-                        self['entry_accelerator'].set_text('')
-                        buf = self['source_view_snippet'].get_buffer()
-                        buf.begin_not_undoable_action()
-                        buf.set_text('')
-                        buf.end_not_undoable_action()
-                        self['combo_drop_targets'].get_child().set_text('')
+        if not piter:
+            return snippets
 
+        while piter:
+            snippet = self.snippet_from_iter(model, piter)
+
+            if snippet:
+                if as_path:
+                    snippets.append(model.get_path(piter))
                 else:
-                        sens = True
+                    snippets.append(snippet)
 
-                        self['entry_tab_trigger'].set_text(self.snippet['tag'])
-                        self['entry_accelerator'].set_text( \
-                                        self.snippet.accelerator_display())
-                        self['combo_drop_targets'].get_child().set_text(', 
'.join(self.snippet['drop-targets']))
+            piter = model.iter_next(piter)
 
-                        buf = self['source_view_snippet'].get_buffer()
-                        buf.begin_not_undoable_action()
-                        buf.set_text(self.snippet['text'])
-                        buf.end_not_undoable_action()
+        return snippets
 
+    def selected_snippets(self, include_languages=True, as_path=False):
+        selection = self.tree_view.get_selection()
+        (model, paths) = selection.get_selected_rows()
+        snippets = []
 
-                for name in ['source_view_snippet', 'label_tab_trigger',
-                                'entry_tab_trigger', 'label_accelerator',
-                                'entry_accelerator', 'label_drop_targets',
-                                'combo_drop_targets']:
-                        self[name].set_sensitive(sens)
+        if paths and len(paths) != 0:
+            for p in paths:
+                piter = model.get_iter(p)
+                parent = model.iter_parent(piter)
 
-                self.update_toolbar_buttons()
+                if not piter:
+                    continue
 
-        def select_iter(self, piter, unselect=True):
-                selection = self.tree_view.get_selection()
+                if parent:
+                    snippet = self.snippet_from_iter(model, piter)
 
-                if unselect:
-                        selection.unselect_all()
+                    if not snippet:
+                        continue
 
-                selection.select_iter(piter)
+                    if as_path:
+                        snippets.append(p)
+                    else:
+                        snippets.append(snippet)
+                elif include_languages:
+                    snippets += self.language_snippets(model, piter, as_path)
 
-                self.tree_view.scroll_to_cell(self.model.get_path(piter), None, \
-                        True, 0.5, 0.5)
+        return snippets
 
-        def get_language(self, path):
-                if path.get_indices()[0] == 0:
-                        return None
-                else:
-                        return self.model.get_value(self.model.get_iter(path),
-                                                    self.LANG_COLUMN).get_id()
+    def selected_snippet(self):
+        selection = self.tree_view.get_selection()
+        (model, paths) = selection.get_selected_rows()
 
-        def new_snippet(self, properties=None):
-                if not self.language_path:
-                        return None
+        if len(paths) == 1:
+            piter = model.get_iter(paths[0])
+            parent = model.iter_parent(piter)
+            snippet = self.snippet_from_iter(model, piter)
 
-                snippet = Library().new_snippet(self.get_language(self.language_path), properties)
+            return parent, piter, snippet
+        else:
+            return None, None, None
 
-                return Snippet(snippet)
+    def selection_changed(self):
+        if not self.snippet:
+            sens = False
 
-        def get_dummy(self, parent):
-                if not self.model.iter_n_children(parent) == 1:
-                        return None
+            self['entry_tab_trigger'].set_text('')
+            self['entry_accelerator'].set_text('')
+            buf = self['source_view_snippet'].get_buffer()
+            buf.begin_not_undoable_action()
+            buf.set_text('')
+            buf.end_not_undoable_action()
+            self['combo_drop_targets'].get_child().set_text('')
 
-                dummy = self.model.iter_children(parent)
+        else:
+            sens = True
 
-                if not self.model.get_value(dummy, self.SNIPPET_COLUMN):
-                        return dummy
+            self['entry_tab_trigger'].set_text(self.snippet['tag'])
+            self['entry_accelerator'].set_text( \
+                    self.snippet.accelerator_display())
+            self['combo_drop_targets'].get_child().set_text(', '.join(self.snippet['drop-targets']))
 
-                return None
+            buf = self['source_view_snippet'].get_buffer()
+            buf.begin_not_undoable_action()
+            buf.set_text(self.snippet['text'])
+            buf.end_not_undoable_action()
 
-        def unref_languages(self):
-                piter = self.model.get_iter_first()
-                library = Library()
 
-                while piter:
-                        if self.is_filled(piter):
-                                language = self.get_language(self.model.get_path(piter))
-                                library.save(language)
-
-                                library.unref(language)
-
-                        piter = self.model.iter_next(piter)
-
-        # Callbacks
-        def do_destroy(self):
-                Gtk.Dialog.do_destroy(self)
-
-                if not self.model:
-                        return
-
-                # Remove temporary drag export
-                if self._temp_export:
-                      shutil.rmtree(os.path.dirname(self._temp_export))
-                      self._temp_export = None
-
-                self.unref_languages()
-                self.snippet = None
-                self.model = None
-
-        def on_cell_editing_started(self, renderer, editable, path):
-                piter = self.model.get_iter(path)
-
-                if not self.model.iter_parent(piter):
-                        renderer.stop_editing(True)
-                        editable.remove_widget()
-                elif isinstance(editable, Gtk.Entry):
-                        if self.snippet:
-                                editable.set_text(self.snippet['description'])
-                        else:
-                                # This is the `Add a new snippet...` item
-                                editable.set_text('')
-
-                        editable.grab_focus()
-
-        def on_cell_edited(self, cell, path, new_text):
-                if new_text != '':
-                        piter = self.model.get_iter(path)
-                        node = self.model.get_value(piter, self.SNIPPET_COLUMN)
-
-                        if node:
-                                if node == self.snippet.data:
-                                        s = self.snippet
-                                else:
-                                        s = Snippet(node)
-
-                                s['description'] = new_text
-                                self.snippet_changed(piter)
-                                self.select_iter(piter)
-                        else:
-                                # This is the `Add a new snippet...` item
-                                # We create a new snippet
-                                snippet = self.new_snippet({'description': new_text})
-
-                                if snippet:
-                                        self.model.set_value(piter, self.SNIPPET_COLUMN, snippet.data)
-                                        self.snippet_changed(piter)
-                                        self.snippet = snippet
-                                        self.selection_changed()
-
-        def on_entry_accelerator_focus_out(self, entry, event):
-                if not self.snippet:
-                        return
-
-                entry.set_text(self.snippet.accelerator_display())
-
-        def entry_tab_trigger_update_valid(self):
-                entry = self['entry_tab_trigger']
-                text = entry.get_text()
-
-                if text and not Library().valid_tab_trigger(text):
-                        img = self['image_tab_trigger']
-                        img.set_from_icon_name('dialog-error', Gtk.IconSize.BUTTON)
-                        img.show()
-
-                        #self['hbox_tab_trigger'].set_spacing(3)
-                        tip = _('This is not a valid Tab trigger. Triggers can either contain alphanumeric 
characters (or _, : and .) or a single (non-alphanumeric) character like: {, [, etc.')
-
-                        entry.set_tooltip_text(tip)
-                        img.set_tooltip_text(tip)
-                else:
-                        self['image_tab_trigger'].hide()
-                        #self['hbox_tab_trigger'].set_spacing(0)
-                        entry.set_tooltip_text(_('Single word the snippet is activated with after pressing 
Tab'))
+        for name in ['source_view_snippet', 'label_tab_trigger',
+                'entry_tab_trigger', 'label_accelerator',
+                'entry_accelerator', 'label_drop_targets',
+                'combo_drop_targets']:
+            self[name].set_sensitive(sens)
 
-                return False
+        self.update_toolbar_buttons()
 
-        def on_entry_tab_trigger_focus_out(self, entry, event):
-                if not self.snippet:
-                        return
+    def select_iter(self, piter, unselect=True):
+        selection = self.tree_view.get_selection()
 
-                text = entry.get_text()
+        if unselect:
+            selection.unselect_all()
 
-                # save tag
-                self.snippet['tag'] = text
-                self.snippet_changed()
+        selection.select_iter(piter)
 
-        def on_entry_drop_targets_focus_out(self, entry, event):
-                if not self.snippet:
-                        return
+        self.tree_view.scroll_to_cell(self.model.get_path(piter), None, \
+            True, 0.5, 0.5)
 
-                text = entry.get_text()
+    def get_language(self, path):
+        if path.get_indices()[0] == 0:
+            return None
+        else:
+            return self.model.get_value(self.model.get_iter(path),
+                            self.LANG_COLUMN).get_id()
 
-                # save drop targets
-                self.snippet['drop-targets'] = text
-                self.snippet_changed()
+    def new_snippet(self, properties=None):
+        if not self.language_path:
+            return None
 
-        def on_entry_tab_trigger_changed(self, entry):
-                self.entry_tab_trigger_update_valid()
+        snippet = Library().new_snippet(self.get_language(self.language_path), properties)
 
-        def on_source_view_snippet_focus_out(self, source_view, event):
-                if not self.snippet:
-                        return
+        return Snippet(snippet)
 
-                buf = source_view.get_buffer()
-                text = buf.get_text(buf.get_start_iter(), \
-                       buf.get_end_iter(), False)
+    def get_dummy(self, parent):
+        if not self.model.iter_n_children(parent) == 1:
+            return None
 
-                self.snippet['text'] = text
-                self.snippet_changed()
+        dummy = self.model.iter_children(parent)
 
-        def on_add_snippet_button_clicked(self, button):
-                snippet = self.new_snippet()
+        if not self.model.get_value(dummy, self.SNIPPET_COLUMN):
+            return dummy
 
-                if not snippet:
-                        return
+        return None
 
-                parent = self.model.get_iter(self.language_path)
-                path = self.model.get_path(parent)
+    def unref_languages(self):
+        piter = self.model.get_iter_first()
+        library = Library()
 
-                dummy = self.get_dummy(parent)
+        while piter:
+            if self.is_filled(piter):
+                language = self.get_language(self.model.get_path(piter))
+                library.save(language)
 
-                if dummy:
-                        # Remove the dummy
-                        self.model.remove(dummy)
+                library.unref(language)
 
-                # Add the snippet
-                piter = self.add_snippet(parent, snippet.data)
-                self.select_iter(piter)
+            piter = self.model.iter_next(piter)
 
-                if not self.tree_view.row_expanded(path):
-                        self.tree_view.expand_row(path, False)
-                        self.select_iter(piter)
+    # Callbacks
+    def do_destroy(self):
+        Gtk.Dialog.do_destroy(self)
 
-                self.tree_view.grab_focus()
+        if not self.model:
+            return
 
-                path = self.model.get_path(piter)
-                self.tree_view.set_cursor(path, self.column, True)
+        # Remove temporary drag export
+        if self._temp_export:
+              shutil.rmtree(os.path.dirname(self._temp_export))
+              self._temp_export = None
 
-        def file_filter(self, name, pattern):
-                fil = Gtk.FileFilter()
-                fil.set_name(name)
+        self.unref_languages()
+        self.snippet = None
+        self.model = None
 
-                for p in pattern:
-                        fil.add_pattern(p)
+    def on_cell_editing_started(self, renderer, editable, path):
+        piter = self.model.get_iter(path)
 
-                return fil
+        if not self.model.iter_parent(piter):
+            renderer.stop_editing(True)
+            editable.remove_widget()
+        elif isinstance(editable, Gtk.Entry):
+            if self.snippet:
+                editable.set_text(self.snippet['description'])
+            else:
+                # This is the `Add a new snippet...` item
+                editable.set_text('')
 
-        def import_snippets(self, files):
-                success = True
+            editable.grab_focus()
 
-                for gfile in files:
-                        if not gfile.has_uri_scheme('file'):
-                                continue
+    def on_cell_edited(self, cell, path, new_text):
+        if new_text != '':
+            piter = self.model.get_iter(path)
+            node = self.model.get_value(piter, self.SNIPPET_COLUMN)
 
-                        # Remove file://
-                        filename = gfile.get_path()
+            if node:
+                if node == self.snippet.data:
+                    s = self.snippet
+                else:
+                    s = Snippet(node)
 
-                        importer = Importer(filename)
-                        error = importer.run()
+                s['description'] = new_text
+                self.snippet_changed(piter)
+                self.select_iter(piter)
+            else:
+                # This is the `Add a new snippet...` item
+                # We create a new snippet
+                snippet = self.new_snippet({'description': new_text})
 
-                        if error:
-                                message = _('The following error occurred while importing: %s') % error
-                                success = False
-                                message_dialog(self.get_toplevel(), Gtk.MessageType.ERROR, message)
+                if snippet:
+                    self.model.set_value(piter, self.SNIPPET_COLUMN, snippet.data)
+                    self.snippet_changed(piter)
+                    self.snippet = snippet
+                    self.selection_changed()
 
-                self.build_model(True)
+    def on_entry_accelerator_focus_out(self, entry, event):
+        if not self.snippet:
+            return
 
-                if success:
-                        message = _('Import successfully completed')
-                        message_dialog(self.get_toplevel(), Gtk.MessageType.INFO, message)
+        entry.set_text(self.snippet.accelerator_display())
 
-        def on_import_response(self, dialog, response):
-                if response == Gtk.ResponseType.CANCEL or response == Gtk.ResponseType.CLOSE:
-                        dialog.destroy()
-                        return
+    def entry_tab_trigger_update_valid(self):
+        entry = self['entry_tab_trigger']
+        text = entry.get_text()
 
-                f = dialog.get_files()
-                dialog.destroy()
+        if text and not Library().valid_tab_trigger(text):
+            img = self['image_tab_trigger']
+            img.set_from_icon_name('dialog-error', Gtk.IconSize.BUTTON)
+            img.show()
 
-                self.import_snippets(f)
+            #self['hbox_tab_trigger'].set_spacing(3)
+            tip = _('This is not a valid Tab trigger. Triggers can either contain alphanumeric characters 
(or _, : and .) or a single (non-alphanumeric) character like: {, [, etc.')
 
-        def on_import_snippets_button_clicked(self, button):
-                dlg = Gtk.FileChooserDialog(parent=self.get_toplevel(), title=_("Import snippets"),
-                                action=Gtk.FileChooserAction.OPEN,
-                                buttons=(_("_Cancel"), Gtk.ResponseType.CANCEL,
-                                         _("_Open"), Gtk.ResponseType.OK))
+            entry.set_tooltip_text(tip)
+            img.set_tooltip_text(tip)
+        else:
+            self['image_tab_trigger'].hide()
+            #self['hbox_tab_trigger'].set_spacing(0)
+            entry.set_tooltip_text(_('Single word the snippet is activated with after pressing Tab'))
 
-                dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar', 
'*.xml')))
-                dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
-                dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',)))
-                dlg.add_filter(self.file_filter(_('Single snippets file'), ('*.xml',)))
-                dlg.add_filter(self.file_filter(_('All files'), '*'))
+        return False
 
-                dlg.connect('response', self.on_import_response)
-                dlg.set_local_only(True)
+    def on_entry_tab_trigger_focus_out(self, entry, event):
+        if not self.snippet:
+            return
 
-                dlg.show()
+        text = entry.get_text()
 
-        def export_snippets_real(self, filename, snippets, show_dialogs=True):
-                export = Exporter(filename, snippets)
-                error = export.run()
+        # save tag
+        self.snippet['tag'] = text
+        self.snippet_changed()
 
-                if error:
-                        message = _('The following error occurred while exporting: %s') % error
-                        msgtype = Gtk.MessageType.ERROR
-                        retval = False
-                else:
-                        message = _('Export successfully completed')
-                        msgtype = Gtk.MessageType.INFO
-                        retval = True
+    def on_entry_drop_targets_focus_out(self, entry, event):
+        if not self.snippet:
+            return
 
-                if show_dialogs:
-                        message_dialog(self.get_toplevel(), msgtype, message)
+        text = entry.get_text()
 
-                return retval
+        # save drop targets
+        self.snippet['drop-targets'] = text
+        self.snippet_changed()
 
-        def on_export_response(self, dialog, response):
-                filename = dialog.get_filename()
-                snippets = dialog._export_snippets
+    def on_entry_tab_trigger_changed(self, entry):
+        self.entry_tab_trigger_update_valid()
 
-                dialog.destroy()
+    def on_source_view_snippet_focus_out(self, source_view, event):
+        if not self.snippet:
+            return
 
-                if response != Gtk.ResponseType.OK:
-                        return
+        buf = source_view.get_buffer()
+        text = buf.get_text(buf.get_start_iter(), \
+               buf.get_end_iter(), False)
 
-                self.export_snippets_real(filename, snippets);
+        self.snippet['text'] = text
+        self.snippet_changed()
 
-        def export_snippets(self, filename=None, show_dialogs=True):
-                snippets = self.selected_snippets()
+    def on_add_snippet_button_clicked(self, button):
+        snippet = self.new_snippet()
 
-                if not snippets or len(snippets) == 0:
-                        return False
+        if not snippet:
+            return
 
-                usersnippets = []
-                systemsnippets = []
+        parent = self.model.get_iter(self.language_path)
+        path = self.model.get_path(parent)
 
-                # Iterate through snippets and look for system snippets
-                for snippet in snippets:
-                        if snippet.can_modify():
-                                usersnippets.append(snippet)
-                        else:
-                                systemsnippets.append(snippet)
+        dummy = self.get_dummy(parent)
 
-                export_snippets = snippets
+        if dummy:
+            # Remove the dummy
+            self.model.remove(dummy)
 
-                if len(systemsnippets) != 0 and show_dialogs:
-                        # Ask if system snippets should also be exported
-                        message = _('Do you want to include selected <b>system</b> snippets in your export?')
-                        mes = Gtk.MessageDialog(flags=Gtk.DialogFlags.MODAL,
-                                        type=Gtk.MessageType.QUESTION,
-                                        buttons=Gtk.ButtonsType.YES_NO,
-                                        message_format=message)
-                        mes.set_property('use-markup', True)
-                        resp = mes.run()
-                        mes.destroy()
+        # Add the snippet
+        piter = self.add_snippet(parent, snippet.data)
+        self.select_iter(piter)
 
-                        if resp == Gtk.ResponseType.NO:
-                                export_snippets = usersnippets
-                        elif resp != Gtk.ResponseType.YES:
-                                return False
+        if not self.tree_view.row_expanded(path):
+            self.tree_view.expand_row(path, False)
+            self.select_iter(piter)
 
-                if len(export_snippets) == 0 and show_dialogs:
-                        message = _('There are no snippets selected to be exported')
-                        message_dialog(self.get_toplevel(), Gtk.MessageType.QUESTION, message)
-                        return False
+        self.tree_view.grab_focus()
 
-                if not filename:
-                        dlg = Gtk.FileChooserDialog(parent=self.get_toplevel(), title=_('Export snippets'),
-                                        action=Gtk.FileChooserAction.SAVE,
-                                        buttons=(_("_Cancel"), Gtk.ResponseType.CANCEL,
-                                                 _("_Save"), Gtk.ResponseType.OK))
+        path = self.model.get_path(piter)
+        self.tree_view.set_cursor(path, self.column, True)
 
-                        dlg._export_snippets = export_snippets
-                        dlg.add_filter(self.file_filter(_('All supported archives'), 
('*.gz','*.bz2','*.tar')))
-                        dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
-                        dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',)))
+    def file_filter(self, name, pattern):
+        fil = Gtk.FileFilter()
+        fil.set_name(name)
 
-                        dlg.add_filter(self.file_filter(_('All files'), '*'))
-                        dlg.set_do_overwrite_confirmation(True)
-                        dlg.set_current_name(self.default_export_name)
+        for p in pattern:
+            fil.add_pattern(p)
 
-                        dlg.connect('response', self.on_export_response)
-                        dlg.set_local_only(True)
+        return fil
 
-                        dlg.show()
-                        return True
-                else:
-                        return self.export_snippets_real(filename, export_snippets, show_dialogs)
+    def import_snippets(self, files):
+        success = True
 
-        def on_export_snippets_button_clicked(self, button):
-                snippets = self.selected_snippets()
+        for gfile in files:
+            if not gfile.has_uri_scheme('file'):
+                continue
 
-                if not snippets or len(snippets) == 0:
-                        return
+            # Remove file://
+            filename = gfile.get_path()
 
-                usersnippets = []
-                systemsnippets = []
+            importer = Importer(filename)
+            error = importer.run()
 
-                # Iterate through snippets and look for system snippets
-                for snippet in snippets:
-                        if snippet.can_modify():
-                                usersnippets.append(snippet)
-                        else:
-                                systemsnippets.append(snippet)
+            if error:
+                message = _('The following error occurred while importing: %s') % error
+                success = False
+                helper.message_dialog(self.get_toplevel(), Gtk.MessageType.ERROR, message)
 
-                dlg = Gtk.FileChooserDialog(parent=self.get_toplevel(), title=_('Export snippets'),
-                                action=Gtk.FileChooserAction.SAVE,
-                                buttons=(_('_Cancel'), Gtk.ResponseType.CANCEL,
-                                         _('_Save'), Gtk.ResponseType.OK))
+        self.build_model(True)
 
-                dlg._export_snippets = snippets
+        if success:
+            message = _('Import successfully completed')
+            helper.message_dialog(self.get_toplevel(), Gtk.MessageType.INFO, message)
 
-                if len(systemsnippets) != 0:
-                        # Ask if system snippets should also be exported
-                        message = _('Do you want to include selected <b>system</b> snippets in your export?')
-                        mes = Gtk.MessageDialog(flags=Gtk.DialogFlags.MODAL,
-                                        type=Gtk.MessageType.QUESTION,
-                                        buttons=Gtk.ButtonsType.YES_NO,
-                                        message_format=message)
-                        mes.set_property('use-markup', True)
-                        resp = mes.run()
-                        mes.destroy()
+    def on_import_response(self, dialog, response):
+        if response == Gtk.ResponseType.CANCEL or response == Gtk.ResponseType.CLOSE:
+            dialog.destroy()
+            return
 
-                        if resp == Gtk.ResponseType.NO:
-                                dlg._export_snippets = usersnippets
-                        elif resp != Gtk.ResponseType.YES:
-                                dlg.destroy()
-                                return
+        f = dialog.get_files()
+        dialog.destroy()
 
-                if len(dlg._export_snippets) == 0:
-                        dlg.destroy()
+        self.import_snippets(f)
 
-                        message = _('There are no snippets selected to be exported')
-                        message_dialog(self.get_toplevel(), Gtk.MessageType.QUESTION, message)
-                        return
+    def on_import_snippets_button_clicked(self, button):
+        dlg = Gtk.FileChooserDialog(parent=self.get_toplevel(), title=_("Import snippets"),
+                action=Gtk.FileChooserAction.OPEN,
+                buttons=(_("_Cancel"), Gtk.ResponseType.CANCEL,
+                     _("_Open"), Gtk.ResponseType.OK))
 
-                dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar')))
-                dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
-                dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',)))
+        dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar', '*.xml')))
+        dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
+        dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',)))
+        dlg.add_filter(self.file_filter(_('Single snippets file'), ('*.xml',)))
+        dlg.add_filter(self.file_filter(_('All files'), '*'))
 
-                dlg.add_filter(self.file_filter(_('All files'), '*'))
-                dlg.set_do_overwrite_confirmation(True)
-                dlg.set_current_name(self.default_export_name)
+        dlg.connect('response', self.on_import_response)
+        dlg.set_local_only(True)
 
-                dlg.connect('response', self.on_export_response)
-                dlg.set_local_only(True)
+        dlg.show()
 
-                dlg.show()
+    def export_snippets_real(self, filename, snippets, show_dialogs=True):
+        export = Exporter(filename, snippets)
+        error = export.run()
 
-        def remove_snippet_revert(self, path, piter):
-                node = self.snippet_from_iter(self.model, piter)
-                Library().revert_snippet(node)
+        if error:
+            message = _('The following error occurred while exporting: %s') % error
+            msgtype = Gtk.MessageType.ERROR
+            retval = False
+        else:
+            message = _('Export successfully completed')
+            msgtype = Gtk.MessageType.INFO
+            retval = True
 
-                return piter
+        if show_dialogs:
+            helper.message_dialog(self.get_toplevel(), msgtype, message)
 
-        def remove_snippet_delete(self, path, piter):
-                node = self.snippet_from_iter(self.model, piter)
-                parent = self.model.iter_parent(piter)
+        return retval
 
-                Library().remove_snippet(node)
-                idx = path.get_indices()
+    def on_export_response(self, dialog, response):
+        filename = dialog.get_filename()
+        snippets = dialog._export_snippets
 
-                if self.model.remove(piter):
-                        return piter
-                elif idx[-1] != 0:
-                        self.select_iter(self.model.get_iter((idx[0], idx[1] - 1)))
-                else:
-                        dummy = self.add_new_snippet_node(parent)
-                        self.tree_view.expand_row(self.model.get_path(parent), False)
-                        return dummy
+        dialog.destroy()
 
-        def on_remove_snippet_button_clicked(self, button):
-                override, remove, system = self.selected_snippets_state()
+        if response != Gtk.ResponseType.OK:
+            return
 
-                if not (override ^ remove) or system:
-                        return
+        self.export_snippets_real(filename, snippets);
 
-                paths = self.selected_snippets(include_languages=False, as_path=True)
+    def export_snippets(self, filename=None, show_dialogs=True):
+        snippets = self.selected_snippets()
 
-                if override:
-                        action = self.remove_snippet_revert
-                else:
-                        action = self.remove_snippet_delete
-
-                # Remove selection
-                self.tree_view.get_selection().unselect_all()
-
-                # Create tree row references
-                references = []
-                for path in paths:
-                        # FIXME: this should be fixed in pygobject or something
-                        references.append(Gtk.TreeRowReference.new(self.model, path))
-
-                # Remove/revert snippets
-                select = None
-                for reference in references:
-                        path = reference.get_path()
-                        piter = self.model.get_iter(path)
+        if not snippets or len(snippets) == 0:
+            return False
 
-                        res = action(path, piter)
+        usersnippets = []
+        systemsnippets = []
 
-                        if res:
-                                select = res
+        # Iterate through snippets and look for system snippets
+        for snippet in snippets:
+            if snippet.can_modify():
+                usersnippets.append(snippet)
+            else:
+                systemsnippets.append(snippet)
 
-                if select:
-                        self.select_iter(select)
+        export_snippets = snippets
 
-                self.selection_changed()
+        if len(systemsnippets) != 0 and show_dialogs:
+            # Ask if system snippets should also be exported
+            message = _('Do you want to include selected <b>system</b> snippets in your export?')
+            mes = Gtk.MessageDialog(flags=Gtk.DialogFlags.MODAL,
+                    type=Gtk.MessageType.QUESTION,
+                    buttons=Gtk.ButtonsType.YES_NO,
+                    message_format=message)
+            mes.set_property('use-markup', True)
+            resp = mes.run()
+            mes.destroy()
 
-        def set_accelerator(self, keyval, mod):
-                accelerator = Gtk.accelerator_name(keyval, mod)
-                self.snippet['accelerator'] = accelerator
-
-                return True
+            if resp == Gtk.ResponseType.NO:
+                export_snippets = usersnippets
+            elif resp != Gtk.ResponseType.YES:
+                return False
 
-        def on_entry_accelerator_key_press(self, entry, event):
-                source_view = self['source_view_snippet']
+        if len(export_snippets) == 0 and show_dialogs:
+            message = _('There are no snippets selected to be exported')
+            helper.message_dialog(self.get_toplevel(), Gtk.MessageType.QUESTION, message)
+            return False
+
+        if not filename:
+            dlg = Gtk.FileChooserDialog(parent=self.get_toplevel(), title=_('Export snippets'),
+                    action=Gtk.FileChooserAction.SAVE,
+                    buttons=(_("_Cancel"), Gtk.ResponseType.CANCEL,
+                         _("_Save"), Gtk.ResponseType.OK))
+
+            dlg._export_snippets = export_snippets
+            dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar')))
+            dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
+            dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',)))
+
+            dlg.add_filter(self.file_filter(_('All files'), '*'))
+            dlg.set_do_overwrite_confirmation(True)
+            dlg.set_current_name(self.default_export_name)
+
+            dlg.connect('response', self.on_export_response)
+            dlg.set_local_only(True)
+
+            dlg.show()
+            return True
+        else:
+            return self.export_snippets_real(filename, export_snippets, show_dialogs)
+
+    def on_export_snippets_button_clicked(self, button):
+        snippets = self.selected_snippets()
+
+        if not snippets or len(snippets) == 0:
+            return
+
+        usersnippets = []
+        systemsnippets = []
+
+        # Iterate through snippets and look for system snippets
+        for snippet in snippets:
+            if snippet.can_modify():
+                usersnippets.append(snippet)
+            else:
+                systemsnippets.append(snippet)
+
+        dlg = Gtk.FileChooserDialog(parent=self.get_toplevel(), title=_('Export snippets'),
+                action=Gtk.FileChooserAction.SAVE,
+                buttons=(_('_Cancel'), Gtk.ResponseType.CANCEL,
+                     _('_Save'), Gtk.ResponseType.OK))
 
-                if event.keyval == Gdk.keyval_from_name('Escape'):
-                        # Reset
-                        entry.set_text(self.snippet.accelerator_display())
-                        self.tree_view.grab_focus()
+        dlg._export_snippets = snippets
+
+        if len(systemsnippets) != 0:
+            # Ask if system snippets should also be exported
+            message = _('Do you want to include selected <b>system</b> snippets in your export?')
+            mes = Gtk.MessageDialog(flags=Gtk.DialogFlags.MODAL,
+                    type=Gtk.MessageType.QUESTION,
+                    buttons=Gtk.ButtonsType.YES_NO,
+                    message_format=message)
+            mes.set_property('use-markup', True)
+            resp = mes.run()
+            mes.destroy()
 
-                        return True
-                elif event.keyval == Gdk.keyval_from_name('Delete') or \
-                                event.keyval == Gdk.keyval_from_name('BackSpace'):
-                        # Remove the accelerator
-                        entry.set_text('')
-                        self.snippet['accelerator'] = ''
-                        self.tree_view.grab_focus()
+            if resp == Gtk.ResponseType.NO:
+                dlg._export_snippets = usersnippets
+            elif resp != Gtk.ResponseType.YES:
+                dlg.destroy()
+                return
+
+        if len(dlg._export_snippets) == 0:
+            dlg.destroy()
+
+            message = _('There are no snippets selected to be exported')
+            helper.message_dialog(self.get_toplevel(), Gtk.MessageType.QUESTION, message)
+            return
+
+        dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar')))
+        dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
+        dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',)))
+
+        dlg.add_filter(self.file_filter(_('All files'), '*'))
+        dlg.set_do_overwrite_confirmation(True)
+        dlg.set_current_name(self.default_export_name)
+
+        dlg.connect('response', self.on_export_response)
+        dlg.set_local_only(True)
+
+        dlg.show()
+
+    def remove_snippet_revert(self, path, piter):
+        node = self.snippet_from_iter(self.model, piter)
+        Library().revert_snippet(node)
+
+        return piter
+
+    def remove_snippet_delete(self, path, piter):
+        node = self.snippet_from_iter(self.model, piter)
+        parent = self.model.iter_parent(piter)
+
+        Library().remove_snippet(node)
+        idx = path.get_indices()
+
+        if self.model.remove(piter):
+            return piter
+        elif idx[-1] != 0:
+            self.select_iter(self.model.get_iter((idx[0], idx[1] - 1)))
+        else:
+            dummy = self.add_new_snippet_node(parent)
+            self.tree_view.expand_row(self.model.get_path(parent), False)
+            return dummy
+
+    def on_remove_snippet_button_clicked(self, button):
+        override, remove, system = self.selected_snippets_state()
+
+        if not (override ^ remove) or system:
+            return
+
+        paths = self.selected_snippets(include_languages=False, as_path=True)
+
+        if override:
+            action = self.remove_snippet_revert
+        else:
+            action = self.remove_snippet_delete
+
+        # Remove selection
+        self.tree_view.get_selection().unselect_all()
+
+        # Create tree row references
+        references = []
+        for path in paths:
+            # FIXME: this should be fixed in pygobject or something
+            references.append(Gtk.TreeRowReference.new(self.model, path))
+
+        # Remove/revert snippets
+        select = None
+        for reference in references:
+            path = reference.get_path()
+            piter = self.model.get_iter(path)
+
+            res = action(path, piter)
+
+            if res:
+                select = res
+
+        if select:
+            self.select_iter(select)
+
+        self.selection_changed()
+
+    def set_accelerator(self, keyval, mod):
+        accelerator = Gtk.accelerator_name(keyval, mod)
+        self.snippet['accelerator'] = accelerator
+
+        return True
+
+    def on_entry_accelerator_key_press(self, entry, event):
+        if event.keyval == Gdk.keyval_from_name('Escape'):
+            # Reset
+            entry.set_text(self.snippet.accelerator_display())
+            self.tree_view.grab_focus()
 
-                        self.snippet_changed()
-                        return True
-                elif Library().valid_accelerator(event.keyval, event.get_state()):
-                        # New accelerator
-                        self.set_accelerator(event.keyval, \
-                                        event.get_state() & Gtk.accelerator_get_default_mod_mask())
-                        entry.set_text(self.snippet.accelerator_display())
-                        self.snippet_changed()
-                        self.tree_view.grab_focus()
+            return True
+        elif event.keyval == Gdk.keyval_from_name('Delete') or \
+                event.keyval == Gdk.keyval_from_name('BackSpace'):
+            # Remove the accelerator
+            entry.set_text('')
+            self.snippet['accelerator'] = ''
+            self.tree_view.grab_focus()
 
-                else:
-                        return True
+            self.snippet_changed()
+            return True
+        elif Library().valid_accelerator(event.keyval, event.get_state()):
+            # New accelerator
+            self.set_accelerator(event.keyval, \
+                    event.get_state() & Gtk.accelerator_get_default_mod_mask())
+            entry.set_text(self.snippet.accelerator_display())
+            self.snippet_changed()
+            self.tree_view.grab_focus()
 
-        def on_entry_accelerator_focus_in(self, entry, event):
-                if self.snippet['accelerator']:
-                        entry.set_text(_('Type a new shortcut, or press Backspace to clear'))
-                else:
-                        entry.set_text(_('Type a new shortcut'))
+        else:
+            return True
 
-        def update_language_path(self):
-                model, paths = self.tree_view.get_selection().get_selected_rows()
+    def on_entry_accelerator_focus_in(self, entry, event):
+        if self.snippet['accelerator']:
+            entry.set_text(_('Type a new shortcut, or press Backspace to clear'))
+        else:
+            entry.set_text(_('Type a new shortcut'))
 
-                # Check if all have the same language parent
+    def update_language_path(self):
+        model, paths = self.tree_view.get_selection().get_selected_rows()
+
+        # Check if all have the same language parent
+        current_parent = None
+
+        for path in paths:
+            piter = model.get_iter(path)
+            parent = model.iter_parent(piter)
+
+            if parent:
+                path = model.get_path(parent)
+
+            if current_parent != None and current_parent != path:
                 current_parent = None
+                break
+            else:
+                current_parent = path
 
-                for path in paths:
-                        piter = model.get_iter(path)
-                        parent = model.iter_parent(piter)
+        self.language_path = current_parent
 
-                        if parent:
-                                path = model.get_path(parent)
+    def on_tree_view_selection_changed(self, selection):
+        parent, piter, node = self.selected_snippet()
 
-                        if current_parent != None and current_parent != path:
-                                current_parent = None
-                                break
-                        else:
-                                current_parent = path
+        if self.snippet:
+            self.on_entry_tab_trigger_focus_out(self['entry_tab_trigger'],
+                    None)
+            self.on_source_view_snippet_focus_out(self['source_view_snippet'],
+                    None)
+            self.on_entry_drop_targets_focus_out(self['combo_drop_targets'].get_child(),
+                    None)
 
-                self.language_path = current_parent
+        self.update_language_path()
 
-        def on_tree_view_selection_changed(self, selection):
-                parent, piter, node = self.selected_snippet()
+        if node:
+            self.snippet = Snippet(node)
+        else:
+            self.snippet = None
 
-                if self.snippet:
-                        self.on_entry_tab_trigger_focus_out(self['entry_tab_trigger'],
-                                        None)
-                        self.on_source_view_snippet_focus_out(self['source_view_snippet'],
-                                        None)
-                        self.on_entry_drop_targets_focus_out(self['combo_drop_targets'].get_child(),
-                                        None)
+        self.selection_changed()
 
-                self.update_language_path()
+    def iter_after(self, target, after):
+        if not after:
+            return True
 
-                if node:
-                        self.snippet = Snippet(node)
-                else:
-                        self.snippet = None
-
-                self.selection_changed()
+        tp = self.model.get_path(target)
+        ap = self.model.get_path(after)
 
-        def iter_after(self, target, after):
-                if not after:
-                        return True
+        if tp[0] > ap[0] or (tp[0] == ap[0] and (len(ap) == 1 or tp[1] > ap[1])):
+            return True
 
-                tp = self.model.get_path(target)
-                ap = self.model.get_path(after)
+        return False
 
-                if tp[0] > ap[0] or (tp[0] == ap[0] and (len(ap) == 1 or tp[1] > ap[1])):
-                        return True
+    def on_tree_view_snippets_key_press(self, treeview, event):
+        if event.keyval == Gdk.keyval_from_name('Delete'):
+            self.on_remove_snippet_button_clicked(None)
+            return True
 
-                return False
+    def on_tree_view_snippets_row_expanded(self, treeview, piter, path):
+        # Check if it is already filled
+        self.fill_if_needed(piter)
+        self.select_iter(piter)
 
-        def on_tree_view_snippets_key_press(self, treeview, event):
-                if event.keyval == Gdk.keyval_from_name('Delete'):
-                        self.on_remove_snippet_button_clicked(None)
-                        return True
+    def on_entry_drop_targets_drag_data_received(self, entry, context, x, y, selection_data, info, 
timestamp):
+        uris = helper.drop_get_uris(selection_data)
+        if not uris:
+            return
 
-        def on_tree_view_snippets_row_expanded(self, treeview, piter, path):
-                # Check if it is already filled
-                self.fill_if_needed(piter)
-                self.select_iter(piter)
+        text = entry.get_text()
 
-        def on_entry_drop_targets_drag_data_received(self, entry, context, x, y, selection_data, info, 
timestamp):
-                uris = drop_get_uris(selection_data)
-                if not uris:
-                        return
-
-                text = entry.get_text()
-
-                if text:
-                        mimes = [text]
-                else:
-                        mimes = []
+        if text:
+            mimes = [text]
+        else:
+            mimes = []
 
-                for uri in uris:
-                        try:
-                                mime = Gio.content_type_guess(uri)
-                        except:
-                                mime = None
+        for uri in uris:
+            try:
+                mime = Gio.content_type_guess(uri)
+            except:
+                mime = None
 
-                        if mime:
-                                mimes.append(mime)
+            if mime:
+                mimes.append(mime)
 
-                entry.set_text(', '.join(mimes))
-                self.on_entry_drop_targets_focus_out(entry, None)
-                context.finish(True, False, timestamp)
+        entry.set_text(', '.join(mimes))
+        self.on_entry_drop_targets_focus_out(entry, None)
+        context.finish(True, False, timestamp)
 
-                entry.stop_emission('drag_data_received')
+        entry.stop_emission('drag_data_received')
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/parser.py b/plugins/snippets/snippets/parser.py
index 628db4e..2b6043d 100644
--- a/plugins/snippets/snippets/parser.py
+++ b/plugins/snippets/snippets/parser.py
@@ -15,245 +15,242 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-import os
 import re
-import sys
-from .substitutionparser import SubstitutionParser
 
 class Token:
-        def __init__(self, klass, data):
-                self.klass = klass
-                self.data = data
+    def __init__(self, klass, data):
+        self.klass = klass
+        self.data = data
 
-        def __str__(self):
-                return '%s: [%s]' % (self.klass, self.data)
+    def __str__(self):
+        return '%s: [%s]' % (self.klass, self.data)
 
-        def __eq__(self, other):
-                return self.klass == other.klass and self.data == other.data
+    def __eq__(self, other):
+        return self.klass == other.klass and self.data == other.data
 
-        def __ne__(self, other):
-                return not self.__eq__(other)
+    def __ne__(self, other):
+        return not self.__eq__(other)
 
 class Parser:
-        SREG_ENV = '[A-Z_]+'
-        SREG_ID = '[0-9]+'
+    SREG_ENV = '[A-Z_]+'
+    SREG_ID = '[0-9]+'
 
-        REG_ESCAPE = re.compile('(\\$(%s|\\(|\\{|<|%s)|`|\\\\)' % (SREG_ENV, SREG_ID))
+    REG_ESCAPE = re.compile('(\\$(%s|\\(|\\{|<|%s)|`|\\\\)' % (SREG_ENV, SREG_ID))
 
-        def __init__(self, **kwargs):
-                for k, v in kwargs.items():
-                        setattr(self, k, v)
+    def __init__(self, **kwargs):
+        for k, v in kwargs.items():
+            setattr(self, k, v)
 
-                self.position = 0
-                self.data_length = len(self.data)
+        self.position = 0
+        self.data_length = len(self.data)
 
-                self.RULES = (self._match_env, self._match_regex, self._match_placeholder, 
self._match_shell, self._match_eval, self._text)
+        self.RULES = (self._match_env, self._match_regex, self._match_placeholder, self._match_shell, 
self._match_eval, self._text)
 
-        def remains(self):
-                return self.data[self.position:]
+    def remains(self):
+        return self.data[self.position:]
 
-        def next_char(self):
-                if self.position + 1 >= self.data_length:
-                        return ''
-                else:
-                        return self.data[self.position + 1]
+    def next_char(self):
+        if self.position + 1 >= self.data_length:
+            return ''
+        else:
+            return self.data[self.position + 1]
 
-        def char(self):
-                if self.position >= self.data_length:
-                        return ''
-                else:
-                        return self.data[self.position]
+    def char(self):
+        if self.position >= self.data_length:
+            return ''
+        else:
+            return self.data[self.position]
 
-        def token(self):
-                self.tktext = ''
+    def token(self):
+        self.tktext = ''
 
-                while self.position < self.data_length:
-                        try:
-                                # Get first character
-                                func = {'$': self._rule,
-                                        '`': self._try_match_shell}[self.char()]
-                        except:
-                                func = self._text
+        while self.position < self.data_length:
+            try:
+                # Get first character
+                func = {'$': self._rule,
+                    '`': self._try_match_shell}[self.char()]
+            except:
+                func = self._text
 
-                        # Detect end of text token
-                        if func != self._text and self.tktext != '':
-                                return Token('text', self.tktext)
+            # Detect end of text token
+            if func != self._text and self.tktext != '':
+                return Token('text', self.tktext)
 
-                        tk = func()
+            tk = func()
 
-                        if tk:
-                                return tk
+            if tk:
+                return tk
 
-                if self.tktext != '':
-                        return Token('text', self.tktext)
+        if self.tktext != '':
+            return Token('text', self.tktext)
 
-        def _need_escape(self):
-                text = self.remains()[1:]
+    def _need_escape(self):
+        text = self.remains()[1:]
 
-                if text == '':
-                        return False
+        if text == '':
+            return False
 
-                return self.REG_ESCAPE.match(text)
+        return self.REG_ESCAPE.match(text)
 
-        def _escape(self):
-                if not self._need_escape():
-                        return
+    def _escape(self):
+        if not self._need_escape():
+            return
 
-                # Increase position with 1
-                self.position += 1
+        # Increase position with 1
+        self.position += 1
 
-        def _text(self):
-                if self.char() == '\\':
-                        self._escape()
+    def _text(self):
+        if self.char() == '\\':
+            self._escape()
 
-                self.tktext += self.char()
-                self.position += 1
+        self.tktext += self.char()
+        self.position += 1
 
-        def _rule(self):
-                for rule in self.RULES:
-                        res = rule()
+    def _rule(self):
+        for rule in self.RULES:
+            res = rule()
 
-                        if res:
-                                return res
+            if res:
+                return res
 
-        def _match_env(self):
-                text = self.remains()
-                match = re.match('\\$(%s)' % self.SREG_ENV, text) or re.match('\\${(%s)}' % self.SREG_ENV, 
text)
+    def _match_env(self):
+        text = self.remains()
+        match = re.match('\\$(%s)' % self.SREG_ENV, text) or re.match('\\${(%s)}' % self.SREG_ENV, text)
 
-                if match:
-                        self.position += len(match.group(0))
-                        return Token('environment', match.group(1))
+        if match:
+            self.position += len(match.group(0))
+            return Token('environment', match.group(1))
 
-        def _parse_list(self, lst):
-                pos = 0
-                length = len(lst)
-                items = []
-                last = None
+    def _parse_list(self, lst):
+        pos = 0
+        length = len(lst)
+        items = []
+        last = None
 
-                while pos < length:
-                        char = lst[pos]
-                        next = pos < length - 1 and lst[pos + 1]
+        while pos < length:
+            char = lst[pos]
+            next = pos < length - 1 and lst[pos + 1]
 
-                        if char == '\\' and (next == ',' or next == ']'):
-                                char = next
-                                pos += 1
-                        elif char == ',':
-                                if last != None:
-                                        items.append(last)
+            if char == '\\' and (next == ',' or next == ']'):
+                char = next
+                pos += 1
+            elif char == ',':
+                if last != None:
+                    items.append(last)
 
-                                last = None
-                                pos += 1
-                                continue
+                last = None
+                pos += 1
+                continue
 
-                        last = (last != None and last + char) or char
-                        pos += 1
+            last = (last != None and last + char) or char
+            pos += 1
 
-                if last != None:
-                        items.append(last)
+        if last != None:
+            items.append(last)
 
-                return items
+        return items
 
-        def _parse_default(self, default):
-                match = re.match('^\\s*(\\\\)?(\\[((\\\\]|[^\\]])+)\\]\\s*)$', default)
+    def _parse_default(self, default):
+        match = re.match('^\\s*(\\\\)?(\\[((\\\\]|[^\\]])+)\\]\\s*)$', default)
 
-                if not match:
-                        return [default]
+        if not match:
+            return [default]
 
-                groups = match.groups()
+        groups = match.groups()
 
-                if groups[0]:
-                        return [groups[1]]
+        if groups[0]:
+            return [groups[1]]
 
-                return self._parse_list(groups[2])
+        return self._parse_list(groups[2])
 
-        def _match_placeholder(self):
-                text = self.remains()
+    def _match_placeholder(self):
+        text = self.remains()
 
-                match = re.match('\\${(%s)(:((\\\\\\}|[^}])+))?}' % self.SREG_ID, text) or 
re.match('\\$(%s)' % self.SREG_ID, text)
+        match = re.match('\\${(%s)(:((\\\\\\}|[^}])+))?}' % self.SREG_ID, text) or re.match('\\$(%s)' % 
self.SREG_ID, text)
 
-                if not match:
-                        return None
+        if not match:
+            return None
 
-                groups = match.groups()
-                default = ''
-                tabstop = int(groups[0])
-                self.position += len(match.group(0))
+        groups = match.groups()
+        default = ''
+        tabstop = int(groups[0])
+        self.position += len(match.group(0))
 
-                if len(groups) > 1 and groups[2]:
-                        default = self._parse_default(groups[2].replace('\\}', '}'))
+        if len(groups) > 1 and groups[2]:
+            default = self._parse_default(groups[2].replace('\\}', '}'))
 
-                return Token('placeholder', {'tabstop': tabstop, 'default': default})
+        return Token('placeholder', {'tabstop': tabstop, 'default': default})
 
-        def _match_shell(self):
-                text = self.remains()
-                match = re.match('`((%s):)?((\\\\`|[^`])+?)`' % self.SREG_ID, text) or 
re.match('\\$\\(((%s):)?((\\\\\\)|[^\\)])+?)\\)' % self.SREG_ID, text)
+    def _match_shell(self):
+        text = self.remains()
+        match = re.match('`((%s):)?((\\\\`|[^`])+?)`' % self.SREG_ID, text) or 
re.match('\\$\\(((%s):)?((\\\\\\)|[^\\)])+?)\\)' % self.SREG_ID, text)
 
-                if not match:
-                        return None
+        if not match:
+            return None
 
-                groups = match.groups()
-                tabstop = (groups[1] and int(groups[1])) or -1
-                self.position += len(match.group(0))
+        groups = match.groups()
+        tabstop = (groups[1] and int(groups[1])) or -1
+        self.position += len(match.group(0))
 
-                if text[0] == '`':
-                        contents = groups[2].replace('\\`', '`')
-                else:
-                        contents = groups[2].replace('\\)', ')')
+        if text[0] == '`':
+            contents = groups[2].replace('\\`', '`')
+        else:
+            contents = groups[2].replace('\\)', ')')
 
-                return Token('shell', {'tabstop': tabstop, 'contents': contents})
+        return Token('shell', {'tabstop': tabstop, 'contents': contents})
 
-        def _try_match_shell(self):
-                return self._match_shell() or self._text()
+    def _try_match_shell(self):
+        return self._match_shell() or self._text()
 
-        def _eval_options(self, options):
-                reg = re.compile(self.SREG_ID)
-                tabstop = -1
-                depend = []
+    def _eval_options(self, options):
+        reg = re.compile(self.SREG_ID)
+        tabstop = -1
+        depend = []
 
-                options = options.split(':')
+        options = options.split(':')
 
-                for opt in options:
-                        if reg.match(opt):
-                                tabstop = int(opt)
-                        else:
-                                depend += self._parse_list(opt[1:-1])
+        for opt in options:
+            if reg.match(opt):
+                tabstop = int(opt)
+            else:
+                depend += self._parse_list(opt[1:-1])
 
-                return (tabstop, depend)
+        return (tabstop, depend)
 
-        def _match_eval(self):
-                text = self.remains()
+    def _match_eval(self):
+        text = self.remains()
 
-                options = '((%s)|\\[([0-9, ]+)\\])' % self.SREG_ID
-                match = re.match('\\$<((%s:)*)((\\\\>|[^>])+?)>' % options, text)
+        options = '((%s)|\\[([0-9, ]+)\\])' % self.SREG_ID
+        match = re.match('\\$<((%s:)*)((\\\\>|[^>])+?)>' % options, text)
 
-                if not match:
-                        return None
+        if not match:
+            return None
 
-                groups = match.groups()
-                (tabstop, depend) = (groups[0] and self._eval_options(groups[0][:-1])) or (-1, [])
-                self.position += len(match.group(0))
+        groups = match.groups()
+        (tabstop, depend) = (groups[0] and self._eval_options(groups[0][:-1])) or (-1, [])
+        self.position += len(match.group(0))
 
-                return Token('eval', {'tabstop': tabstop, 'dependencies': depend, 'contents': 
groups[5].replace('\\>', '>')})
+        return Token('eval', {'tabstop': tabstop, 'dependencies': depend, 'contents': 
groups[5].replace('\\>', '>')})
 
-        def _match_regex(self):
-                text = self.remains()
+    def _match_regex(self):
+        text = self.remains()
 
-                content = '((?:\\\\[/]|\\\\}|[^/}])+)'
-                match = re.match('\\${(?:(%s):)?\\s*(%s|\\$([A-Z_]+))?[/]%s[/]%s(?:[/]([a-zA-Z]*))?}' % 
(self.SREG_ID, self.SREG_ID, content, content), text)
+        content = '((?:\\\\[/]|\\\\}|[^/}])+)'
+        match = re.match('\\${(?:(%s):)?\\s*(%s|\\$([A-Z_]+))?[/]%s[/]%s(?:[/]([a-zA-Z]*))?}' % 
(self.SREG_ID, self.SREG_ID, content, content), text)
 
-                if not match:
-                        return None
+        if not match:
+            return None
 
-                groups = match.groups()
-                tabstop = (groups[0] and int(groups[0])) or -1
-                inp = (groups[2] or (groups[1] and int(groups[1]))) or ''
+        groups = match.groups()
+        tabstop = (groups[0] and int(groups[0])) or -1
+        inp = (groups[2] or (groups[1] and int(groups[1]))) or ''
 
-                pattern = re.sub('\\\\([/}])', '\\1', groups[3])
-                substitution = re.sub('\\\\([/}])', '\\1', groups[4])
-                modifiers = groups[5] or ''
+        pattern = re.sub('\\\\([/}])', '\\1', groups[3])
+        substitution = re.sub('\\\\([/}])', '\\1', groups[4])
+        modifiers = groups[5] or ''
 
-                self.position += len(match.group(0))
+        self.position += len(match.group(0))
 
-                return Token('regex', {'tabstop': tabstop, 'input': inp, 'pattern': pattern, 'substitution': 
substitution, 'modifiers': modifiers})
+        return Token('regex', {'tabstop': tabstop, 'input': inp, 'pattern': pattern, 'substitution': 
substitution, 'modifiers': modifiers})
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/placeholder.py b/plugins/snippets/snippets/placeholder.py
index 3693e87..9758ba1 100644
--- a/plugins/snippets/snippets/placeholder.py
+++ b/plugins/snippets/snippets/placeholder.py
@@ -17,694 +17,690 @@
 
 import traceback
 import re
-import os
 import sys
 import signal
-import select
 import locale
 import subprocess
-from gi.repository import GObject
+from gi.repository import GObject, Gtk
 
-from .helper import *
+from . import helper
 from .substitutionparser import SubstitutionParser
 
 # These are places in a view where the cursor can go and do things
 class Placeholder:
-        def __init__(self, view, tabstop, environ, defaults, begin):
-                self.ok = True
-                self.done = False
-                self.buf = view.get_buffer()
-                self.view = view
-                self.has_references = False
-                self.mirrors = []
-                self.leave_mirrors = []
-                self.tabstop = tabstop
-                self.environ = environ
-                self.set_default(defaults)
-                self.prev_contents = self.default
-                self.set_mark_gravity()
+    def __init__(self, view, tabstop, environ, defaults, begin):
+        self.ok = True
+        self.done = False
+        self.buf = view.get_buffer()
+        self.view = view
+        self.has_references = False
+        self.mirrors = []
+        self.leave_mirrors = []
+        self.tabstop = tabstop
+        self.environ = environ
+        self.set_default(defaults)
+        self.prev_contents = self.default
+        self.set_mark_gravity()
 
-                if begin:
-                        self.begin = self.buf.create_mark(None, begin, self.mark_gravity[0])
-                else:
-                        self.begin = None
+        if begin:
+            self.begin = self.buf.create_mark(None, begin, self.mark_gravity[0])
+        else:
+            self.begin = None
 
-                self.end = None
+        self.end = None
 
-        def get_environ(self):
-                return self.environ['utf8']
+    def get_environ(self):
+        return self.environ['utf8']
 
-        def __str__(self):
-                return '%s (%s)' % (str(self.__class__), str(self.default))
+    def __str__(self):
+        return '%s (%s)' % (str(self.__class__), str(self.default))
 
-        def set_mark_gravity(self):
-                self.mark_gravity = [True, False]
+    def set_mark_gravity(self):
+        self.mark_gravity = [True, False]
 
-        def set_default(self, defaults):
-                self.default = None
-                self.defaults = []
+    def set_default(self, defaults):
+        self.default = None
+        self.defaults = []
 
-                if not defaults:
-                        return
+        if not defaults:
+            return
 
-                for d in defaults:
-                        dm = self.expand_environment(d)
-
-                        if dm:
-                                self.defaults.append(dm)
+        for d in defaults:
+            dm = self.expand_environment(d)
 
-                                if not self.default:
-                                        self.default = dm
+            if dm:
+                self.defaults.append(dm)
 
-                                if dm != d:
-                                        break
+                if not self.default:
+                    self.default = dm
+
+                if dm != d:
+                    break
 
-        def literal(self, s):
-                return repr(s)
+    def literal(self, s):
+        return repr(s)
 
-        def format_environment(self, s):
-                return s
+    def format_environment(self, s):
+        return s
 
-        def re_environment(self, m):
-                env = self.get_environ()
+    def re_environment(self, m):
+        env = self.get_environ()
 
-                if m.group(1) or not m.group(2) in env:
-                        return '$' + m.group(2)
-                else:
-                        return self.format_environment(env[m.group(2)])
+        if m.group(1) or not m.group(2) in env:
+            return '$' + m.group(2)
+        else:
+            return self.format_environment(env[m.group(2)])
 
-        def expand_environment(self, text):
-                if not text:
-                        return text
+    def expand_environment(self, text):
+        if not text:
+            return text
 
-                return re.sub('(\\\\)?\\$([A-Z_]+)', self.re_environment, text)
+        return re.sub('(\\\\)?\\$([A-Z_]+)', self.re_environment, text)
 
-        def get_iter(self, mark):
-                if mark and not mark.get_deleted():
-                        return self.buf.get_iter_at_mark(mark)
-                else:
-                        return None
+    def get_iter(self, mark):
+        if mark and not mark.get_deleted():
+            return self.buf.get_iter_at_mark(mark)
+        else:
+            return None
 
-        def begin_iter(self):
-                return self.get_iter(self.begin)
+    def begin_iter(self):
+        return self.get_iter(self.begin)
 
-        def end_iter(self):
-                return self.get_iter(self.end)
+    def end_iter(self):
+        return self.get_iter(self.end)
 
-        def run_last(self, placeholders):
-                begin = self.begin_iter()
-                self.end = self.buf.create_mark(None, begin, self.mark_gravity[1])
+    def run_last(self, placeholders):
+        begin = self.begin_iter()
+        self.end = self.buf.create_mark(None, begin, self.mark_gravity[1])
 
-                if self.default:
-                        insert_with_indent(self.view, begin, self.default, False, self)
+        if self.default:
+            helper.insert_with_indent(self.view, begin, self.default, False, self)
 
-        def remove(self, force = False):
-                if self.begin and not self.begin.get_deleted():
-                        self.buf.delete_mark(self.begin)
+    def remove(self, force = False):
+        if self.begin and not self.begin.get_deleted():
+            self.buf.delete_mark(self.begin)
 
-                if self.end and not self.end.get_deleted():
-                        self.buf.delete_mark(self.end)
+        if self.end and not self.end.get_deleted():
+            self.buf.delete_mark(self.end)
 
-        # Do something on beginning this placeholder
-        def enter(self):
-                if not self.begin or self.begin.get_deleted():
-                        return
+    # Do something on beginning this placeholder
+    def enter(self):
+        if not self.begin or self.begin.get_deleted():
+            return
 
-                self.buf.move_mark(self.buf.get_insert(), self.begin_iter())
+        self.buf.move_mark(self.buf.get_insert(), self.begin_iter())
 
-                if self.end:
-                        self.buf.move_mark(self.buf.get_selection_bound(), self.end_iter())
-                else:
-                        self.buf.move_mark(self.buf.get_selection_bound(), self.begin_iter())
+        if self.end:
+            self.buf.move_mark(self.buf.get_selection_bound(), self.end_iter())
+        else:
+            self.buf.move_mark(self.buf.get_selection_bound(), self.begin_iter())
 
-        def get_text(self):
-                if self.begin and self.end:
-                        biter = self.begin_iter()
-                        eiter = self.end_iter()
+    def get_text(self):
+        if self.begin and self.end:
+            biter = self.begin_iter()
+            eiter = self.end_iter()
 
-                        if biter and eiter:
-                                return self.buf.get_text(self.begin_iter(), self.end_iter(), False)
-                        else:
-                                return ''
-                else:
-                        return ''
+            if biter and eiter:
+                return self.buf.get_text(self.begin_iter(), self.end_iter(), False)
+            else:
+                return ''
+        else:
+            return ''
 
-        def add_mirror(self, mirror, onleave = False):
-                mirror.has_references = True
+    def add_mirror(self, mirror, onleave = False):
+        mirror.has_references = True
 
-                if onleave:
-                        self.leave_mirrors.append(mirror)
-                else:
-                        self.mirrors.append(mirror)
+        if onleave:
+            self.leave_mirrors.append(mirror)
+        else:
+            self.mirrors.append(mirror)
 
-        def set_text(self, text):
-                if self.begin.get_deleted() or self.end.get_deleted():
-                        return
+    def set_text(self, text):
+        if self.begin.get_deleted() or self.end.get_deleted():
+            return
 
-                # Set from self.begin to self.end to text!
-                self.buf.begin_user_action()
-                # Remove everything between self.begin and self.end
-                begin = self.begin_iter()
-                self.buf.delete(begin, self.end_iter())
+        # Set from self.begin to self.end to text!
+        self.buf.begin_user_action()
+        # Remove everything between self.begin and self.end
+        begin = self.begin_iter()
+        self.buf.delete(begin, self.end_iter())
 
-                # Insert the text from the mirror
-                insert_with_indent(self.view, begin, text, True, self)
-                self.buf.end_user_action()
+        # Insert the text from the mirror
+        helper.insert_with_indent(self.view, begin, text, True, self)
+        self.buf.end_user_action()
 
-                self.update_contents()
+        self.update_contents()
 
-        def update_contents(self):
-                prev = self.prev_contents
-                self.prev_contents = self.get_text()
+    def update_contents(self):
+        prev = self.prev_contents
+        self.prev_contents = self.get_text()
 
-                if prev != self.get_text():
-                        for mirror in self.mirrors:
-                                if not mirror.update(self):
-                                        return
+        if prev != self.get_text():
+            for mirror in self.mirrors:
+                if not mirror.update(self):
+                    return
 
-        def update_leave_mirrors(self):
-                # Notify mirrors
-                for mirror in self.leave_mirrors:
-                        if not mirror.update(self):
-                                return
+    def update_leave_mirrors(self):
+        # Notify mirrors
+        for mirror in self.leave_mirrors:
+            if not mirror.update(self):
+                return
 
-        # Do something on ending this placeholder
-        def leave(self):
-               self.update_leave_mirrors()
+    # Do something on ending this placeholder
+    def leave(self):
+           self.update_leave_mirrors()
 
-        def find_mirrors(self, text, placeholders):
-                mirrors = []
+    def find_mirrors(self, text, placeholders):
+        mirrors = []
 
-                while (True):
-                        m = re.search('(\\\\)?\\$(?:{([0-9]+)}|([0-9]+))', text)
+        while (True):
+            m = re.search('(\\\\)?\\$(?:{([0-9]+)}|([0-9]+))', text)
 
-                        if not m:
-                                break
+            if not m:
+                break
 
-                        # Skip escaped mirrors
-                        if m.group(1):
-                                text = text[m.end():]
-                                continue
+            # Skip escaped mirrors
+            if m.group(1):
+                text = text[m.end():]
+                continue
 
-                        tabstop = int(m.group(2) or m.group(3))
+            tabstop = int(m.group(2) or m.group(3))
 
-                        if tabstop in placeholders:
-                                if not tabstop in mirrors:
-                                        mirrors.append(tabstop)
+            if tabstop in placeholders:
+                if not tabstop in mirrors:
+                    mirrors.append(tabstop)
 
-                                text = text[m.end():]
-                        else:
-                                self.ok = False
-                                return None
+                text = text[m.end():]
+            else:
+                self.ok = False
+                return None
 
-                return mirrors
+        return mirrors
 
 # This is an placeholder which inserts a mirror of another Placeholder
 class PlaceholderMirror(Placeholder):
-        def __init__(self, view, tabstop, environ, begin):
-                Placeholder.__init__(self, view, -1, environ, None, begin)
-                self.mirror_stop = tabstop
+    def __init__(self, view, tabstop, environ, begin):
+        Placeholder.__init__(self, view, -1, environ, None, begin)
+        self.mirror_stop = tabstop
 
-        def update(self, mirror):
-                self.set_text(mirror.get_text())
-                return True
+    def update(self, mirror):
+        self.set_text(mirror.get_text())
+        return True
 
-        def run_last(self, placeholders):
-                Placeholder.run_last(self, placeholders)
+    def run_last(self, placeholders):
+        Placeholder.run_last(self, placeholders)
 
-                if self.mirror_stop in placeholders:
-                        mirror = placeholders[self.mirror_stop]
+        if self.mirror_stop in placeholders:
+            mirror = placeholders[self.mirror_stop]
 
-                        mirror.add_mirror(self)
+            mirror.add_mirror(self)
 
-                        if mirror.default:
-                                self.set_text(mirror.default)
-                else:
-                        self.ok = False
+            if mirror.default:
+                self.set_text(mirror.default)
+        else:
+            self.ok = False
 
 # This placeholder indicates the end of a snippet
 class PlaceholderEnd(Placeholder):
-        def __init__(self, view, environ, begin, default):
-                Placeholder.__init__(self, view, 0, environ, default, begin)
+    def __init__(self, view, environ, begin, default):
+        Placeholder.__init__(self, view, 0, environ, default, begin)
 
-        def run_last(self, placeholders):
-                Placeholder.run_last(self, placeholders)
+    def run_last(self, placeholders):
+        Placeholder.run_last(self, placeholders)
 
-                # Remove the begin mark and set the begin mark
-                # to the end mark, this is needed so the end placeholder won't contain
-                # any text
+        # Remove the begin mark and set the begin mark
+        # to the end mark, this is needed so the end placeholder won't contain
+        # any text
 
-                if not self.default:
-                        self.mark_gravity[0] = False
-                        self.buf.delete_mark(self.begin)
-                        self.begin = self.buf.create_mark(None, self.end_iter(), self.mark_gravity[0])
+        if not self.default:
+            self.mark_gravity[0] = False
+            self.buf.delete_mark(self.begin)
+            self.begin = self.buf.create_mark(None, self.end_iter(), self.mark_gravity[0])
 
-        def enter(self):
-                if self.begin and not self.begin.get_deleted():
-                        self.buf.move_mark(self.buf.get_insert(), self.begin_iter())
+    def enter(self):
+        if self.begin and not self.begin.get_deleted():
+            self.buf.move_mark(self.buf.get_insert(), self.begin_iter())
 
-                if self.end and not self.end.get_deleted():
-                        self.buf.move_mark(self.buf.get_selection_bound(), self.end_iter())
+        if self.end and not self.end.get_deleted():
+            self.buf.move_mark(self.buf.get_selection_bound(), self.end_iter())
 
-        def leave(self):
-                self.enter()
+    def leave(self):
+        self.enter()
 
 # This placeholder is used to expand a command with embedded mirrors
 class PlaceholderExpand(Placeholder):
-        def __init__(self, view, tabstop, environ, begin, s):
-                Placeholder.__init__(self, view, tabstop, environ, None, begin)
-
-                self.mirror_text = {0: ''}
-                self.timeout_id = None
-                self.cmd = s
-                self.instant_update = False
+    def __init__(self, view, tabstop, environ, begin, s):
+        Placeholder.__init__(self, view, tabstop, environ, None, begin)
 
-        def __str__(self):
-                s = Placeholder.__str__(self)
+        self.mirror_text = {0: ''}
+        self.timeout_id = None
+        self.cmd = s
+        self.instant_update = False
 
-                return s + ' ' + self.cmd
+    def __str__(self):
+        s = Placeholder.__str__(self)
 
-        def get_mirrors(self, placeholders):
-                return self.find_mirrors(self.cmd, placeholders)
+        return s + ' ' + self.cmd
 
-        # Check if all substitution placeholders are accounted for
-        def run_last(self, placeholders):
-                Placeholder.run_last(self, placeholders)
+    def get_mirrors(self, placeholders):
+        return self.find_mirrors(self.cmd, placeholders)
 
-                self.ok = True
-                mirrors = self.get_mirrors(placeholders)
+    # Check if all substitution placeholders are accounted for
+    def run_last(self, placeholders):
+        Placeholder.run_last(self, placeholders)
 
-                if mirrors:
-                        allDefault = True
+        self.ok = True
+        mirrors = self.get_mirrors(placeholders)
 
-                        for mirror in mirrors:
-                                p = placeholders[mirror]
-                                p.add_mirror(self, not self.instant_update)
-                                self.mirror_text[p.tabstop] = p.default
+        if mirrors:
+            allDefault = True
 
-                                if not p.default and not isinstance(p, PlaceholderExpand):
-                                        allDefault = False
+            for mirror in mirrors:
+                p = placeholders[mirror]
+                p.add_mirror(self, not self.instant_update)
+                self.mirror_text[p.tabstop] = p.default
 
-                        if allDefault:
-                                self.update(None)
-                                self.default = self.get_text() or None
-                else:
-                        self.update(None)
-                        self.default = self.get_text() or None
+                if not p.default and not isinstance(p, PlaceholderExpand):
+                    allDefault = False
 
-                        if self.tabstop == -1:
-                                self.done = True
+            if allDefault:
+                self.update(None)
+                self.default = self.get_text() or None
+        else:
+            self.update(None)
+            self.default = self.get_text() or None
 
-        def re_placeholder(self, m, formatter):
-                if m.group(1):
-                        return '"$' + m.group(2) + '"'
-                else:
-                        if m.group(3):
-                                index = int(m.group(3))
-                        else:
-                                index = int(m.group(4))
+            if self.tabstop == -1:
+                self.done = True
 
-                        return formatter(self.mirror_text[index])
+    def re_placeholder(self, m, formatter):
+        if m.group(1):
+            return '"$' + m.group(2) + '"'
+        else:
+            if m.group(3):
+                index = int(m.group(3))
+            else:
+                index = int(m.group(4))
 
-        def remove_timeout(self):
-                if self.timeout_id != None:
-                        GObject.source_remove(self.timeout_id)
-                        self.timeout_id = None
+            return formatter(self.mirror_text[index])
 
-        def install_timeout(self):
-                self.remove_timeout()
-                self.timeout_id = GObject.timeout_add(1000, self.timeout_cb)
+    def remove_timeout(self):
+        if self.timeout_id != None:
+            GObject.source_remove(self.timeout_id)
+            self.timeout_id = None
 
-        def timeout_cb(self):
-                self.timeout_id = None
+    def install_timeout(self):
+        self.remove_timeout()
+        self.timeout_id = GObject.timeout_add(1000, self.timeout_cb)
 
-                return False
+    def timeout_cb(self):
+        self.timeout_id = None
 
-        def format_environment(self, text):
-                return self.literal(text)
+        return False
 
-        def substitute(self, text, formatter = None):
-                formatter = formatter or self.literal
+    def format_environment(self, text):
+        return self.literal(text)
 
-                # substitute all mirrors, but also environmental variables
-                text = re.sub('(\\\\)?\\$({([0-9]+)}|([0-9]+))', lambda m: self.re_placeholder(m, formatter),
-                                text)
+    def substitute(self, text, formatter = None):
+        formatter = formatter or self.literal
 
-                return self.expand_environment(text)
+        # substitute all mirrors, but also environmental variables
+        text = re.sub('(\\\\)?\\$({([0-9]+)}|([0-9]+))', lambda m: self.re_placeholder(m, formatter),
+                text)
 
-        def run_update(self):
-                text = self.substitute(self.cmd)
+        return self.expand_environment(text)
 
-                if text:
-                        ret = self.expand(text)
+    def run_update(self):
+        text = self.substitute(self.cmd)
 
-                        if ret:
-                                self.update_leave_mirrors()
-                else:
-                        ret = True
+        if text:
+            ret = self.expand(text)
 
-                return ret
+            if ret:
+                self.update_leave_mirrors()
+        else:
+            ret = True
 
-        def update(self, mirror):
-                text = None
+        return ret
 
-                if mirror:
-                        self.mirror_text[mirror.tabstop] = mirror.get_text()
+    def update(self, mirror):
+        if mirror:
+            self.mirror_text[mirror.tabstop] = mirror.get_text()
 
-                        # Check if all substitutions have been made
-                        for tabstop in self.mirror_text:
-                                if tabstop == 0:
-                                        continue
+            # Check if all substitutions have been made
+            for tabstop in self.mirror_text:
+                if tabstop == 0:
+                    continue
 
-                                if self.mirror_text[tabstop] == None:
-                                        return False
+                if self.mirror_text[tabstop] == None:
+                    return False
 
-                return self.run_update()
+        return self.run_update()
 
-        def expand(self, text):
-                return True
+    def expand(self, text):
+        return True
 
 # The shell placeholder executes commands in a subshell
 class PlaceholderShell(PlaceholderExpand):
-        def __init__(self, view, tabstop, environ, begin, s):
-                PlaceholderExpand.__init__(self, view, tabstop, environ, begin, s)
+    def __init__(self, view, tabstop, environ, begin, s):
+        PlaceholderExpand.__init__(self, view, tabstop, environ, begin, s)
 
-                self.shell = None
-                self.remove_me = False
+        self.shell = None
+        self.remove_me = False
 
-        def get_environ(self):
-                return self.environ['noenc']
+    def get_environ(self):
+        return self.environ['noenc']
 
-        def close_shell(self):
-                self.shell.stdout.close()
-                self.shell = None
+    def close_shell(self):
+        self.shell.stdout.close()
+        self.shell = None
 
-        def timeout_cb(self):
-                PlaceholderExpand.timeout_cb(self)
-                self.remove_timeout()
+    def timeout_cb(self):
+        PlaceholderExpand.timeout_cb(self)
+        self.remove_timeout()
 
-                if not self.shell:
-                        return False
+        if not self.shell:
+            return False
 
-                GObject.source_remove(self.watch_id)
-                self.close_shell()
+        GObject.source_remove(self.watch_id)
+        self.close_shell()
 
-                if self.remove_me:
-                        PlaceholderExpand.remove(self)
+        if self.remove_me:
+            PlaceholderExpand.remove(self)
 
-                message_dialog(None, Gtk.MessageType.ERROR, 'Execution of the shell ' \
-                                'command (%s) exceeded the maximum time; ' \
-                                'execution aborted.' % self.command)
+        helper.message_dialog(None, Gtk.MessageType.ERROR, 'Execution of the shell ' \
+                'command (%s) exceeded the maximum time; ' \
+                'execution aborted.' % self.command)
 
-                return False
+        return False
 
-        def process_close(self):
-                self.close_shell()
-                self.remove_timeout()
+    def process_close(self):
+        self.close_shell()
+        self.remove_timeout()
 
-                self.set_text(str.join('', self.shell_output).rstrip('\n'))
+        self.set_text(str.join('', self.shell_output).rstrip('\n'))
 
-                if self.default == None:
-                        self.default = self.get_text()
-                        self.leave()
+        if self.default == None:
+            self.default = self.get_text()
+            self.leave()
 
-                if self.remove_me:
-                        PlaceholderExpand.remove(self, True)
+        if self.remove_me:
+            PlaceholderExpand.remove(self, True)
 
-        def process_cb(self, source, condition):
-                if condition & GObject.IO_IN:
-                        line = source.readline()
+    def process_cb(self, source, condition):
+        if condition & GObject.IO_IN:
+            line = source.readline()
 
-                        if len(line) > 0:
-                                try:
-                                        line = line.decode('utf-8')
-                                except UnicodeDecodeError:
-                                        line = line.decode(locale.getdefaultlocale()[1], errors='replace')
+            if len(line) > 0:
+                try:
+                    line = line.decode('utf-8')
+                except UnicodeDecodeError:
+                    line = line.decode(locale.getdefaultlocale()[1], errors='replace')
 
-                                self.shell_output += line
-                                self.install_timeout()
+                self.shell_output += line
+                self.install_timeout()
 
-                                return True
+                return True
 
-                self.process_close()
-                return False
+        self.process_close()
+        return False
 
-        def literal_replace(self, match):
-                return "\\%s" % (match.group(0))
+    def literal_replace(self, match):
+        return "\\%s" % (match.group(0))
 
-        def literal(self, text):
-                return '"' + re.sub('([\\\\"])', self.literal_replace, text) + '"'
+    def literal(self, text):
+        return '"' + re.sub('([\\\\"])', self.literal_replace, text) + '"'
 
-        def expand(self, text):
-                self.remove_timeout()
+    def expand(self, text):
+        self.remove_timeout()
 
-                if self.shell:
-                        GObject.source_remove(self.watch_id)
-                        self.close_shell()
-
-                popen_args = {
-                        'cwd': None,
-                        'shell': True,
-                        'env': self.get_environ(),
-                        'stdout': subprocess.PIPE
-                }
-
-                self.command = text
-                self.shell = subprocess.Popen(text, **popen_args)
-                self.shell_output = ''
-                self.watch_id = GObject.io_add_watch(self.shell.stdout, GObject.IO_IN | \
-                                GObject.IO_HUP, self.process_cb)
-                self.install_timeout()
+        if self.shell:
+            GObject.source_remove(self.watch_id)
+            self.close_shell()
 
-                return True
+        popen_args = {
+            'cwd': None,
+            'shell': True,
+            'env': self.get_environ(),
+            'stdout': subprocess.PIPE
+        }
+
+        self.command = text
+        self.shell = subprocess.Popen(text, **popen_args)
+        self.shell_output = ''
+        self.watch_id = GObject.io_add_watch(self.shell.stdout, GObject.IO_IN | \
+                GObject.IO_HUP, self.process_cb)
+        self.install_timeout()
 
-        def remove(self, force = False):
-                if not force and self.shell:
-                        # Still executing shell command
-                        self.remove_me = True
-                else:
-                        if force:
-                                self.remove_timeout()
+        return True
 
-                                if self.shell:
-                                        self.close_shell()
+    def remove(self, force = False):
+        if not force and self.shell:
+            # Still executing shell command
+            self.remove_me = True
+        else:
+            if force:
+                self.remove_timeout()
+
+                if self.shell:
+                    self.close_shell()
 
-                        PlaceholderExpand.remove(self, force)
+            PlaceholderExpand.remove(self, force)
 
 class TimeoutError(Exception):
-        def __init__(self, value):
-                self.value = value
+    def __init__(self, value):
+        self.value = value
 
-        def __str__(self):
-                return repr(self.value)
+    def __str__(self):
+        return repr(self.value)
 
 # The python placeholder evaluates commands in python
 class PlaceholderEval(PlaceholderExpand):
-        def __init__(self, view, tabstop, environ, refs, begin, s, namespace):
-                PlaceholderExpand.__init__(self, view, tabstop, environ, begin, s)
+    def __init__(self, view, tabstop, environ, refs, begin, s, namespace):
+        PlaceholderExpand.__init__(self, view, tabstop, environ, begin, s)
+
+        self.fdread = 0
+        self.remove_me = False
+        self.namespace = namespace
+
+        self.refs = []
 
-                self.fdread = 0
-                self.remove_me = False
-                self.namespace = namespace
+        if refs:
+            for ref in refs:
+                self.refs.append(int(ref.strip()))
 
-                self.refs = []
+    def get_mirrors(self, placeholders):
+        mirrors = PlaceholderExpand.get_mirrors(self, placeholders)
 
-                if refs:
-                        for ref in refs:
-                                self.refs.append(int(ref.strip()))
+        if not self.ok:
+            return None
 
-        def get_mirrors(self, placeholders):
-                mirrors = PlaceholderExpand.get_mirrors(self, placeholders)
+        for ref in self.refs:
+            if ref in placeholders:
+                if ref not in mirrors:
+                    mirrors.append(ref)
+            else:
+                self.ok = False
+                return None
 
-                if not self.ok:
-                        return None
+        return mirrors
 
-                for ref in self.refs:
-                        if ref in placeholders:
-                                if ref not in mirrors:
-                                        mirrors.append(ref)
-                        else:
-                                self.ok = False
-                                return None
+    # SIGALRM is not supported on all platforms (e.g. windows). Timeout
+    # with SIGALRM will not be used on those platforms. This will
+    # potentially block gedit if you have a placeholder which gets stuck,
+    # but it's better than not supporting them at all. At some point we
+    # might have proper thread support and we can fix this in a better way
+    def timeout_supported(self):
+        return hasattr(signal, 'SIGALRM')
 
-                return mirrors
+    def timeout_cb(self, signum = 0, frame = 0):
+        raise TimeoutError("Operation timed out (>2 seconds)")
 
-        # SIGALRM is not supported on all platforms (e.g. windows). Timeout
-        # with SIGALRM will not be used on those platforms. This will
-        # potentially block gedit if you have a placeholder which gets stuck,
-        # but it's better than not supporting them at all. At some point we
-        # might have proper thread support and we can fix this in a better way
-        def timeout_supported(self):
-                return hasattr(signal, 'SIGALRM')
+    def install_timeout(self):
+        if not self.timeout_supported():
+            return
 
-        def timeout_cb(self, signum = 0, frame = 0):
-                raise TimeoutError("Operation timed out (>2 seconds)")
+        if self.timeout_id != None:
+            self.remove_timeout()
 
-        def install_timeout(self):
-                if not self.timeout_supported():
-                        return
+        self.timeout_id = signal.signal(signal.SIGALRM, self.timeout_cb)
+        signal.alarm(2)
 
-                if self.timeout_id != None:
-                        self.remove_timeout()
+    def remove_timeout(self):
+        if not self.timeout_supported():
+            return
 
-                self.timeout_id = signal.signal(signal.SIGALRM, self.timeout_cb)
-                signal.alarm(2)
+        if self.timeout_id != None:
+            signal.alarm(0)
 
-        def remove_timeout(self):
-                if not self.timeout_supported():
-                        return
+            signal.signal(signal.SIGALRM, self.timeout_id)
 
-                if self.timeout_id != None:
-                        signal.alarm(0)
+            self.timeout_id = None
 
-                        signal.signal(signal.SIGALRM, self.timeout_id)
+    def expand(self, text):
+        self.remove_timeout()
 
-                        self.timeout_id = None
+        text = text.strip()
+        self.command = text
 
-        def expand(self, text):
+        if not self.command or self.command == '':
+            self.set_text('')
+            return
+
+        text = "def process_snippet():\n\t" + "\n\t".join(text.split("\n"))
+
+        if 'process_snippet' in self.namespace:
+            del self.namespace['process_snippet']
+
+        try:
+            exec(text, self.namespace)
+        except:
+            traceback.print_exc()
+
+        if 'process_snippet' in self.namespace:
+            try:
+                # Install a sigalarm signal. This is a HACK to make sure
+                # gedit doesn't get freezed by someone creating a python
+                # placeholder which for instance loops indefinately. Since
+                # the code is executed synchronously it will hang gedit. With
+                # the alarm signal we raise an exception and catch this
+                # (see below). We show an error message and return False.
+                # ___this is a HACK___ and should be fixed properly (I just
+                # don't know how)
+                self.install_timeout()
+                result = self.namespace['process_snippet']()
+                self.remove_timeout()
+            except TimeoutError:
                 self.remove_timeout()
 
-                text = text.strip()
-                self.command = text
+                helper.message_dialog(None, Gtk.MessageType.ERROR, \
+                    _('Execution of the Python command (%s) exceeds the maximum ' \
+                    'time, execution aborted.') % self.command)
 
-                if not self.command or self.command == '':
-                        self.set_text('')
-                        return
+                return False
+            except Exception as detail:
+                self.remove_timeout()
 
-                text = "def process_snippet():\n\t" + "\n\t".join(text.split("\n"))
+                helper.message_dialog(None, Gtk.MessageType.ERROR,
+                    _('Execution of the Python command (%s) failed: %s') %
+                    (self.command, detail))
 
-                if 'process_snippet' in self.namespace:
-                        del self.namespace['process_snippet']
+                return False
 
-                try:
-                        exec(text, self.namespace)
-                except:
-                        traceback.print_exc()
-
-                if 'process_snippet' in self.namespace:
-                        try:
-                                # Install a sigalarm signal. This is a HACK to make sure
-                                # gedit doesn't get freezed by someone creating a python
-                                # placeholder which for instance loops indefinately. Since
-                                # the code is executed synchronously it will hang gedit. With
-                                # the alarm signal we raise an exception and catch this
-                                # (see below). We show an error message and return False.
-                                # ___this is a HACK___ and should be fixed properly (I just
-                                # don't know how)
-                                self.install_timeout()
-                                result = self.namespace['process_snippet']()
-                                self.remove_timeout()
-                        except TimeoutError:
-                                self.remove_timeout()
-
-                                message_dialog(None, Gtk.MessageType.ERROR, \
-                                _('Execution of the Python command (%s) exceeds the maximum ' \
-                                'time, execution aborted.') % self.command)
-
-                                return False
-                        except Exception as detail:
-                                self.remove_timeout()
-
-                                message_dialog(None, Gtk.MessageType.ERROR,
-                                _('Execution of the Python command (%s) failed: %s') %
-                                (self.command, detail))
-
-                                return False
-
-                        if result == None:
-                                # sys.stderr.write("%s:\n>> %s\n" % (_('The following python code, run in a 
snippet, does not return a value'), "\n>> ".join(self.command.split("\n"))))
-                                result = ''
-
-                        self.set_text(str(result))
+            if result == None:
+                # sys.stderr.write("%s:\n>> %s\n" % (_('The following python code, run in a snippet, does 
not return a value'), "\n>> ".join(self.command.split("\n"))))
+                result = ''
 
-                return True
+            self.set_text(str(result))
+
+        return True
 
 # Regular expression placeholder
 class PlaceholderRegex(PlaceholderExpand):
-        def __init__(self, view, tabstop, environ, begin, inp, pattern, substitution, modifiers):
-                PlaceholderExpand.__init__(self, view, tabstop, environ, begin, '')
+    def __init__(self, view, tabstop, environ, begin, inp, pattern, substitution, modifiers):
+        PlaceholderExpand.__init__(self, view, tabstop, environ, begin, '')
 
-                self.instant_update = True
-                self.inp = inp
-                self.pattern = pattern
-                self.substitution = substitution
+        self.instant_update = True
+        self.inp = inp
+        self.pattern = pattern
+        self.substitution = substitution
 
-                self.init_modifiers(modifiers)
+        self.init_modifiers(modifiers)
 
-        def init_modifiers(self, modifiers):
-                mods = {'I': re.I,
-                        'L': re.L,
-                        'M': re.M,
-                        'S': re.S,
-                        'U': re.U,
-                        'X': re.X}
+    def init_modifiers(self, modifiers):
+        mods = {'I': re.I,
+            'L': re.L,
+            'M': re.M,
+            'S': re.S,
+            'U': re.U,
+            'X': re.X}
 
-                self.modifiers = 0
+        self.modifiers = 0
 
-                for modifier in modifiers:
-                        if modifier in mods:
-                                self.modifiers |= mods[modifier]
+        for modifier in modifiers:
+            if modifier in mods:
+                self.modifiers |= mods[modifier]
 
-        def get_mirrors(self, placeholders):
-                mirrors = self.find_mirrors(self.pattern, placeholders) + 
self.find_mirrors(self.substitution, placeholders)
+    def get_mirrors(self, placeholders):
+        mirrors = self.find_mirrors(self.pattern, placeholders) + self.find_mirrors(self.substitution, 
placeholders)
 
-                if isinstance(self.inp, int):
-                        if self.inp not in placeholders:
-                                self.ok = False
-                                return None
-                        elif self.inp not in mirrors:
-                                mirrors.append(self.inp)
+        if isinstance(self.inp, int):
+            if self.inp not in placeholders:
+                self.ok = False
+                return None
+            elif self.inp not in mirrors:
+                mirrors.append(self.inp)
 
-                return mirrors
+        return mirrors
 
-        def literal(self, s):
-                return re.escape(s)
+    def literal(self, s):
+        return re.escape(s)
 
-        def get_input(self):
-                env = self.get_environ()
+    def get_input(self):
+        env = self.get_environ()
 
-                if isinstance(self.inp, int):
-                        return self.mirror_text[self.inp]
-                elif self.inp in env:
-                        return env[self.inp]
-                else:
-                        return ''
+        if isinstance(self.inp, int):
+            return self.mirror_text[self.inp]
+        elif self.inp in env:
+            return env[self.inp]
+        else:
+            return ''
 
-        def run_update(self):
-                pattern = self.substitute(self.pattern)
-                substitution = self.substitute(self.substitution, SubstitutionParser.escape_substitution)
+    def run_update(self):
+        pattern = self.substitute(self.pattern)
+        substitution = self.substitute(self.substitution, SubstitutionParser.escape_substitution)
 
-                if pattern:
-                        return self.expand(pattern, substitution)
+        if pattern:
+            return self.expand(pattern, substitution)
 
-                return True
+        return True
 
-        def expand(self, pattern, substitution):
-                # Try to compile pattern
-                try:
-                        regex = re.compile(pattern, self.modifiers)
-                except re.error as message:
-                        sys.stderr.write('Could not compile regular expression: %s\n%s\n' % (pattern, 
message))
-                        return False
+    def expand(self, pattern, substitution):
+        # Try to compile pattern
+        try:
+            regex = re.compile(pattern, self.modifiers)
+        except re.error as message:
+            sys.stderr.write('Could not compile regular expression: %s\n%s\n' % (pattern, message))
+            return False
 
-                inp = self.get_input()
-                match = regex.search(inp)
+        inp = self.get_input()
+        match = regex.search(inp)
 
-                if not match:
-                        self.set_text(inp)
-                else:
-                        groups = match.groupdict()
+        if not match:
+            self.set_text(inp)
+        else:
+            groups = match.groupdict()
 
-                        idx = 0
-                        for group in match.groups():
-                                groups[str(idx + 1)] = group
-                                idx += 1
+            idx = 0
+            for group in match.groups():
+                groups[str(idx + 1)] = group
+                idx += 1
 
-                        groups['0'] = match.group(0)
+            groups['0'] = match.group(0)
 
-                        parser = SubstitutionParser(substitution, groups)
-                        self.set_text(parser.parse())
+            parser = SubstitutionParser(substitution, groups)
+            self.set_text(parser.parse())
 
-                return True
+        return True
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/shareddata.py b/plugins/snippets/snippets/shareddata.py
index f3268ac..be6fd14 100644
--- a/plugins/snippets/snippets/shareddata.py
+++ b/plugins/snippets/snippets/shareddata.py
@@ -20,6 +20,9 @@ import os
 
 from gi.repository import Gtk
 
+# To register the GeditSnippetsManager type
+from .manager import Manager
+
 class SharedData(object, metaclass=Singleton):
     def __init__(self):
         self.dlg = None
diff --git a/plugins/snippets/snippets/snippet.py b/plugins/snippets/snippets/snippet.py
index bd21470..6b18156 100644
--- a/plugins/snippets/snippets/snippet.py
+++ b/plugins/snippets/snippets/snippet.py
@@ -15,345 +15,346 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-import os
-from gi.repository import Gio
+from gi.repository import Gio, Gtk
 
-from .placeholder import *
-from .parser import Parser, Token
-from .helper import *
+import sys
+
+from .placeholder import PlaceholderEnd, PlaceholderMirror, Placeholder, PlaceholderShell, PlaceholderEval, 
PlaceholderRegex, PlaceholderExpand
+from .parser import Parser
+from . import helper
 
 class EvalUtilities:
-        def __init__(self, view=None):
-                self.view = view
-                self._init_namespace()
+    def __init__(self, view=None):
+        self.view = view
+        self._init_namespace()
 
-        def _init_namespace(self):
-                self.namespace = {
-                        '__builtins__': __builtins__,
-                        'align': self.util_align,
-                        'readfile': self.util_readfile,
-                        'filesize': self.util_filesize
-                }
+    def _init_namespace(self):
+        self.namespace = {
+            '__builtins__': __builtins__,
+            'align': self.util_align,
+            'readfile': self.util_readfile,
+            'filesize': self.util_filesize
+        }
 
-        def _real_len(self, s, tablen = 0):
-                if tablen == 0:
-                        tablen = self.view.get_tab_width()
+    def _real_len(self, s, tablen = 0):
+        if tablen == 0:
+            tablen = self.view.get_tab_width()
 
-                return len(s.expandtabs(tablen))
+        return len(s.expandtabs(tablen))
 
-        def _filename_to_uri(self, filename):
-                gfile = Gio.file_new_for_path(filename)
+    def _filename_to_uri(self, filename):
+        gfile = Gio.file_new_for_path(filename)
 
-                return gfile.get_uri()
+        return gfile.get_uri()
 
-        def util_readfile(self, filename):
-                stream = Gio.file_new_for_path(filename).read()
+    def util_readfile(self, filename):
+        stream = Gio.file_new_for_path(filename).read()
 
-                if not stream:
-                        return ''
+        if not stream:
+            return ''
 
-                res = stream.read()
-                stream.close()
+        res = stream.read()
+        stream.close()
 
-                return res
+        return res
 
-        def util_filesize(self, filename):
-                gfile = Gio.file_new_for_path(filename)
-                info = gfile.query_info(Gio.FILE_ATTRIBUTE_STANDARD_SIZE)
+    def util_filesize(self, filename):
+        gfile = Gio.file_new_for_path(filename)
+        info = gfile.query_info(Gio.FILE_ATTRIBUTE_STANDARD_SIZE)
 
-                if not info:
-                        return 0
+        if not info:
+            return 0
 
-                return info.get_size()
+        return info.get_size()
 
-        def util_align(self, items):
-                maxlen = []
-                tablen = self.view.get_tab_width()
+    def util_align(self, items):
+        maxlen = []
+        tablen = self.view.get_tab_width()
 
-                for row in range(0, len(items)):
-                        for col in range(0, len(items[row]) - 1):
-                                if row == 0:
-                                        maxlen.append(0)
+        for row in range(0, len(items)):
+            for col in range(0, len(items[row]) - 1):
+                if row == 0:
+                    maxlen.append(0)
 
-                                items[row][col] += "\t"
-                                rl = self._real_len(items[row][col], tablen)
+                items[row][col] += "\t"
+                rl = self._real_len(items[row][col], tablen)
 
-                                if (rl > maxlen[col]):
-                                        maxlen[col] = rl
+                if (rl > maxlen[col]):
+                    maxlen[col] = rl
 
-                result = ''
+        result = ''
 
-                for row in range(0, len(items)):
-                        for col in range(0, len(items[row]) - 1):
-                                item = items[row][col]
+        for row in range(0, len(items)):
+            for col in range(0, len(items[row]) - 1):
+                item = items[row][col]
 
-                                result += item + ("\t" * int(((maxlen[col] - \
-                                                self._real_len(item, tablen)) / tablen)))
+                result += item + ("\t" * int(((maxlen[col] - \
+                        self._real_len(item, tablen)) / tablen)))
 
-                        result += items[row][len(items[row]) - 1]
+            result += items[row][len(items[row]) - 1]
 
-                        if row != len(items) - 1:
-                                result += "\n"
+            if row != len(items) - 1:
+                result += "\n"
 
-                return result
+        return result
 
 class Snippet:
-        def __init__(self, data, environ = {}):
-                self.data = data
-                self.environ = environ
-
-        def __getitem__(self, prop):
-                return self.data[prop]
-
-        def __setitem__(self, prop, value):
-                self.data[prop] = value
-
-        def accelerator_display(self):
-                accel = self['accelerator']
-
-                if accel:
-                        keyval, mod = Gtk.accelerator_parse(accel)
-                        accel = Gtk.accelerator_get_label(keyval, mod)
-
-                return accel or ''
+    def __init__(self, data, environ = {}):
+        self.data = data
+        self.environ = environ
+
+    def __getitem__(self, prop):
+        return self.data[prop]
+
+    def __setitem__(self, prop, value):
+        self.data[prop] = value
+
+    def accelerator_display(self):
+        accel = self['accelerator']
+
+        if accel:
+            keyval, mod = Gtk.accelerator_parse(accel)
+            accel = Gtk.accelerator_get_label(keyval, mod)
+
+        return accel or ''
 
-        def display(self):
-                nm = markup_escape(self['description'])
-
-                tag = self['tag']
-                accel = self.accelerator_display()
-                detail = []
-
-                if tag and tag != '':
-                        detail.append(tag)
-
-                if accel and accel != '':
-                        detail.append(accel)
-
-                if not detail:
-                        return nm
-                else:
-                        return nm + ' (<b>' + markup_escape(', '.join(detail)) + \
-                                        '</b>)'
-
-        def _add_placeholder(self, placeholder):
-                if placeholder.tabstop in self.placeholders:
-                        if placeholder.tabstop == -1:
-                                self.placeholders[-1].append(placeholder)
-                                self.plugin_data.ordered_placeholders.append(placeholder)
-                elif placeholder.tabstop == -1:
-                        self.placeholders[-1] = [placeholder]
-                        self.plugin_data.ordered_placeholders.append(placeholder)
-                else:
-                        self.placeholders[placeholder.tabstop] = placeholder
-                        self.plugin_data.ordered_placeholders.append(placeholder)
-
-        def _insert_text(self, text):
-                # Insert text keeping indentation in mind
-                indented = str.join('\n' + self._indent, spaces_instead_of_tabs(self._view, 
text).split('\n'))
-                self._view.get_buffer().insert(self._insert_iter(), indented)
-
-        def _insert_iter(self):
-                return self._view.get_buffer().get_iter_at_mark(self._insert_mark)
-
-        def _create_environment(self, data):
-                if data in self.environ['utf8']:
-                        val = self.environ['utf8'][data]
-                else:
-                        val = ''
-
-                # Get all the current indentation
-                all_indent = compute_indentation(self._view, self._insert_iter())
-
-                # Substract initial indentation to get the snippet indentation
-                indent = all_indent[len(self._indent):]
-
-                # Keep indentation
-                return str.join('\n' + indent, val.split('\n'))
-
-        def _create_placeholder(self, data):
-                tabstop = data['tabstop']
-                begin = self._insert_iter()
-
-                if tabstop == 0:
-                        # End placeholder
-                        return PlaceholderEnd(self._view, self.environ, begin, data['default'])
-                elif tabstop in self.placeholders:
-                        # Mirror placeholder
-                        return PlaceholderMirror(self._view, tabstop, self.environ, begin)
-                else:
-                        # Default placeholder
-                        return Placeholder(self._view, tabstop, self.environ, data['default'], begin)
-
-        def _create_shell(self, data):
-                begin = self._insert_iter()
-                return PlaceholderShell(self._view, data['tabstop'], self.environ, begin, data['contents'])
-
-        def _create_eval(self, data):
-                begin = self._insert_iter()
-                return PlaceholderEval(self._view, data['tabstop'], self.environ, data['dependencies'], 
begin, data['contents'], self._utils.namespace)
-
-        def _create_regex(self, data):
-                begin = self._insert_iter()
-                return PlaceholderRegex(self._view, data['tabstop'], self.environ, begin, data['input'], 
data['pattern'], data['substitution'], data['modifiers'])
-
-        def _create_text(self, data):
-                return data
-
-        def _invalid_placeholder(self, placeholder, remove):
-                buf = self._view.get_buffer()
-
-                # Remove the text because this placeholder is invalid
-                if placeholder.default and remove:
-                        buf.delete(placeholder.begin_iter(), placeholder.end_iter())
-
-                placeholder.remove()
-
-                if placeholder.tabstop == -1:
-                        index = self.placeholders[-1].index(placeholder)
-                        del self.placeholders[-1][index]
-                else:
-                        del self.placeholders[placeholder.tabstop]
-
-                self.plugin_data.ordered_placeholders.remove(placeholder)
-
-        def _parse(self, plugin_data):
-                # Initialize current variables
-                self._view = plugin_data.view
-                self._indent = compute_indentation(self._view, 
self._view.get_buffer().get_iter_at_mark(self.begin_mark))
-                self._utils = EvalUtilities(self._view)
-                self.placeholders = {}
-                self._insert_mark = self.end_mark
-                self.plugin_data = plugin_data
-
-                # Create parser
-                parser = Parser(data=self['text'])
-
-                # Parse tokens
-                while (True):
-                        token = parser.token()
-
-                        if not token:
-                                break
-
-                        try:
-                                val = {'environment': self._create_environment,
-                                       'placeholder': self._create_placeholder,
-                                       'shell': self._create_shell,
-                                       'eval': self._create_eval,
-                                       'regex': self._create_regex,
-                                       'text': self._create_text}[token.klass](token.data)
-                        except KeyError:
-                                sys.stderr.write('Token class not supported: %s (%s)\n' % token.klass)
-                                continue
-
-                        if isinstance(val, str):
-                                # Insert text
-                                self._insert_text(val)
-                        else:
-                                # Insert placeholder
-                                self._add_placeholder(val)
-
-                # Create end placeholder if there isn't one yet
-                if 0 not in self.placeholders:
-                        self.placeholders[0] = PlaceholderEnd(self._view, self.environ, self.end_iter(), 
None)
-                        self.plugin_data.ordered_placeholders.append(self.placeholders[0])
-
-                # Make sure run_last is ran for all placeholders and remove any
-                # non `ok` placeholders
-                for tabstop in self.placeholders.copy():
-                        ph = (tabstop == -1 and list(self.placeholders[-1])) or [self.placeholders[tabstop]]
-
-                        for placeholder in ph:
-                                placeholder.run_last(self.placeholders)
-
-                                if not placeholder.ok or placeholder.done:
-                                        self._invalid_placeholder(placeholder, not placeholder.ok)
-
-                # Remove all the Expand placeholders which have a tabstop because
-                # they can be used to mirror, but they shouldn't be real tabstops
-                # (if they have mirrors installed). This is problably a bit of
-                # a dirty hack :)
-                if -1 not in self.placeholders:
-                        self.placeholders[-1] = []
-
-                for tabstop in self.placeholders.copy():
-                        placeholder = self.placeholders[tabstop]
-
-                        if tabstop != -1:
-                                if isinstance(placeholder, PlaceholderExpand) and \
-                                   placeholder.has_references:
-                                        # Add to anonymous placeholders
-                                        self.placeholders[-1].append(placeholder)
-
-                                        # Remove placeholder
-                                        del self.placeholders[tabstop]
-
-                self.plugin_data = None
-
-        def insert_into(self, plugin_data, insert):
-                buf = plugin_data.view.get_buffer()
-                last_index = 0
-
-                # Find closest mark at current insertion, so that we may insert
-                # our marks in the correct order
-                (current, next) = plugin_data.next_placeholder()
-
-                if current:
-                        # Insert AFTER current
-                        last_index = plugin_data.placeholders.index(current) + 1
-                elif next:
-                        # Insert BEFORE next
-                        last_index = plugin_data.placeholders.index(next)
-                else:
-                        # Insert at first position
-                        last_index = 0
-
-                # lastIndex now contains the position of the last mark
-                # Create snippet bounding marks
-                self.begin_mark = buf.create_mark(None, insert, True)
-                self.end_mark = buf.create_mark(None, insert, False)
-
-                # Now parse the contents of this snippet, create Placeholders
-                # and insert the placholder marks in the marks array of plugin_data
-                self._parse(plugin_data)
-
-                # So now all of the snippet is in the buffer, we have all our
-                # placeholders right here, what's next, put all marks in the
-                # plugin_data.marks
-                k = sorted(self.placeholders.keys(), reverse=True)
-
-                plugin_data.placeholders.insert(last_index, self.placeholders[0])
-                last_iter = self.placeholders[0].end_iter()
-
-                for tabstop in k:
-                        if tabstop != -1 and tabstop != 0:
-                                placeholder = self.placeholders[tabstop]
-                                end_iter = placeholder.end_iter()
-
-                                if last_iter.compare(end_iter) < 0:
-                                        last_iter = end_iter
-
-                                # Inserting placeholder
-                                plugin_data.placeholders.insert(last_index, placeholder)
-
-                # Move end mark to last placeholder
-                buf.move_mark(self.end_mark, last_iter)
-
-                return self
-
-        def deactivate(self):
-                buf = self.begin_mark.get_buffer()
+    def display(self):
+        nm = helper.markup_escape(self['description'])
+
+        tag = self['tag']
+        accel = self.accelerator_display()
+        detail = []
+
+        if tag and tag != '':
+            detail.append(tag)
+
+        if accel and accel != '':
+            detail.append(accel)
+
+        if not detail:
+            return nm
+        else:
+            return nm + ' (<b>' + helper.markup_escape(', '.join(detail)) + \
+                    '</b>)'
+
+    def _add_placeholder(self, placeholder):
+        if placeholder.tabstop in self.placeholders:
+            if placeholder.tabstop == -1:
+                self.placeholders[-1].append(placeholder)
+                self.plugin_data.ordered_placeholders.append(placeholder)
+        elif placeholder.tabstop == -1:
+            self.placeholders[-1] = [placeholder]
+            self.plugin_data.ordered_placeholders.append(placeholder)
+        else:
+            self.placeholders[placeholder.tabstop] = placeholder
+            self.plugin_data.ordered_placeholders.append(placeholder)
+
+    def _insert_text(self, text):
+        # Insert text keeping indentation in mind
+        indented = str.join('\n' + self._indent, helper.spaces_instead_of_tabs(self._view, text).split('\n'))
+        self._view.get_buffer().insert(self._insert_iter(), indented)
+
+    def _insert_iter(self):
+        return self._view.get_buffer().get_iter_at_mark(self._insert_mark)
+
+    def _create_environment(self, data):
+        if data in self.environ['utf8']:
+            val = self.environ['utf8'][data]
+        else:
+            val = ''
+
+        # Get all the current indentation
+        all_indent = helper.compute_indentation(self._view, self._insert_iter())
+
+        # Substract initial indentation to get the snippet indentation
+        indent = all_indent[len(self._indent):]
+
+        # Keep indentation
+        return str.join('\n' + indent, val.split('\n'))
+
+    def _create_placeholder(self, data):
+        tabstop = data['tabstop']
+        begin = self._insert_iter()
+
+        if tabstop == 0:
+            # End placeholder
+            return PlaceholderEnd(self._view, self.environ, begin, data['default'])
+        elif tabstop in self.placeholders:
+            # Mirror placeholder
+            return PlaceholderMirror(self._view, tabstop, self.environ, begin)
+        else:
+            # Default placeholder
+            return Placeholder(self._view, tabstop, self.environ, data['default'], begin)
+
+    def _create_shell(self, data):
+        begin = self._insert_iter()
+        return PlaceholderShell(self._view, data['tabstop'], self.environ, begin, data['contents'])
+
+    def _create_eval(self, data):
+        begin = self._insert_iter()
+        return PlaceholderEval(self._view, data['tabstop'], self.environ, data['dependencies'], begin, 
data['contents'], self._utils.namespace)
+
+    def _create_regex(self, data):
+        begin = self._insert_iter()
+        return PlaceholderRegex(self._view, data['tabstop'], self.environ, begin, data['input'], 
data['pattern'], data['substitution'], data['modifiers'])
+
+    def _create_text(self, data):
+        return data
+
+    def _invalid_placeholder(self, placeholder, remove):
+        buf = self._view.get_buffer()
+
+        # Remove the text because this placeholder is invalid
+        if placeholder.default and remove:
+            buf.delete(placeholder.begin_iter(), placeholder.end_iter())
+
+        placeholder.remove()
+
+        if placeholder.tabstop == -1:
+            index = self.placeholders[-1].index(placeholder)
+            del self.placeholders[-1][index]
+        else:
+            del self.placeholders[placeholder.tabstop]
+
+        self.plugin_data.ordered_placeholders.remove(placeholder)
+
+    def _parse(self, plugin_data):
+        # Initialize current variables
+        self._view = plugin_data.view
+        self._indent = helper.compute_indentation(self._view, 
self._view.get_buffer().get_iter_at_mark(self.begin_mark))
+        self._utils = EvalUtilities(self._view)
+        self.placeholders = {}
+        self._insert_mark = self.end_mark
+        self.plugin_data = plugin_data
+
+        # Create parser
+        parser = Parser(data=self['text'])
+
+        # Parse tokens
+        while (True):
+            token = parser.token()
+
+            if not token:
+                break
+
+            try:
+                val = {'environment': self._create_environment,
+                       'placeholder': self._create_placeholder,
+                       'shell': self._create_shell,
+                       'eval': self._create_eval,
+                       'regex': self._create_regex,
+                       'text': self._create_text}[token.klass](token.data)
+            except KeyError:
+                sys.stderr.write('Token class not supported: %s (%s)\n' % token.klass)
+                continue
+
+            if isinstance(val, str):
+                # Insert text
+                self._insert_text(val)
+            else:
+                # Insert placeholder
+                self._add_placeholder(val)
+
+        # Create end placeholder if there isn't one yet
+        if 0 not in self.placeholders:
+            self.placeholders[0] = PlaceholderEnd(self._view, self.environ, self.end_iter(), None)
+            self.plugin_data.ordered_placeholders.append(self.placeholders[0])
+
+        # Make sure run_last is ran for all placeholders and remove any
+        # non `ok` placeholders
+        for tabstop in self.placeholders.copy():
+            ph = (tabstop == -1 and list(self.placeholders[-1])) or [self.placeholders[tabstop]]
+
+            for placeholder in ph:
+                placeholder.run_last(self.placeholders)
+
+                if not placeholder.ok or placeholder.done:
+                    self._invalid_placeholder(placeholder, not placeholder.ok)
+
+        # Remove all the Expand placeholders which have a tabstop because
+        # they can be used to mirror, but they shouldn't be real tabstops
+        # (if they have mirrors installed). This is problably a bit of
+        # a dirty hack :)
+        if -1 not in self.placeholders:
+            self.placeholders[-1] = []
+
+        for tabstop in self.placeholders.copy():
+            placeholder = self.placeholders[tabstop]
+
+            if tabstop != -1:
+                if isinstance(placeholder, PlaceholderExpand) and \
+                   placeholder.has_references:
+                    # Add to anonymous placeholders
+                    self.placeholders[-1].append(placeholder)
+
+                    # Remove placeholder
+                    del self.placeholders[tabstop]
+
+        self.plugin_data = None
+
+    def insert_into(self, plugin_data, insert):
+        buf = plugin_data.view.get_buffer()
+        last_index = 0
+
+        # Find closest mark at current insertion, so that we may insert
+        # our marks in the correct order
+        (current, next) = plugin_data.next_placeholder()
+
+        if current:
+            # Insert AFTER current
+            last_index = plugin_data.placeholders.index(current) + 1
+        elif next:
+            # Insert BEFORE next
+            last_index = plugin_data.placeholders.index(next)
+        else:
+            # Insert at first position
+            last_index = 0
+
+        # lastIndex now contains the position of the last mark
+        # Create snippet bounding marks
+        self.begin_mark = buf.create_mark(None, insert, True)
+        self.end_mark = buf.create_mark(None, insert, False)
+
+        # Now parse the contents of this snippet, create Placeholders
+        # and insert the placholder marks in the marks array of plugin_data
+        self._parse(plugin_data)
+
+        # So now all of the snippet is in the buffer, we have all our
+        # placeholders right here, what's next, put all marks in the
+        # plugin_data.marks
+        k = sorted(self.placeholders.keys(), reverse=True)
+
+        plugin_data.placeholders.insert(last_index, self.placeholders[0])
+        last_iter = self.placeholders[0].end_iter()
+
+        for tabstop in k:
+            if tabstop != -1 and tabstop != 0:
+                placeholder = self.placeholders[tabstop]
+                end_iter = placeholder.end_iter()
+
+                if last_iter.compare(end_iter) < 0:
+                    last_iter = end_iter
+
+                # Inserting placeholder
+                plugin_data.placeholders.insert(last_index, placeholder)
+
+        # Move end mark to last placeholder
+        buf.move_mark(self.end_mark, last_iter)
+
+        return self
+
+    def deactivate(self):
+        buf = self.begin_mark.get_buffer()
 
-                buf.delete_mark(self.begin_mark)
-                buf.delete_mark(self.end_mark)
+        buf.delete_mark(self.begin_mark)
+        buf.delete_mark(self.end_mark)
 
-                self.placeholders = {}
+        self.placeholders = {}
 
-        def begin_iter(self):
-                return self.begin_mark.get_buffer().get_iter_at_mark(self.begin_mark)
+    def begin_iter(self):
+        return self.begin_mark.get_buffer().get_iter_at_mark(self.begin_mark)
 
-        def end_iter(self):
-                return self.end_mark.get_buffer().get_iter_at_mark(self.end_mark)
+    def end_iter(self):
+        return self.end_mark.get_buffer().get_iter_at_mark(self.end_mark)
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/substitutionparser.py b/plugins/snippets/snippets/substitutionparser.py
index 45aa1f9..da62f7b 100644
--- a/plugins/snippets/snippets/substitutionparser.py
+++ b/plugins/snippets/snippets/substitutionparser.py
@@ -18,186 +18,186 @@
 import re
 
 class ParseError(Exception):
-        def __str__(self):
-                return 'Parse error, resume next'
+    def __str__(self):
+        return 'Parse error, resume next'
 
 class Modifiers:
-        def _first_char(s):
-                first = (s != '' and s[0]) or ''
-                rest = (len(s) > 1 and s[1:]) or ''
+    def _first_char(s):
+        first = (s != '' and s[0]) or ''
+        rest = (len(s) > 1 and s[1:]) or ''
 
-                return first, rest
+        return first, rest
 
-        def upper_first(s):
-                first, rest = Modifiers._first_char(s)
+    def upper_first(s):
+        first, rest = Modifiers._first_char(s)
 
-                return '%s%s' % (first.upper(), rest)
+        return '%s%s' % (first.upper(), rest)
 
-        def upper(s):
-                return s.upper()
+    def upper(s):
+        return s.upper()
 
-        def lower_first(s):
-                first, rest = Modifiers._first_char(s)
+    def lower_first(s):
+        first, rest = Modifiers._first_char(s)
 
-                return '%s%s' % (first.lower(), rest)
+        return '%s%s' % (first.lower(), rest)
 
-        def lower(s):
-                return s.lower()
+    def lower(s):
+        return s.lower()
 
-        def title(s):
-                return s.title()
+    def title(s):
+        return s.title()
 
-        upper_first = staticmethod(upper_first)
-        upper = staticmethod(upper)
-        lower_first = staticmethod(lower_first)
-        lower = staticmethod(lower)
-        title = staticmethod(title)
-        _first_char = staticmethod(_first_char)
+    upper_first = staticmethod(upper_first)
+    upper = staticmethod(upper)
+    lower_first = staticmethod(lower_first)
+    lower = staticmethod(lower)
+    title = staticmethod(title)
+    _first_char = staticmethod(_first_char)
 
 class SubstitutionParser:
-        REG_ID = '[0-9]+'
-        REG_NAME = '[a-zA-Z_]+'
-        REG_MOD = '[a-zA-Z]+'
-        REG_ESCAPE = '\\\\|\\(\\?|,|\\)'
+    REG_ID = '[0-9]+'
+    REG_NAME = '[a-zA-Z_]+'
+    REG_MOD = '[a-zA-Z]+'
+    REG_ESCAPE = '\\\\|\\(\\?|,|\\)'
 
-        def __init__(self, pattern, groups = {}, modifiers = {}):
-                self.pattern = pattern
-                self.groups = groups
+    REG_GROUP = '(?:(%s)|<(%s|%s)(?:,(%s))?>)' % (REG_ID, REG_ID, REG_NAME, REG_MOD)
 
-                self.REG_GROUP = '(?:(%s)|<(%s|%s)(?:,(%s))?>)' % (self.REG_ID, self.REG_ID, self.REG_NAME, 
self.REG_MOD)
-                self.modifiers = {'u': Modifiers.upper_first,
-                                  'U': Modifiers.upper,
-                                  'l': Modifiers.lower_first,
-                                  'L': Modifiers.lower,
-                                  't': Modifiers.title}
+    def __init__(self, pattern, groups = {}, modifiers = {}):
+        self.pattern = pattern
+        self.groups = groups
 
-                for k, v in modifiers.items():
-                        self.modifiers[k] = v
+        self.modifiers = {'u': Modifiers.upper_first,
+                  'U': Modifiers.upper,
+                  'l': Modifiers.lower_first,
+                  'L': Modifiers.lower,
+                  't': Modifiers.title}
 
-        def parse(self):
-                result, tokens = self._parse(self.pattern, None)
+        for k, v in modifiers.items():
+            self.modifiers[k] = v
 
-                return result
+    def parse(self):
+        result, tokens = self._parse(self.pattern, None)
 
-        def _parse(self, tokens, terminator):
-                result = ''
+        return result
 
-                while tokens != '':
-                        if self._peek(tokens) == '' or self._peek(tokens) == terminator:
-                                tokens = self._remains(tokens)
-                                break
+    def _parse(self, tokens, terminator):
+        result = ''
 
-                        try:
-                                res, tokens = self._expr(tokens, terminator)
-                        except ParseError:
-                                res, tokens = self._text(tokens)
+        while tokens != '':
+            if self._peek(tokens) == '' or self._peek(tokens) == terminator:
+                tokens = self._remains(tokens)
+                break
 
-                        result += res
+            try:
+                res, tokens = self._expr(tokens, terminator)
+            except ParseError:
+                res, tokens = self._text(tokens)
 
-                return result, tokens
+            result += res
 
-        def _peek(self, tokens, num = 0):
-                return (num < len(tokens) and tokens[num])
+        return result, tokens
 
-        def _token(self, tokens):
-                if tokens == '':
-                        return '', '';
+    def _peek(self, tokens, num = 0):
+        return (num < len(tokens) and tokens[num])
 
-                return tokens[0], (len(tokens) > 1 and tokens[1:]) or ''
+    def _token(self, tokens):
+        if tokens == '':
+            return '', '';
 
-        def _remains(self, tokens, num = 1):
-                return (num < len(tokens) and tokens[num:]) or ''
+        return tokens[0], (len(tokens) > 1 and tokens[1:]) or ''
 
-        def _expr(self, tokens, terminator):
-                if tokens == '':
-                        return ''
+    def _remains(self, tokens, num = 1):
+        return (num < len(tokens) and tokens[num:]) or ''
 
-                try:
-                        return {'\\': self._escape,
-                                '(': self._condition}[self._peek(tokens)](tokens, terminator)
-                except KeyError:
-                        raise ParseError
+    def _expr(self, tokens, terminator):
+        if tokens == '':
+            return ''
 
-        def _text(self, tokens):
-                return self._token(tokens)
+        try:
+            return {'\\': self._escape,
+                '(': self._condition}[self._peek(tokens)](tokens, terminator)
+        except KeyError:
+            raise ParseError
 
-        def _substitute(self, group, modifiers = ''):
-                result = (self.groups.has_key(group) and self.groups[group]) or ''
+    def _text(self, tokens):
+        return self._token(tokens)
 
-                for modifier in modifiers:
-                        if self.modifiers.has_key(modifier):
-                                result = self.modifiers[modifier](result)
+    def _substitute(self, group, modifiers = ''):
+        result = (self.groups.has_key(group) and self.groups[group]) or ''
 
-                return result
+        for modifier in modifiers:
+            if self.modifiers.has_key(modifier):
+                result = self.modifiers[modifier](result)
 
-        def _match_group(self, tokens):
-                match = re.match('\\\\%s' % self.REG_GROUP, tokens)
+        return result
 
-                if not match:
-                        return None, tokens
+    def _match_group(self, tokens):
+        match = re.match('\\\\%s' % self.REG_GROUP, tokens)
 
-                return self._substitute(match.group(1) or match.group(2), match.group(3) or ''), 
tokens[match.end():]
+        if not match:
+            return None, tokens
 
-        def _escape(self, tokens, terminator):
-                # Try to match a group
-                result, tokens = self._match_group(tokens)
+        return self._substitute(match.group(1) or match.group(2), match.group(3) or ''), tokens[match.end():]
 
-                if result != None:
-                        return result, tokens
+    def _escape(self, tokens, terminator):
+        # Try to match a group
+        result, tokens = self._match_group(tokens)
 
-                s = self.REG_GROUP
+        if result != None:
+            return result, tokens
 
-                if terminator:
-                        s += '|%s' % re.escape(terminator)
+        s = self.REG_GROUP
 
-                match = re.match('\\\\(\\\\%s|%s)' % (s, self.REG_ESCAPE), tokens)
+        if terminator:
+            s += '|%s' % re.escape(terminator)
 
-                if not match:
-                        raise ParseError
+        match = re.match('\\\\(\\\\%s|%s)' % (s, self.REG_ESCAPE), tokens)
 
-                return match.group(1), tokens[match.end():]
+        if not match:
+            raise ParseError
 
-        def _condition_value(self, tokens):
-                match = re.match('\\\\?%s\s*' % self.REG_GROUP, tokens)
+        return match.group(1), tokens[match.end():]
 
-                if not match:
-                        return None, tokens
+    def _condition_value(self, tokens):
+        match = re.match('\\\\?%s\s*' % self.REG_GROUP, tokens)
 
-                groups = match.groups()
-                name = groups[0] or groups[1]
+        if not match:
+            return None, tokens
 
-                return self.groups.has_key(name) and self.groups[name] != None, tokens[match.end():]
+        groups = match.groups()
+        name = groups[0] or groups[1]
 
-        def _condition(self, tokens, terminator):
-                # Match ? after (
-                if self._peek(tokens, 1) != '?':
-                        raise ParseError
+        return self.groups.has_key(name) and self.groups[name] != None, tokens[match.end():]
 
-                # Remove initial (? token
-                tokens = self._remains(tokens, 2)
-                condition, tokens = self._condition_value(tokens)
+    def _condition(self, tokens, terminator):
+        # Match ? after (
+        if self._peek(tokens, 1) != '?':
+            raise ParseError
 
-                if condition == None or self._peek(tokens) != ',':
-                        raise ParseError
+        # Remove initial (? token
+        tokens = self._remains(tokens, 2)
+        condition, tokens = self._condition_value(tokens)
 
-                truepart, tokens = self._parse(self._remains(tokens), ',')
+        if condition == None or self._peek(tokens) != ',':
+            raise ParseError
 
-                if truepart == None:
-                        raise ParseError
+        truepart, tokens = self._parse(self._remains(tokens), ',')
 
-                falsepart, tokens = self._parse(tokens, ')')
+        if truepart == None:
+            raise ParseError
 
-                if falsepart == None:
-                        raise ParseError
+        falsepart, tokens = self._parse(tokens, ')')
 
-                if condition:
-                        return truepart, tokens
-                else:
-                        return falsepart, tokens
+        if falsepart == None:
+            raise ParseError
 
-        def escape_substitution(substitution):
-                return re.sub('(%s|%s)' % (self.REG_GROUP, self.REG_ESCAPE), '\\\\\\1', substitution)
+        if condition:
+            return truepart, tokens
+        else:
+            return falsepart, tokens
 
-        escapesubstitution = staticmethod(escape_substitution)
+    @staticmethod
+    def escape_substitution(substitution):
+        return re.sub('(%s|%s)' % (SubstitutionParser.REG_GROUP, SubstitutionParser.REG_ESCAPE), '\\\\\\1', 
substitution)
 
-# ex:ts=8:et:
+# ex:ts=4:et:
diff --git a/plugins/snippets/snippets/windowactivatable.py b/plugins/snippets/snippets/windowactivatable.py
index 4ae9c5d..8f2d74a 100644
--- a/plugins/snippets/snippets/windowactivatable.py
+++ b/plugins/snippets/snippets/windowactivatable.py
@@ -15,176 +15,172 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-import re
-import os
-import gettext
+from gi.repository import Gtk, Gedit, GObject
 
-from gi.repository import Gtk, Gdk, Gedit, GObject, Gio
-
-from .document import Document
+from .snippet import Snippet
 from .library import Library
 from .shareddata import SharedData
 from .signals import Signals
 
 class Message(Gedit.Message):
-        view = GObject.property(type=Gedit.View)
-        iter = GObject.property(type=Gtk.TextIter)
+    view = GObject.property(type=Gedit.View)
+    iter = GObject.property(type=Gtk.TextIter)
 
 class Activate(Message):
-        trigger = GObject.property(type=str)
+    trigger = GObject.property(type=str)
 
 class ParseAndActivate(Message):
-        snippet = GObject.property(type=str)
+    snippet = GObject.property(type=str)
 
 class WindowActivatable(GObject.Object, Gedit.WindowActivatable, Signals):
-        __gtype_name__ = "GeditSnippetsWindowActivatable"
+    __gtype_name__ = "GeditSnippetsWindowActivatable"
 
-        window = GObject.property(type=Gedit.Window)
+    window = GObject.property(type=Gedit.Window)
 
-        def __init__(self):
-                GObject.Object.__init__(self)
-                Signals.__init__(self)
+    def __init__(self):
+        GObject.Object.__init__(self)
+        Signals.__init__(self)
 
-                self.current_language_accel_group = None
+        self.current_language_accel_group = None
 
-        def do_activate(self):
-                self.register_messages()
+    def do_activate(self):
+        self.register_messages()
 
-                library = Library()
-                library.add_accelerator_callback(self.accelerator_activated)
+        library = Library()
+        library.add_accelerator_callback(self.accelerator_activated)
 
-                self.accel_group = Library().get_accel_group(None)
+        self.accel_group = Library().get_accel_group(None)
 
-                if self.accel_group:
-                        self.window.add_accel_group(self.accel_group)
+        if self.accel_group:
+            self.window.add_accel_group(self.accel_group)
 
-                self.connect_signal(self.window,
-                                    'active-tab-changed',
-                                    self.on_active_tab_changed)
+        self.connect_signal(self.window,
+                    'active-tab-changed',
+                    self.on_active_tab_changed)
 
-                self.do_update_state()
+        self.do_update_state()
 
-                SharedData().register_window(self)
+        SharedData().register_window(self)
 
-        def do_deactivate(self):
-                if self.accel_group:
-                        self.window.remove_accel_group(self.accel_group)
+    def do_deactivate(self):
+        if self.accel_group:
+            self.window.remove_accel_group(self.accel_group)
 
-                self.accel_group = None
+        self.accel_group = None
 
-                self.unregister_messages()
+        self.unregister_messages()
 
-                library = Library()
-                library.remove_accelerator_callback(self.accelerator_activated)
+        library = Library()
+        library.remove_accelerator_callback(self.accelerator_activated)
 
-                self.disconnect_signals(self.window)
+        self.disconnect_signals(self.window)
 
-                SharedData().unregister_window(self)
+        SharedData().unregister_window(self)
 
-        def do_update_state(self):
-                controller = SharedData().get_active_controller(self.window)
+    def do_update_state(self):
+        controller = SharedData().get_active_controller(self.window)
 
-                self.update_language(controller)
+        self.update_language(controller)
 
-        def register_messages(self):
-                bus = self.window.get_message_bus()
+    def register_messages(self):
+        bus = self.window.get_message_bus()
 
-                bus.register(Activate, '/plugins/snippets', 'activate')
-                bus.register(ParseAndActivate, '/plugins/snippets', 'parse-and-activate')
+        bus.register(Activate, '/plugins/snippets', 'activate')
+        bus.register(ParseAndActivate, '/plugins/snippets', 'parse-and-activate')
 
-                self.signal_ids = set()
+        self.signal_ids = set()
 
-                sid = bus.connect('/plugins/snippets', 'activate', self.on_message_activate, None)
-                self.signal_ids.add(sid)
+        sid = bus.connect('/plugins/snippets', 'activate', self.on_message_activate, None)
+        self.signal_ids.add(sid)
 
-                sid = bus.connect('/plugins/snippets', 'parse-and-activate', 
self.on_message_parse_and_activate, None)
-                self.signal_ids.add(sid)
+        sid = bus.connect('/plugins/snippets', 'parse-and-activate', self.on_message_parse_and_activate, 
None)
+        self.signal_ids.add(sid)
 
-        def unregister_messages(self):
-                bus = self.window.get_message_bus()
-                for sid in self.signal_ids:
-                    bus.disconnect(sid)
-                signal_ids = None
-                bus.unregister_all('/plugins/snippets')
+    def unregister_messages(self):
+        bus = self.window.get_message_bus()
+        for sid in self.signal_ids:
+            bus.disconnect(sid)
+        self.signal_ids = set()
+        bus.unregister_all('/plugins/snippets')
 
-        def on_message_activate(self, bus, message, userdata):
-                view = message.props.view
+    def on_message_activate(self, bus, message, userdata):
+        view = message.props.view
 
-                if not view:
-                        view = self.window.get_active_view()
+        if not view:
+            view = self.window.get_active_view()
 
-                controller = SharedData().get_controller(view)
+        controller = SharedData().get_controller(view)
 
-                if not controller:
-                        return
+        if not controller:
+            return
 
-                iter = message.props.iter
+        iter = message.props.iter
 
-                if not iter:
-                        iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert())
+        if not iter:
+            iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert())
 
-                controller.run_snippet_trigger(message.props.trigger, (iter, iter))
+        controller.run_snippet_trigger(message.props.trigger, (iter, iter))
 
-        def on_message_parse_and_activate(self, bus, message, userdata):
-                view = message.props.view
+    def on_message_parse_and_activate(self, bus, message, userdata):
+        view = message.props.view
 
-                if not view:
-                        view = self.window.get_active_view()
+        if not view:
+            view = self.window.get_active_view()
 
-                controller = SharedData().get_controller(view)
+        controller = SharedData().get_controller(view)
 
-                if not controller:
-                        return
+        if not controller:
+            return
 
-                iter = message.props.iter
-                
-                if not iter:
-                        iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert())
+        iter = message.props.iter
+        
+        if not iter:
+            iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert())
 
-                controller.parse_and_run_snippet(message.props.snippet, iter)
+        controller.parse_and_run_snippet(message.props.snippet, iter)
 
-        def find_snippet(self, snippets, tag):
-                result = []
+    def find_snippet(self, snippets, tag):
+        result = []
 
-                for snippet in snippets:
-                        if Snippet(snippet)['tag'] == tag:
-                                result.append(snippet)
+        for snippet in snippets:
+            if Snippet(snippet)['tag'] == tag:
+                result.append(snippet)
 
-                return result
+        return result
 
-        def update_language(self, controller):
-                if not self.window:
-                        return
+    def update_language(self, controller):
+        if not self.window:
+            return
 
-                if controller:
-                        langid = controller.language_id
-                else:
-                        langid = None
+        if controller:
+            langid = controller.language_id
+        else:
+            langid = None
 
-                if langid != None:
-                        accelgroup = Library().get_accel_group(langid)
-                else:
-                        accelgroup = None
+        if langid != None:
+            accelgroup = Library().get_accel_group(langid)
+        else:
+            accelgroup = None
 
-                if accelgroup != self.current_language_accel_group:
-                        if self.current_language_accel_group:
-                                self.window.remove_accel_group(self.current_language_accel_group)
+        if accelgroup != self.current_language_accel_group:
+            if self.current_language_accel_group:
+                self.window.remove_accel_group(self.current_language_accel_group)
 
-                        if accelgroup:
-                                self.window.add_accel_group(accelgroup)
+            if accelgroup:
+                self.window.add_accel_group(accelgroup)
 
-                self.current_language_accel_group = accelgroup
+        self.current_language_accel_group = accelgroup
 
-        def on_active_tab_changed(self, window, tab):
-                self.update_language(SharedData().get_controller(tab.get_view()))
+    def on_active_tab_changed(self, window, tab):
+        self.update_language(SharedData().get_controller(tab.get_view()))
 
-        def accelerator_activated(self, group, obj, keyval, mod):
-                if obj == self.window:
-                        controller = SharedData().get_active_controller(self.window)
+    def accelerator_activated(self, group, obj, keyval, mod):
+        if obj == self.window:
+            controller = SharedData().get_active_controller(self.window)
 
-                        if controller:
-                                return controller.accelerator_activate(keyval, mod)
-                else:
-                        return False
+            if controller:
+                return controller.accelerator_activate(keyval, mod)
+        else:
+            return False
 
-# ex:ts=8:et:
+# ex:ts=4:et:



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