1
0
Fork 0

Adding upstream version 2.8.4.

Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
Daniel Baumann 2025-06-21 14:32:14 +02:00
parent 09b97de4ea
commit 52d7687863
Signed by: daniel.baumann
GPG key ID: BCC918A2ABD66424
381 changed files with 40831 additions and 0 deletions

20
.editorconfig Normal file
View file

@ -0,0 +1,20 @@
# editorconfig ini file
# Check out http://editorconfig.org for a list of plugins for different
# IDEs/text editors that support this file. Vim plugin to support this:
#
# http://www.vim.org/scripts/script.php?script_id=3934
# https://github.com/editorconfig/editorconfig-vim
root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = tab
# Despite promise somewhere alignment is done only using tabs. Thus setting
# indent_size and tab_width is a requirement.
indent_size = 4
tab_width = 4
charset = utf-8
[*.rst]
indent_style = space

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
*.rst whitespace=-blank-at-eol

46
.github/workflows/main.yaml vendored Normal file
View 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: [3.7, 3.8, 3.9, 3.11, 3.12]
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/

16
.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
tags
*.py[co]
__pycache__
*.egg
*.egg-info
dist
build
message.fail
/client/powerline
/tests/tmp
/tests/status

11
.local.vimrc Normal file
View file

@ -0,0 +1,11 @@
" Project vimrc file. To be sourced each time you open any file in this
" repository. You may use [vimscript #3393][1] [(homepage)][2] to do this
" automatically.
"
" [1]: http://www.vim.org/scripts/script.php?script_id=3393
" [2]: https://github.com/thinca/vim-localrc
let g:syntastic_python_flake8_args = '--ignore=W191,E501,E128,W291,E126,E101'
let b:syntastic_checkers = ['flake8']
unlet! g:python_space_error_highlight
let g:pymode_syntax_indent_errors = 0
let g:pymode_syntax_space_errors = 0

32
.travis.yml Normal file
View file

@ -0,0 +1,32 @@
sudo: false
dist: trusty
cache:
directories:
- $HOME/.cache/pip
- tests/bot-ci
addons:
apt:
packages:
- libssl1.0.0
- zsh
- tcsh
- mksh
- busybox
# - rc
- socat
- bc
language: python
install: tests/install.sh
script: tests/test.sh
jobs:
include:
- stage: PyPy
python: "pypy"
- python: "pypy3"
- stage: Latest Python
python: "3.6"
- stage: Intermediate versions
python: "3.5"
- python: "3.4"
# vim: et

138
CONTRIBUTING.rst Normal file
View file

@ -0,0 +1,138 @@
*****************
How to contribute
*****************
So you want to contribute to the Powerline project? Awesome! This document
describes the guidelines you should follow when making contributions to the
project.
**Please note that these guidelines aren't mandatory in any way, but your
pull request will be merged a lot faster if you follow them.**
Getting started
===============
* Make sure you have a `GitHub account <https://github.com/signup/free>`_.
* Submit an `issue on GitHub <https://github.com/powerline/powerline/issues>`_,
assuming one does not already exist.
* Clearly describe the issue.
* If the issue is a bug: make sure you include steps to reproduce, and
include the earliest revision that you know has the issue.
* Fork the repository on GitHub.
Making changes
==============
* Create a topic branch from where you want to base your work.
* Powerline uses the `Git Flow
<http://nvie.com/posts/a-successful-git-branching-model/>`_ branching
model.
* Most contributions should be based off the ``develop`` branch.
* Prefix your branch with ``feature/`` if you're working on a new feature.
* Include the issue number in your topic branch, e.g.
``321-fix-some-error`` or ``feature/123-a-cool-feature``.
* Make commits of logical units.
* Run your code through ``flake8`` and fix any programming style errors. Use
common sense regarding whitespace warnings, not all warnings need to be
fixed.
* Make sure your commit messages are in the `proper format
<http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`_.
The summary must be no longer than 70 characters. Refer to any related
issues with e.g. ``Ref #123`` or ``Fixes #234`` at the bottom of the
commit message. Commit messages can use Markdown with the following
exceptions:
* No HTML extensions.
* Only indented code blocks (no ``````` blocks).
* Long links should be moved to the bottom if they make the text wrap or
extend past 72 columns.
* Make sure you have added the necessary tests for your changes.
* Run *all* the tests to assure nothing else was accidentally broken.
Programming style
-----------------
* The project uses *tabs for indentation* and *spaces for alignment*, this
is also included in a vim modeline on top of every script file.
* Run your code through ``flake8 --ignore=W191,E501,E128,W291,E126,E101`` to fix
any style errors. Use common sense regarding whitespace warnings, not all
``flake8`` warnings need to be fixed.
* Trailing whitespace to indicate a continuing paragraph is OK in comments,
documentation and commit messages.
* It is allowed to have too long lines. It is advised though to avoid lines
wider then a hundred of characters.
* Imports have the following structure:
1. Shebang and modeline in a form
.. code-block:: python
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
. Modeline is required, shebang is not. If shebang is present file must end
with
.. code-block:: python
if __name__ == '__main__':
# Actual script here
2. Module docstring.
3. ``__future__`` import exactly in a form
.. code-block:: python
from __future__ import (unicode_literals, division, absolute_import, print_function)
(powerline.shell is the only exception due to problems with argparse). It
is not separated by newline with shebang and modeline, but is with
docstring.
4. Standard python library imports in a form ``import X``.
5. Standard python library imports in a form ``from X import Y``.
6. Third-party (non-python and non-powerline) library imports in a form
``import X``.
7. Third-party library imports in a form ``from X import Y``.
8. Powerline non-test imports in a form ``from powerline.X import Y``.
9. Powerline test imports in a form ``import tests.vim as vim_module``.
10. Powerline test imports in a form ``from tests.X import Y``.
Each entry is separated by newline from another entry. Any entry except for
the first and third ones is optional. Example with all entries:
.. code-block:: python
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
'''Powerline super module'''
from __future__ import (unicode_literals, division, absolute_import, print_function)
import sys
from argparse import ArgumentParser
import psutil
from colormath.color_diff import delta_e_cie2000
from powerline.lib.unicode import u
import tests.vim as vim_module
from tests import TestCase
Submitting changes
==================
* Push your changes to a topic branch in your fork of the repository.
* If necessary, use ``git rebase -i <revision>`` to squash or reword commits
before submitting a pull request.
* Submit a pull request to `powerline repository
<https://github.com/powerline/powerline>`_.

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
Copyright 2013 Kim Silkebækken and other contributors
https://github.com/powerline/powerline
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

8
MANIFEST.in Normal file
View file

@ -0,0 +1,8 @@
recursive-include powerline *.json *.vim
recursive-include powerline/bindings *.*
recursive-exclude powerline/bindings *.pyc *.pyo
recursive-include powerline/dist *.*
recursive-include client *.*
recursive-include docs/source *.rst *.py
include docs/Makefile
include LICENSE

120
README.rst Normal file
View file

@ -0,0 +1,120 @@
Powerline
=========
.. 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.**
+---------+---------------------------------------------------+
| Author | Kim Silkebækken (kim.silkebaekken+vim@gmail.com) |
+---------+---------------------------------------------------+
| Source | https://github.com/powerline/powerline |
+---------+---------------------------------------------------+
| Version | beta |
+---------+---------------------------------------------------+
**Powerline does not support python2 anymore and powerline will stop working with python2 in the near future.**
Features
--------
* **Extensible and feature rich, written in Python.** Powerline was
completely rewritten in Python to get rid of as much vimscript as
possible. This has allowed much better extensibility, leaner and better
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 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
bash/zsh and other applications. Its simple to write renderers for any
other applications that Powerline doesnt yet support.
* **Configuration and colorschemes written in JSON.** JSON is
a standardized, simple and easy to use file format that allows for easy
user configuration across all of Powerlines supported applications.
* **Fast and lightweight, with daemon support for even better performance.**
Although the code base spans a couple of thousand lines of code with no
goal of “less than X lines of code”, the main focus is on good performance
and as little code as possible while still providing a rich set of
features. The new daemon also ensures that only one Python instance is
launched for prompts and statuslines, which provides excellent
performance.
*But I hate Python / I dont need shell prompts / this is just too much
hassle for me / what happened to the original vim-powerline project / …*
You should check out some of the Powerline derivatives. The most lightweight
and feature-rich alternative is currently the `vim-airline
<https://github.com/vim-airline/vim-airline>`_ project.
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:
::
.config/powerline/
├── colorschemes
│   ├── ...
│   └── wm
|      └── default.json // Your configuration goes here
├── colors.json
├── config.json
└── themes
├── ...
└── wm
└── default.json // Your configuration goes here
The files in the subdirectories of `themes` are used to specify which segments shall be shown; the files in subdirectories of `colorschemes` are used to specify which colors (as defined in `colors.json`) shall be used to display a segment.
Note that your local configuration only overrides the global configuration, it does not replace it, i.e. if you don't configure something locally, the global default will be used instead.
* Consult the `documentation <https://powerline.readthedocs.org/en/latest/configuration.html#quick-setup-guide>`_ for more details. See also the `segment reference <https://powerline.readthedocs.org/en/latest/configuration/segments.html>`_ for available segments and their configuration.
* Check out `powerline-fonts <https://github.com/powerline/fonts>`_ for
pre-patched versions of popular, open source coding fonts.
Screenshots
-----------
Vim statusline
^^^^^^^^^^^^^^
**Mode-dependent highlighting**
* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-mode-normal.png
:alt: Normal mode
* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-mode-insert.png
:alt: Insert mode
* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-mode-visual.png
:alt: Visual mode
* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-mode-replace.png
:alt: Replace mode
**Automatic truncation of segments in small windows**
* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-truncate1.png
:alt: Truncation illustration
* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-truncate2.png
:alt: Truncation illustration
* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-truncate3.png
:alt: Truncation illustration
----
The font in the screenshots is `Pragmata Pro`_ by Fabrizio Schiavi.
.. _`Pragmata Pro`: http://www.fsd.it/shop/fonts/pragmatapro

164
client/powerline.c Normal file
View file

@ -0,0 +1,164 @@
/* vim:fileencoding=utf-8:noet
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#define HANDLE_ERROR(msg) \
do { \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
#define TEMP_FAILURE_RETRY(var, expression) \
do { \
ptrdiff_t __result; \
do { \
__result = (expression); \
} while (__result == -1L && errno == EINTR); \
var = __result; \
} while (0)
extern char **environ;
void do_write(int sd, const char *raw, size_t len) {
size_t written = 0;
ptrdiff_t n = -1;
while (written < len) {
TEMP_FAILURE_RETRY(n, write(sd, raw + written, len - written));
if (n == -1) {
close(sd);
HANDLE_ERROR("write() failed");
}
written += (size_t) n;
}
}
static inline size_t true_sun_len(const struct sockaddr_un *ptr) {
#ifdef __linux__
/* Because SUN_LEN uses strlen and abstract namespace paths begin
* with a null byte, SUN_LEN is broken for these. Passing the full
* struct size also fails on Linux, so compute manually. The
* abstract namespace is Linux-only. */
if (ptr->sun_path[0] == '\0') {
return sizeof(ptr->sun_family) + strlen(ptr->sun_path + 1) + 1;
}
#endif
#ifdef SUN_LEN
/* If the vendor provided SUN_LEN, we may as well use it. */
return SUN_LEN(ptr);
#else
/* SUN_LEN is not POSIX, so if it was not provided, use the struct
* size as a fallback. */
return sizeof(struct sockaddr_un);
#endif
}
#ifdef __linux__
# define ADDRESS_TEMPLATE "powerline-ipc-%d"
# define A +1
#else
# define ADDRESS_TEMPLATE "/tmp/powerline-ipc-%d"
# define A
#endif
#define ADDRESS_SIZE sizeof(ADDRESS_TEMPLATE) + (sizeof(uid_t) * 4)
#define NUM_ARGS_SIZE (sizeof(int) * 2 + 1)
#define BUF_SIZE 4096
#define NEW_ARGV_SIZE 200
int main(int argc, char *argv[]) {
int sd = -1;
int i;
ptrdiff_t read_size;
struct sockaddr_un server;
char address_buf[ADDRESS_SIZE];
const char eof[2] = "\0\0";
char num_args[NUM_ARGS_SIZE];
char buf[BUF_SIZE];
char *newargv[NEW_ARGV_SIZE];
char *wd = NULL;
char **envp;
const char *address;
int len;
if (argc < 2) {
printf("Must provide at least one argument.\n");
return EXIT_FAILURE;
}
if (argc > 3 && strcmp(argv[1], "--socket") == 0) {
address = argv[2];
argv += 2;
argc -= 2;
} else {
snprintf(address_buf, ADDRESS_SIZE, ADDRESS_TEMPLATE, getuid());
address = &(address_buf[0]);
}
sd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sd == -1)
HANDLE_ERROR("socket() failed");
memset(&server, 0, sizeof(struct sockaddr_un));
server.sun_family = AF_UNIX;
strncpy(server.sun_path A, address, strlen(address));
if (connect(sd, (struct sockaddr *) &server, true_sun_len(&server)) < 0) {
close(sd);
/* We failed to connect to the daemon, execute powerline instead */
argc = (argc < NEW_ARGV_SIZE - 1) ? argc : NEW_ARGV_SIZE - 1;
for (i = 1; i < argc; i++)
newargv[i] = argv[i];
newargv[0] = "powerline-render";
newargv[argc] = NULL;
execvp("powerline-render", newargv);
}
len = snprintf(num_args, NUM_ARGS_SIZE, "%x", argc - 1);
do_write(sd, num_args, len);
do_write(sd, eof, 1);
for (i = 1; i < argc; i++) {
do_write(sd, argv[i], strlen(argv[i]));
do_write(sd, eof, 1);
}
wd = getcwd(NULL, 0);
if (wd != NULL) {
do_write(sd, wd, strlen(wd));
free(wd);
wd = NULL;
}
do_write(sd, eof, 1);
for(envp=environ; *envp; envp++) {
do_write(sd, *envp, strlen(*envp));
do_write(sd, eof, 1);
}
do_write(sd, eof, 2);
read_size = -1;
while (read_size != 0) {
TEMP_FAILURE_RETRY(read_size, read(sd, buf, BUF_SIZE));
if (read_size == -1) {
close(sd);
HANDLE_ERROR("read() failed");
} else if (read_size > 0) {
do_write(STDOUT_FILENO, buf, (size_t) read_size);
}
}
close(sd);
return 0;
}

104
client/powerline.py Executable file
View file

@ -0,0 +1,104 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import sys
import socket
import errno
import os
try:
from posix import environ
except ImportError:
from os import environ
# XXX Hack for importing powerline modules to work.
sys.path.pop(0)
try:
from powerline.lib.encoding import get_preferred_output_encoding
except ImportError:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__)))))
from powerline.lib.encoding import get_preferred_output_encoding
if len(sys.argv) < 2:
print('Must provide at least one argument.', file=sys.stderr)
raise SystemExit(1)
use_filesystem = not sys.platform.lower().startswith('linux')
if sys.argv[1] == '--socket':
address = sys.argv[2]
if not use_filesystem:
address = '\0' + address
del sys.argv[1:3]
else:
address = ('/tmp/powerline-ipc-%d' if use_filesystem else '\0powerline-ipc-%d') % os.getuid()
sock = socket.socket(family=socket.AF_UNIX)
def eintr_retry_call(func, *args, **kwargs):
while True:
try:
return func(*args, **kwargs)
except EnvironmentError as e:
if getattr(e, 'errno', None) == errno.EINTR:
continue
raise
try:
eintr_retry_call(sock.connect, address)
except Exception:
# Run the powerline renderer
args = ['powerline-render'] + sys.argv[1:]
os.execvp('powerline-render', args)
fenc = get_preferred_output_encoding()
def tobytes(s):
if isinstance(s, bytes):
return s
else:
return s.encode(fenc)
args = [tobytes('%x' % (len(sys.argv) - 1))]
args.extend((tobytes(s) for s in sys.argv[1:]))
try:
cwd = os.getcwd()
except EnvironmentError:
pass
else:
if not isinstance(cwd, bytes):
cwd = cwd.encode(fenc)
args.append(cwd)
args.extend((tobytes(k) + b'=' + tobytes(v) for k, v in environ.items()))
EOF = b'\0\0'
for a in args:
eintr_retry_call(sock.sendall, a + b'\0')
eintr_retry_call(sock.sendall, EOF)
received = []
while True:
r = sock.recv(4096)
if not r:
break
received.append(r)
sock.close()
if sys.version_info < (3,):
sys.stdout.write(b''.join(received))
else:
sys.stdout.buffer.write(b''.join(received))

53
client/powerline.sh Executable file
View file

@ -0,0 +1,53 @@
#!/bin/sh
use_filesystem=1
darwin=
if test -n "$OSTYPE" ; then
# OSTYPE variable is a shell feature. supported by bash and zsh, but not
# dash, busybox or (m)ksh.
if test "${OSTYPE#linux}" '!=' "${OSTYPE}" ; then
use_filesystem=
elif test "${OSTYPE#darwin}" ; then
darwin=1
fi
elif command -v uname >/dev/null ; then
if uname -o | grep -iqF linux ; then
use_filesystem=
elif uname -o | grep -iqF darwin ; then
darwin=1
fi
fi
if test "$1" = "--socket" ; then
shift
ADDRESS="$1"
shift
else
ADDRESS="powerline-ipc-${UID:-`id -u`}"
test -n "$use_filesystem" && ADDRESS="/tmp/$ADDRESS"
fi
if test -n "$darwin" ; then
ENV=genv
else
ENV=env
fi
if test -z "$use_filesystem" ; then
ADDRESS="abstract-client:$ADDRESS"
fi
# Warning: env -0 does not work in busybox. Consider switching to parsing
# `set` output in this case
(
printf '%x\0' "$#"
for argv in "$@" ; do
printf '%s\0' "$argv"
done
printf '%s\0' "$PWD"
$ENV -0
) 2>/dev/null | socat -lf/dev/null -t 10 - "$ADDRESS"
if test $? -ne 0 ; then
powerline-render "$@"
fi

1
docs/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
_build

39
docs/Makefile Normal file
View file

