# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)

from powerline.pdb import PDBPowerline
from powerline.lib.encoding import get_preferred_output_encoding


def use_powerline_prompt(cls):
	'''Decorator that installs powerline prompt to the class

	:param pdb.Pdb cls:
		Class that should be decorated.

	:return:
		``cls`` argument or a class derived from it. Latter is used to turn 
		old-style classes into new-style classes.
	'''
	encoding = get_preferred_output_encoding()

	@property
	def prompt(self):
		try:
			powerline = self.powerline
		except AttributeError:
			powerline = PDBPowerline()
			powerline.setup(self)
			self.powerline = powerline
		ret = powerline.render(side='left')
		if not isinstance(ret, str):
			# Python-2
			ret = ret.encode(encoding)
		return ret

	@prompt.setter
	def prompt(self, _):
		pass

	@prompt.deleter
	def prompt(self):
		pass

	if not hasattr(cls, '__class__'):
		# Old-style class: make it new-style or @property will not work.
		old_cls = cls

		class cls(cls, object):
			__module__ = cls.__module__
			__doc__ = cls.__doc__

		cls.__name__ = old_cls.__name__

	cls.prompt = prompt

	return cls

# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)

import sys

from powerline.pdb import PDBPowerline
from powerline.lib.encoding import get_preferred_output_encoding
from powerline.lib.unicode import unicode


if sys.version_info < (3,):
	# XXX The below classes make code compatible with PDBpp which uses pyrepl
	#     which does not expect unicode or something above ASCII. They are 
	#     completely not needed if pdbpp is not used, but that’s not always the 
	#     case.
	class PowerlineRenderBytesResult(bytes):
		def __new__(cls, s, encoding=None):
			encoding = encoding or s.encoding
			self = bytes.__new__(cls, s.encode(encoding) if isinstance(s, unicode) else s)
			self.encoding = encoding
			return self

		for meth in (
			'__contains__',
			'partition', 'rpartition',
			'split', 'rsplit',
			'count', 'join',
		):
			exec((
				'def {0}(self, *args):\n'
				'	if any((isinstance(arg, unicode) for arg in args)):\n'
				'		return self.__unicode__().{0}(*args)\n'
				'	else:\n'
				'		return bytes.{0}(self, *args)'
			).format(meth))

		for meth in (
			'find', 'rfind',
			'index', 'rindex',
		):
			exec((
				'def {0}(self, *args):\n'
				'	if any((isinstance(arg, unicode) for arg in args)):\n'
				'		args = [arg.encode(self.encoding) if isinstance(arg, unicode) else arg for arg in args]\n'
				'	return bytes.{0}(self, *args)'
			).format(meth))

		def __len__(self):
			return len(self.decode(self.encoding))

		def __getitem__(self, *args):
			return PowerlineRenderBytesResult(bytes.__getitem__(self, *args), encoding=self.encoding)

		def __getslice__(self, *args):
			return PowerlineRenderBytesResult(bytes.__getslice__(self, *args), encoding=self.encoding)

		@staticmethod
		def add(encoding, *args):
			if any((isinstance(arg, unicode) for arg in args)):
				return ''.join((
					arg
					if isinstance(arg, unicode)
					else arg.decode(encoding)
					for arg in args
				))
			else:
				return PowerlineRenderBytesResult(b''.join(args), encoding=encoding)

		def __add__(self, other):
			return self.add(self.encoding, self, other)

		def __radd__(self, other):
			return self.add(self.encoding, other, self)

		def __unicode__(self):
			return PowerlineRenderResult(self)

	class PowerlineRenderResult(unicode):
		def __new__(cls, s, encoding=None):
			encoding = (
				encoding
				or getattr(s, 'encoding', None)
				or get_preferred_output_encoding()
			)
			if isinstance(s, unicode):
				self = unicode.__new__(cls, s)
			else:
				self = unicode.__new__(cls, s, encoding, 'replace')
			self.encoding = encoding
			return self

		def __str__(self):
			return PowerlineRenderBytesResult(self)
else:
	PowerlineRenderResult = str


def use_powerline_prompt(cls):
	'''Decorator that installs powerline prompt to the class

	:param pdb.Pdb cls:
		Class that should be decorated.

	:return:
		``cls`` argument or a class derived from it. Latter is used to turn 
		old-style classes into new-style classes.
	'''
	@property
	def prompt(self):
		try:
			powerline = self.powerline
		except AttributeError:
			powerline = PDBPowerline()
			powerline.setup(self)
			self.powerline = powerline
		return PowerlineRenderResult(powerline.render(side='left'))

	@prompt.setter
	def prompt(self, _):
		pass

	@prompt.deleter
	def prompt(self):
		pass

	if not hasattr(cls, '__class__'):
		# Old-style class: make it new-style or @property will not work.
		old_cls = cls

		class cls(cls, object):
			__module__ = cls.__module__
			__doc__ = cls.__doc__

		cls.__name__ = old_cls.__name__

	cls.prompt = prompt

	return cls

Add some hacks to make code compatible with pdbpp