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