@ -0,0 +1,39 @@
# Makefile for Sphinx documentation
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -T -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
GH_PAGES_SOURCES = source Makefile
GH_SOURCE_BRANCH = develop
.PHONY: html clean html latexpdf
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
clean:
-rm -rf $(BUILDDIR)/*
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."

View file

@ -0,0 +1,6 @@
.wy-table-responsive > table > tbody > tr > td {
white-space: unset;
}
.wy-table-responsive > table > tbody > tr > td:first-child {
vertical-align: top;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

9
docs/source/commands.rst Normal file
View file

@ -0,0 +1,9 @@
**************************************
Powerline shell commands manual pages
**************************************
.. toctree::
:maxdepth: 1
:glob:
commands/*

View file

@ -0,0 +1,12 @@
:orphan:
powerline-config manual page
============================
.. automan:: powerline.commands.config
:prog: powerline-config
See also
--------
:manpage:`powerline(1)`

View file

@ -0,0 +1,12 @@
:orphan:
powerline-daemon manual page
============================
.. automan:: powerline.commands.daemon
:prog: powerline-daemon
See also
--------
:manpage:`powerline(1)`

View file

@ -0,0 +1,14 @@
:orphan:
.. _command-powerline-lint:
powerline-lint manual page
==========================
.. automan:: powerline.commands.lint
:prog: powerline-lint
See also
--------
:manpage:`powerline(1)`, :manpage:`powerline-config(1)`

View file

@ -0,0 +1,12 @@
:orphan:
powerline manual page
=====================
.. automan:: powerline.commands.main
:prog: powerline
See also
--------
:manpage:`powerline-daemon(1)`, :manpage:`powerline-config(1)`

70
docs/source/conf.py Normal file
View file

@ -0,0 +1,70 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(os.getcwd()))))
sys.path.insert(0, os.path.abspath(os.getcwd()))
extensions = [
'powerline_autodoc', 'powerline_automan',
'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode',
]
source_suffix = '.rst'
master_doc = 'index'
project = 'Powerline'
version = 'beta'
release = 'beta'
exclude_patterns = ['_build']
pygments_style = 'sphinx'
html_theme = 'default'
html_static_path = ['_static']
html_show_copyright = False
latex_show_urls = 'footnote'
latex_elements = {
'preamble': '''
\\DeclareUnicodeCharacter{22EF}{$\\cdots$} % Dots
\\DeclareUnicodeCharacter{2665}{\\ding{170}} % Heart
\\DeclareUnicodeCharacter{2746}{\\ding{105}} % Snow
\\usepackage{pifont}
''',
}
man_pages = []
for doc in os.listdir(os.path.join(os.path.dirname(__file__), 'commands')):
if doc.endswith('.rst'):
name = doc[:-4]
module = 'powerline.commands.{0}'.format(name)
get_argparser = __import__(str(module), fromlist=[str('get_argparser')]).get_argparser
parser = get_argparser()
description = parser.description
man_pages.append([
'commands/' + name,
'powerline' if name == 'main' else 'powerline-' + name,
description,
'',
1
])
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if not on_rtd: # only import and set the theme if were building docs locally
try:
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
except ImportError:
pass
if on_rtd or html_theme == 'sphinx_rtd_theme':
html_context = {
'css_files': [
'https://media.readthedocs.org/css/sphinx_rtd_theme.css',
'https://media.readthedocs.org/css/readthedocs-doc-embed.css',
'_static/css/theme_overrides.css',
],
}

View file

@ -0,0 +1,151 @@
*******************************
Configuration and customization
*******************************
.. note::
**Forking the main GitHub repo is not needed to personalize Powerline
configuration!** Please read through the :ref:`quick-guide` for a quick
introduction to user configuration.
Powerline is configured with one main configuration file, and with separate
configuration files for themes and colorschemes. All configuration files are
written in JSON, with the exception of segment definitions, which are
written in Python.
Powerline provides default configurations in the following locations:
:ref:`Main configuration <config-main>`
:file:`{powerline}/config.json`
:ref:`Colorschemes <config-colorschemes>`
:file:`{powerline}/colorschemes/{name}.json`,
:file:`{powerline}/colorschemes/{extension}/__main__.json`,
:file:`{powerline}/colorschemes/{extension}/{name}.json`
:ref:`Themes <config-themes>`
:file:`{powerline}/themes/{top_theme}.json`,
:file:`{powerline}/themes/{extension}/__main__.json`,
:file:`{powerline}/themes/{extension}/default.json`
Here `{powerline}` is one of the following:
#. The default configuration directory located in the main package:
:file:`{powerline_root}/powerline/config_files`. May be absent in some
packages (e.g. when installing via Gentoo ebuilds).
#. If variable ``$XDG_CONFIG_DIRS`` is set and non-empty then to any
:file:`{directory}/powerline` where `{directory}` is a directory listed in
a colon-separated ``$XDG_CONFIG_DIRS`` list. Directories are checked in
reverse order.
#. User configuration directory located in :file:`$XDG_CONFIG_HOME/powerline`.
This usually corresponds to :file:`~/.config/powerline` on all platforms.
If per-instance configuration is needed please refer to :ref:`Local
configuration overrides <local-configuration-overrides>`.
.. _configuration-merging:
.. note::
Existing multiple configuration files that have the same name, but are placed
in different directories, will be merged. Merging happens in the order given
in the above list of possible `{powerline}` meanings.
When merging configuration only dictionaries are merged and they are merged
recursively: keys from next file overrule those from the previous unless
corresponding values are both dictionaries in which case these dictionaries
are merged and key is assigned the result of the merge.
.. note:: Some configuration files (i.e. themes and colorschemes) have two level
of merging: first happens merging described above, second theme- or
colorscheme-specific merging happens.
.. _quick-guide:
Quick setup guide
=================
This guide will help you with the initial configuration of Powerline.
Look at configuration in :file:`{powerline_root}/powerline/config_files`. If you
want to modify some file you can create :file:`~/.config/powerline` directory
and put modifications there: all configuration files are :ref:`merged
<configuration-merging>` with each other.
Each extension (vim, tmux, etc.) has its own theme, and they are located in
:file:`{config directory}/themes/{extension}/default.json`. Best way to modify
it is to copy this theme as a whole, remove ``segment_data`` key with
corresponding value if present (unless you need to modify it, in which case only
modifications must be left) and do necessary modifications in the list of
segments (lists are not subject to merging: this is why you need a copy).
If you want to move, remove or customize any of the provided segments in the
copy, you can do that by updating the segment dictionary in the theme you want
to customize. A segment dictionary looks like this:
.. code-block:: javascript
{
"name": "segment_name"
...
}
You can move the segment dictionaries around to change the segment
positions, or remove the entire dictionary to remove the segment from the
prompt or statusline.
.. note:: Its essential that the contents of all your configuration files
is valid JSON! Its strongly recommended that you run your configuration
files through ``jsonlint`` after changing them.
.. note::
If your modifications appear not to work, run :ref:`powerline-lint script
<command-powerline-lint>`. This script should show you the location of the
error.
Some segments need a user configuration to work properly. Heres a couple of
segments that you may want to customize right away:
**E-mail alert segment**
You have to set your username and password (and possibly server/port)
for the e-mail alert segment. If youre using GMail its recommended
that you `generate an application-specific password
<https://accounts.google.com/IssuedAuthSubTokens>`_ for this purpose.
Open a theme file, scroll down to the ``email_imap_alert`` segment and
set your ``username`` and ``password``. The server defaults to GMails
IMAP server, but you can set the server/port by adding a ``server`` and
a ``port`` argument.
**Weather segment**
The weather segment will try to find your location using a GeoIP lookup,
so unless youre on a VPN you probably wont 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 youll
have to update the segment arguments. Open a theme file, scroll down to
the weather segment and update it to include unit, location query or
api key arguments:
.. code-block:: javascript
{
"name": "weather",
"priority": 50,
"args": {
"unit": "F",
"location_query": "oslo, norway",
"weather_api_key": "your_api_key"
}
},
References
==========
.. toctree::
:glob:
configuration/reference
configuration/segments
configuration/listers
configuration/selectors
configuration/local

View file

@ -0,0 +1,35 @@
.. _config-listers:
****************
Lister reference
****************
Listers are special segment collections which allow to show some list of
segments for each entity in the list of entities (multiply their segments list
by a list of entities). E.g. ``powerline.listers.vim.tablister`` presented with
``powerline.segments.vim.tabnr`` and ``….file_name`` as segments will emit
segments with buffer names and tabpage numbers for each tabpage shown by vim.
Listers appear in configuration as irregular segments having ``segment_list`` as
their type and ``segments`` key with a list of segments (a bit more details in
:ref:`Themes section of configuration reference <config-themes-segments>`).
More information in :ref:`Writing listers <dev-listers>` section.
Vim listers
-----------
.. automodule:: powerline.listers.vim
:members:
Pdb listers
-----------
.. automodule:: powerline.listers.pdb
:members:
i3wm listers
------------
.. automodule:: powerline.listers.i3wm
:members:

View file

@ -0,0 +1,260 @@
.. _local-configuration-overrides:
*****************************
Local configuration overrides
*****************************
Depending on the application used it is possible to override configuration. Here
is the list:
Vim overrides
=============
Vim configuration can be overridden using the following options:
.. _local-configuration-overrides-vim-config:
``g:powerline_config_overrides``
Dictionary, recursively merged with contents of
:file:`powerline/config.json`.
``g:powerline_theme_overrides``
Dictionary mapping theme names to theme overrides, recursively merged with
contents of :file:`powerline/themes/vim/{key}.json`. Note that this way some
value (e.g. segment) in a list cannot be redefined, only the whole list
itself: only dictionaries are merged recursively.
``g:powerline_config_paths``
Paths list (each path must be expanded, ``~`` shortcut is not supported).
Points to the list of directories which will be searched for configuration.
When this option is present, none of the other locations are searched.
``g:powerline_no_python_error``
If this variable is set to a true value it will prevent Powerline from reporting
an error when loaded in a copy of vim without the necessary Python support.
``g:powerline_use_var_handler``
This variable may be set to either 0 or 1. If it is set to 1 then Vim will
save log in ``g:powerline_log_messages`` variable in addition to whatever
was configured in :ref:`log_* options <config-common-log>`. Level is always
:ref:`log_level <config-common-log_level>`, same for format.
.. warning::
This variable is deprecated. Use :ref:`log_file option
<config-common-log>` in conjunction with
:py:class:`powerline.vim.VimVarHandler` class and :ref:`Vim config
overrides variable <local-configuration-overrides-vim-config>`. Using
this is also the only variant to make saving into the environment
variable the *only* place where log is saved or save into different
variable.
.. autoclass:: powerline.vim.VimVarHandler
.. _local-configuration-overrides-script:
Powerline script overrides
==========================
Powerline script has a number of options controlling powerline behavior. Here
``VALUE`` always means “some JSON object”.
``-c KEY.NESTED_KEY=VALUE`` or ``--config-override=KEY.NESTED_KEY=VALUE``
Overrides options from :file:`powerline/config.json`.
``KEY.KEY2.KEY3=VALUE`` is a shortcut for ``KEY={"KEY2": {"KEY3": VALUE}}``.
Multiple options (i.e. ``-c K1=V1 -c K2=V2``) are allowed, result (in the
example: ``{"K1": V1, "K2": V2}``) is recursively merged with the contents
of the file.
If ``VALUE`` is omitted then corresponding key will be removed from the
configuration (if it was present).
``-t THEME_NAME.KEY.NESTED_KEY=VALUE`` or ``--theme-override=THEME_NAME.KEY.NESTED_KEY=VALUE``
Overrides options from :file:`powerline/themes/{ext}/{THEME_NAME}.json`.
``KEY.NESTED_KEY=VALUE`` is processed like described above, ``{ext}`` is the
first argument to powerline script. May be passed multiple times.
If ``VALUE`` is omitted then corresponding key will be removed from the
configuration (if it was present).
``-p PATH`` or ``--config-path=PATH``
Sets directory where configuration should be read from. If present, no
default locations are searched for configuration. No expansions are
performed by powerline script itself, but ``-p ~/.powerline`` will likely be
expanded by the shell to something like ``-p /home/user/.powerline``.
.. warning::
Such overrides are suggested for testing purposes only. Use
:ref:`Environment variables overrides <local-configuration-overrides-env>`
for other purposes.
.. _local-configuration-overrides-env:
Environment variables overrides
===============================
All bindings that use ``POWERLINE_COMMAND`` environment variable support taking
overrides from environment variables. In this case overrides should look like
the following::
OVERRIDE='key1.key2.key3=value;key4.key5={"value":1};key6=true;key1.key7=10'
. This will be parsed into
.. code-block:: Python
{
"key1": {
"key2": {
"key3": "value"
},
"key7": 10,
},
"key4": {
"key5": {
"value": 1,
},
},
"key6": True,
}
. Rules:
#. Environment variable must form a semicolon-separated list of key-value pairs:
``key=value;key2=value2``.
#. Keys are always dot-separated strings that must not contain equals sign (as
well as semicolon) or start with an underscore. They are interpreted
literally and create a nested set of dictionaries: ``k1.k2.k3`` creates
``{"k1":{"k2":{}}}`` and inside the innermost dictionary last key (``k3`` in
the example) is contained with its value.
#. Value may be empty in which case they are interpreted as an order to remove
some value: ``k1.k2=`` will form ``{"k1":{"k2":REMOVE_THIS_KEY}}`` nested
dictionary where ``k2`` value is a special value that tells
dictionary-merging function to remove ``k2`` rather then replace it with
something.
#. Value may be a JSON strings like ``{"a":1}`` (JSON dictionary), ``["a",1]``
(JSON list), ``1`` or ``-1`` (JSON number), ``"abc"`` (JSON string) or
``true``, ``false`` and ``null`` (JSON boolean objects and ``Null`` object
from JSON). General rule is that anything starting with a digit (U+0030 till
U+0039, inclusive), a hyphenminus (U+002D), a quotation mark (U+0022), a left
curly bracket (U+007B) or a left square bracket (U+005B) is considered to be
some JSON object, same for *exact* values ``true``, ``false`` and ``null``.
#. Any other value is considered to be literal string: ``k1=foo:bar`` parses to
``{"k1": "foo:bar"}``.
The following environment variables may be used for overrides according to the
above rules:
``POWERLINE_CONFIG_OVERRIDES``
Overrides values from :file:`powerline/config.json`.
``POWERLINE_THEME_OVERRIDES``
Overrides values from :file:`powerline/themes/{ext}/{key}.json`. Top-level
key is treated as a name of the theme for which overrides are used: e.g. to
disable cwd segment defined in :file:`powerline/themes/shell/default.json`
one needs to use::
POWERLINE_THEME_OVERRIDES=default.segment_data.cwd.display=false
Additionally one environment variable is a usual *colon*-separated list of
directories: ``POWERLINE_CONFIG_PATHS``. This one defines paths which will be
searched for configuration. Empty paths in ``POWERLINE_CONFIG_PATHS`` are
ignored.
.. note::
Overrides from environment variables have lower priority then
:ref:`Powerline script overrides <local-configuration-overrides-script>`.
Latter are suggested for tests only.
Zsh/zpython overrides
=====================
Here overrides are controlled by similarly to the powerline script, but values
are taken from zsh variables. :ref:`Environment variable overrides
<local-configuration-overrides-env>` are also supported: if variable is a string
this variant is used.
``POWERLINE_CONFIG_OVERRIDES``
Overrides options from :file:`powerline/config.json`. Should be a zsh
associative array with keys equal to ``KEY.NESTED_KEY`` and values being
JSON strings. Pair ``KEY.KEY1 VALUE`` is equivalent to ``{"KEY": {"KEY1":
VALUE}}``. All pairs are then recursively merged into one dictionary and
this dictionary is recursively merged with the contents of the file.
``POWERLINE_THEME_OVERRIDES``
Overrides options from :file:`powerline/themes/shell/*.json`. Should be
a zsh associative array with keys equal to ``THEME_NAME.KEY.NESTED_KEY`` and
values being JSON strings. Is processed like the above
``POWERLINE_CONFIG_OVERRIDES``, but only subdictionaries for ``THEME_NAME``
key are merged with theme configuration when theme with given name is
requested.
``POWERLINE_CONFIG_PATHS``
Sets directories where configuration should be read from. If present, no
default locations are searched for configuration. No expansions are
performed by powerline script itself, but zsh usually performs them on its
own if variable without is set without quotes: ``POWERLINE_CONFIG_PATHS=(
~/example )``. In addition to arrays usual colon-separated “array” string
can be used: ``POWERLINE_CONFIG_PATHS=$HOME/path1:$HOME/path2``.
Ipython overrides
=================
Ipython overrides depend on ipython version. Before ipython-0.11 additional
keyword arguments should be passed to setup() function. After ipython-0.11
``c.Powerline.KEY`` should be used. Supported ``KEY`` strings or keyword
argument names:
``config_overrides``
Overrides options from :file:`powerline/config.json`. Should be a dictionary
that will be recursively merged with the contents of the file.
``theme_overrides``
Overrides options from :file:`powerline/themes/ipython/*.json`. Should be
a dictionary where keys are theme names and values are dictionaries which
will be recursively merged with the contents of the given theme.
``config_paths``
Sets directories where configuration should be read from. If present, no
default locations are searched for configuration. No expansions are
performed thus paths starting with ``~/`` cannot be used: use
:py:func:`os.path.expanduser`.
Prompt command
==============
In addition to the above configuration options ``$POWERLINE_COMMAND``
environment variable can be used to tell shell or tmux to use specific powerline
implementation and ``$POWERLINE_CONFIG_COMMAND`` to tell zsh or tmux where
``powerline-config`` script is located. This is mostly useful for putting
powerline into different directory.
.. note::
``$POWERLINE_COMMAND`` is always treated as one path in shell bindings, so
path with spaces in it may be used. To specify additional arguments one may
use ``$POWERLINE_COMMAND_ARGS``, but note that this variable exists for
testing purposes only and may be removed. One should use :ref:`Environment
variable overrides <local-configuration-overrides-env>` instead.
To disable prompt in shell, but still have tmux support or to disable tmux
support environment variables ``$POWERLINE_NO_{SHELL}_PROMPT`` and
``$POWERLINE_NO_{SHELL}_TMUX_SUPPORT`` can be used (substitute ``{SHELL}`` with
the name of the shell (all-caps) that should be affected (e.g. ``BASH``) or use
all-inclusive ``SHELL`` that will disable support for all shells). These
variables have no effect after configuration script was sourced (in fish case:
after ``powerline-setup`` function was run). To disable specific feature support
set one of these variables to some non-empty value.
In order to keep shell prompt, but avoid launching Python twice to get unused
:ref:`above <config-themes-above>` lines in tcsh ``$POWERLINE_NO_TCSH_ABOVE`` or
``$POWERLINE_NO_SHELL_ABOVE`` variable should be set.
In order to remove additional space from the end of the right prompt in fish
that was added in order to support multiline prompt ``$POWERLINE_NO_FISH_ABOVE``
or ``$POWERLINE_NO_SHELL_ABOVE`` variable should be set.
PDB overrides
=============
Like shell bindings :ref:`PDB bindings <pdb-prompt>` take overrides from
:ref:`environment variables <local-configuration-overrides-env>`.

View file

@ -0,0 +1,602 @@
***********************
Configuration reference
***********************
.. _config-main:
Main configuration
==================
:Location: :file:`powerline/config.json`
The main configuration file defines some common options that applies to all
extensions, as well as some extension-specific options like themes and
colorschemes.
Common configuration
--------------------
Common configuration is a subdictionary that is a value of ``common`` key in
:file:`powerline/config.json` file.
.. _config-common-term_truecolor:
``term_truecolor``
Defines whether to output cterm indices (8-bit) or RGB colors (24-bit)
to the terminal emulator. See the :ref:`term-feature-support-matrix` for
information on whether used terminal emulator supports 24-bit colors.
This variable is forced to be ``false`` if :ref:`term_escape_style
<config-common-term_escape_style>` option is set to ``"fbterm"`` or if it is
set to ``"auto"`` and powerline detected fbterm.
.. _config-common-term_escape_style:
``term_escape_style``
Defines what escapes sequences should be used. Accepts three variants:
======= ===================================================================
Variant Description
======= ===================================================================
auto ``xterm`` or ``fbterm`` depending on ``$TERM`` variable value:
``TERM=fbterm`` implies ``fbterm`` escaping style, all other values
select ``xterm`` escaping.
xterm Uses ``\e[{fb};5;{color}m`` for colors (``{fb}`` is either ``38``
(foreground) or ``48`` (background)). Should be used for most
terminals.
fbterm Uses ``\e[{fb};{color}}`` for colors (``{fb}`` is either ``1``
(foreground) or ``2`` (background)). Should be used for fbterm:
framebuffer terminal.
======= ===================================================================
.. _config-common-ambiwidth:
``ambiwidth``
Tells powerline what to do with characters with East Asian Width Class
Ambiguous (such as Euro, Registered Sign, Copyright Sign, Greek
letters, Cyrillic letters). Valid values: any positive integer; it is
suggested that this option is only set it to 1 (default) or 2.
.. _config-common-watcher:
``watcher``
Select filesystem watcher. Variants are
======= ===================================
Variant Description
======= ===================================
auto Selects most performant watcher.
inotify Select inotify watcher. Linux only.
stat Select stat-based polling watcher.
uv Select libuv-based watcher.
======= ===================================
Default is ``auto``.
.. _config-common-additional_escapes:
``additional_escapes``
Valid for shell extensions, makes sense only if :ref:`term_truecolor
<config-common-term_truecolor>` is enabled. Is to be set from command-line.
Controls additional escaping that is needed for tmux/screen to work with
terminal true color escape codes: normally tmux/screen prevent terminal
emulator from receiving these control codes thus rendering powerline prompt
colorless. Valid values: ``"tmux"``, ``"screen"``, ``null`` (default).
.. _config-common-paths:
``paths``
Defines additional paths which will be searched for modules when using
:ref:`function segment option <config-themes-seg-function>` or :ref:`Vim
local_themes option <config-ext-local_themes>`. Paths defined here have
priority when searching for modules.
.. _config-common-log:
``log_file``
Defines how logs will be handled. There are three variants here:
#. Absent. In this case logging will be done to stderr: equivalent to
``[["logging.StreamHandler", []]]`` or ``[null]``.
#. Plain string. In this case logging will be done to the given file:
``"/file/name"`` is equivalent to ``[["logging.FileHandler",
[["/file/name"]]]]`` or ``["/file/name"]``. Leading ``~/`` is expanded in
the file name, so using ``"~/.log/foo"`` is permitted. If directory
pointed by the option is absent, it will be created, but not its parent.
#. List of handler definitions. Handler definition may either be ``null``,
a string or a list with two or three elements:
#. Logging class name and module. If module name is absent, it is
equivalent to ``logging.handlers``.
#. Class constructor arguments in a form ``[[args[, kwargs]]]``: accepted
variants are ``[]`` (no arguments), ``[args]`` (e.g.
``[["/file/name"]]``: only positional arguments) or ``[args, kwargs]``
(e.g. ``[[], {"host": "localhost", "port": 6666}]``: positional and
keyword arguments, but no positional arguments in the example).
#. Optional logging level. Overrides :ref:`log_level key
<config-common-log_level>` and has the same format.
#. Optional format string. Partially overrides :ref:`log_format key
<config-common-log_format>` and has the same format. “Partially” here
means that it may only specify more critical level.
.. _config-common-log_level:
``log_level``
String, determines logging level. Defaults to ``WARNING``.
.. _config-common-log_format:
``log_format``
String, determines format of the log messages. Defaults to
``'%(asctime)s:%(level)s:%(message)s'``.
``interval``
Number, determines time (in seconds) between checks for changed
configuration. Checks are done in a separate thread. Use ``null`` to check
for configuration changes on ``.render()`` call in main thread.
Defaults to ``None``.
``reload_config``
Boolean, determines whether configuration should be reloaded at all.
Defaults to ``True``.
.. _config-common-default_top_theme:
``default_top_theme``
String, determines which top-level theme will be used as the default.
Defaults to ``powerline_terminus`` in unicode locales and ``ascii`` in
non-unicode locales. See `Themes`_ section for more details.
Extension-specific configuration
--------------------------------
Common configuration is a subdictionary that is a value of ``ext`` key in
:file:`powerline/config.json` file.
``colorscheme``
Defines the colorscheme used for this extension.
.. _config-ext-theme:
``theme``
Defines the theme used for this extension.
.. _config-ext-top_theme:
``top_theme``
Defines the top-level theme used for this extension. See `Themes`_ section
for more details.
.. _config-ext-local_themes:
``local_themes``
Defines themes used when certain conditions are met, e.g. for
buffer-specific statuslines in vim. Value depends on extension used. For vim
it is a dictionary ``{matcher_name : theme_name}``, where ``matcher_name``
is either ``matcher_module.module_attribute`` or ``module_attribute``
(``matcher_module`` defaults to ``powerline.matchers.vim``) and
``module_attribute`` should point to a function that returns boolean value
indicating that current buffer has (not) matched conditions. There is an
exception for ``matcher_name`` though: if it is ``__tabline__`` no functions
are loaded. This special theme is used for ``tabline`` Vim option.
For shell and ipython it is a simple ``{prompt_type : theme_name}``, where
``prompt_type`` is a string with no special meaning (specifically it does
not refer to any Python function). Shell has ``continuation``, and
``select`` prompts with rather self-explanatory names, IPython has ``in2``,
``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.
.. _config-ext-components:
``components``
Determines which extension components should be enabled. This key is highly
extension-specific, here is the table of extensions and corresponding
components:
+---------+----------+-----------------------------------------------------+
|Extension|Component |Description |
+---------+----------+-----------------------------------------------------+
|vim |statusline|Makes Vim use powerline statusline. |
| +----------+-----------------------------------------------------+
| |tabline |Makes Vim use powerline tabline. |
+---------+----------+-----------------------------------------------------+
|shell |prompt |Makes shell display powerline prompt. |
| +----------+-----------------------------------------------------+
| |tmux |Makes shell report its current working directory |
| | |and screen width to tmux for tmux powerline |
| | |bindings. |
| | |  |
+---------+----------+-----------------------------------------------------+
All components are enabled by default.
.. _config-ext-update_interval:
``update_interval``
Determines how often WM status bars need to be updated, in seconds. Only
valid for WM extensions which use ``powerline-daemon``. Defaults to
2 seconds.
.. _config-colors:
Color definitions
=================
:Location: :file:`powerline/colors.json`
.. _config-colors-colors:
``colors``
Color definitions, consisting of a dict where the key is the name of the
color, and the value is one of the following:
* A cterm color index.
* A list with a cterm color index and a hex color string (e.g. ``[123,
"aabbcc"]``). This is useful for colorschemes that use colors that
arent available in color terminals.
``gradients``
Gradient definitions, consisting of a dict where the key is the name of the
gradient, and the value is a list containing one or two items, second item
is optional:
* A list of cterm color indices.
* A list of hex color strings.
It is expected that gradients are defined from least alert color to most
alert or non-alert colors are used.
.. _config-colorschemes:
Colorschemes
============
:Location: :file:`powerline/colorschemes/{name}.json`,
:file:`powerline/colorschemes/__main__.json`,
:file:`powerline/colorschemes/{extension}/{name}.json`
Colorscheme files are processed in order given: definitions from each next file
override those from each previous file. It is required that either
:file:`powerline/colorschemes/{name}.json`, or
:file:`powerline/colorschemes/{extension}/{name}.json` exists.
``name``
Name of the colorscheme.
.. _config-colorschemes-groups:
``groups``
Segment highlighting groups, consisting of a dict where the key is the
name of the highlighting group (usually the function name for function
segments), and the value is either
#) a dict that defines the foreground color, background color and
attributes:
``fg``
Foreground color. Must be defined in :ref:`colors
<config-colors-colors>`.
``bg``
Background color. Must be defined in :ref:`colors
<config-colors-colors>`.
``attrs``
List of attributes. Valid values are one or more of ``bold``,
``italic`` and ``underline``. Note that some attributes may be
unavailable in some applications or terminal emulators. If no
attributes are needed this list should be left empty.
#) a string (an alias): a name of existing group. This groups definition
will be used when this color is requested.
``mode_translations``
Mode-specific highlighting for extensions that support it (e.g. the vim
extension). Its an easy way of changing a color in a specific mode.
Consists of a dict where the key is the mode and the value is a dict
with the following options:
``colors``
A dict where the key is the color to be translated in this mode, and
the value is the new color. Both the key and the value must be defined
in :ref:`colors <config-colors-colors>`.
``groups``
Segment highlighting groups for this mode. Same syntax as the main
:ref:`groups <config-colorschemes-groups>` option.
.. _config-themes:
Themes
======
:Location: :file:`powerline/themes/{top_theme}.json`,
:file:`powerline/themes/{extension}/__main__.json`,
:file:`powerline/themes/{extension}/{name}.json`
Theme files are processed in order given: definitions from each next file
override those from each previous file. It is required that file
:file:`powerline/themes/{extension}/{name}.json` exists.
`{top_theme}` component of the file name is obtained either from :ref:`top_theme
extension-specific key <config-ext-top_theme>` or from :ref:`default_top_theme
common configuration key <config-common-default_top_theme>`. Powerline ships
with the following top themes:
.. _config-top_themes-list:
========================== ====================================================
Theme Description
========================== ====================================================
powerline Default powerline theme with fancy powerline symbols
powerline_unicode7 Theme with powerline dividers and unicode-7 symbols
unicode Theme without any symbols from private use area
unicode_terminus Theme containing only symbols from terminus PCF font
unicode_terminus_condensed Like above, but occupies as less space as possible
powerline_terminus Like unicode_terminus, but with powerline symbols
ascii Theme without any unicode characters at all
========================== ====================================================
``name``
Name of the theme.
.. _config-themes-default_module:
``default_module``
Python module where segments will be looked by default. Defaults to
``powerline.segments.{ext}``.
``spaces``
Defines number of spaces just before the divider (on the right side) or just
after it (on the left side). These spaces will not be added if divider is
not drawn.
``use_non_breaking_spaces``
Determines whether non-breaking spaces should be used in place of the
regular ones. This option is needed because regular spaces are not displayed
properly when using powerline with some font configuration. Defaults to
``True``.
.. note::
Unlike all other options this one is only checked once at startup using
whatever theme is :ref:`the default <config-ext-theme>`. If this option
is set in the local themes it will be ignored. This option may also be
ignored in some bindings.
``outer_padding``
Defines number of spaces at the end of output (on the right side) or at
the start of output (on the left side). Defaults to ``1``.
``dividers``
Defines the dividers used in all Powerline extensions.
The ``hard`` dividers are used to divide segments with different
background colors, while the ``soft`` dividers are used to divide
segments with the same background color.
.. _config-themes-cursor_space:
``cursor_space``
Space reserved for user input in shell bindings. It is measured in per
cents.
``cursor_columns``
Space reserved for user input in shell bindings. Unlike :ref:`cursor_space
<config-themes-cursor_space>` it is measured in absolute amount of columns.
.. _config-themes-segment_data:
``segment_data``
A dict where keys are segment names or strings ``{module}.{function}``. Used
to specify default values for various keys:
:ref:`after <config-themes-seg-after>`,
:ref:`before <config-themes-seg-before>`,
:ref:`contents <config-themes-seg-contents>` (only for string segments
if :ref:`name <config-themes-seg-name>` is defined),
:ref:`display <config-themes-seg-display>`.
Key :ref:`args <config-themes-seg-args>` (only for function and
segment_list segments) is handled specially: unlike other values it is
merged with all other values, except that a single ``{module}.{function}``
key if found prevents merging all ``{function}`` values.
When using :ref:`local themes <config-ext-local_themes>` values of these
keys are first searched in the segment description, then in ``segment_data``
key of a local theme, then in ``segment_data`` key of a :ref:`default theme
<config-ext-theme>`. For the :ref:`default theme <config-ext-theme>` itself
step 2 is obviously avoided.
.. note:: Top-level themes are out of equation here: they are merged
before the above merging process happens.
.. _config-themes-segments:
``segments``
A dict with a ``left`` and a ``right`` lists, consisting of segment
dictionaries. Shell themes may also contain ``above`` list of dictionaries.
Each item in ``above`` list may have ``left`` and ``right`` keys like this
dictionary, but no ``above`` key.
.. _config-themes-above:
``above`` list is used for multiline shell configurations.
``left`` and ``right`` lists are used for segments that should be put on the
left or right side in the output. Actual mechanizm of putting segments on
the left or the right depends on used renderer, but most renderers require
one to specify segment with :ref:`width <config-themes-seg-width>` ``auto``
on either side to make generated line fill all of the available width.
Each segment dictionary has the following options:
.. _config-themes-seg-type:
``type``
The segment type. Can be one of ``function`` (default), ``string`` or
``segment_list``:
``function``
The segment contents is the return value of the function defined in
the :ref:`function option <config-themes-seg-function>`.
List of function segments is available in :ref:`Segment reference
<config-segments>` section.
``string``
A static string segment where the contents is defined in the
:ref:`contents option <config-themes-seg-contents>`, and the
highlighting group is defined in the :ref:`highlight_groups option
<config-themes-seg-highlight_groups>`.
``segment_list``
Sub-list of segments. This list only allows :ref:`function
<config-themes-seg-function>`, :ref:`segments
<config-themes-seg-segments>` and :ref:`args
<config-themes-seg-args>` options.
List of lister segments is available in :ref:`Lister reference
<config-listers>` section.
.. _config-themes-seg-name:
``name``
Segment name. If present allows referring to this segment in
:ref:`segment_data <config-themes-segment_data>` dictionary by this
name. If not ``string`` segments may not be referred there at all and
``function`` and ``segment_list`` segments may be referred there using
either ``{module}.{function_name}`` or ``{function_name}``, whichever
will be found first. Function name is taken from :ref:`function key
<config-themes-seg-function>`.
.. note::
If present prevents ``function`` key from acting as a segment name.
.. _config-themes-seg-function:
``function``
Function used to get segment contents, in format ``{module}.{function}``
or ``{function}``. If ``{module}`` is omitted :ref:`default_module
option <config-themes-default_module>` is used.
.. _config-themes-seg-highlight_groups:
``highlight_groups``
Highlighting group for this segment. Consists of a prioritized list of
highlighting groups, where the first highlighting group that is
available in the colorscheme is used.
Ignored for segments that have ``function`` type.
.. _config-themes-seg-before:
``before``
A string which will be prepended to the segment contents.
.. _config-themes-seg-after:
``after``
A string which will be appended to the segment contents.
.. _config-themes-seg-contents:
``contents``
Segment contents, only required for ``string`` segments.
.. _config-themes-seg-args:
``args``
A dict of arguments to be passed to a ``function`` segment.
.. _config-themes-seg-align:
``align``
Aligns the segments contents to the left (``l``), center (``c``) or
right (``r``). Has no sense if ``width`` key was not specified or if
segment provides its own function for ``auto`` ``width`` handling and
does not care about this option.
.. _config-themes-seg-width:
``width``
Enforces a specific width for this segment.
This segment will work as a spacer if the width is set to ``auto``.
Several spacers may be used, and the space will be distributed
equally among all the spacer segments. Spacers may have contents,
either returned by a function or a static string, and the contents
can be aligned with the ``align`` property.
.. _config-themes-seg-priority:
``priority``
Optional segment priority. Segments with priority ``None`` (the default
priority, represented by ``null`` in json) will always be included,
regardless of the width of the prompt/statusline.
If the priority is any number, the segment may be removed if the
prompt/statusline width is too small for all the segments to be
rendered. A lower number means that the segment has a higher priority.
Segments are removed according to their priority, with low priority
segments (i.e. with a greater priority number) being removed first.
.. _config-themes-seg-draw_divider:
``draw_hard_divider``, ``draw_soft_divider``
Whether to draw a divider between this and the adjacent segment. The
adjacent segment is to the *right* for segments on the *left* side, and
vice versa. Hard dividers are used between segments with different
background colors, soft ones are used between segments with same
background. Both options default to ``True``.
.. _config-themes-seg-draw_inner_divider:
``draw_inner_divider``
Determines whether inner soft dividers are to be drawn for function
segments. Only applicable for functions returning multiple segments.
Defaults to ``False``.
.. _config-themes-seg-exclude_modes:
``exclude_modes``, ``include_modes``
A list of modes where this segment will be excluded: the segment is not
included or is included in all modes, *except* for the modes in one of
these lists respectively. If ``exclude_modes`` is not present then it
acts like an empty list (segment is not excluded from any modes).
Without ``include_modes`` it acts like a list with all possible modes
(segment is included in all modes). When there are both
``exclude_modes`` overrides ``include_modes``.
.. _config-themes-seg-exclude_function:
``exclude_function``, ``include_function``
Function name in a form ``{name}`` or ``{module}.{name}`` (in the first
form ``{module}`` defaults to ``powerline.selectors.{ext}``). Determines
under which condition specific segment will be included or excluded. By
default segment is always included and never excluded.
``exclude_function`` overrides ``include_function``.
.. note::
Options :ref:`exclude_/include_modes
<config-themes-seg-exclude_modes>` complement
``exclude_/include_functions``: segment will be included if it is
included by either ``include_mode`` or ``include_function`` and will
be excluded if it is excluded by either ``exclude_mode`` or
``exclude_function``.
.. _config-themes-seg-display:
``display``
Boolean. If false disables displaying of the segment.
Defaults to ``True``.
.. _config-themes-seg-segments:
``segments``
A list of subsegments.

View file

@ -0,0 +1,28 @@
.. _config-segments:
*****************
Segment reference
*****************
Segments
========
Segments are written in Python, and the default segments provided with
Powerline are located in :file:`powerline/segments/{extension}.py`.
User-defined segments can be defined in any module in ``sys.path`` or
:ref:`paths common configuration option <config-common-paths>`, import is
always absolute.
Segments are regular Python functions, and they may accept arguments. All
arguments should have a default value which will be used for themes that
dont provide an ``args`` dict.
More information is available in :ref:`Writing segments <dev-segments>` section.
Available segments
==================
.. toctree::
:glob:
segments/*

View file

@ -0,0 +1,57 @@
***************
Common segments
***************
VCS submodule
=============
.. automodule:: powerline.segments.common.vcs
:members:
System properties
=================
.. automodule:: powerline.segments.common.sys
:members:
Network
=======
.. automodule:: powerline.segments.common.net
:members:
Current environment
===================
.. automodule:: powerline.segments.common.env
:members:
Battery
=======
.. automodule:: powerline.segments.common.bat
:members:
Weather
=======
.. automodule:: powerline.segments.common.wthr
:members:
Date and time
=============
.. automodule:: powerline.segments.common.time
:members:
Mail
====
.. automodule:: powerline.segments.common.mail
:members:
Media players
=============
.. automodule:: powerline.segments.common.players
:members:

View file

@ -0,0 +1,6 @@
*************
i3wm segments
*************
.. automodule:: powerline.segments.i3wm
:members:

View file

@ -0,0 +1,7 @@
************
PDB segments
************
.. automodule:: powerline.segments.pdb
:members:

View file

@ -0,0 +1,6 @@
**************
Shell segments
**************
.. automodule:: powerline.segments.shell
:members:

View file

@ -0,0 +1,6 @@
*************
Tmux segments
*************
.. automodule:: powerline.segments.tmux
:members:

View file

@ -0,0 +1,46 @@
************
Vim segments
************
.. automodule:: powerline.segments.vim
:members:
Plugin-specific segments
========================
Asynchronous Linter Engine (ALE) segments
-----------------------------------------
.. automodule:: powerline.segments.vim.plugin.ale
:members:
Syntastic segments
------------------
.. automodule:: powerline.segments.vim.plugin.syntastic
:members:
Command-T segments
------------------
.. automodule:: powerline.segments.vim.plugin.commandt
:members:
Tagbar segments
---------------
.. automodule:: powerline.segments.vim.plugin.tagbar
:members:
NERDTree segments
-----------------
.. automodule:: powerline.segments.vim.plugin.nerdtree
:members:
Capslock segments
-----------------
.. automodule:: powerline.segments.vim.plugin.capslock
:members:

View file

@ -0,0 +1,17 @@
.. _config-selectors:
******************
Selector functions
******************
Selector functions are functions that return ``True`` or ``False`` depending on
application state. They are used for :ref:`exclude_function and include_function
segment options <config-themes-seg-exclude_function>`.
Available selectors
===================
.. toctree::
:glob:
selectors/*

View file

@ -0,0 +1,6 @@
*************
Vim selectors
*************
.. automodule:: powerline.selectors.vim
:members:

13
docs/source/develop.rst Normal file
View file

@ -0,0 +1,13 @@
***************
Developer guide
***************
.. toctree::
:maxdepth: 2
:glob:
develop/segments
develop/listers
develop/local-themes
develop/extensions
develop/tips-and-tricks

View file

@ -0,0 +1,47 @@
********************************
Creating new powerline extension
********************************
Powerline extension is a code that tells powerline how to highlight and display
segments in some set of applications. Specifically this means
#. Creating a :py:class:`powerline.Powerline` subclass that knows how to obtain
:ref:`local configuration overrides <local-configuration-overrides>`. It also
knows how to load local themes, but not when to apply them.
Instance of this class is the only instance that interacts directly with
bindings code, so it has a proxy :py:meth:`powerline.Powerline.render` and
:py:meth:`powerline.Powerline.shutdown` methods and other methods which may
be useful for bindings.
This subclass must be placed directly in :file:`powerline` directory (e.g. in
:file:`powerline/vim.py`) and named like ``VimPowerline`` (version of the
file name without directory and extension and first capital letter
+ ``Powerline``). There is no technical reason for naming classes like this.
#. Creating a :py:class:`powerline.renderer.Renderer` subclass that knows how to
highlight a segment or reset highlighting to the default value (only makes
sense in prompts). It is also responsible for selecting local themes and
computing text width.
This subclass must be placed directly in :file:`powerline/renderers`
directory (for powerline extensions developed for a set of applications use
:file:`powerline/renderers/{ext}/*.py`) and named like ``ExtRenderer`` or
``AppPromptRenderer``. For technical reasons the class itself must be
referenced in ``renderer`` module attribute thus allowing only one renderer
per one module.
#. Creating an extension bindings. These are to be placed in
:file:`powerline/bindings/{ext}` and may contain virtually anything which may
be required for powerline to work inside given applications, assuming it does
not fit in other places.
Powerline class
===============
.. autoclass:: powerline.Powerline
:members:
Renderer class
==============
.. autoclass:: powerline.renderer.Renderer
:members:

View file

@ -0,0 +1,49 @@
.. _dev-listers:
***************
Writing listers
***************
Listers provide a way to show some segments multiple times: once per each entity
(buffer, tabpage, etc) lister knows. They are functions which receive the
following arguments:
``pl``
A :py:class:`powerline.PowerlineLogger` class instance. It must be used for
logging.
``segment_info``
Base segment info dictionary. Lister function or class must have
``powerline_requires_segment_info`` to receive this argument.
.. warning::
Listers are close to useless if they do not have access to this
argument.
Refer to :ref:`segment_info detailed description <dev-segments-info>` for
further details.
``draw_inner_divider``
If False (default) soft dividers between segments in the listed group will
not be drawn regardless of actual segment settings. If True they will be
drawn, again regardless of actual segment settings. Set it to ``None`` in
order to respect segment settings.
And also any other argument(s) specified by user in :ref:`args key
<config-themes-seg-args>` (no additional arguments by default).
Listers must return a sequence of pairs. First item in the pair must contain
a ``segment_info`` dictionary specific to one of the listed entities.
Second item must contain another dictionary: it will be used to modify the
resulting segment. In addition to :ref:`usual keys that describe segment
<dev-segments-segment>` the following keys may be present (it is advised that
*only* the following keys will be used):
``priority_multiplier``
Value (usually a ``float``) used to multiply segment priority. It is useful
for finer-grained controlling which segments disappear first: e.g. when
listing tab pages make first disappear directory names of the tabpages which
are most far away from current tabpage, then (when all directory names
disappeared) buffer names. Check out existing listers implementation in
:file:`powerline/listers/vim.py`.

View file

@ -0,0 +1,59 @@
************
Local themes
************
From the user point of view local themes are the regular themes with a specific
scope where they are applied (i.e. specific vim window or specific kind of
prompt). Used themes are defined in :ref:`local_themes key
<config-ext-local_themes>`.
Vim local themes
================
Vim is the only available extension that has a wide variaty of options for local
themes. It is the only extension where local theme key refers to a function as
described in :ref:`local_themes value documentation <config-ext-local_themes>`.
This function always takes a single value named ``matcher_info`` which is the
same dictionary as :ref:`segment_info dictionary <dev-segment_info-vim>`. Unlike
segments it takes this single argument as a *positional* argument, not as
a keyword one.
Matcher function should return a boolean value: ``True`` if theme applies for
the given ``matcher_info`` dictionary or ``False`` if it is not. When one of the
matcher functions returns ``True`` powerline takes the corresponding theme at
uses it for the given window. Matchers are not tested in any particular order.
In addition to :ref:`local_themes configuration key <config-ext-local_themes>`
developer of some plugin which wishes to support powerline without including his
code in powerline tree may use
:py:meth:`powerline.vim.VimPowerline.add_local_theme` method. It accepts two
arguments: matcher name (same as in :ref:`local_themes
<config-ext-local_themes>`) and dictionary with theme. This dictionary is merged
with :ref:`top theme <config-ext-top_theme>` and
:file:`powerline/themes/vim/__main__.json`. Note that if user already specified
the matcher in his configuration file ``KeyError`` is raised.
Other local themes
==================
Except for Vim only IPython and shells have local themes. Unlike Vim these
themes are names with no special meaning (they do not refer to or cause loading
of any Python functions):
+---------+------------+-------------------------------------------------------+
|Extension|Theme name |Description |
+---------+------------+-------------------------------------------------------+
|Shell |continuation|Shown for unfinished command (unclosed quote, |
| | |unfinished cycle). |
| +------------+-------------------------------------------------------+
| |select |Shown for ``select`` command available in some shells. |
+---------+------------+-------------------------------------------------------+
|IPython |in2 |Continuation prompt: shown for unfinished (multiline) |
| | |expression, unfinished class or function definition. |
| +------------+-------------------------------------------------------+
| |out |Displayed before the result. |
| +------------+-------------------------------------------------------+
| |rewrite |Displayed before the actually executed code when |
| | |``autorewrite`` IPython feature is enabled.  |
+---------+------------+-------------------------------------------------------+

View file

@ -0,0 +1,547 @@
.. _dev-segments:
****************
Writing segments
****************
Each powerline segment is a callable object. It is supposed to be either
a Python function or :py:class:`powerline.segments.Segment` class. As a callable
object it should receive the following arguments:
.. note:: All received arguments are keyword arguments.
``pl``
A :py:class:`powerline.PowerlineLogger` instance. It must be used every time
something needs to be logged.
``segment_info``
A dictionary. It is only received if callable has
``powerline_requires_segment_info`` attribute.
Refer to :ref:`segment_info detailed description <dev-segments-info>` for
further details.
``create_watcher``
Function that will create filesystem watcher once called. Which watcher will
be created exactly is controlled by :ref:`watcher configuration option
<config-common-watcher>`.
And also any other argument(s) specified by user in :ref:`args key
<config-themes-seg-args>` (no additional arguments by default).
.. note::
For powerline-lint to work properly the following things may be needed:
#. If segment is a :py:class:`powerline.segments.Segment` instance and used
arguments are scattered over multiple methods
:py:meth:`powerline.segments.Segment.argspecobjs` should be overridden in
subclass to tell powerline-lint which objects should be inspected for
arguments.
#. If segment takes some arguments that are never listed, but accessed via
``kwargs.get()`` or previous function cannot be used for whatever reason
:py:meth:`powerline.segments.Segment.additional_args` should be
overridden in subclass.
#. If user is expected to use one :ref:`name <config-themes-seg-name>` for
multiple segments which cannot be linked to the segment function
automatically by powerline-lint (e.g. because there are no instances of
the segments in question in the default configuration)
:py:func:`powerline.lint.checks.register_common_name` function should be
used.
Object representing segment may have the following attributes used by
powerline:
``powerline_requires_segment_info``
This attribute controls whether segment will receive ``segment_info``
argument: if it is present argument will be received.
``powerline_requires_filesystem_watcher``
This attribute controls whether segment will receive ``create_watcher``
argument: if it is present argument will be received.
``powerline_segment_datas``
This attribute must be a dictionary containing ``top_theme: segment_data``
mapping where ``top_theme`` is any theme name (it is expected that all of
the names from :ref:`top-level themes list <config-top_themes-list>` are
present) and ``segment_data`` is a dictionary like the one that is contained
inside :ref:`segment_data dictionary in configuration
<config-themes-segment_data>`. This attribute should be used to specify
default theme-specific values for *third-party* segments: powerline
theme-specific values go directly to :ref:`top-level themes
<config-themes>`.
.. _dev-segments-startup:
``startup``
This attribute must be a callable which accepts the following keyword
arguments:
* ``pl``: :py:class:`powerline.PowerlineLogger` instance which is to be used
for logging.
* ``shutdown_event``: :py:class:`Event` object which will be set when
powerline will be shut down.
* Any arguments found in user configuration for the given segment (i.e.
:ref:`args key <config-themes-seg-args>`).
This function is called at powerline startup when using long-running
processes (e.g. powerline in vim, in zsh with libzpython, in ipython or in
powerline daemon) and not called when ``powerline-render`` executable is
used (more specific: when :py:class:`powerline.Powerline` constructor
received true ``run_once`` argument).
.. _dev-segments-shutdown:
``shutdown``
This attribute must be a callable that accepts no arguments and shuts down
threads and frees any other resources allocated in ``startup`` method of the
segment in question.
This function is not called when ``startup`` method is not called.
.. _dev-segments-expand:
``expand``
This attribute must be a callable that accepts the following keyword
arguments:
* ``pl``: :py:class:`powerline.PowerlineLogger` instance which is to be used
for logging.
* ``amount``: integer number representing amount of display cells result
must occupy.
.. warning::
“Amount of display cells” is *not* number of Unicode codepoints, string
length, or byte count. It is suggested that this function should look
something like ``return (' ' * amount) + segment['contents']`` where
``' '`` may be replaced with anything that is known to occupy exactly
one display cell.
* ``segment``: :ref:`segment dictionary <dev-segments-segment>`.
* Any arguments found in user configuration for the given segment (i.e.
:ref:`args key <config-themes-seg-args>`).
It must return new value of :ref:`contents <dev-segments-seg-contents>` key.
.. _dev-segments-truncate:
``truncate``
Like :ref:`expand function <dev-segments-expand>`, but for truncating
segments. Here ``amount`` means the number of display cells which must be
freed.
This function is called for all segments before powerline starts purging
them to free space.
This callable object should may return either a string (``unicode`` in Python2
or ``str`` in Python3, *not* ``str`` in Python2 or ``bytes`` in Python3) object
or a list of dictionaries. String object is a short form of the following return
value:
.. code-block:: python
[{
'contents': original_return,
'highlight_groups': [segment_name],
}]
.. _dev-segments-return:
Returned list is a list of segments treated independently, except for
:ref:`draw_inner_divider key <dev-segments-draw_inner_divider>`.
All keys in segments returned by the function override those obtained from
:ref:`configuration <config-themes-segments>` and have the same meaning.
Detailed description of used dictionary keys:
.. _dev-segments-contents:
``contents``
Text displayed by segment. Should be a ``unicode`` (Python2) or ``str``
(Python3) instance.
``literal_contents``
Text that needs to be output literally (i.e. without passing through
:py:meth:`powerline.renderer.strwidth` to determine length, through
:py:meth:`powerline.renderer.escape` to escape special characters and
through :py:meth:`powerline.renderer.hl` to highlight it). Should be a tuple
``(contents_length, contents)`` where ``contents_length`` is an integer and
``contents`` is a ``unicode`` (Python2) or ``str`` (Python3) instance.
If this key is present and its second value is true then other contents keys
(:ref:`contents <dev-segments-contents>`, :ref:`after
<config-themes-seg-after>`, :ref:`before <config-themes-seg-before>`) will
be ignored.
.. note::
If target is inclusion of the segment in powerline upstream all segment
functions that output *only* subsegments with ``literal_contents`` key
must contain the following string in documentation::
No highlight groups are used (literal segment).
String must be present on the separate line.
.. _dev-segments-draw_inner_divider:
``draw_hard_divider``, ``draw_soft_divider``, ``draw_inner_divider``
Determines whether given divider should be drawn. All have the same meaning
as :ref:`the similar keys in configuration <config-themes-seg-draw_divider>`
(:ref:`draw_inner_divider <config-themes-seg-draw_inner_divider>`).
.. _dev-segments-highlight_groups:
``highlight_groups``
Determines segment highlighting. Refer to :ref:`themes documentation
<config-themes-seg-highlight_groups>` for more details.
Defaults to the name of the segment.
.. note::
If target is inclusion of the segment in powerline upstream all used
highlighting groups must be specified in the segment documentation in the
form::
Highlight groups used: ``g1``[ or ``g2``]*[, ``g3`` (gradient)[ or ``g4``]*]*.
I.e. use::
Highlight groups used: ``foo_gradient`` (gradient) or ``foo``, ``bar``.
to specify that the segment uses *either* ``foo_gradient`` group or
``foo`` group *and* ``bar`` group meaning that ``powerline-lint`` will
check that at least one of the first two groups is defined (and if
``foo_gradient`` is defined it must use at least one gradient color) and
third group is defined as well.
All groups must be specified on one line.
``divider_highlight_group``
Determines segment divider highlight group. Only applicable for soft
dividers: colors for hard dividers are determined by colors of adjacent
segments.
.. note::
If target is inclusion of the segment in powerline upstream used divider
highlight group must be specified in the segment documentation in the
form::
Divider highlight group used: ``group``.
This text must not wrap and all divider highlight group names are
supposed to end with ``:divider``: e.g. ``cwd:divider``.
``gradient_level``
First and the only key that may not be specified in user configuration. It
determines which color should be used for this segment when one of the
highlighting groups specified by :ref:`highlight_groups
<dev-segments-highlight_groups>` was defined to use the color gradient.
This key may have any value from 0 to 100 inclusive, value is supposed to be
an ``int`` or ``float`` instance.
No error occurs if segment has this key, but no used highlight groups use
gradient color.
``_*``
Keys starting with underscore are reserved for powerline and must not be
returned.
``__*``
Keys starting with two underscores are reserved for the segment functions,
specifically for :ref:`expand function <dev-segments-expand>`.
.. _dev-segments-segment:
Segment dictionary
==================
Segment dictionary contains the following keys:
* All keys returned by segment function (if it was used).
* All of the following keys:
``name``
Segment name: value of the :ref:`name key <config-themes-seg-name>` or
function name (last component of the :ref:`function key
<config-themes-seg-function>`). May be ``None``.
``type``
:ref:`Segment type <config-themes-seg-type>`. Always represents actual type
and is never ``None``.
``highlight_groups``, ``divider_highlight_group``
Used highlight groups. May be ``None``.
``highlight_group_prefix``
If this key is present then given prefix will be prepended to each highlight
group (both regular and divider) used by this segment in a form
``{prefix}:{group}`` (note the colon). This key is mostly useful for
:ref:`segment listers <dev-listers>`.
.. _dev-segments-seg-around:
``before``, ``after``
Value of :ref:`before <config-themes-seg-before>` or :ref:`after
<config-themes-seg-after>` configuration options. May be ``None`` as well as
an empty string.
``contents_func``
Function used to get segment contents. May be ``None``.
.. _dev-segments-seg-contents:
``contents``
Actual segment contents, excluding dividers and :ref:`before/after
<dev-segments-seg-around>`. May be ``None``.
``priority``
:ref:`Segment priority <config-themes-seg-priority>`. May be ``None`` for no
priority (such segments are always shown).
``draw_soft_divider``, ``draw_hard_divider``, ``draw_inner_divider``
:ref:`Divider control flags <dev-segments-draw_inner_divider>`.
``side``
Segment side: ``right`` or ``left``.
``display_condition``
Contains function that takes three position parameters:
:py:class:`powerline.PowerlineLogger` instance, :ref:`segment_info
<dev-segments-info>` dictionary and current mode and returns either ``True``
or ``False`` to indicate whether particular segment should be processed.
This key is constructed based on :ref:`exclude_/include_modes keys
<config-themes-seg-exclude_modes>` and :ref:`exclude_/include_function keys
<config-themes-seg-exclude_function>`.
``width``, ``align``
:ref:`Width and align options <config-themes-seg-align>`. May be ``None``.
``expand``, ``truncate``
Partially applied :ref:`expand <dev-segments-expand>` or :ref:`truncate
<dev-segments-truncate>` function. Accepts ``pl``, ``amount`` and
``segment`` positional parameters, keyword parameters from :ref:`args
<config-themes-seg-args>` key were applied.
``startup``
Partially applied :ref:`startup function <dev-segments-startup>`. Accepts
``pl`` and ``shutdown_event`` positional parameters, keyword parameters from
:ref:`args <config-themes-seg-args>` key were applied.
``shutdown``
:ref:`Shutdown function <dev-segments-shutdown>`. Accepts no argument.
Segments layout
===============
Powerline segments are all located in one of the ``powerline.segments``
submodules. For extension-specific segments ``powerline.segments.{ext}`` module
should be used (e.g. ``powerline.segments.shell``), for extension-agnostic there
is ``powerline.segments.common``.
Plugin-specific segments (currently only those that are specific to vim plugins)
should live in ``powerline.segments.{ext}.plugin.{plugin_name}``: e.g.
``powerline.segments.vim.plugin.gundo``.
.. _dev-segments-info:
Segment information used in various extensions
==============================================
Each ``segment_info`` value should be a dictionary with at least the following
keys:
``environ``
Current environment, may be an alias to ``os.environ``. Is guaranteed to
have ``__getitem__`` and ``get`` methods and nothing more.
.. warning::
``os.environ`` must not ever be used:
* If segment is run in the daemon this way it will get daemons
environment which is not correct.
* If segment is run in Vim or in zsh with libzpython ``os.environ`` will
contain Vim or zsh environ *at the moment Python interpreter was
loaded*.
``getcwd``
Function that returns current working directory being called with no
arguments. ``os.getcwd`` must not be used for the same reasons the use of
``os.environ`` is forbidden, except that current working directory is valid
in Vim and zsh (but not in daemon).
``home``
Current home directory. May be false.
.. _dev-segment_info-vim:
Vim
---
Vim ``segment_info`` argument is a dictionary with the following keys:
``window``
``vim.Window`` object. ``vim.current.window`` or ``vim.windows[number - 1]``
may be used to obtain such object. May be a false object, in which case any
of this objects properties must not be used.
``winnr``
Window number. Same as ``segment_info['window'].number`` *assuming* Vim is
new enough for ``vim.Window`` object to have ``number`` attribute.
``window_id``
Internal powerline window id, unique for each newly created window. It is
safe to assume that this ID is hashable and supports equality comparison,
but no other assumptions about it should be used. Currently uses integer
numbers incremented each time window is created.
``buffer``
``vim.Buffer`` object. One may be obtained using ``vim.current.buffer``,
``segment_info['window'].buffer`` or ``vim.buffers[some_number]``. Note that
in the latter case depending on vim version ``some_number`` may be ``bufnr``
or the internal Vim buffer index which is *not* buffer number. For this
reason to get ``vim.Buffer`` object other then stored in ``segment_info``
dictionary iteration over ``vim.buffers`` and checking their ``number``
attributes should be performed.
``bufnr``
Buffer number.
``tabpage``
``vim.Tabpage`` object. One may be obtained using ``vim.current.tabpage`` or
``vim.tabpages[number - 1]``. May be a false object, in which case no
objects properties can be used.
``tabnr``
Tabpage number.
``mode``
Current mode.
``encoding``
Value of ``&encoding`` from the time when powerline was initialized. It
should be used to convert return values.
.. note::
Segment generally should not assume that it is run for the current window,
current buffer or current tabpage. “Current window” and “current buffer”
restrictions may be ignored if ``window_cached`` decorator is used, “current
tabpage” restriction may be safely ignored if segment is not supposed to be
used in tabline.
.. warning::
Powerline is being tested with vim-7.0.112 (some minor sanity check) and
latest Vim. This means that most of the functionality like
``vim.Window.number``, ``vim.*.vars``, ``vim.*.options`` or even ``dir(vim
object)`` should be avoided in segments that want to be included in the
upstream.
Shell
-----
``args``
Parsed shell arguments: a ``argparse.Namespace`` object. Check out
``powerline-render --help`` for the list of all available arguments.
Currently it is expected to contain at least the following attributes:
``last_exit_code``
Exit code returned by last shell command. Is either one integer,
``sig{name}`` or ``sig{name}+core`` (latter two are only seen in ``rc``
shell).
``last_pipe_status``
List of exit codes returned by last programs in the pipe or some false
object. Only available in ``zsh`` and ``rc``. Is a list of either
integers, ``sig{name}`` or ``sig{name}+core`` (latter two are only seen
in ``rc`` shell).
``jobnum``
Number of background jobs.
``renderer_arg``
Dictionary containing some keys that are additional arguments used by
shell bindings. *This attribute must not be used directly*: all
arguments from this dictionary are merged with ``segment_info``
dictionary. Known to have at least the following keys:
``client_id``
Identifier unique to one shell instance. Is used to record instance
state by powerline daemon. In tmux this is the same as :ref:`pane_id
<dev-seginfo-shell-renarg-pane_id>`.
It is not guaranteed that existing client ID will not be retaken
when old shell with this ID quit: usually process PID is used as
a client ID.
It is also not guaranteed that client ID will be process PID, number
or something else at all. It is guaranteed though that client ID
will be some hashable object which supports equality comparison.
``local_theme``
Local theme that will be used by shell. One should not rely on the
existence of this key.
.. _dev-seginfo-shell-renarg-pane_id:
``pane_id``
Identifier unique to each tmux pane. Is always an integer, optional.
Obtained by using ``tmux display -p '#D'``, then all leading spaces
and per cent signs are stripped and the result is converted into an
integer.
Other keys, if any, are specific to segments.
Ipython
-------
``ipython``
Some object which has ``prompt_count`` attribute. Currently it is guaranteed
to have only this attribute.
Attribute ``prompt_count`` contains the so-called “history count”
(equivalent to ``\N`` in ``in_template``).
Pdb
---
``pdb``
Currently active :py:class:`pdb.Pdb` instance.
``curframe``
Frame which will be run next. Note: due to the existence of
:py:func:`powerline.listers.pdb.frame_lister` one must not use
``segment_info['pdb'].curframe``.
``initial_stack_length``
Equal to the length of :py:attr:`pdb.Pdb.stack` at the first invocation of
the prompt decremented by one.
i3wm
----
``mode``
Currently active i3 mode (as a string).
``output``
``xrandr`` output name currently drawing to. Currently only available
in lemonbar bindings.
``workspace``
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
=============
.. autoclass:: powerline.segments.Segment
:members:
PowerlineLogger class
=====================
.. autoclass:: powerline.PowerlineLogger
:members:
:undoc-members:

View file

@ -0,0 +1,21 @@
****************************************
Tips and tricks for powerline developers
****************************************
Profiling powerline in Vim
==========================
Given that current directory is the root of the powerline repository the
following command may be used:
.. code-block:: sh
vim --cmd 'let g:powerline_pyeval="powerline#debug#profile_pyeval"' \
--cmd 'set rtp=powerline/bindings/vim' \
-c 'runtime! plugin/powerline.vim' \
{other arguments if needed}
After some time run ``:WriteProfiling {filename}`` Vim command. Currently this
only works with recent Vim and python-2*. It should be easy to modify
:file:`powerline/bindings/vim/autoload/powerline/debug.vim` to suit other
needs.

28
docs/source/index.rst Normal file
View file

@ -0,0 +1,28 @@
*********
Powerline
*********
.. toctree::
:maxdepth: 3
:glob:
overview
installation
usage
configuration
develop
troubleshooting
tips-and-tricks
license-and-credits
.. toctree::
:maxdepth: 2
commands
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View file

@ -0,0 +1,131 @@
************
Installation
************
Generic requirements
====================
* Python 2.6 or later, 3.2 or later, PyPy 2.0 or later, PyPy3 2.3 or later. It
is the only non-optional requirement.
.. warning:
It is highly advised to use UCS-4 version of Python because UCS-2 version
uses significantly slower text processing (length determination and
non-printable character replacement) functions due to the need of
supporting unicode characters above U+FFFF which are represented as
surrogate pairs. This price will be paid even if configuration has no such
characters.
* C compiler. Required to build powerline client on linux. If it is not present
then powerline will fall back to shell script or python client.
* ``socat`` program. Required for shell variant of client which runs a bit
faster than python version of the client, but still slower than C version.
* ``psutil`` python package. Required for some segments like cpu_percent. Some
segments have linux-only fallbacks for ``psutil`` functionality.
* ``hglib`` python package *and* mercurial executable. Required to work with
mercurial repositories.
* ``pygit2`` python package or ``git`` executable. Required to work with ``git``
repositories.
* ``bzr`` python package (note: *not* standalone executable). Required to work
with bazaar repositories.
* ``pyuv`` python package. Required for :ref:`libuv-based watcher
<config-common-watcher>` to work.
* ``i3ipc`` python package. Required for i3wm bindings and segments.
* ``xrandr`` program. Required for the multi-monitor lemonbar binding and the
:py:func:`powerline.listers.i3wm.output_lister`.
.. note::
Until bazaar supports Python-3 or PyPy powerline will not support
repository information when running in these interpreters.
.. _repository-root:
.. note::
When using ``pip``, the ``{repository_root}`` directory referenced in
documentation may be found using ``pip show powerline-status``. In the output
of ``pip show`` there is a line like ``Location: {path}``, that ``{path}`` is
``{repository_root}``. Unless it is ``--editable`` installation this is only
applicable for ``{repository_root}/powerline/…`` paths: something like
``{repository_root}/scripts/powerline-render`` is not present.
When using other packages referenced paths may not exist, in this case refer
to package documentation.
Pip installation
================
Due to a naming conflict with an unrelated project, powerline is available on
PyPI under the ``powerline-status`` name:
.. code-block:: sh
pip install powerline-status
is the preferred method because this will get the latest release. To get current
development version
.. code-block:: sh
pip install --user git+https://github.com/powerline/powerline
may be used. If powerline was already checked out into some directory
.. code-block:: sh
pip install --user --editable={path_to_powerline}
is useful, but note that in this case ``pip`` will not install ``powerline``
executable and something like
.. code-block:: sh
ln -s {path_to_powerline}/scripts/powerline ~/.local/bin
will have to be done (:file:`~/.local/bin` should be replaced with some path
present in ``$PATH``).
.. note::
We can use either ``https``(``git+ssh://git@github.com/powerline/powerline``)
or ``https``(``git+https://github.com/powerline/powerline``) protocols.
``git`` protocol is deprecated by Github.
Fonts installation
==================
Powerline uses several special glyphs to get the arrow effect and some custom
symbols for developers. This requires having either a symbol font or a patched
font installed in the system. The used application (e.g. terminal emulator) must
also either be configured to use patched fonts (in some cases even support it
because custom glyphs live in private use area which some applications reserve
for themselves) or support fontconfig for powerline to work properly with
powerline-specific glyphs.
:ref:`24-bit color support <config-common-term_truecolor>` may be enabled if
used terminal emulator supports it (see :ref:`the terminal emulator support
matrix <usage-terminal-emulators>`).
There are basically two ways to get powerline glyphs displayed: use
:file:`PowerlineSymbols.otf` font as a fallback for one of the existing fonts or
install a patched font.
.. _installation-patched-fonts:
Patched fonts
-------------
This method is the fallback method and works for every terminal.
Download the font from `powerline-fonts`_. If preferred font cant be found in
the `powerline-fonts`_ repo, then patching the preferred font is needed instead.
.. _powerline-fonts: https://github.com/powerline/fonts
After downloading this font refer to platform-specific instructions.
Installation on various platforms
=================================
.. toctree::
Linux <installation/linux>
OS X <installation/osx>

View file

@ -0,0 +1,110 @@
*********************
Installation on Linux
*********************
The following distribution-specific packages are officially supported, and they
provide an easy way of installing and upgrading Powerline. The packages will
automatically do most of the configuration.
* `Arch Linux (AUR), Python 2 version <https://aur.archlinux.org/packages/python2-powerline-git/>`_
* `Arch Linux (AUR), Python 3 version <https://aur.archlinux.org/packages/python-powerline-git/>`_
* Gentoo Live ebuild in `raiagent <https://github.com/leycec/raiagent>`_ overlay
* Powerline package is available for Debian starting from Wheezy (via `backports
<https://packages.debian.org/wheezy-backports/powerline>`_). Use `search
<https://packages.debian.org/search?keywords=powerline&searchon=names&suite=all&section=all>`_
to get more information.
If used distribution does not have an official package installation guide below
should be followed:
1. Install Python 3.2+, Python 2.6+ or PyPy and ``pip`` with ``setuptools``.
This step is distribution-specific, so no commands provided.
2. Install Powerline using one of the following commands:
.. code-block:: sh
pip install --user powerline-status
will get the latest release version and
.. code-block:: sh
pip install --user git+https://github.com/powerline/powerline
will get the latest development version.
.. note:: Due to the naming conflict with an unrelated project powerline is
named ``powerline-status`` in PyPI.
.. note::
Powerline developers should be aware that``pip install --editable`` does
not currently fully work. Installation performed this way are missing
``powerline`` executable that needs to be symlinked. It will be located in
``scripts/powerline``.
Fonts installation
==================
Fontconfig
----------
This method only works on Linux. Its the second recommended method if terminal
emulator supports it as patching fonts is not needed, and it generally works
with any coding font.
#. Download the latest version of the symbol font and fontconfig file::
wget https://github.com/powerline/powerline/raw/develop/font/PowerlineSymbols.otf
wget https://github.com/powerline/powerline/raw/develop/font/10-powerline-symbols.conf
#. Move the symbol font to a valid X font path. Valid font paths can be
listed with ``xset q``::
mv PowerlineSymbols.otf ~/.local/share/fonts/
#. Update font cache for the path the font was moved to (root privileges may be
needed to update cache for the system-wide paths)::
fc-cache -vf ~/.local/share/fonts/
#. Install the fontconfig file. For newer versions of fontconfig the config
path is ``~/.config/fontconfig/conf.d/``, for older versions its
``~/.fonts.conf.d/``::
mv 10-powerline-symbols.conf ~/.config/fontconfig/conf.d/
If custom symbols still cannot be seen then try closing all instances of the
terminal emulator. Restarting X may be needed for the changes to take effect.
If custom symbols *still* cant be seen, double-check that the font have been
installed to a valid X font path, and that the fontconfig file was installed to
a valid fontconfig path. Alternatively try to install a :ref:`patched font
<installation-patched-fonts>`.
Patched font installation
-------------------------
This is the preferred method, but it is not always available because not all
fonts were patched and not all fonts *can* be patched due to licensing issues.
After downloading font the following should be done:
#. Move the patched font to a valid X font path. Valid font paths can be
listed with ``xset q``::
mv 'SomeFont for Powerline.otf' ~/.local/share/fonts/
#. Update font cache for the path the font was moved to (root privileges may be
needed for updating font cache for some paths)::
fc-cache -vf ~/.local/share/fonts/
After installing patched font terminal emulator, GVim or whatever application
powerline should work with must be configured to use the patched font. The
correct font usually ends with *for Powerline*.
If custom symbols cannot be seen then try closing all instances of the terminal
emulator. X server may need to be restarted for the changes to take effect.
If custom symbols *still* cant be seen then double-check that the font have
been installed to a valid X font path.

View file

@ -0,0 +1,71 @@
********************
Installation on OS X
********************
Python package
==============
1. Install a proper Python version (see `issue #39
<https://github.com/powerline/powerline/issues/39>`_ for a discussion
regarding the required Python version on OS X)::
sudo port select python python27-apple
Homebrew may be used here::
brew install python
.. note::
There are three variants of the powerline client. The fastest is
written in C and will be compiled if the compiler and libraries are
detected during installation. The second fastest option is
:file:`powerline.sh` which requires ``socat`` and ``coreutils``.
``coreutils`` may be installed using ``brew install
coreutils``. If neither of these are viable, then Powerline will
utilize a fallback client written in Python.
2. Install Powerline using one of the following commands:
.. code-block:: sh
pip install --user powerline-status
will get current release version and
.. code-block:: sh
pip install --user git+https://github.com/powerline/powerline
will get latest development version.
.. warning::
When using ``brew install`` to install Python one must not supply
``--user`` flag to ``pip``.
.. note::
Due to the naming conflict with an unrelated project powerline is named
``powerline-status`` in PyPI.
.. note::
Powerline developers should be aware that ``pip install --editable`` does
not currently fully work. Installation performed this way are missing
``powerline`` executable that needs to be symlinked. It will be located in
``scripts/powerline``.
Vim installation
================
Any terminal vim version with Python 3.2+ or Python 2.6+ support should work,
but MacVim users need to install it using the following command::
brew install macvim --env-std --with-override-system-vim
Fonts installation
==================
To install patched font double-click the font file in Finder, then click
:guilabel:`Install this font` in the preview window.
After installing the patched font MacVim or terminal emulator (whatever
application powerline should work with) need to be configured to use the patched
font. The correct font usually ends with *for Powerline*.

View file

@ -0,0 +1,31 @@
*******************
License and credits
*******************
Powerline is licensed under the `MIT license
<https://raw.github.com/powerline/powerline/develop/LICENSE>`_.
..
This document is parsed by powerline_automan.py module. Do not forget to
check that file before altering this one. Specifically it expects
``Authors`` and ``Contributors`` sections underlined by ``---``, a list of
authors in format ``* `{name} <`` in the “Authors” section and fonts
contributor name in format ``The glyphs in the font patcher are created by
{name},`` in the “Contributors” section.
Authors
-------
* `Kim Silkebækken <https://github.com/Lokaltog>`_
* `Nikolay Pavlov <https://github.com/ZyX-I>`_
* `Kovid Goyal <https://github.com/kovidgoyal>`_
Contributors
------------
* `List of contributors
<https://github.com/powerline/powerline/contributors>`_
* The glyphs in the font patcher are created by Fabrizio Schiavi, creator of
the excellent coding font `Pragmata Pro`_.
.. _`Pragmata Pro`: http://www.fsd.it/fonts/pragmatapro.htm

67
docs/source/overview.rst Normal file
View file

@ -0,0 +1,67 @@
********
Overview
********
**Powerline is a statusline plugin for vim, and provides statuslines and
prompts for several other applications, including zsh, bash, tmux, IPython,
Awesome, i3 and Qtile.**
Features
--------
* **Extensible and feature rich, written in Python.** Powerline was
completely rewritten in Python to get rid of as much vimscript as
possible. This has allowed much better extensibility, leaner and better
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.
* **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
bash/zsh and other applications. Its simple to write renderers for any
other applications that Powerline doesnt yet support.
* **Configuration and colorschemes written in JSON.** JSON is
a standardized, simple and easy to use file format that allows for easy
user configuration across all of Powerlines supported applications.
* **Fast and lightweight, with daemon support for even better performance.**
Although the code base spans a couple of thousand lines of code with no
goal of “less than X lines of code”, the main focus is on good performance
and as little code as possible while still providing a rich set of
features. The new daemon also ensures that only one Python instance is
launched for prompts and statuslines, which provides excellent
performance.
*But I hate Python / I dont need shell prompts / this is just too much
hassle for me / what happened to the original vim-powerline project / …*
You should check out some of the Powerline derivatives. The most lightweight
and feature-rich alternative is currently the `vim-airline
<https://github.com/vim-airline/vim-airline>`_ project.
Screenshots
-----------
Vim statusline
^^^^^^^^^^^^^^
**Mode-dependent highlighting**
* .. image:: _static/img/pl-mode-normal.png
:alt: Normal mode
* .. image:: _static/img/pl-mode-insert.png
:alt: Insert mode
* .. image:: _static/img/pl-mode-visual.png
:alt: Visual mode
* .. image:: _static/img/pl-mode-replace.png
:alt: Replace mode
**Automatic truncation of segments in small windows**
* .. image:: _static/img/pl-truncate1.png
:alt: Truncation illustration
* .. image:: _static/img/pl-truncate2.png
:alt: Truncation illustration
* .. image:: _static/img/pl-truncate3.png
:alt: Truncation illustration

View file

@ -0,0 +1,62 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
from sphinx.ext import autodoc
from powerline.lint.inspect import formatconfigargspec, getconfigargspec
from powerline.segments import Segment
from powerline.lib.unicode import unicode
def formatvalue(val):
if type(val) is str:
return '="' + unicode(val, 'utf-8').replace('"', '\\"').replace('\\', '\\\\') + '"'
else:
return '=' + repr(val)
class ThreadedDocumenter(autodoc.FunctionDocumenter):
'''Specialized documenter subclass for ThreadedSegment subclasses.'''
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return (isinstance(member, Segment) or
super(ThreadedDocumenter, cls).can_document_member(member, membername, isattr, parent))
def format_args(self):
argspec = getconfigargspec(self.object)
return formatconfigargspec(*argspec, formatvalue=formatvalue).replace('\\', '\\\\')
class Repr(object):
def __init__(self, repr_contents):
self.repr_contents = repr_contents
def __repr__(self):
return '<{0}>'.format(self.repr_contents)
class EnvironDocumenter(autodoc.AttributeDocumenter):
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
if type(member) is dict and member.get('environ') is os.environ:
return True
else:
return False
def import_object(self, *args, **kwargs):
ret = super(EnvironDocumenter, self).import_object(*args, **kwargs)
if not ret:
return ret
self.object = self.object.copy()
if 'home' in self.object:
self.object.update(home=Repr('home directory'))
self.object.update(environ=Repr('environ dictionary'))
return True
def setup(app):
autodoc.setup(app)
app.add_autodocumenter(ThreadedDocumenter)
app.add_autodocumenter(EnvironDocumenter)

View file

@ -0,0 +1,408 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
import re
import codecs
from collections import namedtuple
from argparse import REMAINDER
from functools import reduce
from docutils.parsers.rst import Directive
from docutils.parsers.rst.directives import unchanged_required
from docutils import nodes
from powerline.lib.unicode import u
AUTHOR_LINE_START = '* `'
GLYPHS_AUTHOR_LINE_START = '* The glyphs in the font patcher are created by '
def get_authors():
credits_file = os.path.join(os.path.dirname(__file__), 'license-and-credits.rst')
authors = []
glyphs_author = None
with codecs.open(credits_file, encoding='utf-8') as CF:
section = None
prev_line = None
for line in CF:
line = line[:-1]
if line and not line.replace('-', ''):
section = prev_line
elif section == 'Authors':
if line.startswith(AUTHOR_LINE_START):
authors.append(line[len(AUTHOR_LINE_START):line.index('<')].strip())
elif section == 'Contributors':
if line.startswith(GLYPHS_AUTHOR_LINE_START):
assert(not glyphs_author)
glyphs_author = line[len(GLYPHS_AUTHOR_LINE_START):line.index(',')].strip()
prev_line = line
return {
'authors': ', '.join(authors),
'glyphs_author': glyphs_author,
}
class AutoManSubparsers(object):
def __init__(self):
self.parsers = []
def add_parser(self, command, *args, **kwargs):
self.parsers.append((command, AutoManParser(*args, **kwargs)))
return self.parsers[-1][1]
Argument = namedtuple('Argument', ('names', 'help', 'choices', 'metavar', 'required', 'nargs', 'is_option', 'is_long_option', 'is_short_option', 'multi', 'can_be_joined'))
def parse_argument(*args, **kwargs):
is_option = args[0].startswith('-')
is_long_option = args[0].startswith('--')
is_short_option = is_option and not is_long_option
action = kwargs.get('action', 'store')
multi = kwargs.get('action') in ('append',) or kwargs.get('nargs') is REMAINDER
nargs = kwargs.get('nargs', (1 if action in ('append', 'store') else 0))
return Argument(
names=args,
help=u(kwargs.get('help', '')),
choices=[str(choice) for choice in kwargs.get('choices', [])],
metavar=kwargs.get('metavar') or args[-1].lstrip('-').replace('-', '_').upper(),
required=kwargs.get('required', False) if is_option else (
kwargs.get('nargs') not in ('?',)),
nargs=nargs,
multi=multi,
is_option=is_option,
is_long_option=is_long_option,
is_short_option=is_short_option,
can_be_joined=(is_short_option and not multi and not nargs)
)
class AutoManGroup(object):
is_short_option = False
is_option = False
is_long_option = False
can_be_joined = False
def __init__(self):
self.arguments = []
self.required = False
def add_argument(self, *args, **kwargs):
self.arguments.append(parse_argument(*args, **kwargs))
def add_argument_group(self, *args, **kwargs):
self.arguments.append(AutoManGroup())
return self.arguments[-1]
class SurroundWith():
def __init__(self, ret, condition, start='[', end=']'):
self.ret = ret
self.condition = condition
self.start = start
self.end = end
def __enter__(self, *args):
if self.condition:
self.ret.append(nodes.Text(self.start))
def __exit__(self, *args):
if self.condition:
self.ret.append(nodes.Text(self.end))
def insert_separators(ret, sep):
for i in range(len(ret) - 1, 0, -1):
ret.insert(i, nodes.Text(sep))
return ret
def format_usage_arguments(arguments, base_length=None):
line = []
prev_argument = None
arg_indexes = [0]
arguments = arguments[:]
while arguments:
argument = arguments.pop(0)
if isinstance(argument, nodes.Text):
line += [argument]
continue
can_join_arguments = (
argument.is_short_option
and prev_argument
and prev_argument.can_be_joined
and prev_argument.required == argument.required
)
if (
prev_argument
and not prev_argument.required
and prev_argument.can_be_joined
and not can_join_arguments
):
line.append(nodes.Text(']'))
arg_indexes.append(len(line))
if isinstance(argument, AutoManGroup):
arguments = (
[nodes.Text(' (')]
+ insert_separators(argument.arguments[:], nodes.Text(' |'))
+ [nodes.Text(' )')]
+ arguments
)
else:
if not can_join_arguments:
line.append(nodes.Text(' '))
with SurroundWith(line, not argument.required and not argument.can_be_joined):
if argument.can_be_joined and not can_join_arguments and not argument.required:
line.append(nodes.Text('['))
if argument.is_option:
line.append(nodes.strong())
name = argument.names[0]
if can_join_arguments:
name = name[1:]
# `--` is automatically transformed into &#8211; (EN DASH)
# when parsing into HTML. We do not need this.
line[-1] += [nodes.Text(char) for char in name]
elif argument.nargs is REMAINDER:
line.append(nodes.Text('['))
line.append(nodes.strong())
line[-1] += [nodes.Text(char) for char in '--']
line.append(nodes.Text('] '))
if argument.nargs:
assert(argument.nargs in (1, '?', REMAINDER))
with SurroundWith(
line, (
True
if argument.nargs is REMAINDER
else (argument.nargs == '?' and argument.is_option)
)
):
if argument.is_long_option:
line.append(nodes.Text('='))
line.append(nodes.emphasis(text=argument.metavar))
elif not argument.is_option:
line.append(nodes.strong(text=argument.metavar))
if argument.multi:
line.append(nodes.Text(''))
prev_argument = argument
if (
prev_argument
and prev_argument.can_be_joined
and not prev_argument.required
):
line.append(nodes.Text(']'))
arg_indexes.append(len(line))
ret = []
if base_length is None:
ret = line
else:
length = base_length
prev_arg_idx = arg_indexes.pop(0)
while arg_indexes:
next_arg_idx = arg_indexes.pop(0)
arg_length = sum((len(element.astext()) for element in line[prev_arg_idx:next_arg_idx]))
if length + arg_length > 68:
ret.append(nodes.Text('\n' + (' ' * base_length)))
length = base_length
ret += line[prev_arg_idx:next_arg_idx]
length += arg_length
prev_arg_idx = next_arg_idx
return ret
LITERAL_RE = re.compile(r"`(.*?)'")
def parse_argparse_text(text):
rst_text = LITERAL_RE.subn(r'``\1``', text)[0]
ret = []
for i, text in enumerate(rst_text.split('``')):
if i % 2 == 0:
ret.append(nodes.Text(text))
else:
ret.append(nodes.literal(text=text))
return ret
def flatten_groups(arguments):
for argument in arguments:
if isinstance(argument, AutoManGroup):
for group_argument in flatten_groups(argument.arguments):
yield group_argument
else:
yield argument
def format_arguments(arguments):
return [nodes.definition_list(
'', *[
nodes.definition_list_item(
'',
nodes.term(
# node.Text('') is required because otherwise for some
# reason first name node is seen in HTML output as
# `<strong>abc</strong>`.
'', *([nodes.Text('')] + (
insert_separators([
nodes.strong('', '', *[nodes.Text(ch) for ch in name])
for name in argument.names
], ', ')
if argument.is_option else
# Unless node.Text('') is here metavar is written in
# bold in the man page.
[nodes.Text(''), nodes.emphasis(text=argument.metavar)]
) + (
[] if not argument.is_option or not argument.nargs else
[nodes.Text(' '), nodes.emphasis('', argument.metavar)]
))
),
nodes.definition('', nodes.paragraph('', *parse_argparse_text(argument.help or ''))),
)
for argument in flatten_groups(arguments)
] + [
nodes.definition_list_item(
'',
nodes.term(
'', nodes.Text(''),
nodes.strong(text='-h'),
nodes.Text(', '),
nodes.strong('', '', nodes.Text('-'), nodes.Text('-help')),
),
nodes.definition('', nodes.paragraph('', nodes.Text('Display help and exit.')))
)
]
)]
def format_subcommand_usage(arguments, subcommands, progname, base_length):
return reduce((lambda a, b: a + reduce((lambda c, d: c + d), b, [])), [
[
[progname]
+ format_usage_arguments(arguments)
+ [nodes.Text(' '), nodes.strong(text=subcmd)]
+ format_usage_arguments(subparser.arguments)
+ [nodes.Text('\n')]
for subcmd, subparser in subparsers.parsers
]
for subparsers in subcommands
], [])
def format_subcommands(subcommands):
return reduce((lambda a, b: a + reduce((lambda c, d: c + d), b, [])), [
[
[
nodes.section(
'',
nodes.title(text='Arguments specific to ' + subcmd + ' subcommand'),
*format_arguments(subparser.arguments),
ids=['subcmd-' + subcmd]
)
]
for subcmd, subparser in subparsers.parsers
]
for subparsers in subcommands
], [])
class AutoManParser(object):
def __init__(self, description=None, help=None):
self.description = description
self.help = help
self.arguments = []
self.subcommands = []
def add_argument(self, *args, **kwargs):
self.arguments.append(parse_argument(*args, **kwargs))
def add_subparsers(self):
self.subcommands.append(AutoManSubparsers())
return self.subcommands[-1]
def add_mutually_exclusive_group(self):
self.arguments.append(AutoManGroup())
return self.arguments[-1]
def automan_usage(self, prog):
block = nodes.literal_block()
progname = nodes.strong()
progname += [nodes.Text(prog)]
base_length = len(prog)
if self.subcommands:
block += format_subcommand_usage(self.arguments, self.subcommands, progname, base_length)
else:
block += [progname]
block += format_usage_arguments(self.arguments, base_length)
return [block]
def automan_description(self):
ret = []
if self.help:
ret += parse_argparse_text(self.help)
ret += format_arguments(self.arguments) + format_subcommands(self.subcommands)
return ret
class AutoMan(Directive):
required_arguments = 1
optional_arguments = 0
option_spec = dict(prog=unchanged_required, minimal=bool)
has_content = False
def run(self):
minimal = self.options.get('minimal')
module = self.arguments[0]
template_args = {}
template_args.update(get_authors())
get_argparser = __import__(str(module), fromlist=[str('get_argparser')]).get_argparser
parser = get_argparser(AutoManParser)
if minimal:
container = nodes.container()
container += parser.automan_usage(self.options['prog'])
container += parser.automan_description()
return [container]
synopsis_section = nodes.section(
'',
nodes.title(text='Synopsis'),
ids=['synopsis-section'],
)
synopsis_section += parser.automan_usage(self.options['prog'])
description_section = nodes.section(
'', nodes.title(text='Description'),
ids=['description-section'],
)
description_section += parser.automan_description()
author_section = nodes.section(
'', nodes.title(text='Author'),
nodes.paragraph(
'',
nodes.Text('Written by {authors} and contributors. The glyphs in the font patcher are created by {glyphs_author}.'.format(
**get_authors()
))
),
ids=['author-section']
)
issues_url = 'https://github.com/powerline/powerline/issues'
reporting_bugs_section = nodes.section(
'', nodes.title(text='Reporting bugs'),
nodes.paragraph(
'',
nodes.Text('Report {prog} bugs to '.format(
prog=self.options['prog'])),
nodes.reference(
issues_url, issues_url,
refuri=issues_url,
internal=False,
),
nodes.Text('.'),
),
ids=['reporting-bugs-section']
)
return [synopsis_section, description_section, author_section, reporting_bugs_section]
def setup(app):
app.add_directive('automan', AutoMan)

View file

@ -0,0 +1,110 @@
***************
Tips and tricks
***************
Vim
===
Useful settings
---------------
You may find the following vim settings useful when using the Powerline
statusline:
.. code-block:: vim
set laststatus=2 " Always display the statusline in all windows
set showtabline=2 " Always display the tabline, even if there is only one tab
set noshowmode " Hide the default mode text (e.g. -- INSERT -- below the statusline)
.. _tips-and-tricks-vscode:
VS-Code
=======
Useful settings
---------------
To make powerline work in the internal terminal, add the following settings;
where the shell command needs to be adjusted according to your preferred shell.
.. code-block:: json
"terminal.integrated.shell.linux": "/bin/bash"
"terminal.integrated.inheritEnv": true
.. _tips-and-tricks-urxvt:
Rxvt-unicode
============
Terminus font and urxvt
-----------------------
The Terminus fonts does not have the powerline glyphs and unless someone submits
a patch to the font author, it is unlikely to happen. However, Andre Klärner
came up with this work around: In your ``~/.Xdefault`` file add the following::
urxvt*font: xft:Terminus:pixelsize=12,xft:Inconsolata\ for\ Powerline:pixelsize=12
This will allow urxvt to fallback onto the Inconsolata fonts in case it does not
find the right glyphs within the terminus font.
Source Code Pro font and urxvt
------------------------------
Much like the terminus font that was mentioned above, a similar fix can be
applied to the Source Code Pro fonts.
In the ``~/.Xdefaults`` add the following::
URxvt*font: xft:Source\ Code\ Pro\ Medium:pixelsize=13:antialias=true:hinting=true,xft:Source\ Code\ Pro\ Medium:pixelsize=13:antialias=true:hinting=true
I noticed that Source Code Pro has the glyphs there already, but the pixel size
of the fonts play a role in whether or not the > or the < separators showing up
or not. Using font size 12, glyphs on the right hand side of the powerline are
present, but the ones on the left dont. Pixel size 14, brings the reverse
problem. Font size 13 seems to work just fine.
Reloading powerline after update
================================
Once you have updated powerline you generally have the following options:
#. Restart the application you are using it in. This is the safest one. Will not
work if the application uses ``powerline-daemon``.
#. For shell and tmux bindings (except for zsh with libzpython): do not do
anything if you do not use ``powerline-daemon``, run ``powerline-daemon
--replace`` if you do.
#. Use powerline reloading feature.
.. warning::
This feature is an unsafe one. It is not guaranteed to work always, it may
render your Python constantly error out in place of displaying powerline
and sometimes may render your application useless, forcing you to
restart.
*Do not report any bugs occurred when using this feature unless you know
both what caused it and how this can be fixed.*
* When using zsh with libzpython use
.. code-block:: bash
powerline-reload
.. note:: This shell function is only defined when using libzpython.
* When using IPython use
::
%powerline reload
* When using Vim use
.. code-block:: Vim
py powerline.reload()
" or (depending on Python version you are using)
py3 powerline.reload()

View file

@ -0,0 +1,333 @@
***************
Troubleshooting
***************
System-specific issues
======================
.. toctree::
Linux <troubleshooting/linux>
OS X <troubleshooting/osx>
Common issues
=============
After an update something stopped working
-----------------------------------------
Assuming powerline was working before update and stopped only after there are
two possible explanations:
* You have more then one powerline installation (e.g. ``pip`` and ``Vundle``
installations) and you have updated only one.
* Update brought some bug to powerline.
In the second case you, of course, should report the bug to `powerline bug
tracker <https://github.com/powerline/powerline>`_. In the first you should
make sure you either have only one powerline installation or you update all of
them simultaneously (beware that in the second case you are not supported). To
diagnose this problem you may do the following:
#) If this problem is observed within the shell make sure that
.. code-block:: sh
python -c 'import powerline; print (powerline.__file__)'
which should report something like
:file:`/usr/lib64/python2.7/site-packages/powerline/__init__.pyc` (if
powerline is installed system-wide) or
:file:`/home/USER/.../powerline/__init__.pyc` (if powerline was cloned
somewhere, e.g. in :file:`/home/USER/.vim/bundle/powerline`) reports the same
location you use to source in your shell configuration: in first case it
should be some location in :file:`/usr` (e.g.
:file:`/usr/share/zsh/site-contrib/powerline.zsh`), in the second it should
be something like
:file:`/home/USER/.../powerline/bindings/zsh/powerline.zsh`. If this is true
it may be a powerline bug, but if locations do not match you should not
report the bug until you observe it on configuration where locations do
match.
#) If this problem is observed specifically within bash make sure that you clean
``$POWERLINE_COMMAND`` and ``$PROMPT_COMMAND`` environment variables on
startup or, at least, that it was cleaned after update. While different
``$POWERLINE_COMMAND`` variable should not cause any troubles most of time
(and when it will cause troubles are rather trivial) spoiled
``$PROMPT_COMMAND`` may lead to strange error messages or absence of exit
code reporting.
These are the sources which may keep outdated environment variables:
* Any command launched from any application inherits its environment unless
callee explicitly requests to use specific environment. So if you did
``exec bash`` after update it is rather unlikely to fix the problem.
* More interesting: `tmux` is a client-server application, it keeps one
server instance per one user. You probably already knew that, but there is
an interesting consequence: once `tmux` server was started it inherits its
environment from the callee and keeps it *forever* (i.e. until server is
killed). This environment is then inherited by applications you start with
``tmux new-session``. Easiest solution is to kill tmux with ``tmux
kill-server``, but you may also use ``tmux set-environment -u`` to unset
offending variables.
* Also check `When using z powerline shows wrong number of jobs`_: though
this problem should not be seen after update only, it contains another
example of ``$PROMPT_COMMAND`` spoiling results.
#) If this problem is observed within the vim instance you should check out the
output of the following Ex mode commands
.. code-block:: vim
python import powerline as pl ; print (pl.__file__)
python3 import powerline as pl ; print (pl.__file__)
One (but not both) of them will most likely error out, this is OK. The same
rules apply as in the 1), but in place of sourcing you should seek for the
place where you modify `runtimepath` vim option. If you install powerline
using `VAM <https://github.com/MarcWeber/vim-addon-manager>`_ then no
explicit modifications of runtimpath were performed in your vimrc
(runtimepath is modified by VAM in this case), but powerline will be placed
in :file:`{plugin_root_dir}/powerline` where `{plugin_root_dir}` is stored in
VAM settings dictionary: do `echo g:vim_addon_manager.plugin_root_dir`.
There is a hint if you want to place powerline repository somewhere, but still
make powerline package importable anywhere: use
.. code-block:: sh
pip install --user --editable path/to/powerline
Tmux/screen-related issues
==========================
Im using tmux and Powerline looks like crap, whats wrong?
-----------------------------------------------------------
* You need to tell tmux that it has 256-color capabilities. Add this to your
:file:`.tmux.conf` to solve this issue::
set -g default-terminal "screen-256color"
* If youre using iTerm2, make sure that you have enabled the setting
:guilabel:`Set locale variables automatically` in :menuselection:`Profiles -->
Terminal --> Environment`.
* Make sure tmux knows that terminal it is running in support 256 colors. You
may tell it tmux by using ``-2`` option when launching it.
Im using tmux/screen and Powerline is colorless
------------------------------------------------
* If the above advices do not help, then you need to disable
:ref:`term_truecolor <config-common-term_truecolor>`.
* Alternative: set :ref:`additional_escapes <config-common-additional_escapes>`
to ``"tmux"`` or ``"screen"``. Note that it is known to work perfectly in
screen, but in tmux it may produce ugly spaces.
.. warning::
Both tmux and screen are not resending sequences escaped in such a way. Thus
even though additional escaping will work for the last shown prompt,
highlighting will eventually go away when tmux or screen will redraw screen
for some reason.
E.g. in screen it will go away when you used copy mode and prompt got out of
screen and in tmux it will go away immediately after you press ``<Enter>``.
In tmux there is a green bar in place of powerline
--------------------------------------------------
In order for tmux bindings to work ``powerline-config`` script is required to be
present in ``$PATH``. Alternatively one may define ``$POWERLINE_CONFIG_COMMAND``
environment variable pointing to the location of the script. *This variable must
be defined prior to launching tmux server and in the environment where server is
started from.*
Shell issues
============
Pipe status segment displays only last value in bash
----------------------------------------------------
Make sure that powerline command that sets prompt appears the very first in
``$PROMPT_COMMAND``. To do this ``powerline.sh`` needs to be sourced the very
last, after all other users of ``$PROMPT_COMMAND``.
Bash prompt stopped updating
----------------------------
Make sure that powerline commands appear in ``$PROMPT_COMMAND``: some users of
``$PROMPT_COMMAND`` have a habit of overwriting the value instead of
prepending/appending to it. All powerline commands start with ``_powerline`` or
``powerline``, e.g. ``_powerline_set_prompt``.
Bash prompt does not show last exit code
----------------------------------------
There are two possibilities here:
* You are using ``default`` theme in place of ``default_leftonly``. Unlike
``default_leftonly`` ``default`` theme was designed for shells with right
prompt support (e.g. zsh, tcsh, fish) and status in question is supposed to be
shown on the right side which bash cannot display.
* There is some other user of ``$PROMPT_COMMAND`` which prepended to this
variable, but did not bother keeping the exit code. For the best experience
powerline must appear first in ``$PROMPT_COMMAND`` which may be achieved by
sourcing powerline bindings the last.
.. note::
Resourcing bash bindings will not resolve the problem unless you clear
powerline commands from ``$PROMPT_COMMAND`` first.
When sourcing shell bindings it complains about missing command or file
-----------------------------------------------------------------------
If you are using ``pip`` based installation do not forget to add pip-specific
executable path to ``$PATH`` environment variable. This path usually looks
something like ``$HOME/.local/bin`` (linux) or
``$HOME/Library/Python/{python_version}/bin`` (OS X). One may check out where
``powerline-config`` script was installed by using ``pip show -f
powerline-status | grep powerline-config`` (does not always work).
I am suffering bad lags before displaying shell prompt
------------------------------------------------------
To get rid of these lags there currently are two options:
* Run ``powerline-daemon``. Powerline does not automatically start it for you.
See installation instructions for more details.
* Compile and install ``libzpython`` module that lives in
https://bitbucket.org/ZyX_I/zpython. This variant is zsh-specific.
* If you are a python package manager, be sure to set ``POWERLINE_COMMAND``
to your Powerline command. See installation instructions for details.
Prompt is spoiled after completing files in ksh
-----------------------------------------------
This is exactly why powerline has official mksh support, but not official ksh
support. If you know the solution feel free to share it in `powerline bug
tracker`_.
When using z powerline shows wrong number of jobs
-------------------------------------------------
This happens because `z <https://github.com/rupa/z>`_ is launching some jobs in
the background from ``$POWERLINE_COMMAND`` and these jobs fail to finish before
powerline prompt is run.
Solution to this problem is simple: be sure that :file:`z.sh` is sourced
strictly after :file:`powerline/bindings/bash/powerline.sh`. This way background
jobs are spawned by `z <https://github.com/rupa/z>`_ after powerline has done
its job.
When using shell I do not see powerline fancy characters
--------------------------------------------------------
If your locale encoding is not unicode (any encoding that starts with “utf” or
“ucs” will work, case is ignored) powerline falls back to ascii-only theme. You
should set up your system to use unicode locale or forget about powerline fancy
characters.
Urxvt unicode3 and frills
-------------------------
Make sure that, whatever urxvt package you're installing, both the `unicode3`
and `frills` features are enabled at compile time. Run
``urxvt --help 2>&1 | grep options:`` to get a list of enabled options.
This should contain at least `frills`, `unicode3` and optionally `iso14755`
if you want to input Unicode characters as well.
Compiler flags example:
--enable-frills \
--enable-unicode3
As long as your terminal emulator is compiled without unicode rendering,
no amount of configuration will make it display unicode characters.
They're being considered 'unnecessary features', but they add negligible
overhead to the size of the installed package (~100KB).
Vim issues
==========
My vim statusline has strange characters like ``^B`` in it!
-----------------------------------------------------------
* Please add ``set encoding=utf-8`` to your :file:`vimrc`.
My vim statusline has a lot of ``^`` or underline characters in it!
-------------------------------------------------------------------
* You need to configure the ``fillchars`` setting to disable statusline
fillchars (see ``:h 'fillchars'`` for details). Add this to your :file:`vimrc`
to solve this issue:
.. code-block:: vim
set fillchars+=stl:\ ,stlnc:\
My vim statusline is hidden/only appears in split windows!
----------------------------------------------------------
* Make sure that you have ``set laststatus=2`` in your :file:`vimrc`.
My vim statusline is not displayed completely and has too much spaces
---------------------------------------------------------------------
* Be sure you have ``ambiwidth`` option set to ``single``.
* Alternative: set :ref:`ambiwidth <config-common-ambiwidth>` to 2, remove fancy
dividers (they suck when ``ambiwidth`` is set to double).
Powerline loses color after editing vimrc
-----------------------------------------
If your vimrc has something like
.. code-block:: vim
autocmd! BufWritePost ~/.vimrc :source ~/.vimrc
used to automatically source vimrc after saving it then you must add ``nested``
after pattern (``vimrc`` in this case):
.. code-block:: vim
autocmd! BufWritePost ~/.vimrc nested :source ~/.vimrc
. Alternatively move ``:colorscheme`` command out of the vimrc to the file which
will not be automatically resourced.
Observed problem is that when you use ``:colorscheme`` command existing
highlighting groups are usually cleared, including those defined by powerline.
To workaround this issue powerline hooks ``Colorscheme`` event, but when you
source vimrc with ``BufWritePost`` (or any other) event, but without ``nested``
this event is not launched. See also `autocmd-nested
<http://vimcommunity.bitbucket.org/doc/autocmd.txt.html#autocmd-nested>`_ Vim
documentation.
Powerline loses color after saving any file
-------------------------------------------
It may be one of the incarnations of the above issue: specifically minibufexpl
is known to trigger it. If you are using minibufexplorer you should set
.. code-block:: vim
let g:miniBufExplForceSyntaxEnable = 1
variable so that this issue is not triggered. Complete explanation:
#. When MBE autocommand is executed it launches ``:syntax enable`` Vim command…
#. … which makes Vim source :file:`syntax/syntax.vim` file …
#. … which in turn sources :file:`syntax/synload.vim`
#. … which executes ``:colorscheme`` command. Normally this command triggers
``Colorscheme`` event, but in the first point minibufexplorer did set up
autocommands that miss ``nested`` attribute meaning that no events will be
triggered when processing MBE events.
.. note::
This setting was introduced in version 6.3.1 of `minibufexpl
<http://www.vim.org/scripts/script.php?script_id=159>`_ and removed in
version 6.5.0 of its successor `minibufexplorer
<http://www.vim.org/scripts/script.php?script_id=3239>`_. It is highly
advised to use the latter because `minibufexpl`_ was last updated late in
2004.

View file

@ -0,0 +1,78 @@
************************
Troubleshooting on Linux
************************
I cant see any fancy symbols, whats wrong?
--------------------------------------------
* Make sure that youve configured gvim or your terminal emulator to use
a patched font.
* You need to set your ``LANG`` and ``LC_*`` environment variables to
a UTF-8 locale (e.g. ``LANG=en_US.utf8``). Consult your Linux distros
documentation for information about setting these variables correctly.
* Make sure that vim is compiled with the ``--with-features=big`` flag.
* If youre using rxvt-unicode make sure that its compiled with the
``--enable-unicode3`` flag.
* If youre using xterm make sure you have told it to work with unicode. You may
need ``-u8`` command-line argument, ``uxterm`` shell wrapper that is usually
shipped with xterm for this or ``xterm*utf8`` property set to ``1`` or ``2``
in ``~/.Xresources`` (applied with ``xrdb``). Note that in case ``uxterm`` is
used configuration is done via ``uxterm*…`` properties and not ``xterm*…``.
In any case the only absolute requirement is launching xterm with UTF-8
locale.
* If you are using bitmap font make sure that
:file:`/etc/fonts/conf.d/70-no-bitmaps.conf` does not exist. If it does check
out your distribution documentation to find a proper way to remove it (so that
it wont reappear after update). E.g. in Gentoo this is::
eselect fontconfig disable 70-no-bitmaps.conf
(currently this only removes the symlink from :file:`/etc/fonts/conf.d`). Also
check out that no other fontconfig file does not have ``rejectfont`` tag that
tells fontconfig to disable bitmap fonts (they are referenced as not
scalable).
The fancy symbols look a bit blurry or “off”!
---------------------------------------------
* Make sure that you have patched all variants of your font (i.e. both the
regular and the bold font files).
I am seeing strange blocks in place of playing/paused/stopped signs
-------------------------------------------------------------------
If you are using ``powerline_unicode7`` :ref:`top-level theme
<config-common-default_top_theme>` then symbols for player segments are taken
from U+23F4U+23FA range which is missing from most fonts. You may fix the issue
by using `Symbola <http://users.teilar.gr/~g1951d/>`_ font (or any other font
which contains these glyphs).
If your terminal emulator is using fontconfig library then you can create
a fontconfig configuration file with the following contents:
.. code-block:: xml
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<alias>
<family>Terminus</family>
<prefer><family>Symbola</family></prefer>
</alias>
</fontconfig>
(replace ``Terminus`` with the name of the font you are using). Exact sequence
of actions you need to perform is different across distributions, most likely it
will work if you put the above xml into
:file:`/etc/fonts/conf.d/99-prefer-symbola.conf`. On Gentoo you need to put it
into :file:`/etc/fonts/conf.d/99-prefer-symbola.conf` and run::
eselect fontconfig enable 99-prefer-symbola
.
.. warning::
This answer is only applicable if you use ``powerline_unicode7`` theme or if
you configured powerline to use the same characters yourself.

View file

@ -0,0 +1,71 @@
***********************
Troubleshooting on OS X
***********************
I cant see any fancy symbols, whats wrong?
--------------------------------------------
* If youre using iTerm2, please update to `this revision
<https://github.com/gnachman/iTerm2/commit/8e3ad6dabf83c60b8cf4a3e3327c596401744af6>`_
or newer. Also make sure that Preferences>Profiles>Text>Non-ASCII Font is the same as
your main Font.
* You need to set your ``LANG`` and ``LC_*`` environment variables to
a UTF-8 locale (e.g. ``LANG=en_US.utf8``). Consult your Linux distros
documentation for information about setting these variables correctly.
The colors look weird in the default OS X Terminal app!
-------------------------------------------------------
* The arrows may have the wrong colors if you have changed the “minimum
contrast” slider in the color tab of your OS X settings.
* The default OS X Terminal app is known to have some issues with the
Powerline colors. Please use another terminal emulator. iTerm2 should work
fine.
The colors look weird in iTerm2!
--------------------------------
* The arrows may have the wrong colors if you have changed the “minimum
contrast” slider in the color tab of your OS X settings.
* If you're using transparency, check “Keep background colors opaque”.
Statusline is getting wrapped to the next line in iTerm2
--------------------------------------------------------
* Turn off “Treat ambigious-width characters as double width” in `Preferences
--> Text`.
* Alternative: remove fancy dividers (they suck in this case), set
:ref:`ambiwidth <config-common-ambiwidth>` to 2.
I receive a ``NameError`` when trying to use Powerline with MacVim!
-------------------------------------------------------------------
* Please install MacVim using this command::
brew install macvim --env-std --override-system-vim
Then install Powerline locally with ``pip install --user``, or by
running these commands in the ``powerline`` directory::
./setup.py build
./setup.py install --user
I receive an ``ImportError`` when trying to use Powerline on OS X!
------------------------------------------------------------------
* This is caused by an invalid ``sys.path`` when using system vim and system
Python. Please try to select another Python distribution::
sudo port select python python27-apple
* See `issue #39 <https://github.com/powerline/powerline/issues/39>`_ for
a discussion and other possible solutions for this issue.
I receive “FSEventStreamStart: register_with_server: ERROR” with status_colors
------------------------------------------------------------------------------
This is `a known <https://github.com/joyent/node/issues/5463>`_ libuv issue that
happens if one is trying to watch too many files. It should be fixed in
libuv-0.12. Until then it is suggested to either disable ``status_colors`` (from
:py:func:`powerline.segments.common.vcs.branch`) or choose stat-based watcher
(will have effectively the same effect as disabling ``status_colors``).

88
docs/source/usage.rst Normal file
View file

@ -0,0 +1,88 @@
*****
Usage
*****
Application-specific requirements
---------------------------------
Vim plugin requirements
^^^^^^^^^^^^^^^^^^^^^^^
The vim plugin requires a vim version with Python support compiled in. Presence
of Python support in Vim can be checked by running ``vim --version | grep
+python``.
If Python support is absent then Vim needs to be compiled with it. To do this
use ``--enable-pythoninterp`` :file:`./configure` flag (Python 3 uses
``--enable-python3interp`` flag instead). Note that this also requires the
related Python headers to be installed. Please consult distributions
documentation for details on how to compile and install packages.
Vim version 7.4 or newer is recommended for performance reasons, but Powerline
supports Vim 7.0.112 and higher.
Shell prompts requirements
^^^^^^^^^^^^^^^^^^^^^^^^^^
Due to fish having incorrect code for prompt width calculations up to version
2.1 and no way to tell that certain sequence of characters has no width
(``%{…%}`` in zsh and ``\[…\]`` in bash prompts serve exactly this purpose)
users that have fish versions below 2.1 are not supported..
WM widgets requirements
^^^^^^^^^^^^^^^^^^^^^^^
Awesome is supported starting from version 3.5.1, inclusive. QTile is supported
from version 0.6, inclusive.
.. _usage-terminal-emulators:
Terminal emulator requirements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Powerline uses several special glyphs to get the arrow effect and some custom
symbols for developers. This requires either a symbol font or a patched font
installed. Used terminal emulator must also support either patched fonts or
fontconfig for Powerline to work properly.
:ref:`24-bit color support <config-common-term_truecolor>` can also be enabled
if terminal emulator supports it.
.. table:: Application/terminal emulator feature support matrix
:name: term-feature-support-matrix
===================== ======= ===================== ===================== =====================
Name OS Patched font support Fontconfig support 24-bit color support
===================== ======= ===================== ===================== =====================
Gvim Linux |i_yes| |i_no| |i_yes|
iTerm2 OS X |i_yes| |i_no| |i_no|
Konsole Linux |i_yes| |i_yes| |i_yes|
lxterminal Linux |i_yes| |i_yes| |i_no|
MacVim OS X |i_yes| |i_no| |i_yes|
rxvt-unicode Linux |i_partial| [#]_ |i_no| |i_no|
st Linux |i_yes| |i_yes| |i_yes| [#]_
Terminal.app OS X |i_yes| |i_no| |i_no|
libvte-based [#]_ Linux |i_yes| |i_yes| |i_yes| [#]_
xterm Linux |i_yes| |i_no| |i_partial| [#]_
fbterm Linux |i_yes| |i_yes| |i_no|
===================== ======= ===================== ===================== =====================
.. |i_yes| image:: _static/img/icons/tick.png
.. |i_no| image:: _static/img/icons/cross.png
.. |i_partial| image:: _static/img/icons/error.png
.. [#] Must be compiled with ``--enable-unicode3`` for the patched font to work.
.. [#] Since version 0.5.
.. [#] Including XFCE terminal and GNOME terminal.
.. [#] Since version 0.36.
.. [#] Uses nearest color from 8-bit palette.
Plugins
-------
.. toctree::
usage/shell-prompts
usage/wm-widgets
usage/other

224
docs/source/usage/other.rst Normal file
View file

@ -0,0 +1,224 @@
*************
Other plugins
*************
.. _vim-vimrc:
Vim statusline
==============
If installed using pip just add
.. code-block:: vim
python from powerline.vim import setup as powerline_setup
python powerline_setup()
python del powerline_setup
(replace ``python`` with ``python3`` if appropriate) to the :file:`vimrc`.
.. note::
Status line will not appear by default when there is only a single window
displayed. Run ``:h 'laststatus'`` in Vim for more information.
If the repository was just cloned the following line needs to be added to the
:file:`vimrc`:
.. code-block:: vim
set rtp+={repository_root}/powerline/bindings/vim
where ``{repository_root}`` is the absolute path to the Powerline installation
directory (see :ref:`repository root <repository-root>`).
If pathogen is used and Powerline functionality is not needed outside of Vim
then it is possible to simply add Powerline as a bundle and point the path above
to the Powerline bundle directory, e.g.
:file:`~/.vim/bundle/powerline/powerline/bindings/vim`.
Vundle and NeoBundle users may instead use
.. code-block:: vim
Bundle 'powerline/powerline', {'rtp': 'powerline/bindings/vim/'}
(NeoBundle users need ``NeoBundle`` in place of ``Bundle``, otherwise setup is
the same).
Vim-addon-manager setup is even easier because it is not needed to write this
big path or install anything by hand: ``powerline`` can be installed and
activated just like any other plugin using
.. code-block:: vim
call vam#ActivateAddons(['powerline'])
.. warning::
*Never* install powerline with pathogen/VAM/Vundle/NeoBundle *and* with pip.
If powerline functionality is needed in applications other then Vim then
system-wide installation (in case used OS distribution has powerline
package), pip-only or ``pip install --editable`` kind of installation
performed on the repository installed by Vim plugin manager should be used.
No issues are accepted in powerline issue tracker for double pip/non-pip
installations, especially if these issues occur after update.
.. note::
If supplied :file:`powerline.vim` file is used to load powerline there are
additional configuration variables available: ``g:powerline_pycmd`` and
``g:powerline_pyeval``. First sets command used to load powerline: expected
values are ``"py"`` and ``"py3"``. Second sets function used in statusline,
expected values are ``"pyeval"`` and ``"py3eval"``.
If ``g:powerline_pycmd`` is set to the one of the expected values then
``g:powerline_pyeval`` will be set accordingly. If it is set to some other
value then ``g:powerline_pyeval`` must also be set. Powerline will not check
that Vim is compiled with Python support if ``g:powerline_pycmd`` is set to
an unexpected value.
These values are to be used to specify the only Python that is to be loaded
if both versions are present: Vim may disable loading one python version if
other was already loaded. They should also be used if two python versions
are able to load simultaneously, but powerline was installed only for
python-3 version.
Tmux statusline
===============
Add the following lines to :file:`.tmux.conf`, where ``{repository_root}`` is
the absolute path to the Powerline installation directory (see :ref:`repository
root <repository-root>`)::
source "{repository_root}/powerline/bindings/tmux/powerline.conf"
.. note::
The availability of the ``powerline-config`` command is required for
powerline support. The location of this script may be specified via
the ``$POWERLINE_CONFIG_COMMAND`` environment variable.
.. note::
It is advised to run ``powerline-daemon`` before adding the above line to
tmux.conf. To do so add::
run-shell "powerline-daemon -q"
to :file:`.tmux.conf`.
.. warning::
Segments which depend on current working directory (e.g.
:py:func:`powerline.segments.common.vcs.branch`) require also setting up
:ref:`shell bindings <usage-shell>`. It is not required to use powerline
shell prompt, :ref:`components setting <config-ext-components>` allows to
set up only powerline bindings for tmux without altering your prompt.
Without setting up shell bindings powerline will use current working
directory of *tmux server* which is probably not what you need.
Segments which depend on environment like
:py:func:`powerline.segments.common.env.virtualenv` will not work at all
(i.e. they will use environment of the tmux server), tracking environment
changes is going to slow down shell a lot.
In any case it is suggested to avoid both kinds of segments in tmux
:ref:`themes <config-themes>` because even support for tracking current
directory is very limited:
#. It works only in shell. Should you e.g. run Vim and run ``:cd`` there you
will get current working directory from shell.
#. It works only in local shell and requires configuring it.
#. Some shells are not supported at all.
IPython prompt
==============
For IPython>=7.0, add the following line to
:file:`~/.ipython/profile_default/ipython_config.py` file in the used profile:
.. code-block:: Python
from powerline.bindings.ipython.since_7 import PowerlinePrompts
c.TerminalInteractiveShell.prompts_class = PowerlinePrompts
.. note::
If certain graphical/colored elements are not showing, make sure `c.TerminalInteractiveShell.simple_prompt`
is set to `False` in your config.
Setting ``simple_prompt`` to False after IPython-5.0 is required regardless
of whether you use ``c.InteractiveShellApp.extensions`` setting or
``c.TerminalInteractiveShell.prompts_class``. But you probably already have
this line because ``simple_prompt`` is set to ``False`` by default and IPython
is not very useful without it.
For IPython>=5.0 and <7.0 it is suggested to use
.. code-block:: Python
from powerline.bindings.ipython.since_5 import PowerlinePrompts
c = get_config()
c.TerminalInteractiveShell.simple_prompt = False
c.TerminalInteractiveShell.prompts_class = PowerlinePrompts
For IPython>=5.0 and <7.0 you may use the below set up, but it is deprecated.
For IPython>=0.11 add the following line to
:file:`~/.ipython/profile_default/ipython_config.py` file in the used profile:
.. code-block:: Python
c = get_config()
c.InteractiveShellApp.extensions = [
'powerline.bindings.ipython.post_0_11'
]
For IPython<0.11 add the following lines to :file:`.ipython/ipy_user_conf.py`:
.. code-block:: Python
# top
from powerline.bindings.ipython.pre_0_11 import setup as powerline_setup
# main() function (assuming ipython was launched without configuration to
# create skeleton ipy_user_conf.py file):
powerline_setup()
IPython=0.11* is not supported and does not work. IPython<0.10 was not
tested (not installable by pip).
.. _pdb-prompt:
PDB prompt
==========
To use Powerline with PDB prompt you need to use custom class. Inherit your
class from :py:class:`pdb.Pdb` and decorate it with
:py:func:`powerline.bindings.pdb.use_powerline_prompt`:
.. code-block:: Python
import pdb
from powerline.bindings.pdb import use_powerline_prompt
@use_powerline_prompt
class MyPdb(pdb.Pdb):
pass
MyPdb.run('some.code.to.debug()')
. Alternatively you may use
.. code-block:: bash
python -mpowerline.bindings.pdb path/to/script.py
just like you used ``python -m pdb``.
.. note:
If you are using Python-2.6 you need to use ``python
-mpowerline.bindings.pdb.__main__``, not what is shown above.
.. warning:
Using PyPy (not PyPy3) forces ASCII-only prompts. In other cases unicode
characters are allowed, even if you use `pdbpp
<https://pypi.python.org/pypi/pdbpp>`_.

View file

@ -0,0 +1,161 @@
.. _usage-shell:
*************
Shell prompts
*************
.. note::
Powerline can operate without a background daemon, but the shell performance
can be very slow. The Powerline daemon improves this performance
significantly, but must be started separately. It is advised to add
.. code-block:: bash
powerline-daemon -q
before any other powerline-related code in the shell configuration file.
Bash prompt
===========
Add the following line to the :file:`bashrc`, where ``{repository_root}`` is the
absolute path to the Powerline installation directory (see :ref:`repository root
<repository-root>`):
.. code-block:: bash
. {repository_root}/powerline/bindings/bash/powerline.sh
.. note::
Since without powerline daemon bash bindings are very slow PS2
(continuation) and PS3 (select) prompts are not set up. Thus it is advised
to use
.. code-block:: bash
powerline-daemon -q
POWERLINE_BASH_CONTINUATION=1
POWERLINE_BASH_SELECT=1
. {repository_root}/powerline/bindings/bash/powerline.sh
in the bash configuration file. Without ``POWERLINE_BASH_*`` variables PS2
and PS3 prompts are computed exactly once at bash startup.
.. warning::
At maximum bash continuation PS2 and select PS3 prompts are computed each
time main PS1 prompt is computed. Thus putting e.g. current time into PS2 or
PS3 prompt will not work as expected.
At minimum they are computed once on startup.
Zsh prompt
==========
Add the following line to the :file:`zshrc`, where ``{repository_root}`` is the
absolute path to the Powerline installation directory (see :ref:`repository root
<repository-root>`):
.. code-block:: bash
. {repository_root}/powerline/bindings/zsh/powerline.zsh
Fish prompt
===========
Add the following line to :file:`config.fish`, where ``{repository_root}`` is
the absolute path to the Powerline installation directory (see :ref:`repository
root <repository-root>`):
.. code-block:: bash
set fish_function_path $fish_function_path "{repository_root}/powerline/bindings/fish"
powerline-setup
.. warning:: Fish is supported only starting from version 2.1.
Rcsh prompt
===========
Powerline supports Plan9 rc reimplementation *by Byron Rakitzis* packaged by
many \*nix distributions. To use it add
.. code-block:: bash
. {repository_root}/powerline/bindings/rc/powerline.rc
(``{repository_root}`` is the absolute path to the Powerline installation
directory, see :ref:`repository root <repository-root>`) to :file:`rcrc` file
(usually :file:`~/.rcrc`) and make sure ``rc`` is started as a login shell (with
``-l`` argument): otherwise this configuration file is not read.
.. warning::
Original Plan9 shell and its \*nix port are not supported because they are
missing ``prompt`` special function (it is being called once before each
non-continuation prompt). Since powerline could not support shell without
this or equivalent feature some other not-so-critical features of that port
were used.
Busybox (ash), mksh and dash prompt
=====================================
After launching busybox run the following command:
.. code-block:: bash
. {repository_root}/powerline/bindings/shell/powerline.sh
where ``{repository_root}`` is the absolute path to the Powerline installation
directory (see :ref:`repository root <repository-root>`).
Mksh users may put this line into ``~/.mkshrc`` file. Dash users may use the
following in ``~/.profile``:
.. code-block:: bash
if test "$0" != "${0#dash}" ; then
export ENV={repository_root}/powerline/bindings/shell/powerline.sh
fi
.. note::
Dash users that already have ``$ENV`` defined should either put the ``.
…/shell/powerline.sh`` line in the ``$ENV`` file or create a new file which
will source (using ``.`` command) both former ``$ENV`` file and
:file:`powerline.sh` files and set ``$ENV`` to the path of this new file.
.. warning::
Mksh users have to set ``$POWERLINE_SHELL_CONTINUATION`` and
``$POWERLINE_SHELL_SELECT`` to 1 to get PS2 and PS3 (continuation and
select) prompts support respectively: as command substitution is not
performed in these shells for these prompts they are updated once each time
PS1 prompt is displayed which may be slow.
It is also known that while PS2 and PS3 update is triggered at PS1 update it
is *actually performed* only *next* time PS1 is displayed which means that
PS2 and PS3 prompts will be outdated and may be incorrect for this reason.
Without these variables PS2 and PS3 prompts will be set once at startup.
This only touches mksh users: busybox and dash both have no such problem.
.. warning::
Job count is using some weird hack that uses signals and temporary files for
interprocess communication. It may be wrong sometimes. Not the case in mksh.
.. warning::
Busybox has two shells: ``ash`` and ``hush``. Second is known to segfault in
busybox 1.22.1 when using :file:`powerline.sh` script.
Python Virtual Environments (conda, pyenv)
==========================================
If your system uses virtual environments to manage different Python versions,
such as pyenv or anaconda, these tools will add a performance delay to every
shell prompt. This delay can be bypassed by explicitly specifying your command
path.
.. code-block:: bash
export POWERLINE_COMMAND={path_to_powerline}
where ``{path_to_powerline}`` is the full filepath for powerline. If you
installed Powerline within an environment, you can find this path for pyenv
with ``pyenv which powerline`` or for conda with ``which powerline``.

View file

@ -0,0 +1,101 @@
**********************
Window manager widgets
**********************
Awesome widget
==============
.. note:: Powerline currently only supports awesome 3.5 and 4+.
.. note:: The Powerline widget will spawn a shell script that runs in the
background and updates the statusline with ``awesome-client``.
Add the following to :file:`rc.lua`, where ``{repository_root}`` is the absolute
path to Powerline installation directory (see :ref:`repository root
<repository-root>`):
.. code-block:: lua
package.path = package.path .. ';{repository_root}/powerline/bindings/awesome/?.lua'
require('powerline')
Then add the ``powerline_widget`` to ``wibox``:
.. code-block:: lua
-- awesome3.5
right_layout:add(powerline_widget)
-- awesome4+
s.mywibox:setup {
...
{ -- Right widgets
...
powerline_widget,
},
}
Qtile widget
============
Add the following to :file:`~/.config/qtile/config.py`:
.. code-block:: python
from libqtile.bar import Bar
from libqtile.config import Screen
from libqtile.widget import Spacer
from powerline.bindings.qtile.widget import PowerlineTextBox
screens = [
Screen(
top=Bar([
PowerlineTextBox(update_interval=2, side='left'),
Spacer(),
PowerlineTextBox(update_interval=2, side='right'),
],
35 # width
),
),
]
.. _lemonbar-usage:
lemonbar (formerly bar-aint-recursive)
======================================
To run the bar simply start the binding script:
python /path/to/powerline/bindings/lemonbar/powerline-lemonbar.py
You can specify options to be passed to ``lemonbar`` after ``--``, like so:
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>`_.
See the `lemonbar documentation <https://github.com/LemonBoy/bar>`_ for more
information and options.
All ``powerline-lemonbar.py`` arguments:
.. automan:: powerline.commands.lemonbar
:prog: powerline-lemonbar.py
:minimal: true
I3 bar
======
Add the following to :file:`~/.config/i3/config`::
bar {
status_command python /path/to/powerline/bindings/i3/powerline-i3.py
font pango:PowerlineFont 12
}
where ``PowerlineFont`` is any system font with powerline support.

View file

@ -0,0 +1,105 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<alias>
<family>monospace</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Droid Sans Mono</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Droid Sans Mono Slashed</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Droid Sans Mono Dotted</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>DejaVu Sans Mono</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>DejaVu Sans Mono</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Envy Code R</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Inconsolata</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Lucida Console</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Monaco</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Pragmata</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>PragmataPro</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Menlo</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Source Code Pro</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Consolas</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Anonymous pro</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Bitstream Vera Sans Mono</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Liberation Mono</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Ubuntu Mono</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Meslo LG L</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Meslo LG L DZ</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Meslo LG M</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Meslo LG M DZ</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Meslo LG S</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
<alias>
<family>Meslo LG S DZ</family>
<prefer><family>PowerlineSymbols</family></prefer>
</alias>
</fontconfig>

BIN
font/PowerlineSymbols.otf Normal file

Binary file not shown.

991
powerline/__init__.py Normal file
View file

@ -0,0 +1,991 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
import sys
import logging
from threading import Lock, Event
from powerline.colorscheme import Colorscheme
from powerline.lib.config import ConfigLoader
from powerline.lib.unicode import unicode, safe_unicode, FailedUnicode
from powerline.config import DEFAULT_SYSTEM_CONFIG_DIR
from powerline.lib.dict import mergedicts
from powerline.lib.encoding import get_preferred_output_encoding
from powerline.lib.path import join
from powerline.version import __version__
class NotInterceptedError(BaseException):
pass
def _config_loader_condition(path):
if path and os.path.isfile(path):
return path
return None
def _find_config_files(search_paths, config_file, config_loader=None, loader_callback=None):
config_file += '.json'
found = False
for path in search_paths:
config_file_path = join(path, config_file)
if os.path.isfile(config_file_path):
yield config_file_path
found = True
elif config_loader:
config_loader.register_missing(_config_loader_condition, loader_callback, config_file_path)
if not found:
raise IOError('Config file not found in search paths ({0}): {1}'.format(
', '.join(search_paths),
config_file
))
class PowerlineLogger(object):
'''Proxy class for logging.Logger instance
It emits messages in format ``{ext}:{prefix}:{message}`` where
``{ext}``
is a used powerline extension (e.g. vim, shell, ipython).
``{prefix}``
is a local prefix, usually a segment name.
``{message}``
is the original message passed to one of the logging methods.
Each of the methods (``critical``, ``exception``, ``info``, ``error``,
``warn``, ``debug``) expects to receive message in an ``str.format`` format,
not in printf-like format.
Log is saved to the location :ref:`specified by user <config-common-log>`.
'''
def __init__(self, use_daemon_threads, logger, ext):
self.logger = logger
self.ext = ext
self.use_daemon_threads = use_daemon_threads
self.prefix = ''
self.last_msgs = {}
def _log(self, attr, msg, *args, **kwargs):
prefix = kwargs.get('prefix') or self.prefix
prefix = self.ext + ((':' + prefix) if prefix else '')
msg = safe_unicode(msg)
if args or kwargs:
args = [safe_unicode(s) if isinstance(s, bytes) else s for s in args]
kwargs = dict((
(k, safe_unicode(v) if isinstance(v, bytes) else v)
for k, v in kwargs.items()
))
msg = msg.format(*args, **kwargs)
msg = prefix + ':' + msg
key = attr + ':' + prefix
if msg != self.last_msgs.get(key):
getattr(self.logger, attr)(msg)
self.last_msgs[key] = msg
def critical(self, msg, *args, **kwargs):
self._log('critical', msg, *args, **kwargs)
def exception(self, msg, *args, **kwargs):
self._log('exception', msg, *args, **kwargs)
def info(self, msg, *args, **kwargs):
self._log('info', msg, *args, **kwargs)
def error(self, msg, *args, **kwargs):
self._log('error', msg, *args, **kwargs)
def warn(self, msg, *args, **kwargs):
self._log('warning', msg, *args, **kwargs)
def debug(self, msg, *args, **kwargs):
self._log('debug', msg, *args, **kwargs)
_fallback_logger = None
def get_fallback_logger(stream=None):
global _fallback_logger
if _fallback_logger:
return _fallback_logger
log_format = '%(asctime)s:%(levelname)s:%(message)s'
formatter = logging.Formatter(log_format)
level = logging.WARNING
handler = logging.StreamHandler(stream)
handler.setLevel(level)
handler.setFormatter(formatter)
logger = logging.Logger('powerline')
logger.setLevel(level)
logger.addHandler(handler)
_fallback_logger = PowerlineLogger(None, logger, '_fallback_')
return _fallback_logger
def _generate_change_callback(lock, key, dictionary):
def on_file_change(path):
with lock:
dictionary[key] = True
return on_file_change
def get_config_paths():
'''Get configuration paths from environment variables.
Uses $XDG_CONFIG_HOME and $XDG_CONFIG_DIRS according to the XDG specification.
:return: list of paths
'''
config_home = os.environ.get('XDG_CONFIG_HOME', os.path.join(os.path.expanduser('~'), '.config'))
config_path = join(config_home, 'powerline')
config_paths = [config_path]
config_dirs = os.environ.get('XDG_CONFIG_DIRS', DEFAULT_SYSTEM_CONFIG_DIR)
if config_dirs is not None:
config_paths[:0] = reversed([join(d, 'powerline') for d in config_dirs.split(':')])
plugin_path = join(os.path.realpath(os.path.dirname(__file__)), 'config_files')
config_paths.insert(0, plugin_path)
return config_paths
def generate_config_finder(get_config_paths=get_config_paths):
'''Generate find_config_files function
This function will find .json file given its path.
:param function get_config_paths:
Function that being called with no arguments will return a list of paths
that should be searched for configuration files.
:return:
Function that being given configuration file name will return full path
to it or raise IOError if it failed to find the file.
'''
config_paths = get_config_paths()
return lambda *args: _find_config_files(config_paths, *args)
def load_config(cfg_path, find_config_files, config_loader, loader_callback=None):
'''Load configuration file and setup watches
Watches are only set up if loader_callback is not None.
:param str cfg_path:
Path for configuration file that should be loaded.
:param function find_config_files:
Function that finds configuration file. Check out the description of
the return value of ``generate_config_finder`` function.
:param ConfigLoader config_loader:
Configuration file loader class instance.
:param function loader_callback:
Function that will be called by config_loader when change to
configuration file is detected.
:return: Configuration file contents.
'''
found_files = find_config_files(cfg_path, config_loader, loader_callback)
ret = None
for path in found_files:
if loader_callback:
config_loader.register(loader_callback, path)
if ret is None:
ret = config_loader.load(path)
else:
mergedicts(ret, config_loader.load(path))
return ret
def _set_log_handlers(common_config, logger, get_module_attr, stream=None):
'''Set log handlers
:param dict common_config:
Configuration dictionary used to create handler.
:param logging.Logger logger:
Logger to which handlers will be attached.
:param func get_module_attr:
:py:func:`gen_module_attr_getter` output.
:param file stream:
Stream to use by default for :py:class:`logging.StreamHandler` in place
of :py:attr:`sys.stderr`. May be ``None``.
'''
log_targets = common_config['log_file']
num_handlers = 0
for log_target in log_targets:
if log_target is None:
log_target = ['logging.StreamHandler', []]
elif isinstance(log_target, unicode):
log_target = os.path.expanduser(log_target)
log_dir = os.path.dirname(log_target)
if log_dir and not os.path.isdir(log_dir):
os.mkdir(log_dir)
log_target = ['logging.FileHandler', [[log_target]]]
module, handler_class_name = log_target[0].rpartition('.')[::2]
module = module or 'logging.handlers'
try:
handler_class_args = log_target[1][0]
except IndexError:
if module == 'logging' and handler_class_name == 'StreamHandler':
handler_class_args = [stream]
else:
handler_class_args = ()
try:
handler_class_kwargs = log_target[1][1]
except IndexError:
handler_class_kwargs = {}
module = str(module)
handler_class_name = str(handler_class_name)
handler_class = get_module_attr(module, handler_class_name)
if not handler_class:
continue
handler = handler_class(*handler_class_args, **handler_class_kwargs)
try:
handler_level_name = log_target[2]
except IndexError:
handler_level_name = common_config['log_level']
try:
handler_format = log_target[3]
except IndexError:
handler_format = common_config['log_format']
handler.setLevel(getattr(logging, handler_level_name))
handler.setFormatter(logging.Formatter(handler_format))
logger.addHandler(handler)
num_handlers += 1
if num_handlers == 0 and log_targets:
raise ValueError('Failed to set up any handlers')
def create_logger(common_config, use_daemon_threads=True, ext='__unknown__',
import_paths=None, imported_modules=None, stream=None):
'''Create logger according to provided configuration
:param dict common_config:
Common configuration, from :py:func:`finish_common_config`.
:param bool use_daemon_threads:
Whether daemon threads should be used. Argument to
:py:class:`PowerlineLogger` constructor.
:param str ext:
Used extension. Argument to :py:class:`PowerlineLogger` constructor.
:param set imported_modules:
Set where imported modules are saved. Argument to
:py:func:`gen_module_attr_getter`. May be ``None``, in this case new
empty set is used.
:param file stream:
Stream to use by default for :py:class:`logging.StreamHandler` in place
of :py:attr:`sys.stderr`. May be ``None``.
:return: Three objects:
#. :py:class:`logging.Logger` instance.
#. :py:class:`PowerlineLogger` instance.
#. Function, output of :py:func:`gen_module_attr_getter`.
'''
logger = logging.Logger('powerline')
level = getattr(logging, common_config['log_level'])
logger.setLevel(level)
pl = PowerlineLogger(use_daemon_threads, logger, ext)
get_module_attr = gen_module_attr_getter(
pl, common_config['paths'],
set() if imported_modules is None else imported_modules)
_set_log_handlers(common_config, logger, get_module_attr, stream)
return logger, pl, get_module_attr
def get_default_theme(is_unicode=True):
'''Get default theme used by powerline
:param bool is_unicode:
If true, return theme for unicode environments, otherwise return theme
that is supposed to be ASCII-only.
:return: theme name.
'''
return 'powerline_terminus' if is_unicode else 'ascii'
def finish_common_config(encoding, common_config):
'''Add default values to common config and expand ~ in paths
:param dict common_config:
Common configuration, as it was just loaded.
:return:
Copy of common configuration with all configuration keys and expanded
paths.
'''
encoding = encoding.lower()
default_top_theme = get_default_theme(
encoding.startswith('utf') or encoding.startswith('ucs'))
common_config = common_config.copy()
common_config.setdefault('default_top_theme', default_top_theme)
common_config.setdefault('paths', [])
common_config.setdefault('watcher', 'auto')
common_config.setdefault('log_level', 'WARNING')
common_config.setdefault('log_format', '%(asctime)s:%(levelname)s:%(message)s')
common_config.setdefault('term_truecolor', False)
common_config.setdefault('term_escape_style', 'auto')
common_config.setdefault('ambiwidth', 1)
common_config.setdefault('additional_escapes', None)
common_config.setdefault('reload_config', True)
common_config.setdefault('interval', None)
common_config.setdefault('log_file', [None])
if not isinstance(common_config['log_file'], list):
common_config['log_file'] = [common_config['log_file']]
common_config['paths'] = [
os.path.expanduser(path) for path in common_config['paths']
]
return common_config
if sys.version_info < (3,):
# `raise exception[0], None, exception[1]` is a SyntaxError in python-3*
# Not using ('''…''') because this syntax does not work in python-2.6
exec((
'def reraise(exception):\n'
' if type(exception) is tuple:\n'
' raise exception[0], None, exception[1]\n'
' else:\n'
' raise exception\n'
))
else:
def reraise(exception):
if type(exception) is tuple:
raise exception[0].with_traceback(exception[1])
else:
raise exception
def gen_module_attr_getter(pl, import_paths, imported_modules):
def get_module_attr(module, attr, prefix='powerline'):
'''Import module and get its attribute.
Replaces ``from {module} import {attr}``.
:param str module:
Module name, will be passed as first argument to ``__import__``.
:param str attr:
Module attribute, will be passed to ``__import__`` as the only value
in ``fromlist`` tuple.
:return:
Attribute value or ``None``. Note: there is no way to distinguish
between successful import of attribute equal to ``None`` and
unsuccessful import.
'''
oldpath = sys.path
sys.path = import_paths + sys.path
module = str(module)
attr = str(attr)
try:
imported_modules.add(module)
return getattr(__import__(module, fromlist=(attr,)), attr)
except Exception as e:
pl.exception('Failed to import attr {0} from module {1}: {2}', attr, module, str(e), prefix=prefix)
return None
finally:
sys.path = oldpath
return get_module_attr
LOG_KEYS = set(('log_format', 'log_level', 'log_file', 'paths'))
'''List of keys related to logging
'''
def _get_log_keys(common_config):
'''Return a common configuration copy with only log-related config left
:param dict common_config:
Common configuration.
:return:
:py:class:`dict` instance which has only keys from
:py:attr:`powerline.LOG_KEYS` left.
'''
return dict((
(k, v) for k, v in common_config.items() if k in LOG_KEYS
))
DEFAULT_UPDATE_INTERVAL = 2
'''Default value for :ref:`update_interval <config-ext-update_interval>`
'''
class Powerline(object):
'''Main powerline class, entrance point for all powerline uses. Sets
powerline up and loads the configuration.
:param str ext:
extension used. Determines where configuration files will
searched and what renderer module will be used. Affected: used ``ext``
dictionary from :file:`powerline/config.json`, location of themes and
colorschemes, render module (``powerline.renders.{ext}``).
:param str renderer_module:
Overrides renderer module (defaults to ``ext``). Should be the name of
the package imported like this: ``powerline.renderers.{render_module}``.
If this parameter contains a dot ``powerline.renderers.`` is not
prepended. There is also a special case for renderers defined in
toplevel modules: ``foo.`` (note: dot at the end) tries to get renderer
from module ``foo`` (because ``foo`` (without dot) tries to get renderer
from module ``powerline.renderers.foo``). When ``.foo`` (with leading
dot) variant is used ``renderer_module`` will be
``powerline.renderers.{ext}{renderer_module}``.
:param bool run_once:
Determines whether :py:meth:`render` method will be run only once
during python session.
:param Logger logger:
If present no new logger will be created and the provided logger will be
used.
:param bool use_daemon_threads:
When creating threads make them daemon ones.
:param Event shutdown_event:
Use this Event as shutdown_event instead of creating new event.
:param ConfigLoader config_loader:
Instance of the class that manages (re)loading of the configuration.
'''
def __init__(self, *args, **kwargs):
self.init_args = (args, kwargs)
self.init(*args, **kwargs)
def init(self,
ext,
renderer_module=None,
run_once=False,
logger=None,
use_daemon_threads=True,
shutdown_event=None,
config_loader=None):
'''Do actual initialization.
__init__ function only stores the arguments and runs this function. This
function exists for powerline to be able to reload itself: it is easier
to make ``__init__`` store arguments and call overridable ``init`` than
tell developers that each time they override Powerline.__init__ in
subclasses they must store actual arguments.
'''
self.ext = ext
self.run_once = run_once
self.logger = logger
self.had_logger = bool(self.logger)
self.use_daemon_threads = use_daemon_threads
if not renderer_module:
self.renderer_module = 'powerline.renderers.' + ext
elif '.' not in renderer_module:
self.renderer_module = 'powerline.renderers.' + renderer_module
elif renderer_module.startswith('.'):
self.renderer_module = 'powerline.renderers.' + ext + renderer_module
elif renderer_module.endswith('.'):
self.renderer_module = renderer_module[:-1]
else:
self.renderer_module = renderer_module
self.find_config_files = generate_config_finder(self.get_config_paths)
self.cr_kwargs_lock = Lock()
self.cr_kwargs = {}
self.cr_callbacks = {}
for key in ('main', 'colors', 'colorscheme', 'theme'):
self.cr_kwargs['load_' + key] = True
self.cr_callbacks[key] = _generate_change_callback(
self.cr_kwargs_lock,
'load_' + key,
self.cr_kwargs
)
self.shutdown_event = shutdown_event or Event()
self.config_loader = config_loader or ConfigLoader(shutdown_event=self.shutdown_event, run_once=run_once)
self.run_loader_update = False
self.renderer_options = {}
self.prev_common_config = None
self.prev_ext_config = None
self.pl = None
self.setup_args = ()
self.setup_kwargs = {}
self.imported_modules = set()
self.update_interval = DEFAULT_UPDATE_INTERVAL
get_encoding = staticmethod(get_preferred_output_encoding)
'''Get encoding used by the current application
Usually returns encoding of the current locale.
'''
def create_logger(self):
'''Create logger
This function is used to create logger unless it was already specified
at initialization.
:return: Three objects:
#. :py:class:`logging.Logger` instance.
#. :py:class:`PowerlineLogger` instance.
#. Function, output of :py:func:`gen_module_attr_getter`.
'''
return create_logger(
common_config=self.common_config,
use_daemon_threads=self.use_daemon_threads,
ext=self.ext,
imported_modules=self.imported_modules,
stream=self.default_log_stream,
)
def create_renderer(self, load_main=False, load_colors=False, load_colorscheme=False, load_theme=False):
'''(Re)create renderer object. Can be used after Powerline object was
successfully initialized. If any of the below parameters except
``load_main`` is True renderer object will be recreated.
:param bool load_main:
Determines whether main configuration file (:file:`config.json`)
should be loaded. If appropriate configuration changes implies
``load_colorscheme`` and ``load_theme`` and recreation of renderer
object. Wont trigger recreation if only unrelated configuration
changed.
:param bool load_colors:
Determines whether colors configuration from :file:`colors.json`
should be (re)loaded.
:param bool load_colorscheme:
Determines whether colorscheme configuration should be (re)loaded.
:param bool load_theme:
Determines whether theme configuration should be reloaded.
'''
common_config_differs = False
ext_config_differs = False
if load_main:
self._purge_configs('main')
config = self.load_main_config()
self.common_config = finish_common_config(self.get_encoding(), config['common'])
if self.common_config != self.prev_common_config:
common_config_differs = True
load_theme = (load_theme
or not self.prev_common_config
or self.prev_common_config['default_top_theme'] != self.common_config['default_top_theme'])
log_keys_differ = (not self.prev_common_config or (
_get_log_keys(self.prev_common_config) != _get_log_keys(self.common_config)
))
self.prev_common_config = self.common_config
if log_keys_differ:
if self.had_logger:
self.pl = PowerlineLogger(self.use_daemon_threads, self.logger, self.ext)
self.get_module_attr = gen_module_attr_getter(
self.pl, self.common_config['paths'], self.imported_modules)
else:
self.logger, self.pl, self.get_module_attr = self.create_logger()
self.config_loader.pl = self.pl
if not self.run_once:
self.config_loader.set_watcher(self.common_config['watcher'])
mergedicts(self.renderer_options, dict(
pl=self.pl,
term_truecolor=self.common_config['term_truecolor'],
term_escape_style=self.common_config['term_escape_style'],
ambiwidth=self.common_config['ambiwidth'],
tmux_escape=self.common_config['additional_escapes'] == 'tmux',
screen_escape=self.common_config['additional_escapes'] == 'screen',
theme_kwargs={
'ext': self.ext,
'common_config': self.common_config,
'run_once': self.run_once,
'shutdown_event': self.shutdown_event,
'get_module_attr': self.get_module_attr,
},
))
if not self.run_once and self.common_config['reload_config']:
interval = self.common_config['interval']
self.config_loader.set_interval(interval)
self.run_loader_update = (interval is None)
if interval is not None and not self.config_loader.is_alive():
self.config_loader.start()
self.ext_config = config['ext'][self.ext]
top_theme = (
self.ext_config.get('top_theme')
or self.common_config['default_top_theme']
)
self.theme_levels = (
os.path.join('themes', top_theme),
os.path.join('themes', self.ext, '__main__'),
)
self.renderer_options['theme_kwargs']['top_theme'] = top_theme
if self.ext_config != self.prev_ext_config:
ext_config_differs = True
if (
not self.prev_ext_config
or self.ext_config.get('components') != self.prev_ext_config.get('components')
):
self.setup_components(self.ext_config.get('components'))
if (
not self.prev_ext_config
or self.ext_config.get('local_themes') != self.prev_ext_config.get('local_themes')
):
self.renderer_options['local_themes'] = self.get_local_themes(self.ext_config.get('local_themes'))
self.update_interval = self.ext_config.get('update_interval', 2)
load_colorscheme = (
load_colorscheme
or not self.prev_ext_config
or self.prev_ext_config['colorscheme'] != self.ext_config['colorscheme']
)
load_theme = (
load_theme
or not self.prev_ext_config
or self.prev_ext_config['theme'] != self.ext_config['theme']
)
self.prev_ext_config = self.ext_config
create_renderer = load_colors or load_colorscheme or load_theme or common_config_differs or ext_config_differs
if load_colors:
self._purge_configs('colors')
self.colors_config = self.load_colors_config()
if load_colorscheme or load_colors:
self._purge_configs('colorscheme')
if load_colorscheme:
self.colorscheme_config = self.load_colorscheme_config(self.ext_config['colorscheme'])
self.renderer_options['theme_kwargs']['colorscheme'] = (
Colorscheme(self.colorscheme_config, self.colors_config))
if load_theme:
self._purge_configs('theme')
self.renderer_options['theme_config'] = self.load_theme_config(self.ext_config.get('theme', 'default'))
if create_renderer:
Renderer = self.get_module_attr(self.renderer_module, 'renderer')
if not Renderer:
if hasattr(self, 'renderer'):
return
else:
raise ImportError('Failed to obtain renderer')
# Renderer updates configuration file via segments .startup thus it
# should be locked to prevent state when configuration was updated,
# but .render still uses old renderer.
try:
renderer = Renderer(**self.renderer_options)
except Exception as e:
self.exception('Failed to construct renderer object: {0}', str(e))
if not hasattr(self, 'renderer'):
raise
else:
self.renderer = renderer
default_log_stream = sys.stdout
'''Default stream for default log handler
Usually it is ``sys.stderr``, but there is sometimes a reason to prefer
``sys.stdout`` or a custom file-like object. It is not supposed to be used
to write to some file.
'''
def setup_components(self, components):
'''Run component-specific setup
:param set components:
Set of the enabled components or None.
Should be overridden by subclasses.
'''
pass
@staticmethod
def get_config_paths():
'''Get configuration paths.
Should be overridden in subclasses in order to provide a way to override
used paths.
:return: list of paths
'''
return get_config_paths()
def load_config(self, cfg_path, cfg_type):
'''Load configuration and setup watches
:param str cfg_path:
Path to the configuration file without any powerline configuration
directory or ``.json`` suffix.
:param str cfg_type:
Configuration type. May be one of ``main`` (for ``config.json``
file), ``colors``, ``colorscheme``, ``theme``.
:return: dictionary with loaded configuration.
'''
return load_config(
cfg_path,
self.find_config_files,
self.config_loader,
self.cr_callbacks[cfg_type]
)
def _purge_configs(self, cfg_type):
function = self.cr_callbacks[cfg_type]
self.config_loader.unregister_functions(set((function,)))
self.config_loader.unregister_missing(set(((self.find_config_files, function),)))
def load_main_config(self):
'''Get top-level configuration.
:return: dictionary with :ref:`top-level configuration <config-main>`.
'''
return self.load_config('config', 'main')
def _load_hierarhical_config(self, cfg_type, levels, ignore_levels):
'''Load and merge multiple configuration files
:param str cfg_type:
Type of the loaded configuration files (e.g. ``colorscheme``,
``theme``).
:param list levels:
Configuration names resembling levels in hierarchy, sorted by
priority. Configuration file names with higher priority should go
last.
:param set ignore_levels:
If only files listed in this variable are present then configuration
file is considered not loaded: at least one file on the level not
listed in this variable must be present.
'''
config = {}
loaded = 0
exceptions = []
for i, cfg_path in enumerate(levels):
try:
lvl_config = self.load_config(cfg_path, cfg_type)
except IOError as e:
if sys.version_info < (3,):
tb = sys.exc_info()[2]
exceptions.append((e, tb))
else:
exceptions.append(e)
else:
if i not in ignore_levels:
loaded += 1
mergedicts(config, lvl_config)
if not loaded:
for exception in exceptions:
if type(exception) is tuple:
e = exception[0]
else:
e = exception
self.exception('Failed to load %s: {0}' % cfg_type, e, exception=exception)
raise e
return config
def load_colorscheme_config(self, name):
'''Get colorscheme.
:param str name:
Name of the colorscheme to load.
:return: dictionary with :ref:`colorscheme configuration <config-colorschemes>`.
'''
levels = (
os.path.join('colorschemes', name),
os.path.join('colorschemes', self.ext, '__main__'),
os.path.join('colorschemes', self.ext, name),
)
return self._load_hierarhical_config('colorscheme', levels, (1,))
def load_theme_config(self, name):
'''Get theme configuration.
:param str name:
Name of the theme to load.
:return: dictionary with :ref:`theme configuration <config-themes>`
'''
levels = self.theme_levels + (
os.path.join('themes', self.ext, name),
)
return self._load_hierarhical_config('theme', levels, (0, 1,))
def load_colors_config(self):
'''Get colorscheme.
:return: dictionary with :ref:`colors configuration <config-colors>`.
'''
return self.load_config('colors', 'colors')
@staticmethod
def get_local_themes(local_themes):
'''Get local themes. No-op here, to be overridden in subclasses if
required.
:param dict local_themes:
Usually accepts ``{matcher_name : theme_name}``. May also receive
None in case there is no local_themes configuration.
:return:
anything accepted by ``self.renderer.get_theme`` and processable by
``self.renderer.add_local_theme``. Renderer module is determined by
``__init__`` arguments, refer to its documentation.
'''
return None
def update_renderer(self):
'''Updates/creates a renderer if needed.'''
if self.run_loader_update:
self.config_loader.update()
cr_kwargs = None
with self.cr_kwargs_lock:
if self.cr_kwargs:
cr_kwargs = self.cr_kwargs.copy()
if cr_kwargs:
try:
self.create_renderer(**cr_kwargs)
except Exception as e:
self.exception('Failed to create renderer: {0}', str(e))
if hasattr(self, 'renderer'):
with self.cr_kwargs_lock:
self.cr_kwargs.clear()
else:
raise
else:
with self.cr_kwargs_lock:
self.cr_kwargs.clear()
def render(self, *args, **kwargs):
'''Update/create renderer if needed and pass all arguments further to
``self.renderer.render()``.
'''
try:
self.update_renderer()
return self.renderer.render(*args, **kwargs)
except Exception as e:
exc = e
try:
self.exception('Failed to render: {0}', str(e))
except Exception as e:
exc = e
ret = FailedUnicode(safe_unicode(exc))
if kwargs.get('output_width', False):
ret = ret, len(ret)
return ret
def render_above_lines(self, *args, **kwargs):
'''Like .render(), but for ``self.renderer.render_above_lines()``
'''
try:
self.update_renderer()
for line in self.renderer.render_above_lines(*args, **kwargs):
yield line
except Exception as e:
exc = e
try:
self.exception('Failed to render: {0}', str(e))
except Exception as e:
exc = e
yield FailedUnicode(safe_unicode(exc))
def setup(self, *args, **kwargs):
'''Setup the environment to use powerline.
Must not be overridden by subclasses. This one only saves setup
arguments for :py:meth:`reload` method and calls :py:meth:`do_setup`.
'''
self.shutdown_event.clear()
self.setup_args = args
self.setup_kwargs.update(kwargs)
self.do_setup(*args, **kwargs)
@staticmethod
def do_setup():
'''Function that does initialization
Should be overridden by subclasses. May accept any number of regular or
keyword arguments.
'''
pass
def reload(self):
'''Reload powerline after update.
Should handle most (but not all) powerline updates.
Purges out all powerline modules and modules imported by powerline for
segment and matcher functions. Requires defining ``setup`` function that
updates reference to main powerline object.
.. warning::
Not guaranteed to work properly, use it at your own risk. It
may break your python code.
'''
import sys
modules = self.imported_modules | set((module for module in sys.modules if module.startswith('powerline')))
modules_holder = []
for module in modules:
try:
# Needs to hold module to prevent garbage collecting until they
# are all reloaded.
modules_holder.append(sys.modules.pop(module))
except KeyError:
pass
PowerlineClass = getattr(__import__(self.__module__, fromlist=(self.__class__.__name__,)), self.__class__.__name__)
self.shutdown(set_event=True)
init_args, init_kwargs = self.init_args
powerline = PowerlineClass(*init_args, **init_kwargs)
powerline.setup(*self.setup_args, **self.setup_kwargs)
def shutdown(self, set_event=True):
'''Shut down all background threads.
:param bool set_event:
Set ``shutdown_event`` and call ``renderer.shutdown`` which should
shut down all threads. Set it to False unless you are exiting an
application.
If set to False this does nothing more then resolving reference
cycle ``powerline config_loader bound methods powerline`` by
unsubscribing from config_loader events.
'''
if set_event:
self.shutdown_event.set()
try:
self.renderer.shutdown()
except AttributeError:
pass
functions = tuple(self.cr_callbacks.values())
self.config_loader.unregister_functions(set(functions))
self.config_loader.unregister_missing(set(((self.find_config_files, function) for function in functions)))
def __enter__(self):
return self
def __exit__(self, *args):
self.shutdown()
def exception(self, msg, *args, **kwargs):
if 'prefix' not in kwargs:
kwargs['prefix'] = 'powerline'
exception = kwargs.pop('exception', None)
pl = getattr(self, 'pl', None) or get_fallback_logger(self.default_log_stream)
if exception:
try:
reraise(exception)
except Exception:
return pl.exception(msg, *args, **kwargs)
return pl.exception(msg, *args, **kwargs)

View file

View file

@ -0,0 +1,20 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import sys
from powerline.bindings.wm import DEFAULT_UPDATE_INTERVAL
from powerline.bindings.wm.awesome import run
def main():
try:
interval = float(sys.argv[1])
except IndexError:
interval = DEFAULT_UPDATE_INTERVAL
run(interval=interval)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,15 @@
local wibox = require('wibox')
local awful = require('awful')
powerline_widget = wibox.widget.textbox()
powerline_widget:set_align('right')
function powerline(mode, widget) end
if string.find(awesome.version, 'v4') then
awful.spawn.with_shell('powerline-daemon -q')
awful.spawn.with_shell('powerline wm.awesome')
else
awful.util.spawn_with_shell('powerline-daemon -q')
awful.util.spawn_with_shell('powerline wm.awesome')
end

View file

@ -0,0 +1,60 @@
#!/usr/bin/env python
# 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.lemonbar import LemonbarPowerline
from powerline.lib.encoding import get_unicode_writer
from powerline.bindings.wm import DEFAULT_UPDATE_INTERVAL
if __name__ == '__main__':
parser = ArgumentParser(description='Powerline lemonbar bindings.')
parser.add_argument(
'--i3', action='store_true',
help='Subscribe for i3 events.'
)
args = parser.parse_args()
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')
def render(reschedule=False):
if reschedule:
Timer(DEFAULT_UPDATE_INTERVAL, render, kwargs={'reschedule': True}).start()
global lock
with lock:
write(powerline.render(mode=modes[0]))
write('\n')
sys.stdout.flush()
def update(evt):
modes[0] = evt.change
render()
render(reschedule=True)
if args.i3:
try:
import i3ipc
except ImportError:
import i3
i3.Subscription(lambda evt, data, sub: print(render()), 'workspace')
else:
conn = i3ipc.Connection()
conn.on('workspace::focus', lambda conn, evt: render())
conn.on('mode', lambda conn, evt: update(evt))
conn.main()
while True:
time.sleep(1e8)

View file

@ -0,0 +1,153 @@
_powerline_columns_fallback() {
if command -v stty &>/dev/null ; then
local cols="$(stty size 2>/dev/null)"
if ! test -z "$cols" ; then
echo "${cols#* }"
return 0
fi
fi
echo 0
return 0
}
_powerline_tmux_pane() {
echo "${TMUX_PANE:-`TMUX="$_POWERLINE_TMUX" tmux display -p "#D"`}" | \
tr -d ' %'
}
_powerline_tmux_setenv() {
TMUX="$_POWERLINE_TMUX" tmux setenv -g TMUX_"$1"_`_powerline_tmux_pane` "$2"
TMUX="$_POWERLINE_TMUX" tmux refresh -S
}
_powerline_tmux_set_pwd() {
if test "$_POWERLINE_SAVED_PWD" != "$PWD" ; then
_POWERLINE_SAVED_PWD="$PWD"
_powerline_tmux_setenv PWD "$PWD"
fi
}
_powerline_return() {
return $1
}
_POWERLINE_HAS_PIPESTATUS="$(
_powerline_return 0 | _powerline_return 43
test "${PIPESTATUS[*]}" = "0 43"
echo "$?"
)"
_powerline_has_pipestatus() {
return $_POWERLINE_HAS_PIPESTATUS
}
_powerline_status_wrapper() {
local last_exit_code=$? last_pipe_status=( "${PIPESTATUS[@]}" )
if ! _powerline_has_pipestatus \
|| test "${#last_pipe_status[@]}" -eq "0" \
|| test "$last_exit_code" != "${last_pipe_status[$(( ${#last_pipe_status[@]} - 1 ))]}" ; then
last_pipe_status=()
fi
"$@" $last_exit_code "${last_pipe_status[*]}"
return $last_exit_code
}
_powerline_add_status_wrapped_command() {
local action="$1" ; shift
local cmd="$1" ; shift
full_cmd="_powerline_status_wrapper $cmd"
if test "$action" = "append" ; then
PROMPT_COMMAND="$PROMPT_COMMAND"$'\n'"$full_cmd"
else
PROMPT_COMMAND="$full_cmd"$'\n'"$PROMPT_COMMAND"
fi
}
_powerline_tmux_set_columns() {
_powerline_tmux_setenv COLUMNS "${COLUMNS:-`_powerline_columns_fallback`}"
}
_powerline_init_tmux_support() {
if test -n "$TMUX" && tmux refresh -S &>/dev/null ; then
# TMUX variable may be unset to create new tmux session inside this one
_POWERLINE_TMUX="$TMUX"
trap '_powerline_tmux_set_columns' WINCH
_powerline_tmux_set_columns
test "$PROMPT_COMMAND" != "${PROMPT_COMMAND/_powerline_tmux_set_pwd}" \
|| _powerline_add_status_wrapped_command append _powerline_tmux_set_pwd
fi
}
_powerline_local_prompt() {
# Arguments:
# 1: side
# 2: renderer_module arg
# 3: last_exit_code
# 4: last_pipe_status
# 5: jobnum
# 6: local theme
"$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \
$2 \
--last-exit-code=$3 \
--last-pipe-status="$4" \
--jobnum=$5 \
--renderer-arg="client_id=$$" \
--renderer-arg="local_theme=$6"
}
_powerline_prompt() {
# Arguments:
# 1: side
# 2: last_exit_code
# 3: last_pipe_status
# 4: jobnum
"$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \
--width="${COLUMNS:-$(_powerline_columns_fallback)}" \
-r.bash \
--last-exit-code=$2 \
--last-pipe-status="$3" \
--jobnum=$4 \
--renderer-arg="client_id=$$"
}
_powerline_set_prompt() {
local last_exit_code=$1 ; shift
local last_pipe_status=$1 ; shift
local jobnum="$(jobs -p|wc -l)"
PS1="$(_powerline_prompt aboveleft $last_exit_code "$last_pipe_status" $jobnum)"
if test -n "$POWERLINE_SHELL_CONTINUATION$POWERLINE_BASH_CONTINUATION" ; then
PS2="$(_powerline_local_prompt left -r.bash $last_exit_code "$last_pipe_status" $jobnum continuation)"
fi
if test -n "$POWERLINE_SHELL_SELECT$POWERLINE_BASH_SELECT" ; then
PS3="$(_powerline_local_prompt left '' $last_exit_code "$last_pipe_status" $jobnum select)"
fi
}
_powerline_setup_prompt() {
VIRTUAL_ENV_DISABLE_PROMPT=1
if test -z "${POWERLINE_COMMAND}" ; then
POWERLINE_COMMAND="$("$POWERLINE_CONFIG_COMMAND" shell command)"
fi
test "$PROMPT_COMMAND" != "${PROMPT_COMMAND%_powerline_set_prompt*}" \
|| _powerline_add_status_wrapped_command prepend _powerline_set_prompt
PS2="$(_powerline_local_prompt left -r.bash 0 0 0 continuation)"
PS3="$(_powerline_local_prompt left '' 0 0 0 select)"
}
if test -z "${POWERLINE_CONFIG_COMMAND}" ; then
if command -v powerline-config >/dev/null ; then
POWERLINE_CONFIG_COMMAND=powerline-config
else
POWERLINE_CONFIG_COMMAND="$(dirname "$BASH_SOURCE")/../../../scripts/powerline-config"
fi
fi
if "${POWERLINE_CONFIG_COMMAND}" shell --shell=bash uses prompt ; then
_powerline_setup_prompt
fi
if "${POWERLINE_CONFIG_COMMAND}" shell --shell=bash uses tmux ; then
_powerline_init_tmux_support
fi

View file

@ -0,0 +1,286 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
import re
import sys
import subprocess
import shlex
from powerline.config import POWERLINE_ROOT, TMUX_CONFIG_DIRECTORY
from powerline.lib.config import ConfigLoader
from powerline import generate_config_finder, load_config, create_logger, finish_common_config
from powerline.shell import ShellPowerline
from powerline.lib.shell import which
from powerline.bindings.tmux import (TmuxVersionInfo, run_tmux_command, set_tmux_environment, get_tmux_version,
source_tmux_file)
from powerline.lib.encoding import get_preferred_output_encoding
from powerline.renderers.tmux import attrs_to_tmux_attrs
from powerline.commands.main import finish_args
CONFIG_FILE_NAME = re.compile(r'powerline_tmux_(?P<major>\d+)\.(?P<minor>\d+)(?P<suffix>[a-z]+)?(?:_(?P<mod>plus|minus))?\.conf')
CONFIG_MATCHERS = {
None: (lambda a, b: a.major == b.major and a.minor == b.minor),
'plus': (lambda a, b: a[:2] <= b[:2]),
'minus': (lambda a, b: a[:2] >= b[:2]),
}
CONFIG_PRIORITY = {
None: 3,
'plus': 2,
'minus': 1,
}
def list_all_tmux_configs():
'''List all version-specific tmux configuration files'''
for root, dirs, files in os.walk(TMUX_CONFIG_DIRECTORY):
dirs[:] = ()
for fname in files:
match = CONFIG_FILE_NAME.match(fname)
if match:
assert match.group('suffix') is None
yield (
os.path.join(root, fname),
CONFIG_MATCHERS[match.group('mod')],
CONFIG_PRIORITY[match.group('mod')],
TmuxVersionInfo(
int(match.group('major')),
int(match.group('minor')),
match.group('suffix'),
),
)
def get_tmux_configs(version):
'''Get tmux configuration suffix given parsed tmux version
:param TmuxVersionInfo version: Parsed tmux version.
'''
for fname, matcher, priority, file_version in list_all_tmux_configs():
if matcher(file_version, version):
yield (fname, priority + file_version.minor * 10 + file_version.major * 10000)
def source_tmux_files(pl, args, tmux_version=None, source_tmux_file=source_tmux_file):
'''Source relevant version-specific tmux configuration files
Files are sourced in the following order:
* First relevant files with older versions are sourced.
* If files for same versions are to be sourced then first _minus files are
sourced, then _plus files and then files without _minus or _plus suffixes.
'''
tmux_version = tmux_version or get_tmux_version(pl)
source_tmux_file(os.path.join(TMUX_CONFIG_DIRECTORY, 'powerline-base.conf'))
for fname, priority in sorted(get_tmux_configs(tmux_version), key=(lambda v: v[1])):
source_tmux_file(fname)
if not os.environ.get('POWERLINE_COMMAND'):
cmd = deduce_command()
if cmd:
set_tmux_environment('POWERLINE_COMMAND', deduce_command(), remove=False)
try:
run_tmux_command('refresh-client')
except subprocess.CalledProcessError:
# On tmux-2.0 this command may fail for whatever reason. Since it is
# critical just ignore the failure.
pass
class EmptyArgs(object):
def __init__(self, ext, config_path):
self.ext = [ext]
self.side = 'left'
self.config_path = None
def __getattr__(self, attr):
return None
def init_tmux_environment(pl, args, set_tmux_environment=set_tmux_environment):
'''Initialize tmux environment from tmux configuration
'''
powerline = ShellPowerline(finish_args(None, os.environ, EmptyArgs('tmux', args.config_path)))
# TODO Move configuration files loading out of Powerline object and use it
# directly
powerline.update_renderer()
# FIXME Use something more stable then `theme_kwargs`
colorscheme = powerline.renderer_options['theme_kwargs']['colorscheme']
def get_highlighting(group):
return colorscheme.get_highlighting([group], None)
for varname, highlight_group in (
('_POWERLINE_BACKGROUND_COLOR', 'background'),
('_POWERLINE_ACTIVE_WINDOW_STATUS_COLOR', 'active_window_status'),
('_POWERLINE_WINDOW_STATUS_COLOR', 'window_status'),
('_POWERLINE_ACTIVITY_STATUS_COLOR', 'activity_status'),
('_POWERLINE_BELL_STATUS_COLOR', 'bell_status'),
('_POWERLINE_WINDOW_COLOR', 'window'),
('_POWERLINE_WINDOW_DIVIDER_COLOR', 'window:divider'),
('_POWERLINE_WINDOW_CURRENT_COLOR', 'window:current'),
('_POWERLINE_WINDOW_NAME_COLOR', 'window_name'),
('_POWERLINE_SESSION_COLOR', 'session'),
):
highlight = get_highlighting(highlight_group)
set_tmux_environment(varname, powerline.renderer.hlstyle(**highlight)[2:-1])
for varname, prev_group, next_group in (
('_POWERLINE_WINDOW_CURRENT_HARD_DIVIDER_COLOR', 'window', 'window:current'),
('_POWERLINE_WINDOW_CURRENT_HARD_DIVIDER_NEXT_COLOR', 'window:current', 'window'),
('_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR', 'session', 'background'),
):
prev_highlight = get_highlighting(prev_group)
next_highlight = get_highlighting(next_group)
set_tmux_environment(
varname,
powerline.renderer.hlstyle(
fg=prev_highlight['bg'],
bg=next_highlight['bg'],
attrs=0,
)[2:-1]
)
for varname, attr, group in (
('_POWERLINE_ACTIVE_WINDOW_FG', 'fg', 'active_window_status'),
('_POWERLINE_WINDOW_STATUS_FG', 'fg', 'window_status'),
('_POWERLINE_ACTIVITY_STATUS_FG', 'fg', 'activity_status'),
('_POWERLINE_ACTIVITY_STATUS_ATTR', 'attrs', 'activity_status'),
('_POWERLINE_BELL_STATUS_FG', 'fg', 'bell_status'),
('_POWERLINE_BELL_STATUS_ATTR', 'attrs', 'bell_status'),
('_POWERLINE_BACKGROUND_FG', 'fg', 'background'),
('_POWERLINE_BACKGROUND_BG', 'bg', 'background'),
('_POWERLINE_SESSION_FG', 'fg', 'session'),
('_POWERLINE_SESSION_BG', 'bg', 'session'),
('_POWERLINE_SESSION_ATTR', 'attrs', 'session'),
('_POWERLINE_SESSION_PREFIX_FG', 'fg', 'session:prefix'),
('_POWERLINE_SESSION_PREFIX_BG', 'bg', 'session:prefix'),
('_POWERLINE_SESSION_PREFIX_ATTR', 'attrs', 'session:prefix'),
):
if attr == 'attrs':
attrs = attrs_to_tmux_attrs(get_highlighting(group)[attr])
set_tmux_environment(varname, ']#['.join(attrs))
set_tmux_environment(varname + '_LEGACY', (','.join(
# Tmux-1.6 does not accept no… attributes in
# window-status-…-attr options.
(attr for attr in attrs if not attr.startswith('no')))
# But it does not support empty attributes as well.
or 'none'))
else:
if powerline.common_config['term_truecolor']:
set_tmux_environment(varname, '#{0:06x}'.format(get_highlighting(group)[attr][1]))
else:
set_tmux_environment(varname, 'colour' + str(get_highlighting(group)[attr][0]))
left_dividers = powerline.renderer.theme.dividers['left']
set_tmux_environment('_POWERLINE_LEFT_HARD_DIVIDER', left_dividers['hard'])
set_tmux_environment('_POWERLINE_LEFT_SOFT_DIVIDER', left_dividers['soft'])
set_tmux_environment('_POWERLINE_LEFT_HARD_DIVIDER_SPACES', (
' ' * powerline.renderer.strwidth(left_dividers['hard'])))
TMUX_VAR_RE = re.compile(r'\$(_POWERLINE_\w+)')
def tmux_setup(pl, args):
tmux_environ = {}
tmux_version = get_tmux_version(pl)
def set_tmux_environment_nosource(varname, value, remove=True):
tmux_environ[varname] = value
def replace_cb(match):
return tmux_environ[match.group(1)]
def replace_env(s):
return TMUX_VAR_RE.subn(replace_cb, s)[0]
def source_tmux_file_nosource(fname):
with open(fname) as fd:
for line in fd:
if line.startswith('#') or line == '\n':
continue
args = shlex.split(line)
args = [args[0]] + [replace_env(arg) for arg in args[1:]]
run_tmux_command(*args)
if args.source is None:
args.source = tmux_version < (1, 9)
if args.source:
ste = set_tmux_environment
stf = source_tmux_file
else:
ste = set_tmux_environment_nosource
stf = source_tmux_file_nosource
init_tmux_environment(pl, args, set_tmux_environment=ste)
source_tmux_files(pl, args, tmux_version=tmux_version, source_tmux_file=stf)
def get_main_config(args):
find_config_files = generate_config_finder()
config_loader = ConfigLoader(run_once=True)
return load_config('config', find_config_files, config_loader)
def create_powerline_logger(args):
config = get_main_config(args)
common_config = finish_common_config(get_preferred_output_encoding(), config['common'])
logger, pl, get_module_attr = create_logger(common_config)
return pl
def check_command(cmd):
if which(cmd):
return cmd
def deduce_command():
'''Deduce which command to use for ``powerline``
Candidates:
* ``powerline``. Present only when installed system-wide.
* ``{powerline_root}/scripts/powerline``. Present after ``pip install -e``
was run and C client was compiled (in this case ``pip`` does not install
binary file).
* ``{powerline_root}/client/powerline.sh``. Useful when ``sh``, ``sed`` and
``socat`` are present, but ``pip`` or ``setup.py`` was not run.
* ``{powerline_root}/client/powerline.py``. Like above, but when one of
``sh``, ``sed`` and ``socat`` was not present.
* ``powerline-render``. Should not really ever be used.
* ``{powerline_root}/scripts/powerline-render``. Same.
'''
return (
None
or check_command('powerline')
or check_command(os.path.join(POWERLINE_ROOT, 'scripts', 'powerline'))
or ((which('sh') and which('sed') and which('socat'))
and check_command(os.path.join(POWERLINE_ROOT, 'client', 'powerline.sh')))
or check_command(os.path.join(POWERLINE_ROOT, 'client', 'powerline.py'))
or check_command('powerline-render')
or check_command(os.path.join(POWERLINE_ROOT, 'scripts', 'powerline-render'))
)
def shell_command(pl, args):
cmd = deduce_command()
if cmd:
print(cmd)
else:
sys.exit(1)
def uses(pl, args):
component = args.component
if not component:
raise ValueError('Must specify component')
shell = args.shell
template = 'POWERLINE_NO_{shell}_{component}'
for sh in (shell, 'shell') if shell else ('shell'):
varname = template.format(shell=sh.upper(), component=component.upper())
if os.environ.get(varname):
sys.exit(1)
config = get_main_config(args)
if component in config.get('ext', {}).get('shell', {}).get('components', ('tmux', 'prompt')):
sys.exit(0)
else:
sys.exit(1)

View file

@ -0,0 +1,100 @@
function powerline-setup
function _powerline_columns
if which stty >/dev/null
if stty size >/dev/null
stty size | cut -d' ' -f2
return 0
end
end
echo 0
return 0
end
if test -z "$POWERLINE_CONFIG_COMMAND"
if which powerline-config >/dev/null
set -g POWERLINE_CONFIG_COMMAND powerline-config
else
set -g POWERLINE_CONFIG_COMMAND (dirname (status -f))/../../../scripts/powerline-config
end
end
if env $POWERLINE_CONFIG_COMMAND shell --shell=fish uses prompt
if test -z "$POWERLINE_COMMAND"
set -g POWERLINE_COMMAND (env $POWERLINE_CONFIG_COMMAND shell command)
end
function _powerline_set_default_mode --on-variable fish_key_bindings
if test $fish_key_bindings != fish_vi_key_bindings
set -g _POWERLINE_DEFAULT_MODE default
else
set -g -e _POWERLINE_DEFAULT_MODE
end
end
function _powerline_update --on-variable POWERLINE_COMMAND
set -l addargs "--last-exit-code=\$status"
set -l addargs "$addargs --last-pipe-status=\$status"
set -l addargs "$addargs --jobnum=(jobs -p | wc -l)"
# One random value has an 1/32767 = 0.0031% probability of having
# the same value in two shells
set -l addargs "$addargs --renderer-arg=client_id="(random)
set -l addargs "$addargs --width=\$_POWERLINE_COLUMNS"
set -l addargs "$addargs --renderer-arg=mode=\$fish_bind_mode"
set -l addargs "$addargs --renderer-arg=default_mode=\$_POWERLINE_DEFAULT_MODE"
set -l promptside
set -l rpromptpast
set -l columnsexpr
if test -z "$POWERLINE_NO_FISH_ABOVE$POWERLINE_NO_SHELL_ABOVE"
set promptside aboveleft
set rpromptpast 'echo -n " "'
set columnsexpr '(math (_powerline_columns) - 1)'
else
set promptside left
set rpromptpast
set columnsexpr '(_powerline_columns)'
end
echo "
function fish_prompt
env \$POWERLINE_COMMAND $POWERLINE_COMMAND_ARGS shell $promptside $addargs
end
function fish_right_prompt
env \$POWERLINE_COMMAND $POWERLINE_COMMAND_ARGS shell right $addargs
$rpromptpast
end
function fish_mode_prompt
end
function _powerline_set_columns --on-signal WINCH
set -g _POWERLINE_COLUMNS $columnsexpr
end
" | source
_powerline_set_columns
end
_powerline_set_default_mode
_powerline_update
end
if env $POWERLINE_CONFIG_COMMAND shell --shell=fish uses tmux
if test -n "$TMUX"
if tmux refresh -S ^/dev/null
set -g _POWERLINE_TMUX "$TMUX"
function _powerline_tmux_pane
if test -z "$TMUX_PANE"
env TMUX="$_POWERLINE_TMUX" tmux display -p "#D" | tr -d ' %'
else
echo "$TMUX_PANE" | tr -d ' %'
end
end
function _powerline_tmux_setenv
env TMUX="$_POWERLINE_TMUX" tmux setenv -g TMUX_$argv[1]_(_powerline_tmux_pane) "$argv[2]"
env TMUX="$_POWERLINE_TMUX" tmux refresh -S
end
function _powerline_tmux_set_pwd --on-variable PWD
_powerline_tmux_setenv PWD "$PWD"
end
function _powerline_tmux_set_columns --on-signal WINCH
_powerline_tmux_setenv COLUMNS (_powerline_columns)
end
_powerline_tmux_set_columns
_powerline_tmux_set_pwd
end
end
end
end
# vim: ft=fish

View file

@ -0,0 +1,52 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import sys
import time
from threading import Lock
from powerline.bindings.wm import get_i3_connection, i3_subscribe
from powerline import Powerline
from powerline.lib.monotonic import monotonic
class I3Powerline(Powerline):
'''Powerline child for i3bar
Currently only changes the default log target.
'''
default_log_stream = sys.stderr
if __name__ == '__main__':
name = 'wm'
if len(sys.argv) > 1:
name = sys.argv[1]
powerline = I3Powerline(name, renderer_module='i3bar')
powerline.update_renderer()
interval = 0.5
print ('{"version": 1}')
print ('[')
print ('[]')
lock = Lock()
def render(event=None, data=None, sub=None):
global lock
with lock:
print (',[' + powerline.render()[:-1] + ']')
sys.stdout.flush()
i3 = get_i3_connection()
i3_subscribe(i3, 'workspace', render)
while True:
start_time = monotonic()
render()
time.sleep(max(interval - (monotonic() - start_time), 0.1))

View file

View file

@ -0,0 +1,126 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division,
absolute_import, print_function)
from weakref import ref
from warnings import warn
try:
from IPython.core.prompts import PromptManager
has_prompt_manager = True
except ImportError:
has_prompt_manager = False
from IPython.core.magic import Magics, magics_class, line_magic
from powerline.ipython import IPythonPowerline, IPythonInfo
if has_prompt_manager:
from powerline.ipython import RewriteResult
@magics_class
class PowerlineMagics(Magics):
def __init__(self, ip, powerline):
super(PowerlineMagics, self).__init__(ip)
self._powerline = powerline
@line_magic
def powerline(self, line):
if line == 'reload':
self._powerline.reload()
else:
raise ValueError('Expected `reload`, but got {0}'.format(line))
old_prompt_manager = None
class ShutdownHook(object):
def __init__(self, ip):
self.powerline = lambda: None
ip.hooks.shutdown_hook.add(self)
def __call__(self):
from IPython.core.hooks import TryNext
powerline = self.powerline()
if powerline is not None:
powerline.shutdown()
raise TryNext()
if has_prompt_manager:
class PowerlinePromptManager(PromptManager):
def __init__(self, powerline, shell):
self.powerline = powerline
self.powerline_segment_info = IPythonInfo(shell)
self.shell = shell
def render(self, name, color=True, *args, **kwargs):
res = self.powerline.render(
is_prompt=name.startswith('in'),
side='left',
output_width=True,
output_raw=not color,
matcher_info=name,
segment_info=self.powerline_segment_info,
)
self.txtwidth = res[-1]
self.width = res[-1]
ret = res[0] if color else res[1]
if name == 'rewrite':
return RewriteResult(ret)
else:
return ret
class ConfigurableIPythonPowerline(IPythonPowerline):
def init(self, ip):
config = ip.config.Powerline
self.config_overrides = config.get('config_overrides')
self.theme_overrides = config.get('theme_overrides', {})
self.config_paths = config.get('config_paths')
if has_prompt_manager:
renderer_module = '.pre_5'
else:
renderer_module = '.since_7'
super(ConfigurableIPythonPowerline, self).init(
renderer_module=renderer_module)
def do_setup(self, ip, shutdown_hook):
global old_prompt_manager
if old_prompt_manager is None:
old_prompt_manager = ip.prompt_manager
prompt_manager = PowerlinePromptManager(
powerline=self,
shell=ip.prompt_manager.shell,
)
ip.prompt_manager = prompt_manager
magics = PowerlineMagics(ip, self)
shutdown_hook.powerline = ref(self)
ip.register_magics(magics)
def load_ipython_extension(ip):
if has_prompt_manager:
shutdown_hook = ShutdownHook(ip)
powerline = ConfigurableIPythonPowerline(ip)
powerline.setup(ip, shutdown_hook)
else:
from powerline.bindings.ipython.since_7 import PowerlinePrompts
ip.prompts_class = PowerlinePrompts
ip.prompts = PowerlinePrompts(ip)
warn(DeprecationWarning(
'post_0_11 extension is deprecated since IPython 5, use\n'
' from powerline.bindings.ipython.since_7 import PowerlinePrompts\n'
' c.TerminalInteractiveShell.prompts_class = PowerlinePrompts\n'
'or check: \n'
'https://powerline.readthedocs.io/en/master/usage/other.html\n'
))
def unload_ipython_extension(ip):
global old_prompt_manager
if old_prompt_manager is not None:
ip.prompt_manager = old_prompt_manager
old_prompt_manager = None

View file

@ -0,0 +1,146 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import re
from weakref import ref
from IPython.Prompts import BasePrompt
from IPython.ipapi import get as get_ipython
from IPython.ipapi import TryNext
from powerline.ipython import IPythonPowerline, RewriteResult
from powerline.lib.unicode import string
class IPythonInfo(object):
def __init__(self, cache):
self._cache = cache
@property
def prompt_count(self):
return self._cache.prompt_count
class PowerlinePrompt(BasePrompt):
def __init__(self, powerline, powerline_last_in, old_prompt):
self.powerline = powerline
self.powerline_last_in = powerline_last_in
self.powerline_segment_info = IPythonInfo(old_prompt.cache)
self.cache = old_prompt.cache
if hasattr(old_prompt, 'sep'):
self.sep = old_prompt.sep
self.pad_left = False
def __str__(self):
self.set_p_str()
return string(self.p_str)
def set_p_str(self):
self.p_str, self.p_str_nocolor, self.powerline_prompt_width = (
self.powerline.render(
is_prompt=self.powerline_is_prompt,
side='left',
output_raw=True,
output_width=True,
segment_info=self.powerline_segment_info,
matcher_info=self.powerline_prompt_type,
)
)
@staticmethod
def set_colors():
pass
class PowerlinePrompt1(PowerlinePrompt):
powerline_prompt_type = 'in'
powerline_is_prompt = True
rspace = re.compile(r'(\s*)$')
def __str__(self):
self.cache.prompt_count += 1
self.set_p_str()
self.cache.last_prompt = self.p_str_nocolor.split('\n')[-1]
return string(self.p_str)
def set_p_str(self):
super(PowerlinePrompt1, self).set_p_str()
self.nrspaces = len(self.rspace.search(self.p_str_nocolor).group())
self.powerline_last_in['nrspaces'] = self.nrspaces
def auto_rewrite(self):
return RewriteResult(self.powerline.render(
is_prompt=False,
side='left',
matcher_info='rewrite',
segment_info=self.powerline_segment_info) + (' ' * self.nrspaces)
)
class PowerlinePromptOut(PowerlinePrompt):
powerline_prompt_type = 'out'
powerline_is_prompt = False
def set_p_str(self):
super(PowerlinePromptOut, self).set_p_str()
spaces = ' ' * self.powerline_last_in['nrspaces']
self.p_str += spaces
self.p_str_nocolor += spaces
class PowerlinePrompt2(PowerlinePromptOut):
powerline_prompt_type = 'in2'
powerline_is_prompt = True
class ConfigurableIPythonPowerline(IPythonPowerline):
def init(self, config_overrides=None, theme_overrides={}, config_paths=None):
self.config_overrides = config_overrides
self.theme_overrides = theme_overrides
self.config_paths = config_paths
super(ConfigurableIPythonPowerline, self).init(renderer_module='.pre_5')
def ipython_magic(self, ip, parameter_s=''):
if parameter_s == 'reload':
self.reload()
else:
raise ValueError('Expected `reload`, but got {0}'.format(parameter_s))
def do_setup(self, ip, shutdown_hook):
last_in = {'nrspaces': 0}
for attr, prompt_class in (
('prompt1', PowerlinePrompt1),
('prompt2', PowerlinePrompt2),
('prompt_out', PowerlinePromptOut)
):
old_prompt = getattr(ip.IP.outputcache, attr)
prompt = prompt_class(self, last_in, old_prompt)
setattr(ip.IP.outputcache, attr, prompt)
ip.expose_magic('powerline', self.ipython_magic)
shutdown_hook.powerline = ref(self)
class ShutdownHook(object):
powerline = lambda: None
def __call__(self):
from IPython.ipapi import TryNext
powerline = self.powerline()
if powerline is not None:
powerline.shutdown()
raise TryNext()
def setup(**kwargs):
ip = get_ipython()
powerline = ConfigurableIPythonPowerline(**kwargs)
shutdown_hook = ShutdownHook()
def late_startup_hook():
powerline.setup(ip, shutdown_hook)
raise TryNext()
ip.IP.hooks.late_startup_hook.add(late_startup_hook)
ip.IP.hooks.shutdown_hook.add(shutdown_hook)

View file

@ -0,0 +1,81 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from weakref import ref
from IPython.terminal.prompts import Prompts
from pygments.token import Token # NOQA
from powerline.ipython import IPythonPowerline
from powerline.renderers.ipython.since_5 import PowerlinePromptStyle
from powerline.bindings.ipython.post_0_11 import PowerlineMagics, ShutdownHook
class ConfigurableIPythonPowerline(IPythonPowerline):
def init(self, ip):
config = ip.config.Powerline
self.config_overrides = config.get('config_overrides')
self.theme_overrides = config.get('theme_overrides', {})
self.config_paths = config.get('config_paths')
super(ConfigurableIPythonPowerline, self).init(
renderer_module='.since_5')
def do_setup(self, ip, prompts, shutdown_hook):
prompts.powerline = self
msfn_missing = ()
saved_msfn = getattr(ip, '_make_style_from_name', msfn_missing)
if hasattr(saved_msfn, 'powerline_original'):
saved_msfn = saved_msfn.powerline_original
def _make_style_from_name(ip, name):
prev_style = saved_msfn(name)
new_style = PowerlinePromptStyle(lambda: prev_style)
return new_style
_make_style_from_name.powerline_original = saved_msfn
if not isinstance(ip._style, PowerlinePromptStyle):
prev_style = ip._style
ip._style = PowerlinePromptStyle(lambda: prev_style)
if not isinstance(saved_msfn, type(self.init)):
_saved_msfn = saved_msfn
saved_msfn = lambda: _saved_msfn(ip)
if saved_msfn is not msfn_missing:
ip._make_style_from_name = _make_style_from_name
magics = PowerlineMagics(ip, self)
ip.register_magics(magics)
if shutdown_hook:
shutdown_hook.powerline = ref(self)
class PowerlinePrompts(Prompts):
'''Class that returns powerline prompts
'''
def __init__(self, shell):
shutdown_hook = ShutdownHook(shell)
powerline = ConfigurableIPythonPowerline(shell)
self.shell = shell
powerline.do_setup(shell, self, shutdown_hook)
self.last_output_count = None
self.last_output = {}
for prompt in ('in', 'continuation', 'rewrite', 'out'):
exec((
'def {0}_prompt_tokens(self, *args, **kwargs):\n'
' if self.last_output_count != self.shell.execution_count:\n'
' self.last_output.clear()\n'
' self.last_output_count = self.shell.execution_count\n'
' if "{0}" not in self.last_output:\n'
' self.last_output["{0}"] = self.powerline.render('
' side="left",'
' matcher_info="{1}",'
' segment_info=self.shell,'
' ) + [(Token.Generic.Prompt, " ")]\n'
' return self.last_output["{0}"]'
).format(prompt, 'in2' if prompt == 'continuation' else prompt))

View file

@ -0,0 +1,78 @@
# vim:fileencoding=utf-8:noet
from weakref import ref
from atexit import register as atexit
from IPython.terminal.prompts import Prompts
from pygments.token import Token # NOQA
from powerline.ipython import IPythonPowerline
from powerline.renderers.ipython.since_7 import PowerlinePromptStyle
from powerline.bindings.ipython.post_0_11 import PowerlineMagics
class ConfigurableIPythonPowerline(IPythonPowerline):
def init(self, ip):
config = ip.config.Powerline
self.config_overrides = config.get('config_overrides')
self.theme_overrides = config.get('theme_overrides', {})
self.config_paths = config.get('config_paths')
super(ConfigurableIPythonPowerline, self).init(
renderer_module='.since_7')
def do_setup(self, ip, prompts):
prompts.powerline = self
msfn_missing = ()
saved_msfn = getattr(ip, '_make_style_from_name', msfn_missing)
if hasattr(saved_msfn, 'powerline_original'):
saved_msfn = saved_msfn.powerline_original
def _make_style_from_name(ip, name):
prev_style = saved_msfn(name)
new_style = PowerlinePromptStyle(lambda: prev_style)
return new_style
_make_style_from_name.powerline_original = saved_msfn
if not isinstance(ip._style, PowerlinePromptStyle):
prev_style = ip._style
ip._style = PowerlinePromptStyle(lambda: prev_style)
if not isinstance(saved_msfn, type(self.init)):
_saved_msfn = saved_msfn
saved_msfn = lambda: _saved_msfn(ip)
if saved_msfn is not msfn_missing:
ip._make_style_from_name = _make_style_from_name
magics = PowerlineMagics(ip, self)
ip.register_magics(magics)
atexit(self.shutdown)
class PowerlinePrompts(Prompts):
'''Class that returns powerline prompts
'''
def __init__(self, shell):
powerline = ConfigurableIPythonPowerline(shell)
self.shell = shell
powerline.do_setup(shell, self)
self.last_output_count = None
self.last_output = {}
for prompt in ('in', 'continuation', 'rewrite', 'out'):
exec((
'def {0}_prompt_tokens(self, *args, **kwargs):\n'
' if self.last_output_count != self.shell.execution_count:\n'
' self.last_output.clear()\n'
' self.last_output_count = self.shell.execution_count\n'
' if "{0}" not in self.last_output:\n'
' self.last_output["{0}"] = self.powerline.render('
' side="left",'
' matcher_info="{1}",'
' segment_info=self.shell,'
' ) + [(Token.Generic.Prompt, " ")]\n'
' return self.last_output["{0}"]'
).format(prompt, 'in2' if prompt == 'continuation' else prompt))

View file

@ -0,0 +1,61 @@
#!/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 powerline.lemonbar import LemonbarPowerline
from powerline.commands.lemonbar import get_argparser
from powerline.bindings.wm import get_connected_xrandr_outputs
if __name__ == '__main__':
parser = get_argparser()
args = parser.parse_args()
powerline = LemonbarPowerline()
powerline.update_renderer()
bars = []
for screen in get_connected_xrandr_outputs(powerline.pl):
command = [args.bar_command, '-g', '{0}x{1}+{2}+{3}'.format(screen['width'], args.height, screen['x'], screen['y'])] + 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)

View file

@ -0,0 +1,183 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import sys
import pdb
from powerline.pdb import PDBPowerline
from powerline.lib.encoding import get_preferred_output_encoding
from powerline.lib.unicode import unicode
if sys.version_info < (3,):
# XXX The below classes make code compatible with PDBpp which uses pyrepl
# which does not expect unicode or something above ASCII. They are
# completely not needed if pdbpp is not used, but thats not always the
# case.
class PowerlineRenderBytesResult(bytes):
def __new__(cls, s, encoding=None):
encoding = encoding or s.encoding
if isinstance(s, PowerlineRenderResult):
return s.encode(encoding)
self = bytes.__new__(cls, s.encode(encoding) if isinstance(s, unicode) else s)
self.encoding = encoding
return self
for meth in (
'__contains__',
'partition', 'rpartition',
'split', 'rsplit',
'count', 'join',
):
exec((
'def {0}(self, *args):\n'
' if any((isinstance(arg, unicode) for arg in args)):\n'
' return self.__unicode__().{0}(*args)\n'
' else:\n'
' return bytes.{0}(self, *args)'
).format(meth))
for meth in (
'find', 'rfind',
'index', 'rindex',
):
exec((
'def {0}(self, *args):\n'
' if any((isinstance(arg, unicode) for arg in args)):\n'
' args = [arg.encode(self.encoding) if isinstance(arg, unicode) else arg for arg in args]\n'
' return bytes.{0}(self, *args)'
).format(meth))
def __len__(self):
return len(self.decode(self.encoding))
def __getitem__(self, *args):
return PowerlineRenderBytesResult(bytes.__getitem__(self, *args), encoding=self.encoding)
def __getslice__(self, *args):
return PowerlineRenderBytesResult(bytes.__getslice__(self, *args), encoding=self.encoding)
@staticmethod
def add(encoding, *args):
if any((isinstance(arg, unicode) for arg in args)):
return PowerlineRenderResult(''.join((
arg
if isinstance(arg, unicode)
else arg.decode(encoding)
for arg in args
)), encoding)
else:
return PowerlineRenderBytesResult(b''.join(args), encoding=encoding)
def __add__(self, other):
return self.add(self.encoding, self, other)
def __radd__(self, other):
return self.add(self.encoding, other, self)
def __unicode__(self):
return PowerlineRenderResult(self)
class PowerlineRenderResult(unicode):
def __new__(cls, s, encoding=None):
encoding = (
encoding
or getattr(s, 'encoding', None)
or get_preferred_output_encoding()
)
if isinstance(s, unicode):
self = unicode.__new__(cls, s)
else:
self = unicode.__new__(cls, s, encoding, 'replace')
self.encoding = encoding
return self
def __str__(self):
return PowerlineRenderBytesResult(self)
def __getitem__(self, *args):
return PowerlineRenderResult(unicode.__getitem__(self, *args))
def __getslice__(self, *args):
return PowerlineRenderResult(unicode.__getslice__(self, *args))
@staticmethod
def add(encoding, *args):
return PowerlineRenderResult(''.join((
arg
if isinstance(arg, unicode)
else arg.decode(encoding)
for arg in args
)), encoding)
def __add__(self, other):
return self.add(self.encoding, self, other)
def __radd__(self, other):
return self.add(self.encoding, other, self)
def encode(self, *args, **kwargs):
return PowerlineRenderBytesResult(unicode.encode(self, *args, **kwargs), args[0])
else:
PowerlineRenderResult = str
def use_powerline_prompt(cls):
'''Decorator that installs powerline prompt to the class
:param pdb.Pdb cls:
Class that should be decorated.
:return:
``cls`` argument or a class derived from it. Latter is used to turn
old-style classes into new-style classes.
'''
@property
def prompt(self):
try:
powerline = self.powerline
except AttributeError:
powerline = PDBPowerline()
powerline.setup(self)
self.powerline = powerline
return PowerlineRenderResult(powerline.render(side='left'))
@prompt.setter
def prompt(self, _):
pass
@prompt.deleter
def prompt(self):
pass
if not hasattr(cls, '__class__'):
# Old-style class: make it new-style or @property will not work.
old_cls = cls
class cls(cls, object):
__module__ = cls.__module__
__doc__ = cls.__doc__
cls.__name__ = old_cls.__name__
cls.prompt = prompt
return cls
def main():
'''Run module as a script
Uses :py:func:`pdb.main` function directly, but prior to that it mocks
:py:class:`pdb.Pdb` class with powerline-specific class instance.
'''
orig_pdb = pdb.Pdb
@use_powerline_prompt
class Pdb(pdb.Pdb, object):
def __init__(self):
orig_pdb.__init__(self)
pdb.Pdb = Pdb
return pdb.main()

View file

@ -0,0 +1,9 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline.bindings.pdb import main
if __name__ == '__main__':
main()

View file

View file

@ -0,0 +1,61 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from libqtile.bar import CALCULATED
from libqtile.widget import TextBox
from powerline import Powerline
class QTilePowerline(Powerline):
def do_setup(self, obj):
obj.powerline = self
class PowerlineTextBox(TextBox):
# TODO Replace timeout argument with update_interval argument in next major
# release.
def __init__(self, timeout=2, text=b' ', width=CALCULATED, side='right', update_interval=None, **config):
super(PowerlineTextBox, self).__init__(text, width, **config)
self.side = side
self.update_interval = update_interval or timeout
self.did_run_timer_setup = False
powerline = QTilePowerline(ext='wm', renderer_module='pango_markup')
powerline.setup(self)
def update(self):
if not self.configured:
return True
self.text = self.powerline.render(side=self.side).encode('utf-8')
self.bar.draw()
return True
def cmd_update(self, text):
self.update(text)
def cmd_get(self):
return self.text
def timer_setup(self):
if not self.did_run_timer_setup:
self.did_run_timer_setup = True
self.timeout_add(self.update_interval, self.update)
def _configure(self, qtile, bar):
super(PowerlineTextBox, self)._configure(qtile, bar)
if self.layout.markup:
# QTile-0.9.1: no need to recreate layout or run timer_setup
return
self.layout = self.drawer.textlayout(
self.text,
self.foreground,
self.font,
self.fontsize,
self.fontshadow,
markup=True,
)
self.timer_setup()
# TODO: Remove this at next major release
Powerline = PowerlineTextBox

View file

@ -0,0 +1,92 @@
fn _powerline_sigwinch {
_POWERLINE_COLUMNS = `{
stty size | cut -d' ' -f2
}
_powerline_tmux_setenv COLUMNS $_POWERLINE_COLUMNS
}
fn _powerline_update_pwd {
_POWERLINE_NEW_PWD = `{pwd}
if (test $^_POWERLINE_NEW_PWD '=' $^_POWERLINE_SAVED_PWD) {
_POWERLINE_SAVED_PWD = $_POWERLINE_NEW_PWD
_powerline_tmux_setenv PWD $_POWERLINE_SAVED_PWD
}
}
fn _powerline_continuation_prompt {
_powerline_prompt --renderer-arg 'local_theme=continuation' $*
}
fn _powerline_prompt {
$POWERLINE_COMMAND $POWERLINE_COMMAND_ARGS shell aboveleft -r.readline --last-pipe-status $^_POWERLINE_STATUS --last-exit-code $_POWERLINE_STATUS($#_POWERLINE_STATUS) --jobnum $_POWERLINE_JOBNUM --renderer-arg 'client_id='$pid $*
}
fn _powerline_set_prompt {
_POWERLINE_STATUS = ( $status )
_POWERLINE_JOBNUM = $#apids
prompt = (``() {
_powerline_prompt
} ``() {
_powerline_continuation_prompt
})
_powerline_update_pwd
}
fn _powerline_common_setup {
fn sigwinch {
_powerline_sigwinch
}
_powerline_sigwinch
_POWERLINE_SAVED_PWD = ''
}
fn _powerline_tmux_pane {
if (test -n $TMUX_PANE) {
echo $TMUX_PANE | tr -d ' %'
} else {
TMUX=$_POWERLINE_TMUX tmux display -p '#D' | tr -d ' %'
}
}
fn _powerline_tmux_setenv {
}
if (test -z $POWERLINE_CONFIG_COMMAND) {
if (which powerline-config >/dev/null) {
POWERLINE_CONFIG_COMMAND = powerline-config
} else {
echo powerline-config executable not found, unable to proceed >[2=1]
}
}
if (test -n $POWERLINE_CONFIG_COMMAND) {
if ($POWERLINE_CONFIG_COMMAND shell --shell rcsh uses prompt) {
if (test -n $POWERLINE_COMMAND_ARGS) {
# Perform splitting
POWERLINE_COMMAND_ARGS=( `{echo $POWERLINE_COMMAND_ARGS} )
}
fn prompt {
_powerline_set_prompt
}
if (test -z $POWERLINE_SHELL_CONTINUATION$POWERLINE_RCSH_CONTINUATION) {
_POWERLINE_STATUS = 0
_POWERLINE_JOBNUM = 0
_POWERLINE_CONTINUATION = `{
_powerline_continuation_prompt
}
fn _powerline_continuation_prompt {
echo -n $_POWERLINE_CONTINUATION
}
}
_powerline_common_setup
}
if (test -n $TMUX) {
if ($POWERLINE_CONFIG_COMMAND shell --shell rcsh uses tmux) {
_POWERLINE_TMUX=$TMUX
fn _powerline_tmux_setenv {
if (test -n $2) {
TMUX=$_POWERLINE_TMUX tmux setenv -g TMUX_$1^_`{
_powerline_tmux_pane
} $2
}
}
_powerline_common_setup
}
}
}
# vim: ft=rcshell

View file

@ -0,0 +1,239 @@
_POWERLINE_SOURCED="$_"
_powerline_columns_fallback() {
if command -v stty >/dev/null ; then
# Ksh does not have “local” built-in
_powerline_cols="$(stty size 2>/dev/null)"
if ! test -z "$_powerline_cols" ; then
echo "${_powerline_cols#* }"
return 0
fi
fi
echo 0
return 0
}
_powerline_has_jobs_in_subshell() {
if test -n "$_POWERLINE_HAS_JOBS_IN_SUBSHELL" ; then
return $_POWERLINE_HAS_JOBS_IN_SUBSHELL
elif test -z "$1" ; then
sleep 1 &
# Check whether shell outputs anything in a subshell when using jobs
# built-in. Shells like dash will not output anything meaning that
# I have to bother with temporary files.
test "$(jobs -p|wc -l)" -gt 0
else
case "$1" in
dash|bb|ash) return 1 ;;
mksh|ksh|bash) return 0 ;;
*) _powerline_has_jobs_in_subshell ;;
esac
fi
_POWERLINE_HAS_JOBS_IN_SUBSHELL=$?
return $_POWERLINE_HAS_JOBS_IN_SUBSHELL
}
_powerline_set_append_trap() {
if _powerline_has_jobs_in_subshell "$@" ; then
_powerline_append_trap() {
# Arguments: command, signal
# Ksh does not have “local” built-in
_powerline_traps="$(trap)"
if echo "$_powerline_traps" | grep -cm1 $2'$' >/dev/null ; then
_powerline_traps="$(echo "$_powerline_traps" | sed "s/ $2/'\\n$1' $2/")"
eval "$_powerline_traps"
else
trap "$1" $2
fi
}
else
_powerline_append_trap() {
# Arguments: command, signal
_powerline_create_temp
trap > $_POWERLINE_TEMP
if grep -cm1 $2'$' $_POWERLINE_TEMP >/dev/null ; then
sed -i -e "s/ $2/'\\n$1' $2/"
. $_POWERLINE_TEMP
else
trap "$1" $2
fi
echo -n > $_POWERLINE_TEMP
}
fi
_powerline_set_append_trap() {
return 0
}
}
_powerline_create_temp() {
if test -z "$_POWERLINE_TEMP" || ! test -e "$_POWERLINE_TEMP" ; then
_POWERLINE_TEMP="$(mktemp "${TMPDIR:-/tmp}/powerline.XXXXXXXX")"
_powerline_append_trap 'rm $_POWERLINE_TEMP' EXIT
fi
}
_powerline_set_set_jobs() {
if _powerline_has_jobs_in_subshell "$@" ; then
_powerline_set_jobs() {
_POWERLINE_JOBS="$(jobs -p|wc -l|tr -d ' ')"
}
else
_powerline_set_append_trap "$@"
_POWERLINE_PID=$$
_powerline_append_trap '_powerline_do_set_jobs' USR1
_powerline_do_set_jobs() {
_powerline_create_temp
jobs -p > $_POWERLINE_TEMP
}
# This command will always be launched from a subshell, thus a hack is
# needed to run `jobs -p` outside of the subshell.
_powerline_set_jobs() {
kill -USR1 $_POWERLINE_PID
# Note: most likely this will read data from the previous run. Tests
# show that it is OK for some reasons.
_POWERLINE_JOBS="$(wc -l < $_POWERLINE_TEMP | tr -d ' ')"
}
fi
_powerline_set_set_jobs() {
return 0
}
}
_powerline_set_command() {
if test -z "${POWERLINE_COMMAND}" ; then
POWERLINE_COMMAND="$("$POWERLINE_CONFIG_COMMAND" shell command)"
fi
}
_powerline_tmux_pane() {
echo "${TMUX_PANE:-`TMUX="$_POWERLINE_TMUX" tmux display -p "#D"`}" | \
tr -d ' %'
}
_powerline_tmux_setenv() {
TMUX="$_POWERLINE_TMUX" tmux setenv -g TMUX_"$1"_`_powerline_tmux_pane` "$2"
TMUX="$_POWERLINE_TMUX" tmux refresh -S
}
_powerline_tmux_set_pwd() {
if test "$_POWERLINE_SAVED_PWD" != "$PWD" ; then
_POWERLINE_SAVED_PWD="$PWD"
_powerline_tmux_setenv PWD "$PWD"
fi
}
_powerline_tmux_set_columns() {
_powerline_tmux_setenv COLUMNS "${COLUMNS:-$(_powerline_columns_fallback)}"
}
_powerline_set_renderer_arg() {
case "$1" in
bb|ash) _POWERLINE_RENDERER_ARG="-r .bash" ;;
mksh|ksh) _POWERLINE_RENDERER_ARG="-r .ksh" ;;
bash|dash) _POWERLINE_RENDERER_ARG= ;;
esac
}
_powerline_set_jobs() {
_powerline_set_set_jobs
_powerline_set_jobs
}
_powerline_local_prompt() {
# Arguments: side, exit_code, local theme
_powerline_set_jobs
"$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \
$_POWERLINE_RENDERER_ARG \
--renderer-arg="client_id=$$" \
--last-exit-code=$2 \
--jobnum=$_POWERLINE_JOBS \
--renderer-arg="local_theme=$3"
}
_powerline_prompt() {
# Arguments: side, exit_code
_powerline_set_jobs
"$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \
--width="${COLUMNS:-$(_powerline_columns_fallback)}" \
$_POWERLINE_RENDERER_ARG \
--renderer-arg="client_id=$$" \
--last-exit-code=$2 \
--jobnum=$_POWERLINE_JOBS
_powerline_update_psN
}
_powerline_setup_psN() {
case "$1" in
mksh|ksh|bash)
_POWERLINE_PID=$$
_powerline_update_psN() {
kill -USR1 $_POWERLINE_PID
}
# No command substitution in PS2 and PS3
_powerline_set_psN() {
if test -n "$POWERLINE_SHELL_CONTINUATION" ; then
PS2="$(_powerline_local_prompt left $? continuation)"
fi
if test -n "$POWERLINE_SHELL_SELECT" ; then
PS3="$(_powerline_local_prompt left $? select)"
fi
}
_powerline_append_trap '_powerline_set_psN' USR1
_powerline_set_psN
;;
bb|ash|dash)
_powerline_update_psN() {
# Do nothing
return
}
PS2='$(_powerline_local_prompt left $? continuation)'
# No select support
;;
esac
}
_powerline_setup_prompt() {
VIRTUAL_ENV_DISABLE_PROMPT=1
_powerline_set_append_trap "$@"
_powerline_set_set_jobs "$@"
_powerline_set_command "$@"
_powerline_set_renderer_arg "$@"
PS1='$(_powerline_prompt aboveleft $?)'
PS2="$(_powerline_local_prompt left 0 continuation)"
PS3="$(_powerline_local_prompt left 0 select)"
_powerline_setup_psN "$@"
}
_powerline_init_tmux_support() {
# Dash does not have &>/dev/null
if test -n "$TMUX" && tmux refresh -S >/dev/null 2>/dev/null ; then
# TMUX variable may be unset to create new tmux session inside this one
_POWERLINE_TMUX="$TMUX"
_powerline_set_append_trap "$@"
# If _powerline_tmux_set_pwd is used before _powerline_prompt it sets $?
# to zero in ksh.
PS1="$PS1"'$(_powerline_tmux_set_pwd)'
_powerline_append_trap '_powerline_tmux_set_columns' WINCH
_powerline_tmux_set_columns
fi
}
if test -z "${POWERLINE_CONFIG_COMMAND}" ; then
if command -v powerline-config >/dev/null ; then
POWERLINE_CONFIG_COMMAND=powerline-config
else
POWERLINE_CONFIG_COMMAND="$(dirname "$_POWERLINE_SOURCED")/../../../scripts/powerline-config"
fi
fi
# Strips the leading `-`: it may be present when shell is a login shell
_POWERLINE_USED_SHELL=${0#-}
_POWERLINE_USED_SHELL=${_POWERLINE_USED_SHELL##*/}
if "${POWERLINE_CONFIG_COMMAND}" shell uses tmux ; then
_powerline_init_tmux_support $_POWERLINE_USED_SHELL
fi
if "${POWERLINE_CONFIG_COMMAND}" shell --shell=bash uses prompt ; then
_powerline_setup_prompt $_POWERLINE_USED_SHELL
fi

