Merge pull request #840 from ZyX-I/review-res-fixes

Fixes #819.
This commit is contained in:
ZyX-I 2014-03-13 20:12:12 +03:00
commit 820b5ec4ef
19 changed files with 143 additions and 65 deletions

View File

@ -129,6 +129,7 @@ if sys.version_info < (3,):
return buf.name return buf.name
else: else:
vim_bufname = vim_get_func('bufname') vim_bufname = vim_get_func('bufname')
def buffer_name(buf): # NOQA def buffer_name(buf): # NOQA
try: try:
name = buf.name name = buf.name

View File

@ -13,11 +13,12 @@ from threading import RLock
from powerline.lib.monotonic import monotonic from powerline.lib.monotonic import monotonic
from powerline.lib.inotify import INotify, INotifyError from powerline.lib.inotify import INotify, INotifyError
def realpath(path): def realpath(path):
return os.path.abspath(os.path.realpath(path)) return os.path.abspath(os.path.realpath(path))
class INotifyWatch(INotify):
class INotifyWatch(INotify):
is_stat_based = False is_stat_based = False
def __init__(self, expire_time=10): def __init__(self, expire_time=10):

View File

@ -17,6 +17,6 @@ def humanize_bytes(num, suffix='B', si_prefix=False):
unit, decimals = unit_list[exponent] unit, decimals = unit_list[exponent]
if unit and not si_prefix: if unit and not si_prefix:
unit = unit.upper() + '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

@ -16,19 +16,21 @@ from powerline.lib.inotify import INotify, INotifyError
class NoSuchDir(ValueError): class NoSuchDir(ValueError):
pass pass
class BaseDirChanged(ValueError): class BaseDirChanged(ValueError):
pass pass
class DirTooLarge(ValueError):
class DirTooLarge(ValueError):
def __init__(self, bdir): def __init__(self, bdir):
ValueError.__init__(self, 'The directory {0} is too large to monitor. Try increasing the value in /proc/sys/fs/inotify/max_user_watches'.format(bdir)) ValueError.__init__(self, 'The directory {0} is too large to monitor. Try increasing the value in /proc/sys/fs/inotify/max_user_watches'.format(bdir))
def realpath(path): def realpath(path):
return os.path.abspath(os.path.realpath(path)) return os.path.abspath(os.path.realpath(path))
class INotifyTreeWatcher(INotify):
class INotifyTreeWatcher(INotify):
is_dummy = False is_dummy = False
def __init__(self, basedir, ignore_event=None): def __init__(self, basedir, ignore_event=None):
@ -141,7 +143,6 @@ class INotifyTreeWatcher(INotify):
class DummyTreeWatcher(object): class DummyTreeWatcher(object):
is_dummy = True is_dummy = True
def __init__(self, basedir): def __init__(self, basedir):
@ -150,8 +151,8 @@ class DummyTreeWatcher(object):
def __call__(self): def __call__(self):
return False return False
class TreeWatcher(object):
class TreeWatcher(object):
def __init__(self, expire_time=10): def __init__(self, expire_time=10):
self.watches = {} self.watches = {}
self.last_query_times = {} self.last_query_times = {}
@ -203,6 +204,7 @@ class TreeWatcher(object):
self.watches[path] = DummyTreeWatcher(path) self.watches[path] = DummyTreeWatcher(path)
return False return False
if __name__ == '__main__': if __name__ == '__main__':
w = INotifyTreeWatcher(sys.argv[-1]) w = INotifyTreeWatcher(sys.argv[-1])
w() w()

View File

