hmichael@tronyxworld.be:~$

Shell sous stéroïdes : ZSH + OhMyZsh + Powerlevel10k

En tant qu’utilisateur de GNU/Linux/Unix nous interargissons des dizaines, des centaines voir des milliers de fois chaque jour avec notre shell.

Qu’est ce que le Shell

C’est le programme qui sert d’interface entre l’utilisateur et le système d’exploitation.

C’est un interpréteur de commande.

La majorité des distributions GNU/Linux sont livrées avec le shell BASH par défaut.

Ils en existent d’autres :

  • SH
  • DASH
  • CSH
  • TCSH
  • KSH
  • Fish
  • ZSH

C’est sur ce dernier que je vais m’attarder, le ZSH.

Zorn Shell

Voici quelques avantages offert par le ZSH :

  • 100% rétrocompatible avec le BASH.
  • Autocompletion des commandes, de leurs options, des dossiers et fichiers.
  • Correction ortographique des commandes.
  • Historique partagé entre les différentes consoles.

Le ZSH réunit le meilleur des fonctions offertent par les autres shells.

Le gain de temps est sensible dès les premières minutes d’utilisation mais ne vous y trompez pas il faudra du temps pour “maîtriser” toutes ses subtilités.

Pour ne rien gâcher à la fête, il bénéficie d’énormement de ressources complémentaires (thèmes, plugins, framework) pour lui ajouter tout un tas de fonctions.

Cela permet de vite et simplement personnaliser son shell pour qu’il corresponde à ce que l’on souhaite.

De Bash à ZSH

Installons les outils nécessaires :

# Debian/Ubuntu/LinuxMint
sudo apt install -y zsh git curl wget

# CentOS/RHEL/Fedora
sudo dnf install -y zsh git curl wget

# Arch/Manjaro
sudo pacman -Sy zsh git curl wget

# Suse
sudo zypper install -y zsh git curl wget

Pour connaître les shells disponible sur votre machine exécutez cat /etc/shells depuis votre terminal qui vous retournera une sortie similaire :

# /etc/shells: valid login shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/rbash
/usr/bin/rbash
/bin/dash
/usr/bin/dash
/bin/zsh
/usr/bin/zsh

Changeons le shell de l’utilisateur désiré :

sudo chsh -s /usr/bin/zsh nom_utilisateur

On quitte et on relance notre terminal qui affichera :

zsh first prompt

Appuyer sur “0” afin de quitter l’invite tout en créant le fichier .zshrc.

Ce fichier contiendra la configuration qui s’appliquera à votre ZSH.

OhMyZsh

Plusieurs framework existent pour ZSH :

  • Zgen
  • Zim
  • Zplugin
  • Prezto
  • OhMyZsh

C’est sur OhMyZsh qui est certainement le plus réputé de tous que j’ai porté mon choix, après plusieurs années d’utilisation il ne m’a pas déçu.

Il est stable, bien suivi (plus de 1300 contributeurs) et offre une documentation claire et concise.

OhMyZsh offre dès son installation un accès à des centaines de plugins et de thèmes.

Pour ceux qui auraient peur pour le maintien du projet dans le temps, sachez qu’il a soufflé ses 10 bougies le 28/08/2019 et qu’il n’est pas prêt de s’arrêter en si bon chemin.

Fonts

Avant d’aller plus loin il faut savoir que plusieurs thèmes utilisent des icônes pour agrémenter le visuel, par exemple affichage de l’icône git lorsqu’on se trouve dans un repo github/gitlab ou l’icône de la batterie sur un laptop, le wifi etc… Tout cela est configurable.

Mais pour en profiter il faut installer une police (font) de caractère supportant ces icônes sinon vous aurez un affichage de caractère très étrange.

Vous avez un large choix de police compatible sur nerdfonts.

C’est totalement libre donc faites vous plaisir et n’hésitez pas à partager le projet nerdfonts à vos amis & collègues.

De mon côté j’ai choisi la police “Hack” de chez NF et c’est donc sur elle que je vais baser mon installation libre à vous d’adapter à vos envies.

wget https://github.com/ryanoasis/nerd-fonts/releases/download/v2.0.0/Hack.zip -O ~/hack.zip
unzip ~/hack.zip -d hack && rm ~/hack.zip
find ~/hack/ -iname "*Windows*" -exec rm {} \; # suppression des fonts compatible Windows.
sudo mv hack /usr/share/fonts/
fc-cache -v # rafraichi le cache des polices.
fc-list | grep -i 'hack' # vérifier la présence et prise en charge de la police.

