Merge pull request #1030 from ZyX-I/locale-support

Improve locales support
This commit is contained in:
Nikolai Aleksandrovich Pavlov 2014-08-28 00:00:09 +04:00
commit 305fd7917b
33 changed files with 170 additions and 86 deletions

View File

@ -5,8 +5,15 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
import sys
import socket
import os
import errno
import os
from locale import getpreferredencoding
try:
from posix import environ
except ImportError:
from os import environ
if len(sys.argv) < 2:
@ -37,6 +44,7 @@ def eintr_retry_call(func, *args, **kwargs):
continue
raise
try:
eintr_retry_call(sock.connect, address)
except Exception:
@ -44,11 +52,15 @@ except Exception:
args = ['powerline-render'] + sys.argv[1:]
os.execvp('powerline-render', args)
fenc = sys.getfilesystemencoding() or 'utf-8'
if fenc == 'ascii':
fenc = 'utf-8'
fenc = getpreferredencoding() or 'utf-8'
def tobytes(s):
if isinstance(s, bytes):
return s
else:
return s.encode(fenc)
tobytes = lambda s: s if isinstance(s, bytes) else s.encode(fenc)
args = [tobytes('%x' % (len(sys.argv) - 1))]
args.extend((tobytes(s) for s in sys.argv[1:]))
@ -64,7 +76,7 @@ else:
args.append(cwd)
args.extend((tobytes(k) + b'=' + tobytes(v) for k, v in os.environ.items()))
args.extend((tobytes(k) + b'=' + tobytes(v) for k, v in environ.items()))
EOF = b'\0\0'

View File

@ -94,7 +94,8 @@ Common configuration is a subdictionary that is a value of ``common`` key in
``default_top_theme``
String, determines which top-level theme will be used as the default.
Defaults to ``powerline``. See `Themes`_ section for more details.
Defaults to ``powerline`` in unicode locales and ``ascii`` in non-unicode
locales. See `Themes`_ section for more details.
Extension-specific configuration
--------------------------------
@ -287,6 +288,19 @@ ascii Theme without any unicode characters at all
after it (on the left side). These spaces will not be added if divider is
not drawn.
``use_non_breaking_spaces``
Determines whether non-breaking spaces should be used in place of the
regular ones. This option is needed because regular spaces are not displayed
properly when using powerline with some font configuration. Defaults to
``True``.
.. note::
Unlike all other options this one is only checked once at startup using
whatever theme is :ref:`the default <config-ext-theme>`. If this option
is set in the local themes it will be ignored. This option may also be
ignored in some bindings.
``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

View File

@ -120,6 +120,48 @@ make powerline package importable anywhere: use
pip install --user --editable path/to/powerline
Shell issues
============
I am suffering bad lags before displaying shell prompt
------------------------------------------------------
To get rid of these lags there currently are two options:
* Run ``powerline-daemon``. Powerline does not automatically start it for you.
* Compile and install ``libzpython`` module that lives in
https://bitbucket.org/ZyX_I/zpython. This variant is zsh-specific.
Prompt is spoiled after completing files in ksh
-----------------------------------------------
This is exactly why powerline has official mksh support, but not official ksh
support. If you know the solution feel free to share it in `powerline bug
tracker`_.
When using z powerline shows wrong number of jobs
-------------------------------------------------
This happens because `z <https://github.com/rupa/z>`_ is launching some jobs in
the background from ``$POWERLINE_COMMAND`` and these jobs fail to finish before
powerline prompt is run.
Solution to this problem is simple: be sure that :file:`z.sh` is sourced
strictly after :file:`powerline/bindings/bash/powerline.sh`. This way background
jobs are spawned by `z <https://github.com/rupa/z>`_ after powerline has done
its job.
When using shell I do not see powerline fancy characters
--------------------------------------------------------
If your locale encoding is not unicode (any encoding that starts with “utf” or
“ucs” will work, case is ignored) powerline falls back to ascii-only theme. You
should set up your system to use unicode locale or forget about powerline fancy
characters.
Vim issues
==========
My vim statusline has strange characters like ``^B`` in it!
-----------------------------------------------------------
@ -148,34 +190,6 @@ My vim statusline is not displayed completely and has too much spaces
* Alternative: set :ref:`ambiwidth <config-common-ambiwidth>` to 2, remove fancy
dividers (they suck when ``ambiwidth`` is set to double).
When using z powerline shows wrong number of jobs
-------------------------------------------------
This happens because `z <https://github.com/rupa/z>`_ is launching some jobs in
the background from ``$POWERLINE_COMMAND`` and these jobs fail to finish before
powerline prompt is run.
Solution to this problem is simple: be sure that :file:`z.sh` is sourced
strictly after :file:`powerline/bindings/bash/powerline.sh`. This way background
jobs are spawned by `z <https://github.com/rupa/z>`_ after powerline has done
its job.
I am suffering bad lags before displaying shell prompt
------------------------------------------------------
To get rid of these lags there currently are two options:
* Run ``powerline-daemon``. Powerline does not automatically start it for you.
* Compile and install ``libzpython`` module that lives in
https://bitbucket.org/ZyX_I/zpython. This variant is zsh-specific.
Prompt is spoiled after completing files in ksh
-----------------------------------------------
This is exactly why powerline has official mksh support, but not official ksh
support. If you know the solution feel free to share it in `powerline bug
tracker`_.
Powerline loses color after editing vimrc
-----------------------------------------