@ -1,16 +1,11 @@
# vim:fileencoding=utf-8:noet # vim:fileencoding=utf-8:noet
from __future__ import absolute_import from __future__ import absolute_import
import os, errno import os
import errno
from threading import Lock from threading import Lock
from collections import defaultdict from collections import defaultdict
vcs_props = (
('git', '.git', os.path.exists),
('mercurial', '.hg', os.path.isdir),
('bzr', '.bzr', os.path.isdir),
)
def generate_directories(path): def generate_directories(path):
if os.path.isdir(path): if os.path.isdir(path):
@ -24,8 +19,10 @@ def generate_directories(path):
break break
yield path yield path
_file_watcher = None _file_watcher = None
def file_watcher(): def file_watcher():
global _file_watcher global _file_watcher
if _file_watcher is None: if _file_watcher is None:
@ -33,8 +30,10 @@ def file_watcher():
_file_watcher = create_file_watcher() _file_watcher = create_file_watcher()
return _file_watcher return _file_watcher
_branch_watcher = None _branch_watcher = None
def branch_watcher(): def branch_watcher():
global _branch_watcher global _branch_watcher
if _branch_watcher is None: if _branch_watcher is None:
@ -42,10 +41,12 @@ def branch_watcher():
_branch_watcher = create_file_watcher() _branch_watcher = create_file_watcher()
return _branch_watcher return _branch_watcher
branch_name_cache = {} branch_name_cache = {}
branch_lock = Lock() branch_lock = Lock()
file_status_lock = Lock() file_status_lock = Lock()
def get_branch_name(directory, config_file, get_func): def get_branch_name(directory, config_file, get_func):
global branch_name_cache global branch_name_cache
with branch_lock: with branch_lock:
@ -79,8 +80,8 @@ def get_branch_name(directory, config_file, get_func):
branch_name_cache[config_file] = get_func(directory, config_file) branch_name_cache[config_file] = get_func(directory, config_file)
return branch_name_cache[config_file] return branch_name_cache[config_file]
class FileStatusCache(dict):
class FileStatusCache(dict):
def __init__(self): def __init__(self):
self.dirstate_map = defaultdict(set) self.dirstate_map = defaultdict(set)
self.ignore_map = defaultdict(set) self.ignore_map = defaultdict(set)
@ -112,8 +113,10 @@ class FileStatusCache(dict):
for ignf in self.keypath_ignore_map[keypath]: for ignf in self.keypath_ignore_map[keypath]:
yield ignf yield ignf
file_status_cache = FileStatusCache() file_status_cache = FileStatusCache()
def get_file_status(directory, dirstate_file, file_path, ignore_file_name, get_func, extra_ignore_files=()): def get_file_status(directory, dirstate_file, file_path, ignore_file_name, get_func, extra_ignore_files=()):
global file_status_cache global file_status_cache
keypath = file_path if os.path.isabs(file_path) else os.path.join(directory, file_path) keypath = file_path if os.path.isabs(file_path) else os.path.join(directory, file_path)
@ -175,8 +178,8 @@ def get_file_status(directory, dirstate_file, file_path, ignore_file_name, get_f
file_status_cache[keypath] = ans = get_func(directory, file_path) file_status_cache[keypath] = ans = get_func(directory, file_path)
return ans return ans
class TreeStatusCache(dict):
class TreeStatusCache(dict):
def __init__(self): def __init__(self):
from powerline.lib.tree_watcher import TreeWatcher from powerline.lib.tree_watcher import TreeWatcher
self.tw = TreeWatcher() self.tw = TreeWatcher()
@ -196,14 +199,24 @@ class TreeStatusCache(dict):
logger.warn('Failed to check %s for changes, with error: %s'% key, e) logger.warn('Failed to check %s for changes, with error: %s'% key, e)
return self.cache_and_get(key, repo.status) return self.cache_and_get(key, repo.status)
_tree_status_cache = None _tree_status_cache = None
def tree_status(repo, logger): def tree_status(repo, logger):
global _tree_status_cache global _tree_status_cache
if _tree_status_cache is None: if _tree_status_cache is None:
_tree_status_cache = TreeStatusCache() _tree_status_cache = TreeStatusCache()
return _tree_status_cache(repo, logger) return _tree_status_cache(repo, logger)
vcs_props = (
('git', '.git', os.path.exists),
('mercurial', '.hg', os.path.isdir),
('bzr', '.bzr', os.path.isdir),
)
def guess(path): def guess(path):
for directory in generate_directories(path): for directory in generate_directories(path):
for vcs, vcs_dir, check in vcs_props: for vcs, vcs_dir, check in vcs_props:
@ -219,8 +232,12 @@ def guess(path):
pass pass
return None return None
def debug(): def debug():
''' To use run python -c "from powerline.lib.vcs import debug; debug()" some_file_to_watch ''' '''Test run guess(), repo.branch() and repo.status()
To use run python -c "from powerline.lib.vcs import debug; debug()"
some_file_to_watch '''
import sys import sys
dest = sys.argv[-1] dest = sys.argv[-1]
repo = guess(os.path.abspath(dest)) repo = guess(os.path.abspath(dest))

View File

@ -10,16 +10,17 @@ from bzrlib import (workingtree, status, library_state, trace, ui)
from powerline.lib.vcs import get_branch_name, get_file_status from powerline.lib.vcs import get_branch_name, get_file_status
class CoerceIO(StringIO): class CoerceIO(StringIO):
def write(self, arg): def write(self, arg):
if isinstance(arg, bytes): if isinstance(arg, bytes):
arg = arg.decode('utf-8', 'replace') arg = arg.decode('utf-8', 'replace')
return super(CoerceIO, self).write(arg) return super(CoerceIO, self).write(arg)
state = None
nick_pat = re.compile(br'nickname\s*=\s*(.+)') nick_pat = re.compile(br'nickname\s*=\s*(.+)')
def branch_name_from_config_file(directory, config_file): def branch_name_from_config_file(directory, config_file):
ans = None ans = None
try: try:
@ -33,8 +34,11 @@ def branch_name_from_config_file(directory, config_file):
pass pass
return ans or os.path.basename(directory) return ans or os.path.basename(directory)
class Repository(object):
state = None
class Repository(object):
def __init__(self, directory): def __init__(self, directory):
if isinstance(directory, bytes): if isinstance(directory, bytes):
directory = directory.decode(sys.getfilesystemencoding() or sys.getdefaultencoding() or 'utf-8') directory = directory.decode(sys.getfilesystemencoding() or sys.getdefaultencoding() or 'utf-8')
@ -75,7 +79,7 @@ class Repository(object):
return return
if path: if path:
ans = raw[:2] ans = raw[:2]
if ans == 'I ': # Ignored if ans == 'I ': # Ignored
ans = None ans = None
return ans return ans
dirtied = untracked = ' ' dirtied = untracked = ' '
@ -90,4 +94,3 @@ class Repository(object):
def branch(self): def branch(self):
config_file = os.path.join(self.directory, '.bzr', 'branch', 'branch.conf') config_file = os.path.join(self.directory, '.bzr', 'branch', 'branch.conf')
return get_branch_name(self.directory, config_file, branch_name_from_config_file) return get_branch_name(self.directory, config_file, branch_name_from_config_file)

View File

@ -2,12 +2,13 @@
import os import os
import re import re
import errno
from powerline.lib.vcs import get_branch_name as _get_branch_name, get_file_status from powerline.lib.vcs import get_branch_name as _get_branch_name, get_file_status
_ref_pat = re.compile(br'ref:\s*refs/heads/(.+)') _ref_pat = re.compile(br'ref:\s*refs/heads/(.+)')
def branch_name_from_config_file(directory, config_file): def branch_name_from_config_file(directory, config_file):
try: try:
with open(config_file, 'rb') as f: with open(config_file, 'rb') as f:
@ -19,6 +20,7 @@ def branch_name_from_config_file(directory, config_file):
return m.group(1).decode('utf-8', 'replace') return m.group(1).decode('utf-8', 'replace')
return raw[:7] return raw[:7]
def git_directory(directory): def git_directory(directory):
path = os.path.join(directory, '.git') path = os.path.join(directory, '.git')
if os.path.isfile(path): if os.path.isfile(path):
@ -28,10 +30,12 @@ def git_directory(directory):
else: else:
return path return path
def get_branch_name(base_dir): def get_branch_name(base_dir):
head = os.path.join(git_directory(base_dir), 'HEAD') head = os.path.join(git_directory(base_dir), 'HEAD')
return _get_branch_name(base_dir, head, branch_name_from_config_file) return _get_branch_name(base_dir, head, branch_name_from_config_file)
def do_status(directory, path, func): def do_status(directory, path, func):
if path: if path:
gitd = git_directory(directory) gitd = git_directory(directory)
@ -43,12 +47,14 @@ def do_status(directory, path, func):
path, '.gitignore', func, extra_ignore_files=tuple(os.path.join(gitd, x) for x in ('logs/HEAD', 'info/exclude'))) path, '.gitignore', func, extra_ignore_files=tuple(os.path.join(gitd, x) for x in ('logs/HEAD', 'info/exclude')))
return func(directory, path) return func(directory, path)
def ignore_event(path, name): def ignore_event(path, name):
# Ignore changes to the index.lock file, since they happen frequently and # Ignore changes to the index.lock file, since they happen frequently and
# dont indicate an actual change in the working tree status # dont indicate an actual change in the working tree status
return False return False
return path.endswith('.git') and name == 'index.lock' return path.endswith('.git') and name == 'index.lock'
try: try:
import pygit2 as git import pygit2 as git

