Deprecate "bar" bindings in favor of lemonbar

This commit is contained in:
S0lll0s 2016-01-05 01:15:09 +01:00
parent 7b60b941fd
commit ee5f471b49
10 changed files with 212 additions and 74 deletions

View File

@ -187,6 +187,10 @@ Common configuration is a subdictionary that is a value of ``ext`` key in
``out`` and ``rewrite`` prompts (refer to IPython documentation for more
details) while ``in`` prompt is the default.
For wm (:ref:`lemonbar <lemonbar-usage>` only) it is a dictionary
``{output : theme_name}`` that maps the ``xrandr`` output names to the
local themes to use on that output.
``components``
Determines which extension components should be enabled. This key is highly
extension-specific, here is the table of extensions and corresponding

View File

@ -50,24 +50,27 @@ Add the following to :file:`~/.config/qtile/config.py`:
),
]
.. _bar-usage:
.. _lemonbar-usage:
bar-aint-recursive
==================
lemonbar (formerly bar-aint-recursive)
======================================
To run the bar simply pipe the output of the binding script into ``bar`` and
specify appropriate options, for example like this::
To run the bar simply start the binding script:
python /path/to/powerline/bindings/bar/powerline-bar.py | bar
python /path/to/powerline/bindings/lemonbar/powerline-lemonbar.py
to run with i3, simply ``exec`` this in i3 config file::
You can specify options to be passed to ``lemonbar`` after ``--``, like so:
exec python /path/to/powerline/bindings/bar/powerline-bar.py --i3 | bar
python /path/to/powerline/bindings/lemonbar/powerline-lemonbar.py --height 16 -- -f "Source Code Pro for Powerline-9"
to run with i3, simply ``exec`` this in the i3 config file and set the ``--i3`` switch:
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>`_).
See the `bar documentation <https://github.com/LemonBoy/bar>`_ for more
See the `lemonbar documentation <https://github.com/LemonBoy/bar>`_ for more
information and options.
I3 bar

View File

@ -2,31 +2,27 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
import sys
import time
from threading import Lock, Timer
from argparse import ArgumentParser
from powerline import Powerline
from powerline.lemonbar import LemonbarPowerline
from powerline.lib.encoding import get_unicode_writer
class BarPowerline(Powerline):
get_encoding = staticmethod(lambda: 'utf-8')
def init(self):
super(BarPowerline, self).init(ext='wm', renderer_module='bar')
if __name__ == '__main__':
parser = ArgumentParser(description='Powerline BAR bindings.')
parser = ArgumentParser(description='Powerline lemonbar bindings.')
parser.add_argument(
'--i3', action='store_true',
help='Subscribe for i3 events.'
)
args = parser.parse_args()
powerline = BarPowerline()
powerline = LemonbarPowerline()
powerline.update_renderer()
powerline.pl.warn("The 'bar' bindings are deprecated, please switch to 'lemonbar'")
lock = Lock()
modes = ['default']
write = get_unicode_writer(encoding='utf-8')
@ -60,4 +56,4 @@ if __name__ == '__main__':
conn.main()
while True:
time.sleep(1e10)
time.sleep(1e8)

View File

@ -0,0 +1,91 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import time
import re
import subprocess
from threading import Lock, Timer
from argparse import ArgumentParser, REMAINDER
from powerline.lemonbar import LemonbarPowerline
from powerline.lib.shell import run_cmd
if __name__ == '__main__':
parser = ArgumentParser(
description='Powerline BAR bindings.',
usage='%(prog)s [-h] [--i3] [--height HEIGHT] [--interval INTERVAL] [--bar-command CMD] -- args'
)
parser.add_argument(
'--i3', action='store_true',
help='Subscribe for i3 events.'
)
parser.add_argument(
'--height', default='',
help='Bar height.'
)
parser.add_argument(
'--interval', '-i',
type=float, default=0.5,
help='Refresh interval.'
)
parser.add_argument(
'--bar-command', '-c',
default='lemonbar',
help='Name of the lemonbar executable to use.'
)
parser.add_argument(
'args', nargs=REMAINDER,
help='Extra arguments for lemonbar.'
)
args = parser.parse_args()
powerline = LemonbarPowerline()
powerline.update_renderer()
bars = []
active_screens = [match.groupdict() for match in re.finditer(
'^(?P<name>[0-9A-Za-z-]+) connected (?P<width>\d+)x(?P<height>\d+)\+(?P<x>\d+)\+(?P<y>\d+)',
run_cmd(powerline.pl, ['xrandr', '-q']),
re.MULTILINE
)]
for screen in active_screens:
command = [args.bar_command, '-g', '{0}x{1}+{2}'.format(screen['width'], args.height, screen['x'])] + args.args[1:]
process = subprocess.Popen(command, stdin=subprocess.PIPE)
bars.append((screen['name'], process, int(screen['width']) / 5))
lock = Lock()
modes = ['default']
def render(reschedule=False):
if reschedule:
Timer(args.interval, render, kwargs={'reschedule': True}).start()
global lock
with lock:
for output, process, width in bars:
process.stdin.write(powerline.render(mode=modes[0], width=width, matcher_info=output).encode('utf-8') + b'\n')
process.stdin.flush()
def update(evt):
modes[0] = evt.change
render()
render(reschedule=True)
if args.i3:
try:
import i3ipc
except ImportError:
import i3
i3.Subscription(lambda evt, data, sub: render(), 'workspace')
else:
conn = i3ipc.Connection()
conn.on('workspace::focus', lambda conn, evt: render())
conn.on('mode', lambda conn, evt: update(evt))
conn.main()
while True:
time.sleep(1e8)

