Release 2.2
- Added support for newest psutil version. - Added support for non-SSL IMAP4 connection. - Added support for clickable tab names in Vim. - Added support for truncating tmux segments. - Added support for new (i3ipc) module that interacts with i3. - Added support for i3 modes. - Fixed coloring of network\_load segment. - Fixed dash bindings on OS X. - Fixed parsing numbers starting with 2 supplied by POWERLINE\_\*\_OVERRIDES environment variables.
This commit is contained in:
commit
029d54a64a
|
@ -15,20 +15,27 @@ written in Python.
|
|||
Powerline provides default configurations in the following locations:
|
||||
|
||||
:ref:`Main configuration <config-main>`
|
||||
:file:`powerline/config.json`
|
||||
:file:`{powerline}/config.json`
|
||||
:ref:`Colorschemes <config-colorschemes>`
|
||||
:file:`powerline/colorschemes/{name}.json`,
|
||||
:file:`powerline/colorscheme/{extension}/__main__.json`,
|
||||
:file:`powerline/colorschemes/{extension}/{name}.json`
|
||||
:file:`{powerline}/colorschemes/{name}.json`,
|
||||
:file:`{powerline}/colorschemes/{extension}/__main__.json`,
|
||||
:file:`{powerline}/colorschemes/{extension}/{name}.json`
|
||||
:ref:`Themes <config-themes>`
|
||||
:file:`powerline/themes/{top_theme}.json`,
|
||||
:file:`powerline/themes/{extension}/__main__.json`,
|
||||
:file:`powerline/themes/{extension}/default.json`
|
||||
:file:`{powerline}/themes/{top_theme}.json`,
|
||||
:file:`{powerline}/themes/{extension}/__main__.json`,
|
||||
:file:`{powerline}/themes/{extension}/default.json`
|
||||
|
||||
The default configuration files are stored in the main package. User
|
||||
configuration files are stored in :file:`$XDG_CONFIG_HOME/powerline` for
|
||||
Linux users, and in :file:`~/.config/powerline` for OS X users. This usually
|
||||
corresponds to :file:`~/.config/powerline` on both platforms.
|
||||
Here `{powerline}` is one of the following:
|
||||
|
||||
#. The default configuration directory located in the main package:
|
||||
:file:`{powerline_root}/powerline/config_files`. May be absent in some
|
||||
packages (e.g. when installing via Gentoo ebuilds).
|
||||
#. If variable ``$XDG_CONFIG_DIRS`` is set and non-empty then to any
|
||||
:file:`{directory}/powerline` where `{directory}` is a directory listed in
|
||||
a colon-separated ``$XDG_CONFIG_DIRS`` list. Directories are checked in
|
||||
reverse order.
|
||||
#. User configuration directory located in :file:`$XDG_CONFIG_HOME/powerline`.
|
||||
This usually corresponds to :file:`~/.config/powerline` on all platforms.
|
||||
|
||||
If per-instance configuration is needed please refer to :ref:`Local
|
||||
configuration overrides <local-configuration-overrides>`.
|
||||
|
@ -37,17 +44,8 @@ configuration overrides <local-configuration-overrides>`.
|
|||
|
||||
.. note::
|
||||
Existing multiple configuration files that have the same name, but are placed
|
||||
in different directories, will be merged. Merging happens in the following
|
||||
order:
|
||||
|
||||
* :file:`{powerline_root}/powerline/config_files` is checked for
|
||||
configuration first. Configuration from this source has least priority.
|
||||
* :file:`$XDG_CONFIG_DIRS/powerline` directories are the next ones to check.
|
||||
Checking happens in the reversed order: directories mentioned last are
|
||||
checked before directories mentioned first. Each new found file is merged
|
||||
with the result of previous merge.
|
||||
* :file:`$XDG_CONFIG_HOME/powerline` directory is the last to check.
|
||||
Configuration from there has top priority.
|
||||
in different directories, will be merged. Merging happens in the order given
|
||||
in the above list of possible `{powerline}` meanings.
|
||||
|
||||
When merging configuration only dictionaries are merged and they are merged
|
||||
recursively: keys from next file overrule those from the previous unless
|
||||
|
|
|
@ -502,7 +502,7 @@ ascii Theme without any unicode characters at all
|
|||
rendered. A lower number means that the segment has a higher priority.
|
||||
|
||||
Segments are removed according to their priority, with low priority
|
||||
segments being removed first.
|
||||
segments (i.e. with a greater priority number) being removed first.
|
||||
|
||||
.. _config-themes-seg-draw_divider:
|
||||
|
||||
|
|
|
@ -153,10 +153,34 @@ All keys in segments returned by the function override those obtained from
|
|||
|
||||
Detailed description of used dictionary keys:
|
||||
|
||||
.. _dev-segments-contents:
|
||||
|
||||
``contents``
|
||||
Text displayed by segment. Should be a ``unicode`` (Python2) or ``str``
|
||||
(Python3) instance.
|
||||
|
||||
``literal_contents``
|
||||
Text that needs to be output literally (i.e. without passing through
|
||||
:py:meth:`powerline.renderer.strwidth` to determine length, through
|
||||
:py:meth:`powerline.renderer.escape` to escape special characters and
|
||||
through :py:meth:`powerline.renderer.hl` to highlight it). Should be a tuple
|
||||
``(contents_length, contents)`` where ``contents_length`` is an integer and
|
||||
``contents`` is a ``unicode`` (Python2) or ``str`` (Python3) instance.
|
||||
|
||||
If this key is present and its second value is true then other contents keys
|
||||
(:ref:`contents <dev-segments-contents>`, :ref:`after
|
||||
<config-themes-seg-after>`, :ref:`before <config-themes-seg-before>`) will
|
||||
be ignored.
|
||||
|
||||
.. note::
|
||||
If target is inclusion of the segment in powerline upstream all segment
|
||||
functions that output *only* subsegments with ``literal_contents`` key
|
||||
must contain the following string in documentation::
|
||||
|
||||
No highlight groups are used (literal segment).
|
||||
|
||||
String must be present on the separate line.
|
||||
|
||||
.. _dev-segments-draw_inner_divider:
|
||||
|
||||
``draw_hard_divider``, ``draw_soft_divider``, ``draw_inner_divider``
|
||||
|
|
|
@ -37,6 +37,19 @@ Generic requirements
|
|||
Until mercurial and bazaar support Python-3 or PyPy powerline will not
|
||||
support repository information when running in these interpreters.
|
||||
|
||||
.. _repository-root:
|
||||
|
||||
.. note::
|
||||
When using ``pip`` ``{repository_root}`` directory referenced in
|
||||
documentation may be found using ``pip show powerline-status``. In the output
|
||||
of ``pip show`` there is a line like ``Location: {path}``, that ``{path}`` is
|
||||
``{repository_root}``. Unless it is ``--editable`` installation this is only
|
||||
applicable for ``{repository_root}/powerline/…`` paths: something like
|
||||
``{repository_root}/scripts/powerline-render`` is not present.
|
||||
|
||||
When using other packages referenced paths may not exist, in this case refer
|
||||
to package documentation.
|
||||
|
||||
Pip installation
|
||||
================
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ If the repository was just cloned the following line needs to be added to the
|
|||
set rtp+={repository_root}/powerline/bindings/vim
|
||||
|
||||
where ``{repository_root}`` is the absolute path to the Powerline installation
|
||||
directory.
|
||||
directory (see :ref:`repository root <repository-root>`).
|
||||
|
||||
If pathogen is used and Powerline functionality is not needed outside of Vim
|
||||
then it is possible to simply add Powerline as a bundle and point the path above
|
||||
|
@ -82,7 +82,8 @@ Tmux statusline
|
|||
===============
|
||||
|
||||
Add the following lines to :file:`.tmux.conf`, where ``{repository_root}`` is
|
||||
the absolute path to the Powerline installation directory::
|
||||
the absolute path to the Powerline installation directory (see :ref:`repository
|
||||
root <repository-root>`)::
|
||||
|
||||
source "{repository_root}/powerline/bindings/tmux/powerline.conf"
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ Bash prompt
|
|||
===========
|
||||
|
||||
Add the following line to the :file:`bashrc`, where ``{repository_root}`` is the
|
||||
absolute path to the Powerline installation directory:
|
||||
absolute path to the Powerline installation directory (see :ref:`repository root
|
||||
<repository-root>`):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
@ -48,7 +49,8 @@ Zsh prompt
|
|||
==========
|
||||
|
||||
Add the following line to the :file:`zshrc`, where ``{repository_root}`` is the
|
||||
absolute path to the Powerline installation directory:
|
||||
absolute path to the Powerline installation directory (see :ref:`repository root
|
||||
<repository-root>`):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
@ -58,7 +60,8 @@ Fish prompt
|
|||
===========
|
||||
|
||||
Add the following line to :file:`config.fish`, where ``{repository_root}`` is
|
||||
the absolute path to the Powerline installation directory:
|
||||
the absolute path to the Powerline installation directory (see :ref:`repository
|
||||
root <repository-root>`):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
@ -77,9 +80,10 @@ many \*nix distributions. To use it add
|
|||
|
||||
. {repository_root}/powerline/bindings/rc/powerline.rc
|
||||
|
||||
to :file:`rcrc` file (usually :file:`~/.rcrc`) and make sure ``rc`` is started
|
||||
as a login shell (with ``-l`` argument): otherwise this configuration file is
|
||||
not read.
|
||||
(``{repository_root}`` is the absolute path to the Powerline installation
|
||||
directory, see :ref:`repository root <repository-root>`) to :file:`rcrc` file
|
||||
(usually :file:`~/.rcrc`) and make sure ``rc`` is started as a login shell (with
|
||||
``-l`` argument): otherwise this configuration file is not read.
|
||||
|
||||
.. warning::
|
||||
Original Plan9 shell and its \*nix port are not supported because they are
|
||||
|
@ -97,6 +101,9 @@ After launching busybox run the following command:
|
|||
|
||||
. {repository_root}/powerline/bindings/shell/powerline.sh
|
||||
|
||||
where ``{repository_root}`` is the absolute path to the Powerline installation
|
||||
directory (see :ref:`repository root <repository-root>`).
|
||||
|
||||
Mksh users may put this line into ``~/.mkshrc`` file. Dash users may use the
|
||||
following in ``~/.profile``:
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ Awesome widget
|
|||
background and updates the statusline with ``awesome-client``.
|
||||
|
||||
Add the following to :file:`rc.lua`, where ``{repository_root}`` is the absolute
|
||||
path to Powerline installation directory:
|
||||
path to Powerline installation directory (see :ref:`repository root
|
||||
<repository-root>`):
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
|
@ -51,8 +52,8 @@ Add the following to :file:`~/.config/qtile/config.py`:
|
|||
|
||||
.. _bar-usage:
|
||||
|
||||
LemonBoy’s bar
|
||||
==============
|
||||
bar-aint-recursive
|
||||
==================
|
||||
|
||||
To run the bar simply pipe the output of the binding script into ``bar`` and
|
||||
specify appropriate options, for example like this::
|
||||
|
@ -63,6 +64,9 @@ to run with i3, simply ``exec`` this in i3 config file::
|
|||
|
||||
exec python /path/to/powerline/bindings/bar/powerline-bar.py --i3 | bar
|
||||
|
||||
Running the binding in i3-mode will require `i3ipc <https://github.com/acrisci/i3ipc-python>`_
|
||||
(or the outdated `i3-py <https://github.com/ziberna/i3-py>`_).
|
||||
|
||||
See the `bar documentation <https://github.com/LemonBoy/bar>`_ for more
|
||||
information and options.
|
||||
|
||||
|
|
|
@ -5,11 +5,10 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
|||
import sys
|
||||
import time
|
||||
|
||||
from threading import Lock
|
||||
from threading import Lock, Timer
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from powerline import Powerline
|
||||
from powerline.lib.monotonic import monotonic
|
||||
from powerline.lib.encoding import get_unicode_writer
|
||||
|
||||
|
||||
|
@ -20,14 +19,6 @@ class BarPowerline(Powerline):
|
|||
super(BarPowerline, self).init(ext='wm', renderer_module='bar')
|
||||
|
||||
|
||||
def render(event=None, data=None, sub=None):
|
||||
global lock
|
||||
with lock:
|
||||
write(powerline.render())
|
||||
write('\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description='Powerline BAR bindings.')
|
||||
parser.add_argument(
|
||||
|
@ -36,17 +27,37 @@ if __name__ == '__main__':
|
|||
)
|
||||
args = parser.parse_args()
|
||||
powerline = BarPowerline()
|
||||
|
||||
interval = 0.5
|
||||
lock = Lock()
|
||||
|
||||
modes = ['default']
|
||||
write = get_unicode_writer(encoding='utf-8')
|
||||
|
||||
def render(reschedule=False):
|
||||
if reschedule:
|
||||
Timer(0.5, render, kwargs={'reschedule': True}).start()
|
||||
|
||||
global lock
|
||||
with lock:
|
||||
write(powerline.render(mode=modes[0]))
|
||||
write('\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
def update(evt):
|
||||
modes[0] = evt.change
|
||||
render()
|
||||
|
||||
render(reschedule=True)
|
||||
|
||||
if args.i3:
|
||||
import i3
|
||||
sub = i3.Subscription(render, 'workspace')
|
||||
try:
|
||||
import i3ipc
|
||||
except ImportError:
|
||||
import i3
|
||||
i3.Subscription(lambda evt, data, sub: print(render()), 'workspace')
|
||||
else:
|
||||
conn = i3ipc.Connection()
|
||||
conn.on('workspace::focus', lambda conn, evt: render())
|
||||
conn.on('mode', lambda conn, evt: update(evt))
|
||||
conn.main()
|
||||
|
||||
while True:
|
||||
start_time = monotonic()
|
||||
render()
|
||||
time.sleep(max(interval - (monotonic() - start_time), 0.1))
|
||||
time.sleep(1e10)
|
||||
|
|
|
@ -66,7 +66,7 @@ _powerline_set_append_trap() {
|
|||
|
||||
_powerline_create_temp() {
|
||||
if test -z "$_POWERLINE_TEMP" || ! test -e "$_POWERLINE_TEMP" ; then
|
||||
_POWERLINE_TEMP="$(mktemp)"
|
||||
_POWERLINE_TEMP="$(mktemp "${TMPDIR:-/tmp}/powerline.XXXXXXXX")"
|
||||
_powerline_append_trap 'rm $_POWERLINE_TEMP' EXIT
|
||||
fi
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ _powerline_create_temp() {
|
|||
_powerline_set_set_jobs() {
|
||||
if _powerline_has_jobs_in_subshell "$@" ; then
|
||||
_powerline_set_jobs() {
|
||||
_POWERLINE_JOBS="$(jobs -p|wc -l)"
|
||||
_POWERLINE_JOBS="$(jobs -p|wc -l|tr -d ' ')"
|
||||
}
|
||||
else
|
||||
_powerline_set_append_trap "$@"
|
||||
|
@ -90,7 +90,7 @@ _powerline_set_set_jobs() {
|
|||
kill -USR1 $_POWERLINE_PID
|
||||
# Note: most likely this will read data from the previous run. Tests
|
||||
# show that it is OK for some reasons.
|
||||
_POWERLINE_JOBS="$(wc -l < $_POWERLINE_TEMP)"
|
||||
_POWERLINE_JOBS="$(wc -l < $_POWERLINE_TEMP | tr -d ' ')"
|
||||
}
|
||||
fi
|
||||
_powerline_set_set_jobs() {
|
||||
|
|
|
@ -8,5 +8,5 @@ set -g window-status-format "#[$_POWERLINE_WINDOW_COLOR]$_POWERLINE_LEFT_HARD_DI
|
|||
set -g window-status-current-format "#[$_POWERLINE_WINDOW_CURRENT_HARD_DIVIDER_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#[$_POWERLINE_WINDOW_CURRENT_COLOR]#I $_POWERLINE_LEFT_SOFT_DIVIDER#[$_POWERLINE_WINDOW_NAME_COLOR]#W #[$_POWERLINE_WINDOW_CURRENT_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER"
|
||||
|
||||
# Legacy status-left definition to be overwritten for tmux Versions 1.8+
|
||||
set -g status-left "#[$_POWERLINE_SESSION_COLOR] #S #[$_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#(env \"\$POWERLINE_COMMAND\" tmux left)"
|
||||
set -g status-left "#[$_POWERLINE_SESSION_COLOR] #S #[$_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#(env \"\$POWERLINE_COMMAND\" tmux left -R pane_id=`tmux display -p '#D'`)"
|
||||
# vim: ft=tmux
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
set -g status-right '#(env "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS tmux right -R pane_id=`tmux display -p "#D"` --width=`tmux display -p "#{client_width}"` -R width_adjust=`tmux show-options -g status-left-length | cut -d" " -f 2`)'
|
||||
set -g status-left "#[$_POWERLINE_SESSION_COLOR] #S #[$_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#(env \"\$POWERLINE_COMMAND\" tmux left --width=`tmux display -p '#{client_width}'` -R width_adjust=`tmux show-options -g status-right-length | cut -d' ' -f2` -R pane_id=`tmux display -p '#D'`)"
|
||||
# vim: ft=tmux
|
|
@ -1,5 +1,5 @@
|
|||
# powerline_tmux_1.8_plus.conf
|
||||
# tmux Version 1.8 introduces the 'client_prefix' format variable, applicable
|
||||
# for versions 1.8+
|
||||
set -qg status-left "#{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_FG]#[bg=$_POWERLINE_SESSION_PREFIX_BG]#[$_POWERLINE_SESSION_PREFIX_ATTR],#[fg=$_POWERLINE_SESSION_FG]#[bg=$_POWERLINE_SESSION_BG]#[$_POWERLINE_SESSION_ATTR]} #S #{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_BG],#[fg=$_POWERLINE_SESSION_BG]}#[bg=$_POWERLINE_BACKGROUND_BG]#[nobold]$_POWERLINE_LEFT_HARD_DIVIDER#(env \$POWERLINE_COMMAND \$POWERLINE_COMMAND_ARGS tmux left)"
|
||||
set -qg status-left "#{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_FG]#[bg=$_POWERLINE_SESSION_PREFIX_BG]#[$_POWERLINE_SESSION_PREFIX_ATTR],#[fg=$_POWERLINE_SESSION_FG]#[bg=$_POWERLINE_SESSION_BG]#[$_POWERLINE_SESSION_ATTR]} #S #{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_BG],#[fg=$_POWERLINE_SESSION_BG]}#[bg=$_POWERLINE_BACKGROUND_BG]#[nobold]$_POWERLINE_LEFT_HARD_DIVIDER#(env \$POWERLINE_COMMAND \$POWERLINE_COMMAND_ARGS tmux left --width=`tmux display -p '#{client_width}'` -R width_adjust=`tmux show-options -g status-right-length | cut -d' ' -f2` -R pane_id=`tmux display -p '#D'`)"
|
||||
# vim: ft=tmux
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"internal_ip": { "fg": "gray8", "bg": "gray0", "attrs": [] },
|
||||
"network_load": { "fg": "gray8", "bg": "gray0", "attrs": [] },
|
||||
"network_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attrs": [] },
|
||||
"network_load:divider": "background:divider",
|
||||
"system_load": { "fg": "gray8", "bg": "gray0", "attrs": [] },
|
||||
"system_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attrs": [] },
|
||||
"environment": { "fg": "gray8", "bg": "gray0", "attrs": [] },
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"cwd:current_folder": "information:regular",
|
||||
"cwd:divider": { "fg": "solarized:base1", "bg": "solarized:base01", "attrs": [] },
|
||||
"network_load": { "fg": "solarized:base1", "bg": "solarized:base03", "attrs": [] },
|
||||
"network_load:divider": { "fg": "solarized:base1", "bg": "solarized:base03", "attrs": [] },
|
||||
"hostname": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": [] },
|
||||
"environment": { "fg": "solarized:base3", "bg": "solarized:green", "attrs": [] },
|
||||
"attached_clients": { "fg": "solarized:base3", "bg": "solarized:green", "attrs": [] },
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
"function": "powerline.listers.vim.tablister",
|
||||
"exclude_function": "single_tab",
|
||||
"segments": [
|
||||
{
|
||||
"function": "tab"
|
||||
},
|
||||
{
|
||||
"function": "tabnr",
|
||||
"after": " ",
|
||||
|
@ -29,6 +32,12 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "tab",
|
||||
"args": {
|
||||
"end": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "segment_list",
|
||||
"function": "powerline.listers.vim.bufferlister",
|
||||
|
|
|
@ -25,7 +25,7 @@ def parse_value(s):
|
|||
'''
|
||||
if not s:
|
||||
return REMOVE_THIS_KEY
|
||||
elif s[0] in '"{[0193456789-' or s in ('null', 'true', 'false'):
|
||||
elif s[0] in '"{[0123456789-' or s in ('null', 'true', 'false'):
|
||||
return json.loads(s)
|
||||
else:
|
||||
return s
|
||||
|
|
|
@ -198,10 +198,8 @@ args_spec = Spec(
|
|||
segment_info=Spec().error('Segment info dictionary must be set by powerline').optional(),
|
||||
).unknown_spec(Spec(), Spec()).optional().copy
|
||||
segment_module_spec = Spec().type(unicode).func(check_segment_module).optional().copy
|
||||
sub_segments_spec = Spec()
|
||||
exinclude_spec = Spec().re(function_name_re).func(check_exinclude_function).copy
|
||||
segment_spec = Spec(
|
||||
type=Spec().oneof(type_keys).optional(),
|
||||
segment_spec_base = Spec(
|
||||
name=Spec().re('^[a-zA-Z_]\w*$').optional(),
|
||||
function=Spec().re(function_name_re).func(check_segment_function).optional(),
|
||||
exclude_modes=Spec().list(vim_mode_spec()).optional(),
|
||||
|
@ -230,10 +228,14 @@ segment_spec = Spec(
|
|||
':divider$',
|
||||
(lambda value: 'it is recommended that divider highlight group names end with ":divider"')
|
||||
).optional(),
|
||||
segments=sub_segments_spec,
|
||||
).func(check_full_segment_data)
|
||||
sub_segments_spec.optional().list(segment_spec)
|
||||
del sub_segments_spec
|
||||
).func(check_full_segment_data).copy
|
||||
subsegment_spec = segment_spec_base().update(
|
||||
type=Spec().oneof(set((key for key in type_keys if key != 'segment_list'))).optional(),
|
||||
)
|
||||
segment_spec = segment_spec_base().update(
|
||||
type=Spec().oneof(type_keys).optional(),
|
||||
segments=Spec().optional().list(subsegment_spec),
|
||||
)
|
||||
segments_spec = Spec().optional().list(segment_spec).copy
|
||||
segdict_spec = Spec(
|
||||
left=segments_spec().context_message('Error while loading segments from left side (key {key})'),
|
||||
|
|
|
@ -381,7 +381,10 @@ def check_segment_function(function_name, data, context, echoerr):
|
|||
hl_groups = []
|
||||
divider_hl_group = None
|
||||
|
||||
hadproblem = False
|
||||
|
||||
if func.__doc__:
|
||||
NO_H_G_USED_STR = 'No highlight groups are used (literal segment).'
|
||||
H_G_USED_STR = 'Highlight groups used: '
|
||||
LHGUS = len(H_G_USED_STR)
|
||||
D_H_G_USED_STR = 'Divider highlight group used: '
|
||||
|
@ -391,6 +394,20 @@ def check_segment_function(function_name, data, context, echoerr):
|
|||
for i, line in enumerate(func.__doc__.split('\n')):
|
||||
if H_G_USED_STR in line:
|
||||
idx = line.index(H_G_USED_STR) + LHGUS
|
||||
if hl_groups is None:
|
||||
idx -= LHGUS
|
||||
mark = Mark(mark_name, i + 1, idx + 1, func.__doc__, pointer + idx)
|
||||
echoerr(
|
||||
context='Error while checking theme (key {key})'.format(key=context.key),
|
||||
context_mark=function_name.mark,
|
||||
problem=(
|
||||
'found highlight group definition in addition to sentense stating that '
|
||||
'no highlight groups are used'
|
||||
),
|
||||
problem_mark=mark,
|
||||
)
|
||||
hadproblem = True
|
||||
continue
|
||||
hl_groups.append((
|
||||
line[idx:],
|
||||
(mark_name, i + 1, idx + 1, func.__doc__),
|
||||
|
@ -400,10 +417,24 @@ def check_segment_function(function_name, data, context, echoerr):
|
|||
idx = line.index(D_H_G_USED_STR) + LDHGUS + 2
|
||||
mark = Mark(mark_name, i + 1, idx + 1, func.__doc__, pointer + idx)
|
||||
divider_hl_group = MarkedUnicode(line[idx:-3], mark)
|
||||
elif NO_H_G_USED_STR in line:
|
||||
idx = line.index(NO_H_G_USED_STR)
|
||||
if hl_groups:
|
||||
mark = Mark(mark_name, i + 1, idx + 1, func.__doc__, pointer + idx)
|
||||
echoerr(
|
||||
context='Error while checking theme (key {key})'.format(key=context.key),
|
||||
context_mark=function_name.mark,
|
||||
problem=(
|
||||
'found sentense stating that no highlight groups are used '
|
||||
'in addition to highlight group definition'
|
||||
),
|
||||
problem_mark=mark,
|
||||
)
|
||||
hadproblem = True
|
||||
continue
|
||||
hl_groups = None
|
||||
pointer += len(line) + len('\n')
|
||||
|
||||
hadproblem = False
|
||||
|
||||
if divider_hl_group:
|
||||
r = hl_exists(divider_hl_group, data, context, echoerr, allow_gradients=True)
|
||||
if r:
|
||||
|
@ -466,7 +497,7 @@ def check_segment_function(function_name, data, context, echoerr):
|
|||
h[0], list_sep.join(r))
|
||||
)
|
||||
hadproblem = True
|
||||
else:
|
||||
elif hl_groups is not None:
|
||||
r = hl_exists(function_name, data, context, echoerr, allow_gradients=True)
|
||||
if r:
|
||||
echoerr(
|
||||
|
|
|
@ -391,7 +391,10 @@ class Renderer(object):
|
|||
segment['contents'] = translate_np(segment['contents'])
|
||||
if calculate_contents_len:
|
||||
for segment in segments:
|
||||
segment['_contents_len'] = self.strwidth(segment['contents'])
|
||||
if segment['literal_contents'][1]:
|
||||
segment['_contents_len'] = segment['literal_contents'][0]
|
||||
else:
|
||||
segment['_contents_len'] = self.strwidth(segment['contents'])
|
||||
|
||||
def _render_length(self, theme, segments, divider_widths):
|
||||
'''Update segments lengths and return them
|
||||
|
@ -399,24 +402,52 @@ class Renderer(object):
|
|||
segments_len = len(segments)
|
||||
ret = 0
|
||||
divider_spaces = theme.get_spaces()
|
||||
prev_segment = theme.EMPTY_SEGMENT
|
||||
try:
|
||||
first_segment = next(iter((
|
||||
segment
|
||||
for segment in segments
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
except StopIteration:
|
||||
first_segment = None
|
||||
try:
|
||||
last_segment = next(iter((
|
||||
segment
|
||||
for segment in reversed(segments)
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
except StopIteration:
|
||||
last_segment = None
|
||||
for index, segment in enumerate(segments):
|
||||
side = segment['side']
|
||||
segment_len = segment['_contents_len']
|
||||
if not segment['literal_contents'][1]:
|
||||
if side == 'left':
|
||||
if segment is not last_segment:
|
||||
compare_segment = next(iter((
|
||||
segment
|
||||
for segment in segments[index + 1:]
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
else:
|
||||
compare_segment = theme.EMPTY_SEGMENT
|
||||
else:
|
||||
compare_segment = prev_segment
|
||||
|
||||
prev_segment = segments[index - 1] if index > 0 else theme.EMPTY_SEGMENT
|
||||
next_segment = segments[index + 1] if index < segments_len - 1 else theme.EMPTY_SEGMENT
|
||||
compare_segment = next_segment if side == 'left' else prev_segment
|
||||
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
|
||||
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
|
||||
|
||||
outer_padding = int(bool(
|
||||
(index == 0 and side == 'left') or
|
||||
(index == segments_len - 1 and side == 'right')
|
||||
))
|
||||
outer_padding = int(bool(
|
||||
segment is first_segment
|
||||
if side == 'left' else
|
||||
segment is last_segment
|
||||
))
|
||||
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
segment_len += outer_padding
|
||||
if draw_divider:
|
||||
segment_len += divider_widths[side][divider_type] + divider_spaces
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
segment_len += outer_padding
|
||||
if draw_divider:
|
||||
segment_len += divider_widths[side][divider_type] + divider_spaces
|
||||
prev_segment = segment
|
||||
|
||||
segment['_len'] = segment_len
|
||||
ret += segment_len
|
||||
|
@ -435,61 +466,92 @@ class Renderer(object):
|
|||
'''
|
||||
segments_len = len(segments)
|
||||
divider_spaces = theme.get_spaces()
|
||||
prev_segment = theme.EMPTY_SEGMENT
|
||||
try:
|
||||
first_segment = next(iter((
|
||||
segment
|
||||
for segment in segments
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
except StopIteration:
|
||||
first_segment = None
|
||||
try:
|
||||
last_segment = next(iter((
|
||||
segment
|
||||
for segment in reversed(segments)
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
except StopIteration:
|
||||
last_segment = None
|
||||
|
||||
for index, segment in enumerate(segments):
|
||||
side = segment['side']
|
||||
prev_segment = segments[index - 1] if index > 0 else theme.EMPTY_SEGMENT
|
||||
next_segment = segments[index + 1] if index < segments_len - 1 else theme.EMPTY_SEGMENT
|
||||
compare_segment = next_segment if side == 'left' else prev_segment
|
||||
outer_padding = int(bool(
|
||||
(index == 0 and side == 'left') or
|
||||
(index == segments_len - 1 and side == 'right')
|
||||
)) * ' '
|
||||
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
|
||||
|
||||
divider_highlighted = ''
|
||||
contents_raw = segment['contents']
|
||||
contents_highlighted = ''
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
|
||||
# XXX Make sure self.hl() calls are called in the same order
|
||||
# segments are displayed. This is needed for Vim renderer to work.
|
||||
if draw_divider:
|
||||
divider_raw = self.escape(theme.get_divider(side, divider_type))
|
||||
if not segment['literal_contents'][1]:
|
||||
if side == 'left':
|
||||
contents_raw = outer_padding + contents_raw + (divider_spaces * ' ')
|
||||
if segment is not last_segment:
|
||||
compare_segment = next(iter((
|
||||
segment
|
||||
for segment in segments[index + 1:]
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
else:
|
||||
compare_segment = theme.EMPTY_SEGMENT
|
||||
else:
|
||||
contents_raw = (divider_spaces * ' ') + contents_raw + outer_padding
|
||||
compare_segment = prev_segment
|
||||
outer_padding = int(bool(
|
||||
segment is first_segment
|
||||
if side == 'left' else
|
||||
segment is last_segment
|
||||
)) * ' '
|
||||
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
|
||||
|
||||
if divider_type == 'soft':
|
||||
divider_highlight_group_key = 'highlight' if segment['divider_highlight_group'] is None else 'divider_highlight'
|
||||
divider_fg = segment[divider_highlight_group_key]['fg']
|
||||
divider_bg = segment[divider_highlight_group_key]['bg']
|
||||
else:
|
||||
divider_fg = segment['highlight']['bg']
|
||||
divider_bg = compare_segment['highlight']['bg']
|
||||
divider_highlighted = ''
|
||||
contents_raw = segment['contents']
|
||||
contents_highlighted = ''
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
|
||||
if side == 'left':
|
||||
if render_highlighted:
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False)
|
||||
segment['_rendered_raw'] = contents_raw + divider_raw
|
||||
segment['_rendered_hl'] = contents_highlighted + divider_highlighted
|
||||
# XXX Make sure self.hl() calls are called in the same order
|
||||
# segments are displayed. This is needed for Vim renderer to work.
|
||||
if draw_divider:
|
||||
divider_raw = self.escape(theme.get_divider(side, divider_type))
|
||||
if side == 'left':
|
||||
contents_raw = outer_padding + contents_raw + (divider_spaces * ' ')
|
||||
else:
|
||||
contents_raw = (divider_spaces * ' ') + contents_raw + outer_padding
|
||||
|
||||
if divider_type == 'soft':
|
||||
divider_highlight_group_key = 'highlight' if segment['divider_highlight_group'] is None else 'divider_highlight'
|
||||
divider_fg = segment[divider_highlight_group_key]['fg']
|
||||
divider_bg = segment[divider_highlight_group_key]['bg']
|
||||
else:
|
||||
divider_fg = segment['highlight']['bg']
|
||||
divider_bg = compare_segment['highlight']['bg']
|
||||
|
||||
if side == 'left':
|
||||
if render_highlighted:
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False)
|
||||
segment['_rendered_raw'] = contents_raw + divider_raw
|
||||
segment['_rendered_hl'] = contents_highlighted + divider_highlighted
|
||||
else:
|
||||
if render_highlighted:
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False)
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
segment['_rendered_raw'] = divider_raw + contents_raw
|
||||
segment['_rendered_hl'] = divider_highlighted + contents_highlighted
|
||||
else:
|
||||
if render_highlighted:
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False)
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
segment['_rendered_raw'] = divider_raw + contents_raw
|
||||
segment['_rendered_hl'] = divider_highlighted + contents_highlighted
|
||||
if side == 'left':
|
||||
contents_raw = outer_padding + contents_raw
|
||||
else:
|
||||
contents_raw = contents_raw + outer_padding
|
||||
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
segment['_rendered_raw'] = contents_raw
|
||||
segment['_rendered_hl'] = contents_highlighted
|
||||
prev_segment = segment
|
||||
else:
|
||||
if side == 'left':
|
||||
contents_raw = outer_padding + contents_raw
|
||||
else:
|
||||
contents_raw = contents_raw + outer_padding
|
||||
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
segment['_rendered_raw'] = contents_raw
|
||||
segment['_rendered_hl'] = contents_highlighted
|
||||
segment['_rendered_raw'] = ' ' * segment['literal_contents'][0]
|
||||
segment['_rendered_hl'] = segment['literal_contents'][1]
|
||||
yield segment
|
||||
|
||||
def escape(self, string):
|
||||
|
|
|
@ -35,10 +35,10 @@ class BarRenderer(Renderer):
|
|||
|
||||
return text + contents + '%{F-B--u}'
|
||||
|
||||
def render(self):
|
||||
def render(self, *args, **kwargs):
|
||||
return '%{{l}}{0}%{{r}}{1}'.format(
|
||||
super(BarRenderer, self).render(side='left'),
|
||||
super(BarRenderer, self).render(side='right'),
|
||||
super(BarRenderer, self).render(side='left', *args, **kwargs),
|
||||
super(BarRenderer, self).render(side='right', *args, **kwargs),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,13 @@ class TmuxRenderer(Renderer):
|
|||
character_translations = Renderer.character_translations.copy()
|
||||
character_translations[ord('#')] = '##[]'
|
||||
|
||||
def render(self, width=None, segment_info={}, **kwargs):
|
||||
if width and segment_info:
|
||||
width -= segment_info.get('width_adjust', 0)
|
||||
if width < 10:
|
||||
width = 10
|
||||
return super(TmuxRenderer, self).render(width=width, segment_info=segment_info, **kwargs)
|
||||
|
||||
def hlstyle(self, fg=None, bg=None, attrs=None):
|
||||
'''Highlight a segment.'''
|
||||
# We don’t need to explicitly reset attributes, so skip those calls
|
||||
|
|
|
@ -127,6 +127,8 @@ def process_segment_lister(pl, segment_info, parsed_segments, side, mode, colors
|
|||
colorscheme,
|
||||
)
|
||||
new_pslen = len(parsed_segments)
|
||||
while parsed_segments[new_pslen - 1]['literal_contents'][1]:
|
||||
new_pslen -= 1
|
||||
if new_pslen > old_pslen + 1 and draw_inner_divider is not None:
|
||||
for i in range(old_pslen, new_pslen - 1) if side == 'left' else range(old_pslen + 1, new_pslen):
|
||||
parsed_segments[i]['draw_soft_divider'] = draw_inner_divider
|
||||
|
@ -134,6 +136,8 @@ def process_segment_lister(pl, segment_info, parsed_segments, side, mode, colors
|
|||
|
||||
|
||||
def set_segment_highlighting(pl, colorscheme, segment, mode):
|
||||
if segment['literal_contents'][1]:
|
||||
return True
|
||||
try:
|
||||
highlight_group_prefix = segment['highlight_group_prefix']
|
||||
except KeyError:
|
||||
|
@ -228,6 +232,7 @@ get_fallback_segment = {
|
|||
'before': None,
|
||||
'after': None,
|
||||
'contents': '',
|
||||
'literal_contents': (0, ''),
|
||||
'priority': None,
|
||||
'draw_soft_divider': True,
|
||||
'draw_hard_divider': True,
|
||||
|
@ -245,6 +250,7 @@ get_fallback_segment = {
|
|||
'_contents_len': None,
|
||||
}.copy
|
||||
|
||||
|
||||
def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, get_module_attr, top_theme):
|
||||
data = {
|
||||
'default_module': default_module or 'powerline.segments.' + ext,
|
||||
|
@ -373,6 +379,7 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
|
|||
)
|
||||
),
|
||||
'contents': None,
|
||||
'literal_contents': None,
|
||||
'priority': None,
|
||||
'draw_soft_divider': None,
|
||||
'draw_hard_divider': None,
|
||||
|
@ -421,6 +428,7 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
|
|||
'after': get_key(False, segment, module, function_name, name, 'after', ''),
|
||||
'contents_func': contents_func,
|
||||
'contents': contents,
|
||||
'literal_contents': (0, ''),
|
||||
'priority': segment.get('priority', None),
|
||||
'draw_hard_divider': segment.get('draw_hard_divider', True),
|
||||
'draw_soft_divider': segment.get('draw_soft_divider', True),
|
||||
|
|
|
@ -3,36 +3,37 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
|||
|
||||
import re
|
||||
|
||||
from imaplib import IMAP4_SSL_PORT, IMAP4_SSL, IMAP4
|
||||
from collections import namedtuple
|
||||
|
||||
from powerline.lib.threaded import KwThreadedSegment
|
||||
from powerline.segments import with_docstring
|
||||
|
||||
|
||||
_IMAPKey = namedtuple('Key', 'username password server port folder')
|
||||
_IMAPKey = namedtuple('Key', 'username password server port folder use_ssl')
|
||||
|
||||
|
||||
class EmailIMAPSegment(KwThreadedSegment):
|
||||
interval = 60
|
||||
|
||||
@staticmethod
|
||||
def key(username, password, server='imap.gmail.com', port=993, folder='INBOX', **kwargs):
|
||||
return _IMAPKey(username, password, server, port, folder)
|
||||
def key(username, password, server='imap.gmail.com', port=IMAP4_SSL_PORT, folder='INBOX', use_ssl=None, **kwargs):
|
||||
if use_ssl is None:
|
||||
use_ssl = (port == IMAP4_SSL_PORT)
|
||||
return _IMAPKey(username, password, server, port, folder, use_ssl)
|
||||
|
||||
def compute_state(self, key):
|
||||
if not key.username or not key.password:
|
||||
self.warn('Username and password are not configured')
|
||||
return None
|
||||
try:
|
||||
import imaplib
|
||||
except imaplib.IMAP4.error as e:
|
||||
unread_count = str(e)
|
||||
if key.use_ssl:
|
||||
mail = IMAP4_SSL(key.server, key.port)
|
||||
else:
|
||||
mail = imaplib.IMAP4_SSL(key.server, key.port)
|
||||
mail.login(key.username, key.password)
|
||||
rc, message = mail.status(key.folder, '(UNSEEN)')
|
||||
unread_str = message[0].decode('utf-8')
|
||||
unread_count = int(re.search('UNSEEN (\d+)', unread_str).group(1))
|
||||
mail = IMAP4(key.server, key.port)
|
||||
mail.login(key.username, key.password)
|
||||
rc, message = mail.status(key.folder, '(UNSEEN)')
|
||||
unread_str = message[0].decode('utf-8')
|
||||
unread_count = int(re.search('UNSEEN (\d+)', unread_str).group(1))
|
||||
return unread_count
|
||||
|
||||
@staticmethod
|
||||
|
@ -53,7 +54,7 @@ class EmailIMAPSegment(KwThreadedSegment):
|
|||
|
||||
|
||||
email_imap_alert = with_docstring(EmailIMAPSegment(),
|
||||
'''Return unread e-mail count for IMAP servers.
|
||||
('''Return unread e-mail count for IMAP servers.
|
||||
|
||||
:param str username:
|
||||
login username
|
||||
|
@ -69,6 +70,9 @@ email_imap_alert = with_docstring(EmailIMAPSegment(),
|
|||
Maximum number of messages. If there are more messages then max_msgs then it
|
||||
will use gradient level equal to 100, otherwise gradient level is equal to
|
||||
``100 * msgs_num / max_msgs``. If not present gradient is not computed.
|
||||
:param bool use_ssl:
|
||||
If ``True`` then use SSL connection. If ``False`` then do not use it.
|
||||
Default is ``True`` if port is equal to {ssl_port} and ``False`` otherwise.
|
||||
|
||||
Highlight groups used: ``email_alert_gradient`` (gradient), ``email_alert``.
|
||||
''')
|
||||
''').format(ssl_port=IMAP4_SSL_PORT))
|
||||
|
|
|
@ -247,7 +247,7 @@ class NetworkLoadSegment(KwThreadedSegment):
|
|||
hl_groups[:0] = (group + '_gradient' for group in hl_groups)
|
||||
r.append({
|
||||
'contents': format.format(value=humanize_bytes(value, suffix, si_prefix)),
|
||||
'divider_highlight_group': 'background:divider',
|
||||
'divider_highlight_group': 'network_load:divider',
|
||||
'highlight_groups': hl_groups,
|
||||
})
|
||||
if is_gradient:
|
||||
|
@ -287,7 +287,7 @@ falls back to reading
|
|||
Maximum number of sent bytes per second. Is only used to compute gradient
|
||||
level.
|
||||
|
||||
Divider highlight group used: ``background:divider``.
|
||||
Divider highlight group used: ``network_load:divider``.
|
||||
|
||||
Highlight groups used: ``network_load_sent_gradient`` (gradient) or ``network_load_recv_gradient`` (gradient) or ``network_load_gradient`` (gradient), ``network_load_sent`` or ``network_load_recv`` or ``network_load``.
|
||||
''')
|
||||
|
|
|
@ -208,7 +208,14 @@ class MpdPlayerSegment(PlayerSegment):
|
|||
mpd = with_docstring(MpdPlayerSegment(),
|
||||
('''Return Music Player Daemon information
|
||||
|
||||
Requires mpc command to be acessible from $PATH or ``mpd`` Python module.
|
||||
Requires ``mpd`` Python module (e.g. |python-mpd2|_ or |python-mpd|_ Python
|
||||
package) or alternatively the ``mpc`` command to be acessible from $PATH.
|
||||
|
||||
.. |python-mpd| replace:: ``python-mpd``
|
||||
.. _python-mpd: https://pypi.python.org/pypi/python-mpd
|
||||
|
||||
.. |python-mpd2| replace:: ``python-mpd2``
|
||||
.. _python-mpd2: https://pypi.python.org/pypi/python-mpd2
|
||||
|
||||
{0}
|
||||
:param str host:
|
||||
|
|
|
@ -131,10 +131,12 @@ if os.path.exists('/proc/uptime'):
|
|||
elif 'psutil' in globals():
|
||||
from time import time
|
||||
|
||||
def _get_uptime():
|
||||
# psutil.BOOT_TIME is not subject to clock adjustments, but time() is.
|
||||
# Thus it is a fallback to /proc/uptime reading and not the reverse.
|
||||
return int(time() - psutil.BOOT_TIME)
|
||||
if hasattr(psutil, 'boot_time'):
|
||||
def _get_uptime():
|
||||
return int(time() - psutil.boot_time())
|
||||
else:
|
||||
def _get_uptime():
|
||||
return int(time() - psutil.BOOT_TIME)
|
||||
else:
|
||||
def _get_uptime():
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import i3
|
||||
from powerline.theme import requires_segment_info
|
||||
|
||||
|
||||
conn = None
|
||||
|
||||
|
||||
def calcgrp(w):
|
||||
|
@ -16,12 +19,46 @@ def calcgrp(w):
|
|||
return group
|
||||
|
||||
|
||||
def workspaces(pl):
|
||||
'''Return workspace list
|
||||
def workspaces(pl, only_show=None, strip=0):
|
||||
'''Return list of used workspaces
|
||||
|
||||
Highlight groups used: ``workspace``, ``w_visible``, ``w_focused``, ``w_urgent``
|
||||
:param list only_show:
|
||||
Specifies which workspaces to show. Valid entries are ``"visible"``,
|
||||
``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces
|
||||
are shown.
|
||||
|
||||
:param int strip:
|
||||
Specifies how many characters from the front of each workspace name
|
||||
should be stripped (e.g. to remove workspace numbers). Defaults to zero.
|
||||
|
||||
Highlight groups used: ``workspace`` or ``w_visible``, ``workspace`` or ``w_focused``, ``workspace`` or ``w_urgent``.
|
||||
'''
|
||||
global conn
|
||||
if not conn:
|
||||
try:
|
||||
import i3ipc
|
||||
except ImportError:
|
||||
import i3 as conn
|
||||
else:
|
||||
conn = i3ipc.Connection()
|
||||
|
||||
return [{
|
||||
'contents': w['name'],
|
||||
'contents': w['name'][min(len(w['name']), strip):],
|
||||
'highlight_groups': calcgrp(w)
|
||||
} for w in i3.get_workspaces()]
|
||||
} for w in conn.get_workspaces() if not only_show or any((w[typ] for typ in only_show))]
|
||||
|
||||
|
||||
@requires_segment_info
|
||||
def mode(pl, segment_info, names={'default': None}):
|
||||
'''Returns current i3 mode
|
||||
|
||||
:param dict names:
|
||||
Specifies the string to show for various modes.
|
||||
Use ``null`` to hide a mode (``default`` is hidden by default).
|
||||
|
||||
Highligh groups used: ``mode``
|
||||
'''
|
||||
mode = segment_info['mode']
|
||||
if mode in names:
|
||||
return names[mode]
|
||||
return mode
|
||||
|
|
|
@ -740,3 +740,21 @@ def csv_col_current(pl, segment_info, display_name='auto', name_format=' ({colum
|
|||
'contents': name_format.format(column_name=column_name),
|
||||
'highlight_groups': ['csv:column_name', 'csv'],
|
||||
}] if column_name else [])
|
||||
|
||||
|
||||
@requires_segment_info
|
||||
def tab(pl, segment_info, end=False):
|
||||
'''Mark start of the clickable region for tabpage
|
||||
|
||||
:param bool end:
|
||||
In place of starting region for the current tab end it.
|
||||
|
||||
No highlight groups are used (literal segment).
|
||||
'''
|
||||
try:
|
||||
return [{
|
||||
'contents': None,
|
||||
'literal_contents': (0, '%{tabnr}T'.format(tabnr=('' if end else segment_info['tabnr']))),
|
||||
}]
|
||||
except KeyError:
|
||||
return None
|
||||
|
|
4
setup.py
4
setup.py
|
@ -59,7 +59,7 @@ else:
|
|||
|
||||
|
||||
def get_version():
|
||||
base_version = '2.1.4'
|
||||
base_version = '2.2'
|
||||
base_version += '.dev9999'
|
||||
try:
|
||||
return base_version + '+git.' + str(subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip())
|
||||
|
@ -70,7 +70,7 @@ def get_version():
|
|||
|
||||
setup(
|
||||
name='powerline-status',
|
||||
version='2.1.4',
|
||||
version='2.2',
|
||||
description='The ultimate statusline/prompt utility.',
|
||||
long_description=README,
|
||||
classifiers=[
|
||||
|
|
|
@ -28,6 +28,7 @@ class ExpectProcess(threading.Thread):
|
|||
child = pexpect.spawn(self.cmd, self.args, cwd=self.cwd, env=self.env)
|
||||
sleep(0.5)
|
||||
child.setwinsize(self.rows, self.cols)
|
||||
sleep(0.5)
|
||||
self.child = child
|
||||
status = None
|
||||
while status is None:
|
||||
|
@ -44,6 +45,13 @@ class ExpectProcess(threading.Thread):
|
|||
self.vterm.push(s)
|
||||
self.buffer.append(s)
|
||||
|
||||
def resize(self, rows, cols):
|
||||
with self.child_lock:
|
||||
self.rows = rows
|
||||
self.cols = cols
|
||||
self.child.setwinsize(rows, cols)
|
||||
self.vterm.resize(rows, cols)
|
||||
|
||||
def __getitem__(self, position):
|
||||
with self.lock:
|
||||
return self.vterm.vtscreen[position]
|
||||
|
|
|
@ -91,6 +91,11 @@ def get_functions(lib):
|
|||
('cols', ctypes.c_int)
|
||||
)),
|
||||
vterm_obtain_screen=(VTermScreen_p, (('vt', VTerm_p),)),
|
||||
vterm_set_size=(None, (
|
||||
('vt', VTerm_p),
|
||||
('rows', ctypes.c_int),
|
||||
('cols', ctypes.c_int)
|
||||
)),
|
||||
vterm_screen_reset=(None, (
|
||||
('screen', VTermScreen_p),
|
||||
('hard', ctypes.c_int)
|
||||
|
@ -171,6 +176,9 @@ class VTerm(object):
|
|||
data = data.encode('utf-8')
|
||||
return self.functions.vterm_input_write(self.vt, data, len(data))
|
||||
|
||||
def resize(self, rows, cols):
|
||||
self.functions.vterm_set_size(self.vt, rows, cols)
|
||||
|
||||
def __del__(self):
|
||||
try:
|
||||
self.functions.vterm_free(self.vt)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/vim -S
|
||||
if has('multibyte')
|
||||
if has('multi_byte')
|
||||
if empty(&encoding)
|
||||
call writefile(['&encoding option value is empty, even though Vim has +multibyte'], 'message.fail')
|
||||
cquit
|
||||
|
|
|
@ -11,6 +11,7 @@ mkdir tests/vterm/path
|
|||
ln -s "$(which "${PYTHON}")" tests/vterm/path/python
|
||||
ln -s "$(which bash)" tests/vterm/path
|
||||
ln -s "$(which env)" tests/vterm/path
|
||||
ln -s "$(which cut)" tests/vterm/path
|
||||
ln -s "$PWD/scripts/powerline-render" tests/vterm/path
|
||||
ln -s "$PWD/scripts/powerline-config" tests/vterm/path
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ def test_expected_result(p, expected_result, cols, rows, print_logs):
|
|||
for key, text in result
|
||||
))
|
||||
print(shesc_result)
|
||||
print(result)
|
||||
print('Expected:')
|
||||
shesc_expected_result = ''.join((
|
||||
'{0}{1}\x1b[m'.format(cell_properties_key_to_shell_escape(key), text)
|
||||
|
@ -95,6 +96,17 @@ def test_expected_result(p, expected_result, cols, rows, print_logs):
|
|||
return False
|
||||
|
||||
|
||||
def get_expected_result(tmux_version, expected_result_old, expected_result_1_7=None, expected_result_new=None, expected_result_2_0=None):
|
||||
if tmux_version >= (2, 0) and expected_result_2_0:
|
||||
return expected_result_2_0
|
||||
elif tmux_version >= (1, 8) and expected_result_new:
|
||||
return expected_result_new
|
||||
elif tmux_version >= (1, 7) and expected_result_1_7:
|
||||
return expected_result_1_7
|
||||
else:
|
||||
return expected_result_old
|
||||
|
||||
|
||||
def main(attempts=3):
|
||||
vterm_path = os.path.join(VTERM_TEST_DIR, 'path')
|
||||
socket_path = 'tmux-socket'
|
||||
|
@ -165,8 +177,8 @@ def main(attempts=3):
|
|||
'POWERLINE_CONFIG_PATHS': os.path.abspath('powerline/config_files'),
|
||||
'POWERLINE_COMMAND': 'powerline-render',
|
||||
'POWERLINE_THEME_OVERRIDES': (
|
||||
'default.segments.right=[{"type":"string","name":"s1","highlight_groups":["cwd"]}];'
|
||||
'default.segments.left=[{"type":"string","name":"s2","highlight_groups":["background"]}];'
|
||||
'default.segments.right=[{"type":"string","name":"s1","highlight_groups":["cwd"],"priority":50}];'
|
||||
'default.segments.left=[{"type":"string","name":"s2","highlight_groups":["background"],"priority":20}];'
|
||||
'default.segment_data.s1.contents=S1 string here;'
|
||||
'default.segment_data.s2.contents=S2 string here;'
|
||||
),
|
||||
|
@ -175,8 +187,47 @@ def main(attempts=3):
|
|||
},
|
||||
)
|
||||
p.start()
|
||||
sleep(2)
|
||||
expected_result_2_0 = (
|
||||
sleep(5)
|
||||
tmux_version = get_tmux_version(get_fallback_logger())
|
||||
expected_result = get_expected_result(tmux_version, expected_result_old=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 1 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2 | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * 127),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '),
|
||||
), expected_result_new=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 1 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2 | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * 127),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '),
|
||||
), expected_result_2_0=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '),
|
||||
|
@ -195,62 +246,69 @@ def main(attempts=3):
|
|||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * 128),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '),
|
||||
)
|
||||
expected_result_new = (
|
||||
))
|
||||
ret = None
|
||||
if not test_expected_result(p, expected_result, cols, rows, not attempts):
|
||||
if attempts:
|
||||
pass
|
||||
# Will rerun main later.
|
||||
else:
|
||||
ret = False
|
||||
elif ret is not False:
|
||||
ret = True
|
||||
cols = 40
|
||||
p.resize(rows, cols)
|
||||
sleep(5)
|
||||
expected_result = get_expected_result(tmux_version, (
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * cols),
|
||||
), expected_result_1_7=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' <'),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'sh '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 1 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2 | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here ')
|
||||
), expected_result_new=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' <'),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), 'sh '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2 | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here ')
|
||||
), expected_result_2_0=(
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), '<'),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2 | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * 127),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '),
|
||||
)
|
||||
expected_result_old = (
|
||||
(((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '),
|
||||
(((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 1 '),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '),
|
||||
(((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '),
|
||||
(((102, 204, 255), (0, 102, 153), 0, 0, 0), '2 | '),
|
||||
(((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '),
|
||||
(((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((255, 255, 255), (11, 11, 11), 0, 0, 0), ' ' * 127),
|
||||
(((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '),
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '),
|
||||
)
|
||||
tmux_version = get_tmux_version(get_fallback_logger())
|
||||
if tmux_version >= (2, 0):
|
||||
expected_result = expected_result_2_0
|
||||
elif tmux_version >= (1, 8):
|
||||
expected_result = expected_result_new
|
||||
else:
|
||||
expected_result = expected_result_old
|
||||
(((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here ')
|
||||
))
|
||||
if not test_expected_result(p, expected_result, cols, rows, not attempts):
|
||||
if attempts:
|
||||
pass
|
||||
# Will rerun main later.
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
ret = False
|
||||
elif ret is not False:
|
||||
ret = True
|
||||
if ret is not None:
|
||||
return ret
|
||||
finally:
|
||||
check_call([tmux_exe, '-S', socket_path, 'kill-server'], env={
|
||||
'PATH': vterm_path,
|
||||
|
|
|
@ -6,8 +6,9 @@ import os
|
|||
|
||||
from functools import partial
|
||||
from collections import namedtuple
|
||||
from time import sleep
|
||||
|
||||
from powerline.segments import shell, tmux, pdb
|
||||
from powerline.segments import shell, tmux, pdb, i3wm
|
||||
from powerline.lib.vcs import get_fallback_create_watcher
|
||||
from powerline.lib.unicode import out_u
|
||||
|
||||
|
@ -397,8 +398,6 @@ class TestNet(TestCommon):
|
|||
self.assertEqual(self.module.internal_ip(pl=pl, ipv=6), None)
|
||||
|
||||
def test_network_load(self):
|
||||
from time import sleep
|
||||
|
||||
def gb(interface):
|
||||
return None
|
||||
|
||||
|
@ -430,24 +429,24 @@ class TestNet(TestCommon):
|
|||
while not self.module.network_load.interfaces.get('eth0', {}).get('prev', (None, None))[1]:
|
||||
sleep(0.1)
|
||||
self.assertEqual(self.module.network_load(pl=pl, interface='eth0'), [
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 'DL 1 KiB/s', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 'UL 2 KiB/s', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 'DL 1 KiB/s', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 'UL 2 KiB/s', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
])
|
||||
self.assertEqual(self.module.network_load(pl=pl, interface='eth0', recv_format='r {value}', sent_format='s {value}'), [
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 'r 1 KiB/s', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 's 2 KiB/s', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
])
|
||||
self.assertEqual(self.module.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', suffix='bps', interface='eth0'), [
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 'r 1 Kibps', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 's 2 Kibps', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 'r 1 Kibps', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 's 2 Kibps', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
])
|
||||
self.assertEqual(self.module.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', si_prefix=True, interface='eth0'), [
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 'r 1 kB/s', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 's 2 kB/s', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 'r 1 kB/s', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 's 2 kB/s', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
])
|
||||
self.assertEqual(self.module.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', recv_max=0, interface='eth0'), [
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_groups': ['network_load_recv_gradient', 'network_load_gradient', 'network_load_recv', 'network_load'], 'gradient_level': 100},
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 'r 1 KiB/s', 'highlight_groups': ['network_load_recv_gradient', 'network_load_gradient', 'network_load_recv', 'network_load'], 'gradient_level': 100},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 's 2 KiB/s', 'highlight_groups': ['network_load_sent', 'network_load']},
|
||||
])
|
||||
|
||||
class ApproxEqual(object):
|
||||
|
@ -455,8 +454,8 @@ class TestNet(TestCommon):
|
|||
return abs(i - 50.0) < 1
|
||||
|
||||
self.assertEqual(self.module.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', sent_max=4800, interface='eth0'), [
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_groups': ['network_load_sent_gradient', 'network_load_gradient', 'network_load_sent', 'network_load'], 'gradient_level': ApproxEqual()},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 'r 1 KiB/s', 'highlight_groups': ['network_load_recv', 'network_load']},
|
||||
{'divider_highlight_group': 'network_load:divider', 'contents': 's 2 KiB/s', 'highlight_groups': ['network_load_sent_gradient', 'network_load_gradient', 'network_load_sent', 'network_load'], 'gradient_level': ApproxEqual()},
|
||||
])
|
||||
finally:
|
||||
self.module.network_load.shutdown()
|
||||
|
@ -816,6 +815,50 @@ class TestWthr(TestCommon):
|
|||
self.module.weather.shutdown()
|
||||
|
||||
|
||||
class TestI3WM(TestCase):
|
||||
def test_workspaces(self):
|
||||
pl = Pl()
|
||||
with replace_attr(i3wm, 'conn', Args(get_workspaces=lambda: iter([
|
||||
{'name': '1: w1', 'focused': False, 'urgent': False, 'visible': False},
|
||||
{'name': '2: w2', 'focused': False, 'urgent': False, 'visible': True},
|
||||
{'name': '3: w3', 'focused': False, 'urgent': True, 'visible': True},
|
||||
{'name': '4: w4', 'focused': True, 'urgent': True, 'visible': True},
|
||||
]))):
|
||||
self.assertEqual(i3wm.workspaces(pl=pl), [
|
||||
{'contents': '1: w1', 'highlight_groups': ['workspace']},
|
||||
{'contents': '2: w2', 'highlight_groups': ['w_visible', 'workspace']},
|
||||
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, only_show=None), [
|
||||
{'contents': '1: w1', 'highlight_groups': ['workspace']},
|
||||
{'contents': '2: w2', 'highlight_groups': ['w_visible', 'workspace']},
|
||||
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, only_show=['focused', 'urgent']), [
|
||||
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, only_show=['visible']), [
|
||||
{'contents': '2: w2', 'highlight_groups': ['w_visible', 'workspace']},
|
||||
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, only_show=['visible'], strip=3), [
|
||||
{'contents': 'w2', 'highlight_groups': ['w_visible', 'workspace']},
|
||||
{'contents': 'w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': 'w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
|
||||
])
|
||||
|
||||
def test_mode(self):
|
||||
pl = Pl()
|
||||
self.assertEqual(i3wm.mode(pl=pl, segment_info={'mode': 'default'}), None)
|
||||
self.assertEqual(i3wm.mode(pl=pl, segment_info={'mode': 'test'}), 'test')
|
||||
self.assertEqual(i3wm.mode(pl=pl, segment_info={'mode': 'default'}, names={'default': 'test'}), 'test')
|
||||
self.assertEqual(i3wm.mode(pl=pl, segment_info={'mode': 'test'}, names={'default': 'test', 'test': 't'}), 't')
|
||||
|
||||
|
||||
class TestMail(TestCommon):
|
||||
module_name = 'mail'
|
||||
|
||||
|
@ -1191,6 +1234,18 @@ class TestVim(TestCase):
|
|||
self.assertEqual(self.vim.tabnr(pl=pl, segment_info=segment_info, show_current=True), '1')
|
||||
self.assertEqual(self.vim.tabnr(pl=pl, segment_info=segment_info, show_current=False), None)
|
||||
|
||||
def test_tab(self):
|
||||
pl = Pl()
|
||||
segment_info = vim_module._get_segment_info()
|
||||
self.assertEqual(self.vim.tab(pl=pl, segment_info=segment_info), [{
|
||||
'contents': None,
|
||||
'literal_contents': (0, '%1T'),
|
||||
}])
|
||||
self.assertEqual(self.vim.tab(pl=pl, segment_info=segment_info, end=True), [{
|
||||
'contents': None,
|
||||
'literal_contents': (0, '%T'),
|
||||
}])
|
||||
|
||||
def test_bufnr(self):
|
||||
pl = Pl()
|
||||
segment_info = vim_module._get_segment_info()
|
||||
|
|
|
@ -188,6 +188,7 @@ ln -s "$(which mktemp)" tests/shell/path
|
|||
ln -s "$(which grep)" tests/shell/path
|
||||
ln -s "$(which sed)" tests/shell/path
|
||||
ln -s "$(which rm)" tests/shell/path
|
||||
ln -s "$(which tr)" tests/shell/path
|
||||
ln -s "$(which uname)" tests/shell/path
|
||||
ln -s "$(which test)" tests/shell/path
|
||||
ln -s "$(which pwd)" tests/shell/path
|
||||
|
|
|
@ -16,7 +16,7 @@ catch
|
|||
cquit
|
||||
endtry
|
||||
|
||||
if result isnot# '%#Pl_247_10395294_236_3158064_NONE# 1 ./abc 2 ./def %#Pl_236_3158064_240_5789784_NONE# %#Pl_250_12369084_240_5789784_NONE#3 ./%#Pl_231_16777215_240_5789784_bold#ghi %#Pl_240_5789784_236_3158064_NONE# %#Pl_231_16777215_236_3158064_NONE# %#Pl_252_13684944_236_3158064_NONE# %#Pl_235_2500134_252_13684944_bold# Tabs '
|
||||
if result isnot# '%1T%#Pl_247_10395294_236_3158064_NONE# 1 ./abc %2T2 ./def %#Pl_236_3158064_240_5789784_NONE# %3T%#Pl_250_12369084_240_5789784_NONE#3 ./%#Pl_231_16777215_240_5789784_bold#ghi %#Pl_240_5789784_236_3158064_NONE# %T%#Pl_231_16777215_236_3158064_NONE# %#Pl_252_13684944_236_3158064_NONE# %#Pl_235_2500134_252_13684944_bold# Tabs '
|
||||
call writefile(['Unexpected tabline', result], 'message.fail')
|
||||
cquit
|
||||
endif
|
||||
|
@ -30,7 +30,7 @@ catch
|
|||
cquit
|
||||
endtry
|
||||
|
||||
if result isnot# '%#Pl_247_10395294_236_3158064_NONE# 1 ./abc 2 ./def %#Pl_236_3158064_240_5789784_NONE# %#Pl_250_12369084_240_5789784_NONE#3 ./%#Pl_231_16777215_240_5789784_bold#ghi %#Pl_240_5789784_236_3158064_NONE# %#Pl_231_16777215_236_3158064_NONE# %#Pl_252_13684944_236_3158064_NONE# %#Pl_235_2500134_252_13684944_bold# Bufs '
|
||||
if result isnot# '%T%#Pl_247_10395294_236_3158064_NONE# 1 ./abc 2 ./def %#Pl_236_3158064_240_5789784_NONE# %#Pl_250_12369084_240_5789784_NONE#3 ./%#Pl_231_16777215_240_5789784_bold#ghi %#Pl_240_5789784_236_3158064_NONE# %#Pl_231_16777215_236_3158064_NONE# %#Pl_252_13684944_236_3158064_NONE# %#Pl_235_2500134_252_13684944_bold# Bufs '
|
||||
call writefile(['Unexpected tabline (2)', result], 'message.fail')
|
||||
cquit
|
||||
endif
|
||||
|
@ -42,7 +42,7 @@ catch
|
|||
call writefile(['Exception while evaluating &tabline (3)', v:exception], 'message.fail')
|
||||
endtry
|
||||
|
||||
if result isnot# '%#Pl_247_10395294_236_3158064_NONE# 1 ./abc 2 ./def %#Pl_236_3158064_240_5789784_NONE# %#Pl_250_12369084_240_5789784_NONE#3 ./%#Pl_231_16777215_240_5789784_bold#ghi %#Pl_240_5789784_236_3158064_NONE# %#Pl_231_16777215_236_3158064_NONE# %#Pl_252_13684944_236_3158064_NONE# %#Pl_235_2500134_252_13684944_bold# Bufs '
|
||||
if result isnot# '%T%#Pl_247_10395294_236_3158064_NONE# 1 ./abc 2 ./def %#Pl_236_3158064_240_5789784_NONE# %#Pl_250_12369084_240_5789784_NONE#3 ./%#Pl_231_16777215_240_5789784_bold#ghi %#Pl_240_5789784_236_3158064_NONE# %#Pl_231_16777215_236_3158064_NONE# %#Pl_252_13684944_236_3158064_NONE# %#Pl_235_2500134_252_13684944_bold# Bufs '
|
||||
call writefile(['Unexpected tabline (3)', result], 'message.fail')
|
||||
cquit
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import argparse
|
||||
|
||||
from getpass import getpass
|
||||
|
||||
from github import Github
|
||||
|
||||
|
||||
p = argparse.ArgumentParser(description='Powerline release script')
|
||||
p.add_argument('-u', '--user', type=str, metavar='USER', help='Github username.', required=True)
|
||||
p.add_argument('-p', '--password', type=str, metavar='PASS', help='Github password. You will be prompted if it is not supplied.')
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = p.parse_args()
|
||||
user = args.user
|
||||
password = args.password or getpass('Password for {0}: '.format(user))
|
||||
gh = Github(user, password)
|
||||
grepo = gh.get_repo('powerline/powerline')
|
||||
for pr in grepo.get_pulls():
|
||||
if pr.base.ref != 'develop':
|
||||
issue = grepo.get_issue(pr.number)
|
||||
issue.create_comment('PRs to any branch, but develop, are not accepted.', )
|
||||
issue.add_to_labels('s:invalid')
|
||||
issue.edit(state='closed')
|
Loading…
Reference in New Issue