View file

@ -0,0 +1,60 @@
# http://unix.stackexchange.com/questions/4650/determining-path-to-sourced-shell-script:
# > In tcsh, $_ at the beginning of the script will contain the location if the
# > file was sourced and $0 contains it if it was run.
#
# Guess this relies on `$_` being set as to last argument to previous command
# which must be `.` or `source` in this case
set POWERLINE_SOURCED=($_)
if ! $?POWERLINE_CONFIG_COMMAND then
if ( { which powerline-config > /dev/null } ) then
set POWERLINE_CONFIG_COMMAND="powerline-config"
else
set POWERLINE_CONFIG_COMMAND="$POWERLINE_SOURCED[2]:h:h:h:h/scripts/powerline-config"
endif
else
if "$POWERLINE_CONFIG_COMMAND" == "" then
if ( { which powerline-config > /dev/null } ) then
set POWERLINE_CONFIG_COMMAND="powerline-config"
else
set POWERLINE_CONFIG_COMMAND="$POWERLINE_SOURCED[2]:h:h:h:h/scripts/powerline-config"
endif
endif
endif
if ( { $POWERLINE_CONFIG_COMMAND shell --shell=tcsh uses tmux } ) then
if ( $?TMUX_PANE ) then
if ( "$TMUX_PANE" == "" ) then
set _POWERLINE_TMUX_PANE="`tmux display -p '#D'`"
else
set _POWERLINE_TMUX_PANE="$TMUX_PANE"
endif
else
set _POWERLINE_TMUX_PANE="`tmux display -p '#D'`"
endif
set _POWERLINE_TMUX_PANE="`echo $_POWERLINE_TMUX_PANE:q | tr -d '% '`"
alias _powerline_tmux_set_pwd 'if ( $?TMUX && { tmux refresh -S >&/dev/null } ) tmux setenv -g TMUX_PWD_$_POWERLINE_TMUX_PANE $PWD:q ; if ( $?TMUX ) tmux refresh -S >&/dev/null'
alias cwdcmd "`alias cwdcmd` ; _powerline_tmux_set_pwd"
endif
if ( { $POWERLINE_CONFIG_COMMAND shell --shell=tcsh uses prompt } ) then
if ! $?POWERLINE_COMMAND then
set POWERLINE_COMMAND="`$POWERLINE_CONFIG_COMMAND:q shell command`"
else
if "$POWERLINE_COMMAND" == "" then
set POWERLINE_COMMAND="`$POWERLINE_CONFIG_COMMAND:q shell command`"
endif
endif
if ! $?POWERLINE_COMMAND_ARGS then
set POWERLINE_COMMAND_ARGS=""
endif
if ( $?POWERLINE_NO_TCSH_ABOVE || $?POWERLINE_NO_SHELL_ABOVE ) then
alias _powerline_above true
else
alias _powerline_above '$POWERLINE_COMMAND:q $POWERLINE_COMMAND_ARGS shell above --renderer-arg=client_id=$$ --last-exit-code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS'
endif
alias _powerline_set_prompt 'set prompt="`$POWERLINE_COMMAND:q $POWERLINE_COMMAND_ARGS shell left -r .tcsh --renderer-arg=client_id=$$ --last-exit-code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS`"'
alias _powerline_set_rprompt 'set rprompt="`$POWERLINE_COMMAND:q $POWERLINE_COMMAND_ARGS shell right -r .tcsh --renderer-arg=client_id=$$ --last-exit-code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS`"'
alias _powerline_set_columns 'set POWERLINE_COLUMNS=`stty size|cut -d" " -f2` ; set POWERLINE_COLUMNS=`expr $POWERLINE_COLUMNS - 2`'
alias precmd 'set POWERLINE_STATUS=$? ; '"`alias precmd`"' ; _powerline_set_columns ; _powerline_above ; _powerline_set_prompt ; _powerline_set_rprompt'
endif