View File

@ -7,6 +7,7 @@ from mercurial import hg, ui, match
from powerline.lib.vcs import get_branch_name, get_file_status from powerline.lib.vcs import get_branch_name, get_file_status
def branch_name_from_config_file(directory, config_file): def branch_name_from_config_file(directory, config_file):
try: try:
with open(config_file, 'rb') as f: with open(config_file, 'rb') as f:
@ -15,6 +16,7 @@ def branch_name_from_config_file(directory, config_file):
except Exception: except Exception:
return 'default' return 'default'
class Repository(object): class Repository(object):
__slots__ = ('directory', 'ui') __slots__ = ('directory', 'ui')

View File

@ -14,6 +14,7 @@ try:
except ImportError: except ImportError:
pass pass
def construct_returned_value(rendered_highlighted, segments, output_raw): def construct_returned_value(rendered_highlighted, segments, output_raw):
if output_raw: if output_raw:
return rendered_highlighted, ''.join((segment['_rendered_raw'] for segment in segments)) return rendered_highlighted, ''.join((segment['_rendered_raw'] for segment in segments))
@ -70,7 +71,7 @@ class Renderer(object):
character_translations = {ord(' '): NBSP} character_translations = {ord(' '): NBSP}
'''Character translations for use in escape() function. '''Character translations for use in escape() function.
See documentation of ``unicode.translate`` for details. See documentation of ``unicode.translate`` for details.
''' '''
@ -111,7 +112,7 @@ class Renderer(object):
def strwidth(self, string): def strwidth(self, string):
'''Function that returns string width. '''Function that returns string width.
Is used to calculate the place given string occupies when handling Is used to calculate the place given string occupies when handling
``width`` argument to ``.render()`` method. Must take east asian width ``width`` argument to ``.render()`` method. Must take east asian width
into account. into account.
@ -125,7 +126,7 @@ class Renderer(object):
def get_theme(self, matcher_info): def get_theme(self, matcher_info):
'''Get Theme object. '''Get Theme object.
Is to be overridden by subclasses to support local themes, this variant Is to be overridden by subclasses to support local themes, this variant
only returns ``.theme`` attribute. only returns ``.theme`` attribute.
@ -152,7 +153,7 @@ class Renderer(object):
def get_segment_info(self, segment_info, mode): def get_segment_info(self, segment_info, mode):
'''Get segment information. '''Get segment information.
Must return a dictionary containing at least ``home``, ``environ`` and Must return a dictionary containing at least ``home``, ``environ`` and
``getcwd`` keys (see documentation for ``segment_info`` attribute). This ``getcwd`` keys (see documentation for ``segment_info`` attribute). This
implementation merges ``segment_info`` dictionary passed to implementation merges ``segment_info`` dictionary passed to

