mirror of
https://github.com/powerline/powerline.git
synced 2025-04-08 19:25:04 +02:00
Release 2.8.2
This commit is contained in:
commit
1c33c4eb5a
46
.github/workflows/main.yaml
vendored
Normal file
46
.github/workflows/main.yaml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
name: Build and Publish to PyPI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/actions
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [2.7, 3.5, 3.6, 3.7, 3.8]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install setuptools wheel
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
python setup.py sdist bdist_wheel
|
||||
|
||||
- name: Publish
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
|
||||
uses: pypa/gh-action-pypi-publish@master
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.PYPI_TOKEN }}
|
||||
packages_dir: dist/
|
@ -26,8 +26,7 @@ jobs:
|
||||
- stage: Latest Python
|
||||
python: "3.6"
|
||||
- stage: Intermediate versions
|
||||
python: "3.3"
|
||||
python: "3.5"
|
||||
- python: "3.4"
|
||||
- python: "3.5"
|
||||
|
||||
# vim: et
|
||||
|
29
README.rst
29
README.rst
@ -1,24 +1,24 @@
|
||||
Powerline
|
||||
=========
|
||||
|
||||
:Author: Kim Silkebækken (kim.silkebaekken+vim@gmail.com)
|
||||
:Source: https://github.com/powerline/powerline
|
||||
:Version: beta
|
||||
.. image:: https://api.travis-ci.org/powerline/powerline.svg?branch=develop
|
||||
:target: `travis-build-status`_
|
||||
:alt: Build status
|
||||
.. _travis-build-status: https://travis-ci.org/powerline/powerline
|
||||
|
||||
**Powerline is a statusline plugin for vim, and provides statuslines and
|
||||
prompts for several other applications, including zsh, bash, fish, tmux,
|
||||
IPython, Awesome, i3 and Qtile.**
|
||||
|
||||
* `Support forum`_ (powerline-support@googlegroups.com)
|
||||
* `Development discussion`_ (powerline-dev@googlegroups.com)
|
||||
+---------+---------------------------------------------------+
|
||||
| Author | Kim Silkebækken (kim.silkebaekken+vim@gmail.com) |
|
||||
+---------+---------------------------------------------------+
|
||||
| Source | https://github.com/powerline/powerline |
|
||||
+---------+---------------------------------------------------+
|
||||
| Version | beta |
|
||||
+---------+---------------------------------------------------+
|
||||
|
||||
.. image:: https://api.travis-ci.org/powerline/powerline.svg?branch=develop
|
||||
:target: `travis-build-status`_
|
||||
:alt: Build status
|
||||
|
||||
.. _travis-build-status: https://travis-ci.org/powerline/powerline
|
||||
.. _`Support forum`: https://groups.google.com/forum/#!forum/powerline-support
|
||||
.. _`Development discussion`: https://groups.google.com/forum/#!forum/powerline-dev
|
||||
**Powerline does not support python2 anymore and powerline will stop working with python2 in the near future.**
|
||||
|
||||
Features
|
||||
--------
|
||||
@ -29,8 +29,7 @@ Features
|
||||
config files, and a structured, object-oriented codebase with no mandatory
|
||||
third-party dependencies other than a Python interpreter.
|
||||
* **Stable and testable code base.** Using Python has allowed unit testing
|
||||
of all the project code. The code is tested to work in Python 2.6+ and
|
||||
Python 3.
|
||||
of all the project code. The code is tested to work in Python 3.6+.
|
||||
* **Support for prompts and statuslines in many applications.** Originally
|
||||
created exclusively for vim statuslines, the project has evolved to
|
||||
provide statuslines in tmux and several WMs, and prompts for shells like
|
||||
@ -60,6 +59,8 @@ Configuration
|
||||
Basic powerline configuration is done via `JSON` files located at `.config/powerline/`. It is a good idea to start by copying the default configuration located at `powerline_root/powerline/config_files/` to `.config/powerline/`.
|
||||
If you installed the powerline from the AUR or via pip, `powerline_root` should be `/usr/lib/python3.6/site-packages/` or something similar, depending on your python version.
|
||||
|
||||
If you installed powerline via apt-get 'powerline_root' should be '/usr/share/powerline/'.
|
||||
|
||||
This should yield you the following directory structure:
|
||||
|
||||
::
|
||||
|
@ -117,10 +117,14 @@ segments that you may want to customize right away:
|
||||
so unless you’re on a VPN you probably won’t have to change the location
|
||||
query.
|
||||
|
||||
It is using OpenWeatherMap as a provider, which can be configured with a
|
||||
personal API key. These can be generated `here
|
||||
<https://home.openweathermap.org/api_keys>`_
|
||||
|
||||
If you want to change the location query or the temperature unit you’ll
|
||||
have to update the segment arguments. Open a theme file, scroll down to
|
||||
the weather segment and update it to include unit/location query
|
||||
arguments:
|
||||
the weather segment and update it to include unit, location query or
|
||||
api key arguments:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
@ -129,7 +133,8 @@ segments that you may want to customize right away:
|
||||
"priority": 50,
|
||||
"args": {
|
||||
"unit": "F",
|
||||
"location_query": "oslo, norway"
|
||||
"location_query": "oslo, norway",
|
||||
"weather_api_key": "your_api_key"
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -528,10 +528,10 @@ i3wm
|
||||
in lemonbar bindings.
|
||||
|
||||
``workspace``
|
||||
dictionary containing the workspace name under the key ``"name"`` and
|
||||
boolean values for the ``"visible"``, ``"urgent"`` and ``"focused"``
|
||||
keys, indicating the state of the workspace. Currently only provided by
|
||||
the :py:func:`powerline.listers.i3wm.workspace_lister` lister.
|
||||
the `i3-ipc` workspace object corresponding to this workspace.
|
||||
Contains string attributes ``name`` and ``output``, as well as boolean
|
||||
attributes for ``visible``, ``urgent`` and ``focused``. Currently only
|
||||
provided by the :py:func:`powerline.listers.i3wm.workspace_lister` lister.
|
||||
|
||||
Segment class
|
||||
=============
|
||||
|
@ -77,8 +77,7 @@ to run with i3, simply ``exec`` this in the i3 config file and set the ``--i3``
|
||||
|
||||
exec python /path/to/powerline/bindings/lemonbar/powerline-lemonbar.py --i3
|
||||
|
||||
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>`_).
|
||||
Running the binding in i3-mode will require `i3ipc <https://github.com/acrisci/i3ipc-python>`_.
|
||||
|
||||
See the `lemonbar documentation <https://github.com/LemonBoy/bar>`_ for more
|
||||
information and options.
|
||||
|
@ -5,4 +5,5 @@ set-option -qg window-status-last-style "$_POWERLINE_ACTIVE_WINDOW_STATUS_COLOR"
|
||||
set-window-option -qg window-status-style "$_POWERLINE_WINDOW_STATUS_COLOR"
|
||||
set-window-option -qg window-status-activity-style "$_POWERLINE_ACTIVITY_STATUS_COLOR"
|
||||
set-window-option -qg window-status-bell-style "$_POWERLINE_BELL_STATUS_COLOR"
|
||||
set -g status-right '#(env "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS tmux right --width=#{client_width} -R width_adjust=#{status-left-length} -R pane_id=#{pane_id} -R pane_current_path=#{q:pane_current_path})'
|
||||
# vim: ft=tmux
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Starting from tmux-2.1 escaping of dollar signs inside #() is harmful
|
||||
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=#{client_width} -R width_adjust=#{status-right-length} -R pane_id=#{pane_id})"
|
||||
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=#{client_width} -R width_adjust=#{status-right-length} -R pane_id=#{pane_id} -R pane_current_path=#{q:pane_current_path})"
|
||||
set -g window-status-format "#[$_POWERLINE_WINDOW_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER_SPACES#I#{?window_flags,#F, } #[$_POWERLINE_WINDOW_DIVIDER_COLOR]$_POWERLINE_LEFT_SOFT_DIVIDER#[default]#W $_POWERLINE_LEFT_HARD_DIVIDER_SPACES"
|
||||
|
@ -26,14 +26,14 @@ if exists('g:powerline_pycmd')
|
||||
let s:pyeval = g:powerline_pyeval
|
||||
let s:has_python = 1
|
||||
endif
|
||||
elseif has('python')
|
||||
let s:has_python = 1
|
||||
let s:pycmd = 'py'
|
||||
let s:pyeval = get(g:, 'powerline_pyeval', 'pyeval')
|
||||
elseif has('python3')
|
||||
let s:has_python = 1
|
||||
let s:pycmd = 'py3'
|
||||
let s:pyeval = get(g:, 'powerline_pyeval', 'py3eval')
|
||||
elseif has('python')
|
||||
let s:has_python = 1
|
||||
let s:pycmd = 'py'
|
||||
let s:pyeval = get(g:, 'powerline_pyeval', 'pyeval')
|
||||
else
|
||||
let s:has_python = 0
|
||||
endif
|
||||
|
@ -24,15 +24,6 @@ def i3_subscribe(conn, event, callback):
|
||||
:param func callback:
|
||||
Function to run on event.
|
||||
'''
|
||||
try:
|
||||
import i3ipc
|
||||
except ImportError:
|
||||
import i3
|
||||
conn.Subscription(callback, event)
|
||||
return
|
||||
else:
|
||||
pass
|
||||
|
||||
conn.on(event, callback)
|
||||
|
||||
from threading import Thread
|
||||
@ -57,12 +48,8 @@ def get_i3_connection():
|
||||
'''
|
||||
global conn
|
||||
if not conn:
|
||||
try:
|
||||
import i3ipc
|
||||
except ImportError:
|
||||
import i3 as conn
|
||||
else:
|
||||
conn = i3ipc.Connection()
|
||||
import i3ipc
|
||||
conn = i3ipc.Connection()
|
||||
return conn
|
||||
|
||||
|
||||
|
@ -101,10 +101,7 @@ class Environment(object):
|
||||
return False
|
||||
|
||||
|
||||
if hasattr(getattr(zsh, 'environ', None), '__contains__'):
|
||||
environ = zsh.environ
|
||||
else:
|
||||
environ = Environment()
|
||||
environ = Environment()
|
||||
|
||||
|
||||
if hasattr(zsh, 'expand') and zsh.expand('${:-}') == '':
|
||||
|
@ -179,19 +179,19 @@ except ImportError:
|
||||
return readlines(('git',) + args, directory)
|
||||
|
||||
def stash(self):
|
||||
return sum(1 for _ in self._gitcmd(self.directory, 'stash', 'list'))
|
||||
return sum(1 for _ in self._gitcmd(self.directory, '--no-optional-locks', 'stash', 'list'))
|
||||
|
||||
def do_status(self, directory, path):
|
||||
if path:
|
||||
try:
|
||||
return next(self._gitcmd(directory, 'status', '--porcelain', '--ignored', '--', path))[:2]
|
||||
return next(self._gitcmd(directory, '--no-optional-locks', 'status', '--porcelain', '--ignored', '--', path))[:2]
|
||||
except StopIteration:
|
||||
return None
|
||||
else:
|
||||
wt_column = ' '
|
||||
index_column = ' '
|
||||
untracked_column = ' '
|
||||
for line in self._gitcmd(directory, 'status', '--porcelain'):
|
||||
for line in self._gitcmd(directory, '--no-optional-locks', 'status', '--porcelain'):
|
||||
if line[0] == '?':
|
||||
untracked_column = 'U'
|
||||
continue
|
||||
|
@ -163,7 +163,7 @@ class Spec(object):
|
||||
'''Define message which will be used when unknown key was found
|
||||
|
||||
“Unknown” is a key that was not provided at the initialization and via
|
||||
:py:meth:`Spec.update` and did not match any ``keyfunc`` proided via
|
||||
:py:meth:`Spec.update` and did not match any ``keyfunc`` provided via
|
||||
:py:meth:`Spec.unknown_spec`.
|
||||
|
||||
:param msgfunc:
|
||||
|
@ -50,19 +50,14 @@ def workspace_lister(pl, segment_info, only_show=None, output=None):
|
||||
(
|
||||
updated(
|
||||
segment_info,
|
||||
output=w['output'],
|
||||
workspace={
|
||||
'name': w['name'],
|
||||
'visible': w['visible'],
|
||||
'urgent': w['urgent'],
|
||||
'focused': w['focused'],
|
||||
},
|
||||
output=w.output,
|
||||
workspace=w,
|
||||
),
|
||||
{
|
||||
'draw_inner_divider': None
|
||||
}
|
||||
)
|
||||
for w in get_i3_connection().get_workspaces()
|
||||
if (((not only_show or any(w[typ] for typ in only_show))
|
||||
and (not output or w['output'] == output)))
|
||||
if (((not only_show or any(getattr(w, typ) for typ in only_show))
|
||||
and (not output or w.output == output)))
|
||||
)
|
||||
|
@ -251,7 +251,7 @@ class Renderer(object):
|
||||
for line in range(theme.get_line_number() - 1, 0, -1):
|
||||
yield self.render(side=None, line=line, **kwargs)
|
||||
|
||||
def render(self, mode=None, width=None, side=None, line=0, output_raw=False, output_width=False, segment_info=None, matcher_info=None):
|
||||
def render(self, mode=None, width=None, side=None, line=0, output_raw=False, output_width=False, segment_info=None, matcher_info=None, hl_args=None):
|
||||
'''Render all segments.
|
||||
|
||||
When a width is provided, low-priority segments are dropped one at
|
||||
@ -286,6 +286,11 @@ class Renderer(object):
|
||||
:param matcher_info:
|
||||
Matcher information. Is processed in :py:meth:`get_segment_info`
|
||||
method.
|
||||
:param dict hl_args:
|
||||
Additional arguments to pass on the :py:meth:`hl` and
|
||||
:py:meth`hlstyle` methods. They are ignored in the default
|
||||
implementation, but renderer-specific overrides can make use of
|
||||
them as run-time "configuration" information.
|
||||
'''
|
||||
theme = self.get_theme(matcher_info)
|
||||
return self.do_render(
|
||||
@ -297,6 +302,7 @@ class Renderer(object):
|
||||
output_width=output_width,
|
||||
segment_info=self.get_segment_info(segment_info, mode),
|
||||
theme=theme,
|
||||
hl_args=hl_args
|
||||
)
|
||||
|
||||
def compute_divider_widths(self, theme):
|
||||
@ -324,7 +330,7 @@ class Renderer(object):
|
||||
:return: Results of joining these segments.
|
||||
'''
|
||||
|
||||
def do_render(self, mode, width, side, line, output_raw, output_width, segment_info, theme):
|
||||
def do_render(self, mode, width, side, line, output_raw, output_width, segment_info, theme, hl_args):
|
||||
'''Like Renderer.render(), but accept theme in place of matcher_info
|
||||
'''
|
||||
segments = list(theme.get_segments(side, line, segment_info, mode))
|
||||
@ -333,14 +339,16 @@ class Renderer(object):
|
||||
|
||||
self._prepare_segments(segments, output_width or width)
|
||||
|
||||
hl_args = hl_args or dict()
|
||||
|
||||
if not width:
|
||||
# No width specified, so we don’t need to crop or pad anything
|
||||
if output_width:
|
||||
current_width = self._render_length(theme, segments, self.compute_divider_widths(theme))
|
||||
return construct_returned_value(self.hl_join([
|
||||
segment['_rendered_hl']
|
||||
for segment in self._render_segments(theme, segments)
|
||||
]) + self.hlstyle(), segments, current_width, output_raw, output_width)
|
||||
for segment in self._render_segments(theme, segments, hl_args)
|
||||
]) + self.hlstyle(**hl_args), segments, current_width, output_raw, output_width)
|
||||
|
||||
divider_widths = self.compute_divider_widths(theme)
|
||||
|
||||
@ -394,10 +402,10 @@ class Renderer(object):
|
||||
|
||||
rendered_highlighted = self.hl_join([
|
||||
segment['_rendered_hl']
|
||||
for segment in self._render_segments(theme, segments)
|
||||
for segment in self._render_segments(theme, segments, hl_args)
|
||||
])
|
||||
if rendered_highlighted:
|
||||
rendered_highlighted += self.hlstyle()
|
||||
rendered_highlighted += self.hlstyle(**hl_args)
|
||||
|
||||
return construct_returned_value(rendered_highlighted, segments, current_width, output_raw, output_width)
|
||||
|
||||
@ -470,7 +478,7 @@ class Renderer(object):
|
||||
ret += segment_len
|
||||
return ret
|
||||
|
||||
def _render_segments(self, theme, segments, render_highlighted=True):
|
||||
def _render_segments(self, theme, segments, hl_args, render_highlighted=True):
|
||||
'''Internal segment rendering method.
|
||||
|
||||
This method loops through the segment array and compares the
|
||||
@ -527,6 +535,10 @@ class Renderer(object):
|
||||
contents_highlighted = ''
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
|
||||
segment_hl_args = {}
|
||||
segment_hl_args.update(segment['highlight'])
|
||||
segment_hl_args.update(hl_args)
|
||||
|
||||
# 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:
|
||||
@ -546,14 +558,14 @@ class Renderer(object):
|
||||
|
||||
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)
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment_hl_args)
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False, **hl_args)
|
||||
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'])
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False, **hl_args)
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment_hl_args)
|
||||
segment['_rendered_raw'] = divider_raw + contents_raw
|
||||
segment['_rendered_hl'] = divider_highlighted + contents_highlighted
|
||||
else:
|
||||
@ -562,7 +574,7 @@ class Renderer(object):
|
||||
else:
|
||||
contents_raw = contents_raw + outer_padding
|
||||
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment_hl_args)
|
||||
segment['_rendered_raw'] = contents_raw
|
||||
segment['_rendered_hl'] = contents_highlighted
|
||||
prev_segment = segment
|
||||
@ -576,7 +588,7 @@ class Renderer(object):
|
||||
'''
|
||||
return string.translate(self.character_translations)
|
||||
|
||||
def hlstyle(fg=None, bg=None, attrs=None):
|
||||
def hlstyle(fg=None, bg=None, attrs=None, **kwargs):
|
||||
'''Output highlight style string.
|
||||
|
||||
Assuming highlighted string looks like ``{style}{contents}`` this method
|
||||
@ -585,10 +597,10 @@ class Renderer(object):
|
||||
'''
|
||||
raise NotImplementedError
|
||||
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None):
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None, **kwargs):
|
||||
'''Output highlighted chunk.
|
||||
|
||||
This implementation just outputs :py:meth:`hlstyle` joined with
|
||||
``contents``.
|
||||
'''
|
||||
return self.hlstyle(fg, bg, attrs) + (contents or '')
|
||||
return self.hlstyle(fg, bg, attrs, **kwargs) + (contents or '')
|
||||
|
@ -17,7 +17,7 @@ class I3barRenderer(Renderer):
|
||||
# We don’t need to explicitly reset attributes, so skip those calls
|
||||
return ''
|
||||
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None):
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None, **kwargs):
|
||||
segment = {
|
||||
'full_text': contents,
|
||||
'separator': False,
|
||||
|
@ -90,7 +90,7 @@ class IPythonPygmentsRenderer(IPythonRenderer):
|
||||
def hl_join(segments):
|
||||
return reduce(operator.iadd, segments, [])
|
||||
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None):
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None, **kwargs):
|
||||
'''Output highlighted chunk.
|
||||
|
||||
This implementation outputs a list containing a single pair
|
||||
|
@ -21,7 +21,7 @@ class LemonbarRenderer(Renderer):
|
||||
# We don’t need to explicitly reset attributes, so skip those calls
|
||||
return ''
|
||||
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None):
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None, **kwargs):
|
||||
text = ''
|
||||
|
||||
if fg is not None:
|
||||
|
@ -15,7 +15,7 @@ class PangoMarkupRenderer(Renderer):
|
||||
# We don’t need to explicitly reset attributes, so skip those calls
|
||||
return ''
|
||||
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None):
|
||||
def hl(self, contents, fg=None, bg=None, attrs=None, **kwargs):
|
||||
'''Highlight a segment.'''
|
||||
awesome_attr = []
|
||||
if fg is not None:
|
||||
|
@ -105,7 +105,7 @@ class ShellRenderer(PromptRenderer):
|
||||
self.used_term_escape_style = self.term_escape_style
|
||||
return super(ShellRenderer, self).do_render(segment_info=segment_info, **kwargs)
|
||||
|
||||
def hlstyle(self, fg=None, bg=None, attrs=None):
|
||||
def hlstyle(self, fg=None, bg=None, attrs=None, escape=True, **kwargs):
|
||||
'''Highlight a segment.
|
||||
|
||||
If an argument is None, the argument is ignored. If an argument is
|
||||
@ -162,7 +162,7 @@ class ShellRenderer(PromptRenderer):
|
||||
r = '\033Ptmux;' + r.replace('\033', '\033\033') + '\033\\'
|
||||
elif self.screen_escape:
|
||||
r = '\033P' + r.replace('\033', '\033\033') + '\033\\'
|
||||
return self.escape_hl_start + r + self.escape_hl_end
|
||||
return self.escape_hl_start + r + self.escape_hl_end if escape else r
|
||||
|
||||
def get_theme(self, matcher_info):
|
||||
if not matcher_info:
|
||||
|
@ -6,13 +6,91 @@ from powerline.renderers.shell import ShellRenderer
|
||||
|
||||
class BashPromptRenderer(ShellRenderer):
|
||||
'''Powerline bash prompt segment renderer.'''
|
||||
escape_hl_start = '\['
|
||||
escape_hl_end = '\]'
|
||||
escape_hl_start = '\\['
|
||||
escape_hl_end = '\\]'
|
||||
|
||||
character_translations = ShellRenderer.character_translations.copy()
|
||||
character_translations[ord('$')] = '\\$'
|
||||
character_translations[ord('`')] = '\\`'
|
||||
character_translations[ord('\\')] = '\\\\'
|
||||
|
||||
def do_render(self, side, line, width, output_width, output_raw, hl_args, **kwargs):
|
||||
|
||||
# we are rendering the normal left prompt
|
||||
if side == 'left' and line == 0 and width is not None:
|
||||
|
||||
# we need left prompt's width to render the raw spacer
|
||||
output_width = output_width or output_raw
|
||||
|
||||
left = super(BashPromptRenderer, self).do_render(
|
||||
side=side,
|
||||
line=line,
|
||||
output_width=output_width,
|
||||
width=width,
|
||||
output_raw=output_raw,
|
||||
hl_args=hl_args,
|
||||
**kwargs
|
||||
)
|
||||
left_rendered = left[0] if output_width else left
|
||||
|
||||
# we don't escape color sequences in the right prompt so we can do escaping as a whole
|
||||
if hl_args:
|
||||
hl_args = hl_args.copy()
|
||||
hl_args.update({'escape': False})
|
||||
else:
|
||||
hl_args = {'escape': False}
|
||||
|
||||
right = super(BashPromptRenderer, self).do_render(
|
||||
side='right',
|
||||
line=line,
|
||||
output_width=True,
|
||||
width=width,
|
||||
output_raw=output_raw,
|
||||
hl_args=hl_args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
ret = []
|
||||
if right[-1] > 0:
|
||||
# if the right prompt is not empty we embed it in the left prompt
|
||||
# it must be escaped as a whole so readline doesn't see it
|
||||
ret.append(''.join((
|
||||
left_rendered,
|
||||
self.escape_hl_start,
|
||||
'\033[s', # save the cursor position
|
||||
'\033[{0}C'.format(width), # move to the right edge of the terminal
|
||||
'\033[{0}D'.format(right[-1] - 1), # move back to the right prompt position
|
||||
right[0],
|
||||
'\033[u', # restore the cursor position
|
||||
self.escape_hl_end
|
||||
)))
|
||||
if output_raw:
|
||||
ret.append(''.join((
|
||||
left[1],
|
||||
' ' * (width - left[-1] - right[-1]),
|
||||
right[1]
|
||||
)))
|
||||
else:
|
||||
ret.append(left_rendered)
|
||||
if output_raw:
|
||||
ret.append(left[1])
|
||||
if output_width:
|
||||
ret.append(left[-1])
|
||||
if len(ret) == 1:
|
||||
return ret[0]
|
||||
else:
|
||||
return ret
|
||||
|
||||
else:
|
||||
return super(BashPromptRenderer, self).do_render(
|
||||
side=side,
|
||||
line=line,
|
||||
width=width,
|
||||
output_width=output_width,
|
||||
output_raw=output_raw,
|
||||
hl_args=hl_args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
renderer = BashPromptRenderer
|
||||
|
@ -38,7 +38,7 @@ class TmuxRenderer(Renderer):
|
||||
width = 10
|
||||
return super(TmuxRenderer, self).render(width=width, segment_info=segment_info, **kwargs)
|
||||
|
||||
def hlstyle(self, fg=None, bg=None, attrs=None):
|
||||
def hlstyle(self, fg=None, bg=None, attrs=None, **kwargs):
|
||||
'''Highlight a segment.'''
|
||||
# We don’t need to explicitly reset attributes, so skip those calls
|
||||
if not attrs and not bg and not fg:
|
||||
@ -68,7 +68,9 @@ class TmuxRenderer(Renderer):
|
||||
r = self.segment_info.copy()
|
||||
if segment_info:
|
||||
r.update(segment_info)
|
||||
if 'pane_id' in r:
|
||||
if 'pane_current_path' in r:
|
||||
r['getcwd'] = lambda: r['pane_current_path']
|
||||
elif 'pane_id' in r:
|
||||
varname = 'TMUX_PWD_' + str(r['pane_id'])
|
||||
if varname in r['environ']:
|
||||
r['getcwd'] = lambda: r['environ'][varname]
|
||||
|
@ -123,7 +123,7 @@ class VimRenderer(Renderer):
|
||||
def reset_highlight(self):
|
||||
self.hl_groups.clear()
|
||||
|
||||
def hlstyle(self, fg=None, bg=None, attrs=None):
|
||||
def hlstyle(self, fg=None, bg=None, attrs=None, **kwargs):
|
||||
'''Highlight a segment.
|
||||
|
||||
If an argument is None, the argument is ignored. If an argument is
|
||||
|
@ -19,20 +19,24 @@ def environment(pl, segment_info, variable=None):
|
||||
|
||||
|
||||
@requires_segment_info
|
||||
def virtualenv(pl, segment_info, ignore_venv=False, ignore_conda=False):
|
||||
def virtualenv(pl, segment_info, ignore_venv=False, ignore_conda=False, ignored_names=("venv", ".venv")):
|
||||
'''Return the name of the current Python or conda virtualenv.
|
||||
|
||||
:param list ignored_names:
|
||||
Names of venvs to ignore. Will then get the name of the venv by ascending to the parent directory
|
||||
:param bool ignore_venv:
|
||||
Whether to ignore virtual environments. Default is False.
|
||||
:param bool ignore_conda:
|
||||
Whether to ignore conda environments. Default is False.
|
||||
'''
|
||||
return (
|
||||
(not ignore_venv and
|
||||
os.path.basename(segment_info['environ'].get('VIRTUAL_ENV', ''))) or
|
||||
(not ignore_conda and
|
||||
segment_info['environ'].get('CONDA_DEFAULT_ENV', '')) or
|
||||
None)
|
||||
if not ignore_venv:
|
||||
for candidate in reversed(segment_info['environ'].get('VIRTUAL_ENV', '').split("/")):
|
||||
if candidate and candidate not in ignored_names:
|
||||
return candidate
|
||||
if not ignore_conda:
|
||||
for candidate in reversed(segment_info['environ'].get('CONDA_DEFAULT_ENV', '').split("/")):
|
||||
if candidate and candidate not in ignored_names:
|
||||
return candidate
|
||||
return None
|
||||
|
||||
|
||||
@requires_segment_info
|
||||
|
@ -31,6 +31,8 @@ def _convert_state(state):
|
||||
|
||||
def _convert_seconds(seconds):
|
||||
'''Convert seconds to minutes:seconds format'''
|
||||
if isinstance(seconds, str):
|
||||
seconds = seconds.replace(",",".")
|
||||
return '{0:.0f}:{1:02.0f}'.format(*divmod(float(seconds), 60))
|
||||
|
||||
|
||||
|
@ -90,8 +90,6 @@ try:
|
||||
self.exception('Exception while calculating cpu_percent: {0}', str(e))
|
||||
|
||||
def render(self, cpu_percent, format='{0:.0f}%', **kwargs):
|
||||
if not cpu_percent:
|
||||
return None
|
||||
return [{
|
||||
'contents': format.format(cpu_percent),
|
||||
'gradient_level': cpu_percent,
|
||||
@ -150,7 +148,8 @@ else:
|
||||
|
||||
|
||||
@add_divider_highlight_group('background:divider')
|
||||
def uptime(pl, days_format='{days:d}d', hours_format=' {hours:d}h', minutes_format=' {minutes:d}m', seconds_format=' {seconds:d}s', shorten_len=3):
|
||||
def uptime(pl, days_format='{days:d}d', hours_format=' {hours:d}h', minutes_format=' {minutes:02d}m',
|
||||
seconds_format=' {seconds:02d}s', shorten_len=3):
|
||||
'''Return system uptime.
|
||||
|
||||
:param str days_format:
|
||||
@ -175,9 +174,11 @@ def uptime(pl, days_format='{days:d}d', hours_format=' {hours:d}h', minutes_form
|
||||
hours, minutes = divmod(minutes, 60)
|
||||
days, hours = divmod(hours, 24)
|
||||
time_formatted = list(filter(None, [
|
||||
days_format.format(days=days) if days and days_format else None,
|
||||
hours_format.format(hours=hours) if hours and hours_format else None,
|
||||
minutes_format.format(minutes=minutes) if minutes and minutes_format else None,
|
||||
seconds_format.format(seconds=seconds) if seconds and seconds_format else None,
|
||||
]))[0:shorten_len]
|
||||
days_format.format(days=days) if days_format else None,
|
||||
hours_format.format(hours=hours) if hours_format else None,
|
||||
minutes_format.format(minutes=minutes) if minutes_format else None,
|
||||
seconds_format.format(seconds=seconds) if seconds_format else None,
|
||||
]))
|
||||
first_non_zero = next((i for i, x in enumerate([days, hours, minutes, seconds]) if x != 0))
|
||||
time_formatted = time_formatted[first_non_zero:first_non_zero + shorten_len]
|
||||
return ''.join(time_formatted).strip()
|
||||
|
@ -4,22 +4,33 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def date(pl, format='%Y-%m-%d', istime=False):
|
||||
def date(pl, format='%Y-%m-%d', istime=False, timezone=None):
|
||||
'''Return the current date.
|
||||
|
||||
:param str format:
|
||||
strftime-style date format string
|
||||
:param bool istime:
|
||||
If true then segment uses ``time`` highlight group.
|
||||
:param string timezone:
|
||||
Specify a timezone to use as ``+HHMM`` or ``-HHMM``.
|
||||
(Defaults to system defaults.)
|
||||
|
||||
Divider highlight group used: ``time:divider``.
|
||||
|
||||
Highlight groups used: ``time`` or ``date``.
|
||||
'''
|
||||
|
||||
try:
|
||||
contents = datetime.now().strftime(format)
|
||||
tz = datetime.strptime(timezone, '%z').tzinfo if timezone else None
|
||||
except ValueError:
|
||||
tz = None
|
||||
|
||||
nw = datetime.now(tz)
|
||||
|
||||
try:
|
||||
contents = nw.strftime(format)
|
||||
except UnicodeEncodeError:
|
||||
contents = datetime.now().strftime(format.encode('utf-8')).decode('utf-8')
|
||||
contents = nw.strftime(format.encode('utf-8')).decode('utf-8')
|
||||
|
||||
return [{
|
||||
'contents': contents,
|
||||
@ -34,59 +45,77 @@ UNICODE_TEXT_TRANSLATION = {
|
||||
}
|
||||
|
||||
|
||||
def fuzzy_time(pl, unicode_text=False):
|
||||
def fuzzy_time(pl, format='{minute_str} {hour_str}', unicode_text=False, timezone=None, hour_str=['twelve', 'one', 'two', 'three', 'four',
|
||||
'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven'], minute_str = {
|
||||
'0': 'o\'clock', '5': 'five past', '10': 'ten past','15': 'quarter past',
|
||||
'20': 'twenty past', '25': 'twenty-five past', '30': 'half past', '35': 'twenty-five to',
|
||||
'40': 'twenty to', '45': 'quarter to', '50': 'ten to', '55': 'five to'
|
||||
}, special_case_str = {
|
||||
'(23, 58)': 'round about midnight',
|
||||
'(23, 59)': 'round about midnight',
|
||||
'(0, 0)': 'midnight',
|
||||
'(0, 1)': 'round about midnight',
|
||||
'(0, 2)': 'round about midnight',
|
||||
'(12, 0)': 'noon',
|
||||
}):
|
||||
|
||||
'''Display the current time as fuzzy time, e.g. "quarter past six".
|
||||
|
||||
:param string format:
|
||||
Format used to display the fuzzy time. (Ignored when a special time
|
||||
is displayed.)
|
||||
:param bool unicode_text:
|
||||
If true then hyphenminuses (regular ASCII ``-``) and single quotes are
|
||||
If true then hyphenminuses (regular ASCII ``-``) and single quotes are
|
||||
replaced with unicode dashes and apostrophes.
|
||||
'''
|
||||
hour_str = ['twelve', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven']
|
||||
minute_str = {
|
||||
5: 'five past',
|
||||
10: 'ten past',
|
||||
15: 'quarter past',
|
||||
20: 'twenty past',
|
||||
25: 'twenty-five past',
|
||||
30: 'half past',
|
||||
35: 'twenty-five to',
|
||||
40: 'twenty to',
|
||||
45: 'quarter to',
|
||||
50: 'ten to',
|
||||
55: 'five to',
|
||||
}
|
||||
special_case_str = {
|
||||
(23, 58): 'round about midnight',
|
||||
(23, 59): 'round about midnight',
|
||||
(0, 0): 'midnight',
|
||||
(0, 1): 'round about midnight',
|
||||
(0, 2): 'round about midnight',
|
||||
(12, 0): 'noon',
|
||||
}
|
||||
:param string timezone:
|
||||
Specify a timezone to use as ``+HHMM`` or ``-HHMM``.
|
||||
(Defaults to system defaults.)
|
||||
:param string list hour_str:
|
||||
Strings to be used to display the hour, starting with midnight.
|
||||
(This list may contain 12 or 24 entries.)
|
||||
:param dict minute_str:
|
||||
Dictionary mapping minutes to strings to be used to display them.
|
||||
:param dict special_case_str:
|
||||
Special strings for special times.
|
||||
|
||||
now = datetime.now()
|
||||
Highlight groups used: ``fuzzy_time``.
|
||||
'''
|
||||
|
||||
try:
|
||||
return special_case_str[(now.hour, now.minute)]
|
||||
tz = datetime.strptime(timezone, '%z').tzinfo if timezone else None
|
||||
except ValueError:
|
||||
tz = None
|
||||
|
||||
now = datetime.now(tz)
|
||||
|
||||
try:
|
||||
# We don't want to enforce a special type of spaces/ alignment in the input
|
||||
from ast import literal_eval
|
||||
special_case_str = {literal_eval(x):special_case_str[x] for x in special_case_str}
|
||||
result = special_case_str[(now.hour, now.minute)]
|
||||
if unicode_text:
|
||||
result = result.translate(UNICODE_TEXT_TRANSLATION)
|
||||
return result
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
hour = now.hour
|
||||
if now.minute > 32:
|
||||
if hour == 23:
|
||||
hour = 0
|
||||
else:
|
||||
hour += 1
|
||||
if hour > 11:
|
||||
hour = hour - 12
|
||||
hour = hour_str[hour]
|
||||
if now.minute >= 30:
|
||||
hour = hour + 1
|
||||
hour = hour % len(hour_str)
|
||||
|
||||
minute = int(round(now.minute / 5.0) * 5)
|
||||
if minute == 60 or minute == 0:
|
||||
result = ' '.join([hour, 'o\'clock'])
|
||||
else:
|
||||
minute = minute_str[minute]
|
||||
result = ' '.join([minute, hour])
|
||||
min_dis = 100
|
||||
min_pos = 0
|
||||
|
||||
for mn in minute_str:
|
||||
mn = int(mn)
|
||||
if now.minute >= mn and now.minute - mn < min_dis:
|
||||
min_dis = now.minute - mn
|
||||
min_pos = mn
|
||||
elif now.minute < mn and mn - now.minute < min_dis:
|
||||
min_dis = mn - now.minute
|
||||
min_pos = mn
|
||||
result = format.format(minute_str=minute_str[str(min_pos)], hour_str=hour_str[hour])
|
||||
|
||||
if unicode_text:
|
||||
result = result.translate(UNICODE_TEXT_TRANSLATION)
|
||||
|
@ -2,76 +2,80 @@
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import json
|
||||
from collections import namedtuple
|
||||
|
||||
from powerline.lib.url import urllib_read, urllib_urlencode
|
||||
from powerline.lib.threaded import KwThreadedSegment
|
||||
from powerline.segments import with_docstring
|
||||
|
||||
|
||||
_WeatherKey = namedtuple('Key', 'location_query weather_api_key')
|
||||
|
||||
|
||||
# XXX Warning: module name must not be equal to the segment name as long as this
|
||||
# segment is imported into powerline.segments.common module.
|
||||
|
||||
|
||||
# Weather condition code descriptions available at
|
||||
# http://developer.yahoo.com/weather/#codes
|
||||
weather_conditions_codes = (
|
||||
('tornado', 'stormy'), # 0
|
||||
('tropical_storm', 'stormy'), # 1
|
||||
('hurricane', 'stormy'), # 2
|
||||
('severe_thunderstorms', 'stormy'), # 3
|
||||
('thunderstorms', 'stormy'), # 4
|
||||
('mixed_rain_and_snow', 'rainy' ), # 5
|
||||
('mixed_rain_and_sleet', 'rainy' ), # 6
|
||||
('mixed_snow_and_sleet', 'snowy' ), # 7
|
||||
('freezing_drizzle', 'rainy' ), # 8
|
||||
('drizzle', 'rainy' ), # 9
|
||||
('freezing_rain', 'rainy' ), # 10
|
||||
('showers', 'rainy' ), # 11
|
||||
('showers', 'rainy' ), # 12
|
||||
('snow_flurries', 'snowy' ), # 13
|
||||
('light_snow_showers', 'snowy' ), # 14
|
||||
('blowing_snow', 'snowy' ), # 15
|
||||
('snow', 'snowy' ), # 16
|
||||
('hail', 'snowy' ), # 17
|
||||
('sleet', 'snowy' ), # 18
|
||||
('dust', 'foggy' ), # 19
|
||||
('fog', 'foggy' ), # 20
|
||||
('haze', 'foggy' ), # 21
|
||||
('smoky', 'foggy' ), # 22
|
||||
('blustery', 'windy' ), # 23
|
||||
('windy', ), # 24
|
||||
('cold', 'day' ), # 25
|
||||
('clouds', 'cloudy'), # 26
|
||||
('mostly_cloudy_night', 'cloudy'), # 27
|
||||
('mostly_cloudy_day', 'cloudy'), # 28
|
||||
('partly_cloudy_night', 'cloudy'), # 29
|
||||
('partly_cloudy_day', 'cloudy'), # 30
|
||||
('clear_night', 'night' ), # 31
|
||||
('sun', 'sunny' ), # 32
|
||||
('fair_night', 'night' ), # 33
|
||||
('fair_day', 'day' ), # 34
|
||||
('mixed_rain_and_hail', 'rainy' ), # 35
|
||||
('hot', 'sunny' ), # 36
|
||||
('isolated_thunderstorms', 'stormy'), # 37
|
||||
('scattered_thunderstorms', 'stormy'), # 38
|
||||
('scattered_thunderstorms', 'stormy'), # 39
|
||||
('scattered_showers', 'rainy' ), # 40
|
||||
('heavy_snow', 'snowy' ), # 41
|
||||
('scattered_snow_showers', 'snowy' ), # 42
|
||||
('heavy_snow', 'snowy' ), # 43
|
||||
('partly_cloudy', 'cloudy'), # 44
|
||||
('thundershowers', 'rainy' ), # 45
|
||||
('snow_showers', 'snowy' ), # 46
|
||||
('isolated_thundershowers', 'rainy' ), # 47
|
||||
)
|
||||
# ('day', (25, 34)),
|
||||
# ('rainy', (5, 6, 8, 9, 10, 11, 12, 35, 40, 45, 47)),
|
||||
# ('cloudy', (26, 27, 28, 29, 30, 44)),
|
||||
# ('snowy', (7, 13, 14, 15, 16, 17, 18, 41, 42, 43, 46)),
|
||||
# ('stormy', (0, 1, 2, 3, 4, 37, 38, 39)),
|
||||
# ('foggy', (19, 20, 21, 22, 23)),
|
||||
# ('sunny', (32, 36)),
|
||||
# ('night', (31, 33))):
|
||||
# https://openweathermap.org/weather-conditions
|
||||
weather_conditions_codes = {
|
||||
200: ('stormy',),
|
||||
201: ('stormy',),
|
||||
202: ('stormy',),
|
||||
210: ('stormy',),
|
||||
211: ('stormy',),
|
||||
212: ('stormy',),
|
||||
221: ('stormy',),
|
||||
230: ('stormy',),
|
||||
231: ('stormy',),
|
||||
232: ('stormy',),
|
||||
300: ('rainy',),
|
||||
301: ('rainy',),
|
||||
302: ('rainy',),
|
||||
310: ('rainy',),
|
||||
311: ('rainy',),
|
||||
312: ('rainy',),
|
||||
313: ('rainy',),
|
||||
314: ('rainy',),
|
||||
321: ('rainy',),
|
||||
500: ('rainy',),
|
||||
501: ('rainy',),
|
||||
502: ('rainy',),
|
||||
503: ('rainy',),
|
||||
504: ('rainy',),
|
||||
511: ('snowy',),
|
||||
520: ('rainy',),
|
||||
521: ('rainy',),
|
||||
522: ('rainy',),
|
||||
531: ('rainy',),
|
||||
600: ('snowy',),
|
||||
601: ('snowy',),
|
||||
602: ('snowy',),
|
||||
611: ('snowy',),
|
||||
612: ('snowy',),
|
||||
613: ('snowy',),
|
||||
615: ('snowy',),
|
||||
616: ('snowy',),
|
||||
620: ('snowy',),
|
||||
621: ('snowy',),
|
||||
622: ('snowy',),
|
||||
701: ('foggy',),
|
||||
711: ('foggy',),
|
||||
721: ('foggy',),
|
||||
731: ('foggy',),
|
||||
741: ('foggy',),
|
||||
751: ('foggy',),
|
||||
761: ('foggy',),
|
||||
762: ('foggy',),
|
||||
771: ('foggy',),
|
||||
781: ('foggy',),
|
||||
800: ('sunny',),
|
||||
801: ('cloudy',),
|
||||
802: ('cloudy',),
|
||||
803: ('cloudy',),
|
||||
804: ('cloudy',),
|
||||
}
|
||||
|
||||
weather_conditions_icons = {
|
||||
'day': 'DAY',
|
||||
'blustery': 'WIND',
|
||||
@ -88,9 +92,9 @@ weather_conditions_icons = {
|
||||
}
|
||||
|
||||
temp_conversions = {
|
||||
'C': lambda temp: temp,
|
||||
'F': lambda temp: (temp * 9 / 5) + 32,
|
||||
'K': lambda temp: temp + 273.15,
|
||||
'C': lambda temp: temp - 273.15,
|
||||
'F': lambda temp: (temp * 9 / 5) - 459.67,
|
||||
'K': lambda temp: temp,
|
||||
}
|
||||
|
||||
# Note: there are also unicode characters for units: ℃, ℉ and K
|
||||
@ -105,38 +109,37 @@ class WeatherSegment(KwThreadedSegment):
|
||||
interval = 600
|
||||
default_location = None
|
||||
location_urls = {}
|
||||
weather_api_key = "fbc9549d91a5e4b26c15be0dbdac3460"
|
||||
|
||||
@staticmethod
|
||||
def key(location_query=None, **kwargs):
|
||||
return location_query
|
||||
|
||||
def get_request_url(self, location_query):
|
||||
try:
|
||||
return self.location_urls[location_query]
|
||||
weather_api_key = kwargs["weather_api_key"]
|
||||
except KeyError:
|
||||
weather_api_key = WeatherSegment.weather_api_key
|
||||
return _WeatherKey(location_query, weather_api_key)
|
||||
|
||||
def get_request_url(self, weather_key):
|
||||
try:
|
||||
return self.location_urls[weather_key]
|
||||
except KeyError:
|
||||
if location_query is None:
|
||||
location_data = json.loads(urllib_read('http://geoip.nekudo.com/api/'))
|
||||
location = ','.join((
|
||||
location_data['city'],
|
||||
location_data['country']['name'],
|
||||
location_data['country']['code']
|
||||
))
|
||||
self.info('Location returned by nekudo is {0}', location)
|
||||
else:
|
||||
location = location_query
|
||||
query_data = {
|
||||
'q':
|
||||
'use "https://raw.githubusercontent.com/yql/yql-tables/master/weather/weather.bylocation.xml" as we;'
|
||||
'select * from weather.forecast where woeid in'
|
||||
' (select woeid from geo.places(1) where text="{0}") and u="c"'.format(location).encode('utf-8'),
|
||||
'format': 'json',
|
||||
"appid": weather_key.weather_api_key
|
||||
}
|
||||
location_query = weather_key.location_query
|
||||
if location_query is None:
|
||||
location_data = json.loads(urllib_read('https://freegeoip.app/json/'))
|
||||
query_data["lat"] = location_data["latitude"]
|
||||
query_data["lon"] = location_data["longitude"]
|
||||
else:
|
||||
query_data["q"] = location_query
|
||||
self.location_urls[location_query] = url = (
|
||||
'http://query.yahooapis.com/v1/public/yql?' + urllib_urlencode(query_data))
|
||||
"https://api.openweathermap.org/data/2.5/weather?" +
|
||||
urllib_urlencode(query_data))
|
||||
return url
|
||||
|
||||
def compute_state(self, location_query):
|
||||
url = self.get_request_url(location_query)
|
||||
def compute_state(self, weather_key):
|
||||
url = self.get_request_url(weather_key)
|
||||
raw_response = urllib_read(url)
|
||||
if not raw_response:
|
||||
self.error('Failed to get response')
|
||||
@ -144,22 +147,18 @@ class WeatherSegment(KwThreadedSegment):
|
||||
|
||||
response = json.loads(raw_response)
|
||||
try:
|
||||
condition = response['query']['results']['channel']['item']['condition']
|
||||
condition_code = int(condition['code'])
|
||||
temp = float(condition['temp'])
|
||||
condition = response['weather'][0]
|
||||
condition_code = int(condition['id'])
|
||||
temp = float(response['main']['temp'])
|
||||
except (KeyError, ValueError):
|
||||
self.exception('Yahoo returned malformed or unexpected response: {0}', repr(raw_response))
|
||||
self.exception('OpenWeatherMap returned malformed or unexpected response: {0}', repr(raw_response))
|
||||
return None
|
||||
|
||||
try:
|
||||
icon_names = weather_conditions_codes[condition_code]
|
||||
except IndexError:
|
||||
if condition_code == 3200:
|
||||
icon_names = ('not_available',)
|
||||
self.warn('Weather is not available for location {0}', self.location)
|
||||
else:
|
||||
icon_names = ('unknown',)
|
||||
self.error('Unknown condition code: {0}', condition_code)
|
||||
icon_names = ('unknown',)
|
||||
self.error('Unknown condition code: {0}', condition_code)
|
||||
|
||||
return (temp, icon_names)
|
||||
|
||||
@ -179,12 +178,12 @@ class WeatherSegment(KwThreadedSegment):
|
||||
|
||||
temp_format = temp_format or ('{temp:.0f}' + temp_units[unit])
|
||||
converted_temp = temp_conversions[unit](temp)
|
||||
if temp <= temp_coldest:
|
||||
if converted_temp <= temp_coldest:
|
||||
gradient_level = 0
|
||||
elif temp >= temp_hottest:
|
||||
elif converted_temp >= temp_hottest:
|
||||
gradient_level = 100
|
||||
else:
|
||||
gradient_level = (temp - temp_coldest) * 100.0 / (temp_hottest - temp_coldest)
|
||||
gradient_level = (converted_temp - temp_coldest) * 100.0 / (temp_hottest - temp_coldest)
|
||||
groups = ['weather_condition_' + icon_name for icon_name in icon_names] + ['weather_conditions', 'weather']
|
||||
return [
|
||||
{
|
||||
@ -202,9 +201,9 @@ class WeatherSegment(KwThreadedSegment):
|
||||
|
||||
|
||||
weather = with_docstring(WeatherSegment(),
|
||||
'''Return weather from Yahoo! Weather.
|
||||
'''Return weather from OpenWeatherMaps.
|
||||
|
||||
Uses GeoIP lookup from http://geoip.nekudo.com to automatically determine
|
||||
Uses GeoIP lookup from https://freegeoip.app to automatically determine
|
||||
your current location. This should be changed if you’re in a VPN or if your
|
||||
IP address is registered at another location.
|
||||
|
||||
@ -231,5 +230,5 @@ weather conditions.
|
||||
Divider highlight group used: ``background:divider``.
|
||||
|
||||
Highlight groups used: ``weather_conditions`` or ``weather``, ``weather_temp_gradient`` (gradient) or ``weather``.
|
||||
Also uses ``weather_conditions_{condition}`` for all weather conditions supported by Yahoo.
|
||||
Also uses ``weather_conditions_{condition}`` for all weather conditions supported by OpenWeatherMap.
|
||||
''')
|
||||
|
@ -12,11 +12,11 @@ WORKSPACE_REGEX = re.compile(r'^[0-9]+: ?')
|
||||
|
||||
def workspace_groups(w):
|
||||
group = []
|
||||
if w['focused']:
|
||||
if w.focused:
|
||||
group.append('w_focused')
|
||||
if w['urgent']:
|
||||
if w.urgent:
|
||||
group.append('w_urgent')
|
||||
if w['visible']:
|
||||
if w.visible:
|
||||
group.append('w_visible')
|
||||
group.append('workspace')
|
||||
return group
|
||||
@ -52,12 +52,12 @@ def workspaces(pl, segment_info, only_show=None, output=None, strip=0):
|
||||
|
||||
return [
|
||||
{
|
||||
'contents': w['name'][strip:],
|
||||
'contents': w.name[strip:],
|
||||
'highlight_groups': workspace_groups(w)
|
||||
}
|
||||
for w in get_i3_connection().get_workspaces()
|
||||
if ((not only_show or any(w[typ] for typ in only_show))
|
||||
and (not output or w['output'] == output))
|
||||
if ((not only_show or any(getattr(w, typ) for typ in only_show))
|
||||
and (not output or w.output == output))
|
||||
]
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ def workspace(pl, segment_info, workspace=None, strip=False):
|
||||
try:
|
||||
w = next((
|
||||
w for w in get_i3_connection().get_workspaces()
|
||||
if w['name'] == workspace
|
||||
if w.name == workspace
|
||||
))
|
||||
except StopIteration:
|
||||
return None
|
||||
@ -90,13 +90,13 @@ def workspace(pl, segment_info, workspace=None, strip=False):
|
||||
try:
|
||||
w = next((
|
||||
w for w in get_i3_connection().get_workspaces()
|
||||
if w['focused']
|
||||
if w.focused
|
||||
))
|
||||
except StopIteration:
|
||||
return None
|
||||
|
||||
return [{
|
||||
'contents': format_name(w['name'], strip=strip),
|
||||
'contents': format_name(w.name, strip=strip),
|
||||
'highlight_groups': workspace_groups(w)
|
||||
}]
|
||||
|
||||
@ -150,6 +150,6 @@ def scratchpad(pl, icons=SCRATCHPAD_ICONS):
|
||||
'contents': icons.get(w.scratchpad_state, icons['changed']),
|
||||
'highlight_groups': scratchpad_groups(w)
|
||||
}
|
||||
for w in get_i3_connection().get_tree().descendents()
|
||||
for w in get_i3_connection().get_tree().descendants()
|
||||
if w.scratchpad_state != 'none'
|
||||
]
|
||||
|
@ -4,7 +4,7 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
||||
import subprocess
|
||||
from traceback import print_exc
|
||||
|
||||
__version__ = "2.8.1"
|
||||
__version__ = "2.8.2"
|
||||
|
||||
def get_version():
|
||||
try:
|
||||
|
@ -262,6 +262,7 @@ class VimPowerline(Powerline):
|
||||
|
||||
def new_win_idx(self, window_id):
|
||||
r = None
|
||||
|
||||
for window in vim.windows:
|
||||
try:
|
||||
curwindow_id = window.vars['powerline_window_id']
|
||||
@ -302,7 +303,18 @@ class VimPowerline(Powerline):
|
||||
return self.render(window, window_id, winnr)
|
||||
|
||||
def tabline(self):
|
||||
return self.render(*self.win_idx(None), is_tabline=True)
|
||||
r = self.win_idx(None)
|
||||
|
||||
if r:
|
||||
return self.render(*r, is_tabline=True)
|
||||
else:
|
||||
win = vim.current.window
|
||||
r = (
|
||||
win,
|
||||
win.vars.get('powerline_window_id', self.last_window_id),
|
||||
win.number,
|
||||
)
|
||||
return self.render(*r, is_tabline=True)
|
||||
|
||||
def new_window(self):
|
||||
return self.render(*self.win_idx(None))
|
||||
|
7
setup.py
7
setup.py
@ -46,14 +46,13 @@ except Exception as e:
|
||||
else:
|
||||
sys.path.append(CURRENT_DIR)
|
||||
from powerline.lib.shell import which
|
||||
can_use_scripts = True
|
||||
if which('socat') and which('sed') and which('sh'):
|
||||
print('Using powerline.sh script instead of C version (requires socat, sed and sh)')
|
||||
shutil.copyfile('client/powerline.sh', 'scripts/powerline')
|
||||
can_use_scripts = True
|
||||
else:
|
||||
print('Using powerline.py script instead of C version')
|
||||
shutil.copyfile('client/powerline.py', 'scripts/powerline')
|
||||
can_use_scripts = True
|
||||
else:
|
||||
can_use_scripts = False
|
||||
|
||||
@ -71,10 +70,10 @@ setup(
|
||||
'Natural Language :: English',
|
||||
'Operating System :: Microsoft :: Windows',
|
||||
'Operating System :: POSIX',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: PyPy',
|
||||
],
|
||||
|
@ -44,15 +44,23 @@ def urllib_read(query_url):
|
||||
return '127.0.0.1'
|
||||
elif query_url.startswith('http://ipv6.icanhazip.com'):
|
||||
return '2001:4801:7818:6:abc5:ba2c:ff10:275f'
|
||||
|
||||
elif query_url.startswith('https://freegeoip.app/json/'):
|
||||
return '{"ip":"82.145.55.16","country_code":"DE","country_name":"Germany","region_code":"NI","region_name":"Lower Saxony","city":"Meppen","zip_code":"49716","time_zone":"Europe/Berlin","latitude":52.6833,"longitude":7.3167,"metro_code":0}'
|
||||
elif query_url.startswith('http://geoip.nekudo.com/api/'):
|
||||
return '{"city":"Meppen","country":{"name":"Germany", "code":"DE"},"location":{"accuracy_radius":100,"latitude":52.6833,"longitude":7.3167,"time_zone":"Europe\/Berlin"},"ip":"82.145.55.16"}'
|
||||
elif query_url.startswith('http://query.yahooapis.com/v1/public/'):
|
||||
if 'Meppen' in query_url:
|
||||
if 'Meppen' in query_url or '52.6833' in query_url:
|
||||
return r'{"query":{"count":1,"created":"2016-05-13T19:43:18Z","lang":"en-US","results":{"channel":{"units":{"distance":"mi","pressure":"in","speed":"mph","temperature":"C"},"title":"Yahoo! Weather - Meppen, NI, DE","link":"http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-674836/","description":"Yahoo! Weather for Meppen, NI, DE","language":"en-us","lastBuildDate":"Fri, 13 May 2016 09:43 PM CEST","ttl":"60","location":{"city":"Meppen","country":"Germany","region":" NI"},"wind":{"chill":"55","direction":"350","speed":"25"},"atmosphere":{"humidity":"57","pressure":"1004.0","rising":"0","visibility":"16.1"},"astronomy":{"sunrise":"5:35 am","sunset":"9:21 pm"},"image":{"title":"Yahoo! Weather","width":"142","height":"18","link":"http://weather.yahoo.com","url":"http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif"},"item":{"title":"Conditions for Meppen, NI, DE at 08:00 PM CEST","lat":"52.68993","long":"7.29115","link":"http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-674836/","pubDate":"Fri, 13 May 2016 08:00 PM CEST","condition":{"code":"23","date":"Fri, 13 May 2016 08:00 PM CEST","temp":"14","text":"Breezy"},"forecast":[{"code":"30","date":"13 May 2016","day":"Fri","high":"71","low":"48","text":"Partly Cloudy"},{"code":"28","date":"14 May 2016","day":"Sat","high":"54","low":"44","text":"Mostly Cloudy"},{"code":"11","date":"15 May 2016","day":"Sun","high":"55","low":"43","text":"Showers"},{"code":"28","date":"16 May 2016","day":"Mon","high":"54","low":"42","text":"Mostly Cloudy"},{"code":"28","date":"17 May 2016","day":"Tue","high":"57","low":"43","text":"Mostly Cloudy"},{"code":"12","date":"18 May 2016","day":"Wed","high":"62","low":"45","text":"Rain"},{"code":"28","date":"19 May 2016","day":"Thu","high":"63","low":"48","text":"Mostly Cloudy"},{"code":"28","date":"20 May 2016","day":"Fri","high":"67","low":"50","text":"Mostly Cloudy"},{"code":"30","date":"21 May 2016","day":"Sat","high":"71","low":"50","text":"Partly Cloudy"},{"code":"30","date":"22 May 2016","day":"Sun","high":"74","low":"54","text":"Partly Cloudy"}],"description":"<![CDATA[<img src=\"http://l.yimg.com/a/i/us/we/52/23.gif\"/>\n<BR />\n<b>Current Conditions:</b>\n<BR />Breezy\n<BR />\n<BR />\n<b>Forecast:</b>\n<BR /> Fri - Partly Cloudy. High: 71Low: 48\n<BR /> Sat - Mostly Cloudy. High: 54Low: 44\n<BR /> Sun - Showers. High: 55Low: 43\n<BR /> Mon - Mostly Cloudy. High: 54Low: 42\n<BR /> Tue - Mostly Cloudy. High: 57Low: 43\n<BR />\n<BR />\n<a href=\"http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-674836/\">Full Forecast at Yahoo! Weather</a>\n<BR />\n<BR />\n(provided by <a href=\"http://www.weather.com\" >The Weather Channel</a>)\n<BR />\n]]>","guid":{"isPermaLink":"false"}}}}}}'
|
||||
elif 'Moscow' in query_url:
|
||||
return r'{"query":{"count":1,"created":"2016-05-13T19:47:01Z","lang":"en-US","results":{"channel":{"units":{"distance":"mi","pressure":"in","speed":"mph","temperature":"C"},"title":"Yahoo! Weather - Moscow, Moscow Federal City, RU","link":"http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2122265/","description":"Yahoo! Weather for Moscow, Moscow Federal City, RU","language":"en-us","lastBuildDate":"Fri, 13 May 2016 10:47 PM MSK","ttl":"60","location":{"city":"Moscow","country":"Russia","region":" Moscow Federal City"},"wind":{"chill":"45","direction":"80","speed":"11"},"atmosphere":{"humidity":"52","pressure":"993.0","rising":"0","visibility":"16.1"},"astronomy":{"sunrise":"4:19 am","sunset":"8:34 pm"},"image":{"title":"Yahoo! Weather","width":"142","height":"18","link":"http://weather.yahoo.com","url":"http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif"},"item":{"title":"Conditions for Moscow, Moscow Federal City, RU at 09:00 PM MSK","lat":"55.741638","long":"37.605061","link":"http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2122265/","pubDate":"Fri, 13 May 2016 09:00 PM MSK","condition":{"code":"33","date":"Fri, 13 May 2016 09:00 PM MSK","temp":"9","text":"Mostly Clear"},"forecast":[{"code":"30","date":"13 May 2016","day":"Fri","high":"62","low":"41","text":"Partly Cloudy"},{"code":"30","date":"14 May 2016","day":"Sat","high":"64","low":"43","text":"Partly Cloudy"},{"code":"30","date":"15 May 2016","day":"Sun","high":"63","low":"44","text":"Partly Cloudy"},{"code":"12","date":"16 May 2016","day":"Mon","high":"60","low":"47","text":"Rain"},{"code":"12","date":"17 May 2016","day":"Tue","high":"64","low":"48","text":"Rain"},{"code":"28","date":"18 May 2016","day":"Wed","high":"67","low":"48","text":"Mostly Cloudy"},{"code":"12","date":"19 May 2016","day":"Thu","high":"68","low":"49","text":"Rain"},{"code":"39","date":"20 May 2016","day":"Fri","high":"66","low":"50","text":"Scattered Showers"},{"code":"39","date":"21 May 2016","day":"Sat","high":"69","low":"49","text":"Scattered Showers"},{"code":"30","date":"22 May 2016","day":"Sun","high":"73","low":"50","text":"Partly Cloudy"}],"description":"<![CDATA[<img src=\"http://l.yimg.com/a/i/us/we/52/33.gif\"/>\n<BR />\n<b>Current Conditions:</b>\n<BR />Mostly Clear\n<BR />\n<BR />\n<b>Forecast:</b>\n<BR /> Fri - Partly Cloudy. High: 62Low: 41\n<BR /> Sat - Partly Cloudy. High: 64Low: 43\n<BR /> Sun - Partly Cloudy. High: 63Low: 44\n<BR /> Mon - Rain. High: 60Low: 47\n<BR /> Tue - Rain. High: 64Low: 48\n<BR />\n<BR />\n<a href=\"http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2122265/\">Full Forecast at Yahoo! Weather</a>\n<BR />\n<BR />\n(provided by <a href=\"http://www.weather.com\" >The Weather Channel</a>)\n<BR />\n]]>","guid":{"isPermaLink":"false"}}}}}}'
|
||||
else:
|
||||
raise NotImplementedError
|
||||
elif query_url.startswith('https://api.openweathermap.org/data/2.5/'):
|
||||
if 'Meppen' in query_url or '52.6833' in query_url:
|
||||
return r'{"coord":{"lon":7.29,"lat":52.69},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"stations","main":{"temp":293.15,"feels_like":295.16,"temp_min":293.15,"temp_max":295.37,"pressure":1018,"humidity":77},"visibility":10000,"wind":{"speed":1.12,"deg":126},"clouds":{"all":0},"dt":1600196220,"sys":{"type":1,"id":1871,"country":"DE","sunrise":1600146332,"sunset":1600191996},"timezone":7200,"id":2871845,"name":"Meppen","cod":200}'
|
||||
elif 'Moscow' in query_url:
|
||||
return r'{"coord":{"lon":37.62,"lat":55.75},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"stations","main":{"temp":283.15,"feels_like":280.78,"temp_min":283.15,"temp_max":284.26,"pressure":1019,"humidity":71},"visibility":10000,"wind":{"speed":3,"deg":330},"clouds":{"all":0},"dt":1600196224,"sys":{"type":1,"id":9029,"country":"RU","sunrise":1600138909,"sunset":1600184863},"timezone":10800,"id":524901,"name":"Moscow","cod":200}'
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Process(object):
|
||||
|
@ -8,14 +8,16 @@ from tests.modules import TestCase
|
||||
|
||||
|
||||
class TestI3WM(TestCase):
|
||||
workspaces = [
|
||||
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),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_workspaces():
|
||||
return iter([
|
||||
{'name': '1: w1', 'output': 'LVDS1', 'focused': False, 'urgent': False, 'visible': False},
|
||||
{'name': '2: w2', 'output': 'LVDS1', 'focused': False, 'urgent': False, 'visible': True},
|
||||
{'name': '3: w3', 'output': 'HDMI1', 'focused': False, 'urgent': True, 'visible': True},
|
||||
{'name': '4: w4', 'output': 'DVI01', 'focused': True, 'urgent': True, 'visible': True},
|
||||
])
|
||||
return iter(TestI3WM.workspaces)
|
||||
|
||||
@staticmethod
|
||||
def get_outputs(pl):
|
||||
@ -46,42 +48,22 @@ class TestI3WM(TestCase):
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'LVDS1',
|
||||
'workspace': {
|
||||
'name': '1: w1',
|
||||
'focused': False,
|
||||
'urgent': False,
|
||||
'visible': False
|
||||
}
|
||||
'workspace': self.workspaces[0],
|
||||
}, {'draw_inner_divider': None}),
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'LVDS1',
|
||||
'workspace': {
|
||||
'name': '2: w2',
|
||||
'focused': False,
|
||||
'urgent': False,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[1],
|
||||
}, {'draw_inner_divider': None}),
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'HDMI1',
|
||||
'workspace': {
|
||||
'name': '3: w3',
|
||||
'focused': False,
|
||||
'urgent': True,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[2],
|
||||
}, {'draw_inner_divider': None}),
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'DVI01',
|
||||
'workspace': {
|
||||
'name': '4: w4',
|
||||
'focused': True,
|
||||
'urgent': True,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[3],
|
||||
}, {'draw_inner_divider': None}),
|
||||
]
|
||||
)
|
||||
@ -92,22 +74,12 @@ class TestI3WM(TestCase):
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'LVDS1',
|
||||
'workspace': {
|
||||
'name': '1: w1',
|
||||
'focused': False,
|
||||
'urgent': False,
|
||||
'visible': False
|
||||
}
|
||||
'workspace': self.workspaces[0],
|
||||
}, {'draw_inner_divider': None}),
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'LVDS1',
|
||||
'workspace': {
|
||||
'name': '2: w2',
|
||||
'focused': False,
|
||||
'urgent': False,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[1],
|
||||
}, {'draw_inner_divider': None}),
|
||||
]
|
||||
)
|
||||
@ -121,22 +93,12 @@ class TestI3WM(TestCase):
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'LVDS1',
|
||||
'workspace': {
|
||||
'name': '1: w1',
|
||||
'focused': False,
|
||||
'urgent': False,
|
||||
'visible': False
|
||||
}
|
||||
'workspace': self.workspaces[0],
|
||||
}, {'draw_inner_divider': None}),
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'LVDS1',
|
||||
'workspace': {
|
||||
'name': '2: w2',
|
||||
'focused': False,
|
||||
'urgent': False,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[1],
|
||||
}, {'draw_inner_divider': None}),
|
||||
]
|
||||
)
|
||||
@ -151,42 +113,22 @@ class TestI3WM(TestCase):
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'LVDS1',
|
||||
'workspace': {
|
||||
'name': '1: w1',
|
||||
'focused': False,
|
||||
'urgent': False,
|
||||
'visible': False
|
||||
}
|
||||
'workspace': self.workspaces[0],
|
||||
}, {'draw_inner_divider': None}),
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'LVDS1',
|
||||
'workspace': {
|
||||
'name': '2: w2',
|
||||
'focused': False,
|
||||
'urgent': False,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[1],
|
||||
}, {'draw_inner_divider': None}),
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'HDMI1',
|
||||
'workspace': {
|
||||
'name': '3: w3',
|
||||
'focused': False,
|
||||
'urgent': True,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[2],
|
||||
}, {'draw_inner_divider': None}),
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'DVI01',
|
||||
'workspace': {
|
||||
'name': '4: w4',
|
||||
'focused': True,
|
||||
'urgent': True,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[3],
|
||||
}, {'draw_inner_divider': None}),
|
||||
]
|
||||
)
|
||||
@ -201,22 +143,12 @@ class TestI3WM(TestCase):
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'HDMI1',
|
||||
'workspace': {
|
||||
'name': '3: w3',
|
||||
'focused': False,
|
||||
'urgent': True,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[2],
|
||||
}, {'draw_inner_divider': None}),
|
||||
({
|
||||
'a': 1,
|
||||
'output': 'DVI01',
|
||||
'workspace': {
|
||||
'name': '4: w4',
|
||||
'focused': True,
|
||||
'urgent': True,
|
||||
'visible': True
|
||||
}
|
||||
'workspace': self.workspaces[3],
|
||||
}, {'draw_inner_divider': None}),
|
||||
]
|
||||
)
|
||||
|
@ -687,6 +687,10 @@ class TestEnv(TestCommon):
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignore_conda=True), 'ghi')
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignore_venv=True), None)
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignore_venv=True, ignore_conda=True), None)
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignored_names=["aaa"]), "ghi")
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignored_names=["ghi"]), "def")
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignored_names=["def", "ghi"]), "abc")
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignored_names=["abc", "def", "ghi"]), None)
|
||||
|
||||
segment_info['environ'].pop('VIRTUAL_ENV')
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info), None)
|
||||
@ -696,6 +700,7 @@ class TestEnv(TestCommon):
|
||||
|
||||
with replace_env('CONDA_DEFAULT_ENV', 'foo') as segment_info:
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info), 'foo')
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignored_names=["foo"]), None)
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignore_conda=True), None)
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignore_venv=True), 'foo')
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignore_venv=True, ignore_conda=True), None)
|
||||
@ -718,6 +723,9 @@ class TestEnv(TestCommon):
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignore_venv=True), None)
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info, ignore_venv=True, ignore_conda=True), None)
|
||||
|
||||
with replace_env('VIRTUAL_ENV', '/abc/def/venv') as segment_info:
|
||||
self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info), 'def')
|
||||
|
||||
def test_environment(self):
|
||||
pl = Pl()
|
||||
variable = 'FOO'
|
||||
@ -819,9 +827,11 @@ class TestTime(TestCommon):
|
||||
|
||||
def test_date(self):
|
||||
pl = Pl()
|
||||
with replace_attr(self.module, 'datetime', Args(now=lambda: Args(strftime=lambda fmt: fmt))):
|
||||
with replace_attr(self.module, 'datetime', Args(strptime=lambda timezone, fmt: Args(tzinfo=timezone), now=lambda tz:Args(strftime=lambda fmt: fmt + (tz if tz else '')))):
|
||||
self.assertEqual(self.module.date(pl=pl), [{'contents': '%Y-%m-%d', 'highlight_groups': ['date'], 'divider_highlight_group': None}])
|
||||
self.assertEqual(self.module.date(pl=pl, timezone='+0900'), [{'contents': '%Y-%m-%d+0900', 'highlight_groups': ['date'], 'divider_highlight_group': None}])
|
||||
self.assertEqual(self.module.date(pl=pl, format='%H:%M', istime=True), [{'contents': '%H:%M', 'highlight_groups': ['time', 'date'], 'divider_highlight_group': 'time:divider'}])
|
||||
self.assertEqual(self.module.date(pl=pl, format='%H:%M', istime=True, timezone='-0900'), [{'contents': '%H:%M-0900', 'highlight_groups': ['time', 'date'], 'divider_highlight_group': 'time:divider'}])
|
||||
unicode_date = self.module.date(pl=pl, format='\u231a', istime=True)
|
||||
expected_unicode_date = [{'contents': '\u231a', 'highlight_groups': ['time', 'date'], 'divider_highlight_group': 'time:divider'}]
|
||||
if python_implementation() == 'PyPy' and sys.version_info >= (3,):
|
||||
@ -832,23 +842,49 @@ class TestTime(TestCommon):
|
||||
def test_fuzzy_time(self):
|
||||
time = Args(hour=0, minute=45)
|
||||
pl = Pl()
|
||||
with replace_attr(self.module, 'datetime', Args(now=lambda: time)):
|
||||
hour_str = ['12', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven']
|
||||
minute_str = {'0': 'o\'clock', '5': 'five past', '10': 'ten past','15':
|
||||
'quarter past','20': 'twenty past', '25': 'twenty-five past',
|
||||
'30': 'half past', '35': 'twenty-five to','40': 'twenty to', '45':
|
||||
'quarter to', '50': 'ten to', '55': 'five to'}
|
||||
special_case_str = {
|
||||
'(23, 58)': '~ midnight',
|
||||
'(23, 59)': '~ midnight',
|
||||
'(0, 0)': 'midnight',
|
||||
'(0, 1)': '~ midnight',
|
||||
'(0, 2)': '~ midnight',
|
||||
'(12, 0)': 'twelve o\'clock'}
|
||||
with replace_attr(self.module, 'datetime', Args(strptime=lambda timezone, fmt: Args(tzinfo=timezone), now=lambda tz: time)):
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'quarter to one')
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl), 'quarter to one')
|
||||
time.hour = 23
|
||||
time.minute = 59
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), '~ midnight')
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl), 'round about midnight')
|
||||
time.hour = 11
|
||||
time.minute = 33
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str),'twenty-five to 12')
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl), 'twenty-five to twelve')
|
||||
time.minute = 60
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl), 'twelve o\'clock')
|
||||
time.hour = 12
|
||||
time.minute = 0
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twelve o\'clock')
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl), 'noon')
|
||||
time.hour = 11
|
||||
time.minute = 33
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twenty-five to 12')
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False), 'twenty-five to twelve')
|
||||
time.minute = 60
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False), 'twelve o\'clock')
|
||||
time.hour = 12
|
||||
time.minute = 0
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twelve o\'clock')
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False), 'noon')
|
||||
time.hour = 11
|
||||
time.minute = 33
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twenty‐five to 12')
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True), 'twenty‐five to twelve')
|
||||
time.minute = 60
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True), 'twelve o’clock')
|
||||
time.hour = 12
|
||||
time.minute = 0
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True, hour_str=hour_str, minute_str=minute_str, special_case_str=special_case_str), 'twelve o’clock')
|
||||
self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True),'noon')
|
||||
|
||||
|
||||
class TestSys(TestCommon):
|
||||
@ -857,10 +893,10 @@ class TestSys(TestCommon):
|
||||
def test_uptime(self):
|
||||
pl = Pl()
|
||||
with replace_attr(self.module, '_get_uptime', lambda: 259200):
|
||||
self.assertEqual(self.module.uptime(pl=pl), [{'contents': '3d', 'divider_highlight_group': 'background:divider'}])
|
||||
self.assertEqual(self.module.uptime(pl=pl), [{'contents': '3d 0h 00m', 'divider_highlight_group': 'background:divider'}])
|
||||
with replace_attr(self.module, '_get_uptime', lambda: 93784):
|
||||
self.assertEqual(self.module.uptime(pl=pl), [{'contents': '1d 2h 3m', 'divider_highlight_group': 'background:divider'}])
|
||||
self.assertEqual(self.module.uptime(pl=pl, shorten_len=4), [{'contents': '1d 2h 3m 4s', 'divider_highlight_group': 'background:divider'}])
|
||||
self.assertEqual(self.module.uptime(pl=pl), [{'contents': '1d 2h 03m', 'divider_highlight_group': 'background:divider'}])
|
||||
self.assertEqual(self.module.uptime(pl=pl, shorten_len=4), [{'contents': '1d 2h 03m 04s', 'divider_highlight_group': 'background:divider'}])
|
||||
with replace_attr(self.module, '_get_uptime', lambda: 65536):
|
||||
self.assertEqual(self.module.uptime(pl=pl), [{'contents': '18h 12m 16s', 'divider_highlight_group': 'background:divider'}])
|
||||
self.assertEqual(self.module.uptime(pl=pl, shorten_len=2), [{'contents': '18h 12m', 'divider_highlight_group': 'background:divider'}])
|
||||
@ -919,46 +955,47 @@ class TestWthr(TestCommon):
|
||||
pl = Pl()
|
||||
with replace_attr(self.module, 'urllib_read', urllib_read):
|
||||
self.assertEqual(self.module.weather(pl=pl), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'WINDY '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '14°C', 'gradient_level': 62.857142857142854}
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_sunny', 'weather_conditions', 'weather'], 'contents': 'SUN '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '20°C', 'gradient_level': 71.42857142857143}
|
||||
])
|
||||
self.assertEqual(self.module.weather(pl=pl, temp_coldest=0, temp_hottest=100), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'WINDY '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '14°C', 'gradient_level': 14.0}
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_sunny', 'weather_conditions', 'weather'], 'contents': 'SUN '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '20°C', 'gradient_level': 20}
|
||||
])
|
||||
self.assertEqual(self.module.weather(pl=pl, temp_coldest=-100, temp_hottest=-50), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'WINDY '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '14°C', 'gradient_level': 100}
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_sunny', 'weather_conditions', 'weather'], 'contents': 'SUN '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '20°C', 'gradient_level': 100}
|
||||
])
|
||||
self.assertEqual(self.module.weather(pl=pl, icons={'blustery': 'o'}), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'o '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '14°C', 'gradient_level': 62.857142857142854}
|
||||
])
|
||||
self.assertEqual(self.module.weather(pl=pl, icons={'windy': 'x'}), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'x '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '14°C', 'gradient_level': 62.857142857142854}
|
||||
self.assertEqual(self.module.weather(pl=pl, icons={'sunny': 'o'}), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_sunny', 'weather_conditions', 'weather'], 'contents': 'o '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '20°C', 'gradient_level': 71.42857142857143}
|
||||
])
|
||||
# Test is disabled as no request has more than 1 weather condition associated currently
|
||||
# self.assertEqual(self.module.weather(pl=pl, icons={'windy': 'x'}), [
|
||||
# {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'x '},
|
||||
# {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '14°C', 'gradient_level': 62.857142857142854}
|
||||
# ])
|
||||
self.assertEqual(self.module.weather(pl=pl, unit='F'), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'WINDY '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '57°F', 'gradient_level': 62.857142857142854}
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_sunny', 'weather_conditions', 'weather'], 'contents': 'SUN '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '68°F', 'gradient_level': 100}
|
||||
])
|
||||
self.assertEqual(self.module.weather(pl=pl, unit='K'), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'WINDY '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '287K', 'gradient_level': 62.857142857142854}
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_sunny', 'weather_conditions', 'weather'], 'contents': 'SUN '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '293K', 'gradient_level': 100}
|
||||
])
|
||||
self.assertEqual(self.module.weather(pl=pl, temp_format='{temp:.1e}C'), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'WINDY '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '1.4e+01C', 'gradient_level': 62.857142857142854}
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_sunny', 'weather_conditions', 'weather'], 'contents': 'SUN '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '2.0e+01C', 'gradient_level': 71.42857142857143}
|
||||
])
|
||||
with replace_attr(self.module, 'urllib_read', urllib_read):
|
||||
self.module.weather.startup(pl=pl, location_query='Meppen,06,DE')
|
||||
self.assertEqual(self.module.weather(pl=pl), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_blustery', 'weather_condition_windy', 'weather_conditions', 'weather'], 'contents': 'WINDY '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '14°C', 'gradient_level': 62.857142857142854}
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_sunny', 'weather_conditions', 'weather'], 'contents': 'SUN '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '20°C', 'gradient_level': 71.42857142857143}
|
||||
])
|
||||
self.assertEqual(self.module.weather(pl=pl, location_query='Moscow,RU'), [
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_fair_night', 'weather_condition_night', 'weather_conditions', 'weather'], 'contents': 'NIGHT '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '9°C', 'gradient_level': 55.714285714285715}
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_sunny', 'weather_conditions', 'weather'], 'contents': 'SUN '},
|
||||
{'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '10°C', 'gradient_level': 57.142857142857146}
|
||||
])
|
||||
self.module.weather.shutdown()
|
||||
|
||||
@ -967,10 +1004,10 @@ class TestI3WM(TestCase):
|
||||
@staticmethod
|
||||
def get_workspaces():
|
||||
return iter([
|
||||
{'name': '1: w1', 'output': 'LVDS1', 'focused': False, 'urgent': False, 'visible': False},
|
||||
{'name': '2: w2', 'output': 'LVDS1', 'focused': False, 'urgent': False, 'visible': True},
|
||||
{'name': '3: w3', 'output': 'HDMI1', 'focused': False, 'urgent': True, 'visible': True},
|
||||
{'name': '4: w4', 'output': 'DVI01', 'focused': True, 'urgent': True, 'visible': True},
|
||||
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):
|
||||
@ -1056,7 +1093,7 @@ class TestI3WM(TestCase):
|
||||
def get_tree(self):
|
||||
return self
|
||||
|
||||
def descendents(self):
|
||||
def descendants(self):
|
||||
nodes_unfocused = [Args(focused = False)]
|
||||
nodes_focused = [Args(focused = True)]
|
||||
|
||||
|
@ -4,6 +4,7 @@ set_theme_option() {
|
||||
set_theme() {
|
||||
export POWERLINE_CONFIG_OVERRIDES="ext.shell.theme=$1"
|
||||
}
|
||||
set_theme_option default.segment_data.hostname.args.only_if_ssh false
|
||||
set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false
|
||||
ABOVE_LEFT='[{
|
||||
"left": [
|
||||
@ -40,7 +41,9 @@ VIRTUAL_ENV=
|
||||
bgscript.sh & waitpid.sh
|
||||
false
|
||||
kill `cat pid` ; sleep 1s
|
||||
set_theme_option default.segment_data.hostname.display false
|
||||
set_theme_option default_leftonly.segment_data.hostname.display false
|
||||
set_theme_option default.segment_data.user.display false
|
||||
set_theme_option default_leftonly.segment_data.user.display false
|
||||
echo '
|
||||
abc
|
||||
@ -56,14 +59,15 @@ cd ../'$(echo)'
|
||||
cd ../'`echo`'
|
||||
cd ../'«Unicode!»'
|
||||
(exit 42)|(exit 43)
|
||||
set_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
|
||||
set_theme default
|
||||
set_theme_option default.segments.above "$ABOVE_LEFT"
|
||||
export DISPLAYED_ENV_VAR=foo
|
||||
unset DISPLAYED_ENV_VAR
|
||||
set_theme_option default_leftonly.segments.above "$ABOVE_FULL"
|
||||
set_theme_option default.segments.above "$ABOVE_FULL"
|
||||
export DISPLAYED_ENV_VAR=foo
|
||||
unset DISPLAYED_ENV_VAR
|
||||
set_theme_option default_leftonly.segments.above
|
||||
set_theme_option default_leftonly.dividers.left.hard \$ABC
|
||||
set_theme_option default.segments.above
|
||||
set_theme_option default.dividers.left.hard \$ABC
|
||||
false
|
||||
true is the last line
|
||||
exit
|
||||
|
@ -7,7 +7,9 @@
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;49;22m [0mfalse
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;48;5;52;22m [0;38;5;231;48;5;52m1 [0;38;5;52;49;22m [0mkill `cat pid` ; sleep 1s
|
||||
[1]+ Terminated bgscript.sh
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mset_theme_option default.segment_data.hostname.display false
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segment_data.hostname.display false
|
||||
[0;38;5;231;48;5;31;1m USER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mset_theme_option default.segment_data.user.display false
|
||||
[0;38;5;231;48;5;31;1m USER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segment_data.user.display false
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mecho '
|
||||
[0;38;5;252;48;5;240;1m [0;38;5;240;49;22m [0mabc
|
||||
@ -27,16 +29,17 @@ def
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m$(echo) [0;38;5;240;49;22m [0mcd ../'`echo`'
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m`echo` [0;38;5;240;49;22m [0mcd ../'«Unicode!»'
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m(exit 42)|(exit 43)
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;48;5;52;22m [0;38;5;231;48;5;52m42 [0;38;5;231;48;5;52;22m [0;38;5;231;48;5;52m43 [0;38;5;52;49;22m [0mset_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;48;5;52;22m [0;38;5;231;48;5;52m42 [0;38;5;231;48;5;52;22m [0;38;5;231;48;5;52m43 [0;38;5;52;49;22m [0mset_theme default
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uset_theme_option default.segments.above "$ABOVE_LEFT"
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;231;48;5;22m foo [0;38;5;22;49;22m [0m
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0munset DISPLAYED_ENV_VAR
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segments.above "$ABOVE_FULL"
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uunset DISPLAYED_ENV_VAR
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uset_theme_option default.segments.above "$ABOVE_FULL"
|
||||
[0;38;5;231;48;5;233m [0m
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;231;48;5;233m [0;38;5;22;48;5;233;22m [0;38;5;231;48;5;22m foo [0m
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0munset DISPLAYED_ENV_VAR
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uunset DISPLAYED_ENV_VAR
|
||||
[0;38;5;231;48;5;233m [0m
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segments.above
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mset_theme_option default_leftonly.dividers.left.hard \$ABC
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m$ABC[0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m$ABC[0mfalse
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uset_theme_option default.segments.above
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uset_theme_option default.dividers.left.hard \$ABC
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m$ABC[0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[ufalse
|
||||
|
@ -7,7 +7,9 @@
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;49;22m [0mfalse
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;48;5;166;22m [0;38;5;220;48;5;166m1 [0;38;5;166;48;5;52;22m [0;38;5;231;48;5;52m1 [0;38;5;52;49;22m [0mkill `cat pid` ; sleep 1s
|
||||
[1]+ Terminated bgscript.sh
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mset_theme_option default.segment_data.hostname.display false
|
||||
[0;38;5;220;48;5;166m HOSTNAME [0;38;5;166;48;5;31;22m [0;38;5;231;48;5;31;1mUSER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segment_data.hostname.display false
|
||||
[0;38;5;231;48;5;31;1m USER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mset_theme_option default.segment_data.user.display false
|
||||
[0;38;5;231;48;5;31;1m USER [0;38;5;31;48;5;236;22m [0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segment_data.user.display false
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mtmp [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m3rd [0;38;5;240;49;22m [0mecho '
|
||||
[0;38;5;252;48;5;240;1m [0;38;5;240;49;22m [0mabc
|
||||
@ -27,16 +29,17 @@ def
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m$(echo) [0;38;5;240;49;22m [0mcd ../'`echo`'
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m`echo` [0;38;5;240;49;22m [0mcd ../'«Unicode!»'
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m(exit 42)|(exit 43)
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;48;5;52;22m [0;38;5;231;48;5;52m42 [0;38;5;231;48;5;52;22m [0;38;5;231;48;5;52m43 [0;38;5;52;49;22m [0mset_theme_option default_leftonly.segments.above "$ABOVE_LEFT"
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;48;5;52;22m [0;38;5;231;48;5;52m42 [0;38;5;231;48;5;52;22m [0;38;5;231;48;5;52m43 [0;38;5;52;49;22m [0mset_theme default
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uset_theme_option default.segments.above "$ABOVE_LEFT"
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;231;48;5;22m foo [0;38;5;22;49;22m [0m
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0munset DISPLAYED_ENV_VAR
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segments.above "$ABOVE_FULL"
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uunset DISPLAYED_ENV_VAR
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uset_theme_option default.segments.above "$ABOVE_FULL"
|
||||
[0;38;5;231;48;5;233m [0m
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uexport DISPLAYED_ENV_VAR=foo
|
||||
[0;38;5;231;48;5;233m [0;38;5;22;48;5;233;22m [0;38;5;231;48;5;22m foo [0m
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0munset DISPLAYED_ENV_VAR
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uunset DISPLAYED_ENV_VAR
|
||||
[0;38;5;231;48;5;233m [0m
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mset_theme_option default_leftonly.segments.above
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m [0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0mset_theme_option default_leftonly.dividers.left.hard \$ABC
|
||||
[0;38;5;250;48;5;236m BRANCH [0;38;5;236;48;5;240;22m$ABC[0;38;5;250;48;5;240m… [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m$ABC[0mfalse
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uset_theme_option default.segments.above
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m [0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[uset_theme_option default.dividers.left.hard \$ABC
|
||||
[0;38;5;250;48;5;240m … [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240mshell [0;38;5;245;48;5;240;22m [0;38;5;250;48;5;240m3rd [0;38;5;245;48;5;240;22m [0;38;5;252;48;5;240;1m«Unicode!» [0;38;5;240;49;22m$ABC[0m[s[300C[11D[0;38;5;236;49;22m [0;38;5;250;48;5;236m BRANCH [0m[ufalse
|
||||
|
Loading…
x
Reference in New Issue
Block a user