Adding upstream version 2.8.4.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
20
.editorconfig
Normal 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
|
@ -0,0 +1 @@
|
||||||
|
*.rst whitespace=-blank-at-eol
|
46
.github/workflows/main.yaml
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
name: Build and Publish to PyPI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
- feature/actions
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
python-version: [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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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. It’s simple to write renderers for any
|
||||||
|
other applications that Powerline doesn’t 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 Powerline’s 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 don’t 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
|
@ -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
|
@ -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
|
@ -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
|
@ -0,0 +1 @@
|
||||||
|
_build
|
39
docs/Makefile
Normal 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."
|
6
docs/source/_static/css/theme_overrides.css
Normal 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;
|
||||||
|
}
|
BIN
docs/source/_static/img/icons/cross.png
Normal file
After Width: | Height: | Size: 473 B |
BIN
docs/source/_static/img/icons/error.png
Normal file
After Width: | Height: | Size: 543 B |
BIN
docs/source/_static/img/icons/tick.png
Normal file
After Width: | Height: | Size: 451 B |
BIN
docs/source/_static/img/pl-mode-insert.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
docs/source/_static/img/pl-mode-normal.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
docs/source/_static/img/pl-mode-replace.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
docs/source/_static/img/pl-mode-visual.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
docs/source/_static/img/pl-truncate1.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
docs/source/_static/img/pl-truncate2.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
docs/source/_static/img/pl-truncate3.png
Normal file
After Width: | Height: | Size: 3 KiB |
9
docs/source/commands.rst
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
**************************************
|
||||||
|
Powerline shell commands’ manual pages
|
||||||
|
**************************************
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
:glob:
|
||||||
|
|
||||||
|
commands/*
|
12
docs/source/commands/config.rst
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
:orphan:
|
||||||
|
|
||||||
|
powerline-config manual page
|
||||||
|
============================
|
||||||
|
|
||||||
|
.. automan:: powerline.commands.config
|
||||||
|
:prog: powerline-config
|
||||||
|
|
||||||
|
See also
|
||||||
|
--------
|
||||||
|
|
||||||
|
:manpage:`powerline(1)`
|
12
docs/source/commands/daemon.rst
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
:orphan:
|
||||||
|
|
||||||
|
powerline-daemon manual page
|
||||||
|
============================
|
||||||
|
|
||||||
|
.. automan:: powerline.commands.daemon
|
||||||
|
:prog: powerline-daemon
|
||||||
|
|
||||||
|
See also
|
||||||
|
--------
|
||||||
|
|
||||||
|
:manpage:`powerline(1)`
|
14
docs/source/commands/lint.rst
Normal 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)`
|
12
docs/source/commands/main.rst
Normal 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
|
@ -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 we’re 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',
|
||||||
|
],
|
||||||
|
}
|
151
docs/source/configuration.rst
Normal 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:: It’s essential that the contents of all your configuration files
|
||||||
|
is valid JSON! It’s 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. Here’s 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 you’re using GMail it’s 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 GMail’s
|
||||||
|
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 you’re on a VPN you probably won’t have to change the location
|
||||||
|
query.
|
||||||
|
|
||||||
|
It is using OpenWeatherMap as a provider, which can be configured with a
|
||||||
|
personal API key. These can be generated `here
|
||||||
|
<https://home.openweathermap.org/api_keys>`_
|
||||||
|
|
||||||
|
If you want to change the location query or the temperature unit you’ll
|
||||||
|
have to update the segment arguments. Open a theme file, scroll down to
|
||||||
|
the weather segment and update it to include unit, location query 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
|
35
docs/source/configuration/listers.rst
Normal 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:
|
260
docs/source/configuration/local.rst
Normal 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>`.
|
602
docs/source/configuration/reference.rst
Normal 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
|
||||||
|
aren’t 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 group’s definition
|
||||||
|
will be used when this color is requested.
|
||||||
|
|
||||||
|
``mode_translations``
|
||||||
|
Mode-specific highlighting for extensions that support it (e.g. the vim
|
||||||
|
extension). It’s 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.
|
28
docs/source/configuration/segments.rst
Normal 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
|
||||||
|
don’t provide an ``args`` dict.
|
||||||
|
|
||||||
|
More information is available in :ref:`Writing segments <dev-segments>` section.
|
||||||
|
|
||||||
|
Available segments
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:glob:
|
||||||
|
|
||||||
|
segments/*
|
57
docs/source/configuration/segments/common.rst
Normal 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:
|
6
docs/source/configuration/segments/i3wm.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
*************
|
||||||
|
i3wm segments
|
||||||
|
*************
|
||||||
|
|
||||||
|
.. automodule:: powerline.segments.i3wm
|
||||||
|
:members:
|
7
docs/source/configuration/segments/pdb.rst
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
************
|
||||||
|
PDB segments
|
||||||
|
************
|
||||||
|
|
||||||
|
.. automodule:: powerline.segments.pdb
|
||||||
|
:members:
|
||||||
|
|
6
docs/source/configuration/segments/shell.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
**************
|
||||||
|
Shell segments
|
||||||
|
**************
|
||||||
|
|
||||||
|
.. automodule:: powerline.segments.shell
|
||||||
|
:members:
|
6
docs/source/configuration/segments/tmux.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
*************
|
||||||
|
Tmux segments
|
||||||
|
*************
|
||||||
|
|
||||||
|
.. automodule:: powerline.segments.tmux
|
||||||
|
:members:
|
46
docs/source/configuration/segments/vim.rst
Normal 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:
|
17
docs/source/configuration/selectors.rst
Normal 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/*
|
6
docs/source/configuration/selectors/vim.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
*************
|
||||||
|
Vim selectors
|
||||||
|
*************
|
||||||
|
|
||||||
|
.. automodule:: powerline.selectors.vim
|
||||||
|
:members:
|
13
docs/source/develop.rst
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
***************
|
||||||
|
Developer guide
|
||||||
|
***************
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:glob:
|
||||||
|
|
||||||
|
develop/segments
|
||||||
|
develop/listers
|
||||||
|
develop/local-themes
|
||||||
|
develop/extensions
|
||||||
|
develop/tips-and-tricks
|
47
docs/source/develop/extensions.rst
Normal 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:
|
49
docs/source/develop/listers.rst
Normal 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`.
|
59
docs/source/develop/local-themes.rst
Normal 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. |
|
||||||
|
+---------+------------+-------------------------------------------------------+
|
547
docs/source/develop/segments.rst
Normal 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 daemon’s
|
||||||
|
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 object’s 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
|
||||||
|
object’s 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:
|
21
docs/source/develop/tips-and-tricks.rst
Normal 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
|
@ -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`
|
131
docs/source/installation.rst
Normal 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 can’t 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>
|
110
docs/source/installation/linux.rst
Normal 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§ion=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. It’s 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 it’s
|
||||||
|
``~/.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* can’t 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* can’t be seen then double-check that the font have
|
||||||
|
been installed to a valid X font path.
|
71
docs/source/installation/osx.rst
Normal 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*.
|
31
docs/source/license-and-credits.rst
Normal 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
|
@ -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. It’s simple to write renderers for any
|
||||||
|
other applications that Powerline doesn’t 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 Powerline’s 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 don’t 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
|
62
docs/source/powerline_autodoc.py
Normal 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)
|
408
docs/source/powerline_automan.py
Normal 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 – (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)
|
110
docs/source/tips-and-tricks.rst
Normal 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 don’t. 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()
|
333
docs/source/troubleshooting.rst
Normal 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
|
||||||
|
==========================
|
||||||
|
|
||||||
|
I’m using tmux and Powerline looks like crap, what’s 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 you’re 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.
|
||||||
|
|
||||||
|
I’m 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.
|
78
docs/source/troubleshooting/linux.rst
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
************************
|
||||||
|
Troubleshooting on Linux
|
||||||
|
************************
|
||||||
|
|
||||||
|
I can’t see any fancy symbols, what’s wrong?
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
* Make sure that you’ve 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 distro’s
|
||||||
|
documentation for information about setting these variables correctly.
|
||||||
|
* Make sure that vim is compiled with the ``--with-features=big`` flag.
|
||||||
|
* If you’re using rxvt-unicode make sure that it’s compiled with the
|
||||||
|
``--enable-unicode3`` flag.
|
||||||
|
* If you’re 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 won’t 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+23F4–U+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.
|
71
docs/source/troubleshooting/osx.rst
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
***********************
|
||||||
|
Troubleshooting on OS X
|
||||||
|
***********************
|
||||||
|
|
||||||
|
I can’t see any fancy symbols, what’s wrong?
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
* If you’re 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 distro’s
|
||||||
|
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
|
@ -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 distribution’s
|
||||||
|
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
|
@ -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>`_.
|
161
docs/source/usage/shell-prompts.rst
Normal 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``.
|
101
docs/source/usage/wm-widgets.rst
Normal 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.
|
105
font/10-powerline-symbols.conf
Normal 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
991
powerline/__init__.py
Normal 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. Won’t 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)
|
0
powerline/bindings/__init__.py
Normal file
20
powerline/bindings/awesome/powerline-awesome.py
Executable 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()
|
15
powerline/bindings/awesome/powerline.lua
Normal 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
|
60
powerline/bindings/bar/powerline-bar.py
Executable 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)
|
153
powerline/bindings/bash/powerline.sh
Normal 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
|
286
powerline/bindings/config.py
Normal 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)
|
100
powerline/bindings/fish/powerline-setup.fish
Normal 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
|
52
powerline/bindings/i3/powerline-i3.py
Executable 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))
|
0
powerline/bindings/ipython/__init__.py
Normal file
126
powerline/bindings/ipython/post_0_11.py
Normal 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
|
146
powerline/bindings/ipython/pre_0_11.py
Normal 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)
|
81
powerline/bindings/ipython/since_5.py
Normal 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))
|
78
powerline/bindings/ipython/since_7.py
Normal 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))
|
61
powerline/bindings/lemonbar/powerline-lemonbar.py
Executable 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)
|
183
powerline/bindings/pdb/__init__.py
Normal 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 that’s 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()
|
9
powerline/bindings/pdb/__main__.py
Executable 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()
|
0
powerline/bindings/qtile/__init__.py
Normal file
61
powerline/bindings/qtile/widget.py
Normal 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
|
92
powerline/bindings/rc/powerline.rc
Normal 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
|
239
powerline/bindings/shell/powerline.sh
Normal 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
|
60
powerline/bindings/tcsh/powerline.tcsh
Normal 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
|
85
powerline/bindings/tmux/__init__.py
Normal 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)
|
11
powerline/bindings/tmux/powerline-base.conf
Normal 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
|
2
powerline/bindings/tmux/powerline.conf
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
if-shell 'env "$POWERLINE_CONFIG_COMMAND" tmux setup' '' 'run-shell "powerline-config tmux setup"'
|
||||||
|
# vim: ft=tmux
|
3
powerline/bindings/tmux/powerline_tmux_1.7_plus.conf
Normal 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
|
5
powerline/bindings/tmux/powerline_tmux_1.8.conf
Normal 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
|
11
powerline/bindings/tmux/powerline_tmux_1.8_minus.conf
Normal 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
|
5
powerline/bindings/tmux/powerline_tmux_1.8_plus.conf
Normal 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
|
9
powerline/bindings/tmux/powerline_tmux_1.9_plus.conf
Normal 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
|
3
powerline/bindings/tmux/powerline_tmux_2.1_plus.conf
Normal 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"
|