[gedit] Fix environment envoding for snippets



commit 64b82ea29a95f0b94031e20f43848d831dac8ec6
Author: Jesse van den Kieboom <jessevdk gnome org>
Date:   Sat Jan 28 15:05:14 2012 +0100

    Fix environment envoding for snippets
    
    The environment for snippets was not correctly
    setup. In particular, not all strings were
    encoded in utf-8, leading to problems when
    for example filenames were not encoded in utf-8
    and used in placeholders.
    
    This commit introduces two separate environments,
    one with proper encoded utf-8 and one with the
    original encoding of all the various strings.
    The original encoding environment is used only
    for shell placeholders.

 plugins/snippets/snippets/document.py    |  282 ++++++++++++++++--------------
 plugins/snippets/snippets/placeholder.py |   49 +++--
 plugins/snippets/snippets/snippet.py     |   32 ++--
 3 files changed, 197 insertions(+), 166 deletions(-)
---
diff --git a/plugins/snippets/snippets/document.py b/plugins/snippets/snippets/document.py
index 86ddc23..119acae 100644
--- a/plugins/snippets/snippets/document.py
+++ b/plugins/snippets/snippets/document.py
@@ -308,124 +308,190 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
                 (current, prev) = self.previous_placeholder()
                 return self.goto_placeholder(current, prev)
 
+        def string_in_native_doc_encoding(self, buf, s):
+                enc = buf.get_encoding()
+
+                if not enc or enc.get_charset() == 'UTF-8':
+                        return s
+
+                try:
+                        cv = GLib.convert(s, -1, enc.get_charset(), 'UTF-8')
+                        return cv[0]
+                except GLib.GError:
+                        pass
+
+                return s
+
         def env_get_selected_text(self, buf):
                 bounds = buf.get_selection_bounds()
 
                 if bounds:
-                        return unicode(buf.get_text(bounds[0], bounds[1], False), 'utf-8')
+                        u8 = unicode(buf.get_text(bounds[0], bounds[1], False), 'utf-8')
+
+                        return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)}
                 else:
-                        return ''
+                        return u''
 
         def env_get_current_word(self, buf):
                 start, end = buffer_word_boundary(buf)
+                enc = buf.get_encoding()
+
+                u8 = unicode(buf.get_text(start, end, False), 'utf-8')
 
-                return unicode(buf.get_text(start, end, False), 'utf-8')
+                return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)}
 
         def env_get_current_line(self, buf):
                 start, end = buffer_line_boundary(buf)
 
-                return unicode(buf.get_text(start, end, False), 'utf-8')
+                u8 = unicode(buf.get_text(start, end, False), 'utf-8')
+
+                return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)}
 
         def env_get_current_line_number(self, buf):
                 start, end = buffer_line_boundary(buf)
 
-                return unicode(start.get_line() + 1)
+                return unicode(str(start.get_line() + 1), 'utf-8')
 
-        def env_get_document_uri(self, buf):
-                location = buf.get_location()
+        def location_uri_for_env(self, location):
+                if not location:
+                        return {'utf8': u'', 'noenc': u''}
 
+                u8 = unicode(location.get_parse_name(), 'utf-8')
+
+                if location.has_uri_scheme('file'):
+                        u8 = "file://" + u8
+
+                return {'utf8': u8, 'noenc': location.get_uri()}
+
+        def location_name_for_env(self, location):
                 if location:
-                        return location.get_uri()
-                else:
-                        return ''
+                        info = location.query_info("standard::display-name", 0, None)
 
-        def env_get_document_name(self, buf):
-                location = buf.get_location()
+                        return {'utf8': unicode(info.get_display_name(), 'utf-8'),
+                                'noenc': location.get_basename()}
+                else:
+                        return u''
 
+        def location_scheme_for_env(self, location):
                 if location:
-                        return location.get_basename()
+                        return unicode(location.get_uri_scheme(), 'utf-8')
                 else:
-                        return ''
+                        return u''
 
-        def env_get_document_scheme(self, buf):
-                location = buf.get_location()
+        def location_path_for_env(self, location):
+                if location and location.has_uri_scheme('file'):
+                        return {'utf8': unicode(location.get_parse_name(), 'utf-8'),
+                                'noenc': location.get_path()}
+                else:
+                        return u''
 
