The Powerlevel10k config file ~/.p10k.zsh
contains close to 2000 lines by default. This file is (re)generated by the configuration wizard when you run p10k configure
. It quickly gets clumsy when applying nuanced modifications, and if you have a certain phobia like I do, you know you might need to restore a default setting later, so you duplicate a default setting, comment out one, and make your changes to the duplicate... you know... just in case.
The file eventually becomes one giant mix of default and custom settings (and comments). It gets even worse when you try to add your own prompt segments.
I wrote this script to provide a simple framework for customising your prompt without touching the generated file. And it's modular! So you can split your custom segments and/or settings into multiple files and manage them individually.
It also allows you to share your extended configuration with others, and each of you can have possibly different prompt styles configured from the wizard, but share the same additional segments, settings, and overrides.
All modifications will be done in an adjacent directory at ~/.p10k.zsh.d
(following the idiomatic .conf.d
in Linux). Any files with a .zsh
extension placed in that directory will be sourced by the main config. This is done through a dotfile named .entry.zsh
in the same directory which contains some core functions (explained in a moment) and the sourcing logic for user-added modules.
In summary, your config tree is going to look like this:
├── .p10k.zsh
├── .p10k.zsh.d
│ ├── .entry.zsh
│ ├── main.zsh <--
│ ├── module_1.zsh <-- Your files
│ ├── module_2.zsh <--
│ └── README.md
Clone the main branch of the repo to your home directory:
git clone --depth 1 https://github.com/emamoah/.p10k.zsh.d.git ~/.p10k.zsh.d
Next, source the entry file from the main ~/.p10k.zsh
file (generated by the wizard) near the end of its main function, after the last typeset
and before the reload logic, with the following line:
source ~/.p10k.zsh.d/.entry.zsh
Like so:
typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true
+ source ~/.p10k.zsh.d/.entry.zsh
# If p10k is already loaded, reload configuration.
# This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true.
(( ! $+functions[p10k] )) || p10k reload
}
Now you can create one or more .zsh
files (modules) in ~/.p10k.zsh.d
, and they will be sourced automatically. Any typeset
parameters redeclared in those files will override the default in the main config (see example below).
A group of commands is defined in the entry file with which you can add/remove/replace segments on either side of the prompt. They are described below:
Adds the given segment(s) to the left side of the prompt. These are the same values you would have put in the POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
array in the main config file. If the last argument is an existing segment, all the arguments before it will be inserted before that segment in the array. Otherwise, the list is simply appended to the array.
Removes the given segment(s) from the left prompt segments. If any given segment is non-existent, it is ignored.
Replaces the existing segment old
with the given new
segment(s). If old
doesn't exist, an error is thrown.
These are identical to the previous ones and take the same arguments, but operate on the POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS
array instead.
Your files can be structured anyhow you like, but the approach I recommend is to have a main file (e.g., main.zsh
) which will contain the prompt segment organisation, followed by any typeset
overrides or additions. Then the custom prompt segment definitions will go into multiple module files (each file for one custom segment).
The directory structure would look something like this:
├── .p10k.zsh
├── .p10k.zsh.d
│ ├── .entry.zsh
│ ├── main.zsh
│ ├── module_1.zsh
│ ├── module_2.zsh
│ └── README.md
Your main.zsh
file would then look like this:
# main.zsh
# Prompt segments
# Action Item(s) Before/With
p10k_d_left_replace os_icon module_1
p10k_d_right_remove nvm \
nodenv
p10k_d_right_add node_version \
rust_version \
module_2 newline
# Parameters
# Node.js
typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION=''
The backslashes are just a formatting trick to keep things visually tabular. The newlines after them are escaped and ignored by the shell, so those two commands are equivalent to:
p10k_d_right_remove nvm nodenv
p10k_d_right_add node_version rust_version module_2 newline
Your module file would also look like this:
# module_1.zsh
function prompt_module_1() {
p10k segment -t 'Hello!'
}
And now you have a clean, modularised p10k configuration!
This repo has a modules branch which will exist as a library for custom modules written by me and other contributors (like you). So feel free to browse those, and more will be added with time.