mirror of
https://github.com/powerline/powerline.git
synced 2025-04-08 19:25:04 +02:00
Release 2.8.3
This commit is contained in:
parent
c86faf23cd
commit
8b07f63961
@ -54,7 +54,7 @@ Generic requirements
|
||||
Pip installation
|
||||
================
|
||||
|
||||
Due to a naming conflict with an unrelated project powerline is available on
|
||||
Due to a naming conflict with an unrelated project, powerline is available on
|
||||
PyPI under the ``powerline-status`` name:
|
||||
|
||||
.. code-block:: sh
|
||||
@ -66,7 +66,7 @@ development version
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
pip install --user git+git://github.com/powerline/powerline
|
||||
pip install --user git+https://github.com/powerline/powerline
|
||||
|
||||
may be used. If powerline was already checked out into some directory
|
||||
|
||||
@ -85,10 +85,9 @@ will have to be done (:file:`~/.local/bin` should be replaced with some path
|
||||
present in ``$PATH``).
|
||||
|
||||
.. note::
|
||||
If ISP blocks git protocol for some reason github also provides ``ssh``
|
||||
(``git+ssh://git@github.com/powerline/powerline``) and ``https``
|
||||
(``git+https://github.com/powerline/powerline``) protocols. ``git`` protocol
|
||||
should be the fastest, but least secure one though.
|
||||
We can use either ``https``(``git+ssh://git@github.com/powerline/powerline``)
|
||||
or ``https``(``git+https://github.com/powerline/powerline``) protocols.
|
||||
``git`` protocol is deprecated by Github.
|
||||
|
||||
Fonts installation
|
||||
==================
|
||||
|
@ -29,7 +29,7 @@ should be followed:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
pip install --user git+git://github.com/powerline/powerline
|
||||
pip install --user git+https://github.com/powerline/powerline
|
||||
|
||||
will get the latest development version.
|
||||
|
||||
|
@ -16,9 +16,13 @@ Python package
|
||||
brew install python
|
||||
|
||||
.. note::
|
||||
In case :file:`powerline.sh` as a client ``socat`` and ``coreutils`` need
|
||||
to be installed. ``coreutils`` may be installed using ``brew install
|
||||
coreutils``.
|
||||
There are three variants of the powerline client. The fastest is
|
||||
written in C and will be compiled if the compiler and libraries are
|
||||
detected during installation. The second fastest option is
|
||||
:file:`powerline.sh` which requires ``socat`` and ``coreutils``.
|
||||
``coreutils`` may be installed using ``brew install
|
||||
coreutils``. If neither of these are viable, then Powerline will
|
||||
utilize a fallback client written in Python.
|
||||
|
||||
2. Install Powerline using one of the following commands:
|
||||
|
||||
@ -30,7 +34,7 @@ Python package
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
pip install --user git+git://github.com/powerline/powerline
|
||||
pip install --user git+https://github.com/powerline/powerline
|
||||
|
||||
will get latest development version.
|
||||
|
||||
|
@ -193,8 +193,12 @@ I am suffering bad lags before displaying shell prompt
|
||||
To get rid of these lags there currently are two options:
|
||||
|
||||
* Run ``powerline-daemon``. Powerline does not automatically start it for you.
|
||||
See installation instructions for more details.
|
||||
* Compile and install ``libzpython`` module that lives in
|
||||
https://bitbucket.org/ZyX_I/zpython. This variant is zsh-specific.
|
||||
* If you are a python package manager, be sure to set ``POWERLINE_COMMAND``
|
||||
to your Powerline command. See installation instructions for details.
|
||||
|
||||
|
||||
Prompt is spoiled after completing files in ksh
|
||||
-----------------------------------------------
|
||||
|
@ -5,8 +5,9 @@ Shell prompts
|
||||
*************
|
||||
|
||||
.. note::
|
||||
Powerline daemon is not run automatically by any of my bindings. It is
|
||||
advised to add
|
||||
Powerline can operate without a background daemon, but the shell performance
|
||||
can be very slow. The Powerline daemon improves this performance
|
||||
significantly, but must be started separately. It is advised to add
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@ -142,3 +143,19 @@ following in ``~/.profile``:
|
||||
.. warning::
|
||||
Busybox has two shells: ``ash`` and ``hush``. Second is known to segfault in
|
||||
busybox 1.22.1 when using :file:`powerline.sh` script.
|
||||
|
||||
Python Virtual Environments (conda, pyenv)
|
||||
==========================================
|
||||
|
||||
If your system uses virtual environments to manage different Python versions,
|
||||
such as pyenv or anaconda, these tools will add a performance delay to every
|
||||
shell prompt. This delay can be bypassed by explicitly specifying your command
|
||||
path.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
export POWERLINE_COMMAND={path_to_powerline}
|
||||
|
||||
where ``{path_to_powerline}`` is the full filepath for powerline. If you
|
||||
installed Powerline within an environment, you can find this path for pyenv
|
||||
with ``pyenv which powerline`` or for conda with ``which powerline``.
|
||||
|
@ -1,14 +1,13 @@
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
from weakref import ref
|
||||
from atexit import register as atexit
|
||||
|
||||
from IPython.terminal.prompts import Prompts
|
||||
from pygments.token import Token # NOQA
|
||||
|
||||
from powerline.ipython import IPythonPowerline
|
||||
from powerline.renderers.ipython.since_7 import PowerlinePromptStyle
|
||||
from powerline.bindings.ipython.post_0_11 import PowerlineMagics, ShutdownHook
|
||||
from powerline.bindings.ipython.post_0_11 import PowerlineMagics
|
||||
|
||||
|
||||
class ConfigurableIPythonPowerline(IPythonPowerline):
|
||||
@ -20,7 +19,7 @@ class ConfigurableIPythonPowerline(IPythonPowerline):
|
||||
super(ConfigurableIPythonPowerline, self).init(
|
||||
renderer_module='.since_7')
|
||||
|
||||
def do_setup(self, ip, prompts, shutdown_hook):
|
||||
def do_setup(self, ip, prompts):
|
||||
prompts.powerline = self
|
||||
|
||||
msfn_missing = ()
|
||||
@ -50,18 +49,16 @@ class ConfigurableIPythonPowerline(IPythonPowerline):
|
||||
magics = PowerlineMagics(ip, self)
|
||||
ip.register_magics(magics)
|
||||
|
||||
if shutdown_hook:
|
||||
shutdown_hook.powerline = ref(self)
|
||||
atexit(self.shutdown)
|
||||
|
||||
|
||||
class PowerlinePrompts(Prompts):
|
||||
'''Class that returns powerline prompts
|
||||
'''
|
||||
def __init__(self, shell):
|
||||
shutdown_hook = ShutdownHook(shell)
|
||||
powerline = ConfigurableIPythonPowerline(shell)
|
||||
self.shell = shell
|
||||
powerline.do_setup(shell, self, shutdown_hook)
|
||||
powerline.do_setup(shell, self)
|
||||
self.last_output_count = None
|
||||
self.last_output = {}
|
||||
|
||||
|
@ -197,7 +197,7 @@ _powerline_add_widget() {
|
||||
}
|
||||
|
||||
if test -z "${POWERLINE_CONFIG_COMMAND}" ; then
|
||||
if which powerline-config >/dev/null ; then
|
||||
if which powerline-config >/dev/null 2>/dev/null ; then
|
||||
typeset -g POWERLINE_CONFIG_COMMAND=powerline-config
|
||||
else
|
||||
typeset -g POWERLINE_CONFIG_COMMAND="${_POWERLINE_SOURCED:h:h:h:h}/scripts/powerline-config"
|
||||
|
@ -51,6 +51,7 @@
|
||||
"cwd:current_folder": "information:regular",
|
||||
"cwd:divider": { "fg": "gray7", "bg": "gray4", "attrs": [] },
|
||||
"virtualenv": { "fg": "white", "bg": "darkcyan", "attrs": [] },
|
||||
"attached_clients": { "fg": "gray8", "bg": "gray0", "attrs": [] }
|
||||
"attached_clients": { "fg": "gray8", "bg": "gray0", "attrs": [] },
|
||||
"workspace": "information:regular"
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
{
|
||||
"segments": {
|
||||
"right": [
|
||||
{
|
||||
"function": "powerline.segments.common.wthr.weather",
|
||||
"priority": 50
|
||||
},
|
||||
{
|
||||
"function": "powerline.segments.common.time.date"
|
||||
},
|
||||
@ -15,14 +11,6 @@
|
||||
"format": "%H:%M",
|
||||
"istime": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "powerline.segments.common.mail.email_imap_alert",
|
||||
"priority": 10,
|
||||
"args": {
|
||||
"username": "",
|
||||
"password": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ class BaseConstructor:
|
||||
mapping = {}
|
||||
for key_node, value_node in node.value:
|
||||
key = self.construct_object(key_node, deep=deep)
|
||||
if not isinstance(key, collections.Hashable):
|
||||
if not isinstance(key, collections.abc.Hashable):
|
||||
self.echoerr(
|
||||
'While constructing a mapping', node.start_mark,
|
||||
'found unhashable key', key_node.start_mark
|
||||
|
@ -26,20 +26,20 @@ def output_lister(pl, segment_info):
|
||||
def workspace_lister(pl, segment_info, only_show=None, output=None):
|
||||
'''List all workspaces in segment_info format
|
||||
|
||||
Sets the segment info values of ``workspace`` and ``output`` to the name of
|
||||
Sets the segment info values of ``workspace`` and ``output`` to the name of
|
||||
the i3 workspace and the ``xrandr`` output respectively and the keys
|
||||
``"visible"``, ``"urgent"`` and ``"focused"`` to a boolean indicating these
|
||||
states.
|
||||
|
||||
:param list only_show:
|
||||
Specifies which workspaces to list. Valid entries are ``"visible"``,
|
||||
``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces
|
||||
Specifies which workspaces to list. Valid entries are ``"visible"``,
|
||||
``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces
|
||||
are listed.
|
||||
|
||||
:param str output:
|
||||
May be set to the name of an X output. If specified, only workspaces
|
||||
on that output are listed. Overrides automatic output detection by
|
||||
the lemonbar renderer and bindings. Set to ``false`` to force
|
||||
May be set to the name of an X output. If specified, only workspaces
|
||||
on that output are listed. Overrides automatic output detection by
|
||||
the lemonbar renderer and bindings. Set to ``false`` to force
|
||||
all workspaces to be shown.
|
||||
'''
|
||||
|
||||
|
@ -6,17 +6,18 @@ import re
|
||||
from powerline.theme import requires_segment_info
|
||||
from powerline.bindings.wm import get_i3_connection
|
||||
|
||||
|
||||
WORKSPACE_REGEX = re.compile(r'^[0-9]+: ?')
|
||||
|
||||
|
||||
def workspace_groups(w):
|
||||
group = []
|
||||
if w.focused:
|
||||
group.append('workspace:focused')
|
||||
group.append('w_focused')
|
||||
if w.urgent:
|
||||
group.append('workspace:urgent')
|
||||
group.append('w_urgent')
|
||||
if w.visible:
|
||||
group.append('workspace:visible')
|
||||
group.append('w_visible')
|
||||
group.append('workspace')
|
||||
return group
|
||||
@ -28,58 +29,191 @@ def format_name(name, strip=False):
|
||||
return name
|
||||
|
||||
|
||||
def is_empty_workspace(workspace, containers):
|
||||
if workspace.focused or workspace.visible:
|
||||
return False
|
||||
wins = [win for win in containers[workspace.name].leaves()]
|
||||
return False if len(wins) > 0 else True
|
||||
|
||||
WS_ICONS = {"multiple": "M"}
|
||||
|
||||
def get_icon(workspace, separator, icons, show_multiple_icons, ws_containers):
|
||||
icons_tmp = WS_ICONS
|
||||
icons_tmp.update(icons)
|
||||
icons = icons_tmp
|
||||
|
||||
wins = [win for win in ws_containers[workspace.name].leaves() \
|
||||
if win.parent.scratchpad_state == 'none']
|
||||
if len(wins) == 0:
|
||||
return ''
|
||||
|
||||
result = ''
|
||||
cnt = 0
|
||||
for key in icons:
|
||||
if not icons[key] or len(icons[key]) < 1:
|
||||
continue
|
||||
if any(key in win.window_class for win in wins if win.window_class):
|
||||
result += (separator if cnt > 0 else '') + icons[key]
|
||||
cnt += 1
|
||||
if not show_multiple_icons and cnt > 1:
|
||||
if 'multiple' in icons:
|
||||
return icons['multiple']
|
||||
else:
|
||||
return ''
|
||||
return result
|
||||
|
||||
@requires_segment_info
|
||||
def workspaces(pl, segment_info, only_show=None, output=None, strip=0):
|
||||
def workspaces(pl, segment_info, only_show=None, output=None, strip=0, format='{name}',
|
||||
icons=WS_ICONS, sort_workspaces=False, show_output=False, priority_workspaces=[],
|
||||
hide_empty_workspaces=False):
|
||||
'''Return list of used workspaces
|
||||
|
||||
:param list only_show:
|
||||
Specifies which workspaces to show. Valid entries are ``"visible"``,
|
||||
``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces
|
||||
Specifies which workspaces to show. Valid entries are ``"visible"``,
|
||||
``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces
|
||||
are shown.
|
||||
|
||||
:param str output:
|
||||
May be set to the name of an X output. If specified, only workspaces
|
||||
on that output are shown. Overrides automatic output detection by
|
||||
May be set to the name of an X output. If specified, only workspaces
|
||||
on that output are shown. Overrides automatic output detection by
|
||||
the lemonbar renderer and bindings.
|
||||
|
||||
Use "__all__" to show workspaces on all outputs.
|
||||
:param int strip:
|
||||
Specifies how many characters from the front of each workspace name
|
||||
Specifies how many characters from the front of each workspace name
|
||||
should be stripped (e.g. to remove workspace numbers). Defaults to zero.
|
||||
:param str format:
|
||||
Specifies the format used to display workspaces; defaults to ``{name}``.
|
||||
Valid fields are: ``name`` (workspace name), ``number`` (workspace number
|
||||
if present), `stipped_name`` (workspace name stripped of leading number),
|
||||
``icon`` (if available, icon for application running in the workspace,
|
||||
uses the ``multiple`` icon instead of multiple different icons), ``multi_icon``
|
||||
(similar to ``icon``, but does not use ``multiple``, instead joins all icons
|
||||
with a single space)
|
||||
:param dict icons:
|
||||
A dictionary mapping a substring of window classes to strings to be used as an
|
||||
icon for that window class.
|
||||
Further, there is a ``multiple`` icon for workspaces containing more than one
|
||||
window.
|
||||
:param bool sort_workspaces:
|
||||
Sort the workspaces displayed by their name according to the natural ordering.
|
||||
:param bool show_output:
|
||||
Shows the name of the output if more than one output is connected.
|
||||
:param list priority_workspaces:
|
||||
A list of workspace names to be sorted before any other workspaces in the given
|
||||
order.
|
||||
:param bool hide_empty_workspaces:
|
||||
Hides all workspaces without any open window.
|
||||
Also hides non-focussed workspaces containing only an open scratchpad.
|
||||
|
||||
Highlight groups used: ``workspace`` or ``w_visible``, ``workspace`` or ``w_focused``, ``workspace`` or ``w_urgent``.
|
||||
|
||||
Highlight groups used: ``workspace`` or ``w_visible``, ``workspace:visible``, ``workspace`` or ``w_focused``, ``workspace:focused``, ``workspace`` or ``w_urgent``, ``workspace:urgent``, ``workspace`` or ``output``.
|
||||
'''
|
||||
output = output or segment_info.get('output')
|
||||
conn = get_i3_connection()
|
||||
|
||||
return [
|
||||
{
|
||||
'contents': w.name[strip:],
|
||||
if not output == "__all__":
|
||||
output = output or segment_info.get('output')
|
||||
else:
|
||||
output = None
|
||||
|
||||
if output:
|
||||
output = [output]
|
||||
else:
|
||||
output = [o.name for o in conn.get_outputs() if o.active]
|
||||
|
||||
|
||||
def sort_ws(ws):
|
||||
if sort_workspaces:
|
||||
def natural_key(ws):
|
||||
str = ws.name
|
||||
return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', str)]
|
||||
ws = sorted(ws, key=natural_key)
|
||||
result = []
|
||||
for n in priority_workspaces:
|
||||
result += [w for w in ws if w.name == n]
|
||||
return result + [w for w in ws if not w.name in priority_workspaces]
|
||||
|
||||
ws_containers = {w_con.name : w_con for w_con in conn.get_tree().workspaces()}
|
||||
|
||||
if len(output) <= 1:
|
||||
res = []
|
||||
if show_output:
|
||||
res += [{
|
||||
'contents': output[0],
|
||||
'highlight_groups': ['output']
|
||||
}]
|
||||
res += [{
|
||||
'contents': format.format(name = w.name[min(len(w.name), strip):],
|
||||
stripped_name = format_name(w.name, strip=True),
|
||||
number = w.num,
|
||||
icon = get_icon(w, '', icons, False, ws_containers),
|
||||
multi_icon = get_icon(w, ' ', icons, True, ws_containers)),
|
||||
'highlight_groups': workspace_groups(w)
|
||||
}
|
||||
for w in get_i3_connection().get_workspaces()
|
||||
if ((not only_show or any(getattr(w, typ) for typ in only_show))
|
||||
and (not output or w.output == output))
|
||||
]
|
||||
|
||||
} for w in sort_ws(conn.get_workspaces()) \
|
||||
if (not only_show or any(getattr(w, tp) for tp in only_show)) \
|
||||
if w.output == output[0] \
|
||||
if not (hide_empty_workspaces and is_empty_workspace(w, ws_containers))]
|
||||
return res
|
||||
else:
|
||||
res = []
|
||||
for n in output:
|
||||
if show_output:
|
||||
res += [{
|
||||
'contents': n,
|
||||
'highlight_groups': ['output']
|
||||
}]
|
||||
res += [{
|
||||
'contents': format.format(name = w.name[min(len(w.name), strip):],
|
||||
stripped_name = format_name(w.name, strip=True),
|
||||
number = w.num,
|
||||
icon = get_icon(w, '', icons, False, ws_containers),
|
||||
multi_icon = get_icon(w, ' ', icons, True, ws_containers)),
|
||||
'highlight_groups': workspace_groups(w)
|
||||
} for w in sort_ws(conn.get_workspaces()) \
|
||||
if (not only_show or any(getattr(w, tp) for tp in only_show)) \
|
||||
if w.output == n \
|
||||
if not (hide_empty_workspaces and is_empty_workspace(w, ws_containers))]
|
||||
return res
|
||||
|
||||
@requires_segment_info
|
||||
def workspace(pl, segment_info, workspace=None, strip=False):
|
||||
def workspace(pl, segment_info, workspace=None, strip=False, format=None, icons=WS_ICONS):
|
||||
'''Return the specified workspace name
|
||||
|
||||
:param str workspace:
|
||||
Specifies which workspace to show. If unspecified, may be set by the
|
||||
``list_workspaces`` lister if used, otherwise falls back to
|
||||
Specifies which workspace to show. If unspecified, may be set by the
|
||||
``list_workspaces`` lister if used, otherwise falls back to
|
||||
currently focused workspace.
|
||||
|
||||
:param bool strip:
|
||||
Specifies whether workspace numbers (in the ``1: name`` format) should
|
||||
Specifies whether workspace numbers (in the ``1: name`` format) should
|
||||
be stripped from workspace names before being displayed. Defaults to false.
|
||||
Deprecated: Use {name} or {stripped_name} of format instead.
|
||||
|
||||
Highlight groups used: ``workspace`` or ``w_visible``, ``workspace`` or ``w_focused``, ``workspace`` or ``w_urgent``.
|
||||
:param str format:
|
||||
Specifies the format used to display workspaces; defaults to ``{name}``.
|
||||
Valid fields are: ``name`` (workspace name), ``number`` (workspace number
|
||||
if present), `stipped_name`` (workspace name stripped of leading number),
|
||||
``icon`` (if available, icon for application running in the workspace,
|
||||
uses the ``multiple`` icon instead of multiple different icons), ``multi_icon``
|
||||
(similar to ``icon``, but does not use ``multiple``, instead joins all icons
|
||||
with a single space)
|
||||
|
||||
:param dict icons:
|
||||
A dictionary mapping a substring of window classes to strings to be used as an
|
||||
icon for that window class.
|
||||
Further, there is a ``multiple`` icon for workspaces containing more than one
|
||||
window.
|
||||
|
||||
Highlight groups used: ``workspace`` or ``w_visible``, ``workspace:visible``, ``workspace`` or ``w_focused``, ``workspace:focused``, ``workspace`` or ``w_urgent``, ``workspace:urgent``, ``workspace``.
|
||||
'''
|
||||
if format == None:
|
||||
format = '{stripped_name}' if strip else '{name}'
|
||||
|
||||
conn = get_i3_connection()
|
||||
ws_containers = {w_con.name : w_con for w_con in conn.get_tree().workspaces()}
|
||||
|
||||
if workspace:
|
||||
try:
|
||||
w = next((
|
||||
w for w in get_i3_connection().get_workspaces()
|
||||
w for w in conn.get_workspaces()
|
||||
if w.name == workspace
|
||||
))
|
||||
except StopIteration:
|
||||
@ -89,16 +223,20 @@ def workspace(pl, segment_info, workspace=None, strip=False):
|
||||
else:
|
||||
try:
|
||||
w = next((
|
||||
w for w in get_i3_connection().get_workspaces()
|
||||
w for w in conn.get_workspaces()
|
||||
if w.focused
|
||||
))
|
||||
except StopIteration:
|
||||
return None
|
||||
|
||||
return [{
|
||||
'contents': format_name(w.name, strip=strip),
|
||||
'contents': format.format(name = w.name,
|
||||
stripped_name = format_name(w.name, strip=True),
|
||||
number = w.num,
|
||||
icon = get_icon(w, '', icons, False, ws_containers),
|
||||
multi_icon = get_icon(w, ' ', icons, True, ws_containers)),
|
||||
'highlight_groups': workspace_groups(w)
|
||||
}]
|
||||
}]
|
||||
|
||||
|
||||
@requires_segment_info
|
||||
@ -139,7 +277,7 @@ def scratchpad(pl, icons=SCRATCHPAD_ICONS):
|
||||
'''Returns the windows currently on the scratchpad
|
||||
|
||||
:param dict icons:
|
||||
Specifies the strings to show for the different scratchpad window states. Must
|
||||
Specifies the strings to show for the different scratchpad window states. Must
|
||||
contain the keys ``fresh`` and ``changed``.
|
||||
|
||||
Highlight groups used: ``scratchpad`` or ``scratchpad:visible``, ``scratchpad`` or ``scratchpad:focused``, ``scratchpad`` or ``scratchpad:urgent``.
|
||||
@ -153,3 +291,19 @@ def scratchpad(pl, icons=SCRATCHPAD_ICONS):
|
||||
for w in get_i3_connection().get_tree().descendants()
|
||||
if w.scratchpad_state != 'none'
|
||||
]
|
||||
|
||||
def active_window(pl, cutoff=100):
|
||||
'''Returns the title of the currently active window.
|
||||
|
||||
:param int cutoff:
|
||||
Maximum title length. If the title is longer, the window_class is used instead.
|
||||
|
||||
Highlight groups used: ``active_window_title``.
|
||||
'''
|
||||
|
||||
focused = get_i3_connection().get_tree().find_focused()
|
||||
cont = focused.name
|
||||
if len(cont) > cutoff:
|
||||
cont = focused.window_class
|
||||
|
||||
return [{'contents': cont, 'highlight_groups': ['active_window_title']}] if focused.name != focused.workspace().name else []
|
||||
|
@ -1,10 +1,7 @@
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import subprocess
|
||||
from traceback import print_exc
|
||||
|
||||
__version__ = "2.8.2"
|
||||
__version__ = "2.8.3"
|
||||
|
||||
def get_version():
|
||||
return __version__
|
||||
|
@ -33,6 +33,7 @@ class PowerlineDummyTest(object):
|
||||
class PowerlineTestSuite(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.suite = ''
|
||||
|
||||
def __enter__(self):
|
||||
self.saved_current_suite = os.environ['POWERLINE_CURRENT_SUITE']
|
||||
|
@ -1001,81 +1001,158 @@ class TestWthr(TestCommon):
|
||||
|
||||
|
||||
class TestI3WM(TestCase):
|
||||
@staticmethod
|
||||
def get_workspaces():
|
||||
return iter([
|
||||
Args(name='1: w1', output='LVDS1', focused = False, urgent = False, visible = False),
|
||||
Args(name='2: w2', output='LVDS1', focused = False, urgent = False, visible = True),
|
||||
Args(name='3: w3', output='HDMI1', focused = False, urgent = True, visible = True),
|
||||
Args(name='4: w4', output='DVI01', focused = True, urgent = True, visible = True),
|
||||
])
|
||||
|
||||
def test_workspaces(self):
|
||||
class Conn(object):
|
||||
def get_tree(self):
|
||||
return self
|
||||
|
||||
def descendents(self):
|
||||
nodes_unfocused = [Args(focused = False)]
|
||||
nodes_focused = [Args(focused = True)]
|
||||
|
||||
workspace_scratch = lambda: Args(name='__i3_scratch')
|
||||
workspace_noscratch = lambda: Args(name='2: w2')
|
||||
return [
|
||||
Args(scratchpad_state='fresh', urgent=False, workspace=workspace_scratch, nodes=nodes_unfocused),
|
||||
Args(scratchpad_state='changed', urgent=True, workspace=workspace_noscratch, nodes=nodes_focused),
|
||||
Args(scratchpad_state='fresh', urgent=False, workspace=workspace_scratch, nodes=nodes_unfocused),
|
||||
Args(scratchpad_state=None, urgent=False, workspace=workspace_noscratch, nodes=nodes_unfocused),
|
||||
Args(scratchpad_state='fresh', urgent=False, workspace=workspace_scratch, nodes=nodes_focused),
|
||||
Args(scratchpad_state=None, urgent=True, workspace=workspace_noscratch, nodes=nodes_unfocused),
|
||||
]
|
||||
|
||||
def workspaces(self):
|
||||
return iter([
|
||||
Args(name='1: w1', output='LVDS1', focused=False, urgent=False, visible=False, num=1, leaves=lambda: []),
|
||||
Args(name='2: w2', output='LVDS1', focused=False, urgent=False, visible=True, num=2, leaves=lambda: []),
|
||||
Args(name='3: w3', output='HDMI1', focused=False, urgent=True, visible=True, num=3, leaves=lambda: []),
|
||||
Args(name='4: w4', output='DVI01', focused=True, urgent=True, visible=True, num=None, leaves=lambda: [])
|
||||
])
|
||||
|
||||
def get_workspaces(self):
|
||||
return iter([
|
||||
Args(name='1: w1', output='LVDS1', focused=False, urgent=False, visible=False, num=1, leaves=lambda: []),
|
||||
Args(name='2: w2', output='LVDS1', focused=False, urgent=False, visible=True, num=2, leaves=lambda: []),
|
||||
Args(name='3: w3', output='HDMI1', focused=False, urgent=True, visible=True, num=3, leaves=lambda: []),
|
||||
Args(name='4: w4', output='DVI01', focused=True, urgent=True, visible=True, num=None, leaves=lambda: [])
|
||||
])
|
||||
|
||||
def get_outputs(self):
|
||||
return iter([
|
||||
Args(name='LVDS1', active=True),
|
||||
Args(name='HDMI1', active=True),
|
||||
Args(name='DVI01', active=True),
|
||||
Args(name='HDMI2', active=False),
|
||||
])
|
||||
|
||||
pl = Pl()
|
||||
with replace_attr(i3wm, 'get_i3_connection', lambda: Args(get_workspaces=self.get_workspaces)):
|
||||
with replace_attr(i3wm, 'get_i3_connection', lambda: Conn()):
|
||||
segment_info = {}
|
||||
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info), [
|
||||
{'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']},
|
||||
{'contents': '2: w2', 'highlight_groups': ['workspace:visible', 'w_visible', 'workspace']},
|
||||
{'contents': '3: w3', 'highlight_groups': ['workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['workspace:focused', 'w_focused', 'workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, 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']},
|
||||
{'contents': '2: w2', 'highlight_groups': ['workspace:visible', 'w_visible', 'workspace']},
|
||||
{'contents': '3: w3', 'highlight_groups': ['workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['workspace:focused', 'w_focused', 'workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, 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']},
|
||||
{'contents': '3: w3', 'highlight_groups': ['workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['workspace:focused', 'w_focused', 'workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, 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']},
|
||||
{'contents': '2: w2', 'highlight_groups': ['workspace:visible', 'w_visible', 'workspace']},
|
||||
{'contents': '3: w3', 'highlight_groups': ['workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['workspace:focused', 'w_focused', 'workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, 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']},
|
||||
{'contents': 'w2', 'highlight_groups': ['workspace:visible', 'w_visible', 'workspace']},
|
||||
{'contents': 'w3', 'highlight_groups': ['workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
{'contents': 'w4', 'highlight_groups': ['workspace:focused', 'w_focused', 'workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['focused', 'urgent'], output='DVI01'), [
|
||||
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['workspace:focused', 'w_focused', 'workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible'], output='HDMI1'), [
|
||||
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': '3: w3', 'highlight_groups': ['workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible'], strip=3, output='LVDS1'), [
|
||||
{'contents': 'w2', 'highlight_groups': ['w_visible', 'workspace']},
|
||||
{'contents': 'w2', 'highlight_groups': ['workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
segment_info['output'] = 'LVDS1'
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible'], output='HDMI1'), [
|
||||
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': '3: w3', 'highlight_groups': ['workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible'], strip=3), [
|
||||
{'contents': 'w2', 'highlight_groups': ['w_visible', 'workspace']},
|
||||
{'contents': 'w2', 'highlight_groups': ['workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
|
||||
def test_workspace(self):
|
||||
class Conn(object):
|
||||
def get_tree(self):
|
||||
return self
|
||||
|
||||
def descendents(self):
|
||||
nodes_unfocused = [Args(focused = False)]
|
||||
nodes_focused = [Args(focused = True)]
|
||||
|
||||
workspace_scratch = lambda: Args(name='__i3_scratch')
|
||||
workspace_noscratch = lambda: Args(name='2: w2')
|
||||
return [
|
||||
Args(scratchpad_state='fresh', urgent=False, workspace=workspace_scratch, nodes=nodes_unfocused),
|
||||
Args(scratchpad_state='changed', urgent=True, workspace=workspace_noscratch, nodes=nodes_focused),
|
||||
Args(scratchpad_state='fresh', urgent=False, workspace=workspace_scratch, nodes=nodes_unfocused),
|
||||
Args(scratchpad_state=None, urgent=False, workspace=workspace_noscratch, nodes=nodes_unfocused),
|
||||
Args(scratchpad_state='fresh', urgent=False, workspace=workspace_scratch, nodes=nodes_focused),
|
||||
Args(scratchpad_state=None, urgent=True, workspace=workspace_noscratch, nodes=nodes_unfocused),
|
||||
]
|
||||
|
||||
def workspaces(self):
|
||||
return iter([
|
||||
Args(name='1: w1', output='LVDS1', focused=False, urgent=False, visible=False, num=1, leaves=lambda: []),
|
||||
Args(name='2: w2', output='LVDS1', focused=False, urgent=False, visible=True, num=2, leaves=lambda: []),
|
||||
Args(name='3: w3', output='HDMI1', focused=False, urgent=True, visible=True, num=3, leaves=lambda: []),
|
||||
Args(name='4: w4', output='DVI01', focused=True, urgent=True, visible=True, num=None, leaves=lambda: [])
|
||||
])
|
||||
|
||||
def get_workspaces(self):
|
||||
return iter([
|
||||
Args(name='1: w1', output='LVDS1', focused=False, urgent=False, visible=False, num=1, leaves=lambda: []),
|
||||
Args(name='2: w2', output='LVDS1', focused=False, urgent=False, visible=True, num=2, leaves=lambda: []),
|
||||
Args(name='3: w3', output='HDMI1', focused=False, urgent=True, visible=True, num=3, leaves=lambda: []),
|
||||
Args(name='4: w4', output='DVI01', focused=True, urgent=True, visible=True, num=None, leaves=lambda: [])
|
||||
])
|
||||
|
||||
def get_outputs(self):
|
||||
return iter([
|
||||
Args(name='LVDS1', active=True),
|
||||
Args(name='HDMI1', active=True),
|
||||
Args(name='DVI01', active=True),
|
||||
Args(name='HDMI2', active=False),
|
||||
])
|
||||
|
||||
pl = Pl()
|
||||
with replace_attr(i3wm, 'get_i3_connection', lambda: Args(get_workspaces=self.get_workspaces)):
|
||||
with replace_attr(i3wm, 'get_i3_connection', lambda: Conn()):
|
||||
segment_info = {}
|
||||
|
||||
self.assertEqual(i3wm.workspace(pl=pl, segment_info=segment_info, workspace='1: w1'), [
|
||||
{'contents': '1: w1', 'highlight_groups': ['workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspace(pl=pl, segment_info=segment_info, workspace='3: w3', strip=True), [
|
||||
{'contents': 'w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': 'w3', 'highlight_groups': ['workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspace(pl=pl, segment_info=segment_info, workspace='9: w9'), None)
|
||||
self.assertEqual(i3wm.workspace(pl=pl, segment_info=segment_info), [
|
||||
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['workspace:focused', 'w_focused', 'workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
segment_info['workspace'] = next(self.get_workspaces())
|
||||
segment_info['workspace'] = next(Conn().get_workspaces())
|
||||
self.assertEqual(i3wm.workspace(pl=pl, segment_info=segment_info, workspace='4: w4'), [
|
||||
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
|
||||
{'contents': '4: w4', 'highlight_groups': ['workspace:focused', 'w_focused', 'workspace:urgent', 'w_urgent', 'workspace:visible', 'w_visible', 'workspace']},
|
||||
])
|
||||
self.assertEqual(i3wm.workspace(pl=pl, segment_info=segment_info, strip=True), [
|
||||
{'contents': 'w1', 'highlight_groups': ['workspace']},
|
||||
|
Loading…
x
Reference in New Issue
Block a user