+        def location_dir_for_env(self, location):
                 if location:
-                        return location.get_uri_scheme()
-                else:
-                        return ''
+                        parent = location.get_parent()
 
-        def env_get_document_path(self, buf):
-                location = buf.get_location()
+                        if parent and parent.has_uri_scheme('file'):
+                                return {'utf8': parent.get_parse_name(),
+                                        'noenc': parent.get_path()}
 
-                if location and Gedit.utils_location_has_file_scheme(location):
-                        return location.get_path()
-                else:
-                        return ''
+                return u''
 
-        def env_get_document_dir(self, buf):
-                location = buf.get_location()
+        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}
 
-                if location:
-                        return location.get_parent().get_path() or ''
-                else:
-                        return ''
+                for k in parts:
+                        v = parts[k](location)
+                        key = prefix + '_' + k
+
+                        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 environ
 
         def env_get_document_type(self, buf):
                 typ = buf.get_mime_type()
 
                 if typ:
-                        return typ
+                        return unicode(typ, 'utf-8')
                 else:
-                        return ''
+                        return u''
 
         def env_get_documents_uri(self, buf):
                 toplevel = self.view.get_toplevel()
 
+                documents_uri = {'utf8': [], 'noenc': []}
+
                 if isinstance(toplevel, Gedit.Window):
-                        documents_uri = [doc.get_location().get_uri()
-                                         for doc in toplevel.get_documents()
-                                         if doc.get_location() is not None]
-                else:
-                        documents_uri = []
+                        for doc in toplevel.get_documents():
+                                r = self.location_uri_for_env(doc.get_location())
+
+                                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))
 
-                return u' '.join(documents_uri)
+                return {'utf8': u' '.join(documents_uri['utf8']),
+                        'noenc': ' '.join(documents_uri['noenc'])}
 
         def env_get_documents_path(self, buf):
                 toplevel = self.view.get_toplevel()
 
+                documents_path = {'utf8': [], 'noenc': []}
+
                 if isinstance(toplevel, Gedit.Window):
-                        documents_location = [doc.get_location()
-                                              for doc in toplevel.get_documents()
-                                              if doc.get_location() is not None]
+                        for doc in toplevel.get_documents():
+                                r = self.location_path_for_env(doc.get_location())
 
-                        documents_path = [location.get_path()
-                                          for location in documents_location
-                                          if Gedit.utils_location_has_file_scheme(location)]
-                else:
-                        documents_path = []
+                                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))
 
-                return u' '.join(documents_path)
+                return {'utf8': u' '.join(documents_path['utf8']),
+                        'noenc': ' '.join(documents_path['noenc'])}
 
-        def update_environment(self):
+        def get_environment(self):
                 buf = self.view.get_buffer()
-
-                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_URI': self.env_get_document_uri,
-                             'GEDIT_CURRENT_DOCUMENT_NAME': self.env_get_document_name,
-                             'GEDIT_CURRENT_DOCUMENT_SCHEME': self.env_get_document_scheme,
-                             'GEDIT_CURRENT_DOCUMENT_PATH': self.env_get_document_path,
-                             'GEDIT_CURRENT_DOCUMENT_DIR': self.env_get_document_dir,
-                             '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,
-                             }
+                environ = {'utf8': {}, 'noenc': {}}
+
+                for k in os.environ:
+                        # Get the original environment, as utf-8
+                        v = os.environ[k]
+                        environ['noenc'][k] = v
+                        environ['utf8'][k] = unicode(os.environ[k], 'utf-8')
+
+                variables = {u'GEDIT_SELECTED_TEXT': self.env_get_selected_text,
+                             u'GEDIT_CURRENT_WORD': self.env_get_current_word,
+                             u'GEDIT_CURRENT_LINE': self.env_get_current_line,
+                             u'GEDIT_CURRENT_LINE_NUMBER': self.env_get_current_line_number,
+                             u'GEDIT_CURRENT_DOCUMENT_TYPE': self.env_get_document_type,
+                             u'GEDIT_DOCUMENTS_URI': self.env_get_documents_uri,
+                             u'GEDIT_DOCUMENTS_PATH': self.env_get_documents_path}
 
                 for var in variables:
