Ensure that _vim_{dec,enc} always succeeds on py3

In py2 we could get by with attempting to encode/decode a string and if
it failed just ignore and return.  Unfortunately on py3 a string decodes
to a bytearray and a bytearray encodes to a string.  We can't simply
return the original object when we fail.  We choose replace for handling
bytes we don't understand.

Test case (using python3 for UltiSnips):
open a new file
:set encoding=utf-8
qa<Backspace>q
"ap

Warning: this test case makes it very difficult to exit vim cleanly and
save files!

Signed-off-by: Andrew Ruder <andrew.ruder@elecsyscorp.com>
This commit is contained in:
Andrew Ruder 2014-04-09 09:51:19 -05:00
parent a3e654fc54
commit cae27fba5c
2 changed files with 31 additions and 15 deletions

View File

@ -1384,6 +1384,7 @@ individuals have contributed to UltiSnips (in chronological order):
Pedro Ferrari - petobens
Ches Martin - ches
Christian - Oberon00
Andrew Ruder - aeruder
Thank you for your support.

View File

@ -10,22 +10,21 @@ import sys
import vim # pylint:disable=import-error
def _vim_dec(string):
"""Decode 'string' using &encoding."""
try:
return string.decode(vim.eval("&encoding"))
except UnicodeDecodeError:
# At least we tried. There might be some problems down the road now
return string
def _vim_enc(string):
"""Encode 'string' using &encoding."""
try:
return string.encode(vim.eval("&encoding"))
except UnicodeEncodeError:
return string
if sys.version_info >= (3, 0):
def _vim_dec(string):
"""Decode 'string' using &encoding."""
# We don't have the luxury here of failing, everything
# falls apart if we don't return a bytearray from the
# passed in string
return string.decode(vim.eval("&encoding"), "replace")
def _vim_enc(bytearray):
"""Encode 'string' using &encoding."""
# We don't have the luxury here of failing, everything
# falls apart if we don't return a string from the passed
# in bytearray
return bytearray.encode(vim.eval("&encoding"), "replace")
def open_ascii_file(filename, mode):
"""Opens a file in "r" mode."""
return open(filename, mode, encoding="utf-8")
@ -60,6 +59,22 @@ if sys.version_info >= (3, 0):
else:
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
def _vim_dec(string):
"""Decode 'string' using &encoding."""
try:
return string.decode(vim.eval("&encoding"))
except UnicodeDecodeError:
# At least we tried. There might be some problems down the road now
return string
def _vim_enc(string):
"""Encode 'string' using &encoding."""
try:
return string.encode(vim.eval("&encoding"))
except UnicodeEncodeError:
return string
def open_ascii_file(filename, mode):
"""Opens a file in "r" mode."""
return open(filename, mode)