Powerline on Linux: An Integration Guide

Render clean status lines and prompts in Vim, Bash, i3 and tmux

Dane Bulat
17 min readNov 27, 2020

Introduction

Productivity tools on Linux often include both a status line and a prompt. The function of a status line is to display important information relevant to the program’s current context; and a prompt identifies where a program is expecting some input from the user. Some good application examples that utilize these features include the Bash shell, i3 window manager and Vim.

Powerline is a program that renders status lines and prompts in a consistent way across multiple applications. The powerline configuration files are modified with JSON to set colors, symbols, and even control the type of content that is rendered on an application’s status line or prompt. For example, we might want the shell prompt to output the absolute path of the current working directory, or have the window manager’s status bar display system information such as CPU loads and consumed memory. Powerline can be configured to accomplish both of these tasks.

This article will detail how to install powerline on Linux along with its dependencies. Subsequent sections will then go through how to integrate powerline with the Vim text editor, Bash shell, i3 window manager, and tmux program. Each section will build upon the last by gradually exposing how powerline works behind the scenes and how to configure it effectively. After completing this guide you will be able to create your own layouts and color schemes with powerline for rendering your favorite prompts and status lines on Linux.

System Dependencies

Powerline is written in the Python programming language, which means that your system will need to have a recent version of Python installed to run it. This guide recommends having the latest version of Python installed to run powerline. Use your Linux distribution’s package manager to install Python if it is not already on your system:

$ sudo pacman -S python      # Arch
$ sudo apt install python # Debian and Ubuntu
$ sudo dnf install python # Fedora and CentOS

It is also a good idea to install the git package so powerline can detect and render information about the git repositories on your file system:

$ sudo pacman -S git         # Arch
$ sudo apt install git # Debian and Ubuntu
$ sudo dnf install git # Fedora and CentOS

Keep in mind that we will need to install a couple of Python packages later to enable rendering of system information, as well as integrating powerline with the i3 window manager. We will install these modules via pip — Python’s very own package manager — which we’ll go through how to set up next.

Installation

This section will detail how to install powerline with the pip package manager. The installation instructions presented in this section will work on any Linux distribution.

You may also have seen a powerline package in your distribution’s official repositories. The problem with these packages is that they often include extra scripts that get invoked automatically when launching certain applications. For example, the official powerline package for Arch Linux installs a global powerline.vim script that Vim automatically loads when it is launched. This will result in a conflict If you have another status line plug-in enabled such as vim-airline. With this in mind, I recommend installing powerline transparently via pip as the first course of action.

Installing Pip

To set up pip we firstly need to download its installation script called get-pip.py from a remote server. Let’s download this script via curl in an appropriate location:

$ cd ~/Downloads
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

Then run get-pip.py via the Python interpreter to install pip on your system:

$ python3.8 get-pip.py# Output
Successfully installed pip-20.2.4 setuptools-50.3.2 wheel-0.35.1

An executable file called pip is created on your file system which will probably be located at ~/.local/bin/pip. Your PATH environment variable may need to be updated if pip cannot be executed directly from the command-line. Let’s firstly confirm where pip is installed with a find command:

$ sudo find / -name pip# Output
/home/dane/.local/bin/pip

The output above confirms that pip is installed locally in the home folder’s .local/bin directory. If necessary, append your location directory to the PATH variable in ~/.bashrc:

$ echo $PATH
$ vim ~/.bashrc
# In bash.rc
export PATH="~/.local/bin:$PATH"

Alternatively, If your system has multiple Python installations with each one containing a different version of pip, you could create an alias that directly points to the pip executable you wish to use:

# Provide an absolute path
alias pip=”/home/dane/.local/bin/pip”

Lastly, be sure to refresh the bash configuration and confirm the pip command works by checking its version:

$ source ~/.bashrc
$ pip --version
# Output
pip 20.2.4 from /home/dane/.local/lib/python3.8/site-packages/pip (python 3.8)
# Display pip help
$ pip -h

We will use pip to download and install the official powerline package in addition to a couple of other important python modules in the next section.

Installing Powerline

The official powerline package in the Python Package index is called powerline-status. Be careful not to confuse it with the powerline package — which is completely unrelated to the plug-in that we are discussing in this guide!

Install powerline via pip by running the following command:

$ pip install powerline-status

