mirror of
https://github.com/powerline/powerline.git
synced 2025-07-30 17:25:28 +02:00
Release 1.2
Changes: - When guessing used network interface for internal_ip segment the priority of various VM bridge interfaces was lowered. - Added `ignore_statuses` option that makes one able to prevent certain repository statutes (e.g. `"U"`: only modification is unknown files) from marking repository as dirty. - Refactored `powerline.segments.common.players` module: deprecated `now_playing` segment, replacing it with segments with names identical to player names (e.g. `powerline.segments.common.players.mpd`). `now_playing` segment will continue to work until powerline-2.0 though. - Fixed `powerline.segments.tmux.attached_clients` segment: it was not working at all due to missing argument in one function call. - Fixed regular expression used to detect NERDTree buffers.
This commit is contained in:
commit
39dda39bdc
@ -29,6 +29,24 @@ object it should receive the following arguments:
|
||||
And also any other argument(s) specified by user in :ref:`args key
|
||||
<config-themes-seg-args>` (no additional arguments by default).
|
||||
|
||||
.. note::
|
||||
For powerline-lint to work properly the following things may be needed:
|
||||
|
||||
#. If your segment is a :py:class:`powerline.segments.Segment` and used
|
||||
arguments are scattered over multiple methods
|
||||
:py:meth:`powerline.segments.Segment.argspecobjs` should be overridden in
|
||||
subclass to tell powerline-lint which objects should be inspected for
|
||||
arguments.
|
||||
#. If your segment takes some arguments that are never listed, but accessed
|
||||
via ``kwargs.get()`` or you cannot use previous function for whatever
|
||||
reason :py:meth:`powerline.segments.Segment.additional_args` should be
|
||||
overridden in subclass.
|
||||
#. If you are expecting user to use one :ref:`name <config-themes-seg-name>`
|
||||
for multiple segments which cannot be linked to the segment function
|
||||
automatically by powerline-lint (e.g. because there are no instances of
|
||||
the segments in question in the default configuration) you should use
|
||||
:py:func:`powerline.lint.checks.register_common_name`.
|
||||
|
||||
Object representing segment may have the following attributes used by
|
||||
powerline:
|
||||
|
||||
|
@ -59,3 +59,12 @@ I receive an ``ImportError`` when trying to use Powerline on OS X!
|
||||
|
||||
* See `issue #39 <https://github.com/Lokaltog/powerline/issues/39>`_ for
|
||||
a discussion and other possible solutions for this issue.
|
||||
|
||||
I receive “FSEventStreamStart: register_with_server: ERROR” with status_colors
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
This is `a known <https://github.com/joyent/node/issues/5463>`_ libuv issue that
|
||||
happens if one is trying to watch too many files. It should be fixed in
|
||||
libuv-0.12. Until then it is suggested to either disable ``status_colors`` (from
|
||||
:py:func:`powerline.segments.common.vcs.branch`) or choose stat-based watcher
|
||||
(will have effectively the same effect as disabling ``status_colors``).
|
||||
|
@ -28,7 +28,7 @@
|
||||
"battery_gradient": { "fg": "white_red", "bg": "gray0", "attr": [] },
|
||||
"battery_full": { "fg": "red", "bg": "gray0", "attr": [] },
|
||||
"battery_empty": { "fg": "white", "bg": "gray0", "attr": [] },
|
||||
"now_playing": { "fg": "gray10", "bg": "black", "attr": [] },
|
||||
"player": { "fg": "gray10", "bg": "black", "attr": [] },
|
||||
"user": { "fg": "white", "bg": "darkblue", "attr": ["bold"] },
|
||||
"superuser": { "fg": "white", "bg": "brightred", "attr": ["bold"] },
|
||||
"branch": { "fg": "gray9", "bg": "gray2", "attr": [] },
|
||||
|
@ -20,6 +20,16 @@
|
||||
"ellipsis": "..."
|
||||
}
|
||||
},
|
||||
"player": {
|
||||
"args": {
|
||||
"state_symbols": {
|
||||
"fallback": "",
|
||||
"play": ">",
|
||||
"pause": "~",
|
||||
"stop": "X"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"line_current_symbol": {
|
||||
"contents": "LN "
|
||||
|
@ -23,6 +23,16 @@
|
||||
"line_current_symbol": {
|
||||
"contents": " "
|
||||
},
|
||||
"player": {
|
||||
"args": {
|
||||
"state_symbols": {
|
||||
"fallback": "♫",
|
||||
"play": "▶",
|
||||
"pause": "▮▮",
|
||||
"stop": "■"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"time": {
|
||||
"before": "⌚ "
|
||||
|
@ -19,6 +19,16 @@
|
||||
"ellipsis": "⋯"
|
||||
}
|
||||
},
|
||||
"player": {
|
||||
"args": {
|
||||
"state_symbols": {
|
||||
"fallback": "♫",
|
||||
"play": "▶",
|
||||
"pause": "▮▮",
|
||||
"stop": "■"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"line_current_symbol": {
|
||||
"contents": " "
|
||||
|
@ -23,6 +23,16 @@
|
||||
"line_current_symbol": {
|
||||
"contents": " "
|
||||
},
|
||||
"player": {
|
||||
"args": {
|
||||
"state_symbols": {
|
||||
"fallback": "♫",
|
||||
"play": "▶",
|
||||
"pause": "▮▮",
|
||||
"stop": "■"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"time": {
|
||||
"before": ""
|
||||
|
@ -24,6 +24,16 @@
|
||||
"line_current_symbol": {
|
||||
"contents": ""
|
||||
},
|
||||
"player": {
|
||||
"args": {
|
||||
"state_symbols": {
|
||||
"fallback": "♫",
|
||||
"play": "▶",
|
||||
"pause": "▮▮",
|
||||
"stop": "■"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"time": {
|
||||
"before": ""
|
||||
|
@ -16,7 +16,7 @@ if sys.platform.startswith('win32'):
|
||||
Popen = partial(Popen, creationflags=0x08000000)
|
||||
|
||||
|
||||
def run_cmd(pl, cmd, stdin=None):
|
||||
def run_cmd(pl, cmd, stdin=None, strip=True):
|
||||
'''Run command and return its stdout, stripped
|
||||
|
||||
If running command fails returns None and logs failure to ``pl`` argument.
|
||||
@ -27,6 +27,8 @@ def run_cmd(pl, cmd, stdin=None):
|
||||
Command which will be run.
|
||||
:param str stdin:
|
||||
String passed to command. May be None.
|
||||
:param bool strip:
|
||||
True if the result should be stripped.
|
||||
'''
|
||||
try:
|
||||
p = Popen(cmd, shell=False, stdout=PIPE, stdin=PIPE)
|
||||
@ -36,7 +38,7 @@ def run_cmd(pl, cmd, stdin=None):
|
||||
else:
|
||||
stdout, err = p.communicate(stdin)
|
||||
stdout = stdout.decode(get_preferred_input_encoding())
|
||||
return stdout.strip()
|
||||
return stdout.strip() if strip else stdout
|
||||
|
||||
|
||||
def asrun(pl, ascript):
|
||||
|
@ -19,7 +19,7 @@ from powerline.lint.checks import (check_matcher_func, check_ext, check_config,
|
||||
check_segment_module, check_exinclude_function, type_keys,
|
||||
check_segment_function, check_args, get_one_segment_function,
|
||||
check_highlight_groups, check_highlight_group, check_full_segment_data,
|
||||
get_all_possible_functions, check_segment_data_key)
|
||||
get_all_possible_functions, check_segment_data_key, register_common_name)
|
||||
from powerline.lint.spec import Spec
|
||||
from powerline.lint.context import Context
|
||||
|
||||
@ -289,6 +289,10 @@ theme_spec = common_theme_spec().update(
|
||||
)
|
||||
|
||||
|
||||
def register_common_names():
|
||||
register_common_name('player', 'powerline.segments.common.players', '_player')
|
||||
|
||||
|
||||
def check(paths=None, debug=False, echoerr=echoerr, require_ext=None):
|
||||
'''Check configuration sanity
|
||||
|
||||
@ -308,6 +312,7 @@ def check(paths=None, debug=False, echoerr=echoerr, require_ext=None):
|
||||
``False`` if user configuration seems to be completely sane and ``True``
|
||||
if some problems were found.
|
||||
'''
|
||||
register_common_names()
|
||||
search_paths = paths or get_config_paths()
|
||||
find_config_files = generate_config_finder(lambda: search_paths)
|
||||
|
||||
|
@ -5,6 +5,8 @@ import os
|
||||
import re
|
||||
import logging
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from powerline.lib.threaded import ThreadedSegment
|
||||
from powerline.lib.unicode import unicode
|
||||
from powerline.lint.markedjson.markedvalue import MarkedUnicode
|
||||
@ -673,6 +675,16 @@ def get_one_segment_function(data, context, echoerr):
|
||||
yield func
|
||||
|
||||
|
||||
common_names = defaultdict(set)
|
||||
|
||||
|
||||
def register_common_name(name, cmodule, cname):
|
||||
s = cmodule + '.' + cname
|
||||
cmodule_mark = Mark('<common name definition>', 1, 1, s, 1)
|
||||
cname_mark = Mark('<common name definition>', 1, len(cmodule) + 1, s, len(cmodule) + 1)
|
||||
common_names[name].add((MarkedUnicode(cmodule, cmodule_mark), MarkedUnicode(cname, cname_mark)))
|
||||
|
||||
|
||||
def get_all_possible_functions(data, context, echoerr):
|
||||
name = context[-2][0]
|
||||
module, name = name.rpartition('.')[::2]
|
||||
@ -681,6 +693,11 @@ def get_all_possible_functions(data, context, echoerr):
|
||||
if func:
|
||||
yield func
|
||||
else:
|
||||
if name in common_names:
|
||||
for cmodule, cname in common_names[name]:
|
||||
cfunc = import_segment(cname, data, context, echoerr, module=MarkedUnicode(cmodule, None))
|
||||
if cfunc:
|
||||
yield cfunc
|
||||
for ext, theme_config in list_themes(data, context):
|
||||
for segments in theme_config.get('segments', {}).values():
|
||||
for segment in segments:
|
||||
|
@ -27,6 +27,12 @@ def import_function(function_type, name, data, context, echoerr, module):
|
||||
problem='module {0} is deprecated'.format(module),
|
||||
problem_mark=module.mark)
|
||||
|
||||
if module == 'powerline.segments.common.players' and name == 'now_playing':
|
||||
echoerr(context='Warning while checking segments (key {key})'.format(key=context.key),
|
||||
context_mark=name.mark,
|
||||
problem='function {0}.{1} is deprecated: use {0}.{{player_name}} instead'.format(module, name),
|
||||
problem_mark=module.mark)
|
||||
|
||||
with WithPath(data['import_paths']):
|
||||
try:
|
||||
func = getattr(__import__(str(module), fromlist=[str(name)]), str(name))
|
||||
|
@ -7,7 +7,7 @@ import re
|
||||
from powerline.bindings.vim import buffer_name
|
||||
|
||||
|
||||
NERD_TREE_RE = re.compile(b'NERD_TREE_\\d+')
|
||||
NERD_TREE_RE = re.compile(b'NERD_tree_\\d+')
|
||||
|
||||
|
||||
def nerdtree(matcher_info):
|
||||
|
@ -72,13 +72,16 @@ except ImportError:
|
||||
return None
|
||||
else:
|
||||
_interface_starts = {
|
||||
'eth': 10, # Regular ethernet adapters : eth1
|
||||
'enp': 10, # Regular ethernet adapters, Gentoo : enp2s0
|
||||
'ath': 9, # Atheros WiFi adapters : ath0
|
||||
'wlan': 9, # Other WiFi adapters : wlan1
|
||||
'wlp': 9, # Other WiFi adapters, Gentoo : wlp5s0
|
||||
'teredo': 1, # miredo interface : teredo
|
||||
'lo': -10, # Loopback interface : lo
|
||||
'eth': 10, # Regular ethernet adapters : eth1
|
||||
'enp': 10, # Regular ethernet adapters, Gentoo : enp2s0
|
||||
'ath': 9, # Atheros WiFi adapters : ath0
|
||||
'wlan': 9, # Other WiFi adapters : wlan1
|
||||
'wlp': 9, # Other WiFi adapters, Gentoo : wlp5s0
|
||||
'teredo': 1, # miredo interface : teredo
|
||||
'lo': -10, # Loopback interface : lo
|
||||
'docker': -5, # Docker bridge interface : docker0
|
||||
'vmnet': -5, # VMWare bridge interface : vmnet1
|
||||
'vboxnet': -5, # VirtualBox bridge interface : vboxnet0
|
||||
}
|
||||
|
||||
_interface_start_re = re.compile(r'^([a-z]+?)(\d|$)')
|
||||
|
@ -5,7 +5,7 @@ import sys
|
||||
|
||||
from powerline.lib.shell import asrun, run_cmd
|
||||
from powerline.lib.unicode import out_u
|
||||
from powerline.segments import Segment
|
||||
from powerline.segments import Segment, with_docstring
|
||||
|
||||
|
||||
STATE_SYMBOLS = {
|
||||
@ -16,9 +16,25 @@ STATE_SYMBOLS = {
|
||||
}
|
||||
|
||||
|
||||
class NowPlayingSegment(Segment):
|
||||
def __call__(self, player='mpd', format='{state_symbol} {artist} - {title} ({total})', state_symbols=STATE_SYMBOLS, **kwargs):
|
||||
player_func = getattr(self, 'player_{0}'.format(player))
|
||||
def _convert_state(state):
|
||||
'''Guess player state'''
|
||||
state = state.lower()
|
||||
if 'play' in state:
|
||||
return 'play'
|
||||
if 'pause' in state:
|
||||
return 'pause'
|
||||
if 'stop' in state:
|
||||
return 'stop'
|
||||
return 'fallback'
|
||||
|
||||
|
||||
def _convert_seconds(seconds):
|
||||
'''Convert seconds to minutes:seconds format'''
|
||||
return '{0:.0f}:{1:02.0f}'.format(*divmod(float(seconds), 60))
|
||||
|
||||
|
||||
class PlayerSegment(Segment):
|
||||
def __call__(self, format='{state_symbol} {artist} - {title} ({total})', state_symbols=STATE_SYMBOLS, **kwargs):
|
||||
stats = {
|
||||
'state': 'fallback',
|
||||
'album': None,
|
||||
@ -27,28 +43,83 @@ class NowPlayingSegment(Segment):
|
||||
'elapsed': None,
|
||||
'total': None,
|
||||
}
|
||||
func_stats = player_func(**kwargs)
|
||||
func_stats = self.get_player_status(**kwargs)
|
||||
if not func_stats:
|
||||
return None
|
||||
stats.update(func_stats)
|
||||
stats['state_symbol'] = state_symbols.get(stats['state'])
|
||||
return format.format(**stats)
|
||||
return [{
|
||||
'contents': format.format(**stats),
|
||||
'highlight_group': ['now_playing', 'player_' + (stats['state'] or 'fallback'), 'player'],
|
||||
}]
|
||||
|
||||
@staticmethod
|
||||
def _convert_state(state):
|
||||
state = state.lower()
|
||||
if 'play' in state:
|
||||
return 'play'
|
||||
if 'pause' in state:
|
||||
return 'pause'
|
||||
if 'stop' in state:
|
||||
return 'stop'
|
||||
def get_player_status(self, pl):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def _convert_seconds(seconds):
|
||||
return '{0:.0f}:{1:02.0f}'.format(*divmod(float(seconds), 60))
|
||||
def argspecobjs(self):
|
||||
for ret in super(PlayerSegment, self).argspecobjs():
|
||||
yield ret
|
||||
yield 'get_player_status', self.get_player_status
|
||||
|
||||
def player_cmus(self, pl):
|
||||
def omitted_args(self, name, method):
|
||||
return (0,)
|
||||
|
||||
|
||||
_common_args = '''
|
||||
This player segment should be added like this:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{{
|
||||
"function": "powerline.segments.common.players.{0}",
|
||||
"name": "player"
|
||||
}}
|
||||
|
||||
(with additional ``"args": {{…}}`` if needed).
|
||||
|
||||
Highlight groups used: ``player_fallback`` or ``player``, ``player_play`` or ``player``, ``player_pause`` or ``player``, ``player_stop`` or ``player``.
|
||||
|
||||
:param str format:
|
||||
Format used for displaying data from player. Should be a str.format-like
|
||||
string with the following keyword parameters:
|
||||
|
||||
+------------+-------------------------------------------------------------+
|
||||
|Parameter |Description |
|
||||
+============+=============================================================+
|
||||
|state_symbol|Symbol displayed for play/pause/stop states. There is also |
|
||||
| |“fallback” state used in case function failed to get player |
|
||||
| |state. For this state symbol is by default empty. All |
|
||||
| |symbols are defined in ``state_symbols`` argument. |
|
||||
+------------+-------------------------------------------------------------+
|
||||
|album |Album that is currently played. |
|
||||
+------------+-------------------------------------------------------------+
|
||||
|artist |Artist whose song is currently played |
|
||||
+------------+-------------------------------------------------------------+
|
||||
|title |Currently played composition. |
|
||||
+------------+-------------------------------------------------------------+
|
||||
|elapsed |Composition duration in format M:SS (minutes:seconds). |
|
||||
+------------+-------------------------------------------------------------+
|
||||
|total |Composition length in format M:SS. |
|
||||
+------------+-------------------------------------------------------------+
|
||||
:param dict state_symbols:
|
||||
Symbols used for displaying state. Must contain all of the following keys:
|
||||
|
||||
======== ========================================================
|
||||
Key Description
|
||||
======== ========================================================
|
||||
play Displayed when player is playing.
|
||||
pause Displayed when player is paused.
|
||||
stop Displayed when player is not playing anything.
|
||||
fallback Displayed if state is not one of the above or not known.
|
||||
======== ========================================================
|
||||
'''
|
||||
|
||||
|
||||
_player = with_docstring(PlayerSegment(), _common_args.format('_player'))
|
||||
|
||||
|
||||
class CmusPlayerSegment(PlayerSegment):
|
||||
def get_player_status(self, pl):
|
||||
'''Return cmus player information.
|
||||
|
||||
cmus-remote -Q returns data with multi-level information i.e.
|
||||
@ -75,21 +146,37 @@ class NowPlayingSegment(Segment):
|
||||
now_playing = dict(((token[0] if token[0] not in ignore_levels else token[1],
|
||||
(' '.join(token[1:]) if token[0] not in ignore_levels else
|
||||
' '.join(token[2:]))) for token in [line.split(' ') for line in now_playing_str.split('\n')[:-1]]))
|
||||
state = self._convert_state(now_playing.get('status'))
|
||||
state = _convert_state(now_playing.get('status'))
|
||||
return {
|
||||
'state': state,
|
||||
'album': now_playing.get('album'),
|
||||
'artist': now_playing.get('artist'),
|
||||
'title': now_playing.get('title'),
|
||||
'elapsed': self._convert_seconds(now_playing.get('position', 0)),
|
||||
'total': self._convert_seconds(now_playing.get('duration', 0)),
|
||||
'elapsed': _convert_seconds(now_playing.get('position', 0)),
|
||||
'total': _convert_seconds(now_playing.get('duration', 0)),
|
||||
}
|
||||
|
||||
def player_mpd(self, pl, host='localhost', port=6600):
|
||||
|
||||
cmus = with_docstring(CmusPlayerSegment(),
|
||||
('''Return CMUS player information
|
||||
|
||||
Requires cmus-remote command be acessible from $PATH.
|
||||
|
||||
{0}
|
||||
''').format(_common_args.format('cmus')))
|
||||
|
||||
|
||||
class MpdPlayerSegment(PlayerSegment):
|
||||
def get_player_status(self, pl, host='localhost', port=6600):
|
||||
try:
|
||||
import mpd
|
||||
except ImportError:
|
||||
now_playing = run_cmd(pl, ['mpc', 'current', '-f', '%album%\n%artist%\n%title%\n%time%', '-h', str(host), '-p', str(port)])
|
||||
now_playing = run_cmd(pl, [
|
||||
'mpc', 'current',
|
||||
'-f', '%album%\n%artist%\n%title%\n%time%',
|
||||
'-h', str(host),
|
||||
'-p', str(port)
|
||||
], strip=False)
|
||||
if not now_playing:
|
||||
return
|
||||
now_playing = now_playing.split('\n')
|
||||
@ -113,16 +200,33 @@ class NowPlayingSegment(Segment):
|
||||
'album': now_playing.get('album'),
|
||||
'artist': now_playing.get('artist'),
|
||||
'title': now_playing.get('title'),
|
||||
'elapsed': self._convert_seconds(now_playing.get('elapsed', 0)),
|
||||
'total': self._convert_seconds(now_playing.get('time', 0)),
|
||||
'elapsed': _convert_seconds(now_playing.get('elapsed', 0)),
|
||||
'total': _convert_seconds(now_playing.get('time', 0)),
|
||||
}
|
||||
|
||||
def player_dbus(self, player_name, bus_name, player_path, iface_prop, iface_player):
|
||||
try:
|
||||
import dbus
|
||||
except ImportError:
|
||||
self.exception('Could not add {0} segment: requires dbus module', player_name)
|
||||
return
|
||||
|
||||
mpd = with_docstring(MpdPlayerSegment(),
|
||||
('''Return Music Player Daemon information
|
||||
|
||||
Requires mpc command to be acessible from $PATH or ``mpd`` Python module.
|
||||
|
||||
{0}
|
||||
:param str host:
|
||||
Host on which mpd runs.
|
||||
:param int port:
|
||||
Port which should be connected to.
|
||||
''').format(_common_args.format('mpd')))
|
||||
|
||||
|
||||
try:
|
||||
import dbus
|
||||
except ImportError:
|
||||
def _get_dbus_player_status(pl, player_name, **kwargs):
|
||||
pl.error('Could not add {0} segment: requires dbus module', player_name)
|
||||
return
|
||||
else:
|
||||
def _get_dbus_player_status(pl, bus_name, player_path, iface_prop,
|
||||
iface_player, player_name='player'):
|
||||
bus = dbus.SessionBus()
|
||||
try:
|
||||
player = bus.get_object(bus_name, player_path)
|
||||
@ -136,7 +240,7 @@ class NowPlayingSegment(Segment):
|
||||
album = out_u(info.get('xesam:album'))
|
||||
title = out_u(info.get('xesam:title'))
|
||||
artist = info.get('xesam:artist')
|
||||
state = self._convert_state(status)
|
||||
state = _convert_state(status)
|
||||
if artist:
|
||||
artist = out_u(artist[0])
|
||||
return {
|
||||
@ -144,11 +248,38 @@ class NowPlayingSegment(Segment):
|
||||
'album': album,
|
||||
'artist': artist,
|
||||
'title': title,
|
||||
'total': self._convert_seconds(info.get('mpris:length') / 1e6),
|
||||
'total': _convert_seconds(info.get('mpris:length') / 1e6),
|
||||
}
|
||||
|
||||
def player_spotify_dbus(self, pl):
|
||||
return self.player_dbus(
|
||||
|
||||
class DbusPlayerSegment(PlayerSegment):
|
||||
get_player_status = staticmethod(_get_dbus_player_status)
|
||||
|
||||
|
||||
dbus_player = with_docstring(DbusPlayerSegment(),
|
||||
('''Return generic dbus player state
|
||||
|
||||
Requires ``dbus`` python module. Only for players that support specific protocol
|
||||
(e.g. like :py:func:`spotify` and :py:func:`clementine`).
|
||||
|
||||
{0}
|
||||
:param str player_name:
|
||||
Player name. Used in error messages only.
|
||||
:param str bus_name:
|
||||
Dbus bus name.
|
||||
:param str player_path:
|
||||
Path to the player on the given bus.
|
||||
:param str iface_prop:
|
||||
Interface properties name for use with dbus.Interface.
|
||||
:param str iface_player:
|
||||
Player name.
|
||||
''').format(_common_args.format('dbus_player')))
|
||||
|
||||
|
||||
class SpotifyDbusPlayerSegment(PlayerSegment):
|
||||
def get_player_status(self, pl):
|
||||
return _get_dbus_player_status(
|
||||
pl=pl,
|
||||
player_name='Spotify',
|
||||
bus_name='com.spotify.qt',
|
||||
player_path='/',
|
||||
@ -156,16 +287,18 @@ class NowPlayingSegment(Segment):
|
||||
iface_player='org.freedesktop.MediaPlayer2',
|
||||
)
|
||||
|
||||
def player_clementine(self, pl):
|
||||
return self.player_dbus(
|
||||
player_name='Clementine',
|
||||
bus_name='org.mpris.MediaPlayer2.clementine',
|
||||
player_path='/org/mpris/MediaPlayer2',
|
||||
iface_prop='org.freedesktop.DBus.Properties',
|
||||
iface_player='org.mpris.MediaPlayer2.Player',
|
||||
)
|
||||
|
||||
def player_spotify_apple_script(self, pl):
|
||||
spotify_dbus = with_docstring(SpotifyDbusPlayerSegment(),
|
||||
('''Return spotify player information
|
||||
|
||||
Requires ``dbus`` python module.
|
||||
|
||||
{0}
|
||||
''').format(_common_args.format('spotify_dbus')))
|
||||
|
||||
|
||||
class SpotifyAppleScriptPlayerSegment(PlayerSegment):
|
||||
def get_player_status(self, pl):
|
||||
status_delimiter = '-~`/='
|
||||
ascript = '''
|
||||
tell application "System Events"
|
||||
@ -196,7 +329,7 @@ class NowPlayingSegment(Segment):
|
||||
return None
|
||||
|
||||
spotify_status = spotify.split(status_delimiter)
|
||||
state = self._convert_state(spotify_status[0])
|
||||
state = _convert_state(spotify_status[0])
|
||||
if state == 'stop':
|
||||
return None
|
||||
return {
|
||||
@ -204,21 +337,58 @@ class NowPlayingSegment(Segment):
|
||||
'album': spotify_status[1],
|
||||
'artist': spotify_status[2],
|
||||
'title': spotify_status[3],
|
||||
'total': self._convert_seconds(int(spotify_status[4]))
|
||||
'total': _convert_seconds(int(spotify_status[4]))
|
||||
}
|
||||
|
||||
try:
|
||||
__import__('dbus')
|
||||
except ImportError:
|
||||
if sys.platform.startswith('darwin'):
|
||||
player_spotify = player_spotify_apple_script
|
||||
else:
|
||||
player_spotify = player_spotify_dbus
|
||||
else:
|
||||
player_spotify = player_spotify_dbus
|
||||
|
||||
def player_rhythmbox(self, pl):
|
||||
now_playing = run_cmd(pl, ['rhythmbox-client', '--no-start', '--no-present', '--print-playing-format', '%at\n%aa\n%tt\n%te\n%td'])
|
||||
spotify_apple_script = with_docstring(SpotifyAppleScriptPlayerSegment(),
|
||||
('''Return spotify player information
|
||||
|
||||
Requires ``osascript`` available in $PATH.
|
||||
|
||||
{0}
|
||||
''').format(_common_args.format('spotify_apple_script')))
|
||||
|
||||
|
||||
if 'dbus' in globals() or not sys.platform.startswith('darwin'):
|
||||
spotify = spotify_dbus
|
||||
_old_name = 'spotify_dbus'
|
||||
else:
|
||||
spotify = spotify_apple_script
|
||||
_old_name = 'spotify_apple_script'
|
||||
|
||||
|
||||
spotify = with_docstring(spotify, spotify.__doc__.replace(_old_name, 'spotify'))
|
||||
|
||||
|
||||
class ClementinePlayerSegment(PlayerSegment):
|
||||
def get_player_status(self, pl):
|
||||
return _get_dbus_player_status(
|
||||
pl=pl,
|
||||
player_name='Clementine',
|
||||
bus_name='org.mpris.MediaPlayer2.clementine',
|
||||
player_path='/org/mpris/MediaPlayer2',
|
||||
iface_prop='org.freedesktop.DBus.Properties',
|
||||
iface_player='org.mpris.MediaPlayer2.Player',
|
||||
)
|
||||
|
||||
|
||||
clementine = with_docstring(ClementinePlayerSegment(),
|
||||
('''Return clementine player information
|
||||
|
||||
Requires ``dbus`` python module.
|
||||
|
||||
{0}
|
||||
''').format(_common_args.format('clementine')))
|
||||
|
||||
|
||||
class RhythmboxPlayerSegment(PlayerSegment):
|
||||
def get_player_status(self, pl):
|
||||
now_playing = run_cmd(pl, [
|
||||
'rhythmbox-client',
|
||||
'--no-start', '--no-present',
|
||||
'--print-playing-format', '%at\n%aa\n%tt\n%te\n%td'
|
||||
], strip=False)
|
||||
if not now_playing:
|
||||
return
|
||||
now_playing = now_playing.split('\n')
|
||||
@ -230,7 +400,18 @@ class NowPlayingSegment(Segment):
|
||||
'total': now_playing[4],
|
||||
}
|
||||
|
||||
def player_rdio(self, pl):
|
||||
|
||||
rhythmbox = with_docstring(RhythmboxPlayerSegment(),
|
||||
('''Return rhythmbox player information
|
||||
|
||||
Requires ``rhythmbox-client`` available in $PATH.
|
||||
|
||||
{0}
|
||||
''').format(_common_args.format('rhythmbox')))
|
||||
|
||||
|
||||
class RDIOPlayerSegment(PlayerSegment):
|
||||
def get_player_status(self, pl):
|
||||
status_delimiter = '-~`/='
|
||||
ascript = '''
|
||||
tell application "System Events"
|
||||
@ -255,9 +436,9 @@ class NowPlayingSegment(Segment):
|
||||
now_playing = now_playing.split('\n')
|
||||
if len(now_playing) != 6:
|
||||
return
|
||||
state = self._convert_state(now_playing[5])
|
||||
total = self._convert_seconds(now_playing[4])
|
||||
elapsed = self._convert_seconds(float(now_playing[3]) * float(now_playing[4]) / 100)
|
||||
state = _convert_state(now_playing[5])
|
||||
total = _convert_seconds(now_playing[4])
|
||||
elapsed = _convert_seconds(float(now_playing[3]) * float(now_playing[4]) / 100)
|
||||
return {
|
||||
'title': now_playing[0],
|
||||
'artist': now_playing[1],
|
||||
@ -265,6 +446,34 @@ class NowPlayingSegment(Segment):
|
||||
'elapsed': elapsed,
|
||||
'total': total,
|
||||
'state': state,
|
||||
'state_symbol': self.STATE_SYMBOLS.get(state)
|
||||
}
|
||||
|
||||
|
||||
rdio = with_docstring(RDIOPlayerSegment(),
|
||||
('''Return rdio player information
|
||||
|
||||
Requires ``osascript`` available in $PATH.
|
||||
|
||||
{0}
|
||||
''').format(_common_args.format('rdio')))
|
||||
|
||||
|
||||
class NowPlayingSegment(Segment):
|
||||
def __call__(self, player='mpd', **kwargs):
|
||||
player_segment = globals()[player]
|
||||
assert(isinstance(player_segment, PlayerSegment))
|
||||
return player_segment(**kwargs)
|
||||
|
||||
def argspecobjs(self):
|
||||
for ret in super(NowPlayingSegment, self).argspecobjs():
|
||||
yield ret
|
||||
yield '__call__', PlayerSegment.__call__
|
||||
for k, v in globals().items():
|
||||
if isinstance(v, type) and issubclass(v, PlayerSegment) and v is not DbusPlayerSegment:
|
||||
yield 'get_player_status', v.get_player_status
|
||||
|
||||
def omitted_args(self, name, method):
|
||||
return (0,)
|
||||
|
||||
|
||||
now_playing = NowPlayingSegment()
|
||||
|
@ -2,32 +2,57 @@
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
from powerline.lib.vcs import guess, tree_status
|
||||
from powerline.segments import Segment, with_docstring
|
||||
from powerline.theme import requires_segment_info, requires_filesystem_watcher
|
||||
|
||||
|
||||
@requires_filesystem_watcher
|
||||
@requires_segment_info
|
||||
def branch(pl, segment_info, create_watcher, status_colors=False):
|
||||
'''Return the current VCS branch.
|
||||
class BranchSegment(Segment):
|
||||
divider_highlight_group = None
|
||||
|
||||
:param bool status_colors:
|
||||
determines whether repository status will be used to determine highlighting. Default: False.
|
||||
@staticmethod
|
||||
def get_directory(segment_info):
|
||||
return segment_info['getcwd']()
|
||||
|
||||
Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``.
|
||||
'''
|
||||
name = segment_info['getcwd']()
|
||||
repo = guess(path=name, create_watcher=create_watcher)
|
||||
if repo is not None:
|
||||
branch = repo.branch()
|
||||
scol = ['branch']
|
||||
if status_colors:
|
||||
try:
|
||||
status = tree_status(repo, pl)
|
||||
except Exception as e:
|
||||
pl.exception('Failed to compute tree status: {0}', str(e))
|
||||
status = '?'
|
||||
scol.insert(0, 'branch_dirty' if status and status.strip() else 'branch_clean')
|
||||
return [{
|
||||
'contents': branch,
|
||||
'highlight_group': scol,
|
||||
}]
|
||||
def __call__(self, pl, segment_info, create_watcher, status_colors=False, ignore_statuses=()):
|
||||
name = self.get_directory(segment_info)
|
||||
if name:
|
||||
repo = guess(path=name, create_watcher=create_watcher)
|
||||
if repo is not None:
|
||||
branch = repo.branch()
|
||||
scol = ['branch']
|
||||
if status_colors:
|
||||
try:
|
||||
status = tree_status(repo, pl)
|
||||
except Exception as e:
|
||||
pl.exception('Failed to compute tree status: {0}', str(e))
|
||||
status = '?'
|
||||
else:
|
||||
status = status and status.strip()
|
||||
if status in ignore_statuses:
|
||||
status = None
|
||||
scol.insert(0, 'branch_dirty' if status else 'branch_clean')
|
||||
return [{
|
||||
'contents': branch,
|
||||
'highlight_group': scol,
|
||||
'divider_highlight_group': self.divider_highlight_group,
|
||||
}]
|
||||
|
||||
|
||||
branch = with_docstring(BranchSegment(),
|
||||
'''Return the current VCS branch.
|
||||
|
||||
:param bool status_colors:
|
||||
Determines whether repository status will be used to determine highlighting.
|
||||
Default: False.
|
||||
:param bool ignore_statuses:
|
||||
List of statuses which will not result in repo being marked as dirty. Most
|
||||
useful is setting this option to ``["U"]``: this will ignore repository
|
||||
which has just untracked files (i.e. repository with modified, deleted or
|
||||
removed files will be marked as dirty, while just untracked files will make
|
||||
segment show clean repository). Only applicable if ``status_colors`` option
|
||||
is True.
|
||||
|
||||
Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``.
|
||||
''')
|
||||
|
@ -11,12 +11,12 @@ def attached_clients(pl, minimum=1):
|
||||
The minimum number of attached clients that must be present for this
|
||||
segment to be visible.
|
||||
'''
|
||||
session_output = get_tmux_output('list-panes', '-F', '#{session_name}')
|
||||
session_output = get_tmux_output(pl, 'list-panes', '-F', '#{session_name}')
|
||||
if not session_output:
|
||||
return None
|
||||
session_name = session_output.rstrip().split('\n')[0]
|
||||
|
||||
attached_clients_output = get_tmux_output('list-clients', '-t', session_name)
|
||||
attached_clients_output = get_tmux_output(pl, 'list-clients', '-t', session_name)
|
||||
attached_count = len(attached_clients_output.rstrip().split('\n'))
|
||||
|
||||
return None if attached_count < minimum else str(attached_count)
|
||||
|
@ -17,9 +17,11 @@ from powerline.bindings.vim import (vim_get_func, getbufvar, vim_getbufoption,
|
||||
list_tabpage_buffers_segment_info)
|
||||
from powerline.theme import requires_segment_info, requires_filesystem_watcher
|
||||
from powerline.lib import add_divider_highlight_group
|
||||
from powerline.lib.vcs import guess, tree_status
|
||||
from powerline.lib.vcs import guess
|
||||
from powerline.lib.humanize_bytes import humanize_bytes
|
||||
from powerline.lib import wraps_saveargs as wraps
|
||||
from powerline.segments.common.vcs import BranchSegment
|
||||
from powerline.segments import with_docstring
|
||||
|
||||
try:
|
||||
from __builtin__ import xrange as range
|
||||
@ -480,31 +482,34 @@ def modified_buffers(pl, text='+ ', join_str=','):
|
||||
|
||||
@requires_filesystem_watcher
|
||||
@requires_segment_info
|
||||
def branch(pl, segment_info, create_watcher, status_colors=False):
|
||||
'''Return the current working branch.
|
||||
class VimBranchSegment(BranchSegment):
|
||||
divider_highlight_group = 'branch:divider'
|
||||
|
||||
:param bool status_colors:
|
||||
determines whether repository status will be used to determine highlighting. Default: False.
|
||||
@staticmethod
|
||||
def get_directory(segment_info):
|
||||
if vim_getbufoption(segment_info, 'buftype'):
|
||||
return None
|
||||
return buffer_name(segment_info)
|
||||
|
||||
Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``.
|
||||
|
||||
Divider highlight group used: ``branch:divider``.
|
||||
'''
|
||||
name = buffer_name(segment_info)
|
||||
skip = not (name and (not vim_getbufoption(segment_info, 'buftype')))
|
||||
if not skip:
|
||||
repo = guess(path=name, create_watcher=create_watcher)
|
||||
if repo is not None:
|
||||
branch = repo.branch()
|
||||
scol = ['branch']
|
||||
if status_colors:
|
||||
status = tree_status(repo, pl)
|
||||
scol.insert(0, 'branch_dirty' if status and status.strip() else 'branch_clean')
|
||||
return [{
|
||||
'contents': branch,
|
||||
'highlight_group': scol,
|
||||
'divider_highlight_group': 'branch:divider',
|
||||
}]
|
||||
branch = with_docstring(VimBranchSegment(),
|
||||
'''Return the current working branch.
|
||||
|
||||
:param bool status_colors:
|
||||
Determines whether repository status will be used to determine highlighting.
|
||||
Default: False.
|
||||
:param bool ignore_statuses:
|
||||
List of statuses which will not result in repo being marked as dirty. Most
|
||||
useful is setting this option to ``["U"]``: this will ignore repository
|
||||
which has just untracked files (i.e. repository with modified, deleted or
|
||||
removed files will be marked as dirty, while just untracked files will make
|
||||
segment show clean repository). Only applicable if ``status_colors`` option
|
||||
is True.
|
||||
|
||||
Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``.
|
||||
|
||||
Divider highlight group used: ``branch:divider``.
|
||||
''')
|
||||
|
||||
|
||||
@requires_filesystem_watcher
|
||||
|
169
scripts/powerline-release.py
Executable file
169
scripts/powerline-release.py
Executable file
@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import argparse
|
||||
import codecs
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from subprocess import check_output, check_call
|
||||
from getpass import getpass
|
||||
|
||||
from github import Github
|
||||
|
||||
|
||||
OVERLAY_NAME = 'raiagent'
|
||||
OVERLAY = 'leycec/' + OVERLAY_NAME
|
||||
OVERLAY_BRANCH_FORMAT = 'powerline-release-{0}'
|
||||
|
||||
|
||||
def parse_version(s):
|
||||
if s == ('+' * len(s)):
|
||||
try:
|
||||
last_version = next(iter(sorted([
|
||||
tuple(map(int, tag.split('.')))
|
||||
for tag in check_output(['git', 'tag', '-l', '[0-9]*.*']).split('\n')[:-1]
|
||||
], reverse=True)))
|
||||
except StopIteration:
|
||||
raise ValueError('No existing versions found')
|
||||
|
||||
version = []
|
||||
for i in range(len(s) - 1):
|
||||
try:
|
||||
version.append(last_version[i])
|
||||
except IndexError:
|
||||
version.append(0)
|
||||
|
||||
try:
|
||||
version.append(last_version[len(s) - 1] + 1)
|
||||
except IndexError:
|
||||
version.append(1)
|
||||
|
||||
if len(version) == 1:
|
||||
version.append(0)
|
||||
|
||||
return tuple(version)
|
||||
else:
|
||||
return tuple(map(int, s.split('.')))
|
||||
|
||||
|
||||
def merge(version_string, rev, **kwargs):
|
||||
check_call(['git', 'checkout', 'master'])
|
||||
check_call(['git', 'merge', '--no-ff', '--no-commit', '--log', rev])
|
||||
|
||||
with codecs.open('.setup.py.new', 'w', encoding='utf-8') as NS:
|
||||
with codecs.open('setup.py', 'r', encoding='utf-8') as OS:
|
||||
for line in OS:
|
||||
if line.startswith('\tversion='):
|
||||
line = '\tversion=\'' + version_string + '\',\n'
|
||||
elif 'Development Status' in line:
|
||||
line = '\t\t\'Development Status :: 5 - Production/Stable\',\n'
|
||||
NS.write(line)
|
||||
|
||||
os.unlink('setup.py')
|
||||
os.rename('.setup.py.new', 'setup.py')
|
||||
check_call(['git', 'add', 'setup.py'])
|
||||
|
||||
check_call(['git', 'commit'])
|
||||
check_call(['git', 'tag', '-m', 'Release ' + version_string, '-a', version_string])
|
||||
|
||||
|
||||
def push(version_string, **kwargs):
|
||||
check_call(['git', 'push', 'upstream', 'master'])
|
||||
check_call(['git', 'push', 'upstream', version_string])
|
||||
|
||||
|
||||
def upload(**args):
|
||||
check_call(['python', 'setup.py', 'sdist', 'upload'])
|
||||
check_call(['python', 'setup.py', 'upload_docs'])
|
||||
|
||||
|
||||
gh = None
|
||||
|
||||
|
||||
def get_gh(user, password):
|
||||
global gh
|
||||
if not gh:
|
||||
gh = Github(user, password)
|
||||
return gh
|
||||
|
||||
|
||||
def create_ebuilds(version_string, overlay, user, **kwargs):
|
||||
overlay_url = 'git://github.com/' + OVERLAY
|
||||
if not os.path.isdir(overlay):
|
||||
check_call(['git', 'clone', overlay_url, overlay])
|
||||
check_call(['git', 'checkout', 'master'], cwd=overlay)
|
||||
check_call(['git', 'pull', '--ff-only', overlay_url, 'master'], cwd=overlay)
|
||||
branch = OVERLAY_BRANCH_FORMAT.format(version_string)
|
||||
check_call(['git', 'branch', branch], cwd=overlay)
|
||||
check_call(['git', 'checkout', branch], cwd=overlay)
|
||||
os.environ['DISTDIR'] = '/tmp/powerline-distfiles'
|
||||
if not os.path.isdir(os.environ['DISTDIR']):
|
||||
os.mkdir(os.environ['DISTDIR'])
|
||||
new_files = []
|
||||
for category, pn in (
|
||||
('app-misc', 'powerline'),
|
||||
('app-vim', 'powerline-vim'),
|
||||
):
|
||||
pdir = os.path.join(overlay, category, pn)
|
||||
v1_0 = os.path.join(pdir, '{0}-1.0.ebuild'.format(pn))
|
||||
vcur = os.path.join(pdir, '{0}-{1}.ebuild'.format(pn, version_string))
|
||||
shutil.copy2(v1_0, vcur)
|
||||
new_files.append(vcur)
|
||||
check_call(['ebuild', vcur, 'manifest'])
|
||||
new_files.append(os.path.join(pdir, 'Manifest'))
|
||||
check_call(['git', 'add', '--'] + new_files, cwd=overlay)
|
||||
check_call(['git', 'commit'] + new_files + ['-m', 'powerline*: Release {0}'.format(version_string)],
|
||||
cwd=overlay)
|
||||
check_call(['git', 'push', 'git@github.com:{0}/{1}'.format(user, OVERLAY_NAME), branch], cwd=overlay)
|
||||
|
||||
|
||||
def update_overlay(version_string, user, password, **kwargs):
|
||||
gh = get_gh(user, password)
|
||||
overlay = gh.get_repo(OVERLAY)
|
||||
overlay.create_pull(
|
||||
title='New powerline version: ' + version_string,
|
||||
body='Add ebuilds for new powerline version\n\n---\n\nCreated automatically by release script',
|
||||
base='master',
|
||||
head=user + ':' + OVERLAY_BRANCH_FORMAT.format(version_string),
|
||||
)
|
||||
|
||||
|
||||
stages = (
|
||||
('merge', merge),
|
||||
('push', push),
|
||||
('upload', upload),
|
||||
('create_ebuilds', create_ebuilds),
|
||||
('update_overlay', update_overlay),
|
||||
)
|
||||
|
||||
|
||||
def create_release(version, user, password=None, run_stages=None, **kwargs):
|
||||
version_string = '.'.join((str(v) for v in version))
|
||||
if not password:
|
||||
password = getpass('Password for {0}: '.format(user))
|
||||
for stname, stfunc in stages:
|
||||
if run_stages is None or stname in run_stages:
|
||||
stfunc(version_string=version_string, user=user, password=password, **kwargs)
|
||||
|
||||
|
||||
p = argparse.ArgumentParser(description='Powerline release script')
|
||||
p.add_argument('-u', '--user', type=str, metavar='USER', help='Github username.', required=True)
|
||||
p.add_argument('-v', '--version', type=parse_version, metavar='VERSION', help='Use given version for the release. If version contains only `+\' signs then it will increase latest version number: one `+\' increases major version number (e.g. 1.2.3 -> 2.0), `++\' increases minor version number (e.g. 1.2.3 -> 1.3), `+++\' increases patch level (e.g. 1.2.3 -> 1.2.4). Defaults to `+++\'.', default='+++')
|
||||
p.add_argument('-r', '--rev', metavar='COMMIT', help='Use given revision for the release. Defaults to `develop\'.', default='develop')
|
||||
p.add_argument('-s', '--stages', action='append', metavar='STAGE', help='Only run one of the given stages (default to all).', choices=tuple((stname for stname, stfunc in stages)))
|
||||
p.add_argument('-p', '--password', type=str, metavar='PASS', help='Github password. You will be prompted if it is not supplied.')
|
||||
p.add_argument('-o', '--overlay', type=str, metavar='PATH', help='Location of the local clone of the {0} overlay. If provided directory does not exist it will be created by “git clone”. Defaults to /tmp/powerline-{0}.'.format(OVERLAY_NAME), default='/tmp/powerline-' + OVERLAY_NAME)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = p.parse_args()
|
||||
create_release(
|
||||
version=args.version,
|
||||
rev=args.rev,
|
||||
user=args.user,
|
||||
password=args.password,
|
||||
overlay=args.overlay,
|
||||
run_stages=args.stages,
|
||||
)
|
2
setup.py
2
setup.py
@ -54,7 +54,7 @@ else:
|
||||
|
||||
setup(
|
||||
name='powerline-status',
|
||||
version='1.1',
|
||||
version='1.2',
|
||||
description='The ultimate statusline/prompt utility.',
|
||||
long_description=README,
|
||||
classifiers=[
|
||||
|
@ -277,7 +277,7 @@ class TestShell(TestCase):
|
||||
|
||||
class TestTmux(TestCase):
|
||||
def test_attached_clients(self):
|
||||
def get_tmux_output(cmd, *args):
|
||||
def get_tmux_output(pl, cmd, *args):
|
||||
if cmd == 'list-panes':
|
||||
return 'session_name\n'
|
||||
elif cmd == 'list-clients':
|
||||
@ -600,25 +600,57 @@ class TestVcs(TestCommon):
|
||||
branch = partial(common.branch, pl=pl, create_watcher=create_watcher)
|
||||
with replace_attr(self.module, 'guess', get_dummy_guess(status=lambda: None, directory='/tmp/tests')):
|
||||
with replace_attr(self.module, 'tree_status', lambda repo, pl: None):
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False), [
|
||||
{'highlight_group': ['branch'], 'contents': 'tests'}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True), [
|
||||
{'contents': 'tests', 'highlight_group': ['branch_clean', 'branch']}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False), [{
|
||||
'highlight_group': ['branch'],
|
||||
'contents': 'tests',
|
||||
'divider_highlight_group': None
|
||||
}])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True), [{
|
||||
'contents': 'tests',
|
||||
'highlight_group': ['branch_clean', 'branch'],
|
||||
'divider_highlight_group': None
|
||||
}])
|
||||
with replace_attr(self.module, 'guess', get_dummy_guess(status=lambda: 'D ', directory='/tmp/tests')):
|
||||
with replace_attr(self.module, 'tree_status', lambda repo, pl: 'D '):
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False), [
|
||||
{'highlight_group': ['branch'], 'contents': 'tests'}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True), [
|
||||
{'contents': 'tests', 'highlight_group': ['branch_dirty', 'branch']}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False), [
|
||||
{'highlight_group': ['branch'], 'contents': 'tests'}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False), [{
|
||||
'highlight_group': ['branch'],
|
||||
'contents': 'tests',
|
||||
'divider_highlight_group': None
|
||||
}])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True), [{
|
||||
'contents': 'tests',
|
||||
'highlight_group': ['branch_dirty', 'branch'],
|
||||
'divider_highlight_group': None
|
||||
}])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False), [{
|
||||
'highlight_group': ['branch'],
|
||||
'contents': 'tests',
|
||||
'divider_highlight_group': None
|
||||
}])
|
||||
with replace_attr(self.module, 'guess', lambda path, create_watcher: None):
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False), None)
|
||||
with replace_attr(self.module, 'guess', get_dummy_guess(status=lambda: 'U')):
|
||||
with replace_attr(self.module, 'tree_status', lambda repo, pl: 'U'):
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False, ignore_statuses=['U']), [{
|
||||
'highlight_group': ['branch'],
|
||||
'contents': 'tests',
|
||||
'divider_highlight_group': None
|
||||
}])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['DU']), [{
|
||||
'highlight_group': ['branch_dirty', 'branch'],
|
||||
'contents': 'tests',
|
||||
'divider_highlight_group': None
|
||||
}])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True), [{
|
||||
'highlight_group': ['branch_dirty', 'branch'],
|
||||
'contents': 'tests',
|
||||
'divider_highlight_group': None
|
||||
}])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['U']), [{
|
||||
'highlight_group': ['branch_clean', 'branch'],
|
||||
'contents': 'tests',
|
||||
'divider_highlight_group': None
|
||||
}])
|
||||
|
||||
|
||||
class TestTime(TestCommon):
|
||||
@ -1057,22 +1089,36 @@ class TestVim(TestCase):
|
||||
create_watcher = get_fallback_create_watcher()
|
||||
branch = partial(self.vim.branch, pl=pl, create_watcher=create_watcher)
|
||||
with vim_module._with('buffer', '/foo') as segment_info:
|
||||
with replace_attr(self.vim, 'guess', get_dummy_guess(status=lambda: None)):
|
||||
with replace_attr(self.vim, 'tree_status', lambda repo, pl: None):
|
||||
with replace_attr(self.vcs, 'guess', get_dummy_guess(status=lambda: None)):
|
||||
with replace_attr(self.vcs, 'tree_status', lambda repo, pl: None):
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False), [
|
||||
{'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch'], 'contents': 'foo'}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True), [
|
||||
{'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_clean', 'branch'], 'contents': 'foo'}
|
||||
])
|
||||
with replace_attr(self.vim, 'guess', get_dummy_guess(status=lambda: 'DU')):
|
||||
with replace_attr(self.vim, 'tree_status', lambda repo, pl: 'DU'):
|
||||
with replace_attr(self.vcs, 'guess', get_dummy_guess(status=lambda: 'DU')):
|
||||
with replace_attr(self.vcs, 'tree_status', lambda repo, pl: 'DU'):
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False), [
|
||||
{'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch'], 'contents': 'foo'}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True), [
|
||||
{'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_dirty', 'branch'], 'contents': 'foo'}
|
||||
])
|
||||
with replace_attr(self.vcs, 'guess', get_dummy_guess(status=lambda: 'U')):
|
||||
with replace_attr(self.vcs, 'tree_status', lambda repo, pl: 'U'):
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=False, ignore_statuses=['U']), [
|
||||
{'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch'], 'contents': 'foo'}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['DU']), [
|
||||
{'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_dirty', 'branch'], 'contents': 'foo'}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True), [
|
||||
{'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_dirty', 'branch'], 'contents': 'foo'}
|
||||
])
|
||||
self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['U']), [
|
||||
{'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_clean', 'branch'], 'contents': 'foo'}
|
||||
])
|
||||
|
||||
def test_file_vcs_status(self):
|
||||
pl = Pl()
|
||||
@ -1155,6 +1201,8 @@ class TestVim(TestCase):
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'path')))
|
||||
from powerline.segments import vim
|
||||
cls.vim = vim
|
||||
from powerline.segments.common import vcs
|
||||
cls.vcs = vcs
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
@ -62,7 +62,7 @@ run() {
|
||||
env -i \
|
||||
LANG=en_US.UTF-8 \
|
||||
PATH="$local_path" \
|
||||
TERM="${TERM}" \
|
||||
TERM="screen-256color" \
|
||||
COLUMNS="${COLUMNS}" \
|
||||
LINES="${LINES}" \
|
||||
TEST_TYPE="${TEST_TYPE}" \
|
||||
|
Loading…
x
Reference in New Issue
Block a user