21
powerline/lemonbar.py Normal file
View File

@ -0,0 +1,21 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline import Powerline
from powerline.lib.dict import mergedicts
class LemonbarPowerline(Powerline):
def init(self):
super(LemonbarPowerline, self).init(ext='wm', renderer_module='lemonbar')
get_encoding = staticmethod(lambda: 'utf-8')
def get_local_themes(self, local_themes):
if not local_themes:
return {}
return dict((
(key, {'config': self.load_theme_config(val)})
for key, val in local_themes.items()
))

View File

@ -126,6 +126,12 @@ main_spec = (Spec(
select=ext_theme_spec(),
),
).optional(),
wm=ext_spec().update(
local_themes=Spec().unknown_spec(
Spec().re('^[0-9A-Za-z-]+$'),
ext_theme_spec()
).optional()
).optional(),
).unknown_spec(
check_ext,
ext_spec(),

View File

@ -1,45 +0,0 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline.renderer import Renderer
from powerline.colorscheme import ATTR_UNDERLINE
class BarRenderer(Renderer):
'''bar (bar ain't recursive) renderer
See documentation of `bar <https://github.com/LemonBoy/bar>`_ and :ref:`the usage instructions <bar-usage>`
'''
character_translations = Renderer.character_translations.copy()
character_translations[ord('%')] = '%%'
@staticmethod
def hlstyle(*args, **kwargs):
# We dont need to explicitly reset attributes, so skip those calls
return ''
def hl(self, contents, fg=None, bg=None, attrs=None):
text = ''
if fg is not None:
if fg is not False and fg[1] is not False:
text += '%{{F#ff{0:06x}}}'.format(fg[1])
if bg is not None:
if bg is not False and bg[1] is not False:
text += '%{{B#ff{0:06x}}}'.format(bg[1])
if attrs & ATTR_UNDERLINE:
text += '%{+u}'
return text + contents + '%{F-B--u}'
def render(self, *args, **kwargs):
return '%{{l}}{0}%{{r}}{1}'.format(
super(BarRenderer, self).render(side='left', *args, **kwargs),
super(BarRenderer, self).render(side='right', *args, **kwargs),
)
renderer = BarRenderer

View File

@ -0,0 +1,61 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline.renderer import Renderer
from powerline.theme import Theme
from powerline.colorscheme import ATTR_UNDERLINE
class LemonbarRenderer(Renderer):
'''lemonbar (formerly bar/bar ain't recursive) renderer
See documentation of `lemonbar <https://github.com/LemonBoy/bar>`_ and :ref:`the usage instructions <lemonbar-usage>`
'''
character_translations = Renderer.character_translations.copy()
character_translations[ord('%')] = '%%{}'
@staticmethod
def hlstyle(*args, **kwargs):
# We dont need to explicitly reset attributes, so skip those calls
return ''
def hl(self, contents, fg=None, bg=None, attrs=None):
text = ''
if fg is not None:
if fg is not False and fg[1] is not False:
text += '%{{F#ff{0:06x}}}'.format(fg[1])
if bg is not None:
if bg is not False and bg[1] is not False:
text += '%{{B#ff{0:06x}}}'.format(bg[1])
if attrs & ATTR_UNDERLINE:
text += '%{+u}'
return text + contents + '%{F-B--u}'
def render(self, *args, **kwargs):
return '%{{l}}{0}%{{r}}{1}'.format(
super(LemonbarRenderer, self).render(side='left', segment_info={'output': kwargs.get('matcher_info')}, *args, **kwargs),
super(LemonbarRenderer, self).render(side='right', segment_info={'output': kwargs.get('matcher_info')}, *args, **kwargs),
)
def get_theme(self, matcher_info):
if not matcher_info or matcher_info not in self.local_themes:
return self.theme
match = self.local_themes[matcher_info]
try:
return match['theme']
except KeyError:
match['theme'] = Theme(
theme_config=match['config'],
main_theme_config=self.theme_config,
**self.theme_kwargs
)
return match['theme']
renderer = LemonbarRenderer

View File

@ -29,8 +29,9 @@ def workspaces(pl, segment_info, only_show=None, output=None, strip=0):
are shown.
:param str output:
If specified, only workspaces on this output are shown. If unspecified,
may be set by the lemonbar renderer and bindings.
May be set to the name of an X output. If specified, only workspaces
on that output are shown. Overrides automatic output detection by
the lemonbar renderer and bindings.
:param int strip:
Specifies how many characters from the front of each workspace name
@ -47,7 +48,7 @@ def workspaces(pl, segment_info, only_show=None, output=None, strip=0):
else:
conn = i3ipc.Connection()
output = output or ('output' in segment_info and segment_info['output'])
output = output or segment_info.get('output')
return [{
'contents': w['name'][min(len(w['name']), strip):],

View File

@ -825,28 +825,28 @@ class TestVim(TestCase):
sys.path.pop(0)
class TestBar(TestRender):
def test_bar(self):
class TestLemonbar(TestRender):
def test_lemonbar(self):
import powerline as powerline_module
with swap_attributes(config, powerline_module):
with get_powerline_raw(config, powerline_module.Powerline, replace_gcp=True, ext='wm', renderer_module='bar') as powerline:
with get_powerline_raw(config, powerline_module.Powerline, replace_gcp=True, ext='wm', renderer_module='lemonbar') as powerline:
self.assertRenderEqual(
powerline,
'%{l}%{F#ffc00000}%{B#ff008000}%{+u} A%{F-B--u}%{F#ff008000}%{B#ffc00000}>>%{F-B--u}%{F#ff008000}%{B#ffc00000}B%{F-B--u}%{F#ffc00000}>>%{F-B--u}%{r}%{F#ffc00000}<<%{F-B--u}%{F#ff804000}%{B#ffc00000}%{+u}C%{F-B--u}%{F#ff0000c0}%{B#ffc00000}<<%{F-B--u}%{F#ff008000}%{B#ff0000c0}D %{F-B--u}'
)
@with_new_config
def test_bar_escape(self, config):
def test_lemonbar_escape(self, config):
import powerline as powerline_module
config['themes/wm/default']['segments']['left'] = (
highlighted_string('%{asd}', 'hl1'),
highlighted_string('10% %', 'hl2'),
)
with swap_attributes(config, powerline_module):
with get_powerline_raw(config, powerline_module.Powerline, replace_gcp=True, ext='wm', renderer_module='bar') as powerline:
with get_powerline_raw(config, powerline_module.Powerline, replace_gcp=True, ext='wm', renderer_module='lemonbar') as powerline:
self.assertRenderEqual(
powerline,
'%{l}%{F#ffc00000}%{B#ff008000}%{+u} %%{asd}%{F-B--u}%{F#ff008000}%{B#ffc00000}>>%{F-B--u}%{F#ff008000}%{B#ffc00000}10%% %%%{F-B--u}%{F#ffc00000}>>%{F-B--u}%{r}%{F#ffc00000}<<%{F-B--u}%{F#ff804000}%{B#ffc00000}%{+u}C%{F-B--u}%{F#ff0000c0}%{B#ffc00000}<<%{F-B--u}%{F#ff008000}%{B#ff0000c0}D %{F-B--u}'
'%{l}%{F#ffc00000}%{B#ff008000}%{+u} %%{}{asd}%{F-B--u}%{F#ff008000}%{B#ffc00000}>>%{F-B--u}%{F#ff008000}%{B#ffc00000}10%%{} %%{}%{F-B--u}%{F#ffc00000}>>%{F-B--u}%{r}%{F#ffc00000}<<%{F-B--u}%{F#ff804000}%{B#ffc00000}%{+u}C%{F-B--u}%{F#ff0000c0}%{B#ffc00000}<<%{F-B--u}%{F#ff008000}%{B#ff0000c0}D %{F-B--u}'
)