Rendez vous dans les réglages de votre terminal favori pour modifier la police par défaut par celle qu’on vient d’installer.

Installation OhMyZsh

On installe OhMyZsh et 3 plugins qui rendent l’expérience plus agréable :

sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:=~/.oh-my-zsh/custom}/plugins/zsh-completions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

Si vous n’avez pas encore effectué le changement de votre shell pour zsh l’installateur de OhMyZsh le ferra pour vous et il déploiera une configuration de base dans votre fichier ~/.zshrc.

Relancer votre terminal pour profiter du résultat, par défaut c’est le thème robbyrussel qui est utilisé.

Pour la liste complète des thèmes inclus dans OMZ faite ls -l $HOME/.oh-my-zsh/themes/ depuis votre terminal.

Configuration ZSH

Avant de pousser plus loin la personnalisation je vous partage une configuration simple mais fonctionnelle où j’ai changé le thème pour agnoster qui est plus visuel et j’ai activé les plugins téléchargés plus haut cela nous servira de base pour la suite.

# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH

# Path to your oh-my-zsh installation.
export ZSH="/home/$USER/.oh-my-zsh"

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="agnoster"

# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in ~/.oh-my-zsh/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )

# Uncomment the following line to use case-sensitive completion.
CASE_SENSITIVE="off"

# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
HYPHEN_INSENSITIVE="true"

# Uncomment the following line to disable bi-weekly auto-update checks.
DISABLE_AUTO_UPDATE="off"

# Uncomment the following line to automatically update without prompting.
DISABLE_UPDATE_PROMPT="off"

# Uncomment the following line to change how often to auto-update (in days).
export UPDATE_ZSH_DAYS=30

# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS=true

# Uncomment the following line to disable colors in ls.
DISABLE_LS_COLORS="off"

# Uncomment the following line to disable auto-setting terminal title.
DISABLE_AUTO_TITLE="off"

# Uncomment the following line to enable command auto-correction.
ENABLE_CORRECTION="true"

# Uncomment the following line to display red dots whilst waiting for completion.
COMPLETION_WAITING_DOTS="true"

# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"

# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
HIST_STAMPS="dd.mm.yyyy"

# Which plugins would you like to load?
# Standard plugins can be found in ~/.oh-my-zsh/plugins/*
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(
zsh-autosuggestions
zsh-completions
zsh-syntax-highlighting)

source $ZSH/oh-my-zsh.sh

# User configuration

export MANPATH="/usr/local/man:$MANPATH"

# You may need to manually set your language environment
# export LANG=en_US.UTF-8

# Preferred editor for local and remote sessions
if [[ -n $SSH_CONNECTION ]]; then
  export EDITOR='vim'
else
  export EDITOR='nano'
fi

# Compilation flags
export ARCHFLAGS="-arch x86_64"

Pour prendre en compte les modifications on saisit source ~/.zshrc.

Et voilà le résultat que vous devriez avoir :

omz_agnoster

Powerlevel10k

Powerlevel10k est une réimplémentation du très connu powerlevel9k.

Il offre 3 gros avantages :

  1. Il est beaucoup plus rapide au rendu comme l’explique et le démontre le site du projet.
  2. Il offre un configurateur qui fait déjà très bien les choses pour moduler l’apparence à son goût.
  3. Il déploie un fichier de configuration sous .p10k.zsh qui regroupe l’entierté des fonctions de P9K avec beaucoup de détail et explication.

Installation de P10K :

git clone https://github.com/romkatv/powerlevel10k.git $ZSH_CUSTOM/themes/powerlevel10k

Il faut maintenant éditer le fichier ~/.zshrc pour activer le thème powerlevel10.

Modifier la ligne ZSH_THEME="agnoster" par ZSH_THEME="powerlevel10k/powerlevel10k".

Et on recharge notre fichier source ~/.zshrc ce qui va lancer le configurateur de P10K.

Une série de questions vous permettent de configurer votre terminal en fonction de vos envies.

Sachez que si la configuration finale ne vous convient pas vous pouvez recommencer autant de fois que vous le désirez en entrant p10k configure.

Configuration

Pour avoir l’affichage de la ram, charge cpu, heure, etc… comme expliqué plus haut il faut éditer le fichier ~/.p10k.zsh avec votre éditeur favori.

En fonction que vous souhaitiez afficher les informations à gauche/droite cela se passe dans 2 segments différents :

  1. typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS : Pour les éléments à afficher sur votre droite.
  2. typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS : Pour les éléments à afficher sur votre gauche.

Voici les blocs de configuration que j’ai modifié :