-                        os.environ[var] = variables[var](buf)
+                        v = variables[var](buf)
+
+                        if isinstance(v, dict):
+                                environ['utf8'][var] = v['utf8']
+                                environ['noenc'][var] = v['noenc']
+                        else:
+                                environ['utf8'][var] = v
+                                environ['noenc'][var] = str(v)
+
+                self.env_add_for_location(environ, buf.get_location(), 'GEDIT_CURRENT_DOCUMENT')
+
+                return environ
 
         def uses_current_word(self, snippet):
                 matches = re.findall('(\\\\*)\\$GEDIT_CURRENT_WORD', snippet['text'])
@@ -445,12 +511,22 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
 
                 return False
 
-        def apply_snippet(self, snippet, start = None, end = None):
+        def apply_snippet(self, snippet, start = None, end = None, environ = {}):
                 if not snippet.valid:
                         return False
 
+                # Set environmental variables
+                env = self.get_environment()
+
+                if environ:
+                        for k in environ['utf8']:
+                                env['utf8'][k] = environ['utf8'][k]
+
+                        for k in environ['noenc']:
+                                env['noenc'][k] = environ['noenc'][k]
+
                 buf = self.view.get_buffer()
-                s = Snippet(snippet)
+                s = Snippet(snippet, env)
 
                 if not start:
                         start = buf.get_iter_at_mark(buf.get_insert())
@@ -469,9 +545,6 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
                         # it will be removed
                         start, end = buffer_line_boundary(buf)
 
-                # Set environmental variables
-                self.update_environment()
-
                 # You know, we could be in an end placeholder
                 (current, next) = self.next_placeholder()
                 if current and current.__class__ == PlaceholderEnd:
@@ -770,78 +843,23 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
                 else:
                         return components
 
-        def relative_path(self, first, second, mime):
-                prot1 = re.match('(^[a-z]+:\/\/|\/)(.*)', first)
-                prot2 = re.match('(^[a-z]+:\/\/|\/)(.*)', second)
-
-                if not prot1 or not prot2:
-                        return second
-
-                # Different protocols
-                if prot1.group(1) != prot2.group(1):
-                        return second
-
-                # Split on backslash
-                path1 = self.path_split(prot1.group(2))
-                path2 = self.path_split(prot2.group(2))
-
-                # Remove as long as common
-                while path1 and path2 and path1[0] == path2[0]:
-                        path1.pop(0)
-                        path2.pop(0)
-
-                # If we need to ../ more than 3 times, then just return
-                # the absolute path
-                if len(path1) - 1 > 3:
-                        return second
-
-                if mime.startswith('x-directory'):
-                        # directory, special case
-                        if not path2:
-                                result = './'
-                        else:
-                                result = '../' * (len(path1) - 1)
-                else:
-                        # Insert ../
-                        result = '../' * (len(path1) - 1)
-
-                        if not path2:
-                                result = os.path.basename(second)
-
-                if path2:
-                        result += os.path.join(*path2)
-
-                return result
-
         def apply_uri_snippet(self, snippet, mime, uri):
                 # Remove file scheme
                 gfile = Gio.file_new_for_uri(uri)
-                pathname = ''
-                dirname = ''
-                ruri = ''
-
-                if Gedit.utils_location_has_file_scheme(gfile):
-                        pathname = gfile.get_path()
-                        dirname = gfile.get_parent().get_path()
 
-                name = gfile.get_basename()
-                scheme = gfile.get_uri_scheme()
+                environ = {'utf8': {'GEDIT_DROP_DOCUMENT_TYPE': unicode(mime, 'utf-8')},
+                           'noenc': {'GEDIT_DROP_DOCUMENT_TYPE': mime}}
 
-                os.environ['GEDIT_DROP_DOCUMENT_URI'] = uri
-                os.environ['GEDIT_DROP_DOCUMENT_NAME'] = name
-                os.environ['GEDIT_DROP_DOCUMENT_SCHEME'] = scheme
-                os.environ['GEDIT_DROP_DOCUMENT_PATH'] = pathname
-                os.environ['GEDIT_DROP_DOCUMENT_DIR'] = dirname
-                os.environ['GEDIT_DROP_DOCUMENT_TYPE'] = mime
+                self.env_add_for_location(environ, gfile, 'GEDIT_DROP_DOCUMENT')
 
                 buf = self.view.get_buffer()
                 location = buf.get_location()
