Fix various segment issues

- Fixed user segment (windows): there is no os.geteuid() here
- Fixed dir_limit_depth in cwd segment (it was not really accepting None
  value)
- Made paste_indicator not use getbufvar for global option
- Made file_size use buffer name for cache key
- Made a number of segments coerce returned integer values to strings
- Fixed modified_buffers (getbufvar() returns empty string for deleted buffers,
  but int() does not accept empty string)
- Fixed file_directory and file_name segments: they were not working in
  python-3.3 because str() object has no attribute decode()
- Made powerline.lib.vcs.git.Repository.status() always return 3-characters
  string
- Made it always check both for dirty index and dirty wt for all files
- Fixed binary prefix handling, renamed it to si_prefix

  Previously there was the following when binary_prefix was False:
      div = 1024
      unit = kB
  (unit is inconsistent with div).
  Now it is the following when si_prefix is False:
      div = 1024
      unit = KiB
  (according to https://en.wikipedia.org/wiki/Binary_prefix IEC prefix kibi is
  abbreviated as Ki, not ki (note the case)). This means that in segments prefixes
  has changed, but not displayed values.
This commit is contained in:
ZyX 2013-02-24 12:21:58 +04:00 committed by Kim Silkebækken
parent 168f4854c1
commit dfaf381040
4 changed files with 50 additions and 34 deletions

View File

@ -4,19 +4,19 @@ from math import log
unit_list = tuple(zip(['', 'k', 'M', 'G', 'T', 'P'], [0, 0, 1, 2, 2, 2])) unit_list = tuple(zip(['', 'k', 'M', 'G', 'T', 'P'], [0, 0, 1, 2, 2, 2]))
def humanize_bytes(num, suffix='B', binary_prefix=False): def humanize_bytes(num, suffix='B', si_prefix=False):
'''Return a human friendly byte representation. '''Return a human friendly byte representation.
Modified version from http://stackoverflow.com/questions/1094841 Modified version from http://stackoverflow.com/questions/1094841
''' '''
if num == 0: if num == 0:
return '0 ' + suffix return '0 ' + suffix
div = 1000 if binary_prefix else 1024 div = 1000 if si_prefix else 1024
exponent = min(int(log(num, div)) if num else 0, len(unit_list) - 1) exponent = min(int(log(num, div)) if num else 0, len(unit_list) - 1)
quotient = float(num) / div ** exponent quotient = float(num) / div ** exponent
unit, decimals = unit_list[exponent] unit, decimals = unit_list[exponent]
if unit and binary_prefix: if unit and not si_prefix:
unit += 'i' unit = unit.upper() + 'i'
return '{{quotient:.{decimals}f}} {{unit}}{{suffix}}'\ return '{{quotient:.{decimals}f}} {{unit}}{{suffix}}'\
.format(decimals=decimals)\ .format(decimals=decimals)\
.format(quotient=quotient, unit=unit, suffix=suffix) .format(quotient=quotient, unit=unit, suffix=suffix)

View File

@ -60,15 +60,18 @@ try:
index_column = ' ' index_column = ' '
untracked_column = ' ' untracked_column = ' '
for status in self._repo().status().values(): for status in self._repo().status().values():
if status & git.GIT_STATUS_WT_NEW:
untracked_column = 'U'
continue
if status & (git.GIT_STATUS_WT_DELETED if status & (git.GIT_STATUS_WT_DELETED
| git.GIT_STATUS_WT_MODIFIED): | git.GIT_STATUS_WT_MODIFIED):
wt_column = 'D' wt_column = 'D'
elif status & (git.GIT_STATUS_INDEX_NEW
if status & (git.GIT_STATUS_INDEX_NEW
| git.GIT_STATUS_INDEX_MODIFIED | git.GIT_STATUS_INDEX_MODIFIED
| git.GIT_STATUS_INDEX_DELETED): | git.GIT_STATUS_INDEX_DELETED):
index_column = 'I' index_column = 'I'
elif status & git.GIT_STATUS_WT_NEW:
untracked_column = 'U'
return wt_column + index_column + untracked_column return wt_column + index_column + untracked_column
def branch(self): def branch(self):
@ -117,14 +120,18 @@ except ImportError:
for line in self._gitcmd('status', '--porcelain'): for line in self._gitcmd('status', '--porcelain'):
if line[0] == '?': if line[0] == '?':
untracked_column = 'U' untracked_column = 'U'
continue
elif line[0] == '!': elif line[0] == '!':
pass continue
elif line[0] != ' ':
if line[0] != ' ':
index_column = 'I' index_column = 'I'
elif line[1] != ' ':
if line[1] != ' ':
wt_column = 'D' wt_column = 'D'
r = wt_column + index_column + untracked_column r = wt_column + index_column + untracked_column
return None if r == ' ' else r return r
def branch(self): def branch(self):
for line in self._gitcmd('branch', '-l'): for line in self._gitcmd('branch', '-l'):