View file

@ -0,0 +1,85 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import re
import os
import subprocess
from collections import namedtuple
from powerline.lib.shell import run_cmd
TmuxVersionInfo = namedtuple('TmuxVersionInfo', ('major', 'minor', 'suffix'))
def get_tmux_executable_name():
'''Returns tmux executable name
It should be defined in POWERLINE_TMUX_EXE environment variable, otherwise
it is simply tmux.
'''
return os.environ.get('POWERLINE_TMUX_EXE', 'tmux')
def _run_tmux(runner, args):
return runner([get_tmux_executable_name()] + list(args))
def run_tmux_command(*args):
'''Run tmux command, ignoring the output'''
_run_tmux(subprocess.check_call, args)
def get_tmux_output(pl, *args):
'''Run tmux command and return its output'''
return _run_tmux(lambda cmd: run_cmd(pl, cmd), args)
def set_tmux_environment(varname, value, remove=True):
'''Set tmux global environment variable
:param str varname:
Name of the variable to set.
:param str value:
Variable value.
:param bool remove:
True if variable should be removed from the environment prior to
attaching any client (runs ``tmux set-environment -r {varname}``).
'''
run_tmux_command('set-environment', '-g', varname, value)
if remove:
try:
run_tmux_command('set-environment', '-r', varname)
except subprocess.CalledProcessError:
# On tmux-2.0 this command may fail for whatever reason. Since it is
# critical just ignore the failure.
pass
def source_tmux_file(fname):
'''Source tmux configuration file
:param str fname:
Full path to the sourced file.
'''
run_tmux_command('source', fname)
NON_DIGITS = re.compile('[^0-9]+')
DIGITS = re.compile('[0-9]+')
NON_LETTERS = re.compile('[^a-z]+')
def get_tmux_version(pl):
version_string = get_tmux_output(pl, '-V')
_, version_string = version_string.split(' ')
version_string = version_string.strip()
if version_string == 'master':
return TmuxVersionInfo(float('inf'), 0, version_string)
major, minor = version_string.split('.')
major = NON_DIGITS.subn('', major)[0]
suffix = DIGITS.subn('', minor)[0] or None
minor = NON_DIGITS.subn('', minor)[0]
return TmuxVersionInfo(int(major), int(minor), suffix)