Then confirm its install location on your file system using pip’s show command:

$ pip show powerline-status# Output
...
Location: /home/dane/.local/lib/python3.8/site-packages

You can issue an uninstall command If you ever want to remove powerline from your system altogether:

$ pip uninstall powerline-status

Python Packages

Moving forward, two Python packages should also be installed to give powerline some extra functionality:

  • psutil: Required for segments that display system properties such as CPU load percentage and network loads.
  • i3ipc: Required for binding the powerline program with the i3 window manager and handling i3 segments.

I recommend installing the i3ipc package even if you are not an i3 user because it might come in handy at a later date. Invoke pip to Install these packages:

$ pip install psutil i3ipc# Installs to:
# ~/.local/lib/python3.8/site-packages/psutil
# ~/.local/lib/python3.8/site-packages/i3ipc

Font Installation

The powerline plug-in uses several special glyphs to do things like render its arrow effect. We therefore need to acquire some fonts that include these special symbols. There are two ways of doing this:

  • Download and install the PowerlineSymbols.otf fallback font by following the instructions on this page. This font will be used when powerline needs to render a special glyph symbol which the primary font is missing.
  • Install a range of patched fonts that are able to render all of powerline’s special glyphs.

This guide recommends the second option which involves downloading the powerline fonts git repository and installing its collection of patched fonts. Feel free to browse through the repository’s GitHub page to discover which patched fonts are included along with their corresponding license. You will notice that most patched fonts inherit the same name as the un-patched version, but have for Powerline appended to the end. For example, the patched Source Code Pro font is named Source Code Pro for Powerline.

Let’s go ahead and download the repository in an appropriate location and run the install.sh script in its root directory. The patched fonts will be copied into your local fonts directory (the place where a user’s fonts are stored) and the font cache will update:

$ git clone https://github.com/powerline/fonts.git --depth=1 
powerline-fonts
$ cd powerline-fonts
$ ./install.sh
# Output
Copying fonts...
Resetting font cache, this may take a moment...
Powerline fonts installed to /home/dane/.local/share/fonts
# List fonts directory to confirm the copy was successful
$ ls ~/.local/share/fonts

An uninstall.sh script is also included in the repository’s root directory. You can run this script to remove the patched fonts from your system.

From here you can open up any application — such as your terminal emulator — and select one of the patched fonts to use for that program. When it comes to choosing a font for powerline, I recommend firstly previewing them in an application called font-manager:

$ yay -S font-manager              # Arch
$ sudo apt install font-manager # Debian and Ubuntu
$ sudo dnf install font-manager # Fedora
# Run
$ font-manager
Previewing powerline fonts with the Font Manager application.

Using Powerline with Vim

This section will detail how to enable powerline inside the Vim text editor. The goal for this section is to simply see powerline in action and get a feel for how it changes the overall experience of using an application.

Your version of Vim must have been compiled with Python in order for powerline to work. Run the following command to check the Python versions your Vim installation supports:

$ vim — version | grep +python# Output
+python/dyn +python3/dyn

You are good to go if you see a line containing either +python or +python3 — meaning that Vim supports Python versions 2 and 3 respectively.

At this point, all we need to do is add some code to .vimrc to enable powerline:

set laststatus=2           " Always display the status bar
set powerline_cmd="py3" " Tell powerline to use Python 3
python3 from powerline.vim import setup as powerline_setup
python3 powerline_setup()
python3 del powerline_setup