View File

@ -24,7 +24,11 @@ def user():
Highlights the user with the ``superuser`` if the effective user ID is 0. Highlights the user with the ``superuser`` if the effective user ID is 0.
''' '''
user = os.environ.get('USER') user = os.environ.get('USER')
try:
euid = os.geteuid() euid = os.geteuid()
except AttributeError:
# os.geteuid is not available on windows
euid = 1
return [{ return [{
'contents': user, 'contents': user,
'highlight_group': 'user' if euid != 0 else ['superuser', 'user'], 'highlight_group': 'user' if euid != 0 else ['superuser', 'user'],
@ -68,7 +72,7 @@ def cwd(dir_shorten_len=None, dir_limit_depth=None):
cwd = re.sub('^' + re.escape(home), '~', cwd, 1) cwd = re.sub('^' + re.escape(home), '~', cwd, 1)
cwd_split = cwd.split(os.sep) cwd_split = cwd.split(os.sep)
cwd_split_len = len(cwd_split) cwd_split_len = len(cwd_split)
if cwd_split_len > dir_limit_depth + 1: if dir_limit_depth and cwd_split_len > dir_limit_depth + 1:
del(cwd_split[0:-dir_limit_depth]) del(cwd_split[0:-dir_limit_depth])
cwd_split.insert(0, u'') cwd_split.insert(0, u'')
cwd = [i[0:dir_shorten_len] if dir_shorten_len and i else i for i in cwd_split[:-1]] + [cwd_split[-1]] cwd = [i[0:dir_shorten_len] if dir_shorten_len and i else i for i in cwd_split[:-1]] + [cwd_split[-1]]
@ -393,7 +397,7 @@ def cpu_load_percent(measure_interval=.5):
@add_divider_highlight_group('background:divider') @add_divider_highlight_group('background:divider')
def network_load(interface='eth0', measure_interval=1, suffix='B/s', binary_prefix=False): def network_load(interface='eth0', measure_interval=1, suffix='B/s', si_prefix=False):
'''Return the network load. '''Return the network load.
Uses the ``psutil`` module if available for multi-platform compatibility, Uses the ``psutil`` module if available for multi-platform compatibility,
@ -406,8 +410,8 @@ def network_load(interface='eth0', measure_interval=1, suffix='B/s', binary_pref
interval used to measure the network load (in seconds) interval used to measure the network load (in seconds)
:param str suffix: :param str suffix:
string appended to each load string string appended to each load string
:param bool binary_prefix: :param bool si_prefix:
use binary prefix, e.g. MiB instead of MB use SI prefix, e.g. MB instead of MiB
''' '''
import time import time
from powerline.lib import humanize_bytes from powerline.lib import humanize_bytes
@ -436,8 +440,8 @@ def network_load(interface='eth0', measure_interval=1, suffix='B/s', binary_pref
time.sleep(measure_interval) time.sleep(measure_interval)
b2 = get_bytes() b2 = get_bytes()
return u'{rx_diff}{tx_diff}'.format( return u'{rx_diff}{tx_diff}'.format(
rx_diff=humanize_bytes((b2[0] - b1[0]) / measure_interval, suffix, binary_prefix).rjust(8), rx_diff=humanize_bytes((b2[0] - b1[0]) / measure_interval, suffix, si_prefix).rjust(8),
tx_diff=humanize_bytes((b2[1] - b1[1]) / measure_interval, suffix, binary_prefix).rjust(8), tx_diff=humanize_bytes((b2[1] - b1[1]) / measure_interval, suffix, si_prefix).rjust(8),
) )

View File

@ -78,6 +78,11 @@ def bufnr(segment_info, **kwargs):
return segment_info['bufnr'] return segment_info['bufnr']
def bufname(segment_info, **kwargs):
'''Used for cache key, returns current buffer name'''
return segment_info['buffer'].name
# TODO Remove cache when needed # TODO Remove cache when needed
def window_cached(func): def window_cached(func):
cache = {} cache = {}
@ -130,7 +135,7 @@ def paste_indicator(segment_info, text='PASTE'):
:param string text: :param string text:
text to display if paste mode is enabled text to display if paste mode is enabled
''' '''
return text if int(getbufvar(segment_info['bufnr'], '&paste')) else None return text if int(vim.eval('&paste')) else None
@requires_segment_info @requires_segment_info
@ -156,7 +161,7 @@ def file_directory(segment_info, shorten_home=False):
file_directory = vim_funcs['fnamemodify'](name, ':~:.:h') file_directory = vim_funcs['fnamemodify'](name, ':~:.:h')
if shorten_home and file_directory.startswith('/home/'): if shorten_home and file_directory.startswith('/home/'):
file_directory = '~' + file_directory[6:] file_directory = '~' + file_directory[6:]
return file_directory.decode('utf-8') + os.sep if file_directory else None return file_directory + os.sep if file_directory else None
@requires_segment_info @requires_segment_info
@ -178,18 +183,18 @@ def file_name(segment_info, display_no_file=False, no_file_text='[No file]'):
else: else:
return None return None
file_name = vim_funcs['fnamemodify'](name, ':~:.:t') file_name = vim_funcs['fnamemodify'](name, ':~:.:t')
return file_name.decode('utf-8') return file_name
@requires_segment_info @requires_segment_info
@memoize(2, cache_key=bufnr, cache_reg_func=purgebuf_on_shell_and_write) @memoize(2, cache_key=bufname, cache_reg_func=purgebuf_on_shell_and_write)
def file_size(segment_info, suffix='B', binary_prefix=False): def file_size(segment_info, suffix='B', si_prefix=False):
'''Return file size. '''Return file size.
:param str suffix: :param str suffix:
string appended to the file size string appended to the file size
:param bool binary_prefix: :param bool si_prefix:
use binary prefix, e.g. MiB instead of MB use SI prefix, e.g. MB instead of MiB
:return: file size or None if the file isn't saved or if the size is too big to fit in a number :return: file size or None if the file isn't saved or if the size is too big to fit in a number
''' '''
file_name = segment_info['buffer'].name file_name = segment_info['buffer'].name
@ -197,7 +202,7 @@ def file_size(segment_info, suffix='B', binary_prefix=False):
file_size = os.stat(file_name).st_size file_size = os.stat(file_name).st_size
except: except:
return None return None
return humanize_bytes(file_size, suffix, binary_prefix) return humanize_bytes(file_size, suffix, si_prefix)
@requires_segment_info @requires_segment_info
@ -241,9 +246,9 @@ def line_percent(segment_info, gradient=False):
line_last = len(segment_info['buffer']) line_last = len(segment_info['buffer'])
percentage = int(line_current * 100 // line_last) percentage = int(line_current * 100 // line_last)
if not gradient: if not gradient:
return percentage return str(percentage)
return [{ return [{
'contents': percentage, 'contents': str(percentage),
'highlight_group': ['line_percent_gradient', 'line_percent'], 'highlight_group': ['line_percent_gradient', 'line_percent'],
'gradient_level': percentage, 'gradient_level': percentage,
}] }]
@ -252,24 +257,24 @@ def line_percent(segment_info, gradient=False):
@requires_segment_info @requires_segment_info
def line_current(segment_info): def line_current(segment_info):
'''Return the current cursor line.''' '''Return the current cursor line.'''
return segment_info['window'].cursor[0] return str(segment_info['window'].cursor[0])
@requires_segment_info @requires_segment_info
def col_current(segment_info): def col_current(segment_info):
'''Return the current cursor column. '''Return the current cursor column.
''' '''
return segment_info['window'].cursor[1] + 1 return str(segment_info['window'].cursor[1] + 1)
@window_cached @window_cached
def virtcol_current(): def virtcol_current():
'''Return current visual column with concealed characters ingored''' '''Return current visual column with concealed characters ingored'''
return [{'contents': vim_funcs['virtcol']('.'), return [{'contents': str(vim_funcs['virtcol']('.')),
'highlight_group': ['virtcol_current', 'col_current']}] 'highlight_group': ['virtcol_current', 'col_current']}]
def modified_buffers(text=u'+', join_str=','): def modified_buffers(text=u'+ ', join_str=u','):
'''Return a comma-separated list of modified buffers. '''Return a comma-separated list of modified buffers.
:param str text: :param str text:
@ -278,9 +283,9 @@ def modified_buffers(text=u'+', join_str=','):
string to use for joining the modified buffer list string to use for joining the modified buffer list
''' '''
buffer_len = vim_funcs['bufnr']('$') buffer_len = vim_funcs['bufnr']('$')
buffer_mod = [str(bufnr) for bufnr in range(1, buffer_len + 1) if int(getbufvar(bufnr, '&modified'))] buffer_mod = [str(bufnr) for bufnr in range(1, buffer_len + 1) if int(getbufvar(bufnr, '&modified') or 0)]
if buffer_mod: if buffer_mod:
return u'{0} {1}'.format(text, join_str.join(buffer_mod)) return text + join_str.join(buffer_mod)
return None return None