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"
|