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 ``out`` and ``rewrite`` prompts (refer to IPython documentation for more
details) while ``in`` prompt is the default. 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`` ``components``
Determines which extension components should be enabled. This key is highly Determines which extension components should be enabled. This key is highly
extension-specific, here is the table of extensions and corresponding 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 To run the bar simply start the binding script:
specify appropriate options, for example like this::
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>`_ 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>`_). (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. information and options.
I3 bar I3 bar

View File

@ -2,31 +2,27 @@
# vim:fileencoding=utf-8:noet # vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function) from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
import sys import sys
import time import time
from threading import Lock, Timer from threading import Lock, Timer
from argparse import ArgumentParser from argparse import ArgumentParser
from powerline import Powerline from powerline.lemonbar import LemonbarPowerline
from powerline.lib.encoding import get_unicode_writer 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__': if __name__ == '__main__':
parser = ArgumentParser(description='Powerline BAR bindings.') parser = ArgumentParser(description='Powerline lemonbar bindings.')
parser.add_argument( parser.add_argument(
'--i3', action='store_true', '--i3', action='store_true',
help='Subscribe for i3 events.' help='Subscribe for i3 events.'
) )
args = parser.parse_args() 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() lock = Lock()
modes = ['default'] modes = ['default']
write = get_unicode_writer(encoding='utf-8') write = get_unicode_writer(encoding='utf-8')
@ -60,4 +56,4 @@ if __name__ == '__main__':
conn.main() conn.main()
while True: 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(), select=ext_theme_spec(),
), ),
).optional(), ).optional(),
wm=ext_spec().update(
local_themes=Spec().unknown_spec(
Spec().re('^[0-9A-Za-z-]+$'),
ext_theme_spec()
).optional()
).optional(),
).unknown_spec( ).unknown_spec(
check_ext, check_ext,
ext_spec(), 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. are shown.
:param str output: :param str output:
If specified, only workspaces on this output are shown. If unspecified, May be set to the name of an X output. If specified, only workspaces
may be set by the lemonbar renderer and bindings. on that output are shown. Overrides automatic output detection by
the lemonbar renderer and bindings.
:param int strip: :param int strip:
Specifies how many characters from the front of each workspace name Specifies how many characters from the front of each workspace name
@ -47,7 +48,7 @@ def workspaces(pl, segment_info, only_show=None, output=None, strip=0):
else: else:
conn = i3ipc.Connection() conn = i3ipc.Connection()
output = output or ('output' in segment_info and segment_info['output']) output = output or segment_info.get('output')
return [{ return [{
'contents': w['name'][min(len(w['name']), strip):], 'contents': w['name'][min(len(w['name']), strip):],

View File

@ -825,28 +825,28 @@ class TestVim(TestCase):
sys.path.pop(0) sys.path.pop(0)
class TestBar(TestRender): class TestLemonbar(TestRender):
def test_bar(self): def test_lemonbar(self):
import powerline as powerline_module import powerline as powerline_module
with swap_attributes(config, 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( self.assertRenderEqual(
powerline, 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}' '%{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 @with_new_config
def test_bar_escape(self, config): def test_lemonbar_escape(self, config):
import powerline as powerline_module import powerline as powerline_module
config['themes/wm/default']['segments']['left'] = ( config['themes/wm/default']['segments']['left'] = (
highlighted_string('%{asd}', 'hl1'), highlighted_string('%{asd}', 'hl1'),
highlighted_string('10% %', 'hl2'), highlighted_string('10% %', 'hl2'),
) )
with swap_attributes(config, 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( self.assertRenderEqual(
powerline, 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}'
) )