View file

@ -0,0 +1,11 @@
set -g status on
set -g status-interval 2
set -g status-left-length 20
set -g status-right '#(env "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS tmux right -R pane_id=#{pane_id})'
set -g status-right-length 150
set -g window-status-format "#[$_POWERLINE_WINDOW_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER_SPACES#I#F #[$_POWERLINE_WINDOW_DIVIDER_COLOR]$_POWERLINE_LEFT_SOFT_DIVIDER#[default]#W $_POWERLINE_LEFT_HARD_DIVIDER_SPACES"
set -g window-status-current-format "#[$_POWERLINE_WINDOW_CURRENT_HARD_DIVIDER_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#[$_POWERLINE_WINDOW_CURRENT_COLOR]#I#F $_POWERLINE_LEFT_SOFT_DIVIDER#[$_POWERLINE_WINDOW_NAME_COLOR]#W #[$_POWERLINE_WINDOW_CURRENT_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER"
# Legacy status-left definition to be overwritten for tmux Versions 1.8+
set -g status-left "#[$_POWERLINE_SESSION_COLOR] #S #[$_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#(env \"\$POWERLINE_COMMAND\" tmux left -R pane_id=#{pane_id})"
# vim: ft=tmux

View file

@ -0,0 +1,2 @@
if-shell 'env "$POWERLINE_CONFIG_COMMAND" tmux setup' '' 'run-shell "powerline-config tmux setup"'
# vim: ft=tmux