View File

@ -140,12 +140,12 @@ class VimRenderer(Renderer):
hl_group['attr'].append('italic') hl_group['attr'].append('italic')
if attr & ATTR_UNDERLINE: if attr & ATTR_UNDERLINE:
hl_group['attr'].append('underline') hl_group['attr'].append('underline')
hl_group['name'] = 'Pl_' + \ hl_group['name'] = ('Pl_' +
str(hl_group['ctermfg']) + '_' + \ str(hl_group['ctermfg']) + '_' +
str(hl_group['guifg']) + '_' + \ str(hl_group['guifg']) + '_' +
str(hl_group['ctermbg']) + '_' + \ str(hl_group['ctermbg']) + '_' +
str(hl_group['guibg']) + '_' + \ str(hl_group['guibg']) + '_' +
''.join(hl_group['attr']) ''.join(hl_group['attr']))
self.hl_groups[(fg, bg, attr)] = hl_group self.hl_groups[(fg, bg, attr)] = hl_group
vim.command('hi {group} ctermfg={ctermfg} guifg={guifg} guibg={guibg} ctermbg={ctermbg} cterm={attr} gui={attr}'.format( vim.command('hi {group} ctermfg={ctermfg} guifg={guifg} guibg={guibg} ctermbg={ctermbg} cterm={attr} gui={attr}'.format(
group=hl_group['name'], group=hl_group['name'],

View File

@ -75,17 +75,22 @@ def branch(pl, segment_info, status_colors=False):
@requires_segment_info @requires_segment_info
def cwd(pl, segment_info, dir_shorten_len=None, dir_limit_depth=None, use_path_separator=False): def cwd(pl, segment_info, dir_shorten_len=None, dir_limit_depth=None, use_path_separator=False, ellipsis=''):
'''Return the current working directory. '''Return the current working directory.
Returns a segment list to create a breadcrumb-like effect. Returns a segment list to create a breadcrumb-like effect.
:param int dir_shorten_len: :param int dir_shorten_len:
shorten parent directory names to this length (e.g. :file:`/long/path/to/powerline` :file:`/l/p/t/powerline`) shorten parent directory names to this length (e.g.
:file:`/long/path/to/powerline` :file:`/l/p/t/powerline`)
:param int dir_limit_depth: :param int dir_limit_depth:
limit directory depth to this number (e.g. :file:`/long/path/to/powerline` :file:`/to/powerline`) limit directory depth to this number (e.g.
:file:`/long/path/to/powerline` :file:`/to/powerline`)
:param bool use_path_separator: :param bool use_path_separator:
Use path separator in place of soft divider. Use path separator in place of soft divider.
:param str ellipsis:
Specifies what to use in place of omitted directories. Use None to not
show this subsegment at all.
Divider highlight group used: ``cwd:divider``. Divider highlight group used: ``cwd:divider``.
@ -110,7 +115,8 @@ def cwd(pl, segment_info, dir_shorten_len=None, dir_limit_depth=None, use_path_s
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]]
if dir_limit_depth and cwd_split_len > dir_limit_depth + 1: if dir_limit_depth and cwd_split_len > dir_limit_depth + 1:
del(cwd[0:-dir_limit_depth]) del(cwd[0:-dir_limit_depth])
cwd.insert(0, '') if ellipsis is not None:
cwd.insert(0, ellipsis)
ret = [] ret = []
if not cwd[0]: if not cwd[0]:
cwd[0] = '/' cwd[0] = '/'
@ -138,6 +144,8 @@ def date(pl, format='%Y-%m-%d', istime=False):
:param str format: :param str format:
strftime-style date format string strftime-style date format string
:param bool istime:
If true then segment uses ``time`` highlight group.
Divider highlight group used: ``time:divider``. Divider highlight group used: ``time:divider``.
@ -150,8 +158,19 @@ def date(pl, format='%Y-%m-%d', istime=False):
}] }]
def fuzzy_time(pl): UNICODE_TEXT_TRANSLATION = {
'''Display the current time as fuzzy time, e.g. "quarter past six".''' ord('\''): '',
ord('-'): '',
}
def fuzzy_time(pl, unicode_text=True):
'''Display the current time as fuzzy time, e.g. "quarter past six".
:param bool unicode_text:
If true then hyphenminuses (regular ASCII ``-``) and single quotes are
replaced with unicode dashes and apostrophes.
'''
hour_str = ['twelve', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven'] hour_str = ['twelve', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven']
minute_str = { minute_str = {
5: 'five past', 5: 'five past',
@ -194,10 +213,15 @@ def fuzzy_time(pl):
minute = int(round(now.minute / 5.0) * 5) minute = int(round(now.minute / 5.0) * 5)
if minute == 60 or minute == 0: if minute == 60 or minute == 0:
return ' '.join([hour, 'o\'clock']) result = ' '.join([hour, 'o\'clock'])
else: else:
minute = minute_str[minute] minute = minute_str[minute]
return ' '.join([minute, hour]) result = ' '.join([minute, hour])
if unicode_text:
result = result.translate(UNICODE_TEXT_TRANSLATION)
return result
def _external_ip(query_url='http://ipv4.icanhazip.com/'): def _external_ip(query_url='http://ipv4.icanhazip.com/'):
@ -223,15 +247,15 @@ class ExternalIpSegment(ThreadedSegment):
external_ip = with_docstring(ExternalIpSegment(), external_ip = with_docstring(ExternalIpSegment(),
'''Return external IP address. '''Return external IP address.
Suggested URIs:
* http://ipv4.icanhazip.com/
* http://ipv6.icanhazip.com/
* http://icanhazip.com/ (returns IPv6 address if available, else IPv4)
:param str query_url: :param str query_url:
URI to query for IP address, should return only the IP address as a text string URI to query for IP address, should return only the IP address as a text string
Suggested URIs:
* http://ipv4.icanhazip.com/
* http://ipv6.icanhazip.com/
* http://icanhazip.com/ (returns IPv6 address if available, else IPv4)
Divider highlight group used: ``background:divider``. Divider highlight group used: ``background:divider``.
''') ''')

View File

@ -46,7 +46,7 @@ def last_pipe_status(pl, segment_info):
@requires_segment_info @requires_segment_info
def mode(pl, segment_info, override={'vicmd': 'COMMND', 'viins': 'INSERT'}, default=None): def mode(pl, segment_info, override={'vicmd': 'COMMND', 'viins': 'INSERT'}, default=None):
'''Return the current mode. '''Return the current mode.
:param dict override: :param dict override:
dict for overriding mode strings. dict for overriding mode strings.
:param str default: :param str default:

View File

@ -161,7 +161,6 @@ def file_directory(pl, segment_info, shorten_user=True, shorten_cwd=True, shorte
name = buffer_name(segment_info['buffer']) name = buffer_name(segment_info['buffer'])
if not name: if not name:
return None return None
import sys
file_directory = vim_funcs['fnamemodify'](name, (':~' if shorten_user else '') file_directory = vim_funcs['fnamemodify'](name, (':~' if shorten_user else '')
+ (':.' if shorten_cwd else '') + ':h') + (':.' if shorten_cwd else '') + ':h')
if not file_directory: if not file_directory:
@ -285,7 +284,7 @@ def line_percent(pl, segment_info, gradient=False):
@window_cached @window_cached
def position(pl, position_strings={'top':'Top', 'bottom':'Bot', 'all':'All'}, gradient=False): def position(pl, position_strings={'top': 'Top', 'bottom': 'Bot', 'all': 'All'}, gradient=False):
'''Return the position of the current view in the file as a percentage. '''Return the position of the current view in the file as a percentage.
:param dict position_strings: :param dict position_strings:
@ -368,6 +367,7 @@ def modified_buffers(pl, text='+ ', join_str=','):
return text + join_str.join(buffer_mod) return text + join_str.join(buffer_mod)
return None return None
@requires_segment_info @requires_segment_info
def branch(pl, segment_info, status_colors=False): def branch(pl, segment_info, status_colors=False):
'''Return the current working branch. '''Return the current working branch.
@ -395,6 +395,7 @@ def branch(pl, segment_info, status_colors=False):
'divider_highlight_group': 'branch:divider', 'divider_highlight_group': 'branch:divider',
}] }]
@requires_segment_info @requires_segment_info
def file_vcs_status(pl, segment_info): def file_vcs_status(pl, segment_info):
'''Return the VCS status for this buffer. '''Return the VCS status for this buffer.