typeset -ga POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
  os_icon                 # os identifier
  context                 # user@hostname
  dir                     # current directory
  vcs                     # git status
  prompt_char             # prompt symbol
)
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
  status                  # exit code of the last command
  command_execution_time  # duration of the last command
  background_jobs         # presence of background jobs
  direnv                  # direnv status (https://direnv.net/)
  virtualenv              # python virtual environment (https://docs.python.org/3/library/venv.html)
  #anaconda               # conda environment (https://conda.io/)
  #pyenv                  # python environment (https://github.com/pyenv/pyenv)
  #goenv                  # go environment (https://github.com/syndbg/goenv)
  #nodenv                 # node.js version from nodenv (https://github.com/nodenv/nodenv)
  #nvm                    # node.js version from nvm (https://github.com/nvm-sh/nvm)
  #nodeenv                # node.js environment (https://github.com/ekalinin/nodeenv)
  #node_version           # node.js version
  #go_version             # go version (https://golang.org)
  #rust_version           # rustc version (https://www.rust-lang.org)
  #dotnet_version         # .NET version (https://dotnet.microsoft.com)
  #rbenv                  # ruby version from rbenv (https://github.com/rbenv/rbenv)
  #rvm                    # ruby version from rvm (https://rvm.io)
  #fvm                    # flutter version management (https://github.com/leoafarias/fvm)
  #luaenv                 # lua version from luaenv (https://github.com/cehoffman/luaenv)
  #jenv                   # java version from jenv (https://github.com/jenv/jenv)
  #plenv                  # perl version from plenv (https://github.com/tokuhirom/plenv)
  #kubecontext            # current kubernetes context (https://kubernetes.io/)
  #terraform              # terraform workspace (https://www.terraform.io)
  #aws                    # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html)
  #aws_eb_env             # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/)
  #azure                  # azure account name (https://docs.microsoft.com/en-us/cli/azure)
  #gcloud                 # google cloud cli acccount and project (https://cloud.google.com/)
  #google_app_cred        # google application credentials (https://cloud.google.com/docs/authentication/production)
  #context                # user@hostname
  #nordvpn                # nordvpn connection status, linux only (https://nordvpn.com/)
  #ranger                 # ranger shell (https://github.com/ranger/ranger)
  #nnn                    # nnn shell (https://github.com/jarun/nnn)
  #vim_shell              # vim shell indicator (:sh)
  #midnight_commander     # midnight commander shell (https://midnight-commander.org/)
  #vpn_ip                 # virtual private network indicator
  load                    # CPU load
  disk_usage              # disk usage
  ram                     # free RAM
  swap                    # used swap
  #todo                   # todo items (https://github.com/todotxt/todo.txt-cli)
  #timewarrior            # timewarrior tracking status (https://timewarrior.net/)
  time                    # current time
  #public_ip              # public IP address
  #proxy                  # system-wide http/https/ftp proxy
  #battery                # internal battery
  #example                # example user-defined segment (see prompt_example function below)
)

Il y a une petite astuce si le context (affichage du pseudo@nomdemachine) sur votre installation locale ne s’affiche pas.

C’est parce qu’à la ligne 491 il y a cette option = #typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= qui ne permet son affichage que via ssh où en utilisant sudo.

Il suffit de la commenter et de recharger votre fichier ~/.zshrc pour que le context soit désormais visible.

Petit rendu sur la vm de test de ce tutoriel :

p10k_demo

Vous pouvez librement mettre un élement du segment gauche à droite ou inversément, les options sont interchangeables.

Mot de la fin

Je n’ai pas écrit cet article pour couvrir l’entierté des fonctions de ZSH + OMZ + P10K ce serait impossible.

Le but de cet article était de simplifier son accès à toutes et tous.

Je ne serais que trop vous conseiller de prendre le temps de découvrir les fonctions avancées qu’offre ce trio afin de vous approprier le tout et de le moduler à votre bon vouloir.

Bien configuré il peut faire gagner un temps considérable !

A titre indicatif sur mes machines j’utilise les options suivantes des éléments de P10K :

  • todo
  • timewarrior
  • nordvpn
  • aws
  • azure
  • pyenv
  • goenv
  • nodeenv
  • kubecontext

Et les plugins dans mon ~/.zshrc :

plugins=(
dnf
git
git-extras
git-flow
history
python
django
ansible
docker
kubectl
npm
zsh-autosuggestions
zsh-completions
zsh-syntax-highlighting)

Je vous remercie de m’avoir lu, j’espère que cela sera utile pour certains d’entre vous et je vous souhaite de vous éclater en “tweak” sur votre shell !