diff --git a/.travis.yml b/.travis.yml index 4eccbf31..b6cedf3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,22 @@ language: python -python: - - "2.6" - - "2.7" - - "3.2" - - "3.3" - - "3.4" - - "pypy" install: tests/install.sh script: tests/test.sh +matrix: + include: + - python: "2.6" + - python: "2.7" + - python: "3.2" + - python: "3.3" + - python: "3.4" + - python: "pypy" + - python: "pypy3" + - python: "2.6" + env: >- + USE_UCS2_PYTHON=1 + UCS2_PYTHON_VARIANT="2.6" + - python: "2.7" + env: >- + USE_UCS2_PYTHON=1 + UCS2_PYTHON_VARIANT="2.7" # vim: et diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index f957e652..3792b708 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -13,9 +13,8 @@ Getting started =============== * Make sure you have a `GitHub account `_. -* Submit an `issue on GitHub - `_, assuming one does not - already exist. +* Submit an `issue on GitHub `_, + assuming one does not already exist. * Clearly describe the issue. * If the issue is a bug: make sure you include steps to reproduce, and @@ -135,5 +134,5 @@ Submitting changes * Push your changes to a topic branch in your fork of the repository. * If necessary, use ``git rebase -i `` to squash or reword commits before submitting a pull request. -* Submit a pull request to `Lokaltog's repository - `_. +* Submit a pull request to `powerline repository + `_. diff --git a/LICENSE b/LICENSE index ad3cf61a..23b2ab29 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ Copyright 2013 Kim Silkebækken and other contributors -https://github.com/Lokaltog/powerline +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 diff --git a/README.rst b/README.rst index 65dc614d..c30679e1 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,7 @@ Powerline ========= :Author: Kim Silkebækken (kim.silkebaekken+vim@gmail.com) -:Source: https://github.com/Lokaltog/powerline +:Source: https://github.com/powerline/powerline :Version: beta **Powerline is a statusline plugin for vim, and provides statuslines and @@ -12,11 +12,11 @@ Awesome and Qtile.** * `Support forum`_ (powerline-support@googlegroups.com) * `Development discussion`_ (powerline-dev@googlegroups.com) -.. image:: https://api.travis-ci.org/Lokaltog/powerline.png?branch=develop +.. image:: https://api.travis-ci.org/powerline/powerline.png?branch=develop :target: `travis-build-status`_ :alt: Build status -.. _travis-build-status: https://travis-ci.org/Lokaltog/powerline +.. _travis-build-status: https://travis-ci.org/powerline/powerline .. _`Support forum`: https://groups.google.com/forum/#!forum/powerline-support .. _`Development discussion`: https://groups.google.com/forum/#!forum/powerline-dev @@ -59,8 +59,8 @@ and feature-rich alternative is currently Bailey Ling’s `vim-airline * Consult the `documentation `_ for more information and installation instructions. -* Check out `powerline-fonts `_ - for pre-patched versions of popular, open source coding fonts. +* Check out `powerline-fonts `_ for + pre-patched versions of popular, open source coding fonts. Screenshots ----------- @@ -70,22 +70,22 @@ Vim statusline **Mode-dependent highlighting** -* .. image:: https://raw.github.com/Lokaltog/powerline/develop/docs/source/_static/img/pl-mode-normal.png +* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-mode-normal.png :alt: Normal mode -* .. image:: https://raw.github.com/Lokaltog/powerline/develop/docs/source/_static/img/pl-mode-insert.png +* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-mode-insert.png :alt: Insert mode -* .. image:: https://raw.github.com/Lokaltog/powerline/develop/docs/source/_static/img/pl-mode-visual.png +* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-mode-visual.png :alt: Visual mode -* .. image:: https://raw.github.com/Lokaltog/powerline/develop/docs/source/_static/img/pl-mode-replace.png +* .. 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/Lokaltog/powerline/develop/docs/source/_static/img/pl-truncate1.png +* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-truncate1.png :alt: Truncation illustration -* .. image:: https://raw.github.com/Lokaltog/powerline/develop/docs/source/_static/img/pl-truncate2.png +* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-truncate2.png :alt: Truncation illustration -* .. image:: https://raw.github.com/Lokaltog/powerline/develop/docs/source/_static/img/pl-truncate3.png +* .. image:: https://raw.github.com/powerline/powerline/develop/docs/source/_static/img/pl-truncate3.png :alt: Truncation illustration ---- diff --git a/docs/source/_static/css/theme_overrides.css b/docs/source/_static/css/theme_overrides.css new file mode 100644 index 00000000..7e39e343 --- /dev/null +++ b/docs/source/_static/css/theme_overrides.css @@ -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; +} diff --git a/docs/source/conf.py b/docs/source/conf.py index 99101df1..5577ef65 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -59,3 +59,12 @@ if not on_rtd: # only import and set the theme if we’re building docs locally 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', + ], + } diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index ed31faba..d3754905 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -2,9 +2,10 @@ Configuration and customization ******************************* -.. note:: **You DO NOT have to fork the main GitHub repo to personalize your - Powerline configuration!** Please read through the :ref:`quick-guide` for - a quick introduction to user configuration. +.. 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 @@ -29,26 +30,27 @@ configuration files are stored in :file:`$XDG_CONFIG_HOME/powerline` for Linux users, and in :file:`~/.config/powerline` for OS X users. This usually corresponds to :file:`~/.config/powerline` on both platforms. -If you need per-instance configuration please refer to :ref:`Local configuration -overrides `. +If per-instance configuration is needed please refer to :ref:`Local +configuration overrides `. -.. note:: If you have multiple configuration files with the same name in - different directories then these files will be merged. Merging happens in - the following order: +.. note:: + Existing multiple configuration files that have the same name, but are placed + in different directories, will be merged. Merging happens in the following + order: - * :file:`{powerline_root}/powerline/config_files` is checked for - configuration first. Configuration from this source has least priority. - * :file:`$XDG_CONFIG_DIRS/powerline` directories are the next ones to check. - Checking happens in the reversed order: directories mentioned last are - checked before directories mentioned first. Each new found file is merged - with the result of previous merge. - * :file:`$XDG_CONFIG_HOME/powerline` directory is the last to check. - Configuration from there has top priority. + * :file:`{powerline_root}/powerline/config_files` is checked for + configuration first. Configuration from this source has least priority. + * :file:`$XDG_CONFIG_DIRS/powerline` directories are the next ones to check. + Checking happens in the reversed order: directories mentioned last are + checked before directories mentioned first. Each new found file is merged + with the result of previous merge. + * :file:`$XDG_CONFIG_HOME/powerline` directory is the last to check. + Configuration from there has top priority. - 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. + 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 diff --git a/docs/source/configuration/local.rst b/docs/source/configuration/local.rst index 385bdfcf..3eec3ee0 100644 --- a/docs/source/configuration/local.rst +++ b/docs/source/configuration/local.rst @@ -16,11 +16,11 @@ Vim configuration can be overridden using the following options: Dictionary, recursively merged with contents of :file:`powerline/config.json`. -``g:powerline_theme_overrides__{theme_name}`` - Dictionary, recursively merged with contents of - :file:`powerline/themes/vim/{theme_name}.json`. Note that this way you can’t - redefine some value (e.g. segment) in list, only the whole list itself: only - dictionaries are merged recursively. +``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). @@ -31,13 +31,21 @@ Vim configuration can be overridden using the following options: 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 `. Level is always + :ref:`log_level `, same for format. + +.. _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=KEY.NESTED_KEY=VALUE`` +``-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 @@ -47,7 +55,7 @@ Powerline script has a number of options controlling powerline behavior. Here 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_option=THEME_NAME.KEY.NESTED_KEY=VALUE`` +``-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. @@ -55,46 +63,133 @@ Powerline script has a number of options controlling powerline behavior. Here If ``VALUE`` is omitted then corresponding key will be removed from the configuration (if it was present). -``-p PATH`` or ``--config_path=PATH`` +``-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 ` + 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 `. + 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. +are taken from zsh variables. :ref:`Environment variable overrides +` are also supported: if variable is a string +this variant is used. -``POWERLINE_CONFIG`` +``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_CONFIG`` +``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``, - but only subdictionaries for ``THEME_NAME`` key are merged with theme - configuration when theme with given name is requested. + 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 you set variable without quotes: ``POWERLINE_CONFIG_PATHS=( ~/example - )``. You should use array parameter or the usual colon-separated - ``POWERLINE_CONFIG_PATHS=$HOME/path1:$HOME/path2``. + 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 you should pass -additional keyword arguments to setup() function. After ipython-0.11 you should -use ``c.Powerline.KEY``. Supported ``KEY`` strings or keyword argument names: +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 @@ -105,43 +200,42 @@ use ``c.Powerline.KEY``. Supported ``KEY`` strings or keyword argument names: a dictionary where keys are theme names and values are dictionaries which will be recursively merged with the contents of the given theme. -``paths`` +``config_paths`` Sets directories where configuration should be read from. If present, no default locations are searched for configuration. No expansions are - performed thus you cannot use paths starting with ``~/``. + performed thus paths starting with ``~/`` cannot be used: use + :py:func:`os.path.expanduser`. Prompt command ============== -In addition to the above configuration options you can use -``$POWERLINE_COMMAND`` environment variable to tell shell or tmux to use -specific powerline implementation and ``$POWERLINE_CONFIG`` to tell zsh or tmux -where ``powerline-config`` script is located. This is mostly useful for putting +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`` appears in shell scripts without quotes thus you can - specify additional parameters in bash. In tmux it is passed to ``eval`` and - depends on the shell used. POSIX-compatible shells, zsh, bash and fish will - split this variable in this case. + ``$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 ` instead. -If you want to disable prompt in shell, but still have tmux support or if you -want to disable tmux support you can use variables -``$POWERLINE_NO_{SHELL}_PROMPT``/``$POWERLINE_NO_SHELL_PROMPT`` and -``$POWERLINE_NO_{SHELL}_TMUX_SUPPORT``/``$POWERLINE_NO_SHELL_TMUX_SUPPORT`` -(substitute ``{SHELL}`` with the name of the shell (all-caps) you want to -disable support for (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. +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. -If you do not want to disable prompt in shell, but yet do not want to launch -python twice to get :ref:`above ` lines you do not use in -tcsh you should set ``$POWERLINE_NO_TCSH_ABOVE`` or -``$POWERLINE_NO_SHELL_ABOVE`` variable. +In order to keep shell prompt, but avoid launching Python twice to get unused +:ref:`above ` lines in tcsh ``$POWERLINE_NO_TCSH_ABOVE`` or +``$POWERLINE_NO_SHELL_ABOVE`` variable should be set. -If you do not want to see additional space which is added to the right prompt in -fish in order to support multiline prompt you should set -``$POWERLINE_NO_FISH_ABOVE`` or ``$POWERLINE_NO_SHELL_ABOVE`` variables. +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. diff --git a/docs/source/configuration/reference.rst b/docs/source/configuration/reference.rst index 4e3ec2b7..d6116019 100644 --- a/docs/source/configuration/reference.rst +++ b/docs/source/configuration/reference.rst @@ -24,7 +24,30 @@ Common configuration is a subdictionary that is a value of ``common`` key in ``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 your terminal emulator supports 24-bit colors. + information on whether used terminal emulator supports 24-bit colors. + + This variable is forced to be ``false`` if :ref:`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: @@ -32,7 +55,7 @@ Common configuration is a subdictionary that is a value of ``common`` key in Tells powerline what to do with characters with East Asian Width Class Ambigious (such as Euro, Registered Sign, Copyright Sign, Greek letters, Cyrillic letters). Valid values: any positive integer; it is - suggested that you only set it to 1 (default) or 2. + suggested that this option is only set it to 1 (default) or 2. .. _config-common-watcher: @@ -54,12 +77,11 @@ Common configuration is a subdictionary that is a value of ``common`` key in ``additional_escapes`` Valid for shell extensions, makes sense only if :ref:`term_truecolor - ` is enabled. Is to be set from command-line - (unless you are sure you always need it). 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). + ` 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: @@ -75,6 +97,8 @@ Common configuration is a subdictionary that is a value of ``common`` key in Defines path which will hold powerline logs. If not present, logging will be done to stderr. +.. _config-common-log_level: + ``log_level`` String, determines logging level. Defaults to ``WARNING``. @@ -187,8 +211,8 @@ Color definitions * A list of cterm color indicies. * A list of hex color strings. - It is expected that you define gradients from least alert color to most - alert or use non-alert colors. + It is expected that gradients are defined from least alert color to most + alert or non-alert colors are used. .. _config-colorschemes: @@ -225,11 +249,11 @@ override those from each previous file. It is required that either Background color. Must be defined in :ref:`colors `. - ``attr`` + ``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 you do not - need any attributes leave this empty. + 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. @@ -273,6 +297,7 @@ with the following top themes: 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 @@ -307,9 +332,7 @@ ascii Theme without any unicode characters at all ``dividers`` - Defines the dividers used in all Powerline extensions. This option - should usually only be changed if you don’t have a patched font, or if - you use a font patched with the legacy font patcher. + 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 @@ -386,8 +409,8 @@ ascii Theme without any unicode characters at all ``string`` A static string segment where the contents is defined in the :ref:`contents option `, and the - highlighting group is defined in the :ref:`highlight_group - option `. + highlighting group is defined in the :ref:`highlight_groups option + `. ``segments_list`` Sub-list of segments. This list only allows :ref:`function @@ -419,9 +442,9 @@ ascii Theme without any unicode characters at all or ``{function}``. If ``{module}`` is omitted :ref:`default_module option ` is used. - .. _config-themes-seg-highlight_group: + .. _config-themes-seg-highlight_groups: - ``highlight_group`` + ``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. diff --git a/docs/source/configuration/segments/vim.rst b/docs/source/configuration/segments/vim.rst index eeadd4f1..b0f52c18 100644 --- a/docs/source/configuration/segments/vim.rst +++ b/docs/source/configuration/segments/vim.rst @@ -15,12 +15,6 @@ Syntastic segments .. automodule:: powerline.segments.vim.plugin.syntastic :members: -Ctrl-P segments ---------------- - -.. automodule:: powerline.segments.vim.plugin.ctrlp - :members: - Command-T segments ------------------ diff --git a/docs/source/develop/extensions.rst b/docs/source/develop/extensions.rst index 9f4437d6..2ddf2234 100644 --- a/docs/source/develop/extensions.rst +++ b/docs/source/develop/extensions.rst @@ -24,8 +24,8 @@ segments in some set of applications. Specifically this means computing text width. This subclass must be placed directly in :file:`powerline/renderers` - directory (if you are creating powerline extension for a set of applications - use :file:`powerline/renderers/{ext}/*.py`) and named like ``ExtRenderer`` or + 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. diff --git a/docs/source/develop/listers.rst b/docs/source/develop/listers.rst index 37917fe2..e7797040 100644 --- a/docs/source/develop/listers.rst +++ b/docs/source/develop/listers.rst @@ -4,7 +4,7 @@ Writing listers *************** -Listers allow you to show some segments multiple times: once per each entity +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: diff --git a/docs/source/develop/local-themes.rst b/docs/source/develop/local-themes.rst index e1ca6483..959e1c4b 100644 --- a/docs/source/develop/local-themes.rst +++ b/docs/source/develop/local-themes.rst @@ -32,7 +32,7 @@ arguments: matcher name (same as in :ref:`local_themes `) and dictionary with theme. This dictionary is merged with :ref:`top theme ` and :file:`powerline/themes/vim/__main__.json`. Note that if user already specified -your matcher in his configuration file ``KeyError`` is raised. +the matcher in his configuration file ``KeyError`` is raised. Other local themes ================== diff --git a/docs/source/develop/segments.rst b/docs/source/develop/segments.rst index 66003a72..509eb7f7 100644 --- a/docs/source/develop/segments.rst +++ b/docs/source/develop/segments.rst @@ -12,7 +12,7 @@ object it should receive the following arguments: ``pl`` A :py:class:`powerline.PowerlineLogger` instance. It must be used every time - you need to log something. + something needs to be logged. ``segment_info`` A dictionary. It is only received if callable has @@ -32,20 +32,21 @@ And also any other argument(s) specified by user in :ref:`args key .. note:: For powerline-lint to work properly the following things may be needed: - #. If your segment is a :py:class:`powerline.segments.Segment` and used + #. 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 your segment takes some arguments that are never listed, but accessed - via ``kwargs.get()`` or you cannot use previous function for whatever - reason :py:meth:`powerline.segments.Segment.additional_args` should be + #. 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 you are expecting user to use one :ref:`name ` - for multiple segments which cannot be linked to the segment function + #. If user is expected to use one :ref:`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) you should use - :py:func:`powerline.lint.checks.register_common_name`. + 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: @@ -110,7 +111,7 @@ powerline: .. warning:: “Amount of display cells” is *not* number of Unicode codepoints, string - length, or byte count. It is suggested that your function should look + 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. @@ -139,7 +140,7 @@ value: [{ 'contents': original_return, - 'highlight_group': [segment_name], + 'highlight_groups': [segment_name], }] .. _dev-segments-return: @@ -163,31 +164,32 @@ Detailed description of used dictionary keys: as :ref:`the similar keys in configuration ` (:ref:`draw_inner_divider `). -.. _dev-segments-highlight_group: +.. _dev-segments-highlight_groups: -``highlight_group`` +``highlight_groups`` Determines segment highlighting. Refer to :ref:`themes documentation - ` for more details. + ` for more details. Defaults to the name of the segment. .. note:: - If you want to include your segment in powerline you must specify all - highlighting groups used in the segment documentation in the form:: + 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``]*]*. + Highlight groups used: ``g1``[ or ``g2``]*[, ``g3`` (gradient)[ or ``g4``]*]*. - I.e. use:: + I.e. use:: - Highlight groups used: ``foo_gradient`` (gradient) or ``foo``, ``bar``. + Highlight groups used: ``foo_gradient`` (gradient) or ``foo``, ``bar``. - to specify that your 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. + 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. - You must specify all groups on one line. + All groups must be specified on one line. ``divider_highlight_group`` Determines segment divider highlight group. Only applicable for soft @@ -195,19 +197,20 @@ Detailed description of used dictionary keys: segments. .. note:: - If you want to include your segment in powerline you must specify used - groups in the segment documentation in the form:: + 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 you are supposed to end all divider - highlight group names with ``:divider``: e.g. ``cwd:divider``. + 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_group - ` was defined to use the color gradient. + highlighting groups specified by :ref:`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. @@ -243,7 +246,7 @@ Segment dictionary contains the following keys: :ref:`Segment type `. Always represents actual type and is never ``None``. - ``highlight_group``, ``divider_highlight_group`` + ``highlight_groups``, ``divider_highlight_group`` Used highlight groups. May be ``None``. ``highlight_group_prefix`` @@ -330,16 +333,19 @@ keys: have ``__getitem__`` and ``get`` methods and nothing more. .. warning:: - You must not ever use ``os.environ``. If your segment is run in daemon - you will get daemon’s environment which is not correct. If your segment - is run in Vim or in zsh with libzpython you will get Vim or zsh - environment at python startup. + ``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. You must not use ``os.getcwd`` for the same reasons you must not - use ``os.environ``, except that current working directory is valid in Vim - and zsh (but not in daemon). + 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. @@ -352,36 +358,36 @@ Vim Vim ``segment_info`` argument is a dictionary with the following keys: ``window`` - ``vim.Window`` object. You may obtain one using ``vim.current.window`` or - ``vim.windows[number - 1]``. May be a false object, in which case you should - not use any of this objects’ properties. + ``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. You - should assume that this ID is hashable and supports equality comparison, but - you must not use any other assumptions about it. Currently uses integer + 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. You may obtain one using ``vim.current.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 you must iterate over ``vim.buffers`` and check their ``number`` - attributes. + dictionary iteration over ``vim.buffers`` and checking their ``number`` + attributes should be performed. ``bufnr`` Buffer number. ``tabpage`` - ``vim.Tabpage`` object. You may obtain one using ``vim.current.tabpage`` or - ``vim.tabpages[number - 1]``. May be a false object, in which case you - should not use any of this objects’ properties. + ``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. @@ -394,18 +400,18 @@ Vim ``segment_info`` argument is a dictionary with the following keys: should be used to convert return values. .. note:: - Your 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 you use ``window_cached`` decorator, - “current tabpage” restriction may be safely ignored if you do not plan to - ever see your segment in the tabline. + 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.2 and will be tested with it until - travis changes used vim version. This means that you may not use most of the - functionality like ``vim.Window.number``, ``vim.*.vars``, ``vim.*.options`` - or even ``dir(vim object)`` if you want your segment to be included in - powerline. + 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 ----- @@ -416,18 +422,22 @@ Shell Currently it is expected to contain at least the following attributes: ``last_exit_code`` - Exit code returned by last shell command. + 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``. + 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. *You must not use this attribute directly*: all + 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: diff --git a/docs/source/installation.rst b/docs/source/installation.rst index c0033c0b..fa8a584b 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -5,8 +5,8 @@ Installation Generic requirements ==================== -* Python 2.6 or later, 3.2 or later, PyPy 2.0 or later. It is the only - non-optional requirement. +* 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 @@ -40,51 +40,55 @@ Generic requirements Pip installation ================ -This project is currently unavailable from PyPI due to a naming conflict with an -unrelated project, thus you will have to use the following command to install -powerline with ``pip``: +Due to a naming conflict with an unrelated project powerline is available on +PyPI under the ``powerline-status`` name: .. code-block:: sh - pip install --user git+git://github.com/Lokaltog/powerline + pip install powerline-status -. You may also choose to clone powerline repository somewhere and use +is the preferred method because this will get the latest release. To get current +development version + +.. code-block:: sh + + pip install --user git+git://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} -, but note that in this case ``pip`` will not install ``powerline`` executable -and you will have to do something like +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 -(:file:`~/.local/bin` should be replaced with some path present in ``$PATH``). +will have to be done (:file:`~/.local/bin` should be replaced with some path +present in ``$PATH``). .. note:: - If your ISP blocks git protocol for some reason github also provides ``ssh`` - (``git+ssh://git@github.com/Lokaltog/powerline``) and ``https`` - (``git+https://github.com/Lokaltog/powerline``) protocols. ``git`` protocol + If ISP blocks git protocol for some reason github also provides ``ssh`` + (``git+ssh://git@github.com/powerline/powerline``) and ``https`` + (``git+https://github.com/powerline/powerline``) protocols. ``git`` protocol should be the fastest, but least secure one though. -To install release version uploaded to PyPI use - -.. code-block:: sh - - pip install powerline-status - Fonts installation ================== Powerline uses several special glyphs to get the arrow effect and some custom -symbols for developers. This requires that you either have a symbol font or -a patched font on your system. Your terminal emulator must also support either -patched fonts or fontconfig for Powerline to work properly. +symbols for developers. This requires having either a symbol font or a patched +font installed in the system. 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. -You can also enable :ref:`24-bit color support ` -if your terminal emulator supports it (see :ref:`the terminal emulator support +:ref:`24-bit color support ` may be enabled if +used terminal emulator supports it (see :ref:`the terminal emulator support matrix `). There are basically two ways to get powerline glyphs displayed: use @@ -99,11 +103,10 @@ Patched fonts This method is the fallback method and works for every terminal, with the exception of :ref:`rxvt-unicode `. -Download the font of your choice from `powerline-fonts`_. If you can’t find -your preferred font in the `powerline-fonts`_ repo, you’ll have to patch your -own font instead. +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/Lokaltog/powerline-fonts +.. _powerline-fonts: https://github.com/powerline/fonts After downloading this font refer to platform-specific instructions. diff --git a/docs/source/installation/linux.rst b/docs/source/installation/linux.rst index 5972c993..aef89508 100644 --- a/docs/source/installation/linux.rst +++ b/docs/source/installation/linux.rst @@ -4,7 +4,7 @@ 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 for you. +automatically do most of the configuration. * `Arch Linux (AUR), Python 2 version `_ * `Arch Linux (AUR), Python 3 version `_ @@ -14,22 +14,33 @@ automatically do most of the configuration for you. `_ to get more information. -If you’re running a distribution without an official package you’ll have to -follow the installation guide below: +If used distribution does not have an official package installation guide below +should be followed: -1. Install Python 3.2+ or Python 2.6+ with ``pip``. This step is - distribution-specific, so no commands provided. -2. Install Powerline using the following command:: +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: - pip install --user git+git://github.com/Lokaltog/powerline + .. code-block:: sh -.. note:: Due to the naming conflict with an unrelated project powerline is - named ``powerline-status`` in PyPI. + pip install --user powerline-status -.. note:: If you are powerline developer you should be aware that ``pip install - --editable`` does not currently fully work. If you - install powerline this way you will be missing ``powerline`` executable and - need to symlink it. It will be located in ``scripts/powerline``. + will get the latest release version and + + .. code-block:: sh + + pip install --user git+git://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 ================== @@ -37,22 +48,22 @@ Fonts installation Fontconfig ---------- -This method only works on Linux. It’s the recommended method if your -terminal emulator supports it as you don’t have to patch any fonts, and it -generally works well with any coding font. +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/Lokaltog/powerline/raw/develop/font/PowerlineSymbols.otf - wget https://github.com/Lokaltog/powerline/raw/develop/font/10-powerline-symbols.conf + 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 ~/.fonts/ -#. Update font cache for the path you moved the font to (you may need to be - root to update the cache for system-wide paths):: +#. Update font cache for the path the font was moved to (root priveleges may be + needed to update cache for the system-wide paths):: fc-cache -vf ~/.fonts/ @@ -62,37 +73,38 @@ generally works well with any coding font. mv 10-powerline-symbols.conf ~/.config/fontconfig/conf.d/ -If you can’t see the custom symbols, please close all instances of your -terminal emulator. You may need to restart X for the changes to take -effect. +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 you *still* can’t see the custom symbols, double-check that you have -installed the font to a valid X font path, and that you have installed the -fontconfig file to a valid fontconfig path. Alternatively try to install -a :ref:`patched font `. +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 +`. Patched font installation ------------------------- -After downloading font you should do the following: +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 'MyFont for Powerline.otf' ~/.fonts/ + mv 'SomeFont for Powerline.otf' ~/.fonts/ -#. Update font cache for the path you moved the font to (you may need to be - root to update the cache for system-wide paths):: +#. Update font cache for the path the font was moved to (root priveleges may be + needed for updating font cache for some paths):: fc-cache -vf ~/.fonts/ -After installing the patched font you need to update Gvim or your terminal -emulator to use the patched font. The correct font usually ends with *for -Powerline*. +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 you can’t see the custom symbols, please close all instances of your -terminal emulator. You may need to restart X for the changes to take -effect. +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 you *still* can’t see the custom symbols, double-check that you have -installed the font to a valid X font path. +If custom symbols *still* can’t be seen then double-check that the font have +been installed to a valid X font path. diff --git a/docs/source/installation/osx.rst b/docs/source/installation/osx.rst index 3483f60e..99e19494 100644 --- a/docs/source/installation/osx.rst +++ b/docs/source/installation/osx.rst @@ -6,25 +6,35 @@ Python package ============== 1. Install a proper Python version (see `issue #39 - `_ for a discussion + `_ for a discussion regarding the required Python version on OS X):: sudo port select python python27-apple - . You may use homebrew for this:: + . Homebrew may be used here:: brew install python . .. note:: - In case you want or have to use ``powerline.sh`` socat-based client you - should also install GNU env named ``genv``. This may be achieved by - running ``brew install coreutils``. + In case :file:`powerline.sh` as a client ``socat`` and ``coreutils`` need + to be installed. ``coreutils`` may be installed using ``brew install + coreutils``. -2. Install Powerline using the following command:: +2. Install Powerline using one of the following commans: - pip install --user git+git://github.com/Lokaltog/powerline + .. code-block:: sh + + pip install --user powerline-status + + will get current release version and + + .. code-block:: sh + + pip install --user git+git://github.com/powerline/powerline + + will get latest development version. .. warning:: When using ``brew install`` to install Python one must not supply @@ -35,16 +45,16 @@ Python package ``powerline-status`` in PyPI. .. note:: - If you are powerline developer you should be aware that ``pip install - --editable`` does not currently fully work. If you install powerline this - way you will be missing ``powerline`` executable and need to symlink it. It - will be located in ``scripts/powerline``. + 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 if you’re using MacVim you need to install it using the following command:: +but MacVim users need to install it using the following command:: brew install macvim --env-std --override-system-vim @@ -54,6 +64,6 @@ Fonts installation Install downloaded patched font by double-clicking the font file in Finder, then clicking :guilabel:`Install this font` in the preview window. -After installing the patched font you need to update MacVim or your terminal -emulator to use the patched font. The correct font usually ends with *for -Powerline*. +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*. diff --git a/docs/source/license-and-credits.rst b/docs/source/license-and-credits.rst index 5c02b2a5..5226669a 100644 --- a/docs/source/license-and-credits.rst +++ b/docs/source/license-and-credits.rst @@ -3,7 +3,7 @@ License and credits ******************* Powerline is licensed under the `MIT license -`_. +`_. .. This document is parsed by powerline_automan.py module. Do not forget to @@ -24,7 +24,7 @@ Contributors ------------ * `List of contributors - `_ + `_ * The glyphs in the font patcher are created by Fabrizio Schiavi, creator of the excellent coding font `Pragmata Pro`_. diff --git a/docs/source/powerline_automan.py b/docs/source/powerline_automan.py index 43f592e9..b4e1a14f 100644 --- a/docs/source/powerline_automan.py +++ b/docs/source/powerline_automan.py @@ -91,6 +91,10 @@ class AutoManGroup(object): 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=']'): @@ -361,7 +365,7 @@ class AutoMan(Directive): ), ids=['author-section'] ) - issues_url = 'https://github.com/Lokaltog/powerline/issues' + issues_url = 'https://github.com/powerline/powerline/issues' reporting_bugs_section = nodes.section( '', nodes.title(text='Reporting bugs'), nodes.paragraph( diff --git a/docs/source/troubleshooting.rst b/docs/source/troubleshooting.rst index 9cf5e923..86aeadbc 100644 --- a/docs/source/troubleshooting.rst +++ b/docs/source/troubleshooting.rst @@ -24,9 +24,9 @@ two possible explanations: * Update brought some bug to powerline. In the second case you, of course, should report the bug to `powerline bug -tracker `_. 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 +tracker `_. 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 diff --git a/docs/source/troubleshooting/linux.rst b/docs/source/troubleshooting/linux.rst index 4fffbd08..e0493c6b 100644 --- a/docs/source/troubleshooting/linux.rst +++ b/docs/source/troubleshooting/linux.rst @@ -38,3 +38,41 @@ 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 +` 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 `_ 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 + + + + + + + Terminus + Symbola + + + +(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. diff --git a/docs/source/troubleshooting/osx.rst b/docs/source/troubleshooting/osx.rst index 3d8363d8..cb7e56b8 100644 --- a/docs/source/troubleshooting/osx.rst +++ b/docs/source/troubleshooting/osx.rst @@ -57,7 +57,7 @@ I receive an ``ImportError`` when trying to use Powerline on OS X! sudo port select python python27-apple -* See `issue #39 `_ for +* See `issue #39 `_ for a discussion and other possible solutions for this issue. I receive “FSEventStreamStart: register_with_server: ERROR” with status_colors diff --git a/docs/source/usage.rst b/docs/source/usage.rst index a5301c92..5605c891 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -8,16 +8,15 @@ Application-specific requirements Vim plugin requirements ^^^^^^^^^^^^^^^^^^^^^^^ -The vim plugin requires a vim version with Python support compiled in. You -can check if your vim supports Python by running ``vim --version | grep +The vim plugin requires a vim version with Python support compiled in. Presense +of Python support in Vim can be checked by running ``vim --version | grep +python``. -If your vim version doesn’t have support for Python, you’ll have to compile -it with the ``--enable-pythoninterp`` flag (``--enable-python3interp`` if -you want Python 3 support instead). Note that this also requires the related -Python headers to be installed on your system. Please consult your -distribution’s documentation for details on how to compile and install -packages. +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 is known to work on vim-7.0.112 (some segments may not work though as it was not @@ -28,13 +27,13 @@ actually tested). Terminal emulator requirements ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Powerline uses several special glyphs to get the arrow effect and some -custom symbols for developers. This requires that you either have a symbol -font or a patched font on your system. Your terminal emulator must also -support either patched fonts or fontconfig for Powerline to work properly. +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. -You can also enable :ref:`24-bit color support ` -if your terminal emulator supports it. +:ref:`24-bit color support ` can also be enabled +if terminal emulator supports it. .. table:: Application/terminal emulator feature support matrix :name: term-feature-support-matrix @@ -52,6 +51,7 @@ if your terminal emulator supports it. 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 diff --git a/docs/source/usage/other.rst b/docs/source/usage/other.rst index befd9a06..cbdab712 100644 --- a/docs/source/usage/other.rst +++ b/docs/source/usage/other.rst @@ -15,32 +15,35 @@ If installed using pip just add python powerline_setup() python del powerline_setup -(replace ``python`` with ``python3`` if appropriate) to your :file:`vimrc`. +(replace ``python`` with ``python3`` if appropriate) to the :file:`vimrc`. -If you just cloned the repository add the following line to your :file:`vimrc`, -where ``{repository_root}`` is the absolute path to your Powerline installation -directory: +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 -If you’re using pathogen and don’t want Powerline functionality in any other -applications, simply add Powerline as a bundle and point the path above to the -Powerline bundle directory, e.g. -``~/.vim/bundle/powerline/powerline/bindings/vim``. +where ``{repository_root}`` is the absolute path to the Powerline installation +directory. -With Vundle you may instead use +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 'Lokaltog/powerline', {'rtp': 'powerline/bindings/vim/'} + Bundle 'powerline/powerline', {'rtp': 'powerline/bindings/vim/'} -(replace ``Bundle`` with ``NeoBundle`` for NeoBundle). +(NeoBundle users need ``NeoBundle`` in place of ``Bundle``, otherwise setup is +the same). -For vim-addon-manager it is even easier since you don’t need to write this big -path or install anything by hand: ``powerline`` is installed and run just like -any other plugin using +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 @@ -48,17 +51,16 @@ any other plugin using .. warning:: *Never* install powerline with pathogen/VAM/Vundle/NeoBundle *and* with pip. - If you want powerline functionality in vim and other applications use - system-wide installation if your system has powerline package, pip-only or - ``pip install --editable`` kind of installation performed on the repository - installed by Vim plugin manager. + 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. - If you have installed powerline with pip and with some of Vim package - managers do never report any errors to powerline bug tracker, especially - errors occurring after updates. + No issues are accepted in powerline issue tracker for double pip/non-pip + installations, especially if these issues occur after update. .. note:: - If you use supplied :file:`powerline.vim` file to load powerline there are + 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, @@ -66,32 +68,32 @@ any other plugin using 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 you must also set ``g:powerline_pyeval``. Powerline will not - check that Vim is compiled with Python support if you set - ``g:powerline_pycmd`` to an unexpected value. + 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 you have both versions: Vim may disable loading one python version if - other was already loaded. They should also be used if you have two python - versions able to load simultaneously, but with powerline installed only for + 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 your :file:`.tmux.conf`, where ``{repository_root}`` -is the absolute path to your Powerline installation directory:: +Add the following lines to :file:`.tmux.conf`, where ``{repository_root}`` is +the absolute path to the Powerline installation directory:: source "{repository_root}/powerline/bindings/tmux/powerline.conf" .. note:: The availability of the ``powerline-config`` command is required for - powerline support. You may specify location of this script via + powerline support. DLlocation of this script may be specified via ``$POWERLINE_CONFIG_COMMAND`` environment variable. .. note:: - It is advised that you run ``powerline-daemon`` before adding the above line - to tmux.conf. To do so add:: + It is advised to run ``powerline-daemon`` before adding the above line to + tmux.conf. To do so add:: run-shell "powerline-daemon -q" @@ -100,18 +102,21 @@ is the absolute path to your Powerline installation directory:: IPython prompt ============== -For IPython<0.11 add the following lines to your -:file:`.ipython/ipy_user_conf.py`:: +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 you launched ipython without configuration to + # main() function (assuming ipython was launched without configuration to # create skeleton ipy_user_conf.py file): powerline_setup() -For IPython>=0.11 add the following line to your :file:`ipython_config.py` -file in the profile you are using:: +For IPython>=0.11 add the following line to :file:`ipython_config.py` file in +the used profile: + +.. code-block:: Python c.InteractiveShellApp.extensions = [ 'powerline.bindings.ipython.post_0_11' diff --git a/docs/source/usage/shell-prompts.rst b/docs/source/usage/shell-prompts.rst index 75fe7a3e..f10beedd 100644 --- a/docs/source/usage/shell-prompts.rst +++ b/docs/source/usage/shell-prompts.rst @@ -4,19 +4,19 @@ Shell prompts .. note:: Powerline daemon is not run automatically by any of my bindings. It is - advised that you add + advised to add .. code-block:: bash powerline-daemon -q - before any other powerline-related code in your shell configuration file. + before any other powerline-related code in the shell configuration file. Bash prompt =========== -Add the following line to your :file:`bashrc`, where ``{repository_root}`` is -the absolute path to your Powerline installation directory: +Add the following line to the :file:`bashrc`, where ``{repository_root}`` is the +absolute path to the Powerline installation directory: .. code-block:: bash @@ -34,21 +34,21 @@ the absolute path to your Powerline installation directory: POWERLINE_BASH_SELECT=1 . {repository_root}/powerline/bindings/bash/powerline.sh - in your bash configuration file. Without ``POWERLINE_BASH_*`` variables PS2 + 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. Do not expect it to work properly if you - e.g. put current time there. + 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 your :file:`zshrc`, where ``{repository_root}`` is the -absolute path to your Powerline installation directory: +Add the following line to the :file:`zshrc`, where ``{repository_root}`` is the +absolute path to the Powerline installation directory: .. code-block:: bash @@ -57,15 +57,34 @@ absolute path to your Powerline installation directory: Fish prompt =========== -Add the following line to your :file:`config.fish`, where ``{repository_root}`` -is the absolute path to your Powerline installation directory: +Add the following line to :file:`config.fish`, where ``{repository_root}`` is +the absolute path to the Powerline installation directory: .. code-block:: bash set fish_function_path $fish_function_path "{repository_root}/powerline/bindings/fish" powerline-setup -.. _tmux-statusline: +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 + +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 ===================================== diff --git a/docs/source/usage/wm-widgets.rst b/docs/source/usage/wm-widgets.rst index 5383a2fd..0a734ea7 100644 --- a/docs/source/usage/wm-widgets.rst +++ b/docs/source/usage/wm-widgets.rst @@ -10,15 +10,15 @@ Awesome widget .. 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 your :file:`rc.lua`, where ``{repository_root}`` is the -absolute path to your Powerline installation directory: +Add the following to :file:`rc.lua`, where ``{repository_root}`` is the absolute +path to Powerline installation directory: .. code-block:: lua package.path = package.path .. ';{repository_root}/powerline/bindings/awesome/?.lua' require('powerline') -Then add the ``powerline_widget`` to your ``wibox``: +Then add the ``powerline_widget`` to ``wibox``: .. code-block:: lua @@ -27,7 +27,7 @@ Then add the ``powerline_widget`` to your ``wibox``: Qtile widget ============ -Add the following to your :file:`~/.config/qtile/config.py`: +Add the following to :file:`~/.config/qtile/config.py`: .. code-block:: python @@ -47,11 +47,12 @@ Add the following to your :file:`~/.config/qtile/config.py`: I3 bar ====== -.. note:: Until the patch is done in i3, you will need a custom ``i3bar`` build - called ``i3bgbar``. The source is available `here - `_. +.. note:: + Until the patch is done in i3 a custom ``i3bar`` build called ``i3bgbar`` is + needed. The source is available `in S0lll0s/i3bgbar github repository + `_. -Add the following to your :file:`~/.i3/config`:: +Add the following to :file:`~/.i3/config`:: bar { i3bar_command i3bgbar diff --git a/powerline/__init__.py b/powerline/__init__.py index 026231b9..9d2bb689 100644 --- a/powerline/__init__.py +++ b/powerline/__init__.py @@ -11,8 +11,9 @@ from powerline.colorscheme import Colorscheme from powerline.lib.config import ConfigLoader from powerline.lib.unicode import safe_unicode, FailedUnicode from powerline.config import DEFAULT_SYSTEM_CONFIG_DIR -from powerline.lib import mergedicts +from powerline.lib.dict import mergedicts from powerline.lib.encoding import get_preferred_output_encoding +from powerline.lib.path import join class NotInterceptedError(BaseException): @@ -29,7 +30,7 @@ def _find_config_files(search_paths, config_file, config_loader=None, loader_cal config_file += '.json' found = False for path in search_paths: - config_file_path = os.path.join(path, config_file) + config_file_path = join(path, config_file) if os.path.isfile(config_file_path): yield config_file_path found = True @@ -142,12 +143,12 @@ def get_config_paths(): :return: list of paths ''' config_home = os.environ.get('XDG_CONFIG_HOME', os.path.join(os.path.expanduser('~'), '.config')) - config_path = os.path.join(config_home, 'powerline') + 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([os.path.join(d, 'powerline') for d in config_dirs.split(':')]) - plugin_path = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'config_files') + 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 @@ -258,6 +259,7 @@ def finish_common_config(encoding, common_config): 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) @@ -423,6 +425,14 @@ class Powerline(object): 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 create_logger(self.common_config, 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 @@ -460,7 +470,7 @@ class Powerline(object): self.import_paths = self.common_config['paths'] if not self.logger: - self.logger = create_logger(self.common_config, self.default_log_stream) + self.logger = self.create_logger() if not self.pl: self.pl = PowerlineLogger(self.use_daemon_threads, self.logger, self.ext) @@ -474,6 +484,7 @@ class Powerline(object): 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', @@ -753,7 +764,10 @@ class Powerline(object): self.exception('Failed to render: {0}', str(e)) except Exception as e: exc = e - return FailedUnicode(safe_unicode(exc)) + 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()`` diff --git a/powerline/bindings/bash/powerline.sh b/powerline/bindings/bash/powerline.sh index cb125a00..8f69546f 100644 --- a/powerline/bindings/bash/powerline.sh +++ b/powerline/bindings/bash/powerline.sh @@ -41,22 +41,22 @@ _powerline_init_tmux_support() { _powerline_local_prompt() { # Arguments: side, renderer_module arg, last_exit_code, jobnum, local theme - $POWERLINE_COMMAND shell $1 \ + "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \ $2 \ - --last_exit_code=$3 \ + --last-exit-code=$3 \ --jobnum=$4 \ - --renderer_arg="client_id=$$" \ - --renderer_arg="local_theme=$5" + --renderer-arg="client_id=$$" \ + --renderer-arg="local_theme=$5" } _powerline_prompt() { # Arguments: side, last_exit_code, jobnum - $POWERLINE_COMMAND shell $1 \ + "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \ --width="${COLUMNS:-$(_powerline_columns_fallback)}" \ -r.bash \ - --last_exit_code=$2 \ + --last-exit-code=$2 \ --jobnum=$3 \ - --renderer_arg="client_id=$$" + --renderer-arg="client_id=$$" } _powerline_set_prompt() { @@ -75,7 +75,7 @@ _powerline_set_prompt() { _powerline_setup_prompt() { VIRTUAL_ENV_DISABLE_PROMPT=1 if test -z "${POWERLINE_COMMAND}" ; then - POWERLINE_COMMAND="$("$POWERLINE_CONFIG" shell command)" + POWERLINE_COMMAND="$("$POWERLINE_CONFIG_COMMAND" shell command)" fi test "x$PROMPT_COMMAND" != "x${PROMPT_COMMAND%_powerline_set_prompt*}" || PROMPT_COMMAND=$'_powerline_set_prompt\n'"${PROMPT_COMMAND}" @@ -83,17 +83,17 @@ _powerline_setup_prompt() { PS3="$(_powerline_local_prompt left '' 0 0 select)" } -if test -z "${POWERLINE_CONFIG}" ; then +if test -z "${POWERLINE_CONFIG_COMMAND}" ; then if which powerline-config >/dev/null ; then - POWERLINE_CONFIG=powerline-config + POWERLINE_CONFIG_COMMAND=powerline-config else - POWERLINE_CONFIG="$(dirname "$BASH_SOURCE")/../../../scripts/powerline-config" + POWERLINE_CONFIG_COMMAND="$(dirname "$BASH_SOURCE")/../../../scripts/powerline-config" fi fi -if "${POWERLINE_CONFIG}" shell --shell=bash uses prompt ; then +if "${POWERLINE_CONFIG_COMMAND}" shell --shell=bash uses prompt ; then _powerline_setup_prompt fi -if "${POWERLINE_CONFIG}" shell --shell=bash uses tmux ; then +if "${POWERLINE_CONFIG_COMMAND}" shell --shell=bash uses tmux ; then _powerline_init_tmux_support fi diff --git a/powerline/bindings/config.py b/powerline/bindings/config.py index ea961d38..ac1ab52c 100644 --- a/powerline/bindings/config.py +++ b/powerline/bindings/config.py @@ -8,11 +8,12 @@ import sys 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, PowerlineLogger, finish_common_config -from powerline.tmux import TmuxPowerline +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 from powerline.lib.encoding import get_preferred_output_encoding -from powerline.renderers.tmux import attr_to_tmux_attr +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\d+)\.(?P\d+)(?P[a-z]+)?(?:_(?Pplus|minus))?\.conf') @@ -77,10 +78,19 @@ def source_tmux_files(pl, args): run_tmux_command('refresh-client') -def init_environment(pl, args): +class EmptyArgs(object): + def __init__(self, ext, config_path): + self.ext = [ext] + self.config_path = None + + def __getattr__(self, attr): + return None + + +def init_tmux_environment(pl, args): '''Initialize tmux environment from tmux configuration ''' - powerline = TmuxPowerline(args.config_path) + powerline = ShellPowerline(finish_args(os.environ, EmptyArgs('tmux', args.config_path))) # TODO Move configuration files loading out of Powerline object and use it # directly powerline.update_renderer() @@ -116,29 +126,34 @@ def init_environment(pl, args): powerline.renderer.hlstyle( fg=prev_highlight['bg'], bg=next_highlight['bg'], - attr=0, + 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', 'attr', 'activity_status'), + ('_POWERLINE_ACTIVITY_STATUS_ATTR', 'attrs', 'activity_status'), ('_POWERLINE_BELL_STATUS_FG', 'fg', 'bell_status'), - ('_POWERLINE_BELL_STATUS_ATTR', 'attr', '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', 'attr', 'session'), + ('_POWERLINE_SESSION_ATTR', 'attrs', 'session'), ('_POWERLINE_SESSION_PREFIX_FG', 'fg', 'session:prefix'), ('_POWERLINE_SESSION_PREFIX_BG', 'bg', 'session:prefix'), - ('_POWERLINE_SESSION_PREFIX_ATTR', 'attr', 'session:prefix'), + ('_POWERLINE_SESSION_PREFIX_ATTR', 'attrs', 'session:prefix'), ): - if attr == 'attr': - attrs = attr_to_tmux_attr(get_highlighting(group)[attr]) + if attr == 'attrs': + attrs = attrs_to_tmux_attrs(get_highlighting(group)[attr]) set_tmux_environment(varname, ']#['.join(attrs)) - set_tmux_environment(varname + '_LEGACY', ','.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: set_tmux_environment(varname, 'colour' + str(get_highlighting(group)[attr][0])) @@ -149,6 +164,11 @@ def init_environment(pl, args): ' ' * powerline.renderer.strwidth(left_dividers['hard']))) +def tmux_setup(pl, args): + init_tmux_environment(pl, args) + source_tmux_files(pl, args) + + def get_main_config(args): find_config_files = generate_config_finder() config_loader = ConfigLoader(run_once=True) diff --git a/powerline/bindings/fish/powerline-setup.fish b/powerline/bindings/fish/powerline-setup.fish index fad70f7b..dc631c5e 100644 --- a/powerline/bindings/fish/powerline-setup.fish +++ b/powerline/bindings/fish/powerline-setup.fish @@ -21,36 +21,35 @@ function powerline-setup end end - if test -z "$POWERLINE_CONFIG" + if test -z "$POWERLINE_CONFIG_COMMAND" if which powerline-config >/dev/null - set -g POWERLINE_CONFIG powerline-config + set -g POWERLINE_CONFIG_COMMAND powerline-config else - set -g POWERLINE_CONFIG (dirname (status -f))/../../../scripts/powerline-config + set -g POWERLINE_CONFIG_COMMAND (dirname (status -f))/../../../scripts/powerline-config end end - if eval $POWERLINE_CONFIG shell --shell=fish uses prompt + if env $POWERLINE_CONFIG_COMMAND shell --shell=fish uses prompt if test -z "$POWERLINE_COMMAND" - set -g POWERLINE_COMMAND (eval $POWERLINE_CONFIG shell command) - end - function --on-variable fish_bind_mode _powerline_bind_mode - set -g -x _POWERLINE_MODE $fish_bind_mode + set -g POWERLINE_COMMAND (env $POWERLINE_CONFIG_COMMAND shell command) end function --on-variable fish_key_bindings _powerline_set_default_mode if test x$fish_key_bindings != xfish_vi_key_bindings - set -g -x _POWERLINE_DEFAULT_MODE default + set -g _POWERLINE_DEFAULT_MODE default else set -g -e _POWERLINE_DEFAULT_MODE end end function --on-variable POWERLINE_COMMAND _powerline_update - set -l addargs "--last_exit_code=\$status" - set -l addargs "$addargs --last_pipe_status=\$status" + 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 --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 @@ -65,10 +64,10 @@ function powerline-setup end eval " function fish_prompt - $POWERLINE_COMMAND shell $promptside $addargs + env \$POWERLINE_COMMAND $POWERLINE_COMMAND_ARGS shell $promptside $addargs end function fish_right_prompt - $POWERLINE_COMMAND shell right $addargs + env \$POWERLINE_COMMAND $POWERLINE_COMMAND_ARGS shell right $addargs $rpromptpast end function --on-signal WINCH _powerline_set_columns @@ -81,7 +80,7 @@ function powerline-setup _powerline_set_default_mode _powerline_update end - if eval $POWERLINE_CONFIG shell --shell=fish uses tmux + if env $POWERLINE_CONFIG_COMMAND shell --shell=fish uses tmux if test -n "$TMUX" if tmux refresh -S ^/dev/null function _powerline_tmux_setenv diff --git a/powerline/bindings/ipython/post_0_11.py b/powerline/bindings/ipython/post_0_11.py index bf2358ac..3d8aea0d 100644 --- a/powerline/bindings/ipython/post_0_11.py +++ b/powerline/bindings/ipython/post_0_11.py @@ -72,7 +72,7 @@ class ConfigurableIPythonPowerline(IPythonPowerline): config = ip.config.Powerline self.config_overrides = config.get('config_overrides') self.theme_overrides = config.get('theme_overrides', {}) - self.paths = config.get('paths') + self.config_paths = config.get('config_paths') super(ConfigurableIPythonPowerline, self).init() def do_setup(self, ip, shutdown_hook): diff --git a/powerline/bindings/ipython/pre_0_11.py b/powerline/bindings/ipython/pre_0_11.py index 6e5e356d..fa34cd86 100644 --- a/powerline/bindings/ipython/pre_0_11.py +++ b/powerline/bindings/ipython/pre_0_11.py @@ -95,10 +95,10 @@ class PowerlinePrompt2(PowerlinePromptOut): class ConfigurableIPythonPowerline(IPythonPowerline): - def init(self, config_overrides=None, theme_overrides={}, paths=None): + def init(self, config_overrides=None, theme_overrides={}, config_paths=None): self.config_overrides = config_overrides self.theme_overrides = theme_overrides - self.paths = paths + self.config_paths = config_paths super(ConfigurableIPythonPowerline, self).init() def ipython_magic(self, ip, parameter_s=''): diff --git a/powerline/bindings/rc/powerline.rc b/powerline/bindings/rc/powerline.rc new file mode 100644 index 00000000..732d40c8 --- /dev/null +++ b/powerline/bindings/rc/powerline.rc @@ -0,0 +1,84 @@ +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.rcsh --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_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 x$POWERLINE_CONFIG_COMMAND '!=' x) { + if ($POWERLINE_CONFIG_COMMAND shell --shell rcsh uses prompt) { + if (test x$POWERLINE_COMMAND_ARGS '!=' x) { + # 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 x$TMUX '!=' x) { + if ($POWERLINE_CONFIG_COMMAND shell --shell rcsh uses tmux) { + _POWERLINE_TMUX=$TMUX + fn _powerline_tmux_setenv { + if (test x$2 '!=' x) { + TMUX=$_POWERLINE_TMUX tmux setenv -g TMUX_$1^_`{ + TMUX=$_POWERLINE_TMUX tmux display -p '#D' | tr -d % + } $2 + } + } + _powerline_common_setup + } + } +} +# vim: ft=rcshell diff --git a/powerline/bindings/shell/powerline.sh b/powerline/bindings/shell/powerline.sh index 8940c028..7ae7237f 100644 --- a/powerline/bindings/shell/powerline.sh +++ b/powerline/bindings/shell/powerline.sh @@ -100,7 +100,7 @@ _powerline_set_set_jobs() { _powerline_set_command() { if test -z "${POWERLINE_COMMAND}" ; then - POWERLINE_COMMAND="$("$POWERLINE_CONFIG" shell command)" + POWERLINE_COMMAND="$("$POWERLINE_CONFIG_COMMAND" shell command)" fi } @@ -136,22 +136,22 @@ _powerline_set_jobs() { _powerline_local_prompt() { # Arguments: side, exit_code, local theme _powerline_set_jobs - $POWERLINE_COMMAND shell $1 \ + "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \ $_POWERLINE_RENDERER_ARG \ - --renderer_arg="client_id=$$" \ - --last_exit_code=$2 \ + --renderer-arg="client_id=$$" \ + --last-exit-code=$2 \ --jobnum=$_POWERLINE_JOBS \ - --renderer_arg="local_theme=$3" + --renderer-arg="local_theme=$3" } _powerline_prompt() { # Arguments: side, exit_code _powerline_set_jobs - $POWERLINE_COMMAND shell $1 \ + "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS shell $1 \ --width="${COLUMNS:-$(_powerline_columns_fallback)}" \ $_POWERLINE_RENDERER_ARG \ - --renderer_arg="client_id=$$" \ - --last_exit_code=$2 \ + --renderer-arg="client_id=$$" \ + --last-exit-code=$2 \ --jobnum=$_POWERLINE_JOBS _powerline_update_psN } @@ -214,11 +214,11 @@ _powerline_init_tmux_support() { fi } -if test -z "${POWERLINE_CONFIG}" ; then +if test -z "${POWERLINE_CONFIG_COMMAND}" ; then if which powerline-config >/dev/null ; then - POWERLINE_CONFIG=powerline-config + POWERLINE_CONFIG_COMMAND=powerline-config else - POWERLINE_CONFIG="$(dirname "$_POWERLINE_SOURCED")/../../../scripts/powerline-config" + POWERLINE_CONFIG_COMMAND="$(dirname "$_POWERLINE_SOURCED")/../../../scripts/powerline-config" fi fi @@ -227,9 +227,9 @@ _POWERLINE_USED_SHELL=${0#-} _POWERLINE_USED_SHELL=${_POWERLINE_USED_SHELL#/usr} _POWERLINE_USED_SHELL=${_POWERLINE_USED_SHELL#/bin/} -if "${POWERLINE_CONFIG}" shell uses tmux ; then +if "${POWERLINE_CONFIG_COMMAND}" shell uses tmux ; then _powerline_init_tmux_support $_POWERLINE_USED_SHELL fi -if "${POWERLINE_CONFIG}" shell --shell=bash uses prompt ; then +if "${POWERLINE_CONFIG_COMMAND}" shell --shell=bash uses prompt ; then _powerline_setup_prompt $_POWERLINE_USED_SHELL fi diff --git a/powerline/bindings/tcsh/powerline.tcsh b/powerline/bindings/tcsh/powerline.tcsh index fafdb39b..502e95e3 100644 --- a/powerline/bindings/tcsh/powerline.tcsh +++ b/powerline/bindings/tcsh/powerline.tcsh @@ -5,42 +5,45 @@ # 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 then +if ! $?POWERLINE_CONFIG_COMMAND then if ( { which powerline-config > /dev/null } ) then - set POWERLINE_CONFIG="powerline-config" + set POWERLINE_CONFIG_COMMAND="powerline-config" else - set POWERLINE_CONFIG="$POWERLINE_SOURCED[2]:h:h:h:h/scripts/powerline-config" + set POWERLINE_CONFIG_COMMAND="$POWERLINE_SOURCED[2]:h:h:h:h/scripts/powerline-config" endif else - if "$POWERLINE_CONFIG" == "" then + if "$POWERLINE_CONFIG_COMMAND" == "" then if ( { which powerline-config > /dev/null } ) then - set POWERLINE_CONFIG="powerline-config" + set POWERLINE_CONFIG_COMMAND="powerline-config" else - set POWERLINE_CONFIG="$POWERLINE_SOURCED[2]:h:h:h:h/scripts/powerline-config" + set POWERLINE_CONFIG_COMMAND="$POWERLINE_SOURCED[2]:h:h:h:h/scripts/powerline-config" endif endif endif -if ( { $POWERLINE_CONFIG shell --shell=tcsh uses tmux } ) then +if ( { $POWERLINE_CONFIG_COMMAND shell --shell=tcsh uses tmux } ) then alias _powerline_tmux_set_pwd 'if ( $?TMUX && { tmux refresh -S >&/dev/null } ) tmux setenv -g TMUX_PWD_`tmux display -p "#D" | tr -d %` $PWD:q ; if ( $?TMUX ) tmux refresh -S >&/dev/null' alias cwdcmd "`alias cwdcmd` ; _powerline_tmux_set_pwd" endif -if ( { $POWERLINE_CONFIG shell --shell=tcsh uses prompt } ) then +if ( { $POWERLINE_CONFIG_COMMAND shell --shell=tcsh uses prompt } ) then if ! $?POWERLINE_COMMAND then - set POWERLINE_COMMAND="`$POWERLINE_CONFIG:q shell command`" + set POWERLINE_COMMAND="`$POWERLINE_CONFIG_COMMAND:q shell command`" else if "$POWERLINE_COMMAND" == "" then - set POWERLINE_COMMAND="`$POWERLINE_CONFIG:q shell command`" + 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 shell above --renderer_arg=client_id=$$ --last_exit_code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS' + 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 shell left -r .tcsh --renderer_arg=client_id=$$ --last_exit_code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS`"' - alias _powerline_set_rprompt 'set rprompt="`$POWERLINE_COMMAND shell right -r .tcsh --renderer_arg=client_id=$$ --last_exit_code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS` "' + 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' diff --git a/powerline/bindings/tmux/powerline-base.conf b/powerline/bindings/tmux/powerline-base.conf index 38b5de60..cc0eedc8 100644 --- a/powerline/bindings/tmux/powerline-base.conf +++ b/powerline/bindings/tmux/powerline-base.conf @@ -2,7 +2,7 @@ set -g status on set -g status-utf8 on set -g status-interval 2 set -g status-left-length 20 -set -g status-right '#(eval $POWERLINE_COMMAND tmux right -R pane_id=`tmux display -p "#D"`)' +set -g status-right '#(env "$POWERLINE_COMMAND" $POWERLINE_COMMAND_ARGS tmux right -R pane_id=`tmux display -p "#D"`)' set -g status-right-length 150 set -g window-status-format "#[$_POWERLINE_WINDOW_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER_SPACES#I #[$_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 $_POWERLINE_LEFT_SOFT_DIVIDER#[$_POWERLINE_WINDOW_NAME_COLOR]#W #[$_POWERLINE_WINDOW_CURRENT_HARD_DIVIDER_NEXT_COLOR]$_POWERLINE_LEFT_HARD_DIVIDER" diff --git a/powerline/bindings/tmux/powerline.conf b/powerline/bindings/tmux/powerline.conf index 8eb11dab..7ea407a5 100644 --- a/powerline/bindings/tmux/powerline.conf +++ b/powerline/bindings/tmux/powerline.conf @@ -1,9 +1,2 @@ -if-shell 'test -z "$POWERLINE_CONFIG_COMMAND"' 'set-environment -g POWERLINE_CONFIG_COMMAND powerline-config' - -run-shell 'eval $POWERLINE_CONFIG_COMMAND tmux setenv' - -# Simplify tmux version checking by using multiple config files. Source these -# config files based on the version in which tmux features were added and/or -# deprecated. By splitting these configuration options into separate files, -run-shell 'eval $POWERLINE_CONFIG_COMMAND tmux source' +if-shell 'test -z "$POWERLINE_CONFIG_COMMAND"' 'set-environment -g POWERLINE_CONFIG_COMMAND powerline-config; run-shell "env \"\$POWERLINE_CONFIG_COMMAND\" tmux setup"' 'run-shell "env \"\$POWERLINE_CONFIG_COMMAND\" tmux setup"' # vim: ft=tmux diff --git a/powerline/bindings/tmux/powerline_tmux_1.8_plus.conf b/powerline/bindings/tmux/powerline_tmux_1.8_plus.conf index d3e1e153..7d694e8a 100644 --- a/powerline/bindings/tmux/powerline_tmux_1.8_plus.conf +++ b/powerline/bindings/tmux/powerline_tmux_1.8_plus.conf @@ -1,5 +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#(eval \$POWERLINE_COMMAND tmux left)" +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)" # vim: ft=tmux diff --git a/powerline/bindings/vim/__init__.py b/powerline/bindings/vim/__init__.py index 6c2e4527..e617943a 100644 --- a/powerline/bindings/vim/__init__.py +++ b/powerline/bindings/vim/__init__.py @@ -12,10 +12,36 @@ except ImportError: from powerline.lib.unicode import unicode -try: - vim_encoding = vim.eval('&encoding') -except AttributeError: - vim_encoding = 'utf-8' +if ( + hasattr(vim, 'options') + and hasattr(vim, 'vvars') + and vim.vvars['version'] > 703 +): + if sys.version_info < (3,): + def get_vim_encoding(): + return vim.options['encoding'] or 'ascii' + else: + def get_vim_encoding(): + return vim.options['encoding'].decode('ascii') or 'ascii' +elif hasattr(vim, 'eval'): + def get_vim_encoding(): + return vim.eval('&encoding') or 'ascii' +else: + def get_vim_encoding(): + return 'utf-8' + +get_vim_encoding.__doc__ = ( + '''Get encoding used for Vim strings + + :return: + Value of ``&encoding``. If it is empty (i.e. Vim is compiled + without +multibyte) returns ``'ascii'``. When building documentation + outputs ``'utf-8'`` unconditionally. + ''' +) + + +vim_encoding = get_vim_encoding() python_to_vim_types = { @@ -24,6 +50,11 @@ python_to_vim_types = { ord('\''): '\'\'', }).encode(vim_encoding)) + b'\'' ), + list: ( + lambda o: b'[' + ( + b','.join((python_to_vim(i) for i in o)) + ) + b']' + ), bytes: (lambda o: b'\'' + o.replace(b'\'', b'\'\'') + b'\''), int: (str if str is bytes else (lambda o: unicode(o).encode('ascii'))), } @@ -158,7 +189,7 @@ _vim_exists = vim_get_func('exists', rettype='int') # It may crash on some old vim versions and I do not remember in which patch # I fixed this crash. -if hasattr(vim, 'vvars') and vim.vvars['version'] > 703: +if hasattr(vim, 'vvars') and vim.vvars[str('version')] > 703: _vim_to_python_types = { getattr(vim, 'Dictionary', None) or type(vim.bindeval('{}')): lambda value: dict(( diff --git a/powerline/bindings/zsh/__init__.py b/powerline/bindings/zsh/__init__.py index d982c5b6..291a4c39 100644 --- a/powerline/bindings/zsh/__init__.py +++ b/powerline/bindings/zsh/__init__.py @@ -8,10 +8,11 @@ from weakref import WeakValueDictionary, ref import zsh from powerline.shell import ShellPowerline -from powerline.lib import parsedotval -from powerline.lib.unicode import unicode +from powerline.lib.overrides import parsedotval, parse_override_var +from powerline.lib.unicode import unicode, u from powerline.lib.encoding import (get_preferred_output_encoding, get_preferred_environment_encoding) +from powerline.lib.dict import mergeargs used_powerlines = WeakValueDictionary() @@ -24,7 +25,13 @@ def shutdown(): def get_var_config(var): try: - return [parsedotval(i) for i in zsh.getvalue(var).items()] + val = zsh.getvalue(var) + if isinstance(val, dict): + return mergeargs([parsedotval((u(k), u(v))) for k, v in val.items()]) + elif isinstance(val, (unicode, str, bytes)): + return mergeargs(parse_override_var(u(val))) + else: + return None except: return None @@ -35,18 +42,12 @@ class Args(object): renderer_module = '.zsh' @property - def config(self): - try: - return get_var_config('POWERLINE_CONFIG') - except IndexError: - return None + def config_override(self): + return get_var_config('POWERLINE_CONFIG_OVERRIDES') @property - def theme_option(self): - try: - return get_var_config('POWERLINE_THEME_CONFIG') - except IndexError: - return None + def theme_override(self): + return get_var_config('POWERLINE_THEME_OVERRIDES') @property def config_path(self): @@ -56,7 +57,11 @@ class Args(object): return None else: if isinstance(ret, (unicode, str, bytes)): - return ret.split(type(ret)(':')) + return [ + path + for path in ret.split((b':' if isinstance(ret, bytes) else ':')) + if path + ] else: return ret @@ -96,7 +101,7 @@ class Environment(object): return False -environ = Environment() +environ = getattr(zsh, 'environ', Environment()) class ZshPowerline(ShellPowerline): @@ -132,6 +137,14 @@ class Prompt(object): def __str__(self): zsh.eval('_POWERLINE_PARSER_STATE="${(%):-%_}"') zsh.eval('_POWERLINE_SHORTENED_PATH="${(%):-%~}"') + try: + mode = u(zsh.getvalue('_POWERLINE_MODE')) + except IndexError: + mode = None + try: + default_mode = u(zsh.getvalue('_POWERLINE_DEFAULT_MODE')) + except IndexError: + default_mode = None segment_info = { 'args': self.args, 'environ': environ, @@ -139,6 +152,8 @@ class Prompt(object): 'local_theme': self.theme, 'parser_state': zsh.getvalue('_POWERLINE_PARSER_STATE'), 'shortened_path': zsh.getvalue('_POWERLINE_SHORTENED_PATH'), + 'mode': mode, + 'default_mode': default_mode, } zsh.setvalue('_POWERLINE_PARSER_STATE', None) zsh.setvalue('_POWERLINE_SHORTENED_PATH', None) @@ -157,6 +172,7 @@ class Prompt(object): width=zsh.columns(), side=self.side, segment_info=segment_info, + mode=mode, ) if type(r) is not str: if type(r) is bytes: @@ -189,6 +205,11 @@ def reload(): powerline.reload() +def reload_config(): + for powerline in used_powerlines.values(): + powerline.create_renderer(load_main=True, load_colors=True, load_colorscheme=True, load_theme=True) + + def setup(zsh_globals): powerline = ZshPowerline() powerline.setup(zsh_globals) diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh index f869cccd..02b8431f 100644 --- a/powerline/bindings/zsh/powerline.zsh +++ b/powerline/bindings/zsh/powerline.zsh @@ -60,7 +60,7 @@ _powerline_init_modes_support() { } function -g _powerline_set_true_keymap_name() { - export _POWERLINE_MODE="${1}" + _POWERLINE_MODE="${1}" local plm_bk="$(bindkey -lL ${_POWERLINE_MODE})" if [[ $plm_bk = 'bindkey -A'* ]] ; then _powerline_set_true_keymap_name ${(Q)${${(z)plm_bk}[3]}} @@ -83,7 +83,7 @@ _powerline_init_modes_support() { _powerline_set_main_keymap_name if [[ "$_POWERLINE_MODE" != vi* ]] ; then - export _POWERLINE_DEFAULT_MODE="$_POWERLINE_MODE" + _POWERLINE_DEFAULT_MODE="$_POWERLINE_MODE" fi precmd_functions+=( _powerline_set_main_keymap_name ) @@ -129,28 +129,35 @@ _powerline_setup_prompt() { zpython '_powerline_reload()' zpython 'del _powerline_reload' } + powerline-reload-config() { + zpython 'from powerline.bindings.zsh import reload_config as _powerline_reload_config' + zpython '_powerline_reload_config()' + zpython 'del _powerline_reload_config' + } else if test -z "${POWERLINE_COMMAND}" ; then - POWERLINE_COMMAND="$($POWERLINE_CONFIG shell command)" + POWERLINE_COMMAND="$($POWERLINE_CONFIG_COMMAND shell command)" fi local add_args='-r .zsh' - add_args+=' --last_exit_code=$?' - add_args+=' --last_pipe_status="$pipestatus"' - add_args+=' --renderer_arg="client_id=$$"' - add_args+=' --renderer_arg="shortened_path=${(%):-%~}"' + add_args+=' --last-exit-code=$?' + add_args+=' --last-pipe-status="$pipestatus"' + add_args+=' --renderer-arg="client_id=$$"' + add_args+=' --renderer-arg="shortened_path=${(%):-%~}"' add_args+=' --jobnum=$_POWERLINE_JOBNUM' - local new_args_2=' --renderer_arg="parser_state=${(%%):-%_}"' - new_args_2+=' --renderer_arg="local_theme=continuation"' - local add_args_3=$add_args' --renderer_arg="local_theme=select"' + add_args+=' --renderer-arg="mode=$_POWERLINE_MODE"' + add_args+=' --renderer-arg="default_mode=$_POWERLINE_DEFAULT_MODE"' + local new_args_2=' --renderer-arg="parser_state=${(%%):-%_}"' + new_args_2+=' --renderer-arg="local_theme=continuation"' + local add_args_3=$add_args' --renderer-arg="local_theme=select"' local add_args_2=$add_args$new_args_2 add_args+=' --width=$(( ${COLUMNS:-$(_powerline_columns_fallback)} - ${ZLE_RPROMPT_INDENT:-1} ))' local add_args_r2=$add_args$new_args_2 - PS1='$($=POWERLINE_COMMAND shell aboveleft '$add_args')' - RPS1='$($=POWERLINE_COMMAND shell right '$add_args')' - PS2='$($=POWERLINE_COMMAND shell left '$add_args_2')' - RPS2='$($=POWERLINE_COMMAND shell right '$add_args_r2')' - PS3='$($=POWERLINE_COMMAND shell left '$add_args_3')' + PS1='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell aboveleft '$add_args')' + RPS1='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell right '$add_args')' + PS2='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell left '$add_args_2')' + RPS2='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell right '$add_args_r2')' + PS3='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell left '$add_args_3')' fi } @@ -174,25 +181,25 @@ _powerline_add_widget() { eval "function $save_widget() { emulate -L zsh; $widget \$@ }" eval "${old_widget_command/$widget/$save_widget}" zle -N $widget $function - export _POWERLINE_SAVE_WIDGET="$save_widget" + _POWERLINE_SAVE_WIDGET="$save_widget" fi } -if test -z "${POWERLINE_CONFIG}" ; then +if test -z "${POWERLINE_CONFIG_COMMAND}" ; then if which powerline-config >/dev/null ; then - export POWERLINE_CONFIG=powerline-config + POWERLINE_CONFIG_COMMAND=powerline-config else - export POWERLINE_CONFIG="$_POWERLINE_SOURCED:h:h:h:h/scripts/powerline-config" + POWERLINE_CONFIG_COMMAND="$_POWERLINE_SOURCED:h:h:h:h/scripts/powerline-config" fi fi setopt promptpercent setopt promptsubst -if ${POWERLINE_CONFIG} shell --shell=zsh uses prompt ; then +if "${POWERLINE_CONFIG_COMMAND}" shell --shell=zsh uses prompt ; then _powerline_setup_prompt _powerline_init_modes_support fi -if ${POWERLINE_CONFIG} shell --shell=zsh uses tmux ; then +if "${POWERLINE_CONFIG_COMMAND}" shell --shell=zsh uses tmux ; then _powerline_init_tmux_support fi diff --git a/powerline/colorscheme.py b/powerline/colorscheme.py index 8d718863..66416b55 100644 --- a/powerline/colorscheme.py +++ b/powerline/colorscheme.py @@ -12,16 +12,16 @@ ATTR_ITALIC = 2 ATTR_UNDERLINE = 4 -def get_attr_flag(attributes): +def get_attrs_flag(attrs): '''Convert an attribute array to a renderer flag.''' - attr_flag = 0 - if 'bold' in attributes: - attr_flag |= ATTR_BOLD - if 'italic' in attributes: - attr_flag |= ATTR_ITALIC - if 'underline' in attributes: - attr_flag |= ATTR_UNDERLINE - return attr_flag + attrs_flag = 0 + if 'bold' in attrs: + attrs_flag |= ATTR_BOLD + if 'italic' in attrs: + attrs_flag |= ATTR_ITALIC + if 'underline' in attrs: + attrs_flag |= ATTR_UNDERLINE + return attrs_flag def pick_gradient_value(grad_list, gradient_level): @@ -112,7 +112,7 @@ class Colorscheme(object): return { 'fg': pick_color(group_props['fg']), 'bg': pick_color(group_props['bg']), - 'attr': get_attr_flag(group_props.get('attr', [])), + 'attrs': get_attrs_flag(group_props.get('attrs', [])), } diff --git a/powerline/commands/config.py b/powerline/commands/config.py index 9211b54b..61afb6bc 100644 --- a/powerline/commands/config.py +++ b/powerline/commands/config.py @@ -20,7 +20,8 @@ class StrFunction(object): TMUX_ACTIONS = { 'source': StrFunction(config.source_tmux_files, 'source'), - 'setenv': StrFunction(config.init_environment, 'setenv'), + 'setenv': StrFunction(config.init_tmux_environment, 'setenv'), + 'setup': StrFunction(config.tmux_setup, 'setup'), } @@ -43,7 +44,12 @@ class ConfigArgParser(argparse.ArgumentParser): def get_argparser(ArgumentParser=ConfigArgParser): parser = ArgumentParser(description='Script used to obtain powerline configuration.') - parser.add_argument('-p', '--config_path', action='append', metavar='PATH', help='Path to configuration directory. If it is present then configuration files will only be seeked in the provided path. May be provided multiple times to search in a list of directories.') + parser.add_argument( + '-p', '--config-path', action='append', metavar='PATH', + help='Path to configuration directory. If it is present ' + 'then configuration files will only be seeked in the provided path. ' + 'May be provided multiple times to search in a list of directories.' + ) subparsers = parser.add_subparsers() tmux_parser = subparsers.add_parser('tmux', help='Tmux-specific commands') tmux_parser.add_argument( @@ -51,7 +57,10 @@ def get_argparser(ArgumentParser=ConfigArgParser): choices=tuple(TMUX_ACTIONS.values()), metavar='ACTION', type=(lambda v: TMUX_ACTIONS.get(v)), - help='If action is `source\' then version-specific tmux configuration files are sourced, if it is `setenv\' then special (prefixed with `_POWERLINE\') tmux global environment variables are filled with data from powerline configuration.' + help='If action is `source\' then version-specific tmux configuration ' + 'files are sourced, if it is `setenv\' then special ' + '(prefixed with `_POWERLINE\') tmux global environment variables ' + 'are filled with data from powerline configuration.' ) shell_parser = subparsers.add_parser('shell', help='Shell-specific commands') @@ -60,14 +69,20 @@ def get_argparser(ArgumentParser=ConfigArgParser): choices=tuple(SHELL_ACTIONS.values()), type=(lambda v: SHELL_ACTIONS.get(v)), metavar='ACTION', - help='If action is `command\' then preferred powerline command is output, if it is `uses\' then powerline-config script will exit with 1 if specified component is disabled and 0 otherwise.', + help='If action is `command\' then preferred powerline command is ' + 'output, if it is `uses\' then powerline-config script will exit ' + 'with 1 if specified component is disabled and 0 otherwise.', ) shell_parser.add_argument( 'component', nargs='?', choices=('tmux', 'prompt'), metavar='COMPONENT', - help='Only applicable for `uses\' subcommand: makes `powerline-config\' exit with 0 if specific component is enabled and with 1 otherwise. `tmux\' component stands for tmux bindings (e.g. those that notify tmux about current directory changes), `prompt\' component stands for shell prompt.' + help='Only applicable for `uses\' subcommand: makes `powerline-config\' ' + 'exit with 0 if specific component is enabled and with 1 otherwise. ' + '`tmux\' component stands for tmux bindings ' + '(e.g. those that notify tmux about current directory changes), ' + '`prompt\' component stands for shell prompt.' ) shell_parser.add_argument( '-s', '--shell', diff --git a/powerline/commands/daemon.py b/powerline/commands/daemon.py index 9efcdca2..7e8c8ab3 100644 --- a/powerline/commands/daemon.py +++ b/powerline/commands/daemon.py @@ -6,10 +6,19 @@ import argparse def get_argparser(ArgumentParser=argparse.ArgumentParser): parser = ArgumentParser(description='Daemon that improves powerline performance.') - parser.add_argument('--quiet', '-q', action='store_true', help='Without other options: do not complain about already running powerline-daemon instance. Will still exit with 1. With `--kill\' and `--replace\': do not show any messages. With `--foreground\': ignored. Does not silence exceptions in any case.') + parser.add_argument( + '--quiet', '-q', action='store_true', + help='Without other options: do not complain about already running ' + 'powerline-daemon instance. ' + 'Will still exit with 1. ' + 'With `--kill\' and `--replace\': do not show any messages. ' + 'With `--foreground\': ignored. ' + 'Does not silence exceptions in any case.' + ) parser.add_argument('--socket', '-s', help='Specify socket which will be used for connecting to daemon.') - arggr = parser.add_mutually_exclusive_group().add_argument - arggr('--kill', '-k', action='store_true', help='Kill an already running instance.') - arggr('--foreground', '-f', action='store_true', help='Run in the foreground (don’t daemonize).') - arggr('--replace', '-r', action='store_true', help='Replace an already running instance.') + exclusive_group = parser.add_mutually_exclusive_group() + exclusive_group.add_argument('--kill', '-k', action='store_true', help='Kill an already running instance.') + replace_group = exclusive_group.add_argument_group() + replace_group.add_argument('--foreground', '-f', action='store_true', help='Run in the foreground (don’t daemonize).') + replace_group.add_argument('--replace', '-r', action='store_true', help='Replace an already running instance.') return parser diff --git a/powerline/commands/lint.py b/powerline/commands/lint.py index a09aa35c..8961a650 100755 --- a/powerline/commands/lint.py +++ b/powerline/commands/lint.py @@ -6,6 +6,16 @@ import argparse def get_argparser(ArgumentParser=argparse.ArgumentParser): parser = ArgumentParser(description='Powerline configuration checker.') - parser.add_argument('-p', '--config_path', action='append', metavar='PATH', help='Paths where configuration should be checked, in order. You must supply all paths necessary for powerline to work, checking partial (e.g. only user overrides) configuration is not supported.') - parser.add_argument('-d', '--debug', action='store_const', const=True, help='Display additional information. Used for debugging `powerline-lint\' itself, not for debugging configuration.') + parser.add_argument( + '-p', '--config-path', action='append', metavar='PATH', + help='Paths where configuration should be checked, in order. You must ' + 'supply all paths necessary for powerline to work, ' + 'checking partial (e.g. only user overrides) configuration ' + 'is not supported.' + ) + parser.add_argument( + '-d', '--debug', action='store_const', const=True, + help='Display additional information. Used for debugging ' + '`powerline-lint\' itself, not for debugging configuration.' + ) return parser diff --git a/powerline/commands/main.py b/powerline/commands/main.py index 2b0c48e1..605098c6 100644 --- a/powerline/commands/main.py +++ b/powerline/commands/main.py @@ -5,57 +5,148 @@ from __future__ import (division, absolute_import, print_function) import argparse import sys -from powerline.lib import mergedicts, parsedotval +from itertools import chain + +from powerline.lib.overrides import parsedotval, parse_override_var +from powerline.lib.dict import mergeargs from powerline.lib.encoding import get_preferred_arguments_encoding +from powerline.lib.unicode import u if sys.version_info < (3,): encoding = get_preferred_arguments_encoding() def arg_to_unicode(s): - return unicode(s, encoding, 'replace') if not isinstance(s, unicode) else s + return unicode(s, encoding, 'replace') if not isinstance(s, unicode) else s # NOQA else: def arg_to_unicode(s): return s -def mergeargs(argvalue): - if not argvalue: - return None - r = {} - for subval in argvalue: - mergedicts(r, dict([subval])) - return r +def finish_args(environ, args): + '''Do some final transformations + Transforms ``*_override`` arguments into dictionaries, adding overrides from + environment variables. Transforms ``renderer_arg`` argument into dictionary + as well, but only if it is true. -def finish_args(args): - if args.config: - args.config = mergeargs((parsedotval(v) for v in args.config)) - if args.theme_option: - args.theme_option = mergeargs((parsedotval(v) for v in args.theme_option)) - else: - args.theme_option = {} + :param dict environ: + Environment from which additional overrides should be taken from. + :param args: + Arguments object returned by + :py:meth:`argparse.ArgumentParser.parse_args`. Will be modified + in-place. + + :return: Object received as second (``args``) argument. + ''' + args.config_override = mergeargs(chain( + parse_override_var(environ.get('POWERLINE_CONFIG_OVERRIDES', '')), + (parsedotval(v) for v in args.config_override or ()), + )) + args.theme_override = mergeargs(chain( + parse_override_var(environ.get('POWERLINE_THEME_OVERRIDES', '')), + (parsedotval(v) for v in args.theme_override or ()), + )) if args.renderer_arg: - args.renderer_arg = mergeargs((parsedotval(v) for v in args.renderer_arg)) + args.renderer_arg = mergeargs((parsedotval(v) for v in args.renderer_arg), remove=True) + args.config_path = ( + [path for path in environ.get('POWERLINE_CONFIG_PATHS', '').split(':') if path] + + (args.config_path or []) + ) + return args + + +def int_or_sig(s): + if s.startswith('sig'): + return u(s) + else: + return int(s) def get_argparser(ArgumentParser=argparse.ArgumentParser): parser = ArgumentParser(description='Powerline prompt and statusline script.') - parser.add_argument('ext', nargs=1, help='Extension: application for which powerline command is launched (usually `shell\' or `tmux\').') - parser.add_argument('side', nargs='?', choices=('left', 'right', 'above', 'aboveleft'), help='Side: `left\' and `right\' represent left and right side respectively, `above\' emits lines that are supposed to be printed just above the prompt and `aboveleft\' is like concatenating `above\' with `left\' with the exception that only one Python instance is used in this case.') parser.add_argument( - '-r', '--renderer_module', metavar='MODULE', type=str, - help='Renderer module. Usually something like `.bash\' or `.zsh\', is supposed to be set only in shell-specific bindings file.' + 'ext', nargs=1, + help='Extension: application for which powerline command is launched ' + '(usually `shell\' or `tmux\').' + ) + parser.add_argument( + 'side', nargs='?', choices=('left', 'right', 'above', 'aboveleft'), + help='Side: `left\' and `right\' represent left and right side ' + 'respectively, `above\' emits lines that are supposed to be printed ' + 'just above the prompt and `aboveleft\' is like concatenating ' + '`above\' with `left\' with the exception that only one Python ' + 'instance is used in this case.' + ) + parser.add_argument( + '-r', '--renderer-module', metavar='MODULE', type=str, + help='Renderer module. Usually something like `.bash\' or `.zsh\' ' + '(with leading dot) which is `powerline.renderers.{ext}{MODULE}\', ' + 'may also be full module name (must contain at least one dot or ' + 'end with a dot in case it is top-level module) or ' + '`powerline.renderers\' submodule (in case there are no dots).' + ) + parser.add_argument( + '-w', '--width', type=int, + help='Maximum prompt with. Triggers truncation of some segments.' + ) + parser.add_argument( + '--last-exit-code', metavar='INT', type=int_or_sig, + help='Last exit code.' + ) + parser.add_argument( + '--last-pipe-status', metavar='LIST', default='', + type=lambda s: [int_or_sig(status) for status in s.split()], + help='Like above, but is supposed to contain space-separated array ' + 'of statuses, representing exit statuses of commands in one pipe.' + ) + parser.add_argument( + '--jobnum', metavar='INT', type=int, + help='Number of jobs.' + ) + parser.add_argument( + '-c', '--config-override', metavar='KEY.KEY=VALUE', type=arg_to_unicode, + action='append', + help='Configuration overrides for `config.json\'. Is translated to a ' + 'dictionary and merged with the dictionary obtained from actual ' + 'JSON configuration: KEY.KEY=VALUE is translated to ' + '`{"KEY": {"KEY": VALUE}}\' and then merged recursively. ' + 'VALUE may be any JSON value, values that are not ' + '`null\', `true\', `false\', start with digit, `{\', `[\' ' + 'are treated like strings. If VALUE is omitted ' + 'then corresponding key is removed.' + ) + parser.add_argument( + '-t', '--theme-override', metavar='THEME.KEY.KEY=VALUE', type=arg_to_unicode, + action='append', + help='Like above, but theme-specific. THEME should point to ' + 'an existing and used theme to have any effect, but it is fine ' + 'to use any theme here.' + ) + parser.add_argument( + '-R', '--renderer-arg', + metavar='KEY=VAL', type=arg_to_unicode, action='append', + help='Like above, but provides argument for renderer. Is supposed ' + 'to be used only by shell bindings to provide various data like ' + 'last-exit-code or last-pipe-status (they are not using ' + '`--renderer-arg\' for historical resons: `--renderer-arg\' ' + 'was added later).' + ) + parser.add_argument( + '-p', '--config-path', action='append', metavar='PATH', + help='Path to configuration directory. If it is present then ' + 'configuration files will only be seeked in the provided path. ' + 'May be provided multiple times to search in a list of directories.' + ) + parser.add_argument( + '--socket', metavar='ADDRESS', type=str, + help='Socket address to use in daemon clients. Is always UNIX domain ' + 'socket on linux and file socket on Mac OS X. Not used here, ' + 'present only for compatibility with other powerline clients. ' + 'This argument must always be the first one and be in a form ' + '`--socket ADDRESS\': no `=\' or short form allowed ' + '(in other powerline clients, not here).' ) - parser.add_argument('-w', '--width', type=int, help='Maximum prompt with. Triggers truncation of some segments.') - parser.add_argument('--last_exit_code', metavar='INT', type=int, help='Last exit code.') - parser.add_argument('--last_pipe_status', metavar='LIST', default='', type=lambda s: [int(status) for status in s.split()], help='Like above, but is supposed to contain space-separated array of statuses, representing exit statuses of commands in one pipe.') - parser.add_argument('--jobnum', metavar='INT', type=int, help='Number of jobs.') - parser.add_argument('-c', '--config', metavar='KEY.KEY=VALUE', type=arg_to_unicode, action='append', help='Configuration overrides for `config.json\'. Is translated to a dictionary and merged with the dictionary obtained from actual JSON configuration: KEY.KEY=VALUE is translated to `{"KEY": {"KEY": VALUE}}\' and then merged recursively. VALUE may be any JSON value, values that are not `null\', `true\', `false\', start with digit, `{\', `[\' are treated like strings. If VALUE is omitted then corresponding key is removed.') - parser.add_argument('-t', '--theme_option', metavar='THEME.KEY.KEY=VALUE', type=arg_to_unicode, action='append', help='Like above, but theme-specific. THEME should point to an existing and used theme to have any effect, but it is fine to use any theme here.') - parser.add_argument('-R', '--renderer_arg', metavar='KEY=VAL', type=arg_to_unicode, action='append', help='Like above, but provides argument for renderer. Is supposed to be used only by shell bindings to provide various data like last_exit_code or last_pipe_status (they are not using `--renderer_arg\' for historical resons: `--renderer_arg\' was added later).') - parser.add_argument('-p', '--config_path', action='append', metavar='PATH', help='Path to configuration directory. If it is present then configuration files will only be seeked in the provided path. May be provided multiple times to search in a list of directories.') - parser.add_argument('--socket', metavar='ADDRESS', type=str, help='Socket address to use in daemon clients. Is always UNIX domain socket on linux and file socket on Mac OS X. Not used here, present only for compatibility with other powerline clients. This argument must always be the first one and be in a form `--socket ADDRESS\': no `=\' or short form allowed (in other powerline clients, not here).') return parser @@ -66,7 +157,7 @@ def write_output(args, powerline, segment_info, write, encoding): for line in powerline.render_above_lines( width=args.width, segment_info=segment_info, - mode=segment_info['environ'].get('_POWERLINE_MODE'), + mode=segment_info.get('mode', None), ): write(line.encode(encoding, 'replace')) write(b'\n') @@ -77,6 +168,6 @@ def write_output(args, powerline, segment_info, write, encoding): width=args.width, side=args.side, segment_info=segment_info, - mode=segment_info['environ'].get('_POWERLINE_MODE'), + mode=segment_info.get('mode', None), ) write(rendered.encode(encoding, 'replace')) diff --git a/powerline/config_files/colorschemes/default.json b/powerline/config_files/colorschemes/default.json index 899f162a..fbea5532 100644 --- a/powerline/config_files/colorschemes/default.json +++ b/powerline/config_files/colorschemes/default.json @@ -1,45 +1,45 @@ { "name": "Default", "groups": { - "background": { "fg": "white", "bg": "gray0", "attr": [] }, - "background:divider": { "fg": "gray5", "bg": "gray0", "attr": [] }, - "session": { "fg": "black", "bg": "gray10", "attr": ["bold"] }, - "date": { "fg": "gray8", "bg": "gray2", "attr": [] }, - "time": { "fg": "gray10", "bg": "gray2", "attr": ["bold"] }, - "time:divider": { "fg": "gray5", "bg": "gray2", "attr": [] }, - "email_alert": { "fg": "white", "bg": "brightred", "attr": ["bold"] }, - "email_alert_gradient": { "fg": "white", "bg": "yellow_orange_red", "attr": ["bold"] }, - "hostname": { "fg": "black", "bg": "gray10", "attr": ["bold"] }, - "weather": { "fg": "gray8", "bg": "gray0", "attr": [] }, - "weather_temp_gradient": { "fg": "blue_red", "bg": "gray0", "attr": [] }, - "weather_condition_hot": { "fg": "khaki1", "bg": "gray0", "attr": [] }, - "weather_condition_snowy": { "fg": "skyblue1", "bg": "gray0", "attr": [] }, - "weather_condition_rainy": { "fg": "skyblue1", "bg": "gray0", "attr": [] }, - "uptime": { "fg": "gray8", "bg": "gray0", "attr": [] }, - "external_ip": { "fg": "gray8", "bg": "gray0", "attr": [] }, - "internal_ip": { "fg": "gray8", "bg": "gray0", "attr": [] }, - "network_load": { "fg": "gray8", "bg": "gray0", "attr": [] }, - "network_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attr": [] }, - "system_load": { "fg": "gray8", "bg": "gray0", "attr": [] }, - "system_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attr": [] }, - "environment": { "fg": "gray8", "bg": "gray0", "attr": [] }, - "cpu_load_percent": { "fg": "gray8", "bg": "gray0", "attr": [] }, - "cpu_load_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attr": [] }, - "battery": { "fg": "gray8", "bg": "gray0", "attr": [] }, - "battery_gradient": { "fg": "white_red", "bg": "gray0", "attr": [] }, - "battery_full": { "fg": "red", "bg": "gray0", "attr": [] }, - "battery_empty": { "fg": "white", "bg": "gray0", "attr": [] }, - "player": { "fg": "gray10", "bg": "black", "attr": [] }, - "user": { "fg": "white", "bg": "darkblue", "attr": ["bold"] }, - "superuser": { "fg": "white", "bg": "brightred", "attr": ["bold"] }, - "branch": { "fg": "gray9", "bg": "gray2", "attr": [] }, - "branch_dirty": { "fg": "brightyellow", "bg": "gray2", "attr": [] }, - "branch_clean": { "fg": "gray9", "bg": "gray2", "attr": [] }, - "branch:divider": { "fg": "gray7", "bg": "gray2", "attr": [] }, - "cwd": { "fg": "gray9", "bg": "gray4", "attr": [] }, - "cwd:current_folder": { "fg": "gray10", "bg": "gray4", "attr": ["bold"] }, - "cwd:divider": { "fg": "gray7", "bg": "gray4", "attr": [] }, - "virtualenv": { "fg": "white", "bg": "darkcyan", "attr": [] }, - "attached_clients": { "fg": "gray8", "bg": "gray0", "attr": [] } + "background": { "fg": "white", "bg": "gray0", "attrs": [] }, + "background:divider": { "fg": "gray5", "bg": "gray0", "attrs": [] }, + "session": { "fg": "black", "bg": "gray10", "attrs": ["bold"] }, + "date": { "fg": "gray8", "bg": "gray2", "attrs": [] }, + "time": { "fg": "gray10", "bg": "gray2", "attrs": ["bold"] }, + "time:divider": { "fg": "gray5", "bg": "gray2", "attrs": [] }, + "email_alert": { "fg": "white", "bg": "brightred", "attrs": ["bold"] }, + "email_alert_gradient": { "fg": "white", "bg": "yellow_orange_red", "attrs": ["bold"] }, + "hostname": { "fg": "black", "bg": "gray10", "attrs": ["bold"] }, + "weather": { "fg": "gray8", "bg": "gray0", "attrs": [] }, + "weather_temp_gradient": { "fg": "blue_red", "bg": "gray0", "attrs": [] }, + "weather_condition_hot": { "fg": "khaki1", "bg": "gray0", "attrs": [] }, + "weather_condition_snowy": { "fg": "skyblue1", "bg": "gray0", "attrs": [] }, + "weather_condition_rainy": { "fg": "skyblue1", "bg": "gray0", "attrs": [] }, + "uptime": { "fg": "gray8", "bg": "gray0", "attrs": [] }, + "external_ip": { "fg": "gray8", "bg": "gray0", "attrs": [] }, + "internal_ip": { "fg": "gray8", "bg": "gray0", "attrs": [] }, + "network_load": { "fg": "gray8", "bg": "gray0", "attrs": [] }, + "network_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attrs": [] }, + "system_load": { "fg": "gray8", "bg": "gray0", "attrs": [] }, + "system_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attrs": [] }, + "environment": { "fg": "gray8", "bg": "gray0", "attrs": [] }, + "cpu_load_percent": { "fg": "gray8", "bg": "gray0", "attrs": [] }, + "cpu_load_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attrs": [] }, + "battery": { "fg": "gray8", "bg": "gray0", "attrs": [] }, + "battery_gradient": { "fg": "white_red", "bg": "gray0", "attrs": [] }, + "battery_full": { "fg": "red", "bg": "gray0", "attrs": [] }, + "battery_empty": { "fg": "white", "bg": "gray0", "attrs": [] }, + "player": { "fg": "gray10", "bg": "black", "attrs": [] }, + "user": { "fg": "white", "bg": "darkblue", "attrs": ["bold"] }, + "superuser": { "fg": "white", "bg": "brightred", "attrs": ["bold"] }, + "branch": { "fg": "gray9", "bg": "gray2", "attrs": [] }, + "branch_dirty": { "fg": "brightyellow", "bg": "gray2", "attrs": [] }, + "branch_clean": { "fg": "gray9", "bg": "gray2", "attrs": [] }, + "branch:divider": { "fg": "gray7", "bg": "gray2", "attrs": [] }, + "cwd": { "fg": "gray9", "bg": "gray4", "attrs": [] }, + "cwd:current_folder": { "fg": "gray10", "bg": "gray4", "attrs": ["bold"] }, + "cwd:divider": { "fg": "gray7", "bg": "gray4", "attrs": [] }, + "virtualenv": { "fg": "white", "bg": "darkcyan", "attrs": [] }, + "attached_clients": { "fg": "gray8", "bg": "gray0", "attrs": [] } } } diff --git a/powerline/config_files/colorschemes/ipython/default.json b/powerline/config_files/colorschemes/ipython/default.json index 54987c48..a5da8ffc 100644 --- a/powerline/config_files/colorschemes/ipython/default.json +++ b/powerline/config_files/colorschemes/ipython/default.json @@ -1,7 +1,7 @@ { "name": "Default color scheme for IPython prompt", "groups": { - "prompt": { "fg": "gray9", "bg": "gray4", "attr": [] }, - "prompt_count": { "fg": "white", "bg": "gray4", "attr": [] } + "prompt": { "fg": "gray9", "bg": "gray4", "attrs": [] }, + "prompt_count": { "fg": "white", "bg": "gray4", "attrs": [] } } } diff --git a/powerline/config_files/colorschemes/shell/default.json b/powerline/config_files/colorschemes/shell/default.json index bb9e0d59..09f3d211 100644 --- a/powerline/config_files/colorschemes/shell/default.json +++ b/powerline/config_files/colorschemes/shell/default.json @@ -1,18 +1,18 @@ { "name": "Default color scheme for shell prompts", "groups": { - "hostname": { "fg": "brightyellow", "bg": "mediumorange", "attr": [] }, - "jobnum": { "fg": "brightyellow", "bg": "mediumorange", "attr": [] }, - "exit_fail": { "fg": "white", "bg": "darkestred", "attr": [] }, - "exit_success": { "fg": "white", "bg": "darkestgreen", "attr": [] }, - "environment": { "fg": "white", "bg": "darkestgreen", "attr": [] }, - "mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] }, - "attached_clients": { "fg": "white", "bg": "darkestgreen", "attr": [] } + "hostname": { "fg": "brightyellow", "bg": "mediumorange", "attrs": [] }, + "jobnum": { "fg": "brightyellow", "bg": "mediumorange", "attrs": [] }, + "exit_fail": { "fg": "white", "bg": "darkestred", "attrs": [] }, + "exit_success": { "fg": "white", "bg": "darkestgreen", "attrs": [] }, + "environment": { "fg": "white", "bg": "darkestgreen", "attrs": [] }, + "mode": { "fg": "darkestgreen", "bg": "brightgreen", "attrs": ["bold"] }, + "attached_clients": { "fg": "white", "bg": "darkestgreen", "attrs": [] } }, "mode_translations": { "vicmd": { "groups": { - "mode": {"fg": "darkestcyan", "bg": "white", "attr": ["bold"]} + "mode": {"fg": "darkestcyan", "bg": "white", "attrs": ["bold"]} } } } diff --git a/powerline/config_files/colorschemes/shell/solarized.json b/powerline/config_files/colorschemes/shell/solarized.json index e9059bd6..43b1666a 100644 --- a/powerline/config_files/colorschemes/shell/solarized.json +++ b/powerline/config_files/colorschemes/shell/solarized.json @@ -1,15 +1,15 @@ { "name": "Solarized dark for shell", "groups": { - "jobnum": { "fg": "solarized:base3", "bg": "solarized:base01", "attr": [] }, - "exit_fail": { "fg": "solarized:base3", "bg": "solarized:red", "attr": [] }, - "exit_success": { "fg": "solarized:base3", "bg": "solarized:green", "attr": [] }, - "mode": { "fg": "solarized:base3", "bg": "solarized:green", "attr": ["bold"] } + "jobnum": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": [] }, + "exit_fail": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": [] }, + "exit_success": { "fg": "solarized:base3", "bg": "solarized:green", "attrs": [] }, + "mode": { "fg": "solarized:base3", "bg": "solarized:green", "attrs": ["bold"] } }, "mode_translations": { "vicmd": { "groups": { - "mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attr": ["bold"] } + "mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attrs": ["bold"] } } } } diff --git a/powerline/config_files/colorschemes/solarized.json b/powerline/config_files/colorschemes/solarized.json index 9c015ccd..9730e825 100644 --- a/powerline/config_files/colorschemes/solarized.json +++ b/powerline/config_files/colorschemes/solarized.json @@ -1,18 +1,18 @@ { "name": "Solarized dark", "groups": { - "background": { "fg": "solarized:base3", "bg": "solarized:base02", "attr": [] }, - "user": { "fg": "solarized:base3", "bg": "solarized:blue", "attr": ["bold"] }, - "superuser": { "fg": "solarized:base3", "bg": "solarized:red", "attr": ["bold"] }, - "virtualenv": { "fg": "solarized:base3", "bg": "solarized:green", "attr": [] }, - "branch": { "fg": "solarized:base1", "bg": "solarized:base02", "attr": [] }, - "branch_dirty": { "fg": "solarized:yellow", "bg": "solarized:base02", "attr": [] }, - "branch_clean": { "fg": "solarized:base1", "bg": "solarized:base02", "attr": [] }, - "cwd": { "fg": "solarized:base2", "bg": "solarized:base01", "attr": [] }, - "cwd:current_folder": { "fg": "solarized:base3", "bg": "solarized:base01", "attr": ["bold"] }, - "cwd:divider": { "fg": "solarized:base1", "bg": "solarized:base01", "attr": [] }, - "hostname": { "fg": "solarized:base3", "bg": "solarized:base01", "attr": [] }, - "environment": { "fg": "solarized:base3", "bg": "solarized:green", "attr": [] }, - "attached_clients": { "fg": "solarized:base3", "bg": "solarized:green", "attr": [] } + "background": { "fg": "solarized:base3", "bg": "solarized:base02", "attrs": [] }, + "user": { "fg": "solarized:base3", "bg": "solarized:blue", "attrs": ["bold"] }, + "superuser": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] }, + "virtualenv": { "fg": "solarized:base3", "bg": "solarized:green", "attrs": [] }, + "branch": { "fg": "solarized:base1", "bg": "solarized:base02", "attrs": [] }, + "branch_dirty": { "fg": "solarized:yellow", "bg": "solarized:base02", "attrs": [] }, + "branch_clean": { "fg": "solarized:base1", "bg": "solarized:base02", "attrs": [] }, + "cwd": { "fg": "solarized:base2", "bg": "solarized:base01", "attrs": [] }, + "cwd:current_folder": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": ["bold"] }, + "cwd:divider": { "fg": "solarized:base1", "bg": "solarized:base01", "attrs": [] }, + "hostname": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": [] }, + "environment": { "fg": "solarized:base3", "bg": "solarized:green", "attrs": [] }, + "attached_clients": { "fg": "solarized:base3", "bg": "solarized:green", "attrs": [] } } } diff --git a/powerline/config_files/colorschemes/tmux/default.json b/powerline/config_files/colorschemes/tmux/default.json index e936f2ce..8525fb05 100644 --- a/powerline/config_files/colorschemes/tmux/default.json +++ b/powerline/config_files/colorschemes/tmux/default.json @@ -1,14 +1,14 @@ { "groups": { - "active_window_status": {"fg": "darkblue", "bg": "gray0", "attr": []}, - "window_status": {"fg": "gray70", "bg": "gray0", "attr": []}, - "activity_status": {"fg": "yellow", "bg": "gray0", "attr": []}, - "bell_status": {"fg": "red", "bg": "gray0", "attr": []}, - "window": {"fg": "gray6", "bg": "gray0", "attr": []}, - "window:divider": {"fg": "gray4", "bg": "gray0", "attr": []}, - "window:current": {"fg": "mediumcyan", "bg": "darkblue", "attr": []}, - "window_name": {"fg": "white", "bg": "darkblue", "attr": ["bold"]}, - "session": {"fg": "black", "bg": "gray90", "attr": ["bold"]}, - "session:prefix": {"fg": "gray90", "bg": "darkblue", "attr": ["bold"]} + "active_window_status": {"fg": "darkblue", "bg": "gray0", "attrs": []}, + "window_status": {"fg": "gray70", "bg": "gray0", "attrs": []}, + "activity_status": {"fg": "yellow", "bg": "gray0", "attrs": []}, + "bell_status": {"fg": "red", "bg": "gray0", "attrs": []}, + "window": {"fg": "gray6", "bg": "gray0", "attrs": []}, + "window:divider": {"fg": "gray4", "bg": "gray0", "attrs": []}, + "window:current": {"fg": "mediumcyan", "bg": "darkblue", "attrs": []}, + "window_name": {"fg": "white", "bg": "darkblue", "attrs": ["bold"]}, + "session": {"fg": "black", "bg": "gray90", "attrs": ["bold"]}, + "session:prefix": {"fg": "gray90", "bg": "darkblue", "attrs": ["bold"]} } } diff --git a/powerline/config_files/colorschemes/vim/default.json b/powerline/config_files/colorschemes/vim/default.json index dd62fdb0..979ddc3f 100644 --- a/powerline/config_files/colorschemes/vim/default.json +++ b/powerline/config_files/colorschemes/vim/default.json @@ -1,38 +1,38 @@ { "name": "Default color scheme", "groups": { - "information:unimportant": { "fg": "gray8", "bg": "gray2", "attr": [] }, - "information:additional": { "fg": "gray9", "bg": "gray4", "attr": [] }, - "background": { "fg": "white", "bg": "gray2", "attr": [] }, - "background:divider": { "fg": "gray6", "bg": "gray2", "attr": [] }, - "mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] }, - "visual_range": { "fg": "brightestorange", "bg": "darkorange", "attr": ["bold"] }, - "modified_indicator": { "fg": "brightyellow", "bg": "gray4", "attr": ["bold"] }, - "paste_indicator": { "fg": "white", "bg": "mediumorange", "attr": ["bold"] }, - "readonly_indicator": { "fg": "brightestred", "bg": "gray4", "attr": [] }, - "branch_dirty": { "fg": "brightyellow", "bg": "gray4", "attr": [] }, - "branch:divider": { "fg": "gray7", "bg": "gray4", "attr": [] }, - "file_name": { "fg": "white", "bg": "gray4", "attr": ["bold"] }, - "window_title": { "fg": "white", "bg": "gray4", "attr": [] }, - "file_name_no_file": { "fg": "gray9", "bg": "gray4", "attr": ["bold"] }, - "file_vcs_status": { "fg": "brightestred", "bg": "gray4", "attr": [] }, - "file_vcs_status_M": { "fg": "brightyellow", "bg": "gray4", "attr": [] }, - "file_vcs_status_A": { "fg": "brightgreen", "bg": "gray4", "attr": [] }, - "line_percent": { "fg": "gray9", "bg": "gray4", "attr": [] }, - "line_percent_gradient": { "fg": "dark_green_gray", "bg": "gray4", "attr": [] }, - "position": { "fg": "gray9", "bg": "gray4", "attr": [] }, - "position_gradient": { "fg": "green_yellow_red", "bg": "gray4", "attr": [] }, - "line_current": { "fg": "gray1", "bg": "gray10", "attr": ["bold"] }, - "line_current_symbol": { "fg": "gray1", "bg": "gray10", "attr": [] }, - "virtcol_current_gradient": { "fg": "dark_GREEN_Orange_red", "bg": "gray10", "attr": [] }, - "col_current": { "fg": "gray6", "bg": "gray10", "attr": [] }, - "modified_buffers": { "fg": "brightyellow", "bg": "gray2", "attr": [] }, - "attached_clients": { "fg": "gray8", "bg": "gray2", "attr": [] }, - "error": { "fg": "brightestred", "bg": "darkred", "attr": ["bold"] }, - "warning": { "fg": "brightyellow", "bg": "darkorange", "attr": ["bold"] }, - "current_tag": { "fg": "gray9", "bg": "gray2", "attr": [] }, + "information:unimportant": { "fg": "gray8", "bg": "gray2", "attrs": [] }, + "information:additional": { "fg": "gray9", "bg": "gray4", "attrs": [] }, + "background": { "fg": "white", "bg": "gray2", "attrs": [] }, + "background:divider": { "fg": "gray6", "bg": "gray2", "attrs": [] }, + "mode": { "fg": "darkestgreen", "bg": "brightgreen", "attrs": ["bold"] }, + "visual_range": { "fg": "brightestorange", "bg": "darkorange", "attrs": ["bold"] }, + "modified_indicator": { "fg": "brightyellow", "bg": "gray4", "attrs": ["bold"] }, + "paste_indicator": { "fg": "white", "bg": "mediumorange", "attrs": ["bold"] }, + "readonly_indicator": { "fg": "brightestred", "bg": "gray4", "attrs": [] }, + "branch_dirty": { "fg": "brightyellow", "bg": "gray4", "attrs": [] }, + "branch:divider": { "fg": "gray7", "bg": "gray4", "attrs": [] }, + "file_name": { "fg": "white", "bg": "gray4", "attrs": ["bold"] }, + "window_title": { "fg": "white", "bg": "gray4", "attrs": [] }, + "file_name_no_file": { "fg": "gray9", "bg": "gray4", "attrs": ["bold"] }, + "file_vcs_status": { "fg": "brightestred", "bg": "gray4", "attrs": [] }, + "file_vcs_status_M": { "fg": "brightyellow", "bg": "gray4", "attrs": [] }, + "file_vcs_status_A": { "fg": "brightgreen", "bg": "gray4", "attrs": [] }, + "line_percent": { "fg": "gray9", "bg": "gray4", "attrs": [] }, + "line_percent_gradient": { "fg": "dark_green_gray", "bg": "gray4", "attrs": [] }, + "position": { "fg": "gray9", "bg": "gray4", "attrs": [] }, + "position_gradient": { "fg": "green_yellow_red", "bg": "gray4", "attrs": [] }, + "line_current": { "fg": "gray1", "bg": "gray10", "attrs": ["bold"] }, + "line_current_symbol": { "fg": "gray1", "bg": "gray10", "attrs": [] }, + "virtcol_current_gradient": { "fg": "dark_GREEN_Orange_red", "bg": "gray10", "attrs": [] }, + "col_current": { "fg": "gray6", "bg": "gray10", "attrs": [] }, + "modified_buffers": { "fg": "brightyellow", "bg": "gray2", "attrs": [] }, + "attached_clients": { "fg": "gray8", "bg": "gray2", "attrs": [] }, + "error": { "fg": "brightestred", "bg": "darkred", "attrs": ["bold"] }, + "warning": { "fg": "brightyellow", "bg": "darkorange", "attrs": ["bold"] }, + "current_tag": { "fg": "gray9", "bg": "gray2", "attrs": [] }, - "tab_nc:modified_indicator": { "fg": "brightyellow", "bg": "gray2", "attr": ["bold"] } + "tab_nc:modified_indicator": { "fg": "brightyellow", "bg": "gray2", "attrs": ["bold"] } }, "mode_translations": { "nc": { @@ -71,29 +71,29 @@ "dark_green_gray": "light_green_gray" }, "groups": { - "mode": { "fg": "darkestcyan", "bg": "white", "attr": ["bold"] }, - "background:divider": { "fg": "darkcyan", "bg": "darkestblue", "attr": [] }, - "branch:divider": { "fg": "darkcyan", "bg": "darkblue", "attr": [] } + "mode": { "fg": "darkestcyan", "bg": "white", "attrs": ["bold"] }, + "background:divider": { "fg": "darkcyan", "bg": "darkestblue", "attrs": [] }, + "branch:divider": { "fg": "darkcyan", "bg": "darkblue", "attrs": [] } } }, "v": { "groups": { - "mode": { "fg": "darkorange", "bg": "brightestorange", "attr": ["bold"] } + "mode": { "fg": "darkorange", "bg": "brightestorange", "attrs": ["bold"] } } }, "V": { "groups": { - "mode": { "fg": "darkorange", "bg": "brightestorange", "attr": ["bold"] } + "mode": { "fg": "darkorange", "bg": "brightestorange", "attrs": ["bold"] } } }, "^V": { "groups": { - "mode": { "fg": "darkorange", "bg": "brightestorange", "attr": ["bold"] } + "mode": { "fg": "darkorange", "bg": "brightestorange", "attrs": ["bold"] } } }, "R": { "groups": { - "mode": { "fg": "white", "bg": "brightred", "attr": ["bold"] } + "mode": { "fg": "white", "bg": "brightred", "attrs": ["bold"] } } } } diff --git a/powerline/config_files/colorschemes/vim/solarized.json b/powerline/config_files/colorschemes/vim/solarized.json index b0fa497d..bf603851 100644 --- a/powerline/config_files/colorschemes/vim/solarized.json +++ b/powerline/config_files/colorschemes/vim/solarized.json @@ -1,37 +1,37 @@ { "name": "Solarized dark for vim", "groups": { - "information:additional": { "fg": "solarized:base2", "bg": "solarized:base01", "attr": [] }, - "information:unimportant": { "fg": "solarized:base3", "bg": "solarized:base01", "attr": [] }, - "background": { "fg": "solarized:base3", "bg": "solarized:base02", "attr": [] }, - "background:divider": { "fg": "solarized:base00", "bg": "solarized:base02", "attr": [] }, - "mode": { "fg": "solarized:base3", "bg": "solarized:green", "attr": ["bold"] }, - "visual_range": { "fg": "solarized:green", "bg": "solarized:base3", "attr": ["bold"] }, - "modified_indicator": { "fg": "solarized:yellow", "bg": "solarized:base01", "attr": ["bold"] }, - "paste_indicator": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] }, - "readonly_indicator": { "fg": "solarized:red", "bg": "solarized:base01", "attr": [] }, - "branch_dirty": { "fg": "solarized:yellow", "bg": "solarized:base01", "attr": [] }, - "branch:divider": { "fg": "solarized:base1", "bg": "solarized:base01", "attr": [] }, - "file_name": { "fg": "solarized:base3", "bg": "solarized:base01", "attr": ["bold"] }, - "window_title": { "fg": "solarized:base3", "bg": "solarized:base01", "attr": [] }, - "file_name_no_file": { "fg": "solarized:base3", "bg": "solarized:base01", "attr": ["bold"] }, - "file_format": { "fg": "solarized:base1", "bg": "solarized:base02", "attr": [] }, - "file_vcs_status": { "fg": "solarized:red", "bg": "solarized:base01", "attr": [] }, - "file_vcs_status_M": { "fg": "solarized:yellow", "bg": "solarized:base01", "attr": [] }, - "file_vcs_status_A": { "fg": "solarized:green", "bg": "solarized:base01", "attr": [] }, - "line_percent": { "fg": "solarized:base3", "bg": "solarized:base00", "attr": [] }, - "line_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "solarized:base00", "attr": [] }, - "position": { "fg": "solarized:base3", "bg": "solarized:base00", "attr": [] }, - "position_gradient": { "fg": "green_yellow_orange_red", "bg": "solarized:base00", "attr": [] }, - "line_current": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": ["bold"] }, - "line_current_symbol": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": [] }, - "virtcol_current_gradient": { "fg": "GREEN_Orange_red", "bg": "solarized:base2", "attr": [] }, - "col_current": { "fg": "solarized:base0", "bg": "solarized:base2", "attr": [] }, - "environment": { "fg": "solarized:base1", "bg": "solarized:base02", "attr": [] }, - "attached_clients": { "fg": "solarized:base1", "bg": "solarized:base02", "attr": [] }, - "error": { "fg": "solarized:base3", "bg": "solarized:red", "attr": ["bold"] }, - "warning": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] }, - "current_tag": { "fg": "solarized:base3", "bg": "solarized:base02", "attr": ["bold"] } + "information:additional": { "fg": "solarized:base2", "bg": "solarized:base01", "attrs": [] }, + "information:unimportant": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": [] }, + "background": { "fg": "solarized:base3", "bg": "solarized:base02", "attrs": [] }, + "background:divider": { "fg": "solarized:base00", "bg": "solarized:base02", "attrs": [] }, + "mode": { "fg": "solarized:base3", "bg": "solarized:green", "attrs": ["bold"] }, + "visual_range": { "fg": "solarized:green", "bg": "solarized:base3", "attrs": ["bold"] }, + "modified_indicator": { "fg": "solarized:yellow", "bg": "solarized:base01", "attrs": ["bold"] }, + "paste_indicator": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] }, + "readonly_indicator": { "fg": "solarized:red", "bg": "solarized:base01", "attrs": [] }, + "branch_dirty": { "fg": "solarized:yellow", "bg": "solarized:base01", "attrs": [] }, + "branch:divider": { "fg": "solarized:base1", "bg": "solarized:base01", "attrs": [] }, + "file_name": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": ["bold"] }, + "window_title": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": [] }, + "file_name_no_file": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": ["bold"] }, + "file_format": { "fg": "solarized:base1", "bg": "solarized:base02", "attrs": [] }, + "file_vcs_status": { "fg": "solarized:red", "bg": "solarized:base01", "attrs": [] }, + "file_vcs_status_M": { "fg": "solarized:yellow", "bg": "solarized:base01", "attrs": [] }, + "file_vcs_status_A": { "fg": "solarized:green", "bg": "solarized:base01", "attrs": [] }, + "line_percent": { "fg": "solarized:base3", "bg": "solarized:base00", "attrs": [] }, + "line_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "solarized:base00", "attrs": [] }, + "position": { "fg": "solarized:base3", "bg": "solarized:base00", "attrs": [] }, + "position_gradient": { "fg": "green_yellow_orange_red", "bg": "solarized:base00", "attrs": [] }, + "line_current": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": ["bold"] }, + "line_current_symbol": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": [] }, + "virtcol_current_gradient": { "fg": "GREEN_Orange_red", "bg": "solarized:base2", "attrs": [] }, + "col_current": { "fg": "solarized:base0", "bg": "solarized:base2", "attrs": [] }, + "environment": { "fg": "solarized:base1", "bg": "solarized:base02", "attrs": [] }, + "attached_clients": { "fg": "solarized:base1", "bg": "solarized:base02", "attrs": [] }, + "error": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] }, + "warning": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] }, + "current_tag": { "fg": "solarized:base3", "bg": "solarized:base02", "attrs": ["bold"] } }, "mode_translations": { "nc": { @@ -46,50 +46,50 @@ }, "i": { "groups": { - "background": { "fg": "solarized:base3", "bg": "solarized:base01", "attr": [] }, - "background:divider": { "fg": "solarized:base2", "bg": "solarized:base01", "attr": [] }, - "mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attr": ["bold"] }, - "modified_indicator": { "fg": "solarized:yellow", "bg": "solarized:base2", "attr": ["bold"] }, - "paste_indicator": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] }, - "readonly_indicator": { "fg": "solarized:red", "bg": "solarized:base2", "attr": [] }, - "branch": { "fg": "solarized:base01", "bg": "solarized:base2", "attr": [] }, - "branch:divider": { "fg": "solarized:base00", "bg": "solarized:base2", "attr": [] }, - "file_directory": { "fg": "solarized:base01", "bg": "solarized:base2", "attr": [] }, - "file_name": { "fg": "solarized:base02", "bg": "solarized:base2", "attr": ["bold"] }, - "file_size": { "fg": "solarized:base02", "bg": "solarized:base2", "attr": [] }, - "file_name_no_file": { "fg": "solarized:base02", "bg": "solarized:base2", "attr": ["bold"] }, - "file_name_empty": { "fg": "solarized:base02", "bg": "solarized:base2", "attr": [] }, - "file_format": { "fg": "solarized:base2", "bg": "solarized:base01", "attr": [] }, - "file_vcs_status": { "fg": "solarized:red", "bg": "solarized:base2", "attr": [] }, - "file_vcs_status_M": { "fg": "solarized:yellow", "bg": "solarized:base2", "attr": [] }, - "file_vcs_status_A": { "fg": "solarized:green", "bg": "solarized:base2", "attr": [] }, - "line_percent": { "fg": "solarized:base3", "bg": "solarized:base1", "attr": [] }, - "line_percent_gradient": { "fg": "solarized:base3", "bg": "solarized:base1", "attr": [] }, - "position": { "fg": "solarized:base3", "bg": "solarized:base1", "attr": [] }, - "position_gradient": { "fg": "solarized:base3", "bg": "solarized:base1", "attr": [] }, - "line_current": { "fg": "solarized:base03", "bg": "solarized:base3", "attr": ["bold"] }, - "line_current_symbol": { "fg": "solarized:base03", "bg": "solarized:base3", "attr": [] }, - "col_current": { "fg": "solarized:base0", "bg": "solarized:base3", "attr": [] } + "background": { "fg": "solarized:base3", "bg": "solarized:base01", "attrs": [] }, + "background:divider": { "fg": "solarized:base2", "bg": "solarized:base01", "attrs": [] }, + "mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attrs": ["bold"] }, + "modified_indicator": { "fg": "solarized:yellow", "bg": "solarized:base2", "attrs": ["bold"] }, + "paste_indicator": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] }, + "readonly_indicator": { "fg": "solarized:red", "bg": "solarized:base2", "attrs": [] }, + "branch": { "fg": "solarized:base01", "bg": "solarized:base2", "attrs": [] }, + "branch:divider": { "fg": "solarized:base00", "bg": "solarized:base2", "attrs": [] }, + "file_directory": { "fg": "solarized:base01", "bg": "solarized:base2", "attrs": [] }, + "file_name": { "fg": "solarized:base02", "bg": "solarized:base2", "attrs": ["bold"] }, + "file_size": { "fg": "solarized:base02", "bg": "solarized:base2", "attrs": [] }, + "file_name_no_file": { "fg": "solarized:base02", "bg": "solarized:base2", "attrs": ["bold"] }, + "file_name_empty": { "fg": "solarized:base02", "bg": "solarized:base2", "attrs": [] }, + "file_format": { "fg": "solarized:base2", "bg": "solarized:base01", "attrs": [] }, + "file_vcs_status": { "fg": "solarized:red", "bg": "solarized:base2", "attrs": [] }, + "file_vcs_status_M": { "fg": "solarized:yellow", "bg": "solarized:base2", "attrs": [] }, + "file_vcs_status_A": { "fg": "solarized:green", "bg": "solarized:base2", "attrs": [] }, + "line_percent": { "fg": "solarized:base3", "bg": "solarized:base1", "attrs": [] }, + "line_percent_gradient": { "fg": "solarized:base3", "bg": "solarized:base1", "attrs": [] }, + "position": { "fg": "solarized:base3", "bg": "solarized:base1", "attrs": [] }, + "position_gradient": { "fg": "solarized:base3", "bg": "solarized:base1", "attrs": [] }, + "line_current": { "fg": "solarized:base03", "bg": "solarized:base3", "attrs": ["bold"] }, + "line_current_symbol": { "fg": "solarized:base03", "bg": "solarized:base3", "attrs": [] }, + "col_current": { "fg": "solarized:base0", "bg": "solarized:base3", "attrs": [] } } }, "v": { "groups": { - "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] } + "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] } } }, "V": { "groups": { - "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] } + "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] } } }, "^V": { "groups": { - "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] } + "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] } } }, "R": { "groups": { - "mode": { "fg": "solarized:base3", "bg": "solarized:red", "attr": ["bold"] } + "mode": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] } } } } diff --git a/powerline/config_files/colorschemes/vim/solarizedlight.json b/powerline/config_files/colorschemes/vim/solarizedlight.json index f6c1e178..2dcbb23d 100644 --- a/powerline/config_files/colorschemes/vim/solarizedlight.json +++ b/powerline/config_files/colorschemes/vim/solarizedlight.json @@ -1,36 +1,36 @@ { "name": "Solarized light for vim", "groups": { - "information:additional": { "fg": "solarized:base02", "bg": "solarized:base2", "attr": [] }, - "information:unimportant": { "fg": "solarized:base1", "bg": "solarized:base01", "attr": [] }, - "background": { "fg": "solarized:base03", "bg": "solarized:base01", "attr": [] }, - "background:divider": { "fg": "solarized:base0", "bg": "solarized:base01", "attr": [] }, - "mode": { "fg": "solarized:base3", "bg": "solarized:green", "attr": ["bold"] }, - "visual_range": { "fg": "solarized:green", "bg": "solarized:base3", "attr": ["bold"] }, - "modified_indicator": { "fg": "solarized:yellow", "bg": "solarized:base2", "attr": ["bold"] }, - "paste_indicator": { "fg": "solarized:red", "bg": "solarized:base2", "attr": ["bold"] }, - "readonly_indicator": { "fg": "solarized:red", "bg": "solarized:base2", "attr": [] }, - "branch_dirty": { "fg": "solarized:yellow", "bg": "solarized:base2", "attr": [] }, - "branch:divider": { "fg": "solarized:base1", "bg": "solarized:base2", "attr": [] }, - "file_name": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": ["bold"] }, - "window_title": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": [] }, - "file_size": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": [] }, - "file_name_no_file": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": ["bold"] }, - "file_name_empty": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": [] }, - "file_vcs_status": { "fg": "solarized:red", "bg": "solarized:base2", "attr": [] }, - "file_vcs_status_M": { "fg": "solarized:yellow", "bg": "solarized:base2", "attr": [] }, - "file_vcs_status_A": { "fg": "solarized:green", "bg": "solarized:base2", "attr": [] }, - "line_percent": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": [] }, - "line_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "solarized:base2", "attr": [] }, - "position": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": [] }, - "position_gradient": { "fg": "green_yellow_orange_red", "bg": "solarized:base2", "attr": [] }, - "line_current": { "fg": "solarized:base3", "bg": "solarized:base02", "attr": ["bold"] }, - "line_current_symbol": { "fg": "solarized:base3", "bg": "solarized:base02", "attr": [] }, - "virtcol_current_gradient": { "fg": "yellow_orange_red", "bg": "solarized:base02", "attr": [] }, - "col_current": { "fg": "solarized:base00", "bg": "solarized:base02", "attr": [] }, - "error": { "fg": "solarized:base03", "bg": "solarized:red", "attr": ["bold"] }, - "warning": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": ["bold"] }, - "current_tag": { "fg": "solarized:base03", "bg": "solarized:base01", "attr": ["bold"] } + "information:additional": { "fg": "solarized:base02", "bg": "solarized:base2", "attrs": [] }, + "information:unimportant": { "fg": "solarized:base1", "bg": "solarized:base01", "attrs": [] }, + "background": { "fg": "solarized:base03", "bg": "solarized:base01", "attrs": [] }, + "background:divider": { "fg": "solarized:base0", "bg": "solarized:base01", "attrs": [] }, + "mode": { "fg": "solarized:base3", "bg": "solarized:green", "attrs": ["bold"] }, + "visual_range": { "fg": "solarized:green", "bg": "solarized:base3", "attrs": ["bold"] }, + "modified_indicator": { "fg": "solarized:yellow", "bg": "solarized:base2", "attrs": ["bold"] }, + "paste_indicator": { "fg": "solarized:red", "bg": "solarized:base2", "attrs": ["bold"] }, + "readonly_indicator": { "fg": "solarized:red", "bg": "solarized:base2", "attrs": [] }, + "branch_dirty": { "fg": "solarized:yellow", "bg": "solarized:base2", "attrs": [] }, + "branch:divider": { "fg": "solarized:base1", "bg": "solarized:base2", "attrs": [] }, + "file_name": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": ["bold"] }, + "window_title": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": [] }, + "file_size": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": [] }, + "file_name_no_file": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": ["bold"] }, + "file_name_empty": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": [] }, + "file_vcs_status": { "fg": "solarized:red", "bg": "solarized:base2", "attrs": [] }, + "file_vcs_status_M": { "fg": "solarized:yellow", "bg": "solarized:base2", "attrs": [] }, + "file_vcs_status_A": { "fg": "solarized:green", "bg": "solarized:base2", "attrs": [] }, + "line_percent": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": [] }, + "line_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "solarized:base2", "attrs": [] }, + "position": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": [] }, + "position_gradient": { "fg": "green_yellow_orange_red", "bg": "solarized:base2", "attrs": [] }, + "line_current": { "fg": "solarized:base3", "bg": "solarized:base02", "attrs": ["bold"] }, + "line_current_symbol": { "fg": "solarized:base3", "bg": "solarized:base02", "attrs": [] }, + "virtcol_current_gradient": { "fg": "yellow_orange_red", "bg": "solarized:base02", "attrs": [] }, + "col_current": { "fg": "solarized:base00", "bg": "solarized:base02", "attrs": [] }, + "error": { "fg": "solarized:base03", "bg": "solarized:red", "attrs": ["bold"] }, + "warning": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": ["bold"] }, + "current_tag": { "fg": "solarized:base03", "bg": "solarized:base01", "attrs": ["bold"] } }, "mode_translations": { "nc": { @@ -45,51 +45,51 @@ }, "i": { "groups": { - "background": { "fg": "solarized:base03", "bg": "solarized:base2", "attr": [] }, - "background:divider": { "fg": "solarized:base02", "bg": "solarized:base2", "attr": [] }, - "mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attr": ["bold"] }, - "modified_indicator": { "fg": "solarized:yellow", "bg": "solarized:base02", "attr": ["bold"] }, - "paste_indicator": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] }, - "readonly_indicator": { "fg": "solarized:red", "bg": "solarized:base02", "attr": [] }, - "branch": { "fg": "solarized:base2", "bg": "solarized:base02", "attr": [] }, - "branch:divider": { "fg": "solarized:base0", "bg": "solarized:base02", "attr": [] }, - "file_directory": { "fg": "solarized:base2", "bg": "solarized:base02", "attr": [] }, - "file_name": { "fg": "solarized:base01", "bg": "solarized:base02", "attr": ["bold"] }, - "file_size": { "fg": "solarized:base01", "bg": "solarized:base02", "attr": [] }, - "file_name_no_file": { "fg": "solarized:base01", "bg": "solarized:base02", "attr": ["bold"] }, - "file_name_empty": { "fg": "solarized:base01", "bg": "solarized:base02", "attr": [] }, - "file_format": { "fg": "solarized:base02", "bg": "solarized:base2", "attr": [] }, - "file_vcs_status": { "fg": "solarized:red", "bg": "solarized:base02", "attr": [] }, - "file_vcs_status_M": { "fg": "solarized:yellow", "bg": "solarized:base02", "attr": [] }, - "file_vcs_status_A": { "fg": "solarized:green", "bg": "solarized:base02", "attr": [] }, - "line_percent": { "fg": "solarized:base03", "bg": "solarized:base1", "attr": [] }, - "line_percent_gradient": { "fg": "solarized:base03", "bg": "solarized:base1", "attr": [] }, - "position": { "fg": "solarized:base03", "bg": "solarized:base1", "attr": [] }, - "position_gradient": { "fg": "solarized:base03", "bg": "solarized:base1", "attr": [] }, - "line_current": { "fg": "solarized:base3", "bg": "solarized:base03", "attr": ["bold"] }, - "line_current_symbol": { "fg": "solarized:base3", "bg": "solarized:base03", "attr": [] }, - "virtcol_current_gradient": { "fg": "yellow_orange_red", "bg": "solarized:base03", "attr": [] }, - "col_current": { "fg": "solarized:base00", "bg": "solarized:base03", "attr": [] } + "background": { "fg": "solarized:base03", "bg": "solarized:base2", "attrs": [] }, + "background:divider": { "fg": "solarized:base02", "bg": "solarized:base2", "attrs": [] }, + "mode": { "fg": "solarized:base3", "bg": "solarized:blue", "attrs": ["bold"] }, + "modified_indicator": { "fg": "solarized:yellow", "bg": "solarized:base02", "attrs": ["bold"] }, + "paste_indicator": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] }, + "readonly_indicator": { "fg": "solarized:red", "bg": "solarized:base02", "attrs": [] }, + "branch": { "fg": "solarized:base2", "bg": "solarized:base02", "attrs": [] }, + "branch:divider": { "fg": "solarized:base0", "bg": "solarized:base02", "attrs": [] }, + "file_directory": { "fg": "solarized:base2", "bg": "solarized:base02", "attrs": [] }, + "file_name": { "fg": "solarized:base01", "bg": "solarized:base02", "attrs": ["bold"] }, + "file_size": { "fg": "solarized:base01", "bg": "solarized:base02", "attrs": [] }, + "file_name_no_file": { "fg": "solarized:base01", "bg": "solarized:base02", "attrs": ["bold"] }, + "file_name_empty": { "fg": "solarized:base01", "bg": "solarized:base02", "attrs": [] }, + "file_format": { "fg": "solarized:base02", "bg": "solarized:base2", "attrs": [] }, + "file_vcs_status": { "fg": "solarized:red", "bg": "solarized:base02", "attrs": [] }, + "file_vcs_status_M": { "fg": "solarized:yellow", "bg": "solarized:base02", "attrs": [] }, + "file_vcs_status_A": { "fg": "solarized:green", "bg": "solarized:base02", "attrs": [] }, + "line_percent": { "fg": "solarized:base03", "bg": "solarized:base1", "attrs": [] }, + "line_percent_gradient": { "fg": "solarized:base03", "bg": "solarized:base1", "attrs": [] }, + "position": { "fg": "solarized:base03", "bg": "solarized:base1", "attrs": [] }, + "position_gradient": { "fg": "solarized:base03", "bg": "solarized:base1", "attrs": [] }, + "line_current": { "fg": "solarized:base3", "bg": "solarized:base03", "attrs": ["bold"] }, + "line_current_symbol": { "fg": "solarized:base3", "bg": "solarized:base03", "attrs": [] }, + "virtcol_current_gradient": { "fg": "yellow_orange_red", "bg": "solarized:base03", "attrs": [] }, + "col_current": { "fg": "solarized:base00", "bg": "solarized:base03", "attrs": [] } } }, "v": { "groups": { - "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] } + "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] } } }, "V": { "groups": { - "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] } + "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] } } }, "^V": { "groups": { - "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attr": ["bold"] } + "mode": { "fg": "solarized:base3", "bg": "solarized:orange", "attrs": ["bold"] } } }, "R": { "groups": { - "mode": { "fg": "solarized:base3", "bg": "solarized:red", "attr": ["bold"] } + "mode": { "fg": "solarized:base3", "bg": "solarized:red", "attrs": ["bold"] } } } } diff --git a/powerline/config_files/config.json b/powerline/config_files/config.json index 2bb53b9d..9502129a 100644 --- a/powerline/config_files/config.json +++ b/powerline/config_files/config.json @@ -35,7 +35,6 @@ "quickfix": "quickfix", "powerline.matchers.vim.plugin.nerdtree.nerdtree": "plugin_nerdtree", - "powerline.matchers.vim.plugin.ctrlp.ctrlp": "plugin_ctrlp", "powerline.matchers.vim.plugin.commandt.commandt": "plugin_commandt", "powerline.matchers.vim.plugin.gundo.gundo": "plugin_gundo", "powerline.matchers.vim.plugin.gundo.gundo_preview": "plugin_gundo-preview" diff --git a/powerline/config_files/themes/ascii.json b/powerline/config_files/themes/ascii.json index 80b2fcb7..9ba09c31 100644 --- a/powerline/config_files/themes/ascii.json +++ b/powerline/config_files/themes/ascii.json @@ -48,16 +48,6 @@ "powerline.segments.common.net.hostname": { "before": "H " }, - "powerline.segments.common.players.now_playing": { - "args": { - "state_symbols": { - "fallback": "", - "play": ">", - "pause": "~", - "stop": "X" - } - } - }, "powerline.segments.common.bat.battery": { "args": { "full_heart": "O", @@ -110,15 +100,15 @@ "S": "S-LINE", "^S": "S-BLCK", "i": "INSERT", - "R": "REPLACE", - "Rv": "V-RPLCE", + "R": "RPLACE", + "Rv": "V-RPLC", "c": "COMMND", - "cv": "VIM EX", - "ce": "EX", + "cv": "VIM-EX", + "ce": "NRM-EX", "r": "PROMPT", - "rm": "MORE", - "r?": "CONFIRM", - "!": "SHELL" + "rm": "-MORE-", + "r?": "CNFIRM", + "!": "!SHELL" } } }, diff --git a/powerline/config_files/themes/ipython/in.json b/powerline/config_files/themes/ipython/in.json index b8957753..edd4d294 100644 --- a/powerline/config_files/themes/ipython/in.json +++ b/powerline/config_files/themes/ipython/in.json @@ -9,7 +9,7 @@ "type": "string", "contents": "In [", "draw_soft_divider": false, - "highlight_group": ["prompt"] + "highlight_groups": ["prompt"] }, { "function": "powerline.segments.ipython.prompt_count", @@ -18,7 +18,7 @@ { "type": "string", "contents": "]", - "highlight_group": ["prompt"] + "highlight_groups": ["prompt"] } ] } diff --git a/powerline/config_files/themes/ipython/in2.json b/powerline/config_files/themes/ipython/in2.json index ce54e1bb..422c44b3 100644 --- a/powerline/config_files/themes/ipython/in2.json +++ b/powerline/config_files/themes/ipython/in2.json @@ -5,7 +5,7 @@ "type": "string", "contents": "", "width": "auto", - "highlight_group": ["prompt"] + "highlight_groups": ["prompt"] } ] } diff --git a/powerline/config_files/themes/ipython/out.json b/powerline/config_files/themes/ipython/out.json index f7c27adf..2425d0b7 100644 --- a/powerline/config_files/themes/ipython/out.json +++ b/powerline/config_files/themes/ipython/out.json @@ -8,7 +8,7 @@ "draw_soft_divider": false, "width": "auto", "align": "r", - "highlight_group": ["prompt"] + "highlight_groups": ["prompt"] }, { "function": "prompt_count", @@ -17,7 +17,7 @@ { "type": "string", "contents": "]", - "highlight_group": ["prompt"] + "highlight_groups": ["prompt"] } ] } diff --git a/powerline/config_files/themes/ipython/rewrite.json b/powerline/config_files/themes/ipython/rewrite.json index 35b39024..8192fe4f 100644 --- a/powerline/config_files/themes/ipython/rewrite.json +++ b/powerline/config_files/themes/ipython/rewrite.json @@ -7,7 +7,7 @@ "contents": "", "draw_soft_divider": false, "width": "auto", - "highlight_group": ["prompt"] + "highlight_groups": ["prompt"] }, { "function": "prompt_count", @@ -16,7 +16,7 @@ { "type": "string", "contents": ">", - "highlight_group": ["prompt"] + "highlight_groups": ["prompt"] } ] } diff --git a/powerline/config_files/themes/powerline.json b/powerline/config_files/themes/powerline.json index ddc6b60c..2bbe7bfd 100644 --- a/powerline/config_files/themes/powerline.json +++ b/powerline/config_files/themes/powerline.json @@ -47,16 +47,6 @@ "powerline.segments.common.net.hostname": { "before": " " }, - "powerline.segments.common.players.now_playing": { - "args": { - "state_symbols": { - "fallback": "♫", - "play": "▶", - "pause": "▮▮", - "stop": "■" - } - } - }, "powerline.segments.common.bat.battery": { "args": { "full_heart": "♥", @@ -108,15 +98,15 @@ "S": "S·LINE", "^S": "S·BLCK", "i": "INSERT", - "R": "REPLACE", - "Rv": "V·RPLCE", + "R": "RPLACE", + "Rv": "V·RPLC", "c": "COMMND", - "cv": "VIM EX", - "ce": "EX", + "cv": "VIM·EX", + "ce": "NRM·EX", "r": "PROMPT", - "rm": "MORE", - "r?": "CONFIRM", - "!": "SHELL" + "rm": "-MORE-", + "r?": "CNFIRM", + "!": "!SHELL" } } }, diff --git a/powerline/config_files/themes/powerline_unicode7.json b/powerline/config_files/themes/powerline_unicode7.json new file mode 100644 index 00000000..2b0b0184 --- /dev/null +++ b/powerline/config_files/themes/powerline_unicode7.json @@ -0,0 +1,146 @@ +{ + "dividers": { + "left": { + "hard": " ", + "soft": " " + }, + "right": { + "hard": " ", + "soft": " " + } + }, + "spaces": 1, + "segment_data": { + "branch": { + "before": "🔀 " + }, + "cwd": { + "args": { + "ellipsis": "⋯" + } + }, + + "line_current_symbol": { + "contents": " " + }, + "player": { + "args": { + "state_symbols": { + "fallback": "♫", + "play": "⏵", + "pause": "⏸", + "stop": "⏹" + } + } + }, + + "time": { + "before": "🕐 " + }, + + "powerline.segments.common.net.network_load": { + "args": { + "recv_format": "⬇ {value:>8}", + "sent_format": "⬆ {value:>8}" + } + }, + "powerline.segments.common.net.hostname": { + "before": "🏠 " + }, + "powerline.segments.common.bat.battery": { + "args": { + "full_heart": "💙", + "empty_heart": "💛" + } + }, + "powerline.segments.common.sys.uptime": { + "before": "⇑ " + }, + "powerline.segments.common.mail.email_imap_alert": { + "before": "✉ " + }, + "powerline.segments.common.env.virtualenv": { + "before": "🐍 " + }, + "powerline.segments.common.wthr.weather": { + "args": { + "icons": { + "tornado": "🌪", + "hurricane": "🌀", + "showers": "☔", + "scattered_showers": "☔", + "thunderstorms": "🌩", + "isolated_thunderstorms": "🌩", + "scattered_thunderstorms": "🌩", + "dust": "🌫", + "fog": "🌫", + "cold": "❄", + "partly_cloudy_day": "🌤", + "mostly_cloudy_day": "🌥", + "sun": "🌣", + "hot": "♨", + "day": "☀", + "blustery": "⚑", + "rainy": "☂", + "cloudy": "☁", + "snowy": "☃", + "stormy": "☈", + "foggy": "🌁", + "sunny": "🌣", + "night": "☾", + "windy": "☴", + "not_available": "�", + "unknown": "⚠" + } + } + }, + "powerline.segments.common.time.fuzzy_time": { + "args": { + "unicode_text": true + } + }, + + "powerline.segments.vim.mode": { + "args": { + "override": { + "n": "NORMAL", + "no": "N·OPER", + "v": "VISUAL", + "V": "V·LINE", + "^V": "V·BLCK", + "s": "SELECT", + "S": "S·LINE", + "^S": "S·BLCK", + "i": "INSERT", + "R": "RPLACE", + "Rv": "V·RPLC", + "c": "COMMND", + "cv": "VIM·EX", + "ce": "NRM·EX", + "r": "PROMPT", + "rm": "-MORE-", + "r?": "CNFIRM", + "!": "!SHELL" + } + } + }, + "powerline.segments.vim.visual_range": { + "args": { + "CTRL_V_text": "{rows} × {vcols}", + "v_text_oneline": "C:{vcols}", + "v_text_multiline": "L:{rows}", + "V_text": "L:{rows}" + } + }, + "powerline.segments.vim.readonly_indicator": { + "args": { + "text": "🔏" + } + }, + "powerline.segments.vim.modified_indicator": { + "args": { + "text": "🖫⃥" + } + } + } +} diff --git a/powerline/config_files/themes/shell/select.json b/powerline/config_files/themes/shell/select.json index 172912f1..3d814080 100644 --- a/powerline/config_files/themes/shell/select.json +++ b/powerline/config_files/themes/shell/select.json @@ -6,7 +6,7 @@ "contents": "Select variant", "width": "auto", "align": "r", - "highlight_group": ["continuation:current"] + "highlight_groups": ["continuation:current"] } ] } diff --git a/powerline/config_files/themes/unicode.json b/powerline/config_files/themes/unicode.json index d1461ee0..f6d6f5e5 100644 --- a/powerline/config_files/themes/unicode.json +++ b/powerline/config_files/themes/unicode.json @@ -47,16 +47,6 @@ "powerline.segments.common.net.hostname": { "before": "⌂ " }, - "powerline.segments.common.players.now_playing": { - "args": { - "state_symbols": { - "fallback": "♫", - "play": "▶", - "pause": "▮▮", - "stop": "■" - } - } - }, "powerline.segments.common.bat.battery": { "args": { "full_heart": "♥", @@ -108,15 +98,15 @@ "S": "S·LINE", "^S": "S·BLCK", "i": "INSERT", - "R": "REPLACE", - "Rv": "V·RPLCE", + "R": "RPLACE", + "Rv": "V·RPLC", "c": "COMMND", - "cv": "VIM EX", - "ce": "EX", + "cv": "VIM·EX", + "ce": "NRM·EX", "r": "PROMPT", - "rm": "MORE", - "r?": "CONFIRM", - "!": "SHELL" + "rm": "-MORE-", + "r?": "CNFIRM", + "!": "!SHELL" } } }, diff --git a/powerline/config_files/themes/unicode_terminus.json b/powerline/config_files/themes/unicode_terminus.json index d4df1fdd..5b0a165b 100644 --- a/powerline/config_files/themes/unicode_terminus.json +++ b/powerline/config_files/themes/unicode_terminus.json @@ -47,16 +47,6 @@ "powerline.segments.common.net.hostname": { "before": "⌂ " }, - "powerline.segments.common.players.now_playing": { - "args": { - "state_symbols": { - "fallback": "♫", - "play": "▶", - "pause": "▮▮", - "stop": "■" - } - } - }, "powerline.segments.common.bat.battery": { "args": { "full_heart": "♥", @@ -108,15 +98,15 @@ "S": "S·LINE", "^S": "S·BLCK", "i": "INSERT", - "R": "REPLACE", - "Rv": "V·RPLCE", + "R": "RPLACE", + "Rv": "V·RPLC", "c": "COMMND", - "cv": "VIM EX", - "ce": "EX", + "cv": "VIM·EX", + "ce": "NRM·EX", "r": "PROMPT", - "rm": "MORE", - "r?": "CONFIRM", - "!": "SHELL" + "rm": "-MORE-", + "r?": "CNFIRM", + "!": "!SHELL" } } }, diff --git a/powerline/config_files/themes/unicode_terminus_condensed.json b/powerline/config_files/themes/unicode_terminus_condensed.json index e153a93c..a725a470 100644 --- a/powerline/config_files/themes/unicode_terminus_condensed.json +++ b/powerline/config_files/themes/unicode_terminus_condensed.json @@ -48,16 +48,6 @@ "powerline.segments.common.net.hostname": { "before": "⌂" }, - "powerline.segments.common.players.now_playing": { - "args": { - "state_symbols": { - "fallback": "♫", - "play": "▶", - "pause": "▮▮", - "stop": "■" - } - } - }, "powerline.segments.common.bat.battery": { "args": { "full_heart": "♥", diff --git a/powerline/config_files/themes/vim/cmdwin.json b/powerline/config_files/themes/vim/cmdwin.json index c300d948..e6a05b06 100644 --- a/powerline/config_files/themes/vim/cmdwin.json +++ b/powerline/config_files/themes/vim/cmdwin.json @@ -4,11 +4,11 @@ { "type": "string", "contents": "Command Line", - "highlight_group": ["file_name"] + "highlight_groups": ["file_name"] }, { "type": "string", - "highlight_group": ["background"], + "highlight_groups": ["background"], "draw_soft_divider": false, "draw_hard_divider": false, "width": "auto" diff --git a/powerline/config_files/themes/vim/default.json b/powerline/config_files/themes/vim/default.json index 44738ed0..9b0c744d 100644 --- a/powerline/config_files/themes/vim/default.json +++ b/powerline/config_files/themes/vim/default.json @@ -71,7 +71,7 @@ }, { "type": "string", - "highlight_group": ["background"], + "highlight_groups": ["background"], "draw_soft_divider": false, "draw_hard_divider": false, "width": "auto" @@ -107,7 +107,7 @@ { "type": "string", "name": "line_current_symbol", - "highlight_group": ["line_current_symbol", "line_current"] + "highlight_groups": ["line_current_symbol", "line_current"] }, { "function": "line_current", diff --git a/powerline/config_files/themes/vim/help.json b/powerline/config_files/themes/vim/help.json index aef0c23e..45c9458c 100644 --- a/powerline/config_files/themes/vim/help.json +++ b/powerline/config_files/themes/vim/help.json @@ -7,7 +7,7 @@ }, { "type": "string", - "highlight_group": ["background"], + "highlight_groups": ["background"], "draw_soft_divider": false, "draw_hard_divider": false, "width": "auto" @@ -23,7 +23,7 @@ { "type": "string", "name": "line_current_symbol", - "highlight_group": ["line_current_symbol", "line_current"] + "highlight_groups": ["line_current_symbol", "line_current"] }, { "function": "line_current", diff --git a/powerline/config_files/themes/vim/plugin_commandt.json b/powerline/config_files/themes/vim/plugin_commandt.json index a9ad7c99..dd6748fa 100644 --- a/powerline/config_files/themes/vim/plugin_commandt.json +++ b/powerline/config_files/themes/vim/plugin_commandt.json @@ -4,7 +4,7 @@ { "type": "string", "contents": "Command-T", - "highlight_group": ["commandt:label"] + "highlight_groups": ["commandt:label"] }, { "function": "powerline.segments.vim.plugin.commandt.finder" @@ -14,7 +14,7 @@ }, { "type": "string", - "highlight_group": ["commandt:background"], + "highlight_groups": ["commandt:background"], "draw_soft_divider": false, "draw_hard_divider": false, "width": "auto" diff --git a/powerline/config_files/themes/vim/plugin_ctrlp.json b/powerline/config_files/themes/vim/plugin_ctrlp.json deleted file mode 100644 index 25e16e79..00000000 --- a/powerline/config_files/themes/vim/plugin_ctrlp.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "default_module": "powerline.segments.vim.plugin.ctrlp", - "segments": { - "left": [ - { - "function": "ctrlp", - "args": { - "side": "left" - } - }, - { - "type": "string", - "highlight_group": ["ctrlp.background", "background"], - "draw_soft_divider": false, - "draw_hard_divider": false, - "width": "auto" - } - ], - "right": [ - { - "function": "ctrlp", - "args": { - "side": "right" - } - } - ] - } -} diff --git a/powerline/config_files/themes/vim/plugin_gundo-preview.json b/powerline/config_files/themes/vim/plugin_gundo-preview.json index cd3b00fe..ad8432c1 100644 --- a/powerline/config_files/themes/vim/plugin_gundo-preview.json +++ b/powerline/config_files/themes/vim/plugin_gundo-preview.json @@ -3,12 +3,12 @@ "left": [ { "type": "string", - "highlight_group": ["gundo.name", "file_name"], + "highlight_groups": ["gundo:name", "file_name"], "contents": "Undo diff" }, { "type": "string", - "highlight_group": ["gundo.background", "background"], + "highlight_groups": ["gundo:background", "background"], "draw_soft_divider": false, "draw_hard_divider": false, "width": "auto" diff --git a/powerline/config_files/themes/vim/plugin_gundo.json b/powerline/config_files/themes/vim/plugin_gundo.json index 0d6a448e..a03b256a 100644 --- a/powerline/config_files/themes/vim/plugin_gundo.json +++ b/powerline/config_files/themes/vim/plugin_gundo.json @@ -3,12 +3,12 @@ "left": [ { "type": "string", - "highlight_group": ["gundo.name", "file_name"], + "highlight_groups": ["gundo:name", "file_name"], "contents": "Undo tree" }, { "type": "string", - "highlight_group": ["gundo.background", "background"], + "highlight_groups": ["gundo:background", "background"], "draw_soft_divider": false, "draw_hard_divider": false, "width": "auto" diff --git a/powerline/config_files/themes/vim/plugin_nerdtree.json b/powerline/config_files/themes/vim/plugin_nerdtree.json index 784523af..896d3937 100644 --- a/powerline/config_files/themes/vim/plugin_nerdtree.json +++ b/powerline/config_files/themes/vim/plugin_nerdtree.json @@ -7,7 +7,7 @@ }, { "type": "string", - "highlight_group": ["background"], + "highlight_groups": ["background"], "draw_soft_divider": false, "draw_hard_divider": false, "width": "auto" diff --git a/powerline/config_files/themes/vim/quickfix.json b/powerline/config_files/themes/vim/quickfix.json index 2aa1c0f1..ae4d5a52 100644 --- a/powerline/config_files/themes/vim/quickfix.json +++ b/powerline/config_files/themes/vim/quickfix.json @@ -9,7 +9,7 @@ { "type": "string", "name": "buffer_name", - "highlight_group": ["file_name"] + "highlight_groups": ["file_name"] }, { "function": "window_title", @@ -17,7 +17,7 @@ }, { "type": "string", - "highlight_group": ["background"], + "highlight_groups": ["background"], "draw_soft_divider": false, "draw_hard_divider": false, "width": "auto" @@ -27,7 +27,7 @@ { "type": "string", "name": "line_current_symbol", - "highlight_group": ["line_current_symbol", "line_current"] + "highlight_groups": ["line_current_symbol", "line_current"] }, { "function": "line_current", diff --git a/powerline/config_files/themes/vim/tabline.json b/powerline/config_files/themes/vim/tabline.json index 1a7ce6ae..31112cb1 100644 --- a/powerline/config_files/themes/vim/tabline.json +++ b/powerline/config_files/themes/vim/tabline.json @@ -58,7 +58,7 @@ }, { "type": "string", - "highlight_group": ["background"], + "highlight_groups": ["background"], "draw_soft_divider": false, "draw_hard_divider": false, "width": "auto" @@ -69,14 +69,14 @@ "type": "string", "contents": "Bufs", "name": "single_tab", - "highlight_group": ["single_tab"], + "highlight_groups": ["single_tab"], "include_function": "single_tab" }, { "type": "string", "contents": "Tabs", "name": "many_tabs", - "highlight_group": ["many_tabs"], + "highlight_groups": ["many_tabs"], "exclude_function": "single_tab" } ] diff --git a/powerline/ipython.py b/powerline/ipython.py index 326114df..6e22c41b 100644 --- a/powerline/ipython.py +++ b/powerline/ipython.py @@ -2,7 +2,7 @@ from __future__ import (unicode_literals, division, absolute_import, print_function) from powerline import Powerline -from powerline.lib import mergedicts +from powerline.lib.dict import mergedicts from powerline.lib.unicode import string @@ -32,8 +32,8 @@ class IPythonPowerline(Powerline): ) def get_config_paths(self): - if self.paths: - return self.paths + if self.config_paths: + return self.config_paths else: return super(IPythonPowerline, self).get_config_paths() diff --git a/powerline/lib/__init__.py b/powerline/lib/__init__.py index ee82d216..2a5fbd09 100644 --- a/powerline/lib/__init__.py +++ b/powerline/lib/__init__.py @@ -1,14 +1,9 @@ # vim:fileencoding=utf-8:noet from __future__ import (unicode_literals, division, absolute_import, print_function) -import json - from functools import wraps -REMOVE_THIS_KEY = object() - - def wraps_saveargs(wrapped): def dec(wrapper): r = wraps(wrapped)(wrapper) @@ -17,47 +12,6 @@ def wraps_saveargs(wrapped): return dec -def mergedicts(d1, d2): - '''Recursively merge two dictionaries - - First dictionary is modified in-place. - ''' - for k in d2: - if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict): - mergedicts(d1[k], d2[k]) - elif d2[k] is REMOVE_THIS_KEY: - d1.pop(k, None) - else: - d1[k] = d2[k] - - -def mergedefaults(d1, d2): - '''Recursively merge two dictionaries, keeping existing values - - First dictionary is modified in-place. - ''' - for k in d2: - if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict): - mergedefaults(d1[k], d2[k]) - else: - d1.setdefault(k, d2[k]) - - -def mergedicts_copy(d1, d2): - '''Recursively merge two dictionaries. - - Dictionaries are not modified. Copying happens only if necessary. Assumes - that first dictionary supports .copy() method. - ''' - ret = d1.copy() - for k in d2: - if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict): - ret[k] = mergedicts_copy(d1[k], d2[k]) - else: - ret[k] = d2[k] - return ret - - def add_divider_highlight_group(highlight_group): def dec(func): @wraps_saveargs(func) @@ -72,39 +26,3 @@ def add_divider_highlight_group(highlight_group): return None return f return dec - - -def keyvaluesplit(s): - if '=' not in s: - raise TypeError('Option must look like option=json_value') - if s[0] == '_': - raise ValueError('Option names must not start with `_\'') - idx = s.index('=') - o = s[:idx] - rest = s[idx + 1:] - if not rest: - val = REMOVE_THIS_KEY - elif rest[0] in '"{[0193456789' or rest in ('null', 'true', 'false'): - val = json.loads(s[idx + 1:]) - else: - val = rest - return (o, val) - - -def parsedotval(s): - if type(s) is tuple: - o, val = s - else: - o, val = keyvaluesplit(s) - - keys = o.split('.') - if len(keys) > 1: - r = (keys[0], {}) - rcur = r[1] - for key in keys[1:-1]: - rcur[key] = {} - rcur = rcur[key] - rcur[keys[-1]] = val - return r - else: - return (o, val) diff --git a/powerline/lib/dict.py b/powerline/lib/dict.py new file mode 100644 index 00000000..d8d2088b --- /dev/null +++ b/powerline/lib/dict.py @@ -0,0 +1,80 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + + +REMOVE_THIS_KEY = object() + + +def mergeargs(argvalue, remove=False): + if not argvalue: + return None + r = {} + for subval in argvalue: + mergedicts(r, dict([subval]), remove=remove) + return r + + +def _clear_special_values(d): + '''Remove REMOVE_THIS_KEY values from dictionary + ''' + l = [d] + while l: + i = l.pop() + pops = [] + for k, v in i.items(): + if v is REMOVE_THIS_KEY: + pops.append(k) + elif isinstance(v, dict): + l.append(v) + for k in pops: + i.pop(k) + + +def mergedicts(d1, d2, remove=True): + '''Recursively merge two dictionaries + + First dictionary is modified in-place. + ''' + _setmerged(d1, d2) + for k in d2: + if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict): + mergedicts(d1[k], d2[k], remove) + elif remove and d2[k] is REMOVE_THIS_KEY: + d1.pop(k, None) + else: + if remove and isinstance(d2[k], dict): + _clear_special_values(d2[k]) + d1[k] = d2[k] + + +def mergedefaults(d1, d2): + '''Recursively merge two dictionaries, keeping existing values + + First dictionary is modified in-place. + ''' + for k in d2: + if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict): + mergedefaults(d1[k], d2[k]) + else: + d1.setdefault(k, d2[k]) + + +def _setmerged(d1, d2): + if hasattr(d1, 'setmerged'): + d1.setmerged(d2) + + +def mergedicts_copy(d1, d2): + '''Recursively merge two dictionaries. + + Dictionaries are not modified. Copying happens only if necessary. Assumes + that first dictionary supports .copy() method. + ''' + ret = d1.copy() + _setmerged(ret, d2) + for k in d2: + if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict): + ret[k] = mergedicts_copy(d1[k], d2[k]) + else: + ret[k] = d2[k] + return ret diff --git a/powerline/lib/overrides.py b/powerline/lib/overrides.py new file mode 100644 index 00000000..cf0ac7b1 --- /dev/null +++ b/powerline/lib/overrides.py @@ -0,0 +1,80 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +import json + +from powerline.lib.dict import REMOVE_THIS_KEY + + +def parse_value(s): + '''Convert string to Python object + + Rules: + + * Empty string means that corresponding key should be removed from the + dictionary. + * Strings that start with a minus, digit or with some character that starts + JSON collection or string object are parsed as JSON. + * JSON special values ``null``, ``true``, ``false`` (case matters) are + parsed as JSON. + * All other values are considered to be raw strings. + + :param str s: Parsed string. + + :return: Python object. + ''' + if not s: + return REMOVE_THIS_KEY + elif s[0] in '"{[0193456789-' or s in ('null', 'true', 'false'): + return json.loads(s) + else: + return s + + +def keyvaluesplit(s): + '''Split K1.K2=VAL into K1.K2 and parsed VAL + ''' + if '=' not in s: + raise TypeError('Option must look like option=json_value') + if s[0] == '_': + raise ValueError('Option names must not start with `_\'') + idx = s.index('=') + o = s[:idx] + val = parse_value(s[idx + 1:]) + return (o, val) + + +def parsedotval(s): + '''Parse K1.K2=VAL into {"K1":{"K2":VAL}} + + ``VAL`` is processed according to rules defined in :py:func:`parse_value`. + ''' + if type(s) is tuple: + o, val = s + val = parse_value(val) + else: + o, val = keyvaluesplit(s) + + keys = o.split('.') + if len(keys) > 1: + r = (keys[0], {}) + rcur = r[1] + for key in keys[1:-1]: + rcur[key] = {} + rcur = rcur[key] + rcur[keys[-1]] = val + return r + else: + return (o, val) + + +def parse_override_var(s): + '''Parse a semicolon-separated list of strings into a sequence of values + + Emits the same items in sequence as :py:func:`parsedotval` does. + ''' + return ( + parsedotval(item) + for item in s.split(';') + if item + ) diff --git a/powerline/lib/watcher/uv.py b/powerline/lib/watcher/uv.py index eba020e1..272db0ff 100644 --- a/powerline/lib/watcher/uv.py +++ b/powerline/lib/watcher/uv.py @@ -18,15 +18,19 @@ class UvNotFound(NotImplementedError): pyuv = None +pyuv_version_info = None def import_pyuv(): global pyuv + global pyuv_version_info if not pyuv: try: pyuv = __import__('pyuv') except ImportError: raise UvNotFound + else: + pyuv_version_info = tuple((int(c) for c in pyuv.__version__.split('.'))) class UvThread(Thread): @@ -34,14 +38,18 @@ class UvThread(Thread): def __init__(self, loop): self.uv_loop = loop + self.async_handle = pyuv.Async(loop, self._async_cb) super(UvThread, self).__init__() + def _async_cb(self, handle): + self.uv_loop.stop() + self.async_handle.close() + def run(self): - while True: - self.uv_loop.run() + self.uv_loop.run() def join(self): - self.uv_loop.stop() + self.async_handle.send() return super(UvThread, self).join() @@ -72,18 +80,30 @@ class UvWatcher(object): self.lock = RLock() self.loop = start_uv_thread() self.fenc = get_preferred_file_name_encoding() + if pyuv_version_info >= (1, 0): + self._start_watch = self._start_watch_1_x + else: + self._start_watch = self._start_watch_0_x + + def _start_watch_1_x(self, path): + handle = pyuv.fs.FSEvent(self.loop) + handle.start(path, 0, partial(self._record_event, path)) + self.watches[path] = handle + + def _start_watch_0_x(self, path): + self.watches[path] = pyuv.fs.FSEvent( + self.loop, + path, + partial(self._record_event, path), + pyuv.fs.UV_CHANGE | pyuv.fs.UV_RENAME + ) def watch(self, path): path = normpath(path, self.fenc) with self.lock: if path not in self.watches: try: - self.watches[path] = pyuv.fs.FSEvent( - self.loop, - path, - partial(self._record_event, path), - pyuv.fs.UV_CHANGE | pyuv.fs.UV_RENAME - ) + self._start_watch(path) except pyuv.error.FSEventError as e: code = e.args[0] if code == pyuv.errno.UV_ENOENT: diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index d1797d99..d6ba0bfe 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -5,13 +5,15 @@ import os import logging from collections import defaultdict +from itertools import chain from functools import partial from powerline import generate_config_finder, get_config_paths, load_config from powerline.segments.vim import vim_modes -from powerline.lib import mergedicts_copy +from powerline.lib.dict import mergedicts_copy from powerline.lib.config import ConfigLoader from powerline.lib.unicode import unicode +from powerline.lib.path import join from powerline.lint.markedjson import load from powerline.lint.markedjson.error import echoerr, EchoErr, MarkedError from powerline.lint.checks import (check_matcher_func, check_ext, check_config, check_top_theme, @@ -19,7 +21,8 @@ from powerline.lint.checks import (check_matcher_func, check_ext, check_config, check_segment_module, check_exinclude_function, type_keys, check_segment_function, check_args, get_one_segment_function, check_highlight_groups, check_highlight_group, check_full_segment_data, - get_all_possible_functions, check_segment_data_key, register_common_name) + get_all_possible_functions, check_segment_data_key, register_common_name, + highlight_group_spec) from powerline.lint.spec import Spec from powerline.lint.context import Context @@ -57,6 +60,7 @@ main_spec = (Spec( common=Spec( default_top_theme=top_theme_spec().optional(), term_truecolor=Spec().type(bool).optional(), + term_escape_style=Spec().type(unicode).oneof(set(('auto', 'xterm', 'fbterm'))).optional(), # Python is capable of loading from zip archives. Thus checking path # only for existence of the path, not for it being a directory paths=Spec().list( @@ -141,7 +145,7 @@ group_name_spec = Spec().ident().copy group_spec = Spec().either(Spec( fg=color_spec(), bg=color_spec(), - attr=Spec().list(Spec().type(unicode).oneof(set(('bold', 'italic', 'underline')))), + attrs=Spec().list(Spec().type(unicode).oneof(set(('bold', 'italic', 'underline')))), ), group_name_spec().func(check_group)).copy groups_spec = Spec().unknown_spec( group_name_spec(), @@ -193,7 +197,6 @@ args_spec = Spec( pl=Spec().error('pl object must be set by powerline').optional(), segment_info=Spec().error('Segment info dictionary must be set by powerline').optional(), ).unknown_spec(Spec(), Spec()).optional().copy -highlight_group_spec = Spec().type(unicode).copy segment_module_spec = Spec().type(unicode).func(check_segment_module).optional().copy sub_segments_spec = Spec() exinclude_spec = Spec().re(function_name_re).func(check_exinclude_function).copy @@ -217,7 +220,7 @@ segment_spec = Spec( align=Spec().oneof(set('lr')).optional(), args=args_spec().func(lambda *args, **kwargs: check_args(get_one_segment_function, *args, **kwargs)), contents=Spec().printable().optional(), - highlight_group=Spec().list( + highlight_groups=Spec().list( highlight_group_spec().re( '^(?:(?!:divider$).)+$', (lambda value: 'it is recommended that only divider highlight group names end with ":divider"') @@ -293,6 +296,74 @@ def register_common_names(): register_common_name('player', 'powerline.segments.common.players', '_player') +def load_json_file(path): + with open_file(path) as F: + try: + config, hadproblem = load(F) + except MarkedError as e: + return True, None, str(e) + else: + return hadproblem, config, None + + +def updated_with_config(d): + hadproblem, config, error = load_json_file(d['path']) + d.update( + hadproblem=hadproblem, + config=config, + error=error, + ) + return d + + +def find_all_ext_config_files(search_paths, subdir): + for config_root in search_paths: + top_config_subpath = join(config_root, subdir) + if not os.path.isdir(top_config_subpath): + if os.path.exists(top_config_subpath): + yield { + 'error': 'Path {0} is not a directory'.format(top_config_subpath), + 'path': top_config_subpath, + } + continue + for ext_name in os.listdir(top_config_subpath): + ext_path = os.path.join(top_config_subpath, ext_name) + if not os.path.isdir(ext_path): + if ext_name.endswith('.json') and os.path.isfile(ext_path): + yield updated_with_config({ + 'error': False, + 'path': ext_path, + 'name': ext_name[:-5], + 'ext': None, + 'type': 'top_' + subdir, + }) + else: + yield { + 'error': 'Path {0} is not a directory or configuration file'.format(ext_path), + 'path': ext_path, + } + continue + for config_file_name in os.listdir(ext_path): + config_file_path = os.path.join(ext_path, config_file_name) + if config_file_name.endswith('.json') and os.path.isfile(config_file_path): + yield updated_with_config({ + 'error': False, + 'path': config_file_path, + 'name': config_file_name[:-5], + 'ext': ext_name, + 'type': subdir, + }) + else: + yield { + 'error': 'Path {0} is not a configuration file'.format(config_file_path), + 'path': config_file_path, + } + + +def dict2(d): + return defaultdict(dict, ((k, dict(v)) for k, v in d.items())) + + def check(paths=None, debug=False, echoerr=echoerr, require_ext=None): '''Check configuration sanity @@ -312,6 +383,8 @@ def check(paths=None, debug=False, echoerr=echoerr, require_ext=None): ``False`` if user configuration seems to be completely sane and ``True`` if some problems were found. ''' + hadproblem = False + register_common_names() search_paths = paths or get_config_paths() find_config_files = generate_config_finder(lambda: search_paths) @@ -336,65 +409,60 @@ def check(paths=None, debug=False, echoerr=echoerr, require_ext=None): config_loader = ConfigLoader(run_once=True, load=load_json_config) - paths = { - 'themes': defaultdict(lambda: []), - 'colorschemes': defaultdict(lambda: []), - 'top_colorschemes': [], - 'top_themes': [], - } lists = { 'colorschemes': set(), 'themes': set(), 'exts': set(), } - for path in reversed(search_paths): - for typ in ('themes', 'colorschemes'): - d = os.path.join(path, typ) - if os.path.isdir(d): - for subp in os.listdir(d): - extpath = os.path.join(d, subp) - if os.path.isdir(extpath): - lists['exts'].add(subp) - paths[typ][subp].append(extpath) - elif extpath.endswith('.json'): - name = subp[:-5] - if name != '__main__': - lists[typ].add(name) - paths['top_' + typ].append(extpath) - else: + found_dir = { + 'themes': False, + 'colorschemes': False, + } + config_paths = defaultdict(lambda: defaultdict(dict)) + loaded_configs = defaultdict(lambda: defaultdict(dict)) + for d in chain( + find_all_ext_config_files(search_paths, 'colorschemes'), + find_all_ext_config_files(search_paths, 'themes'), + ): + if d['error']: + hadproblem = True + ee(problem=d['error']) + continue + if d['hadproblem']: + hadproblem = True + if d['ext']: + found_dir[d['type']] = True + lists['exts'].add(d['ext']) + if d['name'] == '__main__': + pass + elif d['name'].startswith('__') or d['name'].endswith('__'): hadproblem = True - ee(problem='Path {0} is supposed to be a directory, but it is not'.format(d)) + ee(problem='File name is not supposed to start or end with “__”: {0}'.format( + d['path'])) + else: + lists[d['type']].add(d['name']) + config_paths[d['type']][d['ext']][d['name']] = d['path'] + loaded_configs[d['type']][d['ext']][d['name']] = d['config'] + else: + config_paths[d['type']][d['name']] = d['path'] + loaded_configs[d['type']][d['name']] = d['config'] - hadproblem = False - - configs = defaultdict(lambda: defaultdict(lambda: {})) for typ in ('themes', 'colorschemes'): - for ext in paths[typ]: - for d in paths[typ][ext]: - for subp in os.listdir(d): - if subp.endswith('.json'): - name = subp[:-5] - if name != '__main__': - lists[typ].add(name) - if name.startswith('__') or name.endswith('__'): - hadproblem = True - ee(problem='File name is not supposed to start or end with “__”: {0}'.format( - os.path.join(d, subp) - )) - configs[typ][ext][name] = os.path.join(d, subp) - for path in paths['top_' + typ]: - name = os.path.basename(path)[:-5] - configs['top_' + typ][name] = path + if not found_dir[typ]: + hadproblem = True + ee(problem='Subdirectory {0} was not found in paths {1}'.format(typ, ', '.join(search_paths))) - diff = set(configs['colorschemes']) - set(configs['themes']) + diff = set(config_paths['colorschemes']) - set(config_paths['themes']) if diff: hadproblem = True for ext in diff: - typ = 'colorschemes' if ext in configs['themes'] else 'themes' - if not configs['top_' + typ] or typ == 'themes': + typ = 'colorschemes' if ext in config_paths['themes'] else 'themes' + if not config_paths['top_' + typ] or typ == 'themes': ee(problem='{0} extension {1} not present in {2}'.format( ext, - 'configuration' if (ext in paths['themes'] and ext in paths['colorschemes']) else 'directory', + 'configuration' if ( + ext in loaded_configs['themes'] and ext in loaded_configs['colorschemes'] + ) else 'directory', typ, )) @@ -411,7 +479,7 @@ def check(paths=None, debug=False, echoerr=echoerr, require_ext=None): else: if used_main_spec.match( main_config, - data={'configs': configs, 'lists': lists}, + data={'configs': config_paths, 'lists': lists}, context=Context(main_config), echoerr=ee )[1]: @@ -436,42 +504,19 @@ def check(paths=None, debug=False, echoerr=echoerr, require_ext=None): if lhadproblem[0]: hadproblem = True - top_colorscheme_configs = {} + top_colorscheme_configs = dict(loaded_configs['top_colorschemes']) data = { 'ext': None, 'top_colorscheme_configs': top_colorscheme_configs, 'ext_colorscheme_configs': {}, 'colors_config': colors_config } - for colorscheme, cfile in configs['top_colorschemes'].items(): - with open_file(cfile) as config_file_fp: - try: - config, lhadproblem = load(config_file_fp) - except MarkedError as e: - ee(problem=str(e)) - hadproblem = True - continue - if lhadproblem: - hadproblem = True - top_colorscheme_configs[colorscheme] = config + for colorscheme, config in loaded_configs['top_colorschemes'].items(): data['colorscheme'] = colorscheme if top_colorscheme_spec.match(config, context=Context(config), data=data, echoerr=ee)[1]: hadproblem = True - ext_colorscheme_configs = defaultdict(lambda: {}) - for ext in configs['colorschemes']: - for colorscheme, cfile in configs['colorschemes'][ext].items(): - with open_file(cfile) as config_file_fp: - try: - config, lhadproblem = load(config_file_fp) - except MarkedError as e: - ee(problem=str(e)) - hadproblem = True - continue - if lhadproblem: - hadproblem = True - ext_colorscheme_configs[ext][colorscheme] = config - + ext_colorscheme_configs = dict2(loaded_configs['colorschemes']) for ext, econfigs in ext_colorscheme_configs.items(): data = { 'ext': ext, @@ -511,33 +556,8 @@ def check(paths=None, debug=False, echoerr=echoerr, require_ext=None): config = mconfig colorscheme_configs[colorscheme] = config - theme_configs = defaultdict(lambda: {}) - for ext in configs['themes']: - for theme, sfile in configs['themes'][ext].items(): - with open_file(sfile) as config_file_fp: - try: - config, lhadproblem = load(config_file_fp) - except MarkedError as e: - ee(problem=str(e)) - hadproblem = True - continue - if lhadproblem: - hadproblem = True - theme_configs[ext][theme] = config - - top_theme_configs = {} - for top_theme, top_theme_file in configs['top_themes'].items(): - with open_file(top_theme_file) as config_file_fp: - try: - config, lhadproblem = load(config_file_fp) - except MarkedError as e: - ee(problem=str(e)) - hadproblem = True - continue - if lhadproblem: - hadproblem = True - top_theme_configs[top_theme] = config - + theme_configs = dict2(loaded_configs['themes']) + top_theme_configs = dict(loaded_configs['top_themes']) for ext, configs in theme_configs.items(): data = { 'ext': ext, @@ -561,12 +581,12 @@ def check(paths=None, debug=False, echoerr=echoerr, require_ext=None): for top_theme, config in top_theme_configs.items(): data = { - 'ext': ext, + 'ext': None, 'colorscheme_configs': colorscheme_configs, 'import_paths': import_paths, 'main_config': main_config, 'theme_configs': theme_configs, - 'ext_theme_configs': configs, + 'ext_theme_configs': None, 'colors_config': colors_config } data['theme_type'] = 'top' diff --git a/powerline/lint/checks.py b/powerline/lint/checks.py index 52abdb78..24c91f43 100644 --- a/powerline/lint/checks.py +++ b/powerline/lint/checks.py @@ -33,7 +33,7 @@ generic_keys = set(( )) type_keys = { 'function': set(('function', 'args', 'draw_inner_divider')), - 'string': set(('contents', 'type', 'highlight_group', 'divider_highlight_group')), + 'string': set(('contents', 'type', 'highlight_groups', 'divider_highlight_group')), 'segment_list': set(('function', 'segments', 'args', 'type')), } required_keys = { @@ -41,7 +41,7 @@ required_keys = { 'string': set(()), 'segment_list': set(('function', 'segments',)), } -highlight_keys = set(('highlight_group', 'name')) +highlight_keys = set(('highlight_groups', 'name')) def get_function_strings(function_name, context, ext): @@ -281,7 +281,7 @@ def check_key_compatibility(segment, data, context, echoerr): context_mark=context[-1][1].mark, problem=( 'found missing keys required to determine highlight group. ' - 'Either highlight_group or name key must be present' + 'Either highlight_groups or name key must be present' ) ) hadproblem = True @@ -344,6 +344,28 @@ def check_full_segment_data(segment, data, context, echoerr): return check_key_compatibility(segment_copy, data, context, echoerr) +highlight_group_spec = Spec().ident().copy +_highlight_group_spec = highlight_group_spec().context_message( + 'Error while checking function documentation while checking theme (key {key})') + + +def check_hl_group_name(hl_group, context_mark, context, echoerr): + '''Check highlight group name: it should match naming conventions + + :param str hl_group: + Checked group. + :param Mark context_mark: + Context mark. May be ``None``. + :param Context context: + Current context. + :param func echoerr: + Function used for error reporting. + + :return: ``False`` if check succeeded and ``True`` if it failed. + ''' + return _highlight_group_spec.match(hl_group, context_mark=context_mark, context=context, echoerr=echoerr)[1] + + def check_segment_function(function_name, data, context, echoerr): havemarks(function_name) ext = data['ext'] @@ -385,13 +407,16 @@ def check_segment_function(function_name, data, context, echoerr): if r: echoerr( context='Error while checking theme (key {key})'.format(key=context.key), + context_mark=function_name.mark, problem=( 'found highlight group {0} not defined in the following colorschemes: {1}\n' '(Group name was obtained from function documentation.)' ).format(divider_hl_group, list_sep.join(r)), - problem_mark=function_name.mark + problem_mark=divider_hl_group.mark, ) hadproblem = True + if check_hl_group_name(divider_hl_group, function_name.mark, context, echoerr): + hadproblem = True if hl_groups: greg = re.compile(r'``([^`]+)``( \(gradient\))?') @@ -409,6 +434,8 @@ def check_segment_function(function_name, data, context, echoerr): match.group(1), Mark(*mark_args, pointer=sub_pointer + match.start(1)) ) + if check_hl_group_name(hl_group, function_name.mark, context, echoerr): + hadproblem = True gradient = bool(match.group(2)) required_pack.append((hl_group, gradient)) finally: diff --git a/powerline/lint/imp.py b/powerline/lint/imp.py index d3966512..6e402132 100644 --- a/powerline/lint/imp.py +++ b/powerline/lint/imp.py @@ -21,18 +21,6 @@ class WithPath(object): def import_function(function_type, name, data, context, echoerr, module): havemarks(name, module) - if module == 'powerline.segments.common': - echoerr(context='Warning while checking segments (key {key})'.format(key=context.key), - context_mark=name.mark, - problem='module {0} is deprecated'.format(module), - problem_mark=module.mark) - - if module == 'powerline.segments.common.players' and name == 'now_playing': - echoerr(context='Warning while checking segments (key {key})'.format(key=context.key), - context_mark=name.mark, - problem='function {0}.{1} is deprecated: use {0}.{{player_name}} instead'.format(module, name), - problem_mark=module.mark) - with WithPath(data['import_paths']): try: func = getattr(__import__(str(module), fromlist=[str(name)]), str(name)) diff --git a/powerline/lint/markedjson/error.py b/powerline/lint/markedjson/error.py index 7ee65217..d63c638a 100644 --- a/powerline/lint/markedjson/error.py +++ b/powerline/lint/markedjson/error.py @@ -42,15 +42,17 @@ def strtrans(s): class Mark: - def __init__(self, name, line, column, buffer, pointer): + def __init__(self, name, line, column, buffer, pointer, old_mark=None, merged_marks=None): self.name = name self.line = line self.column = column self.buffer = buffer self.pointer = pointer + self.old_mark = old_mark + self.merged_marks = merged_marks or [] def copy(self): - return Mark(self.name, self.line, self.column, self.buffer, self.pointer) + return Mark(self.name, self.line, self.column, self.buffer, self.pointer, self.old_mark, self.merged_marks[:]) def get_snippet(self, indent=4, max_length=75): if self.buffer is None: @@ -85,17 +87,57 @@ class Mark: ret.pointer += diff return ret - def __str__(self): - snippet = self.get_snippet() - where = (' in "%s", line %d, column %d' % ( - self.name, self.line + 1, self.column + 1)) - if snippet is not None: - where += ':\n' + snippet + def set_old_mark(self, old_mark): + if self is old_mark: + return + checked_marks = set([id(self)]) + older_mark = old_mark + while True: + if id(older_mark) in checked_marks: + raise ValueError('Trying to set recursive marks') + checked_marks.add(id(older_mark)) + older_mark = older_mark.old_mark + if not older_mark: + break + self.old_mark = old_mark + + def set_merged_mark(self, merged_mark): + self.merged_marks.append(merged_mark) + + def to_string(self, indent=0, head_text='in ', add_snippet=True): + mark = self + where = '' + processed_marks = set() + while mark: + indentstr = ' ' * indent + where += ('%s %s"%s", line %d, column %d' % ( + indentstr, head_text, mark.name, mark.line + 1, mark.column + 1)) + if add_snippet: + snippet = mark.get_snippet(indent=(indent + 4)) + if snippet: + where += ':\n' + snippet + if mark.merged_marks: + where += '\n' + indentstr + ' with additionally merged\n' + where += mark.merged_marks[0].to_string(indent + 4, head_text='', add_snippet=False) + for mmark in mark.merged_marks[1:]: + where += '\n' + indentstr + ' and\n' + where += mmark.to_string(indent + 4, head_text='', add_snippet=False) + if add_snippet: + processed_marks.add(id(mark)) + if mark.old_mark: + where += '\n' + indentstr + ' which replaced value\n' + indent += 4 + mark = mark.old_mark + if id(mark) in processed_marks: + raise ValueError('Trying to dump recursive mark') if type(where) is str: return where else: return where.encode('utf-8') + def __str__(self): + return self.to_string() + def echoerr(*args, **kwargs): stream = kwargs.pop('stream', sys.stderr) diff --git a/powerline/lint/markedjson/markedvalue.py b/powerline/lint/markedjson/markedvalue.py index c17a8e35..3b8db3e8 100644 --- a/powerline/lint/markedjson/markedvalue.py +++ b/powerline/lint/markedjson/markedvalue.py @@ -65,7 +65,28 @@ class MarkedDict(dict): r.keydict = dict(((key, key) for key in r)) return r + def setmerged(self, d): + try: + self.mark.set_merged_mark(d.mark) + except AttributeError: + pass + def __setitem__(self, key, value): + try: + old_value = self[key] + except KeyError: + pass + else: + try: + key.mark.set_old_mark(self.keydict[key].mark) + except AttributeError: + pass + except KeyError: + pass + try: + value.mark.set_old_mark(old_value.mark) + except AttributeError: + pass dict.__setitem__(self, key, value) self.keydict[key] = key diff --git a/powerline/matchers/vim/plugin/ctrlp.py b/powerline/matchers/vim/plugin/ctrlp.py deleted file mode 100644 index 56028649..00000000 --- a/powerline/matchers/vim/plugin/ctrlp.py +++ /dev/null @@ -1,33 +0,0 @@ -# vim:fileencoding=utf-8:noet -from __future__ import (unicode_literals, division, absolute_import, print_function) - -import os - -from powerline.bindings.vim import buffer_name - - -try: - import vim -except ImportError: - pass -else: - vim.command(''' - function! Powerline_plugin_ctrlp_main(...) - let b:powerline_ctrlp_type = 'main' - let b:powerline_ctrlp_args = a:000 - endfunction''') - - vim.command(''' - function! Powerline_plugin_ctrlp_prog(...) - let b:powerline_ctrlp_type = 'prog' - let b:powerline_ctrlp_args = a:000 - endfunction''') - - vim.command(''' - let g:ctrlp_status_func = {'main': 'Powerline_plugin_ctrlp_main', 'prog': 'Powerline_plugin_ctrlp_prog'} - ''') - - -def ctrlp(matcher_info): - name = buffer_name(matcher_info) - return name and os.path.basename(name) == b'ControlP' diff --git a/powerline/renderer.py b/powerline/renderer.py index e69abca1..6d9b56a7 100644 --- a/powerline/renderer.py +++ b/powerline/renderer.py @@ -291,7 +291,7 @@ class Renderer(object): line=line, output_raw=output_raw, output_width=output_width, - segment_info=segment_info, + segment_info=self.get_segment_info(segment_info, mode), theme=theme, ) @@ -310,7 +310,7 @@ class Renderer(object): def do_render(self, mode, width, side, line, output_raw, output_width, segment_info, theme): '''Like Renderer.render(), but accept theme in place of matcher_info ''' - segments = list(theme.get_segments(side, line, self.get_segment_info(segment_info, mode), mode)) + segments = list(theme.get_segments(side, line, segment_info, mode)) current_width = 0 @@ -492,7 +492,7 @@ class Renderer(object): ''' return string.translate(self.character_translations) - def hlstyle(fg=None, bg=None, attr=None): + def hlstyle(fg=None, bg=None, attrs=None): '''Output highlight style string. Assuming highlighted string looks like ``{style}{contents}`` this method @@ -501,10 +501,10 @@ class Renderer(object): ''' raise NotImplementedError - def hl(self, contents, fg=None, bg=None, attr=None): + def hl(self, contents, fg=None, bg=None, attrs=None): '''Output highlighted chunk. This implementation just outputs ``.hlstyle()`` joined with ``contents``. ''' - return self.hlstyle(fg, bg, attr) + (contents or '') + return self.hlstyle(fg, bg, attrs) + (contents or '') diff --git a/powerline/renderers/i3bar.py b/powerline/renderers/i3bar.py index 9fbdaa0b..dd180941 100644 --- a/powerline/renderers/i3bar.py +++ b/powerline/renderers/i3bar.py @@ -17,7 +17,7 @@ class I3barRenderer(Renderer): # We don’t need to explicitly reset attributes, so skip those calls return '' - def hl(self, contents, fg=None, bg=None, attr=None): + def hl(self, contents, fg=None, bg=None, attrs=None): segment = { 'full_text': contents, 'separator': False, diff --git a/powerline/renderers/ipython/__init__.py b/powerline/renderers/ipython/__init__.py index 985e6c34..3547fd2e 100644 --- a/powerline/renderers/ipython/__init__.py +++ b/powerline/renderers/ipython/__init__.py @@ -33,9 +33,16 @@ class IPythonRenderer(ShellRenderer): if 'theme' in match: match['theme'].shutdown() - def render(self, *args, **kwargs): + def render(self, **kwargs): # XXX super(ShellRenderer), *not* super(IPythonRenderer) - return super(ShellRenderer, self).render(*args, **kwargs) + return super(ShellRenderer, self).render(**kwargs) + + def do_render(self, segment_info, **kwargs): + segment_info.update(client_id='ipython') + return super(IPythonRenderer, self).do_render( + segment_info=segment_info, + **kwargs + ) class IPythonPromptRenderer(IPythonRenderer): diff --git a/powerline/renderers/pango_markup.py b/powerline/renderers/pango_markup.py index e0dfa481..1b7d624b 100644 --- a/powerline/renderers/pango_markup.py +++ b/powerline/renderers/pango_markup.py @@ -15,7 +15,7 @@ class PangoMarkupRenderer(Renderer): # We don’t need to explicitly reset attributes, so skip those calls return '' - def hl(self, contents, fg=None, bg=None, attr=None): + def hl(self, contents, fg=None, bg=None, attrs=None): '''Highlight a segment.''' awesome_attr = [] if fg is not None: @@ -24,12 +24,12 @@ class PangoMarkupRenderer(Renderer): if bg is not None: if bg is not False and bg[1] is not False: awesome_attr += ['background="#{0:06x}"'.format(bg[1])] - if attr is not None and attr is not False: - if attr & ATTR_BOLD: + if attrs is not None and attrs is not False: + if attrs & ATTR_BOLD: awesome_attr += ['font_weight="bold"'] - if attr & ATTR_ITALIC: + if attrs & ATTR_ITALIC: awesome_attr += ['font_style="italic"'] - if attr & ATTR_UNDERLINE: + if attrs & ATTR_UNDERLINE: awesome_attr += ['underline="single"'] return '' + contents + '' diff --git a/powerline/renderers/shell/__init__.py b/powerline/renderers/shell/__init__.py index 3318ff22..8b8b5c85 100644 --- a/powerline/renderers/shell/__init__.py +++ b/powerline/renderers/shell/__init__.py @@ -18,6 +18,7 @@ class ShellRenderer(Renderer): escape_hl_start = '' escape_hl_end = '' term_truecolor = False + term_escape_style = 'auto' tmux_escape = False screen_escape = False @@ -36,22 +37,29 @@ class ShellRenderer(Renderer): ) def do_render(self, output_width, segment_info, side, theme, width=None, **kwargs): + if self.term_escape_style == 'auto': + if segment_info['environ'].get('TERM') == 'fbterm': + self.used_term_escape_style = 'fbterm' + else: + self.used_term_escape_style = 'xterm' + else: + self.used_term_escape_style = self.term_escape_style if isinstance(segment_info, dict): client_id = segment_info.get('client_id') else: client_id = None - local_key = (client_id, side, None if theme is self.theme else id(theme)) - key = (client_id, side, None) - did_width = False - if local_key[-1] != key[-1] and side == 'left': - try: - width = self.old_widths[key] - except KeyError: - pass - else: - did_width = True - if not did_width: - if width is not None: + if client_id is not None: + local_key = (client_id, side, None if theme is self.theme else id(theme)) + key = (client_id, side, None) + did_width = False + if local_key[-1] != key[-1] and side == 'left': + try: + width = self.old_widths[key] + except KeyError: + pass + else: + did_width = True + if not did_width and width is not None: if theme.cursor_space_multiplier is not None: width = int(width * theme.cursor_space_multiplier) elif theme.cursor_columns: @@ -70,14 +78,15 @@ class ShellRenderer(Renderer): side=side, **kwargs ) - self.old_widths[local_key] = res[-1] + if client_id is not None: + self.old_widths[local_key] = res[-1] ret = res if output_width else res[:-1] if len(ret) == 1: return ret[0] else: return ret - def hlstyle(self, fg=None, bg=None, attr=None): + def hlstyle(self, fg=None, bg=None, attrs=None): '''Highlight a segment. If an argument is None, the argument is ignored. If an argument is @@ -85,11 +94,13 @@ class ShellRenderer(Renderer): is a valid color or attribute, it’s added to the ANSI escape code. ''' ansi = [0] + is_fbterm = self.used_term_escape_style == 'fbterm' + term_truecolor = not is_fbterm and self.term_truecolor if fg is not None: if fg is False or fg[0] is False: ansi += [39] else: - if self.term_truecolor: + if term_truecolor: ansi += [38, 2] + list(int_to_rgb(fg[1])) else: ansi += [38, 5, fg[0]] @@ -97,23 +108,37 @@ class ShellRenderer(Renderer): if bg is False or bg[0] is False: ansi += [49] else: - if self.term_truecolor: + if term_truecolor: ansi += [48, 2] + list(int_to_rgb(bg[1])) else: ansi += [48, 5, bg[0]] - if attr is not None: - if attr is False: + if attrs is not None: + if attrs is False: ansi += [22] else: - if attr & ATTR_BOLD: + if attrs & ATTR_BOLD: ansi += [1] - elif attr & ATTR_ITALIC: + elif attrs & ATTR_ITALIC: # Note: is likely not to work or even be inverse in place of # italic. Omit using this in colorschemes. ansi += [3] - elif attr & ATTR_UNDERLINE: + elif attrs & ATTR_UNDERLINE: ansi += [4] - r = '\033[{0}m'.format(';'.join(str(attr) for attr in ansi)) + if is_fbterm: + r = [] + while ansi: + cur_ansi = ansi.pop(0) + if cur_ansi == 38: + ansi.pop(0) + r.append('\033[1;{0}}}'.format(ansi.pop(0))) + elif cur_ansi == 48: + ansi.pop(0) + r.append('\033[2;{0}}}'.format(ansi.pop(0))) + else: + r.append('\033[{0}m'.format(cur_ansi)) + r = ''.join(r) + else: + r = '\033[{0}m'.format(';'.join(str(attr) for attr in ansi)) if self.tmux_escape: r = '\033Ptmux;' + r.replace('\033', '\033\033') + '\033\\' elif self.screen_escape: diff --git a/powerline/renderers/shell/rcsh.py b/powerline/renderers/shell/rcsh.py new file mode 100644 index 00000000..4bc01412 --- /dev/null +++ b/powerline/renderers/shell/rcsh.py @@ -0,0 +1,12 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +from powerline.renderers.shell import ShellRenderer + + +class RcshRenderer(ShellRenderer): + '''Powerline rcsh prompt renderer''' + escape_hl_start = '\x01' + escape_hl_end = '\x02' + +renderer = RcshRenderer diff --git a/powerline/renderers/tmux.py b/powerline/renderers/tmux.py index 7e7d5abd..ef832877 100644 --- a/powerline/renderers/tmux.py +++ b/powerline/renderers/tmux.py @@ -5,20 +5,20 @@ from powerline.renderer import Renderer from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE -def attr_to_tmux_attr(attr): - if attr is False: +def attrs_to_tmux_attrs(attrs): + if attrs is False: return ['nobold', 'noitalics', 'nounderscore'] else: ret = [] - if attr & ATTR_BOLD: + if attrs & ATTR_BOLD: ret += ['bold'] else: ret += ['nobold'] - if attr & ATTR_ITALIC: + if attrs & ATTR_ITALIC: ret += ['italics'] else: ret += ['noitalics'] - if attr & ATTR_UNDERLINE: + if attrs & ATTR_UNDERLINE: ret += ['underscore'] else: ret += ['nounderscore'] @@ -31,25 +31,25 @@ class TmuxRenderer(Renderer): character_translations = Renderer.character_translations.copy() character_translations[ord('#')] = '##[]' - def hlstyle(self, fg=None, bg=None, attr=None): + def hlstyle(self, fg=None, bg=None, attrs=None): '''Highlight a segment.''' # We don’t need to explicitly reset attributes, so skip those calls - if not attr and not bg and not fg: + if not attrs and not bg and not fg: return '' - tmux_attr = [] + tmux_attrs = [] if fg is not None: if fg is False or fg[0] is False: - tmux_attr += ['fg=default'] + tmux_attrs += ['fg=default'] else: - tmux_attr += ['fg=colour' + str(fg[0])] + tmux_attrs += ['fg=colour' + str(fg[0])] if bg is not None: if bg is False or bg[0] is False: - tmux_attr += ['bg=default'] + tmux_attrs += ['bg=default'] else: - tmux_attr += ['bg=colour' + str(bg[0])] - if attr is not None: - tmux_attr += attr_to_tmux_attr(attr) - return '#[' + ','.join(tmux_attr) + ']' + tmux_attrs += ['bg=colour' + str(bg[0])] + if attrs is not None: + tmux_attrs += attrs_to_tmux_attrs(attrs) + return '#[' + ','.join(tmux_attrs) + ']' def get_segment_info(self, segment_info, mode): r = self.segment_info.copy() diff --git a/powerline/renderers/vim.py b/powerline/renderers/vim.py index 58c690dd..281177ce 100644 --- a/powerline/renderers/vim.py +++ b/powerline/renderers/vim.py @@ -5,7 +5,7 @@ import sys import vim -from powerline.bindings.vim import vim_get_func, vim_getoption, environ, current_tabpage +from powerline.bindings.vim import vim_get_func, vim_getoption, environ, current_tabpage, get_vim_encoding from powerline.renderer import Renderer from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE from powerline.theme import Theme @@ -42,7 +42,7 @@ class VimRenderer(Renderer): self.hl_groups = {} self.prev_highlight = None self.strwidth_error_name = register_strwidth_error(self.strwidth) - self.encoding = vim.eval('&encoding') + self.encoding = get_vim_encoding() def shutdown(self): self.theme.shutdown() @@ -123,7 +123,7 @@ class VimRenderer(Renderer): def reset_highlight(self): self.hl_groups.clear() - def hlstyle(self, fg=None, bg=None, attr=None): + def hlstyle(self, fg=None, bg=None, attrs=None): '''Highlight a segment. If an argument is None, the argument is ignored. If an argument is @@ -132,23 +132,23 @@ class VimRenderer(Renderer): ''' # In order not to hit E541 two consequent identical highlighting # specifiers may be squashed into one. - attr = attr or 0 # Normalize `attr` - if (fg, bg, attr) == self.prev_highlight: + attrs = attrs or 0 # Normalize `attrs` + if (fg, bg, attrs) == self.prev_highlight: return '' - self.prev_highlight = (fg, bg, attr) + self.prev_highlight = (fg, bg, attrs) # We don’t need to explicitly reset attributes in vim, so skip those # calls - if not attr and not bg and not fg: + if not attrs and not bg and not fg: return '' - if not (fg, bg, attr) in self.hl_groups: + if not (fg, bg, attrs) in self.hl_groups: hl_group = { 'ctermfg': 'NONE', 'guifg': None, 'ctermbg': 'NONE', 'guibg': None, - 'attr': ['NONE'], + 'attrs': ['NONE'], 'name': '', } if fg is not None and fg is not False: @@ -157,32 +157,32 @@ class VimRenderer(Renderer): if bg is not None and bg is not False: hl_group['ctermbg'] = bg[0] hl_group['guibg'] = bg[1] - if attr: - hl_group['attr'] = [] - if attr & ATTR_BOLD: - hl_group['attr'].append('bold') - if attr & ATTR_ITALIC: - hl_group['attr'].append('italic') - if attr & ATTR_UNDERLINE: - hl_group['attr'].append('underline') + if attrs: + hl_group['attrs'] = [] + if attrs & ATTR_BOLD: + hl_group['attrs'].append('bold') + if attrs & ATTR_ITALIC: + hl_group['attrs'].append('italic') + if attrs & ATTR_UNDERLINE: + hl_group['attrs'].append('underline') hl_group['name'] = ( 'Pl_' + str(hl_group['ctermfg']) + '_' + str(hl_group['guifg']) + '_' + str(hl_group['ctermbg']) + '_' + str(hl_group['guibg']) + '_' - + ''.join(hl_group['attr']) + + ''.join(hl_group['attrs']) ) - self.hl_groups[(fg, bg, attr)] = hl_group - vim.command('hi {group} ctermfg={ctermfg} guifg={guifg} guibg={guibg} ctermbg={ctermbg} cterm={attr} gui={attr}'.format( + self.hl_groups[(fg, bg, attrs)] = hl_group + vim.command('hi {group} ctermfg={ctermfg} guifg={guifg} guibg={guibg} ctermbg={ctermbg} cterm={attrs} gui={attrs}'.format( group=hl_group['name'], ctermfg=hl_group['ctermfg'], guifg='#{0:06x}'.format(hl_group['guifg']) if hl_group['guifg'] is not None else 'NONE', ctermbg=hl_group['ctermbg'], guibg='#{0:06x}'.format(hl_group['guibg']) if hl_group['guibg'] is not None else 'NONE', - attr=','.join(hl_group['attr']), + attrs=','.join(hl_group['attrs']), )) - return '%#' + self.hl_groups[(fg, bg, attr)]['name'] + '#' + return '%#' + self.hl_groups[(fg, bg, attrs)]['name'] + '#' renderer = VimRenderer diff --git a/powerline/segment.py b/powerline/segment.py index edcda434..7864cf31 100644 --- a/powerline/segment.py +++ b/powerline/segment.py @@ -142,7 +142,7 @@ def set_segment_highlighting(pl, colorscheme, segment, mode): hl_groups = lambda hlgs: [highlight_group_prefix + ':' + hlg for hlg in hlgs] + hlgs try: segment['highlight'] = colorscheme.get_highlighting( - hl_groups(segment['highlight_group']), + hl_groups(segment['highlight_groups']), mode, segment.get('gradient_level') ) @@ -220,6 +220,30 @@ def process_segment(pl, side, segment_info, parsed_segments, segment, mode, colo always_true = lambda pl, segment_info, mode: True +get_fallback_segment = { + 'name': 'fallback', + 'type': 'string', + 'highlight_groups': ['background'], + 'divider_highlight_group': None, + 'before': None, + 'after': None, + 'contents': '', + 'priority': None, + 'draw_soft_divider': True, + 'draw_hard_divider': True, + 'draw_inner_divider': True, + 'display_condition': always_true, + 'width': None, + 'align': None, + 'expand': None, + 'truncate': None, + 'startup': None, + 'shutdown': None, + '_rendered_raw': '', + '_rendered_hl': '', + '_len': None, + '_contents_len': None, +}.copy def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, get_module_attr, top_theme): data = { @@ -311,9 +335,9 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge pass if segment_type == 'function': - highlight_group = [function_name] + highlight_groups = [function_name] else: - highlight_group = segment.get('highlight_group') or name + highlight_groups = segment.get('highlight_groups') or [name] if segment_type in ('function', 'segment_list'): args = dict(( @@ -336,7 +360,7 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge return { 'name': name or function_name, 'type': segment_type, - 'highlight_group': None, + 'highlight_groups': None, 'divider_highlight_group': None, 'before': None, 'after': None, @@ -391,7 +415,7 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge return { 'name': name or function_name, 'type': segment_type, - 'highlight_group': highlight_group, + 'highlight_groups': highlight_groups, 'divider_highlight_group': None, 'before': get_key(False, segment, module, function_name, name, 'before', ''), 'after': get_key(False, segment, module, function_name, name, 'after', ''), diff --git a/powerline/segments/common/__init__.py b/powerline/segments/common/__init__.py index f5ec2fa9..e69de29b 100644 --- a/powerline/segments/common/__init__.py +++ b/powerline/segments/common/__init__.py @@ -1,26 +0,0 @@ -# vim:fileencoding=utf-8:noet -from __future__ import (unicode_literals, division, absolute_import, print_function) - - -# DEPRECATED MODULE. Do not add any segments below. Do not remove existing -# segments as well until next major release. - - -from powerline.segments.common.vcs import branch # NOQA -from powerline.segments.common.sys import cpu_load_percent # NOQA -from powerline.segments.common.sys import uptime # NOQA -from powerline.segments.common.sys import system_load # NOQA -from powerline.segments.common.net import hostname # NOQA -from powerline.segments.common.net import external_ip # NOQA -from powerline.segments.common.net import internal_ip # NOQA -from powerline.segments.common.net import network_load # NOQA -from powerline.segments.common.env import cwd # NOQA -from powerline.segments.common.env import user # NOQA -from powerline.segments.common.env import environment # NOQA -from powerline.segments.common.env import virtualenv # NOQA -from powerline.segments.common.bat import battery # NOQA -from powerline.segments.common.wthr import weather # NOQA -from powerline.segments.common.time import date # NOQA -from powerline.segments.common.time import fuzzy_time # NOQA -from powerline.segments.common.mail import email_imap_alert # NOQA -from powerline.segments.common.players import now_playing # NOQA diff --git a/powerline/segments/common/bat.py b/powerline/segments/common/bat.py index 713bc149..ba0eaa97 100644 --- a/powerline/segments/common/bat.py +++ b/powerline/segments/common/bat.py @@ -27,7 +27,7 @@ def _get_battery(pl): try: up = bus.get_object(interface, '/org/freedesktop/UPower') except dbus.exceptions.DBusException as e: - if getattr(e, '_dbus_error_name', '').endswidth('ServiceUnknown'): + if getattr(e, '_dbus_error_name', '').endswith('ServiceUnknown'): pl.debug('Not using DBUS+UPower as UPower is not available via dbus') else: pl.exception('Failed to get UPower service with dbus: {0}', str(e)) @@ -95,7 +95,7 @@ def _get_battery(pl): else: pl.debug('Not using pmset: executable not found') - if sys.platform.startswith('win'): + if sys.platform.startswith('win') or sys.platform == 'cygwin': # From http://stackoverflow.com/a/21083571/273566, reworked try: from win32com.client import GetObject @@ -116,9 +116,15 @@ def _get_battery(pl): return _get_capacity pl.debug('Not using win32com.client as no batteries were found') - - from ctypes import Structure, c_byte, c_ulong, windll, byref - + from ctypes import Structure, c_byte, c_ulong, byref + if sys.platform == 'cygwin': + pl.debug('Using cdll to communicate with kernel32 (Cygwin)') + from ctypes import cdll + library_loader = cdll + else: + pl.debug('Using windll to communicate with kernel32 (Windows)') + from ctypes import windll + library_loader = windll class PowerClass(Structure): _fields_ = [ ('ACLineStatus', c_byte), @@ -131,7 +137,7 @@ def _get_battery(pl): def _get_capacity(pl): powerclass = PowerClass() - result = windll.kernel32.GetSystemPowerStatus(byref(powerclass)) + result = library_loader.kernel32.GetSystemPowerStatus(byref(powerclass)) # http://msdn.microsoft.com/en-us/library/windows/desktop/aa372693(v=vs.85).aspx if result: return None @@ -200,21 +206,21 @@ def battery(pl, format='{capacity:3.0%}', steps=5, gamify=False, full_heart='O', ret.append({ 'contents': full_heart * numer, 'draw_inner_divider': False, - 'highlight_group': ['battery_full', 'battery_gradient', 'battery'], + 'highlight_groups': ['battery_full', 'battery_gradient', 'battery'], # Using zero as “nothing to worry about”: it is least alert color. 'gradient_level': 0, }) ret.append({ 'contents': empty_heart * (denom - numer), 'draw_inner_divider': False, - 'highlight_group': ['battery_empty', 'battery_gradient', 'battery'], + 'highlight_groups': ['battery_empty', 'battery_gradient', 'battery'], # Using a hundred as it is most alert color. 'gradient_level': 100, }) else: ret.append({ 'contents': format.format(capacity=(capacity / 100.0)), - 'highlight_group': ['battery_gradient', 'battery'], + 'highlight_groups': ['battery_gradient', 'battery'], # Gradients are “least alert – most alert” by default, capacity has # the opposite semantics. 'gradient_level': 100 - capacity, diff --git a/powerline/segments/common/env.py b/powerline/segments/common/env.py index f6c49c55..0ba7be5f 100644 --- a/powerline/segments/common/env.py +++ b/powerline/segments/common/env.py @@ -84,7 +84,7 @@ class CwdSegment(Segment): 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': draw_inner_divider, }) - ret[-1]['highlight_group'] = ['cwd:current_folder', 'cwd'] + ret[-1]['highlight_groups'] = ['cwd:current_folder', 'cwd'] if use_path_separator: ret[-1]['contents'] = ret[-1]['contents'][:-1] if len(ret) > 1 and ret[0]['contents'][0] == os.sep: @@ -134,8 +134,13 @@ except ImportError: except ImportError: from getpass import getuser as _get_user else: + try: + from os import geteuid as getuid + except ImportError: + from os import getuid + def _get_user(): - return pwd.getpwuid(os.geteuid()).pw_name + return pwd.getpwuid(getuid()).pw_name username = False @@ -164,5 +169,5 @@ def user(pl, hide_user=None): euid = _geteuid() return [{ 'contents': username, - 'highlight_group': ['user'] if euid != 0 else ['superuser', 'user'], + 'highlight_groups': ['user'] if euid != 0 else ['superuser', 'user'], }] diff --git a/powerline/segments/common/mail.py b/powerline/segments/common/mail.py index dc266f36..5bc87c73 100644 --- a/powerline/segments/common/mail.py +++ b/powerline/segments/common/mail.py @@ -42,12 +42,12 @@ class EmailIMAPSegment(KwThreadedSegment): elif type(unread_count) != int or not max_msgs: return [{ 'contents': str(unread_count), - 'highlight_group': ['email_alert'], + 'highlight_groups': ['email_alert'], }] else: return [{ 'contents': str(unread_count), - 'highlight_group': ['email_alert_gradient', 'email_alert'], + 'highlight_groups': ['email_alert_gradient', 'email_alert'], 'gradient_level': min(unread_count * 100.0 / max_msgs, 100), }] diff --git a/powerline/segments/common/net.py b/powerline/segments/common/net.py index 74ae60d9..46a294db 100644 --- a/powerline/segments/common/net.py +++ b/powerline/segments/common/net.py @@ -68,7 +68,7 @@ Divider highlight group used: ``background:divider``. try: import netifaces except ImportError: - def internal_ip(pl, interface='detect', ipv=4): + def internal_ip(pl, interface='auto', ipv=4): return None else: _interface_starts = { @@ -100,8 +100,8 @@ else: else: return 0 - def internal_ip(pl, interface='detect', ipv=4): - if interface == 'detect': + def internal_ip(pl, interface='auto', ipv=4): + if interface == 'auto': try: interface = next(iter(sorted(netifaces.interfaces(), key=_interface_key, reverse=True))) except StopIteration: @@ -120,7 +120,7 @@ internal_ip = with_docstring(internal_ip, Requires ``netifaces`` module to work properly. :param str interface: - Interface on which IP will be checked. Use ``detect`` to automatically + Interface on which IP will be checked. Use ``auto`` to automatically detect interface. In this case interfaces with lower numbers will be preferred over interfaces with similar names. Order of preference based on names: @@ -174,11 +174,11 @@ class NetworkLoadSegment(KwThreadedSegment): replace_num_pat = re.compile(r'[a-zA-Z]+') @staticmethod - def key(interface='detect', **kwargs): + def key(interface='auto', **kwargs): return interface def compute_state(self, interface): - if interface == 'detect': + if interface == 'auto': proc_exists = getattr(self, 'proc_exists', None) if proc_exists is None: proc_exists = self.proc_exists = os.path.exists('/proc/net/route') @@ -192,7 +192,7 @@ class NetworkLoadSegment(KwThreadedSegment): if not destination.replace(b'0', b''): interface = iface.decode('utf-8') break - if interface == 'detect': + if interface == 'auto': # Choose interface with most total activity, excluding some # well known interface names interface, total = 'eth0', -1 @@ -248,7 +248,7 @@ class NetworkLoadSegment(KwThreadedSegment): r.append({ 'contents': format.format(value=humanize_bytes(value, suffix, si_prefix)), 'divider_highlight_group': 'background:divider', - 'highlight_group': hl_groups, + 'highlight_groups': hl_groups, }) if is_gradient: max = kwargs[max_key] @@ -268,21 +268,24 @@ falls back to reading :file:`/sys/class/net/{interface}/statistics/{rx,tx}_bytes`. :param str interface: - network interface to measure (use the special value "detect" to have powerline try to auto-detect the network interface) + Network interface to measure (use the special value "auto" to have powerline + try to auto-detect the network interface). :param str suffix: - string appended to each load string + String appended to each load string. :param bool si_prefix: - use SI prefix, e.g. MB instead of MiB + Use SI prefix, e.g. MB instead of MiB. :param str recv_format: - format string, receives ``value`` as argument + Format string that determines how download speed should look like. Receives + ``value`` as argument. :param str sent_format: - format string, receives ``value`` as argument + Format string that determines how upload speed should look like. Receives + ``value`` as argument. :param float recv_max: - maximum number of received bytes per second. Is only used to compute - gradient level + Maximum number of received bytes per second. Is only used to compute + gradient level. :param float sent_max: - maximum number of sent bytes per second. Is only used to compute gradient - level + Maximum number of sent bytes per second. Is only used to compute gradient + level. Divider highlight group used: ``background:divider``. diff --git a/powerline/segments/common/players.py b/powerline/segments/common/players.py index c6922e03..4f10cc6f 100644 --- a/powerline/segments/common/players.py +++ b/powerline/segments/common/players.py @@ -50,7 +50,7 @@ class PlayerSegment(Segment): stats['state_symbol'] = state_symbols.get(stats['state']) return [{ 'contents': format.format(**stats), - 'highlight_group': ['now_playing', 'player_' + (stats['state'] or 'fallback'), 'player'], + 'highlight_groups': ['player_' + (stats['state'] or 'fallback'), 'player'], }] def get_player_status(self, pl): @@ -437,7 +437,7 @@ class RDIOPlayerSegment(PlayerSegment): now_playing = asrun(pl, ascript) if not now_playing: return - now_playing = now_playing.split('\n') + now_playing = now_playing.split(status_delimiter) if len(now_playing) != 6: return state = _convert_state(now_playing[5]) @@ -460,24 +460,3 @@ Requires ``osascript`` available in $PATH. {0} ''').format(_common_args.format('rdio'))) - - -class NowPlayingSegment(Segment): - def __call__(self, player='mpd', **kwargs): - player_segment = globals()[player] - assert(isinstance(player_segment, PlayerSegment)) - return player_segment(**kwargs) - - def argspecobjs(self): - for ret in super(NowPlayingSegment, self).argspecobjs(): - yield ret - yield '__call__', PlayerSegment.__call__ - for k, v in globals().items(): - if isinstance(v, type) and issubclass(v, PlayerSegment) and v is not DbusPlayerSegment: - yield 'get_player_status', v.get_player_status - - def omitted_args(self, name, method): - return (0,) - - -now_playing = NowPlayingSegment() diff --git a/powerline/segments/common/sys.py b/powerline/segments/common/sys.py index d3a56307..70d5fe81 100644 --- a/powerline/segments/common/sys.py +++ b/powerline/segments/common/sys.py @@ -57,7 +57,7 @@ def system_load(pl, format='{avg:.1f}', threshold_good=1, threshold_bad=2, track gradient_level = 100 ret.append({ 'contents': format.format(avg=avg), - 'highlight_group': ['system_load_gradient', 'system_load'], + 'highlight_groups': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': gradient_level, }) @@ -88,7 +88,7 @@ try: return [{ 'contents': format.format(cpu_percent), 'gradient_level': cpu_percent, - 'highlight_group': ['cpu_load_percent_gradient', 'cpu_load_percent'], + 'highlight_groups': ['cpu_load_percent_gradient', 'cpu_load_percent'], }] except ImportError: class CPULoadPercentSegment(ThreadedSegment): diff --git a/powerline/segments/common/time.py b/powerline/segments/common/time.py index f13e196e..84518c77 100644 --- a/powerline/segments/common/time.py +++ b/powerline/segments/common/time.py @@ -18,7 +18,7 @@ def date(pl, format='%Y-%m-%d', istime=False): ''' return [{ 'contents': datetime.now().strftime(format), - 'highlight_group': (['time'] if istime else []) + ['date'], + 'highlight_groups': (['time'] if istime else []) + ['date'], 'divider_highlight_group': 'time:divider' if istime else None, }] diff --git a/powerline/segments/common/vcs.py b/powerline/segments/common/vcs.py index 401741b2..90e4e772 100644 --- a/powerline/segments/common/vcs.py +++ b/powerline/segments/common/vcs.py @@ -35,7 +35,7 @@ class BranchSegment(Segment): scol.insert(0, 'branch_dirty' if status else 'branch_clean') return [{ 'contents': branch, - 'highlight_group': scol, + 'highlight_groups': scol, 'divider_highlight_group': self.divider_highlight_group, }] diff --git a/powerline/segments/common/wthr.py b/powerline/segments/common/wthr.py index 38d7e4b3..30a36a4d 100644 --- a/powerline/segments/common/wthr.py +++ b/powerline/segments/common/wthr.py @@ -38,7 +38,7 @@ weather_conditions_codes = ( ('fog', 'foggy' ), # 20 ('haze', 'foggy' ), # 21 ('smoky', 'foggy' ), # 22 - ('blustery', 'foggy' ), # 23 + ('blustery', 'windy' ), # 23 ('windy', ), # 24 ('cold', 'day' ), # 25 ('clouds', 'cloudy'), # 26 @@ -188,12 +188,12 @@ class WeatherSegment(KwThreadedSegment): return [ { 'contents': icon + ' ', - 'highlight_group': groups, + 'highlight_groups': groups, 'divider_highlight_group': 'background:divider', }, { 'contents': temp_format.format(temp=converted_temp), - 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], + 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'divider_highlight_group': 'background:divider', 'gradient_level': gradient_level, }, diff --git a/powerline/segments/i3wm.py b/powerline/segments/i3wm.py index 1a290c78..f3987adf 100644 --- a/powerline/segments/i3wm.py +++ b/powerline/segments/i3wm.py @@ -23,5 +23,5 @@ def workspaces(pl): ''' return [{ 'contents': w['name'], - 'highlight_group': calcgrp(w) + 'highlight_groups': calcgrp(w) } for w in i3.get_workspaces()] diff --git a/powerline/segments/shell.py b/powerline/segments/shell.py index 1b763723..57847e4f 100644 --- a/powerline/segments/shell.py +++ b/powerline/segments/shell.py @@ -30,7 +30,7 @@ def last_status(pl, segment_info): ''' if not segment_info['args'].last_exit_code: return None - return [{'contents': str(segment_info['args'].last_exit_code), 'highlight_group': ['exit_fail']}] + return [{'contents': str(segment_info['args'].last_exit_code), 'highlight_groups': ['exit_fail']}] @requires_segment_info @@ -44,7 +44,7 @@ def last_pipe_status(pl, segment_info): return [ { 'contents': str(status), - 'highlight_group': ['exit_fail' if status else 'exit_success'], + 'highlight_groups': ['exit_fail' if status else 'exit_success'], 'draw_inner_divider': True } for status in last_pipe_status @@ -65,11 +65,11 @@ def mode(pl, segment_info, override={'vicmd': 'COMMND', 'viins': 'INSERT'}, defa ``$POWERLINE_DEFAULT_MODE`` variable. This variable is set by zsh bindings for any mode that does not start from ``vi``. ''' - mode = segment_info['mode'] + mode = segment_info.get('mode', None) if not mode: - pl.debug('No or empty _POWERLINE_MODE variable') + pl.debug('No mode specified') return None - default = default or segment_info['environ'].get('_POWERLINE_DEFAULT_MODE') + default = default or segment_info.get('default_mode', None) if mode == default: return None try: @@ -78,9 +78,9 @@ def mode(pl, segment_info, override={'vicmd': 'COMMND', 'viins': 'INSERT'}, defa # Note: with zsh line editor you can emulate as much modes as you wish. # Thus having unknown mode is not an error: maybe just some developer # added support for his own zle widgets. As there is no built-in mode() - # function like in VimL and _POWERLINE_MODE is likely be defined by our - # code or by somebody knowing what he is doing there is absolutely no - # need in keeping translations dictionary. + # function like in VimL and mode is likely be defined by our code or by + # somebody knowing what he is doing there is absolutely no need in + # keeping translations dictionary. return mode.upper() @@ -102,7 +102,7 @@ def continuation(pl, segment_info, omit_cmdsubst=True, right_align=False, rename return [{ 'contents': '', 'width': 'auto', - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], }] ret = [] @@ -111,7 +111,7 @@ def continuation(pl, segment_info, omit_cmdsubst=True, right_align=False, rename if state: ret.append({ 'contents': state, - 'highlight_group': ['continuation'], + 'highlight_groups': ['continuation'], 'draw_inner_divider': True, }) @@ -125,9 +125,9 @@ def continuation(pl, segment_info, omit_cmdsubst=True, right_align=False, rename if right_align: ret[0].update(width='auto', align='r') - ret[-1]['highlight_group'] = ['continuation:current', 'continuation'] + ret[-1]['highlight_groups'] = ['continuation:current', 'continuation'] else: - ret[-1].update(width='auto', align='l', highlight_group=['continuation:current', 'continuation']) + ret[-1].update(width='auto', align='l', highlight_groups=['continuation:current', 'continuation']) return ret @@ -157,7 +157,7 @@ Returns a segment list to create a breadcrumb-like effect. :param bool use_path_separator: Use path separator in place of soft divider. :param bool use_shortened_path: - Use path from shortened_path ``--renderer_arg`` argument. If this argument + Use path from shortened_path ``--renderer-arg`` argument. If this argument is present ``shorten_home`` argument is ignored. :param bool shorten_home: Shorten home directory to ``~``. diff --git a/powerline/segments/vim/__init__.py b/powerline/segments/vim/__init__.py index 545d696e..77702191 100644 --- a/powerline/segments/vim/__init__.py +++ b/powerline/segments/vim/__init__.py @@ -177,7 +177,7 @@ def tab_modified_indicator(pl, segment_info, text='+'): if int(vim_getbufoption(buf_segment_info, 'modified')): return [{ 'contents': text, - 'highlight_group': ['tab_modified_indicator', 'modified_indicator'], + 'highlight_groups': ['tab_modified_indicator', 'modified_indicator'], }] return None @@ -289,7 +289,7 @@ def file_name(pl, segment_info, display_no_file=False, no_file_text='[No file]') if display_no_file: return [{ 'contents': no_file_text, - 'highlight_group': ['file_name_no_file', 'file_name'], + 'highlight_groups': ['file_name_no_file', 'file_name'], }] else: return None @@ -380,7 +380,7 @@ def line_percent(pl, segment_info, gradient=False): return str(int(round(percentage))) return [{ 'contents': str(int(round(percentage))), - 'highlight_group': ['line_percent_gradient', 'line_percent'], + 'highlight_groups': ['line_percent_gradient', 'line_percent'], 'gradient_level': percentage, }] @@ -418,7 +418,7 @@ def position(pl, position_strings={'top': 'Top', 'bottom': 'Bot', 'all': 'All'}, return content return [{ 'contents': content, - 'highlight_group': ['position_gradient', 'position'], + 'highlight_groups': ['position_gradient', 'position'], 'gradient_level': percentage, }] @@ -452,11 +452,11 @@ def virtcol_current(pl, gradient=True): Highlight groups used: ``virtcol_current_gradient`` (gradient), ``virtcol_current`` or ``col_current``. ''' col = vim_funcs['virtcol']('.') - r = [{'contents': str(col), 'highlight_group': ['virtcol_current', 'col_current']}] + r = [{'contents': str(col), 'highlight_groups': ['virtcol_current', 'col_current']}] if gradient: textwidth = int(getbufvar('%', '&textwidth')) r[-1]['gradient_level'] = min(col * 100 / textwidth, 100) if textwidth else 0 - r[-1]['highlight_group'].insert(0, 'virtcol_current_gradient') + r[-1]['highlight_groups'].insert(0, 'virtcol_current_gradient') return r @@ -530,7 +530,7 @@ def file_vcs_status(pl, segment_info, create_watcher): for status in status: ret.append({ 'contents': status, - 'highlight_group': ['file_vcs_status_' + status, 'file_vcs_status'], + 'highlight_groups': ['file_vcs_status_' + status, 'file_vcs_status'], }) return ret @@ -579,7 +579,7 @@ def trailing_whitespace(pl, segment_info): if has_trailing_ws: ret = [{ 'contents': str(i + 1), - 'highlight_group': ['trailing_whitespace', 'warning'], + 'highlight_groups': ['trailing_whitespace', 'warning'], }] else: ret = None @@ -735,8 +735,8 @@ def csv_col_current(pl, segment_info, display_name='auto', name_format=' ({colum return None return [{ 'contents': column_number, - 'highlight_group': ['csv:column_number', 'csv'], + 'highlight_groups': ['csv:column_number', 'csv'], }] + ([{ 'contents': name_format.format(column_name=column_name), - 'highlight_group': ['csv:column_name', 'csv'], + 'highlight_groups': ['csv:column_name', 'csv'], }] if column_name else []) diff --git a/powerline/segments/vim/plugin/commandt.py b/powerline/segments/vim/plugin/commandt.py index fcaa6712..7b8007f3 100644 --- a/powerline/segments/vim/plugin/commandt.py +++ b/powerline/segments/vim/plugin/commandt.py @@ -54,7 +54,7 @@ def finder(pl): initialize() vim.command('ruby $powerline.commandt_set_active_finder') return [{ - 'highlight_group': ['commandt:finder'], + 'highlight_groups': ['commandt:finder'], 'contents': vim.eval('g:powerline_commandt_reply').replace('CommandT::', '').replace('Finder::', '') }] @@ -88,6 +88,6 @@ def path(pl): return None vim.command('ruby $powerline.commandt_set_path') return [{ - 'highlight_group': ['commandt:path'], + 'highlight_groups': ['commandt:path'], 'contents': vim.eval('g:powerline_commandt_reply') }] diff --git a/powerline/segments/vim/plugin/ctrlp.py b/powerline/segments/vim/plugin/ctrlp.py deleted file mode 100644 index 80cabb76..00000000 --- a/powerline/segments/vim/plugin/ctrlp.py +++ /dev/null @@ -1,116 +0,0 @@ -# vim:fileencoding=utf-8:noet -from __future__ import (unicode_literals, division, absolute_import, print_function) - -try: - import vim -except ImportError: - vim = object() - -from powerline.bindings.vim import getbufvar -from powerline.segments.vim import window_cached - - -@window_cached -def ctrlp(pl, side): - ''' - - Highlight groups used: ``ctrlp.regex`` or ``background``, ``ctrlp.prev`` or ``background``, ``ctrlp.item`` or ``file_name``, ``ctrlp.next`` or ``background``, ``ctrlp.marked`` or ``background``, ``ctrlp.focus`` or ``background``, ``ctrlp.byfname`` or ``background``, ``ctrlp.progress`` or ``file_name``, ``ctrlp.progress`` or ``file_name``. - ''' - ctrlp_type = getbufvar('%', 'powerline_ctrlp_type') - ctrlp_args = getbufvar('%', 'powerline_ctrlp_args') - - return globals()['ctrlp_stl_{0}_{1}'.format(side, ctrlp_type)](pl, *ctrlp_args) - - -def ctrlp_stl_left_main(pl, focus, byfname, regex, prev, item, next, marked): - ''' - - Highlight groups used: ``ctrlp.regex`` or ``background``, ``ctrlp.prev`` or ``background``, ``ctrlp.item`` or ``file_name``, ``ctrlp.next`` or ``background``, ``ctrlp.marked`` or ``background``. - ''' - marked = marked[2:-1] - segments = [] - - if int(regex): - segments.append({ - 'contents': 'regex', - 'highlight_group': ['ctrlp.regex', 'background'], - }) - - segments += [ - { - 'contents': prev + ' ', - 'highlight_group': ['ctrlp.prev', 'background'], - 'draw_inner_divider': True, - 'priority': 40, - }, - { - 'contents': item, - 'highlight_group': ['ctrlp.item', 'file_name'], - 'draw_inner_divider': True, - 'width': 10, - 'align': 'c', - }, - { - 'contents': ' ' + next, - 'highlight_group': ['ctrlp.next', 'background'], - 'draw_inner_divider': True, - 'priority': 40, - }, - ] - - if marked != '-': - segments.append({ - 'contents': marked, - 'highlight_group': ['ctrlp.marked', 'background'], - 'draw_inner_divider': True, - }) - - return segments - - -def ctrlp_stl_right_main(pl, focus, byfname, regex, prev, item, next, marked): - ''' - - Highlight groups used: ``ctrlp.focus`` or ``background``, ``ctrlp.byfname`` or ``background``. - ''' - segments = [ - { - 'contents': focus, - 'highlight_group': ['ctrlp.focus', 'background'], - 'draw_inner_divider': True, - 'priority': 50, - }, - { - 'contents': byfname, - 'highlight_group': ['ctrlp.byfname', 'background'], - 'priority': 50, - }, - ] - - return segments - - -def ctrlp_stl_left_prog(pl, progress): - ''' - - Highlight groups used: ``ctrlp.progress`` or ``file_name``. - ''' - return [ - { - 'contents': 'Loading...', - 'highlight_group': ['ctrlp.progress', 'file_name'], - }, - ] - - -def ctrlp_stl_right_prog(pl, progress): - ''' - - Highlight groups used: ``ctrlp.progress`` or ``file_name``. - ''' - return [ - { - 'contents': progress, - 'highlight_group': ['ctrlp.progress', 'file_name'], - }, - ] diff --git a/powerline/segments/vim/plugin/nerdtree.py b/powerline/segments/vim/plugin/nerdtree.py index 79aba991..f11be14b 100644 --- a/powerline/segments/vim/plugin/nerdtree.py +++ b/powerline/segments/vim/plugin/nerdtree.py @@ -14,12 +14,12 @@ from powerline.segments.vim import window_cached def nerdtree(pl): '''Return directory that is shown by the current buffer. - Highlight groups used: ``nerdtree.path`` or ``file_name``. + Highlight groups used: ``nerdtree:path`` or ``file_name``. ''' if not bufvar_exists(None, 'NERDTreeRoot'): return None path_str = vim.eval('getbufvar("%", "NERDTreeRoot").path.str()') return [{ 'contents': path_str, - 'highlight_group': ['nerdtree.path', 'file_name'], + 'highlight_groups': ['nerdtree:path', 'file_name'], }] diff --git a/powerline/segments/vim/plugin/syntastic.py b/powerline/segments/vim/plugin/syntastic.py index c03edbdc..5bef3c7f 100644 --- a/powerline/segments/vim/plugin/syntastic.py +++ b/powerline/segments/vim/plugin/syntastic.py @@ -20,7 +20,7 @@ def syntastic(pl, err_format='ERR:  {first_line} ({num}) ', warn_format='WARN :param str warn_format: Format string for warnings. - Highlight groups used: ``syntastic.warning`` or ``warning``, ``syntastic.error`` or ``error``. + Highlight groups used: ``syntastic:warning`` or ``warning``, ``syntastic:error`` or ``error``. ''' if not vim_global_exists('SyntasticLoclist'): return None @@ -33,11 +33,11 @@ def syntastic(pl, err_format='ERR:  {first_line} ({num}) ', warn_format='WARN if errors: segments.append({ 'contents': err_format.format(first_line=errors[0]['lnum'], num=len(errors)), - 'highlight_group': ['syntastic.error', 'error'], + 'highlight_groups': ['syntastic:error', 'error'], }) if warnings: segments.append({ 'contents': warn_format.format(first_line=warnings[0]['lnum'], num=len(warnings)), - 'highlight_group': ['syntastic.warning', 'warning'], + 'highlight_groups': ['syntastic:warning', 'warning'], }) return segments diff --git a/powerline/shell.py b/powerline/shell.py index f04ff33b..e10692c1 100644 --- a/powerline/shell.py +++ b/powerline/shell.py @@ -2,25 +2,24 @@ from __future__ import (unicode_literals, division, absolute_import, print_function) from powerline import Powerline -from powerline.lib import mergedicts +from powerline.lib.dict import mergedicts class ShellPowerline(Powerline): def init(self, args, **kwargs): self.args = args - self.theme_option = args.theme_option super(ShellPowerline, self).init(args.ext[0], args.renderer_module, **kwargs) def load_main_config(self): r = super(ShellPowerline, self).load_main_config() - if self.args.config: - mergedicts(r, self.args.config) + if self.args.config_override: + mergedicts(r, self.args.config_override) return r def load_theme_config(self, name): r = super(ShellPowerline, self).load_theme_config(name) - if self.theme_option and name in self.theme_option: - mergedicts(r, self.theme_option[name]) + if self.args.theme_override and name in self.args.theme_override: + mergedicts(r, self.args.theme_override[name]) return r def get_config_paths(self): diff --git a/powerline/theme.py b/powerline/theme.py index 53921e43..26b67a3b 100644 --- a/powerline/theme.py +++ b/powerline/theme.py @@ -3,8 +3,8 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct import itertools -from powerline.segment import gen_segment_getter, process_segment -from powerline.lib.unicode import u +from powerline.segment import gen_segment_getter, process_segment, get_fallback_segment +from powerline.lib.unicode import u, safe_unicode def requires_segment_info(func): @@ -72,7 +72,7 @@ class Theme(object): self.segments = [] self.EMPTY_SEGMENT = { 'contents': None, - 'highlight': {'fg': False, 'bg': False, 'attr': 0} + 'highlight': {'fg': False, 'bg': False, 'attrs': 0} } self.pl = pl theme_configs = [theme_config] @@ -146,23 +146,36 @@ class Theme(object): self.colorscheme, ) for segment in parsed_segments: - width = segment['width'] - align = segment['align'] - if width == 'auto' and segment['expand'] is None: - segment['expand'] = expand_functions.get(align) - if segment['expand'] is None: - self.pl.error('Align argument must be “r”, “l” or “c”, not “{0}”', align) + self.pl.prefix = segment['name'] + try: + width = segment['width'] + align = segment['align'] + if width == 'auto' and segment['expand'] is None: + segment['expand'] = expand_functions.get(align) + if segment['expand'] is None: + self.pl.error('Align argument must be “r”, “l” or “c”, not “{0}”', align) - segment['contents'] = segment['before'] + u(segment['contents'] if segment['contents'] is not None else '') + segment['after'] - # Align segment contents - if segment['width'] and segment['width'] != 'auto': - if segment['align'] == 'l': - segment['contents'] = segment['contents'].ljust(segment['width']) - elif segment['align'] == 'r': - segment['contents'] = segment['contents'].rjust(segment['width']) - elif segment['align'] == 'c': - segment['contents'] = segment['contents'].center(segment['width']) - # We need to yield a copy of the segment, or else mode-dependent - # segment contents can’t be cached correctly e.g. when caching - # non-current window contents for vim statuslines - yield segment.copy() + try: + segment['contents'] = segment['before'] + u( + segment['contents'] if segment['contents'] is not None else '' + ) + segment['after'] + except Exception as e: + self.pl.exception('Failed to compute segment contents: {0}', str(e)) + segment['contents'] = safe_unicode(segment.get('contents')) + # Align segment contents + if segment['width'] and segment['width'] != 'auto': + if segment['align'] == 'l': + segment['contents'] = segment['contents'].ljust(segment['width']) + elif segment['align'] == 'r': + segment['contents'] = segment['contents'].rjust(segment['width']) + elif segment['align'] == 'c': + segment['contents'] = segment['contents'].center(segment['width']) + # We need to yield a copy of the segment, or else mode-dependent + # segment contents can’t be cached correctly e.g. when caching + # non-current window contents for vim statuslines + yield segment.copy() + except Exception as e: + self.pl.exception('Failed to compute segment: {0}', str(e)) + fallback = get_fallback_segment() + fallback.update(side=side) + yield fallback diff --git a/powerline/tmux.py b/powerline/tmux.py deleted file mode 100644 index 15f42127..00000000 --- a/powerline/tmux.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim:fileencoding=utf-8:noet -from __future__ import (unicode_literals, division, absolute_import, print_function) - -from powerline import Powerline - - -class TmuxPowerline(Powerline): - def init(self, config_paths): - self.paths = config_paths - return super(TmuxPowerline, self).init('tmux') - - def get_config_paths(self): - if self.paths: - return self.paths - else: - return super(TmuxPowerline, self).get_config_paths() diff --git a/powerline/vim.py b/powerline/vim.py index 29c82bdf..b93788a8 100644 --- a/powerline/vim.py +++ b/powerline/vim.py @@ -3,25 +3,50 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct import sys import json +import logging from itertools import count import vim -from powerline.bindings.vim import vim_get_func, vim_getvar +from powerline.bindings.vim import vim_get_func, vim_getvar, get_vim_encoding, python_to_vim from powerline import Powerline, FailedUnicode -from powerline.lib import mergedicts +from powerline.lib.dict import mergedicts +from powerline.lib.unicode import u -def _override_from(config, override_varname): +def _override_from(config, override_varname, key=None): try: overrides = vim_getvar(override_varname) except KeyError: return config + if key is not None: + try: + overrides = overrides[key] + except KeyError: + return config mergedicts(config, overrides) return config +class VimVarHandler(logging.Handler, object): + '''Vim-specific handler which emits messages to Vim global variables + + Used variable: ``g:powerline_log_messages``. + ''' + def __init__(self, *args, **kwargs): + super(VimVarHandler, self).__init__(*args, **kwargs) + vim.command('unlet! g:powerline_log_messages') + vim.command('let g:powerline_log_messages = []') + + @staticmethod + def emit(record): + message = u(record.message) + if record.exc_text: + message += '\n' + u(record.exc_text) + vim.eval(b'add(g:powerline_log_messages, ' + python_to_vim(message) + b')') + + class VimPowerline(Powerline): def init(self, pyeval='PowerlinePyeval', **kwargs): super(VimPowerline, self).init('vim', **kwargs) @@ -31,6 +56,18 @@ class VimPowerline(Powerline): default_log_stream = sys.stdout + def create_logger(self): + logger = super(VimPowerline, self).create_logger() + try: + if int(vim_getvar('powerline_use_var_handler')): + formatter = logging.Formatter(self.common_config['log_format']) + handler = VimVarHandler(getattr(logging, self.common_config['log_level'])) + handler.setFormatter(formatter) + logger.addHandler(handler) + except KeyError: + pass + return logger + def add_local_theme(self, key, config): '''Add local themes at runtime (during vim session). @@ -73,20 +110,16 @@ class VimPowerline(Powerline): self.setup_kwargs.setdefault('_local_themes', []).append((key, config)) return True - @staticmethod - def get_encoding(): - return vim.eval('&encoding') + get_encoding = staticmethod(get_vim_encoding) def load_main_config(self): return _override_from(super(VimPowerline, self).load_main_config(), 'powerline_config_overrides') def load_theme_config(self, name): - # Note: themes with non-[a-zA-Z0-9_] names are impossible to override - # (though as far as I know exists() won’t throw). Won’t fix, use proper - # theme names. return _override_from( super(VimPowerline, self).load_theme_config(name), - 'powerline_theme_overrides__' + name + 'powerline_theme_overrides', + name ) def get_local_themes(self, local_themes): diff --git a/scripts/powerline-daemon b/scripts/powerline-daemon index 7e78b6b0..82841878 100755 --- a/scripts/powerline-daemon +++ b/scripts/powerline-daemon @@ -75,11 +75,14 @@ def render(args, environ, cwd): key = ( args.ext[0], args.renderer_module, - tuple(args.config) if args.config else None, - tuple(args.theme_option) if args.theme_option else None, + tuple(args.config_override) if args.config_override else None, + tuple(args.theme_override) if args.theme_override else None, tuple(args.config_path) if args.config_path else None, + environ.get('POWERLINE_THEME_OVERRIDES', ''), + environ.get('POWERLINE_CONFIG_OVERRIDES', ''), + environ.get('POWERLINE_CONFIG_PATHS', ''), ) - finish_args(args) + finish_args(environ, args) powerline = None try: powerline = powerlines[key] @@ -353,7 +356,8 @@ def lockpidfile(): def main(): global address global pidfile - args = get_daemon_argparser().parse_args() + parser = get_daemon_argparser() + args = parser.parse_args() if args.socket: address = args.socket @@ -373,6 +377,8 @@ def main(): pidfile = address + '.pid' if args.kill: + if args.foreground or args.replace: + parser.error('--kill and --foreground/--replace cannot be used together') if kill_daemon(): if not args.quiet: print ('Kill command sent to daemon, if it does not die in a couple of seconds use kill to kill it') diff --git a/scripts/powerline-render b/scripts/powerline-render index 5e4eb05a..07016705 100755 --- a/scripts/powerline-render +++ b/scripts/powerline-render @@ -24,7 +24,7 @@ else: if __name__ == '__main__': args = get_argparser().parse_args() - finish_args(args) + finish_args(os.environ, args) powerline = ShellPowerline(args, run_once=True) segment_info = {'args': args, 'environ': os.environ} write_output(args, powerline, segment_info, write, get_preferred_output_encoding()) diff --git a/setup.py b/setup.py index f95dcf99..06ffce2b 100644 --- a/setup.py +++ b/setup.py @@ -6,6 +6,7 @@ import os import sys import subprocess import logging +import shlex from setuptools import setup, find_packages @@ -27,7 +28,10 @@ def compile_client(): else: from distutils.ccompiler import new_compiler compiler = new_compiler().compiler - subprocess.check_call(compiler + ['-O3', 'client/powerline.c', '-o', 'scripts/powerline']) + cflags = os.environ.get('CFLAGS', '-O3') + # A normal split would do a split on each space which might be incorrect. The + # shlex will not split if a space occurs in an arguments value. + subprocess.check_call(compiler + shlex.split(cflags) + ['client/powerline.c', '-o', 'scripts/powerline']) try: compile_client() @@ -62,7 +66,7 @@ def get_version(): setup( name='powerline-status', - version='1.3.1', + version='2.0', description='The ultimate statusline/prompt utility.', long_description=README, classifiers=[ @@ -82,10 +86,10 @@ setup( 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', ], - download_url='https://github.com/Lokaltog/powerline/archive/develop.zip', + download_url='https://github.com/powerline/powerline/archive/develop.zip', author='Kim Silkebaekken', author_email='kim.silkebaekken+vim@gmail.com', - url='https://github.com/Lokaltog/powerline', + url='https://github.com/powerline/powerline', license='MIT', # XXX Python 3 doesn’t allow compiled C files to be included in the scripts # list below. This is because Python 3 distutils tries to decode the file to diff --git a/tests/install.sh b/tests/install.sh index 42ef7650..974971a5 100755 --- a/tests/install.sh +++ b/tests/install.sh @@ -1,28 +1,57 @@ -#!/bin/sh -pip install . -pip install psutil netifaces -if python -c 'import sys; sys.exit(1 * (sys.version_info[0] != 2))' ; then - # Python 2 - if python -c 'import platform, sys; sys.exit(1 - (platform.python_implementation() == "CPython"))' ; then - # PyPy - pip install mercurial - pip install --allow-external bzr --allow-unverified bzr bzr - fi - if python -c 'import sys; sys.exit(1 * (sys.version_info[1] >= 7))' ; then - # Python 2.6 - pip install unittest2 argparse - else - # Python 2.7 - pip install ipython +#!/bin/bash +git clone --depth=1 git://github.com/powerline/bot-ci tests/bot-ci +git clone --depth=1 git://github.com/powerline/deps tests/bot-ci/deps + +. tests/bot-ci/scripts/common/main.sh + +sudo apt-get install -qq libssl1.0.0 +sudo apt-get install -qq screen zsh tcsh mksh busybox socat realpath bc rc tmux + +if test -n "$USE_UCS2_PYTHON" ; then + pip install virtualenvwrapper + set +e + . virtualenvwrapper.sh + set -e + archive="${PWD:-$(pwd)}/tests/bot-ci/deps/cpython-ucs2/cpython-ucs2-${UCS2_PYTHON_VARIANT}.tar.gz" + sudo sh -c "cd /opt && tar xzf $archive" + PYTHON="/opt/cpython-ucs2-$UCS2_PYTHON_VARIANT/bin/python$UCS2_PYTHON_VARIANT" + export LD_LIBRARY_PATH="/opt/cpython-ucs2-$UCS2_PYTHON_VARIANT/lib${LD_LIBRARY_PATH:+:}${LD_LIBRARY_PATH}" + set +e + mkvirtualenv -p "$PYTHON" cpython-ucs2-$UCS2_PYTHON_VARIANT + set -e + . tests/bot-ci/scripts/common/main.sh + pip install . + if test "$UCS2_PYTHON_VARIANT" = "2.6" ; then + rm tests/bot-ci/deps/wheels/ucs2-CPython-${UCS2_PYTHON_VARIANT}*/pyuv*.whl fi + pip install --no-deps tests/bot-ci/deps/wheels/ucs2-CPython-${UCS2_PYTHON_VARIANT}*/*.whl else - # Python 3 - if python -c 'import sys; sys.exit(1 * (sys.version_info < (3, 3)))' ; then - # Python 3.3+ - pip install ipython + pip install . + # FIXME Uv watcher sometimes misses events and INotify is not available in + # Python-2.6, thus pyuv should be removed in order for VCS tests to + # pass. + if test "$PYTHON_VERSION_MAJOR" -eq 2 && test "$PYTHON_VERSION_MINOR" -lt 7 ; then + rm tests/bot-ci/deps/wheels/$PYTHON_SUFFIX/pyuv*.whl fi + pip install --no-deps tests/bot-ci/deps/wheels/$PYTHON_SUFFIX/*.whl fi -sudo apt-get install -qq screen zsh tcsh mksh busybox socat +if test "$PYTHON_IMPLEMENTATION" = "CPython" ; then + archive="${PWD:-$(pwd)}/tests/bot-ci/deps/zpython/zsh-${PYTHON_MM}${USE_UCS2_PYTHON:+-ucs2}.tar.gz" + sudo sh -c "cd /opt && tar xzf $archive" +fi + +archive="${PWD:-$(pwd)}/tests/bot-ci/deps/fish/fish.tar.gz" +sudo sh -c "cd /opt && tar xzf $archive" + +mkdir tests/vim-plugins + +for archive in "$ROOT"/tests/bot-ci/deps/vim-plugins/*.tar.gz ; do + ( + cd tests/vim-plugins + tar -xzvf "$archive" + ) +done + # Travis has too outdated fish. It cannot be used for tests. # sudo apt-get install fish true diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py index 2b5af567..b9c0d3ad 100644 --- a/tests/lib/__init__.py +++ b/tests/lib/__init__.py @@ -23,8 +23,8 @@ class Pl(object): class Args(object): - theme_option = {} - config = None + theme_override = {} + config_override = {} config_path = None ext = ['shell'] renderer_module = None diff --git a/tests/lib/config_mock.py b/tests/lib/config_mock.py index 7161ea28..dd19ff11 100644 --- a/tests/lib/config_mock.py +++ b/tests/lib/config_mock.py @@ -114,16 +114,16 @@ class Logger(object): class SimpleRenderer(Renderer): - def hlstyle(self, fg=None, bg=None, attr=None): - return '<{fg} {bg} {attr}>'.format(fg=fg and fg[0], bg=bg and bg[0], attr=attr) + def hlstyle(self, fg=None, bg=None, attrs=None): + return '<{fg} {bg} {attrs}>'.format(fg=fg and fg[0], bg=bg and bg[0], attrs=attrs) class EvenSimplerRenderer(Renderer): - def hlstyle(self, fg=None, bg=None, attr=None): - return '{{{fg}{bg}{attr}}}'.format( + def hlstyle(self, fg=None, bg=None, attrs=None): + return '{{{fg}{bg}{attrs}}}'.format( fg=fg and fg[0] or '-', bg=bg and bg[0] or '-', - attr=attr if attr else '', + attrs=attrs if attrs else '', ) diff --git a/tests/lib/fsconfig.py b/tests/lib/fsconfig.py index a1066f65..248a3a70 100644 --- a/tests/lib/fsconfig.py +++ b/tests/lib/fsconfig.py @@ -5,8 +5,8 @@ import os import json from subprocess import check_call -from operator import add from shutil import rmtree +from itertools import chain from powerline import Powerline @@ -64,9 +64,12 @@ class FSTree(object): ) if os.environ.get('POWERLINE_RUN_LINT_DURING_TESTS'): try: - check_call(['scripts/powerline-lint'] + reduce(add, ( - ['-p', d] for d in self.p.get_config_paths() - ))) + check_call(chain(['scripts/powerline-lint'], *[ + ('-p', d) for d in ( + self.p.get_config_paths() if self.p + else self.get_config_paths(self.root) + ) + ])) except: self.__exit__() raise diff --git a/tests/lib/terminal.py b/tests/lib/terminal.py new file mode 100644 index 00000000..f026ec57 --- /dev/null +++ b/tests/lib/terminal.py @@ -0,0 +1,59 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +import threading + +from time import sleep + +import pexpect + +from tests.lib.vterm import VTerm + + +class ExpectProcess(threading.Thread): + def __init__(self, lib, rows, cols, cmd, args, cwd=None, env=None): + super(ExpectProcess, self).__init__() + self.vterm = VTerm(lib, rows, cols) + self.lock = threading.Lock() + self.rows = rows + self.cols = cols + self.cmd = cmd + self.args = args + self.cwd = cwd + self.env = env + self.buffer = [] + self.child_lock = threading.Lock() + + def run(self): + child = pexpect.spawn(self.cmd, self.args, cwd=self.cwd, env=self.env) + sleep(0.5) + child.setwinsize(self.rows, self.cols) + self.child = child + status = None + while status is None: + try: + with self.child_lock: + s = child.read_nonblocking(size=1024, timeout=0) + status = child.status + except pexpect.TIMEOUT: + pass + except pexpect.EOF: + break + else: + with self.lock: + self.vterm.push(s) + self.buffer.append(s) + + def __getitem__(self, position): + with self.lock: + return self.vterm.vtscreen[position] + + def read(self): + with self.lock: + ret = b''.join(self.buffer) + del self.buffer[:] + return ret + + def send(self, data): + with self.child_lock: + self.child.send(data) diff --git a/tests/lib/vterm.py b/tests/lib/vterm.py new file mode 100644 index 00000000..c83235ec --- /dev/null +++ b/tests/lib/vterm.py @@ -0,0 +1,178 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +import ctypes + +from powerline.lib.unicode import unicode, unichr, tointiter + + +class CTypesFunction(object): + def __init__(self, library, name, rettype, args): + self.name = name + self.prototype = ctypes.CFUNCTYPE(rettype, *[ + arg[1] for arg in args + ]) + self.args = args + self.func = self.prototype((name, library), tuple(( + (1, arg[0]) for arg in args + ))) + + def __call__(self, *args, **kwargs): + return self.func(*args, **kwargs) + + def __repr__(self): + return '{cls}(, {name!r}, {rettype!r}, {args!r})'.format( + cls=self.__class__.__name__, + **self.__dict__ + ) + + +class CTypesLibraryFuncsCollection(object): + def __init__(self, lib, **kwargs): + self.lib = lib + library_loader = ctypes.LibraryLoader(ctypes.CDLL) + library = library_loader.LoadLibrary(lib) + self.library = library + for name, args in kwargs.items(): + self.__dict__[name] = CTypesFunction(library, name, *args) + + +class VTermPos_s(ctypes.Structure): + _fields_ = ( + ('row', ctypes.c_int), + ('col', ctypes.c_int), + ) + + +class VTermColor_s(ctypes.Structure): + _fields_ = ( + ('red', ctypes.c_uint8), + ('green', ctypes.c_uint8), + ('blue', ctypes.c_uint8), + ) + + +class VTermScreenCellAttrs_s(ctypes.Structure): + _fields_ = ( + ('bold', ctypes.c_uint, 1), + ('underline', ctypes.c_uint, 2), + ('italic', ctypes.c_uint, 1), + ('blink', ctypes.c_uint, 1), + ('reverse', ctypes.c_uint, 1), + ('strike', ctypes.c_uint, 1), + ('font', ctypes.c_uint, 4), + ('dwl', ctypes.c_uint, 1), + ('dhl', ctypes.c_uint, 2), + ) + + +VTERM_MAX_CHARS_PER_CELL = 6 + + +class VTermScreenCell_s(ctypes.Structure): + _fields_ = ( + ('chars', ctypes.ARRAY(ctypes.c_uint32, VTERM_MAX_CHARS_PER_CELL)), + ('width', ctypes.c_char), + ('attrs', VTermScreenCellAttrs_s), + ('fg', VTermColor_s), + ('bg', VTermColor_s), + ) + + +VTerm_p = ctypes.c_void_p +VTermScreen_p = ctypes.c_void_p + + +def get_functions(lib): + return CTypesLibraryFuncsCollection( + lib, + vterm_new=(VTerm_p, ( + ('rows', ctypes.c_int), + ('cols', ctypes.c_int) + )), + vterm_obtain_screen=(VTermScreen_p, (('vt', VTerm_p),)), + vterm_screen_reset=(None, ( + ('screen', VTermScreen_p), + ('hard', ctypes.c_int) + )), + vterm_input_write=(ctypes.c_size_t, ( + ('vt', VTerm_p), + ('bytes', ctypes.POINTER(ctypes.c_char)), + ('size', ctypes.c_size_t), + )), + vterm_screen_get_cell=(ctypes.c_int, ( + ('screen', VTermScreen_p), + ('pos', VTermPos_s), + ('cell', ctypes.POINTER(VTermScreenCell_s)) + )), + vterm_free=(None, (('vt', VTerm_p),)), + ) + + +class VTermColor(object): + __slots__ = ('red', 'green', 'blue') + + def __init__(self, color): + self.red = color.red + self.green = color.green + self.blue = color.blue + + @property + def color_key(self): + return (self.red, self.green, self.blue) + + +class VTermScreenCell(object): + def __init__(self, vtsc): + for field in VTermScreenCellAttrs_s._fields_: + field_name = field[0] + setattr(self, field_name, getattr(vtsc.attrs, field_name)) + self.text = ''.join(( + unichr(vtsc.chars[i]) for i in range(VTERM_MAX_CHARS_PER_CELL) + )).rstrip('\x00') + self.width = next(tointiter(vtsc.width)) + self.fg = VTermColor(vtsc.fg) + self.bg = VTermColor(vtsc.bg) + self.cell_properties_key = ( + self.fg.color_key, + self.bg.color_key, + self.bold, + self.underline, + self.italic, + ) + + +class VTermScreen(object): + def __init__(self, functions, screen): + self.functions = functions + self.screen = screen + + def __getitem__(self, position): + pos = VTermPos_s(*position) + cell = VTermScreenCell_s() + ret = self.functions.vterm_screen_get_cell(self.screen, pos, cell) + if ret != 1: + raise ValueError('vterm_screen_get_cell returned {0}'.format(ret)) + return VTermScreenCell(cell) + + def reset(self, hard): + self.functions.vterm_screen_reset(self.screen, int(bool(hard))) + + +class VTerm(object): + def __init__(self, lib, rows, cols): + self.functions = get_functions(lib) + self.vt = self.functions.vterm_new(rows, cols) + self.vtscreen = VTermScreen(self.functions, self.functions.vterm_obtain_screen(self.vt)) + self.vtscreen.reset(True) + + def push(self, data): + if isinstance(data, unicode): + data = data.encode('utf-8') + return self.functions.vterm_input_write(self.vt, data, len(data)) + + def __del__(self): + try: + self.functions.vterm_free(self.vt) + except AttributeError: + pass diff --git a/tests/run_vim_tests.sh b/tests/run_vim_tests.sh index ef82ab35..5fdc3975 100755 --- a/tests/run_vim_tests.sh +++ b/tests/run_vim_tests.sh @@ -1,11 +1,62 @@ #!/bin/sh +. tests/bot-ci/scripts/common/main.sh FAILED=0 -for script in tests/*.vim ; do - if ! vim -u NONE -S $script || test -f message.fail ; then - echo "Failed script $script" >&2 + +if test -z "$VIM" ; then + if test -n "$USE_UCS2_PYTHON" ; then + NEW_VIM="$ROOT/tests/bot-ci/deps/vim/tip-$UCS2_PYTHON_VARIANT-ucs2-double/vim" + OLD_VIM="$ROOT/tests/bot-ci/deps/vim/v7-0-112-$UCS2_PYTHON_VARIANT-ucs2/vim" + opt_dir="/opt/cpython-ucs2-$UCS2_PYTHON_VARIANT" + main_path="$opt_dir/lib/python$UCS2_PYTHON_VARIANT" + site_path="$main_path/site-packages" + venv_main_path="$VIRTUAL_ENV/lib/python$UCS2_PYTHON_VARIANT" + venv_site_path="$venv_main_path/site-packages" + new_paths="${main_path}:${site_path}:${venv_main_path}:${venv_site_path}" + export PYTHONPATH="$new_paths${PYTHONPATH:+:}$PYTHONPATH" + else + if test "$PYTHON_IMPLEMENTATION" != "CPython" ; then + exit 0 + fi + NEW_VIM="$ROOT/tests/bot-ci/deps/vim/tip-$PYTHON_MM/vim" + OLD_VIM="$ROOT/tests/bot-ci/deps/vim/v7-0-112-$PYTHON_MM/vim" + if test -e "$OLD_VIM" ; then + VIMS="NEW_VIM OLD_VIM" + else + VIMS="NEW_VIM" + fi + fi +else + NEW_VIM="$VIM" + OLD_VIM="$VIM" +fi + +# Define some overrides. These ones must be ignored and do not affect Vim +# status/tab lines. +export POWERLINE_CONFIG_OVERRIDES='common.default_top_theme=ascii' +export POWERLINE_THEME_OVERRIDES='default.segments.left=[]' + +test_script() { + local vim="$1" + local script="$2" + echo "Running script $script with $vim" + if ! "$vim" -u NONE -S $script || test -f message.fail ; then + echo "Failed script $script run with $VIM" >&2 cat message.fail >&2 rm message.fail FAILED=1 fi +} + +for script in tests/test_*.vim ; do + if test "${script%.old.vim}" = "${script}" ; then + test_script "$NEW_VIM" "$script" + fi done + +if test -e "$OLD_VIM" ; then + for script in tests/test_*.old.vim ; do + test_script "$OLD_VIM" "$script" + done +fi + exit $FAILED diff --git a/tests/run_vterm_tests.sh b/tests/run_vterm_tests.sh new file mode 100755 index 00000000..312b817d --- /dev/null +++ b/tests/run_vterm_tests.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e +FAILED=0 +if ! sh tests/test_in_vterm/test.sh ; then + echo "Failed vterm" + FAILED=1 +fi +exit $FAILED diff --git a/tests/setup_statusline_catcher.py b/tests/setup_statusline_catcher.py new file mode 100644 index 00000000..014a2e94 --- /dev/null +++ b/tests/setup_statusline_catcher.py @@ -0,0 +1,18 @@ +# vim:fileencoding=utf-8:noet +import json + +import vim + +from powerline.lib.unicode import u + + +_powerline_old_render = powerline.render # NOQA + + +def _powerline_test_render_function(*args, **kwargs): + ret = _powerline_old_render(*args, **kwargs) + vim.eval('add(g:statusline_values, %s)' % json.dumps(u(ret))) + return ret + + +powerline.render = _powerline_test_render_function # NOQA diff --git a/tests/terminfo/s/screen b/tests/terminfo/s/screen new file mode 100644 index 00000000..d3800727 Binary files /dev/null and b/tests/terminfo/s/screen differ diff --git a/tests/terminfo/s/st-256color b/tests/terminfo/s/st-256color new file mode 100644 index 00000000..9c2db048 Binary files /dev/null and b/tests/terminfo/s/st-256color differ diff --git a/tests/test.sh b/tests/test.sh index c1195f3f..62b525df 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -1,7 +1,24 @@ -#!/bin/sh +#!/bin/bash +. tests/bot-ci/scripts/common/main.sh + FAILED=0 + +export PATH="/opt/fish/bin:${PATH}" + +if test "$PYTHON_IMPLEMENTATION" = "CPython" ; then + export PATH="/opt/zsh-${PYTHON_MM}${USE_UCS2_PYTHON:+-ucs2}/bin:${PATH}" +fi + +if test -n "$USE_UCS2_PYTHON" ; then + export LD_LIBRARY_PATH="/opt/cpython-ucs2-$UCS2_PYTHON_VARIANT/lib${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH" + set +e + . virtualenvwrapper.sh + workon cpython-ucs2-$UCS2_PYTHON_VARIANT + set -e +fi + export PYTHON="${PYTHON:=python}" -export PYTHONPATH="${PYTHONPATH}:`realpath .`" +export PYTHONPATH="${PYTHONPATH}${PYTHONPATH:+:}`realpath .`" for script in tests/run_*_tests.sh ; do if ! sh $script ; then echo "Failed $script" diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index 57a67456..af3562a3 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -37,18 +37,18 @@ class TestParser(TestCase): (['shell', '-t'], 'expected one argument'), (['shell', '-p'], 'expected one argument'), (['shell', '-R'], 'expected one argument'), - (['shell', '--renderer_module'], 'expected one argument'), + (['shell', '--renderer-module'], 'expected one argument'), (['shell', '--width'], 'expected one argument'), - (['shell', '--last_exit_code'], 'expected one argument'), - (['shell', '--last_pipe_status'], 'expected one argument'), - (['shell', '--config'], 'expected one argument'), - (['shell', '--theme_option'], 'expected one argument'), - (['shell', '--config_path'], 'expected one argument'), - (['shell', '--renderer_arg'], 'expected one argument'), + (['shell', '--last-exit-code'], 'expected one argument'), + (['shell', '--last-pipe-status'], 'expected one argument'), + (['shell', '--config-override'], 'expected one argument'), + (['shell', '--theme-override'], 'expected one argument'), + (['shell', '--config-path'], 'expected one argument'), + (['shell', '--renderer-arg'], 'expected one argument'), (['shell', '--jobnum'], 'expected one argument'), (['-r', '.zsh'], 'too few arguments|the following arguments are required: ext'), - (['shell', '--last_exit_code', 'i'], 'invalid int value'), - (['shell', '--last_pipe_status', '1 i'], 'invalid value'), + (['shell', '--last-exit-code', 'i'], 'invalid int_or_sig value'), + (['shell', '--last-pipe-status', '1 i'], 'invalid value'), ]: self.assertRaises(SystemExit, parser.parse_args, raising_args) self.assertFalse(out.getvalue()) @@ -67,8 +67,8 @@ class TestParser(TestCase): 'shell', 'left', '-r', '.zsh', - '--last_exit_code', '10', - '--last_pipe_status', '10 20 30', + '--last-exit-code', '10', + '--last-pipe-status', '10 20 30', '--jobnum=10', '-w', '100', '-c', 'common.term_truecolor=true', @@ -85,8 +85,8 @@ class TestParser(TestCase): 'last_pipe_status': [10, 20, 30], 'jobnum': 10, 'width': 100, - 'config': {'common': {'term_truecolor': True, 'spaces': 4}}, - 'theme_option': { + 'config_override': {'common': {'term_truecolor': True, 'spaces': 4}}, + 'theme_override': { 'default': { 'segment_data': { 'hostname': { @@ -103,7 +103,7 @@ class TestParser(TestCase): (['shell', '-R', 'arg='], {'ext': ['shell'], 'renderer_arg': {}}), (['shell', '-t', 'default.segment_info={"hostname": {}}'], { 'ext': ['shell'], - 'theme_option': { + 'theme_override': { 'default': { 'segment_info': { 'hostname': {} @@ -111,10 +111,10 @@ class TestParser(TestCase): } }, }), - (['shell', '-c', 'common={ }'], {'ext': ['shell'], 'config': {'common': {}}}), + (['shell', '-c', 'common={ }'], {'ext': ['shell'], 'config_override': {'common': {}}}), ]: args = parser.parse_args(argv) - finish_args(args) + finish_args({}, args) for key, val in expargs.items(): self.assertEqual(getattr(args, key), val) for key, val in args.__dict__.items(): diff --git a/tests/test_commandt_plugin.vim b/tests/test_commandt_plugin.vim new file mode 100755 index 00000000..355fff7c --- /dev/null +++ b/tests/test_commandt_plugin.vim @@ -0,0 +1,17 @@ +#!/usr/bin/vim -S +set nocompatible +set columns=80 +execute 'source' fnameescape(expand(':p:h').'/vim_utils.vim') +call EnablePlugins('command-t') +call SourcePowerline() +let g:statusline_values = [] +call PyFile('setup_statusline_catcher') +execute 'CommandTBuffer'|call feedkeys("\") +call RunPython('powerline.render = _powerline_old_render') +let g:expected_statusline = '%#Pl_231_16777215_240_5789784_bold# Command-T %#Pl_231_16777215_240_5789784_NONE# %#Pl_231_16777215_240_5789784_bold#BufferFinder %#Pl_240_5789784_236_3158064_NONE# %#Pl_231_16777215_236_3158064_NONE#                                                    ' +if index(g:statusline_values, g:expected_statusline) == -1 + call CheckStatuslineValue(get(g:statusline_values, -1, ''), g:expected_statusline) + cquit +endif +call CheckMessages() +qall diff --git a/tests/test_config_merging.py b/tests/test_config_merging.py index ffdc4b51..e0f3d80d 100644 --- a/tests/test_config_merging.py +++ b/tests/test_config_merging.py @@ -8,7 +8,7 @@ from subprocess import check_call from operator import add from shutil import rmtree -from powerline.lib import mergedicts_copy as mdc +from powerline.lib.dict import mergedicts_copy as mdc from powerline import Powerline from tests import TestCase @@ -44,7 +44,7 @@ colors_config = lambda: { colorscheme_config = lambda: { 'groups': { - 'g': {'fg': 'c1', 'bg': 'c2', 'attr': []}, + 'g': {'fg': 'c1', 'bg': 'c2', 'attrs': []}, } } @@ -61,7 +61,7 @@ theme_config = lambda: { 'type': 'string', 'name': 's', 'contents': 't', - 'highlight_group': ['g'], + 'highlight_groups': ['g'], }, ], 'right': [], @@ -246,7 +246,7 @@ class TestMerging(TestCase): with WithConfigTree(mdc(main_tree(), { '2/colorschemes/default': { 'groups': { - 'g': {'fg': 'c2', 'bg': 'c1', 'attr': []}, + 'g': {'fg': 'c2', 'bg': 'c1', 'attrs': []}, } }, })) as p: diff --git a/tests/test_config_reload.py b/tests/test_config_reload.py index 3bcfc9e2..6c835c2c 100644 --- a/tests/test_config_reload.py +++ b/tests/test_config_reload.py @@ -34,14 +34,14 @@ config = { }, 'colorschemes/test/default': { 'groups': { - "str1": {"fg": "col1", "bg": "col2", "attr": ["bold"]}, - "str2": {"fg": "col3", "bg": "col4", "attr": ["underline"]}, + 'str1': {'fg': 'col1', 'bg': 'col2', 'attrs': ['bold']}, + 'str2': {'fg': 'col3', 'bg': 'col4', 'attrs': ['underline']}, }, }, 'colorschemes/test/2': { 'groups': { - "str1": {"fg": "col2", "bg": "col3", "attr": ["bold"]}, - "str2": {"fg": "col1", "bg": "col4", "attr": ["underline"]}, + 'str1': {'fg': 'col2', 'bg': 'col3', 'attrs': ['bold']}, + 'str2': {'fg': 'col1', 'bg': 'col4', 'attrs': ['underline']}, }, }, 'themes/test/default': { @@ -50,12 +50,12 @@ config = { { "type": "string", "contents": "s", - "highlight_group": ["str1"], + "highlight_groups": ["str1"], }, { "type": "string", "contents": "g", - "highlight_group": ["str2"], + "highlight_groups": ["str2"], }, ], "right": [ @@ -94,12 +94,12 @@ config = { { "type": "string", "contents": "t", - "highlight_group": ["str1"], + "highlight_groups": ["str1"], }, { "type": "string", "contents": "b", - "highlight_group": ["str2"], + "highlight_groups": ["str2"], }, ], "right": [ @@ -227,8 +227,8 @@ class TestConfigReload(TestCase): config['colorschemes/nonexistentraise'] = {} config['colorschemes/test/nonexistentraise'] = { 'groups': { - "str1": {"fg": "col1", "bg": "col3", "attr": ["bold"]}, - "str2": {"fg": "col2", "bg": "col4", "attr": ["underline"]}, + 'str1': {'fg': 'col1', 'bg': 'col3', 'attrs': ['bold']}, + 'str2': {'fg': 'col2', 'bg': 'col4', 'attrs': ['underline']}, }, } while not p._will_create_renderer(): diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 8ab6064f..efc21476 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -18,7 +18,7 @@ def highlighted_string(s, group, **kwargs): ret = { 'type': 'string', 'contents': s, - 'highlight_group': [group], + 'highlight_groups': [group], } ret.update(kwargs) return ret @@ -39,6 +39,10 @@ config = { 'theme': 'default', 'colorscheme': 'default', }, + 'shell': { + 'theme': 'default', + 'colorscheme': 'default', + }, }, }, 'colors': { @@ -63,20 +67,20 @@ config = { 'groups': { 'm1': 'g1', 'm2': 'g3', - 'm3': {'fg': 'col11', 'bg': 'col12', 'attr': []}, + 'm3': {'fg': 'col11', 'bg': 'col12', 'attrs': []}, } }, 'colorschemes/default': { 'groups': { - 'g1': {'fg': 'col5', 'bg': 'col6', 'attr': []}, - 'g2': {'fg': 'col7', 'bg': 'col8', 'attr': []}, - 'g3': {'fg': 'col9', 'bg': 'col10', 'attr': []}, + 'g1': {'fg': 'col5', 'bg': 'col6', 'attrs': []}, + 'g2': {'fg': 'col7', 'bg': 'col8', 'attrs': []}, + 'g3': {'fg': 'col9', 'bg': 'col10', 'attrs': []}, } }, 'colorschemes/test/default': { 'groups': { - 'str1': {'fg': 'col1', 'bg': 'col2', 'attr': ['bold']}, - 'str2': {'fg': 'col3', 'bg': 'col4', 'attr': ['underline']}, + 'str1': {'fg': 'col1', 'bg': 'col2', 'attrs': ['bold']}, + 'str2': {'fg': 'col3', 'bg': 'col4', 'attrs': ['underline']}, 'd1': 'g2', 'd2': 'm2', 'd3': 'm3', @@ -84,7 +88,7 @@ config = { }, 'colorschemes/vim/default': { 'groups': { - 'environment': {'fg': 'col3', 'bg': 'col4', 'attr': ['underline']}, + 'environment': {'fg': 'col3', 'bg': 'col4', 'attrs': ['underline']}, }, }, 'themes/test/default': { @@ -119,11 +123,10 @@ config = { }, }, 'themes/vim/default': { - 'default_module': 'powerline.segments.common', 'segments': { 'left': [ { - 'function': 'environment', + 'function': 'powerline.segments.common.env.environment', 'args': { 'variable': 'TEST', }, @@ -131,6 +134,14 @@ config = { ], }, }, + 'themes/shell/default': { + 'default_module': 'powerline.segments.common', + 'segments': { + 'left': [ + highlighted_string('s', 'g1', width='auto'), + ], + }, + }, } @@ -639,6 +650,102 @@ class TestSegmentData(TestRender): self.assertRenderEqual(p, '{56} 1S{56}>{56}3S{610}>>{910}3S{910}>{910}2S{10-}>>{--}') +class TestShellEscapes(TestCase): + @with_new_config + def test_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0;38;5;5;48;5;6m\xa0s\x1b[0;38;5;6;49;22m>>\x1b[0m') + + @with_new_config + def test_tmux_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + config['config']['common']['additional_escapes'] = 'tmux' + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bPtmux;\x1b\x1b[0;38;5;5;48;5;6m\x1b\\\xa0s\x1bPtmux;\x1b\x1b[0;38;5;6;49;22m\x1b\\>>\x1bPtmux;\x1b\x1b[0m\x1b\\') + + @with_new_config + def test_screen_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + config['config']['common']['additional_escapes'] = 'screen' + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bP\x1b\x1b[0;38;5;5;48;5;6m\x1b\\\xa0s\x1bP\x1b\x1b[0;38;5;6;49;22m\x1b\\>>\x1bP\x1b\x1b[0m\x1b\\') + + @with_new_config + def test_fbterm_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + config['config']['common']['term_escape_style'] = 'fbterm' + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0m\x1b[1;5}\x1b[2;6}\xa0s\x1b[0m\x1b[1;6}\x1b[49m\x1b[22m>>\x1b[0m') + + @with_new_config + def test_fbterm_tmux_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + config['config']['common']['term_escape_style'] = 'fbterm' + config['config']['common']['additional_escapes'] = 'tmux' + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bPtmux;\x1b\x1b[0m\x1b\x1b[1;5}\x1b\x1b[2;6}\x1b\\\xa0s\x1bPtmux;\x1b\x1b[0m\x1b\x1b[1;6}\x1b\x1b[49m\x1b\x1b[22m\x1b\\>>\x1bPtmux;\x1b\x1b[0m\x1b\\') + + @with_new_config + def test_fbterm_screen_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + config['config']['common']['term_escape_style'] = 'fbterm' + config['config']['common']['additional_escapes'] = 'screen' + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bP\x1b\x1b[0m\x1b\x1b[1;5}\x1b\x1b[2;6}\x1b\\\xa0s\x1bP\x1b\x1b[0m\x1b\x1b[1;6}\x1b\x1b[49m\x1b\x1b[22m\x1b\\>>\x1bP\x1b\x1b[0m\x1b\\') + + @with_new_config + def test_term_truecolor_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + config['config']['common']['term_truecolor'] = True + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0;38;2;192;0;192;48;2;0;128;128m\xa0s\x1b[0;38;2;0;128;128;49;22m>>\x1b[0m') + + @with_new_config + def test_term_truecolor_fbterm_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + config['config']['common']['term_escape_style'] = 'fbterm' + config['config']['common']['term_truecolor'] = True + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0m\x1b[1;5}\x1b[2;6}\xa0s\x1b[0m\x1b[1;6}\x1b[49m\x1b[22m>>\x1b[0m') + + @with_new_config + def test_term_truecolor_tmux_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + config['config']['common']['term_truecolor'] = True + config['config']['common']['additional_escapes'] = 'tmux' + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bPtmux;\x1b\x1b[0;38;2;192;0;192;48;2;0;128;128m\x1b\\\xa0s\x1bPtmux;\x1b\x1b[0;38;2;0;128;128;49;22m\x1b\\>>\x1bPtmux;\x1b\x1b[0m\x1b\\') + + @with_new_config + def test_term_truecolor_screen_escapes(self, config): + from powerline.shell import ShellPowerline + import powerline as powerline_module + config['config']['common']['term_truecolor'] = True + config['config']['common']['additional_escapes'] = 'screen' + with swap_attributes(config, powerline_module): + with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline: + self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bP\x1b\x1b[0;38;2;192;0;192;48;2;0;128;128m\x1b\\\xa0s\x1bP\x1b\x1b[0;38;2;0;128;128;49;22m\x1b\\>>\x1bP\x1b\x1b[0m\x1b\\') + + class TestVim(TestCase): def test_environ_update(self): # Regression test: test that segment obtains environment from vim, not @@ -674,7 +781,7 @@ class TestVim(TestCase): { 'type': 'string', 'name': 'foo', - 'highlight_group': ['g1'] + 'highlight_groups': ['g1'] } ] } diff --git a/tests/test_empty_encoding.old.vim b/tests/test_empty_encoding.old.vim new file mode 100755 index 00000000..c14e0045 --- /dev/null +++ b/tests/test_empty_encoding.old.vim @@ -0,0 +1,32 @@ +#!/usr/bin/vim -S +if has('multibyte') + if empty(&encoding) + call writefile(['&encoding option value is empty, even though Vim has +multibyte'], 'message.fail') + cquit + endif + qall +endif +if !empty(&encoding) + call writefile(['&encoding option value is not empty, even though Vim does not have +multibyte'], 'message.fail') + cquit +endif + +let g:powerline_config_paths = [expand(':p:h:h') . '/powerline/config_files'] + +try + source powerline/bindings/vim/plugin/powerline.vim +catch + call writefile(['Unexpected exception:', v:exception], 'message.fail') + cquit +endtry +set ls=2 +redrawstatus! +redir => g:messages + messages +redir END +let mess=split(g:messages, "\n") +if len(mess)>1 + call writefile(['Unexpected message(s):']+mess, 'message.fail') + cquit +endif +qall! diff --git a/tests/test_in_vterm/test.sh b/tests/test_in_vterm/test.sh new file mode 100755 index 00000000..447ad97d --- /dev/null +++ b/tests/test_in_vterm/test.sh @@ -0,0 +1,63 @@ +#!/bin/sh +. tests/bot-ci/scripts/common/main.sh +set +x + +FAILED=0 + +rm -rf tests/vterm +mkdir tests/vterm +mkdir tests/vterm/path + +ln -s "$(which "${PYTHON}")" tests/vterm/path/python +ln -s "$(which bash)" tests/vterm/path +ln -s "$(which env)" tests/vterm/path +ln -s "$PWD/scripts/powerline-render" tests/vterm/path +ln -s "$PWD/scripts/powerline-config" tests/vterm/path + +cp -r tests/terminfo tests/vterm + +FAIL_SUMMARY="" + +test_tmux() { + if test "$PYTHON_IMPLEMENTATION" = PyPy && test "$PYTHON_VERSION_MAJOR" -eq 3 ; then + # FIXME PyPy3 segfaults for some reason + return 0 + fi + if ! which "${POWERLINE_TMUX_EXE}" ; then + return 0 + fi + ln -sf "$(which "${POWERLINE_TMUX_EXE}")" tests/vterm/path + f=tests/test_in_vterm/test_tmux.py + if ! "${PYTHON}" $f ; then + echo "Failed vterm test $f" + FAILED=1 + FAIL_SUMMARY="$FAIL_SUMMARY${NL}F $POWERLINE_TMUX_EXE $f" + for file in tests/vterm/*.log ; do + if ! test -e "$file" ; then + break + fi + echo '____________________________________________________________' + echo "$file:" + echo '============================================================' + cat -v $file + done + fi +} + +if test -z "$POWERLINE_TMUX_EXE" && test -d tests/bot-ci/deps/tmux ; then + for tmux in tests/bot-ci/deps/tmux/tmux-*/tmux ; do + export POWERLINE_TMUX_EXE="$PWD/$tmux" + if test_tmux ; then + rm -f tests/vterm/*.log + fi + done +else + test_tmux || true +fi + +if test $FAILED -eq 0 ; then + echo "$FAIL_SUMMARY" + rm -rf tests/vterm +fi + +exit $FAILED diff --git a/tests/test_in_vterm/test_tmux.py b/tests/test_in_vterm/test_tmux.py new file mode 100755 index 00000000..eb8de65f --- /dev/null +++ b/tests/test_in_vterm/test_tmux.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +import os + +from time import sleep +from subprocess import check_call +from itertools import groupby +from difflib import ndiff + +from powerline.lib.unicode import u +from powerline.bindings.tmux import get_tmux_version +from powerline import get_fallback_logger + +from tests.lib.terminal import ExpectProcess + + +def cell_properties_key_to_shell_escape(cell_properties_key): + fg, bg, bold, underline, italic = cell_properties_key + return('\x1b[38;2;{0};48;2;{1}{bold}{underline}{italic}m'.format( + ';'.join((str(i) for i in fg)), + ';'.join((str(i) for i in bg)), + bold=(';1' if bold else ''), + underline=(';4' if underline else ''), + italic=(';3' if italic else ''), + )) + + +def main(): + VTERM_TEST_DIR = os.path.abspath('tests/vterm') + vterm_path = os.path.join(VTERM_TEST_DIR, 'path') + socket_path = os.path.join(VTERM_TEST_DIR, 'tmux-socket') + rows = 50 + cols = 200 + + tmux_exe = os.path.join(vterm_path, 'tmux') + + try: + p = ExpectProcess( + lib='tests/bot-ci/deps/libvterm/libvterm.so', + rows=rows, + cols=cols, + cmd=tmux_exe, + args=[ + # Specify full path to tmux socket (testing tmux instance must + # not interfere with user one) + '-S', socket_path, + # Force 256-color mode + '-2', + # Request verbose logging just in case + '-v', + # Specify configuration file + '-f', os.path.abspath('powerline/bindings/tmux/powerline.conf'), + # Run bash three times + 'new-session', 'bash --norc --noprofile -i', ';', + 'new-window', 'bash --norc --noprofile -i', ';', + 'new-window', 'bash --norc --noprofile -i', ';', + ], + cwd=VTERM_TEST_DIR, + env={ + # Reasoning: + # 1. vt* TERMs (used to be vt100 here) make tmux-1.9 use + # different and identical colors for inactive windows. This + # is not like tmux-1.6: foreground color is different from + # separator color and equal to (0, 102, 153) for some reason + # (separator has correct color). tmux-1.8 is fine, so are + # older versions (though tmux-1.6 and tmux-1.7 do not have + # highlighting for previously active window) and my system + # tmux-1.9a. + # 2. screen, xterm and some other non-256color terminals both + # have the same issue and make libvterm emit complains like + # `Unhandled CSI SGR 3231`. + # 3. screen-256color, xterm-256color and other -256color + # terminals make libvterm emit complains about unhandled + # escapes to stderr. + # 4. `st-256color` does not have any of the above problems, but + # it may be not present on the target system because it is + # installed with x11-terms/st and not with sys-libs/ncurses. + # + # For the given reasons decision was made: to fix tmux-1.9 tests + # and not make libvterm emit any data to stderr st-256color + # $TERM should be used, up until libvterm has its own terminfo + # database entry (if it ever will). To make sure that relevant + # terminfo entry is present on the target system it should be + # distributed with powerline test package. To make distribution + # not require modifying anything outside of powerline test + # directory TERMINFO variable is set. + 'TERMINFO': os.path.join(VTERM_TEST_DIR, 'terminfo'), + 'TERM': 'st-256color', + 'PATH': vterm_path, + 'SHELL': os.path.join(''), + 'POWERLINE_CONFIG_PATHS': os.path.abspath('powerline/config_files'), + 'POWERLINE_COMMAND': 'powerline-render', + 'POWERLINE_THEME_OVERRIDES': ( + 'default.segments.right=[{"type":"string","name":"s1","highlight_groups":["cwd"]}];' + 'default.segments.left=[{"type":"string","name":"s2","highlight_groups":["background"]}];' + 'default.segment_data.s1.contents=S1 string here;' + 'default.segment_data.s2.contents=S2 string here;' + ), + 'LD_LIBRARY_PATH': os.environ.get('LD_LIBRARY_PATH', ''), + 'PYTHONPATH': os.environ.get('PYTHONPATH', ''), + }, + ) + p.start() + sleep(10) + last_line = [] + for col in range(cols): + last_line.append(p[rows - 1, col]) + result = tuple(( + (key, ''.join((i.text for i in subline))) + for key, subline in groupby(last_line, lambda i: i.cell_properties_key) + )) + expected_result_new = ( + (((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '), + (((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '), + (((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '), + (((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '), + (((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '), + (((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '), + (((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '), + (((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 1 '), + (((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '), + (((0, 102, 153), (11, 11, 11), 0, 0, 0), 'bash '), + (((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '), + (((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '), + (((102, 204, 255), (0, 102, 153), 0, 0, 0), '2 | '), + (((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '), + (((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '), + (((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '), + (((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '), + (((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '), + ) + expected_result_old = ( + (((0, 0, 0), (243, 243, 243), 1, 0, 0), ' 0 '), + (((243, 243, 243), (11, 11, 11), 0, 0, 0), ' '), + (((255, 255, 255), (11, 11, 11), 0, 0, 0), ' S2 string here '), + (((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 0 '), + (((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '), + (((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '), + (((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '), + (((133, 133, 133), (11, 11, 11), 0, 0, 0), ' 1 '), + (((88, 88, 88), (11, 11, 11), 0, 0, 0), '| '), + (((188, 188, 188), (11, 11, 11), 0, 0, 0), 'bash '), + (((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '), + (((11, 11, 11), (0, 102, 153), 0, 0, 0), ' '), + (((102, 204, 255), (0, 102, 153), 0, 0, 0), '2 | '), + (((255, 255, 255), (0, 102, 153), 1, 0, 0), 'bash '), + (((0, 102, 153), (11, 11, 11), 0, 0, 0), ' '), + (((255, 255, 255), (11, 11, 11), 0, 0, 0), ' '), + (((88, 88, 88), (11, 11, 11), 0, 0, 0), ' '), + (((199, 199, 199), (88, 88, 88), 0, 0, 0), ' S1 string here '), + ) + print('Result:') + shesc_result = ''.join(( + '{0}{1}\x1b[m'.format(cell_properties_key_to_shell_escape(key), text) + for key, text in result + )) + print(shesc_result) + print('Expected:') + tmux_version = get_tmux_version(get_fallback_logger()) + if tmux_version < (1, 8): + expected_result = expected_result_old + else: + expected_result = expected_result_new + shesc_expected_result = ''.join(( + '{0}{1}\x1b[m'.format(cell_properties_key_to_shell_escape(key), text) + for key, text in expected_result + )) + print(shesc_expected_result) + if result == expected_result: + return True + else: + p.send(b'powerline-config tmux setup\n') + sleep(5) + print('Screen:') + screen = [] + for i in range(rows): + screen.append([]) + for j in range(cols): + screen[-1].append(p[i, j]) + print('\n'.join( + ''.join(( + '{0}{1}\x1b[m'.format( + cell_properties_key_to_shell_escape(i.cell_properties_key), + i.text + ) for i in line + )) + for line in screen + )) + a = shesc_result.replace('\x1b', '\\e') + '\n' + b = shesc_expected_result.replace('\x1b', '\\e') + '\n' + print('_' * 80) + print('Diff:') + print('=' * 80) + print(''.join((u(line) for line in ndiff([a], [b])))) + return False + finally: + check_call([tmux_exe, '-S', socket_path, 'kill-server'], env={ + 'PATH': vterm_path, + 'LD_LIBRARY_PATH': os.environ.get('LD_LIBRARY_PATH', ''), + }) + + +if __name__ == '__main__': + if main(): + raise SystemExit(0) + else: + raise SystemExit(1) diff --git a/tests/test_lib.py b/tests/test_lib.py index 1cd91d04..8b2581ed 100644 --- a/tests/test_lib.py +++ b/tests/test_lib.py @@ -10,7 +10,8 @@ import shutil from time import sleep from subprocess import call, PIPE -from powerline.lib import mergedicts, add_divider_highlight_group, REMOVE_THIS_KEY +from powerline.lib import add_divider_highlight_group +from powerline.lib.dict import mergedicts, REMOVE_THIS_KEY from powerline.lib.humanize_bytes import humanize_bytes from powerline.lib.vcs import guess, get_fallback_create_watcher from powerline.lib.threaded import ThreadedSegment, KwThreadedSegment diff --git a/tests/test_local_overrides.vim b/tests/test_local_overrides.vim index f6cf0931..353c086d 100755 --- a/tests/test_local_overrides.vim +++ b/tests/test_local_overrides.vim @@ -2,7 +2,7 @@ set encoding=utf-8 let g:powerline_config_paths = [expand(':p:h:h') . '/powerline/config_files'] let g:powerline_config_overrides = {'common': {'default_top_theme': 'ascii'}} -let g:powerline_theme_overrides__default = {'segment_data': {'line_current_symbol': {'contents': 'LN '}, 'branch': {'before': 'B '}}} +let g:powerline_theme_overrides = {'default': {'segment_data': {'line_current_symbol': {'contents': 'LN '}, 'branch': {'before': 'B '}}}} redir => g:messages diff --git a/tests/test_nerdtree_plugin.vim b/tests/test_nerdtree_plugin.vim new file mode 100755 index 00000000..56b85b77 --- /dev/null +++ b/tests/test_nerdtree_plugin.vim @@ -0,0 +1,11 @@ +#!/usr/bin/vim -S +set nocompatible +set columns=80 +execute 'source' fnameescape(expand(':p:h').'/vim_utils.vim') +call EnablePlugins('nerdtree') +call SourcePowerline() +NERDTree /home +redrawstatus +call CheckCurrentStatusline('%#Pl_231_16777215_240_5789784_bold# /home %#Pl_240_5789784_236_3158064_NONE# %#Pl_231_16777215_236_3158064_NONE#                      ') +call CheckMessages() +qall diff --git a/tests/test_provided_config_files.py b/tests/test_provided_config_files.py index d0752d0e..00eec49c 100644 --- a/tests/test_provided_config_files.py +++ b/tests/test_provided_config_files.py @@ -54,7 +54,6 @@ class TestVimConfig(TestCase): (('bufname', 'NERD_tree_1'), {}), (('bufname', '__Gundo__'), {}), (('bufname', '__Gundo_Preview__'), {}), - (('bufname', 'ControlP'), {}), # No Command-T tests here: requires +ruby or emulation # No tabline here: tablines are tested separately ) @@ -95,10 +94,6 @@ class TestVimConfig(TestCase): i += 1 if mode in exclude: continue - if mode == 'nc' and args == ('bufname', 'ControlP'): - # ControlP window is not supposed to not - # be in the focus - continue with vim_module._with(*args, **kwargs): check_output(mode, args, kwargs) finally: @@ -143,7 +138,7 @@ class TestConfig(TestCase): def test_bash(self): from powerline.shell import ShellPowerline - args = Args(last_exit_code=1, jobnum=0, ext=['shell'], renderer_module='.bash', config={'ext': {'shell': {'theme': 'default_leftonly'}}}) + args = Args(last_exit_code=1, jobnum=0, ext=['shell'], renderer_module='.bash', config_override={'ext': {'shell': {'theme': 'default_leftonly'}}}) with ShellPowerline(args, logger=get_logger(), run_once=False) as powerline: powerline.render(segment_info={'args': args}) with ShellPowerline(args, logger=get_logger(), run_once=False) as powerline: @@ -153,7 +148,7 @@ class TestConfig(TestCase): from powerline.ipython import IPythonPowerline class IpyPowerline(IPythonPowerline): - paths = None + config_paths = None config_overrides = None theme_overrides = {} diff --git a/tests/test_segments.py b/tests/test_segments.py index a814ac32..73e4bb91 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -7,7 +7,7 @@ import os from functools import partial from collections import namedtuple -from powerline.segments import shell, tmux, common +from powerline.segments import shell, tmux from powerline.lib.vcs import get_fallback_create_watcher from powerline.lib.unicode import out_u @@ -32,12 +32,20 @@ class TestShell(TestCase): pl = Pl() segment_info = {'args': Args(last_exit_code=10)} self.assertEqual(shell.last_status(pl=pl, segment_info=segment_info), [ - {'contents': '10', 'highlight_group': ['exit_fail']} + {'contents': '10', 'highlight_groups': ['exit_fail']} ]) segment_info['args'].last_exit_code = 0 self.assertEqual(shell.last_status(pl=pl, segment_info=segment_info), None) segment_info['args'].last_exit_code = None self.assertEqual(shell.last_status(pl=pl, segment_info=segment_info), None) + segment_info['args'].last_exit_code = 'sigsegv' + self.assertEqual(shell.last_status(pl=pl, segment_info=segment_info), [ + {'contents': 'sigsegv', 'highlight_groups': ['exit_fail']} + ]) + segment_info['args'].last_exit_code = 'sigsegv+core' + self.assertEqual(shell.last_status(pl=pl, segment_info=segment_info), [ + {'contents': 'sigsegv+core', 'highlight_groups': ['exit_fail']} + ]) def test_last_pipe_status(self): pl = Pl() @@ -47,9 +55,27 @@ class TestShell(TestCase): self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), None) segment_info['args'].last_pipe_status = [0, 2, 0] self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [ - {'contents': '0', 'highlight_group': ['exit_success'], 'draw_inner_divider': True}, - {'contents': '2', 'highlight_group': ['exit_fail'], 'draw_inner_divider': True}, - {'contents': '0', 'highlight_group': ['exit_success'], 'draw_inner_divider': True} + {'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True}, + {'contents': '2', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True}, + {'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True} + ]) + segment_info['args'].last_pipe_status = [0, 'sigsegv', 'sigsegv+core'] + self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [ + {'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True}, + {'contents': 'sigsegv', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True}, + {'contents': 'sigsegv+core', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True} + ]) + segment_info['args'].last_pipe_status = [0, 'sigsegv', 0] + self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [ + {'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True}, + {'contents': 'sigsegv', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True}, + {'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True} + ]) + segment_info['args'].last_pipe_status = [0, 'sigsegv+core', 0] + self.assertEqual(shell.last_pipe_status(pl=pl, segment_info=segment_info), [ + {'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True}, + {'contents': 'sigsegv+core', 'highlight_groups': ['exit_fail'], 'draw_inner_divider': True}, + {'contents': '0', 'highlight_groups': ['exit_success'], 'draw_inner_divider': True} ]) def test_jobnum(self): @@ -68,14 +94,14 @@ class TestShell(TestCase): self.assertEqual(shell.continuation(pl=pl, segment_info={}), [{ 'contents': '', 'width': 'auto', - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], }]) segment_info = {'parser_state': 'if cmdsubst'} self.assertEqual(shell.continuation(pl=pl, segment_info=segment_info), [ { 'contents': 'if', 'draw_inner_divider': True, - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], 'width': 'auto', 'align': 'l', }, @@ -84,7 +110,7 @@ class TestShell(TestCase): { 'contents': 'if', 'draw_inner_divider': True, - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], 'width': 'auto', 'align': 'r', }, @@ -93,12 +119,12 @@ class TestShell(TestCase): { 'contents': 'if', 'draw_inner_divider': True, - 'highlight_group': ['continuation'], + 'highlight_groups': ['continuation'], }, { 'contents': 'cmdsubst', 'draw_inner_divider': True, - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], 'width': 'auto', 'align': 'l', }, @@ -107,21 +133,21 @@ class TestShell(TestCase): { 'contents': 'if', 'draw_inner_divider': True, - 'highlight_group': ['continuation'], + 'highlight_groups': ['continuation'], 'width': 'auto', 'align': 'r', }, { 'contents': 'cmdsubst', 'draw_inner_divider': True, - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], }, ]) self.assertEqual(shell.continuation(pl=pl, segment_info=segment_info, omit_cmdsubst=True, right_align=True), [ { 'contents': 'if', 'draw_inner_divider': True, - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], 'width': 'auto', 'align': 'r', }, @@ -130,7 +156,7 @@ class TestShell(TestCase): { 'contents': 'IF', 'draw_inner_divider': True, - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], 'width': 'auto', 'align': 'r', }, @@ -138,7 +164,7 @@ class TestShell(TestCase): self.assertEqual(shell.continuation(pl=pl, segment_info=segment_info, omit_cmdsubst=True, right_align=True, renames={'if': None}), [ { 'contents': '', - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], 'width': 'auto', 'align': 'r', }, @@ -148,17 +174,17 @@ class TestShell(TestCase): { 'contents': 'then', 'draw_inner_divider': True, - 'highlight_group': ['continuation'], + 'highlight_groups': ['continuation'], }, { 'contents': 'then', 'draw_inner_divider': True, - 'highlight_group': ['continuation'], + 'highlight_groups': ['continuation'], }, { 'contents': 'then', 'draw_inner_divider': True, - 'highlight_group': ['continuation:current', 'continuation'], + 'highlight_groups': ['continuation:current', 'continuation'], 'width': 'auto', 'align': 'l', }, @@ -179,95 +205,95 @@ class TestShell(TestCase): segment_info = {'getcwd': getcwd, 'home': None} with replace_attr(shell, 'os', new_os): cwd[0] = '/abc/def/ghi/foo/bar' - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info), [ + self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info), [ {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'abc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'def', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'ghi', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) segment_info['home'] = '/abc/def/ghi' self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info), [ {'contents': '~', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) segment_info.update(shortened_path='~foo/ghi') self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info), [ {'contents': '~foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'ghi', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'ghi', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, use_shortened_path=False), [ {'contents': '~', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) segment_info.pop('shortened_path') self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=3), [ {'contents': '~', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=3, shorten_home=False), [ {'contents': '...', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'ghi', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1), [ {'contents': '...', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, ellipsis='---'), [ {'contents': '---', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, ellipsis=None), [ - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True), [ {'contents': '.../', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True, ellipsis='---'), [ {'contents': '---/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True, ellipsis=None), [ - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2), [ {'contents': '~', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'fo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2, use_path_separator=True), [ {'contents': '~/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, {'contents': 'fo/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) cwd[0] = '/etc' self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, use_path_separator=False), [ {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'etc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'etc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, use_path_separator=True), [ {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, - {'contents': 'etc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'etc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) cwd[0] = '/' self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, use_path_separator=False), [ - {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, use_path_separator=True), [ - {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) ose = OSError() ose.errno = 2 cwd[0] = ose self.assertEqual(shell.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2), [ - {'contents': '[not found]', 'divider_highlight_group': 'cwd:divider', 'highlight_group': ['cwd:current_folder', 'cwd'], 'draw_inner_divider': True} + {'contents': '[not found]', 'divider_highlight_group': 'cwd:divider', 'highlight_groups': ['cwd:current_folder', 'cwd'], 'draw_inner_divider': True} ]) cwd[0] = OSError() self.assertRaises(OSError, shell.cwd, pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2) @@ -303,26 +329,26 @@ class TestNet(TestCommon): pl = Pl() with replace_env('SSH_CLIENT', '192.168.0.12 40921 22') as segment_info: with replace_module_module(self.module, 'socket', gethostname=lambda: 'abc'): - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info), 'abc') - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True), 'abc') + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info), 'abc') + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True), 'abc') with replace_module_module(self.module, 'socket', gethostname=lambda: 'abc.mydomain'): - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info), 'abc.mydomain') - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info, exclude_domain=True), 'abc') - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True), 'abc.mydomain') - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True, exclude_domain=True), 'abc') + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info), 'abc.mydomain') + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info, exclude_domain=True), 'abc') + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True), 'abc.mydomain') + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True, exclude_domain=True), 'abc') segment_info['environ'].pop('SSH_CLIENT') with replace_module_module(self.module, 'socket', gethostname=lambda: 'abc'): - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info), 'abc') - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True), None) + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info), 'abc') + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True), None) with replace_module_module(self.module, 'socket', gethostname=lambda: 'abc.mydomain'): - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info), 'abc.mydomain') - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info, exclude_domain=True), 'abc') - self.assertEqual(common.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True, exclude_domain=True), None) + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info), 'abc.mydomain') + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info, exclude_domain=True), 'abc') + self.assertEqual(self.module.hostname(pl=pl, segment_info=segment_info, only_if_ssh=True, exclude_domain=True), None) def test_external_ip(self): pl = Pl() with replace_attr(self.module, 'urllib_read', urllib_read): - self.assertEqual(common.external_ip(pl=pl), [{'contents': '127.0.0.1', 'divider_highlight_group': 'background:divider'}]) + self.assertEqual(self.module.external_ip(pl=pl), [{'contents': '127.0.0.1', 'divider_highlight_group': 'background:divider'}]) def test_internal_ip(self): try: @@ -351,24 +377,24 @@ class TestNet(TestCommon): AF_INET=netifaces.AF_INET, AF_INET6=netifaces.AF_INET6, ): - self.assertEqual(common.internal_ip(pl=pl), '192.168.100.200') - self.assertEqual(common.internal_ip(pl=pl, interface='detect'), '192.168.100.200') - self.assertEqual(common.internal_ip(pl=pl, interface='lo'), '127.0.0.1') - self.assertEqual(common.internal_ip(pl=pl, interface='teredo'), None) - self.assertEqual(common.internal_ip(pl=pl, ipv=4), '192.168.100.200') - self.assertEqual(common.internal_ip(pl=pl, interface='detect', ipv=4), '192.168.100.200') - self.assertEqual(common.internal_ip(pl=pl, interface='lo', ipv=4), '127.0.0.1') - self.assertEqual(common.internal_ip(pl=pl, interface='teredo', ipv=4), None) - self.assertEqual(common.internal_ip(pl=pl, ipv=6), 'feff::5446:5eff:fe5a:7777%enp2s0') - self.assertEqual(common.internal_ip(pl=pl, interface='detect', ipv=6), 'feff::5446:5eff:fe5a:7777%enp2s0') - self.assertEqual(common.internal_ip(pl=pl, interface='lo', ipv=6), '::1') - self.assertEqual(common.internal_ip(pl=pl, interface='teredo', ipv=6), 'feff::5446:5eff:fe5a:7777') + self.assertEqual(self.module.internal_ip(pl=pl), '192.168.100.200') + self.assertEqual(self.module.internal_ip(pl=pl, interface='auto'), '192.168.100.200') + self.assertEqual(self.module.internal_ip(pl=pl, interface='lo'), '127.0.0.1') + self.assertEqual(self.module.internal_ip(pl=pl, interface='teredo'), None) + self.assertEqual(self.module.internal_ip(pl=pl, ipv=4), '192.168.100.200') + self.assertEqual(self.module.internal_ip(pl=pl, interface='auto', ipv=4), '192.168.100.200') + self.assertEqual(self.module.internal_ip(pl=pl, interface='lo', ipv=4), '127.0.0.1') + self.assertEqual(self.module.internal_ip(pl=pl, interface='teredo', ipv=4), None) + self.assertEqual(self.module.internal_ip(pl=pl, ipv=6), 'feff::5446:5eff:fe5a:7777%enp2s0') + self.assertEqual(self.module.internal_ip(pl=pl, interface='auto', ipv=6), 'feff::5446:5eff:fe5a:7777%enp2s0') + self.assertEqual(self.module.internal_ip(pl=pl, interface='lo', ipv=6), '::1') + self.assertEqual(self.module.internal_ip(pl=pl, interface='teredo', ipv=6), 'feff::5446:5eff:fe5a:7777') interfaces[1:2] = () - self.assertEqual(common.internal_ip(pl=pl, ipv=6), 'feff::5446:5eff:fe5a:7777') + self.assertEqual(self.module.internal_ip(pl=pl, ipv=6), 'feff::5446:5eff:fe5a:7777') interfaces[1:2] = () - self.assertEqual(common.internal_ip(pl=pl, ipv=6), '::1') + self.assertEqual(self.module.internal_ip(pl=pl, ipv=6), '::1') interfaces[:] = () - self.assertEqual(common.internal_ip(pl=pl, ipv=6), None) + self.assertEqual(self.module.internal_ip(pl=pl, ipv=6), None) def test_network_load(self): from time import sleep @@ -384,14 +410,14 @@ class TestNet(TestCommon): pl = Pl() with replace_attr(self.module, '_get_bytes', _get_bytes): - common.network_load.startup(pl=pl) + self.module.network_load.startup(pl=pl) try: - self.assertEqual(common.network_load(pl=pl, interface='eth0'), None) - sleep(common.network_load.interval) - self.assertEqual(common.network_load(pl=pl, interface='eth0'), None) - while 'prev' not in common.network_load.interfaces.get('eth0', {}): + self.assertEqual(self.module.network_load(pl=pl, interface='eth0'), None) + sleep(self.module.network_load.interval) + self.assertEqual(self.module.network_load(pl=pl, interface='eth0'), None) + while 'prev' not in self.module.network_load.interfaces.get('eth0', {}): sleep(0.1) - self.assertEqual(common.network_load(pl=pl, interface='eth0'), None) + self.assertEqual(self.module.network_load(pl=pl, interface='eth0'), None) l = [0, 0] @@ -401,39 +427,39 @@ class TestNet(TestCommon): return tuple(l) f[0] = gb2 - while not common.network_load.interfaces.get('eth0', {}).get('prev', (None, None))[1]: + while not self.module.network_load.interfaces.get('eth0', {}).get('prev', (None, None))[1]: sleep(0.1) - self.assertEqual(common.network_load(pl=pl, interface='eth0'), [ - {'divider_highlight_group': 'background:divider', 'contents': 'DL 1 KiB/s', 'highlight_group': ['network_load_recv', 'network_load']}, - {'divider_highlight_group': 'background:divider', 'contents': 'UL 2 KiB/s', 'highlight_group': ['network_load_sent', 'network_load']}, + self.assertEqual(self.module.network_load(pl=pl, interface='eth0'), [ + {'divider_highlight_group': 'background:divider', 'contents': 'DL 1 KiB/s', 'highlight_groups': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': 'UL 2 KiB/s', 'highlight_groups': ['network_load_sent', 'network_load']}, ]) - self.assertEqual(common.network_load(pl=pl, interface='eth0', recv_format='r {value}', sent_format='s {value}'), [ - {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_group': ['network_load_recv', 'network_load']}, - {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_group': ['network_load_sent', 'network_load']}, + self.assertEqual(self.module.network_load(pl=pl, interface='eth0', recv_format='r {value}', sent_format='s {value}'), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_groups': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_groups': ['network_load_sent', 'network_load']}, ]) - self.assertEqual(common.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', suffix='bps', interface='eth0'), [ - {'divider_highlight_group': 'background:divider', 'contents': 'r 1 Kibps', 'highlight_group': ['network_load_recv', 'network_load']}, - {'divider_highlight_group': 'background:divider', 'contents': 's 2 Kibps', 'highlight_group': ['network_load_sent', 'network_load']}, + self.assertEqual(self.module.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', suffix='bps', interface='eth0'), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 Kibps', 'highlight_groups': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 Kibps', 'highlight_groups': ['network_load_sent', 'network_load']}, ]) - self.assertEqual(common.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', si_prefix=True, interface='eth0'), [ - {'divider_highlight_group': 'background:divider', 'contents': 'r 1 kB/s', 'highlight_group': ['network_load_recv', 'network_load']}, - {'divider_highlight_group': 'background:divider', 'contents': 's 2 kB/s', 'highlight_group': ['network_load_sent', 'network_load']}, + self.assertEqual(self.module.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', si_prefix=True, interface='eth0'), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 kB/s', 'highlight_groups': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 kB/s', 'highlight_groups': ['network_load_sent', 'network_load']}, ]) - self.assertEqual(common.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', recv_max=0, interface='eth0'), [ - {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_group': ['network_load_recv_gradient', 'network_load_gradient', 'network_load_recv', 'network_load'], 'gradient_level': 100}, - {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_group': ['network_load_sent', 'network_load']}, + self.assertEqual(self.module.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', recv_max=0, interface='eth0'), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_groups': ['network_load_recv_gradient', 'network_load_gradient', 'network_load_recv', 'network_load'], 'gradient_level': 100}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_groups': ['network_load_sent', 'network_load']}, ]) class ApproxEqual(object): def __eq__(self, i): return abs(i - 50.0) < 1 - self.assertEqual(common.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', sent_max=4800, interface='eth0'), [ - {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_group': ['network_load_recv', 'network_load']}, - {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_group': ['network_load_sent_gradient', 'network_load_gradient', 'network_load_sent', 'network_load'], 'gradient_level': ApproxEqual()}, + self.assertEqual(self.module.network_load(pl=pl, recv_format='r {value}', sent_format='s {value}', sent_max=4800, interface='eth0'), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_groups': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_groups': ['network_load_sent_gradient', 'network_load_gradient', 'network_load_sent', 'network_load'], 'gradient_level': ApproxEqual()}, ]) finally: - common.network_load.shutdown() + self.module.network_load.shutdown() class TestEnv(TestCommon): @@ -462,16 +488,16 @@ class TestEnv(TestCommon): with replace_attr(self.module, 'os', new_os): with replace_attr(self.module, 'psutil', new_psutil): with replace_attr(self.module, '_geteuid', lambda: 5): - self.assertEqual(common.user(pl=pl), [ - {'contents': 'def', 'highlight_group': ['user']} + self.assertEqual(self.module.user(pl=pl), [ + {'contents': 'def', 'highlight_groups': ['user']} ]) - self.assertEqual(common.user(pl=pl, hide_user='abc'), [ - {'contents': 'def', 'highlight_group': ['user']} + self.assertEqual(self.module.user(pl=pl, hide_user='abc'), [ + {'contents': 'def', 'highlight_groups': ['user']} ]) - self.assertEqual(common.user(pl=pl, hide_user='def'), None) + self.assertEqual(self.module.user(pl=pl, hide_user='def'), None) with replace_attr(self.module, '_geteuid', lambda: 0): - self.assertEqual(common.user(pl=pl), [ - {'contents': 'def', 'highlight_group': ['superuser', 'user']} + self.assertEqual(self.module.user(pl=pl), [ + {'contents': 'def', 'highlight_groups': ['superuser', 'user']} ]) def test_cwd(self): @@ -489,105 +515,105 @@ class TestEnv(TestCommon): segment_info = {'getcwd': getcwd, 'home': None} with replace_attr(self.module, 'os', new_os): cwd[0] = '/abc/def/ghi/foo/bar' - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info), [ {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'abc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'def', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'ghi', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) segment_info['home'] = '/abc/def/ghi' - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info), [ {'contents': '~', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=3), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=3), [ {'contents': '~', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=3, shorten_home=False), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=3, shorten_home=False), [ {'contents': '...', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'ghi', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'foo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1), [ {'contents': '...', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, ellipsis='---'), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, ellipsis='---'), [ {'contents': '---', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, ellipsis=None), [ - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, ellipsis=None), [ + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True), [ {'contents': '.../', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True, ellipsis='---'), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True, ellipsis='---'), [ {'contents': '---/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True, ellipsis=None), [ - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']} + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=1, use_path_separator=True, ellipsis=None), [ + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2), [ {'contents': '~', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, {'contents': 'fo', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2, use_path_separator=True), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2, use_path_separator=True), [ {'contents': '~/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, {'contents': 'fo/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, - {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']} + {'contents': 'bar', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']} ]) cwd[0] = '/etc' - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, use_path_separator=False), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, use_path_separator=False), [ {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True}, - {'contents': 'etc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'etc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, use_path_separator=True), [ + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, use_path_separator=True), [ {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False}, - {'contents': 'etc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']}, + {'contents': 'etc', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) cwd[0] = '/' - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, use_path_separator=False), [ - {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_group': ['cwd:current_folder', 'cwd']}, + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, use_path_separator=False), [ + {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': True, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, use_path_separator=True), [ - {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_group': ['cwd:current_folder', 'cwd']}, + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, use_path_separator=True), [ + {'contents': '/', 'divider_highlight_group': 'cwd:divider', 'draw_inner_divider': False, 'highlight_groups': ['cwd:current_folder', 'cwd']}, ]) ose = OSError() ose.errno = 2 cwd[0] = ose - self.assertEqual(common.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2), [ - {'contents': '[not found]', 'divider_highlight_group': 'cwd:divider', 'highlight_group': ['cwd:current_folder', 'cwd'], 'draw_inner_divider': True} + self.assertEqual(self.module.cwd(pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2), [ + {'contents': '[not found]', 'divider_highlight_group': 'cwd:divider', 'highlight_groups': ['cwd:current_folder', 'cwd'], 'draw_inner_divider': True} ]) cwd[0] = OSError() - self.assertRaises(OSError, common.cwd, pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2) + self.assertRaises(OSError, self.module.cwd, pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2) cwd[0] = ValueError() - self.assertRaises(ValueError, common.cwd, pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2) + self.assertRaises(ValueError, self.module.cwd, pl=pl, segment_info=segment_info, dir_limit_depth=2, dir_shorten_len=2) def test_virtualenv(self): pl = Pl() with replace_env('VIRTUAL_ENV', '/abc/def/ghi') as segment_info: - self.assertEqual(common.virtualenv(pl=pl, segment_info=segment_info), 'ghi') + self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info), 'ghi') segment_info['environ'].pop('VIRTUAL_ENV') - self.assertEqual(common.virtualenv(pl=pl, segment_info=segment_info), None) + self.assertEqual(self.module.virtualenv(pl=pl, segment_info=segment_info), None) def test_environment(self): pl = Pl() variable = 'FOO' value = 'bar' with replace_env(variable, value) as segment_info: - self.assertEqual(common.environment(pl=pl, segment_info=segment_info, variable=variable), value) + self.assertEqual(self.module.environment(pl=pl, segment_info=segment_info, variable=variable), value) segment_info['environ'].pop(variable) - self.assertEqual(common.environment(pl=pl, segment_info=segment_info, variable=variable), None) + self.assertEqual(self.module.environment(pl=pl, segment_info=segment_info, variable=variable), None) class TestVcs(TestCommon): @@ -597,33 +623,33 @@ class TestVcs(TestCommon): pl = Pl() create_watcher = get_fallback_create_watcher() segment_info = {'getcwd': os.getcwd} - branch = partial(common.branch, pl=pl, create_watcher=create_watcher) + branch = partial(self.module.branch, pl=pl, create_watcher=create_watcher) with replace_attr(self.module, 'guess', get_dummy_guess(status=lambda: None, directory='/tmp/tests')): with replace_attr(self.module, 'tree_status', lambda repo, pl: None): self.assertEqual(branch(segment_info=segment_info, status_colors=False), [{ - 'highlight_group': ['branch'], + 'highlight_groups': ['branch'], 'contents': 'tests', 'divider_highlight_group': None }]) self.assertEqual(branch(segment_info=segment_info, status_colors=True), [{ 'contents': 'tests', - 'highlight_group': ['branch_clean', 'branch'], + 'highlight_groups': ['branch_clean', 'branch'], 'divider_highlight_group': None }]) with replace_attr(self.module, 'guess', get_dummy_guess(status=lambda: 'D ', directory='/tmp/tests')): with replace_attr(self.module, 'tree_status', lambda repo, pl: 'D '): self.assertEqual(branch(segment_info=segment_info, status_colors=False), [{ - 'highlight_group': ['branch'], + 'highlight_groups': ['branch'], 'contents': 'tests', 'divider_highlight_group': None }]) self.assertEqual(branch(segment_info=segment_info, status_colors=True), [{ 'contents': 'tests', - 'highlight_group': ['branch_dirty', 'branch'], + 'highlight_groups': ['branch_dirty', 'branch'], 'divider_highlight_group': None }]) self.assertEqual(branch(segment_info=segment_info, status_colors=False), [{ - 'highlight_group': ['branch'], + 'highlight_groups': ['branch'], 'contents': 'tests', 'divider_highlight_group': None }]) @@ -632,22 +658,22 @@ class TestVcs(TestCommon): with replace_attr(self.module, 'guess', get_dummy_guess(status=lambda: 'U')): with replace_attr(self.module, 'tree_status', lambda repo, pl: 'U'): self.assertEqual(branch(segment_info=segment_info, status_colors=False, ignore_statuses=['U']), [{ - 'highlight_group': ['branch'], + 'highlight_groups': ['branch'], 'contents': 'tests', 'divider_highlight_group': None }]) self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['DU']), [{ - 'highlight_group': ['branch_dirty', 'branch'], + 'highlight_groups': ['branch_dirty', 'branch'], 'contents': 'tests', 'divider_highlight_group': None }]) self.assertEqual(branch(segment_info=segment_info, status_colors=True), [{ - 'highlight_group': ['branch_dirty', 'branch'], + 'highlight_groups': ['branch_dirty', 'branch'], 'contents': 'tests', 'divider_highlight_group': None }]) self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['U']), [{ - 'highlight_group': ['branch_clean', 'branch'], + 'highlight_groups': ['branch_clean', 'branch'], 'contents': 'tests', 'divider_highlight_group': None }]) @@ -659,29 +685,29 @@ class TestTime(TestCommon): def test_date(self): pl = Pl() with replace_attr(self.module, 'datetime', Args(now=lambda: Args(strftime=lambda fmt: fmt))): - self.assertEqual(common.date(pl=pl), [{'contents': '%Y-%m-%d', 'highlight_group': ['date'], 'divider_highlight_group': None}]) - self.assertEqual(common.date(pl=pl, format='%H:%M', istime=True), [{'contents': '%H:%M', 'highlight_group': ['time', 'date'], 'divider_highlight_group': 'time:divider'}]) + self.assertEqual(self.module.date(pl=pl), [{'contents': '%Y-%m-%d', 'highlight_groups': ['date'], 'divider_highlight_group': None}]) + self.assertEqual(self.module.date(pl=pl, format='%H:%M', istime=True), [{'contents': '%H:%M', 'highlight_groups': ['time', 'date'], 'divider_highlight_group': 'time:divider'}]) def test_fuzzy_time(self): time = Args(hour=0, minute=45) pl = Pl() with replace_attr(self.module, 'datetime', Args(now=lambda: time)): - self.assertEqual(common.fuzzy_time(pl=pl), 'quarter to one') + self.assertEqual(self.module.fuzzy_time(pl=pl), 'quarter to one') time.hour = 23 time.minute = 59 - self.assertEqual(common.fuzzy_time(pl=pl), 'round about midnight') + self.assertEqual(self.module.fuzzy_time(pl=pl), 'round about midnight') time.minute = 33 - self.assertEqual(common.fuzzy_time(pl=pl), 'twenty-five to twelve') + self.assertEqual(self.module.fuzzy_time(pl=pl), 'twenty-five to twelve') time.minute = 60 - self.assertEqual(common.fuzzy_time(pl=pl), 'twelve o\'clock') + self.assertEqual(self.module.fuzzy_time(pl=pl), 'twelve o\'clock') time.minute = 33 - self.assertEqual(common.fuzzy_time(pl=pl, unicode_text=False), 'twenty-five to twelve') + self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False), 'twenty-five to twelve') time.minute = 60 - self.assertEqual(common.fuzzy_time(pl=pl, unicode_text=False), 'twelve o\'clock') + self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=False), 'twelve o\'clock') time.minute = 33 - self.assertEqual(common.fuzzy_time(pl=pl, unicode_text=True), 'twenty‐five to twelve') + self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True), 'twenty‐five to twelve') time.minute = 60 - self.assertEqual(common.fuzzy_time(pl=pl, unicode_text=True), 'twelve o’clock') + self.assertEqual(self.module.fuzzy_time(pl=pl, unicode_text=True), 'twelve o’clock') class TestSys(TestCommon): @@ -690,48 +716,52 @@ class TestSys(TestCommon): def test_uptime(self): pl = Pl() with replace_attr(self.module, '_get_uptime', lambda: 259200): - self.assertEqual(common.uptime(pl=pl), [{'contents': '3d', 'divider_highlight_group': 'background:divider'}]) + self.assertEqual(self.module.uptime(pl=pl), [{'contents': '3d', 'divider_highlight_group': 'background:divider'}]) with replace_attr(self.module, '_get_uptime', lambda: 93784): - self.assertEqual(common.uptime(pl=pl), [{'contents': '1d 2h 3m', 'divider_highlight_group': 'background:divider'}]) - self.assertEqual(common.uptime(pl=pl, shorten_len=4), [{'contents': '1d 2h 3m 4s', 'divider_highlight_group': 'background:divider'}]) + self.assertEqual(self.module.uptime(pl=pl), [{'contents': '1d 2h 3m', 'divider_highlight_group': 'background:divider'}]) + self.assertEqual(self.module.uptime(pl=pl, shorten_len=4), [{'contents': '1d 2h 3m 4s', 'divider_highlight_group': 'background:divider'}]) with replace_attr(self.module, '_get_uptime', lambda: 65536): - self.assertEqual(common.uptime(pl=pl), [{'contents': '18h 12m 16s', 'divider_highlight_group': 'background:divider'}]) - self.assertEqual(common.uptime(pl=pl, shorten_len=2), [{'contents': '18h 12m', 'divider_highlight_group': 'background:divider'}]) - self.assertEqual(common.uptime(pl=pl, shorten_len=1), [{'contents': '18h', 'divider_highlight_group': 'background:divider'}]) + self.assertEqual(self.module.uptime(pl=pl), [{'contents': '18h 12m 16s', 'divider_highlight_group': 'background:divider'}]) + self.assertEqual(self.module.uptime(pl=pl, shorten_len=2), [{'contents': '18h 12m', 'divider_highlight_group': 'background:divider'}]) + self.assertEqual(self.module.uptime(pl=pl, shorten_len=1), [{'contents': '18h', 'divider_highlight_group': 'background:divider'}]) def _get_uptime(): raise NotImplementedError with replace_attr(self.module, '_get_uptime', _get_uptime): - self.assertEqual(common.uptime(pl=pl), None) + self.assertEqual(self.module.uptime(pl=pl), None) def test_system_load(self): pl = Pl() with replace_module_module(self.module, 'os', getloadavg=lambda: (7.5, 3.5, 1.5)): with replace_attr(self.module, '_cpu_count', lambda: 2): - self.assertEqual(common.system_load(pl=pl), [ - {'contents': '7.5 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, - {'contents': '3.5 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0}, - {'contents': '1.5', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 0} + self.assertEqual(self.module.system_load(pl=pl), [ + {'contents': '7.5 ', 'highlight_groups': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, + {'contents': '3.5 ', 'highlight_groups': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0}, + {'contents': '1.5', 'highlight_groups': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 0} ]) - self.assertEqual(common.system_load(pl=pl, format='{avg:.0f}', threshold_good=0, threshold_bad=1), [ - {'contents': '8 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, - {'contents': '4 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, - {'contents': '2', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0} + self.assertEqual(self.module.system_load(pl=pl, format='{avg:.0f}', threshold_good=0, threshold_bad=1), [ + {'contents': '8 ', 'highlight_groups': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, + {'contents': '4 ', 'highlight_groups': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, + {'contents': '2', 'highlight_groups': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0} ]) def test_cpu_load_percent(self): + try: + __import__('psutil') + except ImportError as e: + raise SkipTest('Failed to import psutil: {0}'.format(e)) pl = Pl() with replace_module_module(self.module, 'psutil', cpu_percent=lambda **kwargs: 52.3): - self.assertEqual(common.cpu_load_percent(pl=pl), [{ + self.assertEqual(self.module.cpu_load_percent(pl=pl), [{ 'contents': '52%', 'gradient_level': 52.3, - 'highlight_group': ['cpu_load_percent_gradient', 'cpu_load_percent'], + 'highlight_groups': ['cpu_load_percent_gradient', 'cpu_load_percent'], }]) - self.assertEqual(common.cpu_load_percent(pl=pl, format='{0:.1f}%'), [{ + self.assertEqual(self.module.cpu_load_percent(pl=pl, format='{0:.1f}%'), [{ 'contents': '52.3%', 'gradient_level': 52.3, - 'highlight_group': ['cpu_load_percent_gradient', 'cpu_load_percent'], + 'highlight_groups': ['cpu_load_percent_gradient', 'cpu_load_percent'], }]) @@ -741,49 +771,49 @@ class TestWthr(TestCommon): def test_weather(self): pl = Pl() with replace_attr(self.module, 'urllib_read', urllib_read): - self.assertEqual(common.weather(pl=pl), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} + self.assertEqual(self.module.weather(pl=pl), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} ]) - self.assertEqual(common.weather(pl=pl, temp_coldest=0, temp_hottest=100), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 0} + self.assertEqual(self.module.weather(pl=pl, temp_coldest=0, temp_hottest=100), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 0} ]) - self.assertEqual(common.weather(pl=pl, temp_coldest=-100, temp_hottest=-50), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 100} + self.assertEqual(self.module.weather(pl=pl, temp_coldest=-100, temp_hottest=-50), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 100} ]) - self.assertEqual(common.weather(pl=pl, icons={'cloudy': 'o'}), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'o '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} + self.assertEqual(self.module.weather(pl=pl, icons={'cloudy': 'o'}), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'o '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} ]) - self.assertEqual(common.weather(pl=pl, icons={'partly_cloudy_day': 'x'}), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'x '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} + self.assertEqual(self.module.weather(pl=pl, icons={'partly_cloudy_day': 'x'}), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'x '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} ]) - self.assertEqual(common.weather(pl=pl, unit='F'), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '16°F', 'gradient_level': 30.0} + self.assertEqual(self.module.weather(pl=pl, unit='F'), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '16°F', 'gradient_level': 30.0} ]) - self.assertEqual(common.weather(pl=pl, unit='K'), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '264K', 'gradient_level': 30.0} + self.assertEqual(self.module.weather(pl=pl, unit='K'), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '264K', 'gradient_level': 30.0} ]) - self.assertEqual(common.weather(pl=pl, temp_format='{temp:.1e}C'), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9.0e+00C', 'gradient_level': 30.0} + self.assertEqual(self.module.weather(pl=pl, temp_format='{temp:.1e}C'), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9.0e+00C', 'gradient_level': 30.0} ]) with replace_attr(self.module, 'urllib_read', urllib_read): - common.weather.startup(pl=pl, location_query='Meppen,06,DE') - self.assertEqual(common.weather(pl=pl), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} + self.module.weather.startup(pl=pl, location_query='Meppen,06,DE') + self.assertEqual(self.module.weather(pl=pl), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} ]) - self.assertEqual(common.weather(pl=pl, location_query='Moscow,RU'), [ - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, - {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '19°C', 'gradient_level': 70.0} + self.assertEqual(self.module.weather(pl=pl, location_query='Moscow,RU'), [ + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'CLOUDS '}, + {'divider_highlight_group': 'background:divider', 'highlight_groups': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '19°C', 'gradient_level': 70.0} ]) - common.weather.shutdown() + self.module.weather.shutdown() class TestMail(TestCommon): @@ -812,46 +842,46 @@ class TestBat(TestCommon): return 86 with replace_attr(self.module, '_get_capacity', _get_capacity): - self.assertEqual(common.battery(pl=pl), [{ + self.assertEqual(self.module.battery(pl=pl), [{ 'contents': '86%', - 'highlight_group': ['battery_gradient', 'battery'], + 'highlight_groups': ['battery_gradient', 'battery'], 'gradient_level': 14, }]) - self.assertEqual(common.battery(pl=pl, format='{capacity:.2f}'), [{ + self.assertEqual(self.module.battery(pl=pl, format='{capacity:.2f}'), [{ 'contents': '0.86', - 'highlight_group': ['battery_gradient', 'battery'], + 'highlight_groups': ['battery_gradient', 'battery'], 'gradient_level': 14, }]) - self.assertEqual(common.battery(pl=pl, steps=7), [{ + self.assertEqual(self.module.battery(pl=pl, steps=7), [{ 'contents': '86%', - 'highlight_group': ['battery_gradient', 'battery'], + 'highlight_groups': ['battery_gradient', 'battery'], 'gradient_level': 14, }]) - self.assertEqual(common.battery(pl=pl, gamify=True), [ + self.assertEqual(self.module.battery(pl=pl, gamify=True), [ { 'contents': 'OOOO', 'draw_inner_divider': False, - 'highlight_group': ['battery_full', 'battery_gradient', 'battery'], + 'highlight_groups': ['battery_full', 'battery_gradient', 'battery'], 'gradient_level': 0 }, { 'contents': 'O', 'draw_inner_divider': False, - 'highlight_group': ['battery_empty', 'battery_gradient', 'battery'], + 'highlight_groups': ['battery_empty', 'battery_gradient', 'battery'], 'gradient_level': 100 } ]) - self.assertEqual(common.battery(pl=pl, gamify=True, full_heart='+', empty_heart='-', steps='10'), [ + self.assertEqual(self.module.battery(pl=pl, gamify=True, full_heart='+', empty_heart='-', steps='10'), [ { 'contents': '++++++++', 'draw_inner_divider': False, - 'highlight_group': ['battery_full', 'battery_gradient', 'battery'], + 'highlight_groups': ['battery_full', 'battery_gradient', 'battery'], 'gradient_level': 0 }, { 'contents': '--', 'draw_inner_divider': False, - 'highlight_group': ['battery_empty', 'battery_gradient', 'battery'], + 'highlight_groups': ['battery_empty', 'battery_gradient', 'battery'], 'gradient_level': 100 } ]) @@ -979,10 +1009,10 @@ class TestVim(TestCase): segment_info = vim_module._get_segment_info() self.assertEqual(self.vim.file_name(pl=pl, segment_info=segment_info), None) self.assertEqual(self.vim.file_name(pl=pl, segment_info=segment_info, display_no_file=True), [ - {'contents': '[No file]', 'highlight_group': ['file_name_no_file', 'file_name']} + {'contents': '[No file]', 'highlight_groups': ['file_name_no_file', 'file_name']} ]) self.assertEqual(self.vim.file_name(pl=pl, segment_info=segment_info, display_no_file=True, no_file_text='X'), [ - {'contents': 'X', 'highlight_group': ['file_name_no_file', 'file_name']} + {'contents': 'X', 'highlight_groups': ['file_name_no_file', 'file_name']} ]) with vim_module._with('buffer', '/tmp/abc') as segment_info: self.assertEqual(self.vim.file_name(pl=pl, segment_info=segment_info), 'abc') @@ -1029,7 +1059,7 @@ class TestVim(TestCase): vim_module._set_cursor(50, 0) self.assertEqual(self.vim.line_percent(pl=pl, segment_info=segment_info), '50') self.assertEqual(self.vim.line_percent(pl=pl, segment_info=segment_info, gradient=True), [ - {'contents': '50', 'highlight_group': ['line_percent_gradient', 'line_percent'], 'gradient_level': 50 * 100.0 / 101} + {'contents': '50', 'highlight_groups': ['line_percent_gradient', 'line_percent'], 'gradient_level': 50 * 100.0 / 101} ]) finally: vim_module._bw(segment_info['bufnr']) @@ -1053,7 +1083,7 @@ class TestVim(TestCase): vim_module._set_cursor(49, 0) self.assertEqual(self.vim.position(pl=pl, segment_info=segment_info), '50%') self.assertEqual(self.vim.position(pl=pl, segment_info=segment_info, gradient=True), [ - {'contents': '50%', 'highlight_group': ['position_gradient', 'position'], 'gradient_level': 50.0} + {'contents': '50%', 'highlight_groups': ['position_gradient', 'position'], 'gradient_level': 50.0} ]) vim_module._set_cursor(0, 0) self.assertEqual(self.vim.position(pl=pl, segment_info=segment_info), 'Top') @@ -1063,7 +1093,7 @@ class TestVim(TestCase): vim_module._set_cursor(0, 0) self.assertEqual(self.vim.position(pl=pl, segment_info=segment_info, position_strings={'top': 'Comienzo', 'bottom': 'Final', 'all': 'Todo'}), 'Todo') self.assertEqual(self.vim.position(pl=pl, segment_info=segment_info, gradient=True), [ - {'contents': 'All', 'highlight_group': ['position_gradient', 'position'], 'gradient_level': 0.0} + {'contents': 'All', 'highlight_groups': ['position_gradient', 'position'], 'gradient_level': 0.0} ]) finally: vim_module._bw(segment_info['bufnr']) @@ -1074,10 +1104,10 @@ class TestVim(TestCase): self.assertEqual(self.vim.line_current(pl=pl, segment_info=segment_info), '1') self.assertEqual(self.vim.col_current(pl=pl, segment_info=segment_info), '1') self.assertEqual(self.vim.virtcol_current(pl=pl, segment_info=segment_info), [{ - 'highlight_group': ['virtcol_current_gradient', 'virtcol_current', 'col_current'], 'contents': '1', 'gradient_level': 100.0 / 80, + 'highlight_groups': ['virtcol_current_gradient', 'virtcol_current', 'col_current'], 'contents': '1', 'gradient_level': 100.0 / 80, }]) self.assertEqual(self.vim.virtcol_current(pl=pl, segment_info=segment_info, gradient=False), [{ - 'highlight_group': ['virtcol_current', 'col_current'], 'contents': '1', + 'highlight_groups': ['virtcol_current', 'col_current'], 'contents': '1', }]) def test_modified_buffers(self): @@ -1092,32 +1122,32 @@ class TestVim(TestCase): with replace_attr(self.vcs, 'guess', get_dummy_guess(status=lambda: None)): with replace_attr(self.vcs, 'tree_status', lambda repo, pl: None): self.assertEqual(branch(segment_info=segment_info, status_colors=False), [ - {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch'], 'contents': 'foo'} + {'divider_highlight_group': 'branch:divider', 'highlight_groups': ['branch'], 'contents': 'foo'} ]) self.assertEqual(branch(segment_info=segment_info, status_colors=True), [ - {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_clean', 'branch'], 'contents': 'foo'} + {'divider_highlight_group': 'branch:divider', 'highlight_groups': ['branch_clean', 'branch'], 'contents': 'foo'} ]) with replace_attr(self.vcs, 'guess', get_dummy_guess(status=lambda: 'DU')): with replace_attr(self.vcs, 'tree_status', lambda repo, pl: 'DU'): self.assertEqual(branch(segment_info=segment_info, status_colors=False), [ - {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch'], 'contents': 'foo'} + {'divider_highlight_group': 'branch:divider', 'highlight_groups': ['branch'], 'contents': 'foo'} ]) self.assertEqual(branch(segment_info=segment_info, status_colors=True), [ - {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_dirty', 'branch'], 'contents': 'foo'} + {'divider_highlight_group': 'branch:divider', 'highlight_groups': ['branch_dirty', 'branch'], 'contents': 'foo'} ]) with replace_attr(self.vcs, 'guess', get_dummy_guess(status=lambda: 'U')): with replace_attr(self.vcs, 'tree_status', lambda repo, pl: 'U'): self.assertEqual(branch(segment_info=segment_info, status_colors=False, ignore_statuses=['U']), [ - {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch'], 'contents': 'foo'} + {'divider_highlight_group': 'branch:divider', 'highlight_groups': ['branch'], 'contents': 'foo'} ]) self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['DU']), [ - {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_dirty', 'branch'], 'contents': 'foo'} + {'divider_highlight_group': 'branch:divider', 'highlight_groups': ['branch_dirty', 'branch'], 'contents': 'foo'} ]) self.assertEqual(branch(segment_info=segment_info, status_colors=True), [ - {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_dirty', 'branch'], 'contents': 'foo'} + {'divider_highlight_group': 'branch:divider', 'highlight_groups': ['branch_dirty', 'branch'], 'contents': 'foo'} ]) self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['U']), [ - {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_clean', 'branch'], 'contents': 'foo'} + {'divider_highlight_group': 'branch:divider', 'highlight_groups': ['branch_clean', 'branch'], 'contents': 'foo'} ]) def test_file_vcs_status(self): @@ -1127,7 +1157,7 @@ class TestVim(TestCase): with vim_module._with('buffer', '/foo') as segment_info: with replace_attr(self.vim, 'guess', get_dummy_guess(status=lambda file: 'M')): self.assertEqual(file_vcs_status(segment_info=segment_info), [ - {'highlight_group': ['file_vcs_status_M', 'file_vcs_status'], 'contents': 'M'} + {'highlight_groups': ['file_vcs_status_M', 'file_vcs_status'], 'contents': 'M'} ]) with replace_attr(self.vim, 'guess', get_dummy_guess(status=lambda file: None)): self.assertEqual(file_vcs_status(segment_info=segment_info), None) @@ -1144,11 +1174,11 @@ class TestVim(TestCase): self.assertEqual(trailing_whitespace(), None) vim_module.current.buffer[0] = ' ' self.assertEqual(trailing_whitespace(), [{ - 'highlight_group': ['trailing_whitespace', 'warning'], + 'highlight_groups': ['trailing_whitespace', 'warning'], 'contents': '1', }]) self.assertEqual(trailing_whitespace(), [{ - 'highlight_group': ['trailing_whitespace', 'warning'], + 'highlight_groups': ['trailing_whitespace', 'warning'], 'contents': '1', }]) vim_module.current.buffer[0] = '' @@ -1181,7 +1211,7 @@ class TestVim(TestCase): vim_module.current.buffer[0] = ' ' self.assertEqual(self.vim.tab_modified_indicator(pl=pl, segment_info=segment_info), [{ 'contents': '+', - 'highlight_group': ['tab_modified_indicator', 'modified_indicator'], + 'highlight_groups': ['tab_modified_indicator', 'modified_indicator'], }]) vim_module._undo() self.assertEqual(self.vim.tab_modified_indicator(pl=pl, segment_info=segment_info), None) @@ -1193,7 +1223,7 @@ class TestVim(TestCase): self.assertEqual(self.vim.modified_indicator(pl=pl, segment_info=segment_info), None) self.assertEqual(self.vim.tab_modified_indicator(pl=pl, segment_info=segment_info), [{ 'contents': '+', - 'highlight_group': ['tab_modified_indicator', 'modified_indicator'], + 'highlight_groups': ['tab_modified_indicator', 'modified_indicator'], }]) def test_csv_col_current(self): @@ -1212,55 +1242,55 @@ class TestVim(TestCase): buffer[:] = ['1;2;3', '4;5;6'] vim_module._set_cursor(1, 1) self.assertEqual(csv_col_current(), [{ - 'contents': '1', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '1', 'highlight_groups': ['csv:column_number', 'csv'] }]) vim_module._set_cursor(2, 3) self.assertEqual(csv_col_current(), [{ - 'contents': '2', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '2', 'highlight_groups': ['csv:column_number', 'csv'] }]) vim_module._set_cursor(2, 3) self.assertEqual(csv_col_current(display_name=True), [{ - 'contents': '2', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '2', 'highlight_groups': ['csv:column_number', 'csv'] }, { - 'contents': ' (2)', 'highlight_group': ['csv:column_name', 'csv'] + 'contents': ' (2)', 'highlight_groups': ['csv:column_name', 'csv'] }]) buffer[:0] = ['Foo;Bar;Baz'] vim_module._set_cursor(2, 3) self.assertEqual(csv_col_current(), [{ - 'contents': '2', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '2', 'highlight_groups': ['csv:column_number', 'csv'] }, { - 'contents': ' (Bar)', 'highlight_group': ['csv:column_name', 'csv'] + 'contents': ' (Bar)', 'highlight_groups': ['csv:column_name', 'csv'] }]) if sys.version_info < (2, 7): raise SkipTest('csv module in Python-2.6 does not handle multiline csv files well') buffer[len(buffer):] = ['1;"bc', 'def', 'ghi', 'jkl";3'] vim_module._set_cursor(5, 1) self.assertEqual(csv_col_current(), [{ - 'contents': '2', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '2', 'highlight_groups': ['csv:column_number', 'csv'] }, { - 'contents': ' (Bar)', 'highlight_group': ['csv:column_name', 'csv'] + 'contents': ' (Bar)', 'highlight_groups': ['csv:column_name', 'csv'] }]) vim_module._set_cursor(7, 6) self.assertEqual(csv_col_current(), [{ - 'contents': '3', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '3', 'highlight_groups': ['csv:column_number', 'csv'] }, { - 'contents': ' (Baz)', 'highlight_group': ['csv:column_name', 'csv'] + 'contents': ' (Baz)', 'highlight_groups': ['csv:column_name', 'csv'] }]) self.assertEqual(csv_col_current(name_format=' ({column_name:.1})'), [{ - 'contents': '3', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '3', 'highlight_groups': ['csv:column_number', 'csv'] }, { - 'contents': ' (B)', 'highlight_group': ['csv:column_name', 'csv'] + 'contents': ' (B)', 'highlight_groups': ['csv:column_name', 'csv'] }]) self.assertEqual(csv_col_current(display_name=True, name_format=' ({column_name:.1})'), [{ - 'contents': '3', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '3', 'highlight_groups': ['csv:column_number', 'csv'] }, { - 'contents': ' (B)', 'highlight_group': ['csv:column_name', 'csv'] + 'contents': ' (B)', 'highlight_groups': ['csv:column_name', 'csv'] }]) self.assertEqual(csv_col_current(display_name=False, name_format=' ({column_name:.1})'), [{ - 'contents': '3', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '3', 'highlight_groups': ['csv:column_number', 'csv'] }]) self.assertEqual(csv_col_current(display_name=False), [{ - 'contents': '3', 'highlight_group': ['csv:column_number', 'csv'] + 'contents': '3', 'highlight_groups': ['csv:column_number', 'csv'] }]) finally: vim_module._bw(segment_info['bufnr']) diff --git a/tests/test_shells/bash.daemon.ok b/tests/test_shells/bash.daemon.ok index f6c3d0ff..e4535b1e 100644 --- a/tests/test_shells/bash.daemon.ok +++ b/tests/test_shells/bash.daemon.ok @@ -7,8 +7,8 @@   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s [1]+ Terminated bgscript.sh -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" - USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.hostname.display false + USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.user.display false   BRANCH  ⋯  tests  shell  3rd  echo '                                      abc                                      def @@ -26,5 +26,5 @@ def   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' -  BRANCH  ⋯  shell  3rd  «Unicode!»  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +  BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.dividers.left.hard \$ABC   BRANCH $ABC⋯  shell  3rd  «Unicode!» $ABCfalse diff --git a/tests/test_shells/bash.nodaemon.ok b/tests/test_shells/bash.nodaemon.ok index 36e317fe..56dd1fc5 100644 --- a/tests/test_shells/bash.nodaemon.ok +++ b/tests/test_shells/bash.nodaemon.ok @@ -7,8 +7,8 @@   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s [1]+ Terminated bgscript.sh -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" - USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.hostname.display false + USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.user.display false   BRANCH  ⋯  tests  shell  3rd  echo '    abc    def @@ -26,5 +26,5 @@ def   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' -  BRANCH  ⋯  shell  3rd  «Unicode!»  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +  BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.dividers.left.hard \$ABC   BRANCH $ABC⋯  shell  3rd  «Unicode!» $ABCfalse diff --git a/tests/test_shells/busybox.daemon.ok b/tests/test_shells/busybox.daemon.ok index fcaf7474..0230f4de 100644 --- a/tests/test_shells/busybox.daemon.ok +++ b/tests/test_shells/busybox.daemon.ok @@ -6,8 +6,8 @@   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s [1]+ Terminated bgscript.sh -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" - USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  set_theme_option default_leftonly.segment_data.hostname.display false + USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.user.display false   BRANCH  ⋯  tests  shell  3rd  echo '                                      abc                                      def @@ -25,5 +25,5 @@ def   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' -  BRANCH  ⋯  shell  3rd  «Unicode!»  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +  BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.dividers.left.hard \$ABC   BRANCH $ABC⋯  shell  3rd  «Unicode!» $ABCfalse diff --git a/tests/test_shells/busybox.nodaemon.ok b/tests/test_shells/busybox.nodaemon.ok index f3edb6e8..fa485401 100644 --- a/tests/test_shells/busybox.nodaemon.ok +++ b/tests/test_shells/busybox.nodaemon.ok @@ -6,8 +6,8 @@   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s [1]+ Terminated bgscript.sh -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" - USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  set_theme_option default_leftonly.segment_data.hostname.display false + USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.user.display false   BRANCH  ⋯  tests  shell  3rd  echo '    abc    def @@ -25,5 +25,5 @@ def   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' -  BRANCH  ⋯  shell  3rd  «Unicode!»  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +  BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.dividers.left.hard \$ABC   BRANCH $ABC⋯  shell  3rd  «Unicode!» $ABCfalse diff --git a/tests/test_shells/dash.daemon.ok b/tests/test_shells/dash.daemon.ok index cbcd8f79..042665d8 100644 --- a/tests/test_shells/dash.daemon.ok +++ b/tests/test_shells/dash.daemon.ok @@ -5,8 +5,8 @@   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bgscript.sh & waitpid.sh   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1   USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +set_theme_option default_leftonly.segment_data.hostname.display false +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1   USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.user.display false   BRANCH  ⋯  tests  shell  3rd  echo '                                      abc                                      def @@ -24,5 +24,5 @@ def   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' -  BRANCH  ⋯  shell  3rd  «Unicode!»  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +  BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.dividers.left.hard \$ABC   BRANCH $ABC⋯  shell  3rd  «Unicode!» $ABCfalse diff --git a/tests/test_shells/dash.nodaemon.ok b/tests/test_shells/dash.nodaemon.ok index 64e455b6..bac163c1 100644 --- a/tests/test_shells/dash.nodaemon.ok +++ b/tests/test_shells/dash.nodaemon.ok @@ -5,8 +5,8 @@   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bgscript.sh & waitpid.sh   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1   USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +set_theme_option default_leftonly.segment_data.hostname.display false +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1   USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.user.display false   BRANCH  ⋯  tests  shell  3rd  echo '    abc    def @@ -24,5 +24,5 @@ def   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' -  BRANCH  ⋯  shell  3rd  «Unicode!»  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +  BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.dividers.left.hard \$ABC   BRANCH $ABC⋯  shell  3rd  «Unicode!» $ABCfalse diff --git a/tests/test_shells/input.bash b/tests/test_shells/input.bash index 4ad925fc..0a1c0165 100644 --- a/tests/test_shells/input.bash +++ b/tests/test_shells/input.bash @@ -1,7 +1,13 @@ +set_theme_option() { + export POWERLINE_THEME_OVERRIDES="${POWERLINE_THEME_OVERRIDES};$1=$2" +} +set_theme() { + export POWERLINE_CONFIG_OVERRIDES="ext.shell.theme=$1" +} +set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false +set_theme default_leftonly export VIRTUAL_ENV= source powerline/bindings/bash/powerline.sh -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" cd tests/shell/3rd cd .git cd .. @@ -10,8 +16,8 @@ VIRTUAL_ENV= bgscript.sh & waitpid.sh false kill `cat pid` ; sleep 1s -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +set_theme_option default_leftonly.segment_data.hostname.display false +set_theme_option default_leftonly.segment_data.user.display false echo ' abc def @@ -25,7 +31,7 @@ cd ../'(echo)' cd ../'$(echo)' cd ../'`echo`' cd ../'«Unicode!»' -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +set_theme_option default_leftonly.dividers.left.hard \$ABC false true is the last line exit diff --git a/tests/test_shells/input.busybox b/tests/test_shells/input.busybox index 94bee2f5..16824d7b 100644 --- a/tests/test_shells/input.busybox +++ b/tests/test_shells/input.busybox @@ -1,6 +1,12 @@ +set_theme_option() { + export POWERLINE_THEME_OVERRIDES="${POWERLINE_THEME_OVERRIDES};$1=$2" +} +set_theme() { + export POWERLINE_CONFIG_OVERRIDES="ext.shell.theme=$1" +} +set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false +set_theme default_leftonly . powerline/bindings/shell/powerline.sh -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" export VIRTUAL_ENV= cd tests/shell/3rd cd .git @@ -10,8 +16,8 @@ VIRTUAL_ENV= bgscript.sh & waitpid.sh false kill `cat pid` ; sleep 1s -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +set_theme_option default_leftonly.segment_data.hostname.display false +set_theme_option default_leftonly.segment_data.user.display false echo ' abc def @@ -25,7 +31,7 @@ cd ../'(echo)' cd ../'$(echo)' cd ../'`echo`' cd ../'«Unicode!»' -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +set_theme_option default_leftonly.dividers.left.hard \$ABC false true is the last line exit diff --git a/tests/test_shells/input.dash b/tests/test_shells/input.dash index 94bee2f5..16824d7b 100644 --- a/tests/test_shells/input.dash +++ b/tests/test_shells/input.dash @@ -1,6 +1,12 @@ +set_theme_option() { + export POWERLINE_THEME_OVERRIDES="${POWERLINE_THEME_OVERRIDES};$1=$2" +} +set_theme() { + export POWERLINE_CONFIG_OVERRIDES="ext.shell.theme=$1" +} +set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false +set_theme default_leftonly . powerline/bindings/shell/powerline.sh -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" export VIRTUAL_ENV= cd tests/shell/3rd cd .git @@ -10,8 +16,8 @@ VIRTUAL_ENV= bgscript.sh & waitpid.sh false kill `cat pid` ; sleep 1s -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +set_theme_option default_leftonly.segment_data.hostname.display false +set_theme_option default_leftonly.segment_data.user.display false echo ' abc def @@ -25,7 +31,7 @@ cd ../'(echo)' cd ../'$(echo)' cd ../'`echo`' cd ../'«Unicode!»' -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +set_theme_option default_leftonly.dividers.left.hard \$ABC false true is the last line exit diff --git a/tests/test_shells/input.fish b/tests/test_shells/input.fish index 0e09b54d..968248f1 100644 --- a/tests/test_shells/input.fish +++ b/tests/test_shells/input.fish @@ -1,10 +1,16 @@ +function set_theme_option + set -g -x POWERLINE_THEME_OVERRIDES "$POWERLINE_THEME_OVERRIDES;$argv[1]=$argv[2]" +end +function set_theme + set -g -x POWERLINE_CONFIG_OVERRIDES "ext.shell.theme=$argv" +end +set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false +set_theme default_leftonly set fish_function_path "$PWD/powerline/bindings/fish" $fish_function_path while jobs | grep fish_update_completions sleep 1 end powerline-setup -set POWERLINE_COMMAND "$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" -set POWERLINE_COMMAND "$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" setenv VIRTUAL_ENV cd tests/shell/3rd cd .git @@ -23,7 +29,7 @@ cd ../'(echo)' cd ../'$(echo)' cd ../'`echo`' cd ../'«Unicode!»' -set POWERLINE_COMMAND "$POWERLINE_COMMAND -c ext.shell.theme=default" +set_theme default set -g fish_key_bindings fish_vi_key_bindings ii false diff --git a/tests/test_shells/input.mksh b/tests/test_shells/input.mksh index 8174254a..1656800e 100644 --- a/tests/test_shells/input.mksh +++ b/tests/test_shells/input.mksh @@ -1,6 +1,12 @@ +set_theme_option() { + export POWERLINE_THEME_OVERRIDES="${POWERLINE_THEME_OVERRIDES};$1=$2" +} +set_theme() { + export POWERLINE_CONFIG_OVERRIDES="ext.shell.theme=$1" +} +set_theme default_leftonly +set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false . powerline/bindings/shell/powerline.sh -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" export VIRTUAL_ENV= cd tests/shell/3rd cd .git @@ -10,8 +16,8 @@ VIRTUAL_ENV= bgscript.sh & waitpid.sh false kill `cat pid` ; sleep 1 -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +set_theme_option default_leftonly.segment_data.hostname.display false +set_theme_option default_leftonly.segment_data.user.display false echo -n echo ' abc @@ -26,7 +32,7 @@ cd ../'(echo)' cd ../'$(echo)' cd ../'`echo`' cd ../'«Unicode!»' -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +set_theme_option default_leftonly.dividers.left.hard \$ABC false true is the last line exit diff --git a/tests/test_shells/input.rc b/tests/test_shells/input.rc new file mode 100644 index 00000000..1ae37ff0 --- /dev/null +++ b/tests/test_shells/input.rc @@ -0,0 +1,32 @@ +fn set_theme_option { + POWERLINE_THEME_OVERRIDES = $POWERLINE_THEME_OVERRIDES';'$1'='$2 +} +set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false +POWERLINE_CONFIG_OVERRIDES = 'ext.shell.theme=default_leftonly' +. powerline/bindings/rc/powerline.rc +VIRTUAL_ENV = () +cd tests/shell/3rd +cd .git +cd .. +VIRTUAL_ENV = '/home/foo/.virtenvs/some-virtual-environment' +VIRTUAL_ENV = () +bgscript.sh & waitpid.sh +false +kill `{cat pid} ; sleep 1s +cd $DIR1 +cd ../$DIR2 +cd ../'\[\]' +cd ../'%%' +cd ../'#[bold]' +cd ../'(echo)' +cd ../'$(echo)' +cd ../'`echo`' +cd ../'«Unicode!»' +false +set_theme_option default_leftonly.segment_data.hostname.display false +set_theme_option default_leftonly.segment_data.user.display false +echo `{ + echo Continuation! +} +true is the last line +exit diff --git a/tests/test_shells/input.tcsh b/tests/test_shells/input.tcsh index 5302783b..509c7ae6 100644 --- a/tests/test_shells/input.tcsh +++ b/tests/test_shells/input.tcsh @@ -1,5 +1,6 @@ +setenv POWERLINE_THEME_OVERRIDES "default_leftonly.segment_data.hostname.args.only_if_ssh=false" +setenv POWERLINE_CONFIG_OVERRIDES "ext.shell.theme=default_leftonly" source powerline/bindings/tcsh/powerline.tcsh -set POWERLINE_COMMAND=$POWERLINE_COMMAND:q" -t default_leftonly.segment_data.hostname.args.only_if_ssh=false -c ext.shell.theme=default_leftonly" unsetenv VIRTUAL_ENV cd tests/shell/3rd cd .git diff --git a/tests/test_shells/input.zsh b/tests/test_shells/input.zsh index 937a9114..7775ba97 100644 --- a/tests/test_shells/input.zsh +++ b/tests/test_shells/input.zsh @@ -2,13 +2,21 @@ unset HOME unsetopt promptsp notransientrprompt setopt interactivecomments setopt autonamedirs -# POWERLINE_CONFIG_PATH=$PWD/powerline/config_files -# POWERLINE_THEME_CONFIG=( default_leftonly.segment_data.hostname.args.only_if_ssh=false ) -# POWERLINE_CONFIG=( ext.shell.theme=default_leftonly ) -POWERLINE_NO_ZSH_ZPYTHON=1 # TODO: make tests work with zsh/zpython +function set_theme_option() { + export POWERLINE_THEME_OVERRIDES="${POWERLINE_THEME_OVERRIDES};$1=$2" + powerline-reload-config +} +function set_theme() { + export POWERLINE_CONFIG_OVERRIDES="ext.shell.theme=$1" + powerline-reload-config +} +if test -n "$POWERLINE_NO_ZSH_ZPYTHON" ; then + powerline-reload-config(): +fi source powerline/bindings/zsh/powerline.zsh -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly" +set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false +set_theme_option default.segment_data.hostname.args.only_if_ssh false +set_theme default_leftonly export VIRTUAL_ENV= cd tests/shell/3rd cd .git @@ -28,13 +36,13 @@ cd ../'$(echo)' cd ../'`echo`' cd ../'«Unicode!»' cd .. -POWERLINE_COMMAND="${POWERLINE_COMMAND//_leftonly}" ; bindkey -v +bindkey -v ; set_theme default  echo abc false -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.hostname.display=false" -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.user.display=false" +set_theme_option default.segment_data.hostname.display false +set_theme_option default.segment_data.user.display false select abc in def ghi jkl do echo $abc @@ -44,7 +52,7 @@ done cd . cd . hash -d foo=$PWD:h ; cd . -POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC" +set_theme_option default.dividers.left.hard \$ABC true true is the last line exit diff --git a/tests/test_shells/ipython_home/profile_default/ipython_config.py b/tests/test_shells/ipython_home/profile_default/ipython_config.py index 9f6bb567..6d4a2624 100644 --- a/tests/test_shells/ipython_home/profile_default/ipython_config.py +++ b/tests/test_shells/ipython_home/profile_default/ipython_config.py @@ -2,7 +2,7 @@ import os c = get_config() c.InteractiveShellApp.extensions = ['powerline.bindings.ipython.post_0_11'] c.TerminalInteractiveShell.autocall = 1 -c.Powerline.paths = [os.path.abspath('powerline/config_files')] +c.Powerline.config_paths = [os.path.abspath('powerline/config_files')] c.Powerline.theme_overrides = { 'in': { 'segment_data': { diff --git a/tests/test_shells/mksh.daemon.ok b/tests/test_shells/mksh.daemon.ok index 72d58e3d..3619f422 100644 --- a/tests/test_shells/mksh.daemon.ok +++ b/tests/test_shells/mksh.daemon.ok @@ -8,8 +8,8 @@   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1 [1] + Terminated bash -c ... -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" - USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.hostname.display false + USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.user.display false   BRANCH  ⋯  tests  shell  3rd  echo -n   BRANCH  ⋯  tests  shell  3rd  echo '                                      abc @@ -28,5 +28,5 @@ def   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' -  BRANCH  ⋯  shell  3rd  «Unicode!»  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +  BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.dividers.left.hard \$ABC   BRANCH $ABC⋯  shell  3rd  «Unicode!» $ABCfalse diff --git a/tests/test_shells/mksh.nodaemon.ok b/tests/test_shells/mksh.nodaemon.ok index a3550ca6..754633ab 100644 --- a/tests/test_shells/mksh.nodaemon.ok +++ b/tests/test_shells/mksh.nodaemon.ok @@ -8,8 +8,8 @@   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false   HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1 [1] + Terminated bash -c ... -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.display=false" - USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.user.display=false" +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.hostname.display false + USER   BRANCH  ⋯  tests  shell  3rd  set_theme_option default_leftonly.segment_data.user.display false   BRANCH  ⋯  tests  shell  3rd  echo -n   BRANCH  ⋯  tests  shell  3rd  echo '    abc @@ -28,5 +28,5 @@ def   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' -  BRANCH  ⋯  shell  3rd  «Unicode!»  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.dividers.left.hard=\$ABC" +  BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.dividers.left.hard \$ABC   BRANCH $ABC⋯  shell  3rd  «Unicode!» $ABCfalse diff --git a/tests/test_shells/postproc.py b/tests/test_shells/postproc.py index df8a6dad..ff9c5748 100755 --- a/tests/test_shells/postproc.py +++ b/tests/test_shells/postproc.py @@ -98,4 +98,7 @@ with codecs.open(fname, 'r', encoding='utf-8') as R: line = IPYPY_DEANSI_RE.subn('', line)[0] if line == '\n' and not was_empty: line = '' + elif shell == 'rc': + if line == 'read() failed: Connection reset by peer\n': + line = '' W.write(line) diff --git a/tests/test_shells/rc.daemon.ok b/tests/test_shells/rc.daemon.ok new file mode 100644 index 00000000..e2914fa4 --- /dev/null +++ b/tests/test_shells/rc.daemon.ok @@ -0,0 +1,24 @@ +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd .git +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  .git  cd .. +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV = '/home/foo/.virtenvs/some-virtual-environment' +  HOSTNAME  USER  ⓔ  some-virtual-environment   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV = () +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bgscript.sh & waitpid.sh +PID +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `{cat pid} ; sleep 1s +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd $DIR1 +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^[[32m  cd ../$DIR2 +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^H  cd ../'\[\]' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  \[\]  cd ../'%%' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  %%  cd ../'#[bold]' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  «Unicode!»  false +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  «Unicode!»  1  set_theme_option default_leftonly.segment_data.hostname.display false + USER   BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.segment_data.user.display false +  BRANCH  ⋯  shell  3rd  «Unicode!»  echo `{ +                                           echo Continuation! +                                          } +Continuation! diff --git a/tests/test_shells/rc.nodaemon.ok b/tests/test_shells/rc.nodaemon.ok new file mode 100644 index 00000000..fa6f22d5 --- /dev/null +++ b/tests/test_shells/rc.nodaemon.ok @@ -0,0 +1,24 @@ +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd .git +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  .git  cd .. +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV = '/home/foo/.virtenvs/some-virtual-environment' +  HOSTNAME  USER  ⓔ  some-virtual-environment   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV = () +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bgscript.sh & waitpid.sh +PID +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `{cat pid} ; sleep 1s +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd $DIR1 +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^[[32m  cd ../$DIR2 +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^H  cd ../'\[\]' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  \[\]  cd ../'%%' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  %%  cd ../'#[bold]' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  «Unicode!»  false +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  «Unicode!»  1  set_theme_option default_leftonly.segment_data.hostname.display false + USER   BRANCH  ⋯  shell  3rd  «Unicode!»  set_theme_option default_leftonly.segment_data.user.display false +  BRANCH  ⋯  shell  3rd  «Unicode!»  echo `{ +    echo Continuation! +   } +Continuation! diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 5ad1bbfe..81b5edb2 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -1,4 +1,5 @@ #!/bin/sh +set -e : ${PYTHON:=python} FAIL_SUMMARY="" FAILED=0 @@ -70,12 +71,18 @@ run() { TEST_CLIENT="${TEST_CLIENT}" \ SH="${SH}" \ DIR1="${DIR1}" \ + POWERLINE_NO_ZSH_ZPYTHON="$(test $TEST_TYPE = zpython || echo 1)" \ DIR2="${DIR2}" \ XDG_CONFIG_HOME="$PWD/tests/shell/fish_home" \ IPYTHONDIR="$PWD/tests/shell/ipython_home" \ + PYTHONPATH="${PWD}${PYTHONPATH:+:}$PYTHONPATH" \ + POWERLINE_CONFIG_OVERRIDES="${POWERLINE_CONFIG_OVERRIDES}" \ + POWERLINE_THEME_OVERRIDES="${POWERLINE_THEME_OVERRIDES}" \ POWERLINE_SHELL_CONTINUATION=$additional_prompts \ POWERLINE_SHELL_SELECT=$additional_prompts \ - POWERLINE_COMMAND="${POWERLINE_COMMAND} -p $PWD/powerline/config_files" \ + POWERLINE_CONFIG_PATHS="$PWD/powerline/config_files" \ + POWERLINE_COMMAND_ARGS="${POWERLINE_COMMAND_ARGS}" \ + POWERLINE_COMMAND="${POWERLINE_COMMAND}" \ "$@" } @@ -83,7 +90,7 @@ run() { NL="$(printf '\nE')" NL="${NL%E}" -run_test() { +do_run_test() { TEST_TYPE="$1" shift TEST_CLIENT="$1" @@ -173,6 +180,20 @@ run_test() { return 0 } +run_test() { + TEST_TYPE="$1" + TEST_CLIENT="$2" + SH="$3" + local attempts=3 + while test $attempts -gt 0 ; do + rm -f tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.log + rm -f tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.full.log + do_run_test "$@" && return 0 + attempts=$(( attempts - 1 )) + done + return 1 +} + test -d tests/shell && rm -r tests/shell mkdir tests/shell git init tests/shell/3rd @@ -217,6 +238,8 @@ ln -s "$(which grep)" tests/shell/path ln -s "$(which sed)" tests/shell/path ln -s "$(which rm)" tests/shell/path ln -s "$(which uname)" tests/shell/path +ln -s "$(which test)" tests/shell/path +ln -s "$(which pwd)" tests/shell/path ln -s ../../test_shells/bgscript.sh tests/shell/path ln -s ../../test_shells/waitpid.sh tests/shell/path if which socat ; then @@ -233,6 +256,20 @@ for pexe in powerline powerline-config ; do fi done +if test -z "$POWERLINE_RC_EXE" ; then + if which rc-status >/dev/null ; then + # On Gentoo `rc` executable is from OpenRC. Thus app-shells/rc instals + # `rcsh` executable. + POWERLINE_RC_EXE=rcsh + else + POWERLINE_RC_EXE=rc + fi +fi + +if which "$POWERLINE_RC_EXE" >/dev/null ; then + ln -s "$(which $POWERLINE_RC_EXE)" tests/shell/path/rc +fi + for exe in bash zsh busybox fish tcsh mksh dash ipython ; do if which $exe >/dev/null ; then ln -s "$(which $exe)" tests/shell/path @@ -245,7 +282,7 @@ export ADDRESS="powerline-ipc-test-$$" export PYTHON echo "Powerline address: $ADDRESS" -if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || test "x${ONLY_SHELL}" = xbusybox ; then +if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || test "x${ONLY_SHELL}" = xbusybox || test "x${ONLY_SHELL}" = xrc ; then scripts/powerline-config shell command for TEST_TYPE in "daemon" "nodaemon" ; do @@ -299,7 +336,8 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te if test "x$ONLY_TEST_CLIENT" != "x" && test "x$TEST_CLIENT" != "x$ONLY_TEST_CLIENT" ; then continue fi - POWERLINE_COMMAND="$POWERLINE_COMMAND --socket $ADDRESS" + POWERLINE_COMMAND_ARGS="--socket $ADDRESS" + POWERLINE_COMMAND="$POWERLINE_COMMAND" export POWERLINE_COMMAND echo ">> powerline command is ${POWERLINE_COMMAND:-empty}" J=-1 @@ -310,7 +348,8 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te "tcsh -f -i" \ "busybox ash -i" \ "mksh -i" \ - "dash -i" + "dash -i" \ + "rc -i -p" do J="$(( J + 1 ))" if test x$FAST = x1 ; then @@ -326,10 +365,10 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te if test "x$ONLY_SHELL" != "x" && test "x$ONLY_SHELL" != "x$SH" ; then continue fi - if ! which $SH >/dev/null ; then + if ! test -x tests/shell/path/$SH ; then continue fi - echo ">>> $(which $SH)" + echo ">>> $(readlink "tests/shell/path/$SH")" if ! run_test $TEST_TYPE $TEST_CLIENT $TEST_COMMAND ; then FAILED=1 FAIL_SUMMARY="${FAIL_SUMMARY}${NL}T ${TEST_TYPE} ${TEST_CLIENT} ${TEST_COMMAND}" @@ -369,13 +408,28 @@ if ! test -z "$(cat tests/shell/daemon_log_2)" ; then FAIL_SUMMARY="${FAIL_SUMMARY}${NL}L" fi +if ( test "x${ONLY_SHELL}" = "x" || test "x${ONLY_SHELL}" = "xzsh" ) \ + && ( test "x${ONLY_TEST_TYPE}" = "x" || test "x${ONLY_TEST_TYPE}" = "xzpython" ) \ + && zsh -f -c 'zmodload libzpython' 2>/dev/null; then + echo "> zpython" + if ! run_test zpython zpython zsh -f -i ; then + FAILED=1 + FAIL_SUMMARY="${FAIL_SUMMARY}${NL}T zpython zsh -f -i" + fi +fi + if test "x${ONLY_SHELL}" = "x" || test "x${ONLY_SHELL}" = "xipython" ; then if which ipython >/dev/null ; then + # Define some overrides which should be ignored by IPython. + POWERLINE_CONFIG_OVERRIDES='common.term_escape_style=fbterm' + POWERLINE_THEME_OVERRIDES='in.segments.left=[]' echo "> $(which ipython)" if ! run_test ipython ipython ipython ; then FAILED=1 FAIL_SUMMARY="${FAIL_SUMMARY}${NL}T ipython" fi + unset POWERLINE_THEME_OVERRIDES + unset POWERLINE_CONFIG_OVERRIDES fi fi diff --git a/tests/test_shells/zsh.daemon.ok b/tests/test_shells/zsh.daemon.ok index 01b4a0e1..53ff5b4c 100644 --- a/tests/test_shells/zsh.daemon.ok +++ b/tests/test_shells/zsh.daemon.ok @@ -18,14 +18,14 @@   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»'   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  «Unicode!»  cd .. -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="${POWERLINE_COMMAND//_leftonly}" ; bindkey -v +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bindkey -v ; set_theme default  INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd   COMMND   HOSTNAME  USER  ⋯  tests  shell  3rd    INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd    INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  echo abc abc  INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  false - INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.hostname.display=false" - INSERT  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.user.display=false" + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  set_theme_option default.segment_data.hostname.display false + INSERT  USER  ⋯  tests  shell  3rd  set_theme_option default.segment_data.user.display false  INSERT  ⋯  tests  shell  3rd  select abc in def ghi jkl  select                            do  select                             echo $abc @@ -37,5 +37,5 @@ def  INSERT  ⋯  tests  shell  3rd  cd .  INSERT  ⋯  tests  shell  3rd  cd .  INSERT  ⋯  tests  shell  3rd  hash -d foo=$PWD:h ; cd . - INSERT  ~foo  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC" + INSERT  ~foo  3rd  set_theme_option default.dividers.left.hard \$ABC  INSERT $ABC~foo  3rd $ABCtrue diff --git a/tests/test_shells/zsh.nodaemon.ok b/tests/test_shells/zsh.nodaemon.ok index 2b86af4e..5883a780 100644 --- a/tests/test_shells/zsh.nodaemon.ok +++ b/tests/test_shells/zsh.nodaemon.ok @@ -18,14 +18,14 @@   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»'   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  «Unicode!»  cd .. -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="${POWERLINE_COMMAND//_leftonly}" ; bindkey -v +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bindkey -v ; set_theme default  INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd   COMMND   HOSTNAME  USER  ⋯  tests  shell  3rd    INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd    INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  echo abc abc  INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  false - INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.hostname.display=false" - INSERT  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.user.display=false" + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  set_theme_option default.segment_data.hostname.display false + INSERT  USER  ⋯  tests  shell  3rd  set_theme_option default.segment_data.user.display false  INSERT  ⋯  tests  shell  3rd  select abc in def ghi jkl  select  do  select   echo $abc @@ -37,5 +37,5 @@ def  INSERT  ⋯  tests  shell  3rd  cd .  INSERT  ⋯  tests  shell  3rd  cd .  INSERT  ⋯  tests  shell  3rd  hash -d foo=$PWD:h ; cd . - INSERT  ~foo  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC" + INSERT  ~foo  3rd  set_theme_option default.dividers.left.hard \$ABC  INSERT $ABC~foo  3rd $ABCtrue diff --git a/tests/test_shells/zsh.zpython.ok b/tests/test_shells/zsh.zpython.ok new file mode 100644 index 00000000..53ff5b4c --- /dev/null +++ b/tests/test_shells/zsh.zpython.ok @@ -0,0 +1,41 @@ + +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd .git +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  .git  cd .. +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV="/home/USER/.virtenvs/some-virtual-environment" +  HOSTNAME  USER  ⓔ  some-virtual-environment   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV= +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bgscript.sh & waitpid.sh +[1] PID +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s +[1] + terminated bgscript.sh +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd "$DIR1" +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^[[32m  cd ../"$DIR2" +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^H  cd ../'\[\]' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  \[\]  cd ../'%%' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  %%  cd ../'#[bold]' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  cd ../'«Unicode!»' +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  «Unicode!»  cd .. +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bindkey -v ; set_theme default + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd   COMMND   HOSTNAME  USER  ⋯  tests  shell  3rd   + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd   + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  echo abc +abc + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  false + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  set_theme_option default.segment_data.hostname.display false + INSERT  USER  ⋯  tests  shell  3rd  set_theme_option default.segment_data.user.display false + INSERT  ⋯  tests  shell  3rd  select abc in def ghi jkl + select                            do + select                             echo $abc + select                             break + select                            done +1) def 2) ghi 3) jkl +                   Select variant  1 +def + INSERT  ⋯  tests  shell  3rd  cd . + INSERT  ⋯  tests  shell  3rd  cd . + INSERT  ⋯  tests  shell  3rd  hash -d foo=$PWD:h ; cd . + INSERT  ~foo  3rd  set_theme_option default.dividers.left.hard \$ABC + INSERT $ABC~foo  3rd $ABCtrue diff --git a/tests/test_watcher.py b/tests/test_watcher.py index dce37bae..571cc8c4 100644 --- a/tests/test_watcher.py +++ b/tests/test_watcher.py @@ -16,7 +16,7 @@ from powerline.lib.monotonic import monotonic from tests import TestCase, SkipTest -INOTIFY_DIR = 'inotify' + os.environ.get('PYTHON', '') +INOTIFY_DIR = 'inotify' + os.path.basename(os.environ.get('PYTHON', '')) def clear_dir(dir): diff --git a/tests/vim.py b/tests/vim.py index f3d84355..142d6929 100644 --- a/tests/vim.py +++ b/tests/vim.py @@ -191,9 +191,6 @@ def command(cmd): elif cmd.startswith('hi '): sp = cmd.split() _highlights[sp[1]] = sp[2:] - elif cmd.startswith('function! Powerline_plugin_ctrlp'): - # Ignore CtrlP updating functions - pass elif cmd.startswith('augroup'): augroup = cmd.partition(' ')[2] if augroup.upper() == 'END': @@ -858,9 +855,6 @@ class _WithBufName(object): self.buffer = buffer self.old = buffer.name buffer.name = self.new - if buffer.name and os.path.basename(buffer.name) == 'ControlP': - buffer.vars['powerline_ctrlp_type'] = 'main' - buffer.vars['powerline_ctrlp_args'] = ['focus', 'byfname', '0', 'prev', 'item', 'next', 'marked'] def __exit__(self, *args): self.buffer.name = self.old diff --git a/tests/vim_utils.vim b/tests/vim_utils.vim new file mode 100644 index 00000000..5922d454 --- /dev/null +++ b/tests/vim_utils.vim @@ -0,0 +1,87 @@ +let g:powerline_use_var_handler = 1 + +let g:root=expand(':p:h:h') +let g:mf=g:root.'/message.fail' + +command -nargs=1 LST :call writefile(, g:mf) | cquit +command -nargs=1 ERR :LST [] +command -nargs=1 EXC :ERR 'Unexpected exception', , v:exception, v:throwpoint + +function EnablePlugins(...) + let &runtimepath = join(map(copy(a:000), 'escape(g:root."/tests/vim-plugins/".v:val, "\\,")'), ',') + try + runtime! plugin/*.vim + silent doautocmd BufWinEnter + silent doautocmd BufEnter + silent doautocmd VimEnter + catch + EXC EnablePlugins + endtry +endfunction +function RecordStatusline() + let g:statusline = &l:statusline + if g:statusline[:1] is# '%!' + let g:statusline_value=eval(g:statusline[2:]) + else + ERR 'Statusline does not start with %!', g:statusline + endif + return '' +endfunction +function SourcePowerline() + let g:powerline_config_paths = [g:root . '/powerline/config_files'] + try + execute 'source' fnameescape(g:root . '/powerline/bindings/vim/plugin/powerline.vim') + catch + EXC SourcePowerline + endtry +endfunction +function NDiff(actual, expected) + return systemlist(shellescape(g:root.'/tests/bot-ci/scripts/ndiff-strings.py').' '.shellescape(a:actual).' '.shellescape(a:expected)) +endfunction +function CheckStatuslineValue(actual, expected) + if a:actual isnot# a:expected + LST ['Expected different statusline value', a:actual, a:expected] + NDiff(a:actual, a:expected) + endif +endfunction +function CheckRecordedStatuslineValue(expected) + return CheckStatuslineValue(g:statusline_value, a:expected) +endfunction +function GetCurrentStatusline() + if &l:statusline[:1] isnot# '%!' + ERR 'Statusline does not start with %!', &l:statusline + endif + return eval(&l:statusline[2:]) +endfunction +function CheckCurrentStatusline(expected) + return CheckStatuslineValue(GetCurrentStatusline(), a:expected) +endfunction +function CheckMessages() + if !empty(g:powerline_log_messages) + LST ['Unexpected messages in log'] + g:powerline_log_messages + endif + redir => mes + messages + redir END + let mesl = split(mes, "\n")[1:] + if !empty(mesl) + LST ['Unexpected messages'] + split(mes, "\n", 1) + endif +endfunction +function RunPython(s) + if has('python') + execute 'python' a:s + else + execute 'python3' a:s + endif +endfunction +function PyFile(f) + if has('python') + execute 'pyfile' fnameescape(g:root.'/tests/'.a:f.'.py') + else + execute 'py3file' fnameescape(g:root.'/tests/'.a:f.'.py') + endif +endfunction + +for s:c in ['noremap', 'noremap!'] + execute s:c '' '(PowerlineTestRecordStatusline)' 'RecordStatusline()' +endfor