View File

@ -5,14 +5,15 @@ import os
import sys
import logging
from locale import getpreferredencoding
from threading import Lock, Event
from powerline.colorscheme import Colorscheme
from powerline.lib.config import ConfigLoader
from powerline.lib.unicode import safe_unicode, FailedUnicode
from powerline.config import DEFAULT_SYSTEM_CONFIG_DIR
from powerline.lib import mergedicts
from threading import Lock, Event
def _config_loader_condition(path):
if path and os.path.isfile(path):
@ -224,7 +225,7 @@ def create_logger(common_config):
return logger
def finish_common_config(common_config):
def finish_common_config(encoding, common_config):
'''Add default values to common config and expand ~ in paths
:param dict common_config:
@ -234,8 +235,14 @@ def finish_common_config(common_config):
Copy of common configuration with all configuration keys and expanded
paths.
'''
encoding = encoding.lower()
if encoding.startswith('utf') or encoding.startswith('ucs'):
default_top_theme = 'powerline'
else:
default_top_theme = 'ascii'
common_config = common_config.copy()
common_config.setdefault('default_top_theme', 'powerline')
common_config.setdefault('default_top_theme', default_top_theme)
common_config.setdefault('paths', [])
common_config.setdefault('watcher', 'auto')
common_config.setdefault('log_level', 'WARNING')
@ -400,6 +407,12 @@ class Powerline(object):
self.setup_kwargs = {}
self.imported_modules = set()
get_encoding = staticmethod(getpreferredencoding)
'''Get encoding used by the current application
Usually returns encoding of the current locale.
'''
def create_renderer(self, load_main=False, load_colors=False, load_colorscheme=False, load_theme=False):
'''(Re)create renderer object. Can be used after Powerline object was
successfully initialized. If any of the below parameters except
@ -424,7 +437,7 @@ class Powerline(object):
if load_main:
self._purge_configs('main')
config = self.load_main_config()
self.common_config = finish_common_config(config['common'])
self.common_config = finish_common_config(self.get_encoding(), config['common'])
if self.common_config != self.prev_common_config:
common_config_differs = True

View File

@ -6,6 +6,8 @@ import os
import re
import sys
from locale import getpreferredencoding
from powerline.config import POWERLINE_ROOT, TMUX_CONFIG_DIRECTORY
from powerline.lib.config import ConfigLoader
from powerline import generate_config_finder, load_config, create_logger, PowerlineLogger, finish_common_config
@ -83,7 +85,7 @@ def get_main_config(args):
def create_powerline_logger(args):
config = get_main_config(args)
common_config = finish_common_config(config['common'])
common_config = finish_common_config(getpreferredencoding(), config['common'])
logger = create_logger(common_config)
return PowerlineLogger(use_daemon_threads=True, logger=logger, ext='config')

View File

@ -1,4 +1,5 @@
{
"use_non_breaking_spaces": false,
"dividers": {
"left": {
"hard": " ",

View File

@ -1388,6 +1388,7 @@ common_theme_spec = Spec(
top_theme_spec = common_theme_spec().update(
dividers=dividers_spec(),
spaces=spaces_spec(),
use_non_breaking_spaces=Spec().type(bool).optional(),
segment_data=Spec().unknown_spec(
Spec().func(check_segment_data_key),
segment_data_value_spec(),

View File

@ -73,7 +73,7 @@ class Renderer(object):
python-2) regular string or ``None``.
'''
character_translations = {ord(' '): NBSP}
character_translations = {}
'''Character translations for use in escape() function.
See documentation of ``unicode.translate`` for details.
@ -101,6 +101,9 @@ class Renderer(object):
self.theme_config = theme_config
theme_kwargs['pl'] = pl
self.pl = pl
if theme_config.get('use_non_breaking_spaces', True):
self.character_translations = self.character_translations.copy()
self.character_translations[ord(' ')] = NBSP
self.theme = Theme(theme_config=theme_config, **theme_kwargs)
self.local_themes = local_themes
self.theme_kwargs = theme_kwargs
@ -382,7 +385,7 @@ class Renderer(object):
# Pad segments first
if draw_divider:
divider_raw = theme.get_divider(side, divider_type).replace(' ', NBSP)
divider_raw = self.escape(theme.get_divider(side, divider_type))
if side == 'left':
contents_raw = (
outer_padding + (segment['_space_left'] * ' ')
@ -442,11 +445,10 @@ class Renderer(object):
segment['_rendered_hl'] = contents_highlighted
yield segment
@classmethod
def escape(cls, string):
def escape(self, string):
'''Method that escapes segment contents.
'''
return string.translate(cls.character_translations)
return string.translate(self.character_translations)
def hlstyle(fg=None, bg=None, attr=None):
'''Output highlight style string.

