Writing a custom Powerline plugin

Powerline is a tool I use as part of my dev environment setup, and have my config backed up as part of my dotfiles.

It shows helpful information and context for stuff I’m working on, as well as providing some eye-candy for my command line environment.

Env

While it comes with a lot of integrations out of the box i.e. bash, zsh, tmux, vim, etc, it also provides a way for you to write your own “segments”. This should serve as a quick guide for rolling your own custom Powerline plugin.

Basic structure and configuration

Each powerline segment is a callable object. It is supposed to be either a Python function or powerline.segments.Segment class.

I recently wrote my own custom one that displays the current Kubernetes context and namespace, which uses a Segment class. Here is a shortened version which shows the basic structure.

class KubernetesSegment(Segment):
    """Constructs the segment's sections with the configured colorscheme and
    visibility options applied."""

    @staticmethod
    def kube_ctx_info(pl):
        """Resolves the current active Kubernetes context (and namespace)
        from `$KUBECONFIG`."""
        try:
            current_context = config.list_kube_config_contexts()[1]
            return current_context['name'] or 'N/A', \
                   current_context['context']['namespace'] or 'default'
        except Exception as e:
            pl.error(e)

    def __call__(self, pl):
        pl.debug('Running powerline-k8s...')

        sections = []

        # additional logic to determine segment contents

        sections.append({
            'contents': f'u'\U00002638' ',
            'highlight_groups': 'k8s',
            'divider_highlight_group': 'k8s:divider',
        })

        return sections

k8s = with_docstring(KubernetesSegment(),
"""Return the current Kubernetes context and namespace.

It will show the current context and namespace from `$KUBECONFIG`.

Divider highlight group used: ``k8s:divider``.

Highlight groups used: ``k8s``, ``k8s_context``, ``k8s_namespace``.
""")
"""Custom segment entry point."""

Make sure to add the powerline-status package as a dependency.

Basically the class contains a function that returns a Segment dictionary which tells Powerline what to display. In this particular example, the following keys were used:

  • contents: Actual segment contents, excluding dividers and before/after. May be None.

  • highlight_groups, divider_highlight_group: Used highlight groups. May be None.

Highlight groups determine the ‘style’ that is used for a particular segment e.g. background and foreground, divider color to clearly distinguish one segment from another.

The colors that are available to you will depend on the current colorscheme that you are using. In general you’ll need to add the “groups” definition to the colorscheme config file, which in this case was <powerline_dir>/colorschemes/solarized.json.

{
  "k8s":           { "fg": "solarized:blue", "bg": "solarized:base02", "attrs": [] },
  "k8s:divider":   { "fg": "gray4",          "bg": "solarized:base02", "attrs": [] }
}

Check out the Powerline docs for a more detailed view into configuration and customization.

The next step is to let Powerline know of the new segment by adding it to the segment’s config file. To add the new segment to the current shell prompt, add the following entry to the <powerline_dir>/themes/shell/default.json config file.

{
  "function": "k8s",
  "priority": 30
}

Installation

Once all configuration has been done it’s time to “install” the segment and try it out, you can do so by executing:

$ python3 -m pip install --editable .

Installing the package in editable mode saves you from having to “re-install” to see the latest changes. If everything went well you should be able to see your new segment.

Troubleshooting

Having issues with your plugin, try out the following:

  • Run powerline-lint to check for errors in the configuration files i.e. colorscheme and/or segment config.

  • Restart powerline by running powerline-daemon --replace.

  • Configure logging with PowerlineLogger and where you want the logs to be written for easier debugging.

It is also worth checking out the Powerline docs for other common issues that you may encounter.

Misc