From 6f3703e312a5cdedebf28037b0f9f90e2eff5217 Mon Sep 17 00:00:00 2001
From: ZyX <kp-pav@ya.ru>
Date: Sun, 10 Mar 2013 13:08:01 +0400
Subject: [PATCH 1/2] Improve ambiwidth handling, readd additional_escapes

Fixes #307
---
 docs/source/configuration.rst                 | 19 +++++++++++++++++++
 docs/source/installation/osx.rst              |  3 ++-
 .../installation/troubleshooting-common.rst   | 12 +++++++++++-
 powerline/__init__.py                         |  6 +++++-
 powerline/renderer.py                         | 16 ++++++++++++++--
 powerline/renderers/vim.py                    | 12 ++++++++++++
 tests/vim.py                                  |  5 +++--
 7 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst
index 05e10a53..e4d8bcbc 100644
--- a/docs/source/configuration.rst
+++ b/docs/source/configuration.rst
@@ -120,6 +120,25 @@ Common configuration is a subdictionary that is a value of ``common`` key in
     to the terminal emulator. See the :ref:`term-feature-support-matrix` for 
     information on whether your terminal emulator supports 24-bit colors.
 
+.. _config-common-ambiwidth:
+
+``ambiwidth``
+    Tells powerline what to do with characters with East Asian Width Class 
+    Ambigious (such as Euro, Registered Sign, Copyright Sign, Greek
+    letters, Cyrillic letters). Valid values: any positive integer; it is 
+    suggested that you only set it to 1 (default) or 2.
+
+.. _config-common-additional_escapes:
+
+``additional_escapes``
+    Valid for shell extensions, makes sense only if :ref:`term_truecolor 
+    <config-common-term_truecolor>` is enabled. Is to be set from command-line 
+    (unless you are sure you always need it). Controls additional escaping that 
+    is needed for tmux/screen to work with terminal true color escape codes: 
+    normally tmux/screen prevent terminal emulator from receiving these control 
+    codes thus rendering powerline prompt colorless. Valid values: ``"tmux"``, 
+    ``"screen"``, ``null`` (default).
+
 ``dividers``
     Defines the dividers used in all Powerline extensions. This option 
     should usually only be changed if you don't have a patched font, or if 
diff --git a/docs/source/installation/osx.rst b/docs/source/installation/osx.rst
index b76bcf19..aa029f11 100644
--- a/docs/source/installation/osx.rst
+++ b/docs/source/installation/osx.rst
@@ -90,7 +90,8 @@ Statusline is getting wrapped to the next line in iTerm2
 
 * Turn off “Treat ambigious-width characters as double width” in `Preferences 
   --> Text`.
-* Alternative: remove fancy dividers and other fancy symbols from configuration.
+* Alternative: remove fancy dividers (they suck in this case), set 
+  :ref:`ambiwidth <config-common-ambiwidth>` to 2.
 
 I receive a ``NameError`` when trying to use Powerline with MacVim!
 -------------------------------------------------------------------
diff --git a/docs/source/installation/troubleshooting-common.rst b/docs/source/installation/troubleshooting-common.rst
index ef3da240..a0142e38 100644
--- a/docs/source/installation/troubleshooting-common.rst
+++ b/docs/source/installation/troubleshooting-common.rst
@@ -10,6 +10,15 @@ I'm using tmux and Powerline looks like crap, what's wrong?
   :guilabel:`Set locale variables automatically` in :menuselection:`Profiles 
   --> Terminal --> Environment`.
 
+I’m using tmux/screen and Powerline is colorless
+------------------------------------------------
+
+* If the above advices do not help, then you need to disable 
+  :ref:`term_truecolor <config-common-term_truecolor>`.
+* Alternative: set :ref:`additional_escapes <config-common-additional_escapes>` 
+  to ``"tmux"`` or ``"screen"``. Note that it is known to work perfectly in 
+  screen, but in tmux it may produce ugly spaces.
+
 My vim statusline has strange characters like ``^B`` in it!
 -----------------------------------------------------------
 
@@ -49,4 +58,5 @@ My vim statusline is not displayed completely and has too much spaces
 ---------------------------------------------------------------------
 
 * Be sure you have ``ambiwidth`` option set to ``single``.
-* Alternative: remove fancy dividers and other fancy symbols from configuration.
+* Alternative: set :ref:`ambiwidth <config-common-ambiwidth>` to 2, remove fancy 
+  dividers (they suck when ``ambiwidth`` is set to double).
diff --git a/powerline/__init__.py b/powerline/__init__.py
index 752d845a..935190ac 100644
--- a/powerline/__init__.py
+++ b/powerline/__init__.py
@@ -71,7 +71,11 @@ class Powerline(object):
 		except ImportError as e:
 			sys.stderr.write('Error while importing renderer module: {0}\n'.format(e))
 			sys.exit(1)