View File

@ -1,7 +1,7 @@
# vim:fileencoding=utf-8:noet # vim:fileencoding=utf-8:noet
from powerline.segment import gen_segment_getter from powerline.segment import gen_segment_getter
from powerline.lib.unicode import u, unicode from powerline.lib.unicode import u
def requires_segment_info(func): def requires_segment_info(func):

View File

@ -18,9 +18,11 @@ class TestParser(TestCase):
parser = get_argparser() parser = get_argparser()
out = StrIO() out = StrIO()
err = StrIO() err = StrIO()
def flush(): def flush():
out.truncate(0) out.truncate(0)
err.truncate(0) err.truncate(0)
with replace_attr(sys, 'stdout', out, 'stderr', err): with replace_attr(sys, 'stdout', out, 'stderr', err):
for raising_args, raising_reg in [ for raising_args, raising_reg in [
([], 'too few arguments|the following arguments are required: ext'), ([], 'too few arguments|the following arguments are required: ext'),
@ -69,7 +71,7 @@ class TestParser(TestCase):
'-c', 'common.spaces=4', '-c', 'common.spaces=4',
'-t', 'default.segment_data.hostname.before=H:', '-t', 'default.segment_data.hostname.before=H:',
'-p', '.', '-p', '.',
'-R', 'smth={"abc":"def"}' '-R', 'smth={"abc":"def"}',
], { ], {
'ext': ['shell'], 'ext': ['shell'],
'side': 'left', 'side': 'left',

View File

@ -257,10 +257,24 @@ class TestCommon(TestCase):
{'contents': '', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': '', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True},
{'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}
]) ])
self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, ellipsis='...'), [
{'contents': '...', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True},
{'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}
])
self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, ellipsis=None), [
{'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}
])
self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True), [ self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True), [
{'contents': '⋯/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, {'contents': '⋯/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False},
{'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']} {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']}
]) ])
self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True, ellipsis='...'), [
{'contents': '.../', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False},
{'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']}
])
self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True, ellipsis=None), [
{'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']}
])
self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2), [ self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2), [
{'contents': '~', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': '~', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True},
{'contents': 'fo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'fo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True},
@ -312,9 +326,13 @@ class TestCommon(TestCase):
time.minute = 59 time.minute = 59
self.assertEqual(common.fuzzy_time(pl=pl), 'round about midnight') self.assertEqual(common.fuzzy_time(pl=pl), 'round about midnight')
time.minute = 33 time.minute = 33
self.assertEqual(common.fuzzy_time(pl=pl), 'twenty-five to twelve') self.assertEqual(common.fuzzy_time(pl=pl), 'twentyfive to twelve')
time.minute = 60 time.minute = 60
self.assertEqual(common.fuzzy_time(pl=pl), 'twelve o\'clock') self.assertEqual(common.fuzzy_time(pl=pl), 'twelve oclock')
time.minute = 33
self.assertEqual(common.fuzzy_time(pl=pl, unicode_text=False), 'twenty-five to twelve')
time.minute = 60
self.assertEqual(common.fuzzy_time(pl=pl, unicode_text=False), 'twelve o\'clock')
def test_external_ip(self): def test_external_ip(self):
pl = Pl() pl = Pl()
@ -476,8 +494,8 @@ class TestCommon(TestCase):
def test_environment(self): def test_environment(self):
pl = Pl() pl = Pl()
variable = 'FOO'; variable = 'FOO'
value = 'bar'; value = 'bar'
with replace_env(variable, value) as segment_info: with replace_env(variable, value) as segment_info:
self.assertEqual(common.environment(pl=pl, segment_info=segment_info, variable=variable), value) self.assertEqual(common.environment(pl=pl, segment_info=segment_info, variable=variable), value)
segment_info['environ'].pop(variable) segment_info['environ'].pop(variable)
@ -542,6 +560,7 @@ class TestCommon(TestCase):
} }
]) ])
class TestVim(TestCase): class TestVim(TestCase):
def test_mode(self): def test_mode(self):
pl = Pl() pl = Pl()
@ -659,10 +678,10 @@ class TestVim(TestCase):
vim_module._set_cursor(0, 0) vim_module._set_cursor(0, 0)
self.assertEqual(vim.position(pl=pl, segment_info=segment_info), 'Top') self.assertEqual(vim.position(pl=pl, segment_info=segment_info), 'Top')
vim_module._set_cursor(97, 0) vim_module._set_cursor(97, 0)
self.assertEqual(vim.position(pl=pl, segment_info=segment_info, position_strings={'top':'Comienzo', 'bottom':'Final', 'all':'Todo'}), 'Final') self.assertEqual(vim.position(pl=pl, segment_info=segment_info, position_strings={'top': 'Comienzo', 'bottom': 'Final', 'all': 'Todo'}), 'Final')
segment_info['buffer'][0:-1] = [str(i) for i in range(2)] segment_info['buffer'][0:-1] = [str(i) for i in range(2)]
vim_module._set_cursor(0, 0) vim_module._set_cursor(0, 0)
self.assertEqual(vim.position(pl=pl, segment_info=segment_info, position_strings={'top':'Comienzo', 'bottom':'Final', 'all':'Todo'}), 'Todo') self.assertEqual(vim.position(pl=pl, segment_info=segment_info, position_strings={'top': 'Comienzo', 'bottom': 'Final', 'all': 'Todo'}), 'Todo')
self.assertEqual(vim.position(pl=pl, segment_info=segment_info, gradient=True), self.assertEqual(vim.position(pl=pl, segment_info=segment_info, gradient=True),
[{'contents': 'All', 'highlight_group': ['position_gradient', 'position'], 'gradient_level': 0.0}]) [{'contents': 'All', 'highlight_group': ['position_gradient', 'position'], 'gradient_level': 0.0}])
finally: finally:

View File

@ -38,14 +38,14 @@ with codecs.open(fname, 'r', encoding='utf-8') as R:
try: try:
start = line.index('\033[0;') start = line.index('\033[0;')
end = line.index('\033[0m', start) end = line.index('\033[0m', start)
line = line[start : end+4] + '\n' line = line[start:end + 4] + '\n'
except ValueError: except ValueError:
line = '' line = ''
elif shell == 'tcsh': elif shell == 'tcsh':
try: try:
start = line.index('\033[0;') start = line.index('\033[0;')
end = line.index(' ', start) end = line.index(' ', start)
line = line[start : end] + '\033[0m\n' line = line[start:end] + '\033[0m\n'
except ValueError: except ValueError:
line = '' line = ''
W.write(line) W.write(line)

View File

@ -307,9 +307,9 @@ def _emul_line(expr):
cursorline = windows[_window - 1].cursor[0] + 1 cursorline = windows[_window - 1].cursor[0] + 1
numlines = len(_buf_lines[_buffer()]) numlines = len(_buf_lines[_buffer()])
if expr == 'w0': if expr == 'w0':
return max(cursorline-5, 1) return max(cursorline - 5, 1)
if expr == 'w$': if expr == 'w$':
return min(cursorline+5, numlines) return min(cursorline + 5, numlines)
raise NotImplementedError raise NotImplementedError
@ -401,7 +401,6 @@ class _Buffer(object):
import os import os
if type(name) is not bytes: if type(name) is not bytes:
name = name.encode('utf-8') name = name.encode('utf-8')
import sys
self._name = os.path.abspath(name) self._name = os.path.abspath(name)
def __getitem__(self, line): def __getitem__(self, line):

View File

@ -138,8 +138,8 @@ palettes = {
'256': (cterm_to_hex, lambda c: c), '256': (cterm_to_hex, lambda c: c),
None: (cterm_to_hex[16:], lambda c: c + 16), None: (cterm_to_hex[16:], lambda c: c + 16),
} }
r = [get_rgb(*color) for color in gradient] r = [get_rgb(*col) for col in gradient]
r2 = [find_color(color, *palettes[args.palette])[0] for color in gradient] r2 = [find_color(col, *palettes[args.palette])[0] for col in gradient]
r3 = [i[0] for i in groupby(r2)] r3 = [i[0] for i in groupby(r2)]
print(json.dumps(r)) print(json.dumps(r))
print(json.dumps(r2)) print(json.dumps(r2))