View File

@ -81,7 +81,7 @@ def finish_args(args):
args.renderer_arg = mergeargs((parsedotval(v) for v in args.renderer_arg))
def write_output(args, powerline, segment_info, write):
def write_output(args, powerline, segment_info, write, encoding):
if args.renderer_arg:
segment_info.update(args.renderer_arg)
if args.side.startswith('above'):
@ -90,8 +90,8 @@ def write_output(args, powerline, segment_info, write):
segment_info=segment_info,
mode=segment_info['environ'].get('_POWERLINE_MODE'),
):
write(line)
write('\n')
write(line.encode(encoding, 'replace'))
write(b'\n')
args.side = args.side[len('above'):]
if args.side:
@ -101,4 +101,4 @@ def write_output(args, powerline, segment_info, write):
segment_info=segment_info,
mode=segment_info['environ'].get('_POWERLINE_MODE'),
)
write(rendered)
write(rendered.encode(encoding, 'replace'))

View File

@ -3,11 +3,14 @@
from __future__ import absolute_import
import sys
from itertools import count
import vim
from powerline.bindings.vim import vim_get_func, vim_getvar
from powerline import Powerline, FailedUnicode
from powerline.lib import mergedicts
import vim
from itertools import count
if not hasattr(vim, 'bindeval'):
import json
@ -71,6 +74,10 @@ class VimPowerline(Powerline):
self.setup_kwargs.setdefault('_local_themes', []).append((key, config))
return True
@staticmethod
def get_encoding():
return vim.eval('&encoding')
def load_main_config(self):
return _override_from(super(VimPowerline, self).load_main_config(), 'powerline_config_overrides')

View File

@ -12,7 +12,7 @@ from signal import signal, SIGTERM
from time import sleep
from functools import partial
from locale import getpreferredencoding
from io import StringIO
from io import BytesIO
from powerline.shell import get_argparser, finish_args, ShellPowerline, write_output
from powerline.lib.monotonic import monotonic
@ -98,8 +98,8 @@ def render(args, environ, cwd):
powerline.pl.exception('Failed to render {0}: {1}', str(key), str(e))
else:
return 'Failed to render {0}: {1}'.format(str(key), str(e))
s = StringIO()
write_output(args, powerline, segment_info, s.write)
s = BytesIO()
write_output(args, powerline, segment_info, s.write, encoding)
s.seek(0)
return s.read()
@ -143,8 +143,6 @@ def do_write(conn, result):
encoding = getpreferredencoding() or 'UTF-8'
if encoding.lower() == 'ascii':
encoding = 'UTF-8'
def safe_bytes(o, encoding=encoding):