View file

@ -0,0 +1,3 @@
set -g status-right '#(env "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS tmux right -R pane_id=#{pane_id} --width=#{client_width} -R width_adjust=#{status-left-length})'
set -g status-left "#[$_POWERLINE_SESSION_COLOR] #S #[$_POWERLINE_SESSION_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER#(env \"\$POWERLINE_COMMAND\" tmux left --width=#{client_width} -R width_adjust=#{status-right-length} -R pane_id=#{pane_id})"
# vim: ft=tmux

View file

@ -0,0 +1,5 @@
# powerline_tmux_1.8.conf
# tmux Version 1.8 introduces window-status-last-{attr,bg,fg}, which is
# deprecated for versions 1.9+, thus only applicable to version 1.8.
set -qg window-status-last-fg "$_POWERLINE_ACTIVE_WINDOW_FG"
# vim: ft=tmux

View file

@ -0,0 +1,11 @@
# powerline_tmux_legacy_common.conf
# tmux Version 1.8 and earlier (legacy) common options. The foo-{attr,bg,fg}
# options are deprecated starting with tmux Version 1.9.
set -g status-fg "$_POWERLINE_BACKGROUND_FG"
set -g status-bg "$_POWERLINE_BACKGROUND_BG"
set-window-option -g window-status-fg "$_POWERLINE_WINDOW_STATUS_FG"
set-window-option -g window-status-activity-attr "$_POWERLINE_ACTIVITY_STATUS_ATTR_LEGACY"
set-window-option -g window-status-bell-attr "$_POWERLINE_BELL_STATUS_ATTR_LEGACY"
set-window-option -g window-status-activity-fg "$_POWERLINE_ACTIVITY_STATUS_FG"
set-window-option -g window-status-bell-fg "$_POWERLINE_BELL_STATUS_FG"
# vim: ft=tmux