-		options = {'term_truecolor': common_config.get('term_truecolor', False)}
+		options = {'term_truecolor': common_config.get('term_truecolor', False),
+				'ambiwidth': common_config.get('ambiwidth', 1),
+				'tmux_escape': common_config.get('additional_escapes') == 'tmux',
+				'screen_escape': common_config.get('additional_escapes') == 'screen',
+				}
 		self.renderer = Renderer(theme_config, local_themes, theme_kwargs, colorscheme, **options)
 
 	@staticmethod
diff --git a/powerline/renderer.py b/powerline/renderer.py
index e91be682..4ecacd24 100644
--- a/powerline/renderer.py
+++ b/powerline/renderer.py
@@ -1,6 +1,7 @@
 # vim:fileencoding=utf-8:noet
 
-from powerline.theme import Theme
+from powerline.theme import Theme, u
+from unicodedata import east_asian_width, combining
 
 
 try:
@@ -17,6 +18,17 @@ class Renderer(object):
 		self.local_themes = local_themes
 		self.theme_kwargs = theme_kwargs
 		self.colorscheme = colorscheme
+		self.width_data = {
+				'N':  1,                              # Neutral
+				'Na': 1,                              # Narrow
+				'A':  getattr(self, 'ambiwidth', 1),  # Ambigious
+				'H':  1,                              # Half-width
+				'W':  2,                              # Wide
+				'F':  2,                              # Fullwidth
+				}
+
+	def strwidth(self, string):
+		return sum((0 if combining(symbol) else self.width_data[east_asian_width(symbol)] for symbol in string))
 
 	def get_theme(self, matcher_info):
 		return self.theme
@@ -151,7 +163,7 @@ class Renderer(object):
 				else:
 					segment['_rendered_raw'] += contents_raw
 					segment['_rendered_hl'] += contents_highlighted
-			segment['_len'] = len(segment['_rendered_raw'])
+			segment['_len'] = self.strwidth(segment['_rendered_raw'])
 			yield segment
 
 	@staticmethod
diff --git a/powerline/renderers/vim.py b/powerline/renderers/vim.py
index 5099e4dc..245d7293 100644
--- a/powerline/renderers/vim.py
+++ b/powerline/renderers/vim.py
@@ -22,6 +22,11 @@ class VimRenderer(Renderer):
 	'''Powerline vim segment renderer.'''
 
 	def __init__(self, *args, **kwargs):
+		if not hasattr(vim, 'strwidth'):
+			# Hope nobody want to change this at runtime
+			if vim.eval('&ambiwidth') == 'double':
+				kwargs = dict(**kwargs)
+				kwargs['ambigious'] = 2
 		super(VimRenderer, self).__init__(*args, **kwargs)
 		self.hl_groups = {}
 
@@ -40,6 +45,13 @@ class VimRenderer(Renderer):
 		else:
 			return self.theme
 
+	if hasattr(vim, 'strwidth'):
+		@staticmethod
+		def strwidth(string):
+			# Does not work with tabs, but neither is strwidth from default 
+			# renderer
+			return vim.strwidth(string.encode('utf-8'))
+
 	def render(self, window_id, winidx, current):
 		'''Render all segments.
 
diff --git a/tests/vim.py b/tests/vim.py
index 6253956f..1b9b820c 100644
--- a/tests/vim.py
+++ b/tests/vim.py
@@ -5,8 +5,9 @@ _window = 0
 _mode = 'n'
 _buf_purge_events = set()
 _options = {
-		'paste': 0,
-		}
+	'paste': 0,
+	'ambiwidth': 'single',
+}
 _last_bufnr = 0
 _highlights = {}
 

From 1960e8329fe14454a30d05566713977e3b6b8445 Mon Sep 17 00:00:00 2001
From: ZyX <kp-pav@ya.ru>
Date: Mon, 11 Mar 2013 21:27:28 +0400
Subject: [PATCH 2/2] Remove useless import

---
 powerline/renderer.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/powerline/renderer.py b/powerline/renderer.py
index 4ecacd24..bdd995b9 100644
--- a/powerline/renderer.py
+++ b/powerline/renderer.py
@@ -1,6 +1,6 @@
 # vim:fileencoding=utf-8:noet
 
-from powerline.theme import Theme, u
+from powerline.theme import Theme
 from unicodedata import east_asian_width, combining