View File

@ -4,6 +4,8 @@
import sys
import os
from locale import getpreferredencoding
try:
from powerline.shell import ShellPowerline, get_argparser, finish_args, write_output
except ImportError:
@ -11,11 +13,10 @@ except ImportError:
from powerline.shell import ShellPowerline, get_argparser, finish_args, write_output # NOQA
def write(output):
try:
sys.stdout.write(output)
except UnicodeEncodeError:
sys.stdout.write(output.encode('utf-8'))
if sys.version_info < (3,):
write = sys.stdout.write
else:
write = sys.stdout.buffer.write
if __name__ == '__main__':
@ -23,4 +24,4 @@ if __name__ == '__main__':
finish_args(args)
powerline = ShellPowerline(args, run_once=True)
segment_info = {'args': args, 'environ': os.environ}
write_output(args, powerline, segment_info, write)
write_output(args, powerline, segment_info, write, getpreferredencoding())

View File

@ -1,4 +1,5 @@
#!/usr/bin/vim -S
set encoding=utf-8
let g:powerline_config_path = expand('<sfile>:p:h:h') . '/powerline/config_files'
let g:powerline_config_overrides = {'common': {'default_top_theme': 'ascii'}}
let g:powerline_theme_overrides__default = {'segment_data': {'line_current_symbol': {'contents': 'LN '}, 'branch': {'before': 'B '}}}
@ -30,7 +31,7 @@ catch
cquit
endtry
if result isnot# '%#Pl_22_24320_148_11523840_bold# NORMAL %#Pl_148_11523840_236_3158064_NONE# %#Pl_231_16777215_236_3158064_NONE#                                                 %#Pl_247_10395294_236_3158064_NONE#unix%#Pl_240_5789784_236_3158064_NONE# %#Pl_247_10329757_240_5789784_NONE# 100%%%#Pl_252_13684944_240_5789784_NONE# %#Pl_235_2500134_252_13684944_NONE# LN %#Pl_235_2500134_252_13684944_bold#  1%#Pl_22_24576_252_13684944_NONE#:1  '
if result isnot# '%#Pl_22_24320_148_11523840_bold# NORMAL %#Pl_148_11523840_236_3158064_NONE# %#Pl_231_16777215_236_3158064_NONE# %#Pl_247_10395294_236_3158064_NONE#unix%#Pl_240_5789784_236_3158064_NONE# %#Pl_247_10329757_240_5789784_NONE# 100%%%#Pl_252_13684944_240_5789784_NONE# %#Pl_235_2500134_252_13684944_NONE# LN %#Pl_235_2500134_252_13684944_bold# 1%#Pl_22_24576_252_13684944_NONE#:1 '
call writefile(['Unexpected result', result], 'message.fail')
cquit
endif

View File

@ -1,5 +1,5 @@
#!/usr/bin/vim -S
set nocompatible
set encoding=utf-8
tabedit abc
tabedit def
try

View File

@ -25,4 +25,5 @@ def
  BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
  BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  ⋯  shell  3rd  `echo`  false
  BRANCH  ⋯  shell  3rd  `echo`  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
  BRANCH $ABC⋯  shell  3rd  `echo` $ABCfalse

View File

@ -25,4 +25,5 @@ def
  BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
  BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  ⋯  shell  3rd  `echo`  false
  BRANCH  ⋯  shell  3rd  `echo`  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
  BRANCH $ABC⋯  shell  3rd  `echo` $ABCfalse

View File

@ -24,4 +24,5 @@ def
  BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
  BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  ⋯  shell  3rd  `echo`  false
  BRANCH  ⋯  shell  3rd  `echo`  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
  BRANCH $ABC⋯  shell  3rd  `echo` $ABCfalse

View File

@ -24,4 +24,5 @@ def
  BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
  BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  ⋯  shell  3rd  `echo`  false
  BRANCH  ⋯  shell  3rd  `echo`  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
  BRANCH $ABC⋯  shell  3rd  `echo` $ABCfalse

