Merge pull request #725 from ZyX-I/fix-fname-special-chars
Handle non-printable characters properly
This commit is contained in:
commit
417884a3ed
|
@ -1,6 +1,7 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
import sys
|
||||
import codecs
|
||||
|
||||
try:
|
||||
import vim
|
||||
|
@ -113,4 +114,34 @@ class VimEnviron(object):
|
|||
+ value.replace('"', '\\"').replace('\\', '\\\\').replace('\n', '\\n').replace('\0', '')
|
||||
+ '"')
|
||||
|
||||
|
||||
if sys.version_info < (3,):
|
||||
def buffer_name(buf):
|
||||
return buf.name
|
||||
else:
|
||||
vim_bufname = vim_get_func('bufname')
|
||||
def buffer_name(buf): # NOQA
|
||||
try:
|
||||
name = buf.name
|
||||
except UnicodeDecodeError:
|
||||
return vim_bufname(buf.number)
|
||||
else:
|
||||
return name.encode('utf-8') if name else None
|
||||
|
||||
|
||||
vim_strtrans = vim_get_func('strtrans')
|
||||
|
||||
|
||||
def powerline_vim_strtrans_error(e):
|
||||
if not isinstance(e, UnicodeDecodeError):
|
||||
raise NotImplementedError
|
||||
# Assuming &encoding is utf-8 strtrans should not return anything but ASCII
|
||||
# under current circumstances
|
||||
text = vim_strtrans(e.object[e.start:e.end]).decode()
|
||||
return (text, e.end)
|
||||
|
||||
|
||||
codecs.register_error('powerline_vim_strtrans_error', powerline_vim_strtrans_error)
|
||||
|
||||
|
||||
environ = VimEnviron()
|
||||
|
|
|
@ -4,12 +4,15 @@ from powerline.theme import Theme
|
|||
from unicodedata import east_asian_width, combining
|
||||
import os
|
||||
|
||||
|
||||
try:
|
||||
NBSP = unicode(' ', 'utf-8')
|
||||
except NameError:
|
||||
NBSP = ' '
|
||||
|
||||
try:
|
||||
from __builtin__ import unichr as chr
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
def construct_returned_value(rendered_highlighted, segments, output_raw):
|
||||
if output_raw:
|
||||
|
@ -65,6 +68,22 @@ class Renderer(object):
|
|||
python-2) regular string or ``None``.
|
||||
'''
|
||||
|
||||
character_translations = {ord(' '): NBSP}
|
||||
'''Character translations for use in escape() function.
|
||||
|
||||
See documentation of ``unicode.translate`` for details.
|
||||
'''
|
||||
|
||||
np_character_translations = dict(((i, '^' + chr(i + 0x40)) for i in range(0x20)))
|
||||
'''Non-printable character translations
|
||||
|
||||
These are used to transform characters in range 0x00—0x1F into ``^@``,
|
||||
``^A`` and so on. Unilke with ``.escape()`` method (and
|
||||
``character_translations``) result is passed to ``.strwidth()`` method.
|
||||
|
||||
Note: transforms tab into ``^I``.
|
||||
'''
|
||||
|
||||
def __init__(self,
|
||||
theme_config,
|
||||
local_themes,
|
||||
|
@ -262,8 +281,8 @@ class Renderer(object):
|
|||
contents_raw = (segment['_space_left'] * ' ') + contents_raw + (segment['_space_right'] * ' ') + outer_padding
|
||||
|
||||
# Replace spaces with no-break spaces
|
||||
contents_raw = contents_raw.replace(' ', NBSP)
|
||||
divider_raw = divider_raw.replace(' ', NBSP)
|
||||
contents_raw = contents_raw.translate(self.np_character_translations)
|
||||
|
||||
# Apply highlighting to padded dividers and contents
|
||||
if render_highlighted:
|
||||
|
@ -295,11 +314,11 @@ class Renderer(object):
|
|||
segment['_len'] = self.strwidth(segment['_rendered_raw'])
|
||||
yield segment
|
||||
|
||||
@staticmethod
|
||||
def escape(string):
|
||||
@classmethod
|
||||
def escape(cls, string):
|
||||
'''Method that escapes segment contents.
|
||||
'''
|
||||
return string
|
||||
return string.translate(cls.character_translations)
|
||||
|
||||
def hlstyle(fg=None, bg=None, attr=None):
|
||||
'''Output highlight style string.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from powerline.renderers.shell import ShellRenderer
|
||||
|
||||
|
||||
|
@ -8,9 +10,10 @@ class BashPromptRenderer(ShellRenderer):
|
|||
escape_hl_start = '\['
|
||||
escape_hl_end = '\]'
|
||||
|
||||
@staticmethod
|
||||
def escape(string):
|
||||
return string.replace('\\', '\\\\').replace('$', '\\$').replace('`', '\\`')
|
||||
character_translations = ShellRenderer.character_translations.copy()
|
||||
character_translations[ord('$')] = '\\$'
|
||||
character_translations[ord('`')] = '\\`'
|
||||
character_translations[ord('\\')] = '\\\\'
|
||||
|
||||
|
||||
renderer = BashPromptRenderer
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from powerline.renderer import Renderer
|
||||
from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE
|
||||
|
||||
|
@ -19,6 +21,8 @@ class ShellRenderer(Renderer):
|
|||
tmux_escape = False
|
||||
screen_escape = False
|
||||
|
||||
character_translations = Renderer.character_translations.copy()
|
||||
|
||||
def hlstyle(self, fg=None, bg=None, attr=None):
|
||||
'''Highlight a segment.
|
||||
|
||||
|
@ -62,9 +66,5 @@ class ShellRenderer(Renderer):
|
|||
r = '\033P' + r.replace('\033', '\033\033') + '\033\\'
|
||||
return self.escape_hl_start + r + self.escape_hl_end
|
||||
|
||||
@staticmethod
|
||||
def escape(string):
|
||||
return string.replace('\\', '\\\\')
|
||||
|
||||
|
||||
renderer = ShellRenderer
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from powerline.renderer import Renderer
|
||||
from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE
|
||||
|
||||
|
||||
class TmuxRenderer(Renderer):
|
||||
'''Powerline tmux segment renderer.'''
|
||||
|
||||
character_translations = Renderer.character_translations.copy()
|
||||
character_translations[ord('#')] = '##[]'
|
||||
|
||||
def hlstyle(self, fg=None, bg=None, attr=None):
|
||||
'''Highlight a segment.'''
|
||||
# We don't need to explicitly reset attributes, so skip those calls
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from powerline.bindings.vim import vim_get_func, environ
|
||||
from powerline.renderer import Renderer
|
||||
|
@ -11,6 +11,12 @@ import vim
|
|||
import sys
|
||||
|
||||
|
||||
try:
|
||||
from __builtin__ import unichr as chr
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
vim_mode = vim_get_func('mode', rettype=str)
|
||||
mode_translations = {
|
||||
chr(ord('V') - 0x40): '^V',
|
||||
|
@ -21,6 +27,9 @@ mode_translations = {
|
|||
class VimRenderer(Renderer):
|
||||
'''Powerline vim segment renderer.'''
|
||||
|
||||
character_translations = Renderer.character_translations.copy()
|
||||
character_translations[ord('%')] = '%%'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if not hasattr(vim, 'strwidth'):
|
||||
# Hope nobody want to change this at runtime
|
||||
|
@ -97,10 +106,6 @@ class VimRenderer(Renderer):
|
|||
def reset_highlight(self):
|
||||
self.hl_groups.clear()
|
||||
|
||||
@staticmethod
|
||||
def escape(string):
|
||||
return string.replace('%', '%%')
|
||||
|
||||
def hlstyle(self, fg=None, bg=None, attr=None):
|
||||
'''Highlight a segment.
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from powerline.renderers.shell import ShellRenderer
|
||||
|
||||
|
||||
|
@ -8,9 +10,8 @@ class ZshPromptRenderer(ShellRenderer):
|
|||
escape_hl_start = '%{'
|
||||
escape_hl_end = '%}'
|
||||
|
||||
@staticmethod
|
||||
def escape(string):
|
||||
return string.replace('%', '%%').replace('\\', '\\\\')
|
||||
character_translations = ShellRenderer.character_translations.copy()
|
||||
character_translations[ord('%')] = '%%'
|
||||
|
||||
|
||||
renderer = ZshPromptRenderer
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from __future__ import absolute_import, division
|
||||
from __future__ import unicode_literals, absolute_import, division
|
||||
|
||||
import os
|
||||
try:
|
||||
|
@ -8,7 +8,8 @@ try:
|
|||
except ImportError:
|
||||
vim = {} # NOQA
|
||||
|
||||
from powerline.bindings.vim import vim_get_func, getbufvar, vim_getbufoption
|
||||
from powerline.bindings.vim import (vim_get_func, getbufvar, vim_getbufoption,
|
||||
buffer_name)
|
||||
from powerline.theme import requires_segment_info
|
||||
from powerline.lib import add_divider_highlight_group
|
||||
from powerline.lib.vcs import guess, tree_status
|
||||
|
@ -19,8 +20,8 @@ from collections import defaultdict
|
|||
vim_funcs = {
|
||||
'virtcol': vim_get_func('virtcol', rettype=int),
|
||||
'getpos': vim_get_func('getpos'),
|
||||
'fnamemodify': vim_get_func('fnamemodify', rettype=str),
|
||||
'expand': vim_get_func('expand', rettype=str),
|
||||
'fnamemodify': vim_get_func('fnamemodify'),
|
||||
'expand': vim_get_func('expand'),
|
||||
'bufnr': vim_get_func('bufnr', rettype=int),
|
||||
'line2byte': vim_get_func('line2byte', rettype=int),
|
||||
'line': vim_get_func('line', rettype=int),
|
||||
|
@ -157,14 +158,18 @@ def file_directory(pl, segment_info, shorten_user=True, shorten_cwd=True, shorte
|
|||
:param bool shorten_home:
|
||||
shorten all directories in :file:`/home/` to :file:`~user/` instead of :file:`/home/user/`.
|
||||
'''
|
||||
name = segment_info['buffer'].name
|
||||
name = buffer_name(segment_info['buffer'])
|
||||
if not name:
|
||||
return None
|
||||
import sys
|
||||
file_directory = vim_funcs['fnamemodify'](name, (':~' if shorten_user else '')
|
||||
+ (':.' if shorten_cwd else '') + ':h')
|
||||
if not file_directory:
|
||||
return None
|
||||
if shorten_home and file_directory.startswith('/home/'):
|
||||
file_directory = '~' + file_directory[6:]
|
||||
return file_directory + os.sep if file_directory else None
|
||||
file_directory = b'~' + file_directory[6:]
|
||||
file_directory = file_directory.decode('utf-8', 'powerline_vim_strtrans_error')
|
||||
return file_directory + os.sep
|
||||
|
||||
|
||||
@requires_segment_info
|
||||
|
@ -178,7 +183,7 @@ def file_name(pl, segment_info, display_no_file=False, no_file_text='[No file]')
|
|||
|
||||
Highlight groups used: ``file_name_no_file`` or ``file_name``, ``file_name``.
|
||||
'''
|
||||
name = segment_info['buffer'].name
|
||||
name = buffer_name(segment_info['buffer'])
|
||||
if not name:
|
||||
if display_no_file:
|
||||
return [{
|
||||
|
@ -187,8 +192,7 @@ def file_name(pl, segment_info, display_no_file=False, no_file_text='[No file]')
|
|||
}]
|
||||
else:
|
||||
return None
|
||||
file_name = vim_funcs['fnamemodify'](name, ':~:.:t')
|
||||
return file_name
|
||||
return os.path.basename(name).decode('utf-8', 'powerline_vim_strtrans_error')
|
||||
|
||||
|
||||
@window_cached
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from powerline.segments import shell, common
|
||||
import tests.vim as vim_module
|
||||
import sys
|
||||
|
@ -467,6 +469,10 @@ class TestVim(TestCase):
|
|||
segment_info = vim_module._get_segment_info()
|
||||
self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info), None)
|
||||
with replace_env('HOME', '/home/foo', os.environ):
|
||||
with vim_module._with('buffer', '/tmp/’’/abc') as segment_info:
|
||||
self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info), '/tmp/’’/')
|
||||
with vim_module._with('buffer', b'/tmp/\xFF\xFF/abc') as segment_info:
|
||||
self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info), '/tmp/<ff><ff>/')
|
||||
with vim_module._with('buffer', '/tmp/abc') as segment_info:
|
||||
self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info), '/tmp/')
|
||||
os.environ['HOME'] = '/tmp'
|
||||
|
@ -484,6 +490,8 @@ class TestVim(TestCase):
|
|||
self.assertEqual(vim.file_name(pl=pl, segment_info=segment_info), 'abc')
|
||||
with vim_module._with('buffer', '/tmp/’’') as segment_info:
|
||||
self.assertEqual(vim.file_name(pl=pl, segment_info=segment_info), '’’')
|
||||
with vim_module._with('buffer', b'/tmp/\xFF\xFF') as segment_info:
|
||||
self.assertEqual(vim.file_name(pl=pl, segment_info=segment_info), '<ff><ff>')
|
||||
|
||||
def test_file_size(self):
|
||||
pl = Pl()
|
||||
|
|
|
@ -7,4 +7,12 @@
|
|||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;49;22m [0mfalse
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;48;5;52;22m [0;38;5;231;48;5;52m1 [0;38;5;52;49;22m [0mkill `cat pid` ; sleep 1s
|
||||
[1]+ Terminated bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done"
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mfalse
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mcd "$DIR1"
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m^[[32m [0;38;5;240;49;22m [0mcd ../"$DIR2"
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m^H [0;38;5;240;49;22m [0mcd ../'\[\]'
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m\[\] [0;38;5;240;49;22m [0mcd ../'%%'
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m%% [0;38;5;240;49;22m [0mcd ../'#[bold]'
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m#[bold] [0;38;5;240;49;22m [0mcd ../'(echo)'
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m(echo) [0;38;5;240;49;22m [0mcd ../'$(echo)'
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m$(echo) [0;38;5;240;49;22m [0mcd ../'`echo`'
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m`echo` [0;38;5;240;49;22m [0mfalse
|
||||
|
|
|
@ -6,3 +6,11 @@
|
|||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;48;5;52;22m [0;38;5;231;48;5;52m1 [0;38;5;52;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m^[[32m [0;38;5;240;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m^H [0;38;5;240;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m\[\] [0;38;5;240;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m%% [0;38;5;240;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m#[bold] [0;38;5;240;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m(echo) [0;38;5;240;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m$(echo) [0;38;5;240;49;22m [0m
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m`echo` [0;38;5;240;49;22m [0m
|
||||
|
|
|
@ -10,6 +10,14 @@ VIRTUAL_ENV=
|
|||
bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done" &
|
||||
false
|
||||
kill `cat pid` ; sleep 1s
|
||||
cd "$DIR1"
|
||||
cd ../"$DIR2"
|
||||
cd ../'\[\]'
|
||||
cd ../'%%'
|
||||
cd ../'#[bold]'
|
||||
cd ../'(echo)'
|
||||
cd ../'$(echo)'
|
||||
cd ../'`echo`'
|
||||
false
|
||||
true is the last line
|
||||
exit
|
||||
|
|
|
@ -11,6 +11,14 @@ set VIRTUAL_ENV
|
|||
bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done" &
|
||||
false
|
||||
kill (cat pid) ; sleep 1s
|
||||
cd "$DIR1"
|
||||
cd ../"$DIR2"
|
||||
cd ../'\[\]'
|
||||
cd ../'%%'
|
||||
cd ../'#[bold]'
|
||||
cd ../'(echo)'
|
||||
cd ../'$(echo)'
|
||||
cd ../'`echo`'
|
||||
false
|
||||
true is the last line
|
||||
exit
|
||||
|
|
|
@ -11,6 +11,14 @@ VIRTUAL_ENV=
|
|||
bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done" &
|
||||
false
|
||||
kill `cat pid` ; sleep 1s
|
||||
cd "$DIR1"
|
||||
cd ../"$DIR2"
|
||||
cd ../'\[\]'
|
||||
cd ../'%%'
|
||||
cd ../'#[bold]'
|
||||
cd ../'(echo)'
|
||||
cd ../'$(echo)'
|
||||
cd ../'`echo`'
|
||||
false
|
||||
true is the last line
|
||||
exit
|
||||
|
|
|
@ -8,11 +8,11 @@ import sys
|
|||
import codecs
|
||||
|
||||
|
||||
fname = sys.argv[1]
|
||||
new_fname = fname + '.new'
|
||||
pid_fname = 'tests/shell/3rd/pid'
|
||||
shell = sys.argv[1]
|
||||
fname = os.path.join('tests', 'shell', shell + '.full.log')
|
||||
new_fname = os.path.join('tests', 'shell', shell + '.log')
|
||||
pid_fname = os.path.join('tests', 'shell', '3rd', 'pid')
|
||||
|
||||
shell = sys.argv[2]
|
||||
|
||||
with open(pid_fname, 'r') as P:
|
||||
pid = P.read().strip()
|
||||
|
@ -42,5 +42,3 @@ with codecs.open(fname, 'r', encoding='utf-8') as R:
|
|||
except ValueError:
|
||||
line = ''
|
||||
W.write(line)
|
||||
|
||||
os.rename(new_fname, fname)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
width 1024
|
||||
height 1
|
||||
logfile "tests/shell/screen.log"
|
||||
logfile "tests/shell/${SH}.full.log"
|
||||
|
|
|
@ -3,11 +3,12 @@ FAILED=0
|
|||
ONLY_SHELL="$1"
|
||||
|
||||
check_screen_log() {
|
||||
if test -e tests/test_shells/${1}.ok ; then
|
||||
diff -u tests/test_shells/${1}.ok tests/shell/screen.log
|
||||
SH="$1"
|
||||
if test -e tests/test_shells/${SH}.ok ; then
|
||||
diff -u tests/test_shells/${SH}.ok tests/shell/${SH}.log
|
||||
return $?
|
||||
else
|
||||
cat tests/shell/screen.log
|
||||
cat tests/shell/${SH}.log
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
@ -20,22 +21,21 @@ run_test() {
|
|||
|
||||
which "${SH}" || return 0
|
||||
|
||||
export SH
|
||||
|
||||
screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \
|
||||
env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "$@"
|
||||
screen -S "$SESNAME" -X readreg a tests/test_shells/input.$SH
|
||||
# Wait for screen to initialize
|
||||
sleep 1s
|
||||
screen -S "$SESNAME" -p 0 -X width 300 1
|
||||
screen -S "$SESNAME" -p 0 -X logfile tests/shell/screen.log
|
||||
screen -S "$SESNAME" -p 0 -X paste a
|
||||
# Wait for screen to exit (sending command to non-existing screen session
|
||||
# fails; when launched instance exits corresponding session is deleted)
|
||||
while screen -S "$SESNAME" -X blankerprg "" > /dev/null ; do
|
||||
sleep 0.1s
|
||||
done
|
||||
cp tests/shell/screen.log tests/shell/${SH}.full.log
|
||||
./tests/test_shells/postproc.py tests/shell/screen.log ${SH}
|
||||
cp tests/shell/screen.log tests/shell/${SH}.log
|
||||
./tests/test_shells/postproc.py ${SH}
|
||||
if ! check_screen_log ${SH} ; then
|
||||
echo '____________________________________________________________'
|
||||
# Repeat the diff to make it better viewable in travis output
|
||||
|
@ -52,10 +52,8 @@ run_test() {
|
|||
cat -v tests/shell/${SH}.full.log
|
||||
echo '____________________________________________________________'
|
||||
${SH} --version
|
||||
rm tests/shell/screen.log
|
||||
return 1
|
||||
fi
|
||||
rm tests/shell/screen.log
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -63,6 +61,16 @@ test -d tests/shell && rm -r tests/shell
|
|||
mkdir tests/shell
|
||||
git init tests/shell/3rd
|
||||
git --git-dir=tests/shell/3rd/.git checkout -b BRANCH
|
||||
export DIR1="[32m"
|
||||
export DIR2=""
|
||||
mkdir tests/shell/3rd/"$DIR1"
|
||||
mkdir tests/shell/3rd/"$DIR2"
|
||||
mkdir tests/shell/3rd/'\[\]'
|
||||
mkdir tests/shell/3rd/'%%'
|
||||
mkdir tests/shell/3rd/'#[bold]'
|
||||
mkdir tests/shell/3rd/'(echo)'
|
||||
mkdir tests/shell/3rd/'$(echo)'
|
||||
mkdir tests/shell/3rd/'`echo`'
|
||||
|
||||
if ! run_test bash --norc --noprofile -i ; then
|
||||
FAILED=1
|
||||
|
|
|
@ -8,4 +8,12 @@
|
|||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;49;22m [0mfalse
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;48;5;52;22m [0;38;5;231;48;5;52m1 [0;38;5;52;49;22m [0mkill `cat pid` ; sleep 1s
|
||||
[1] + terminated bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done"
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mfalse
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtests [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mcd "$DIR1"
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m^[[32m [0;38;5;240;49;22m [0mcd ../"$DIR2"
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m^H [0;38;5;240;49;22m [0mcd ../'\[\]'
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m\[\] [0;38;5;240;49;22m [0mcd ../'%%'
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m%% [0;38;5;240;49;22m [0mcd ../'#[bold]'
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m#[bold] [0;38;5;240;49;22m [0mcd ../'(echo)'
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m(echo) [0;38;5;240;49;22m [0mcd ../'$(echo)'
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m$(echo) [0;38;5;240;49;22m [0mcd ../'`echo`'
|
||||
[0m[23m[24m[J[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m⋯ [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m`echo` [0;38;5;240;49;22m [0mfalse
|
||||
|
|
49
tests/vim.py
49
tests/vim.py
|
@ -60,7 +60,7 @@ class _Buffers(object):
|
|||
|
||||
@_vim
|
||||
def __nonzero__(self):
|
||||
return not not self.d
|
||||
return bool(self.d)
|
||||
|
||||
@_vim
|
||||
def keys(self):
|
||||
|
@ -261,8 +261,8 @@ def _emul_getpos(expr):
|
|||
def _emul_fnamemodify(path, modstring):
|
||||
import os
|
||||
_modifiers = {
|
||||
'~': lambda path: path.replace(os.environ['HOME'], '~') if path.startswith(os.environ['HOME']) else path,
|
||||
'.': lambda path: (lambda tpath: path if tpath[:3] == '..' + os.sep else tpath)(os.path.relpath(path)),
|
||||
'~': lambda path: path.replace(os.environ['HOME'].encode('utf-8'), b'~') if path.startswith(os.environ['HOME'].encode('utf-8')) else path,
|
||||
'.': lambda path: (lambda tpath: path if tpath[:3] == b'..' + os.sep.encode() else tpath)(os.path.relpath(path)),
|
||||
't': lambda path: os.path.basename(path),
|
||||
'h': lambda path: os.path.dirname(path),
|
||||
}
|
||||
|
@ -313,6 +313,22 @@ def _emul_line(expr):
|
|||
raise NotImplementedError
|
||||
|
||||
|
||||
@_vim
|
||||
@_str_func
|
||||
def _emul_strtrans(s):
|
||||
# FIXME Do more replaces
|
||||
return s.replace(b'\xFF', b'<ff>')
|
||||
|
||||
|
||||
@_vim
|
||||
@_str_func
|
||||
def _emul_bufname(bufnr):
|
||||
try:
|
||||
return buffers[bufnr]._name or b''
|
||||
except KeyError:
|
||||
return b''
|
||||
|
||||
|
||||
_window_ids = [None]
|
||||
_window_id = 0
|
||||
|
||||
|
@ -348,11 +364,11 @@ _undo_written = {}
|
|||
class _Buffer(object):
|
||||
def __init__(self, name=None):
|
||||
global _last_bufnr
|
||||
import os
|
||||
_last_bufnr += 1
|
||||
bufnr = _last_bufnr
|
||||
self.number = bufnr
|
||||
self.name = os.path.abspath(name) if name else None
|
||||
# FIXME Use unicode() for python-3
|
||||
self.name = name
|
||||
self.vars = {}
|
||||
self.options = {
|
||||
'modified': 0,
|
||||
|
@ -369,6 +385,25 @@ class _Buffer(object):
|
|||
_undo_written[bufnr] = len(_undostate[bufnr])
|
||||
buffers[bufnr] = self
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
import sys
|
||||
if sys.version_info < (3,):
|
||||
return self._name
|
||||
else:
|
||||
return str(self._name, 'utf-8') if self._name else None
|
||||
|
||||
@name.setter
|
||||
def name(self, name):
|
||||
if name is None:
|
||||
self._name = None
|
||||
else:
|
||||
import os
|
||||
if type(name) is not bytes:
|
||||
name = name.encode('utf-8')
|
||||
import sys
|
||||
self._name = os.path.abspath(name)
|
||||
|
||||
def __getitem__(self, line):
|
||||
return _buf_lines[self.number][line]
|
||||
|
||||
|
@ -676,3 +711,7 @@ def _with(key, *args, **kwargs):
|
|||
return _WithDict(vars, **kwargs)
|
||||
elif key == 'split':
|
||||
return _WithSplit()
|
||||
|
||||
|
||||
class error(Exception):
|
||||
pass
|
||||
|
|
Loading…
Reference in New Issue