View file

@ -0,0 +1,5 @@
# powerline_tmux_1.8_plus.conf
# tmux Version 1.8 introduces the 'client_prefix' format variable, applicable
# for versions 1.8+
set -qg status-left "#{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_FG]#[bg=$_POWERLINE_SESSION_PREFIX_BG]#[$_POWERLINE_SESSION_PREFIX_ATTR],#[fg=$_POWERLINE_SESSION_FG]#[bg=$_POWERLINE_SESSION_BG]#[$_POWERLINE_SESSION_ATTR]} #S #{?client_prefix,#[fg=$_POWERLINE_SESSION_PREFIX_BG],#[fg=$_POWERLINE_SESSION_BG]}#[bg=$_POWERLINE_BACKGROUND_BG]#[nobold]$_POWERLINE_LEFT_HARD_DIVIDER#(env \$POWERLINE_COMMAND \$POWERLINE_COMMAND_ARGS tmux left --width=#{client_width} -R width_adjust=#{status-right-length} -R pane_id=#{pane_id})"
# vim: ft=tmux

View file

@ -0,0 +1,9 @@
# powerline_tmux_1.9_plus.conf
# Version 1.9 introduces the foo-style options, applicable to version 1.9+
set-option -qg status-style "$_POWERLINE_BACKGROUND_COLOR"
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

View file

@ -0,0 +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} -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"

Some files were not shown because too many files have changed in this diff Show more