No other code is necessary to get powerline working inside of Vim. This means that if you are using a Vim plug-in manager such as Vundle and have a :Plugin directive that references another installation of powerline, that line must be removed. To disable powerline in Vim, simply comment out the code above by preceding each line with a double-quote (").

The status line and file tabs will now be rendered via powerline the next time you open Vim. If you switch between the different modes — such as Insert, Visual and Normal — you’ll notice the status line text and colors change appropriately. I encourage you to have a play with some files and observe how the status line changes before proceeding to the next section.

The Vim status line being rendered with powerline.

Using Powerline with Bash

This section will take a look at using powerline to render a custom Bash prompt. Its subsections will detail:

  • Modifying .bashrc to initialize powerline and its environment.
  • Making a local copy of powerline’s default configuration files for further editing.
  • The responsibility of the various configuration files and how they are structured on the file system.
  • Creating a theme for the Bash prompt.
  • Creating a color scheme for the Bash prompt.

After completing this section you will be familiar with the “powerline workflow” and will have acquired enough knowledge to configure powerline to work with other applications.

Modifying .bashrc

An application must invoke a particular binding script when it is launched to enable powerline rendering. Several bindings are shipped with the powerline installation and are stored in the powerline/bindings/ directory. As an example, the bash/powerline.sh script is the binding for bash and must be invoked when bash is launched.

With this in mind, add the upcoming code to your .bashrc file to initialize some necessary environment variables and invoke the corresponding binding script:

# Run powerline daemon
# To locate this file, run: sudo find / -name powerline-deamon

/home/dane/.local/bin/powerline-daemon -q
# Cache powerline location
# To locate this directory, run: pip show powerline-status

export POWERLINE_LOCATION="/home/dane/.local/lib/python3.8/site-packages/powerline"
# Set up powerline environment
export POWERLINE_CONFIG_COMMAND=powerline-config
export POWERLINE_BASH_CONTINUATION=1
export POWERLINE_BASH_SELECT=1
# Invoke binding script
. "$POWERLINE_LOCATION/bindings/bash/powerline.sh"
  • /home/dane/.local/bin/powerline-daemon -q
    We firstly ensure that the powerline daemon is running so it automatically handles requests that are sent from applications rendering with powerline in the background. The daemon process dramatically improves the performance of powerline and should always be running.
  • export POWERLINE_LOCATION="/home/dane/.local/lib/python3.8/site-packages/powerline"
    An environment variable called POWERLINE_LOCATION is defined to cache the powerline installation directory for convenience. Change this value to your installation path accordingly.
  • export POWERLINE_CONFIG_COMMAND=powerline-config
    export POWERLINE_BASH_CONTINUATION=1
    export POWERLINE_BASH_SELECT=1
    Three environment variables are then initialized with recommended values to ensure correct rendering intervals. These values are queried in the bash binding script.
  • . "$POWERLINE_LOCATION/bindings/bash/powerline.sh"
    Invokes the bash binding script. After running this command, powerline will now render your bash prompt.

When we start modifying configuration files, the powerline daemon process needs to be killed and restarted in order to see changes reflected in the terminal. One way to do this is by running these two commands:

# Kill the powerline daemon process
$ powerline-daemon -k
# Start the powerline daemon process quietly
$ powerline-daemon -q

That’s a lot of typing for something that needs to be done often. One way to go about doing this in a less tedious and error-prone way is to create an alias in .bashrc:

# in .bashrc
alias pd=”powerline-daemon -k && powerline-daemon -q”
# Refresh configuration on the command line
$ source ~/.bashrc

Now the powerline deamon is restarted whenever we run pd on the command line:

Restarting the powerline daemon with an alias.

Setting Up a Configuration Directory

The powerline installation contains a directory called config_files which, as you may have guessed, contains a complete set of default configuration files. When a powerline enabled application is launched, the appropriate configuration files are read to render the status line and/or prompt correctly. We modify a set of configuration files to change the behavior and appearance of elements to be rendered.

The official powerline documentation recommends copying the contents of config_files into your own configuration directory at ~/.config/powerline. This enables us to freely modify and add new configuration files whilst leaving the original installation untouched. Now, if an error occurs somewhere within our configuration that cannot be fixed, we can always revert back to the default configuration by copying over the files again.

Let’s set up a local configuration directory and copy over the default set of configuration files that ship with powerline:

$ mkdir ~/.config/powerline
$ cp -fr {powerline_location}/config_files ~/.config/powerline

Make sure to replace {powerline_location} with the appropriate path for your installation. Run pip show powerline-status and refer to the Location key if you are unsure about what path to use.

The next section will take a look at specific configuration files and how they are structured on the file system.

The Configuration Directory Structure

It is important to understand how the configuration directory is structured as well as the main files that require modification when configuring powerline’s behavior. Take note that all of the configuration files are formatted in JSON.

The powerline configuration files are organized in a certain way:

- powerline/
- config.json # Main configuration
- colors.json # Colors and gradient definitions
- colorschemes/ # Directory for all color schemes
- default.json
- <extension>/
- <scheme_name>.json
...
...
- themes/ # Directory for all themes
- <top_level>.json
- <extension>/
- <theme_name>.json
...
...
  • powerline/config.json
    The main powerline configuration file which specifies the theme and colorscheme for each powerline-supported application. Themes and color schemes can be hooked up to an application by modifying this file.
  • powerline/colors.json
    Colors and gradients are defined in this file and are referenced within color scheme configuration files elsewhere in the directory structure. We will define some colors and use them in a color scheme configuration file for theming the bash prompt.
  • powerline/colorschemes/
    All color schemes are saved under this directory. It contains a default.json file that powerlne will fallback to if an application is hooked up to an incomplete color scheme. Color schemes for particular applications are saved in the appropriate <extension> directory. For example, Bash color schemes must be stored in colorschemes/shell/. Browse this directory to see which applications powerline provides color schemes for out of the box.
  • powerline/themes/
    All themes are saved under this directory. The term “theme” in powerline refers to the layout of a prompt or status line, and has nothing to do with color. A theme specifies a list of segments, which are regular Python functions that return string data to be rendered. Powerline provides many segments that output specific information — such as the date and CPU usage. Themes for particular applications are saved in the appropriate <extension> directory, and a default.json file is usually provided as a base configuration.

Creating a Theme for the Bash Prompt

Segments are regular Python functions that return some data to be rendered in a prompt or status line. Powerline ships with many segments which are all defined within Python modules. These Modules are stored in the powerline/segments/ directory. We call a segment using a specific syntax in a theme configuration file:

"function": "powerline.segments.module.segment_name"

Segments also accept a range of arguments which customize their final output. Every argument is assigned a default value in the segment’s signature, but we will sometimes want to override them. This is done by defining a JSON list called args within the corresponding segment block:

"args": {
"arg1": "val1",
"arg2": "val2", ...
}

As an example, the cwd segment is used in our bash theme to render the current working directory in a specifc way:

{
"function": "powerline.segments.common.env.cwd",
"args": {
"ellipsis": "..", # String to use for omitted directories
"dir_shorten_len": 20, # Max directory character length
"dir_limit_depth": 2 # Max directory depth to render
},
"after": " ", # String to display after the output
"priority": 20 # Give a high rendering priority
},
  • We configure the cwd segment to render up to two parent directories. The ellipsis string .. is used to represent collapsed directories. I.e. ~/.config/powerline/themes/vim will become ../powerline/themes/vim.
  • The after key specifies an optional string that is rendered after the output of a particular segment. A single space character is assigned here to adjust the spacing between segments. The before key is also available for rendering a string before the segment output.
  • An optional priority value can also be specified for a segment. In cases where a prompt or status line has limited width, segments with low priority values will be rendered ahead of segments with a high priority. Leave out this option to always render the segment.

Browsing through the Powerline Segment Reference is the best way to discover new segments. A developer guide is also available if you have some Python programming experience and wish to make your own segments.

Let’s go ahead and modify the powerline/themes/shell/default_leftonly.json file to layout the segments we want to render for the Bash prompt. The following gist contains the complete code listing for this file:

The bash theme configuration file.

This table also describes the segments used by this theme:

The segments used for our custom Bash prompt.

To make the shell binding aware of our modified theme, it must be specified in the main powerline/config.json configuration file within the shell block:

"shell": {
"colorscheme": "default",
"theme": "default_leftonly",
"local_themes": {
"continuation": "continuation",
"select": "select"
}
},

Remember to restart the powerline-daemon process to see the theme applied in your terminal.

Creating a Color Scheme for the Bash Prompt

The code presented in this section will apply a dark color scheme to the bash prompt. We will also use a teal background color for the user segment.

Let’s start things off by defining some new colors in the powerline/colors.json configuration file:

“teal”: 6,
“navyblue”: 17,
“darkblue2”: 18,
“slateblue”: 61,
“purpleturquoise”: 66,
“steelblue”: 67,
“gray01”: 234,

We also need to create a new directory inside powerline/colorschemes/ named shell/, in addition to a new JSON file within this directory called teal_dark.json:

$ cd ~/.config/powerline/colorschemes
$ mkdir shell && cd shell
$ touch teal_dark.json

The teal_dark.json file must define the highlight groups (what colors to use) for each segment defined in its corresponding theme file. Color schemes use the following syntax to assign colors to segments:

"group_name": { "fg": "color", "bg": "color", 
"attrs": ["bold", "italic", "underline"] }
  • group_name: Refers to the name of a segment or a custom group.
  • fg and bg: Specifies a color defined in colors.json to set the foreground and background colors of the group respectively.
  • attrs[]: A list containing optional "bold", "italic" and "underline" strings.

The complete code listing for the teal_dark.json file is displayed here:

The color scheme configuration file for the Bash prompt.

To make the shell binding aware of our new color scheme, it must be specified in the main powerline/config.json configuration file within the shell block:

"shell": {
"colorscheme": "teal_dark",
"theme": "default_leftonly",
"local_themes": {
"continuation": "continuation",
"select": "select"
}
},

Restart the powerline-daemon process to see the color scheme rendered in your terminal emulator. I encourage you to experiment with your configurations until you arrive at a prompt you are happy with. Also check out this color code cheat sheet if you intend to add more colors to the colors.json file.

Our configured Bash prompt rendered with powerline.

Using Powerline with i3

This section will take a look at configuring powerline to render the status bar used in the i3 window manager environment.

Firstly modify the bar { .. } block in your ~/.config/i3/config file to invoke the powerline binding for i3. You will also need to replace {powerline_root} with the location of your powerline installation:

bar {
status_command python3 {powerline_root}/powerline/bindings
/i3/powerline-i3.py
font pango:Hacker 11
}

After reloading your i3 configuration, powerline will render the status bar and apply a very basic theme. From here we will add additional segments to the theme configuration file and create a color scheme like we did for the bash prompt.

The i3 bar rendered with the default theme and color scheme configurations applied.

Installing a Powerline Extension for Memory Segments

Since the current version of powerline doesn’t provide any segments for outputting memory usage, we will install a small extension called powerline-mem-segment via pip to get this functionality. Feel free to read the package’s GitHub repository homepage to discover its features and usage details.

All we need to do is run a single command to install the extension:

pip install powerline-mem-segment

The memory usage segments are now available and will be hooked up to our i3 bar in the next section.

Creating a Theme for the i3 Bar

Moving forward, let’s add and configure the segments we want to see on the i3 status bar in the powerline/themes/wm/default.json file. The complete code listing for this file is displayed here:

The theme configuration file for the i3 bar.

The segments used in this theme are described here:

The segments used for our custom i3 bar.

At this point, our configuration still needs to define either the mem_usage or mem_usage_gradient highlight groups for the memory segments to render. This will be covered in the next section.

Creating a Color Scheme for the i3 Bar

The code presented in this section will apply a dark color scheme to the i3 status bar. Following the same process detailed in the bash section, let’s start by creating a new directory inside powerline/colorschemes/ named wm/, in addition to a JSON file within this directory called i3_dark.json:

$ cd ~/.config/powerline/colorschemes
$ mkdir wm && cd wm
$ touch i3_dark.json

The complete code listing of the i3_dark.json file follows:

The color scheme configuration file for the i3 bar.

Lastly, we must specify the i3_dark color scheme name in the main powerline/config.json configuration file, this time within the wm block:

"wm": {
"colorscheme": "i3_dark",
"theme": "default",
"update_interval": 2
}

Powerline will now render the i3 bar using our theme and color scheme configuration files:

Our configured i3 bar without the external IP address segment.

Using Powerline with tmux

This last section will detail how to enable powerline in tmux. I will leave the theme and color scheme configuration steps as an exercise for readers who have read up to this point!

Append some code to your ~/.tmux.conf file to enable powerline rendering:

# Ensure the powerline daemon is running
run-shell "powerline-daemon -q"
# Invoke the tmux powerline binding
source "{powerline_root}/bindings/tmux/powerline.conf"

Make sure to input the correct location of your tmux/powerline.conf binding. Powerline will now render the status line in tmux on its next launch:

$ tmux new-session
Powerline rendering both the tmux status line and Bash prompt.

In Conclusion

Congratulations on completing this powerline integration guide! A lot of content was presented in concise sections throughout, so I certainly recommend taking some time to play with your configuration and referring back to relevant sections if necessary.

From here, I recommend checking out the other applications powerline supports as well as continuing to configure your perfect status lines and prompts. I also encourage you to browse through the segment reference documentation to see the full list of what can be rendered with powerline.

--

--