View File

@ -23,4 +23,5 @@ def
  BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
  BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  ⋯  shell  3rd  `echo`  false
  BRANCH  ⋯  shell  3rd  `echo`  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
  BRANCH $ABC⋯  shell  3rd  `echo` $ABCfalse

View File

@ -23,4 +23,5 @@ def
  BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
  BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  ⋯  shell  3rd  `echo`  false
  BRANCH  ⋯  shell  3rd  `echo`  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
  BRANCH $ABC⋯  shell  3rd  `echo` $ABCfalse

View File

@ -25,6 +25,7 @@ cd ../'#[bold]'
cd ../'(echo)'
cd ../'$(echo)'
cd ../'`echo`'
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
false
true is the last line
exit

View File

@ -25,6 +25,7 @@ cd ../'#[bold]'
cd ../'(echo)'
cd ../'$(echo)'
cd ../'`echo`'
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
false
true is the last line
exit

View File

@ -25,6 +25,7 @@ cd ../'#[bold]'
cd ../'(echo)'
cd ../'$(echo)'
cd ../'`echo`'
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
false
true is the last line
exit

View File

@ -26,6 +26,7 @@ cd ../'#[bold]'
cd ../'(echo)'
cd ../'$(echo)'
cd ../'`echo`'
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
false
true is the last line
exit

View File

@ -40,6 +40,7 @@ do
done
1
hash -d foo=$PWD:h ; cd .
POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC )
true
true is the last line
exit

View File

@ -1,14 +1,14 @@
 In [2]  bool 42
     2>  bool(42)
 Out[2]  True
 In [2]  bool 42
 2>  bool(42)
 Out[2]  True
 In [3]  bool 44
     3>  bool(44)
 Out[3]  True
 In [3]  bool 44
 3>  bool(44)
 Out[3]  True
 In [4]  class Test(object):
          pass
         
 In [4]  class Test(object):
   pass
  
 In [5]  exit
 In [5]  exit

View File

@ -27,4 +27,5 @@ def
  BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
  BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  ⋯  shell  3rd  `echo`  false
  BRANCH  ⋯  shell  3rd  `echo`  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
  BRANCH $ABC⋯  shell  3rd  `echo` $ABCfalse

View File

@ -27,4 +27,5 @@ def
  BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
  BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  BRANCH  ⋯  shell  3rd  `echo`  false
  BRANCH  ⋯  shell  3rd  `echo`  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC"
  BRANCH $ABC⋯  shell  3rd  `echo` $ABCfalse

View File

@ -60,6 +60,7 @@ run() {
local additional_prompts=
fi
env -i \
LANG=en_US.UTF-8 \
PATH="$local_path" \
TERM="${TERM}" \
COLUMNS="${COLUMNS}" \
@ -87,7 +88,7 @@ run_test() {
run "${TEST_TYPE}" "${TEST_CLIENT}" "${SH}" \
screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \
env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "$@"
"$@"
while ! screen -S "$SESNAME" -X readreg a tests/test_shells/input.$SH ; do
sleep 0.1s
done

View File

@ -34,4 +34,5 @@ abc
                   Select variant  1
def
 INSERT  ⋯  tests  shell  3rd  hash -d foo=$PWD:h ; cd .
 INSERT  ~foo  3rd  true
 INSERT  ~foo  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC )
 INSERT $ABC~foo  3rd $ABCtrue

View File

@ -34,4 +34,5 @@ abc
 Select variant  1
def
 INSERT  ⋯  tests  shell  3rd  hash -d foo=$PWD:h ; cd .
 INSERT  ~foo  3rd  true
 INSERT  ~foo  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC )
 INSERT $ABC~foo  3rd $ABCtrue

View File

@ -1,4 +1,5 @@
#!/usr/bin/vim -S
set encoding=utf-8
source powerline/bindings/vim/plugin/powerline.vim
edit abc
tabedit def

View File

@ -9,6 +9,7 @@ options = {
'paste': 0,
'ambiwidth': 'single',
'columns': 80,
'encoding': 'utf-8',
}
_last_bufnr = 0
_highlights = {}