-                if location:
-                        ruri = location.get_uri()
 
-                relpath = self.relative_path(ruri, uri, mime)
+                relpath = location.get_relative_path(gfile)
 
-                os.environ['GEDIT_DROP_DOCUMENT_RELATIVE_PATH'] = relpath
+                # CHECK: what is the encoding of relpath?
+                environ['utf8']['GEDIT_DROP_DOCUMENT_RELATIVE_PATH'] = unicode(relpath, 'utf-8')
+                environ['noenc']['GEDIT_DROP_DOCUMENT_RELATIVE_PATH'] = relpath
 
                 mark = buf.get_mark('gtk_drag_target')
 
@@ -849,7 +867,7 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
                         mark = buf.get_insert()
 
                 piter = buf.get_iter_at_mark(mark)
-                self.apply_snippet(snippet, piter, piter)
+                self.apply_snippet(snippet, piter, piter, environ)
 
         def in_bounds(self, x, y):
                 rect = self.view.get_visible_rect()
diff --git a/plugins/snippets/snippets/placeholder.py b/plugins/snippets/snippets/placeholder.py
index 2628419..c76e4d8 100644
--- a/plugins/snippets/snippets/placeholder.py
+++ b/plugins/snippets/snippets/placeholder.py
@@ -30,7 +30,7 @@ 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, defaults, begin):
+        def __init__(self, view, tabstop, environ, defaults, begin):
                 self.ok = True
                 self.done = False
                 self.buf = view.get_buffer()
@@ -42,6 +42,8 @@ class Placeholder:
                 self.set_default(defaults)
                 self.prev_contents = self.default
                 self.set_mark_gravity()
+                self.environ = environ
+                self.envkey = 'utf8'
 
                 if begin:
                         self.begin = self.buf.create_mark(None, begin, self.mark_gravity[0])
@@ -50,6 +52,9 @@ class Placeholder:
 
                 self.end = None
 
+        def get_environ(self):
+                return self.environ[self.envkey]
+
         def __str__(self):
                 return '%s (%s)' % (str(self.__class__), str(self.default))
 
@@ -75,7 +80,6 @@ class Placeholder:
                                 if dm != d:
                                         break
 
-
         def literal(self, s):
                 return repr(s)
 
@@ -83,10 +87,12 @@ class Placeholder:
                 return s
 
         def re_environment(self, m):
-                if m.group(1) or not m.group(2) in os.environ:
+                env = self.get_environ()
+
+                if m.group(1) or not m.group(2) in env:
                         return '$' + m.group(2)
                 else:
-                        return self.format_environment(os.environ[m.group(2)])
+                        return self.format_environment(env[m.group(2)])
 
         def expand_environment(self, text):
                 if not text:
@@ -216,8 +222,8 @@ class Placeholder:
 
 # This is an placeholder which inserts a mirror of another Placeholder
 class PlaceholderMirror(Placeholder):
-        def __init__(self, view, tabstop, begin):
-                Placeholder.__init__(self, view, -1, None, begin)
+        def __init__(self, view, tabstop, environ, begin):
+                Placeholder.__init__(self, view, -1, environ, None, begin)
                 self.mirror_stop = tabstop
 
         def update(self, mirror):
@@ -239,8 +245,8 @@ class PlaceholderMirror(Placeholder):
 
 # This placeholder indicates the end of a snippet
 class PlaceholderEnd(Placeholder):
-        def __init__(self, view, begin, default):
-                Placeholder.__init__(self, view, 0, 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)
@@ -266,8 +272,8 @@ class PlaceholderEnd(Placeholder):
 
 # This placeholder is used to expand a command with embedded mirrors
 class PlaceholderExpand(Placeholder):
-        def __init__(self, view, tabstop, begin, s):
-                Placeholder.__init__(self, view, tabstop, None, begin)
+        def __init__(self, view, tabstop, environ, begin, s):
+                Placeholder.__init__(self, view, tabstop, environ, None, begin)
 
                 self.mirror_text = {0: ''}
                 self.timeout_id = None
@@ -381,11 +387,12 @@ class PlaceholderExpand(Placeholder):
 
 # The shell placeholder executes commands in a subshell
 class PlaceholderShell(PlaceholderExpand):
-        def __init__(self, view, tabstop, begin, s):
-                PlaceholderExpand.__init__(self, view, tabstop, 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.envkey = 'noenc'
 
         def close_shell(self):
                 self.shell.stdout.close()
@@ -456,9 +463,9 @@ class PlaceholderShell(PlaceholderExpand):
                         self.close_shell()
 
                 popen_args = {
-                        'cwd'  : None,
+                        'cwd': None,
                         'shell': True,
-                        'env'  : os.environ,
+                        'env': self.get_environ(),
                         'stdout': subprocess.PIPE
                 }
 
@@ -493,8 +500,8 @@ class TimeoutError(Exception):
 
 # The python placeholder evaluates commands in python
 class PlaceholderEval(PlaceholderExpand):
-        def __init__(self, view, tabstop, refs, begin, s, namespace):
-                PlaceholderExpand.__init__(self, view, tabstop, 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
@@ -614,8 +621,8 @@ class PlaceholderEval(PlaceholderExpand):
 
 # Regular expression placeholder
 class PlaceholderRegex(PlaceholderExpand):
-        def __init__(self, view, tabstop, begin, inp, pattern, substitution, modifiers):
-                PlaceholderExpand.__init__(self, view, tabstop, 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
@@ -654,10 +661,12 @@ class PlaceholderRegex(PlaceholderExpand):
                 return re.escape(s)
 
         def get_input(self):
+                env = self.get_environ()
+
                 if isinstance(self.inp, int):
                         return self.mirror_text[self.inp]
-                elif self.inp in os.environ:
-                        return os.environ[self.inp]
+                elif self.inp in env:
+                        return env[self.inp]
                 else:
                         return ''
 
diff --git a/plugins/snippets/snippets/snippet.py b/plugins/snippets/snippets/snippet.py
index 1269efd..b8f5a33 100644
--- a/plugins/snippets/snippets/snippet.py
+++ b/plugins/snippets/snippets/snippet.py
@@ -98,8 +98,9 @@ class EvalUtilities:
                 return result
 
 class Snippet:
-        def __init__(self, data):
+        def __init__(self, data, environ = {}):
                 self.data = data
+                self.environ = environ
 
         def __getitem__(self, prop):
                 return self.data[prop]
@@ -156,7 +157,10 @@ class Snippet:
                 return self._view.get_buffer().get_iter_at_mark(self._insert_mark)
 
         def _create_environment(self, data):
-                val = ((data in os.environ) and os.environ[data]) or ''
+                if data in self.environ['utf8']:
+                        val = self.environ['utf8'][data]
+                else:
+                        val = u''
 
                 # Get all the current indentation
                 all_indent = compute_indentation(self._view, self._insert_iter())
@@ -173,25 +177,25 @@ class Snippet:
 
                 if tabstop == 0:
                         # End placeholder
-                        return PlaceholderEnd(self._view, begin, data['default'])
+                        return PlaceholderEnd(self._view, self.environ, begin, data['default'])
                 elif tabstop in self.placeholders:
                         # Mirror placeholder
-                        return PlaceholderMirror(self._view, tabstop, begin)
+                        return PlaceholderMirror(self._view, tabstop, self.environ, begin)
                 else:
                         # Default placeholder
-                        return Placeholder(self._view, tabstop, data['default'], begin)
+                        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'], begin, data['contents'])
+                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'], data['dependencies'], begin, data['contents'], self._utils.namespace)
+                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'], begin, data['input'], data['pattern'], data['substitution'], data['modifiers'])
+                return PlaceholderRegex(self._view, data['tabstop'], self.environ, begin, data['input'], data['pattern'], data['substitution'], data['modifiers'])
 
         def _create_text(self, data):
                 return data
@@ -234,11 +238,11 @@ class Snippet:
 
                         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)
+                                       '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:
                                 sys.stderr.write('Token class not supported: %s\n' % token.klass)
                                 continue
@@ -252,7 +256,7 @@ class Snippet:
 
                 # Create end placeholder if there isn't one yet
                 if 0 not in self.placeholders:
-                        self.placeholders[0] = PlaceholderEnd(self._view, self.end_iter(), None)
+                        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



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