Home 6 steps to pimp my terminal
Post
Cancel

6 steps to pimp my terminal

Tools

My current setup is mixed of tools from following list:

  • oh-my-posh + powerlevel10k_rainbow (with mods) theme + custom font
  • posh-git
  • Set-PSReadlineKeyHandler for “bash style” search + autocomplete
  • PSKubectlCompletion with PSKubeContext for kubernetes
  • Register-ArgumentCompleter for dotnet
  • MagicTooltips which is responsible for displaying tooltips for kubectl and az

If you just want to copy-paste, scroll down to the end and copy what you need from my $PROFILE file 😅

Step 1 - standard + small hacks

The posh-git and oh-my-posh modules are quite popular, but will intruce them shortly:

  • posh-git displays info about git status
  • oh-my-posh allows to displays a lot of segments (like: time, battery, last exit code, kubernetes, aws, az, ….)

There are numerous themes for oh-my-posh. I’m using powerlevel10k rainbow, but there are missing icons even on the oh-my-posh website. You’ll need a unique typeface to get this appearance. Oh-my-posh recommends Meslo LGM NF, but I went with Delugia Nerd Font Complete. Is is a Cascadia Code “Extended”, which includes Nerd Fonts and powerline glyphs.

You must “force it” in Windows Terminal JSON after installation (to access settings, press CTRL+, then the gear icon on the left):

1
2
3
4
5
6
 "profiles": 
    {
        "defaults": 
        {
            "fontFace": "Delugia Nerd Font Complete"
        },

The final outcome is awesome:

terminal

Finally, remember to include your $PROFILE file (the best approach is to modify it using code $PROFILE if you have VS Code installed):

1
2
3
4
5
6
# posh git
Import-Module-With-Measure posh-git

# oh-my-posh
Import-Module-With-Measure oh-my-posh
Set-PoshPrompt -Theme powerlevel10k_rainbow

Step 2: bash style history search and autocomplete

Do you get tired of typing CTRL+R to look up commands in the history? Is it easier to just use arrows to find the last invocation of kubectl get, for example? I was one of them. Simply add the following to your profile:

1
2
3
# up&down arrow for history search
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward

Add one more if you’d like to view all autocomplete options after pressing TAB:

1
2
# menu complete using TAB instead of CTRL+SPACE
Set-PSReadlineKeyHandler -Chord Tab -Function MenuComplete

Still not convinced? It’s time for a little demonstration:

Yummy 😋

Step 3: Autocomplete

Today I’m only using dotnet and kubernetes autocomplete. I hope that soon I could use also az. Kubernetes config I described in my last post,

Anyway, the dotnet command is easy:

1
2
3
4
5
6
7
# dotnet completion
Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock {
    param($commandName, $wordToComplete, $cursorPosition)
    dotnet complete --position $cursorPosition "$wordToComplete" | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
    }
}

What about Az CLI? The proof of concept is easy, but it isn’t a top priority for Azure team 😥, just check GitHub. The gist is the only thing I’ve found, but I’m not using it.

If you need more stuff for autocomplete, just search, implement or rewrite bash to PowerShell. No shorthands, sorry 😥

Step 4: Magic tooltips

That’s great for displaying dynamic segments. What does this imply? When I type kubectl<SPACE>, for example, I want to see information about Kubernetes context, but I don’t need it most of the time. The same goes for az and aws. The oh-my-posh author guides me to a MagicTooltips module. I’ll probably have to submit a PR there to include namespace as well. Anyway, I choose to set it up as follows:

1
2
3
4
5
6
7
8
9
10
11
$global:MagicTooltipsSettings = @{
    VerticalOffset = 0
    HorizontalOffset = 4
    HorizontalAlignment = "Right"
    Providers= @{
        Kubernetes = @{
            Commands = "kubectl,helm,kubens,kubectx,k9s,k"
        }
    }
}
Import-Module MagicTooltips

However, to make your theme seem good, you’ll probably need to set HorizontalOffset and VerticalOffset.

My powerlevel 10k setup looks like this (the cluster name is under the clock):

Step 5: find slow modules/segments

I noticed performance issues after installing various extensions. To repair it, I chose to do the following:

  • remove unused segments in powerlevel theme
  • measure Import-Module

Step 6: having “sudo” mode

Isn’t it awesome to use sudo in a terminal? I used two functions to implement it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function fcuk {
    $cmd = (Get-History ((Get-History).Count))[0].CommandLine
    Write-Host "Running $cmd in $PWD"
    start-process pwsh -verb runas -WorkingDirectory $PWD -ArgumentList "-NoExit -Command pushd $PWD; Write-host 'cmd to run: $cmd'; $cmd"
}

function sudo {
    if ($first -eq '!!') {
        fcuk;
    }
    else {
        $file=$args[0];
        [string]$arguments = "";
        if ($args.Count -gt 1) {
            $c = $args.Count - 1;
            [string]$arguments = $args[1..$c]
        }
        Write-Host "file = $file args = $arguments";
        start-process $file -verb runas -WorkingDirectory $PWD -ArgumentList $arguments;
    }
}

My $PROFILE file

Finally, here’s what my $PROFILE file looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# helper
function Import-Module-With-Measure {
    param ($ModuleName)
    $import = Measure-Command {
        Import-Module $ModuleName
    }
    Write-Host "$ModuleName import $($import.TotalMilliseconds) ms"
}

# posh git
Import-Module-With-Measure posh-git

# oh-my-posh
Import-Module-With-Measure oh-my-posh
Set-PoshPrompt -Theme powerlevel10k_rainbow

# menu complete using TAB instead of CTRL+SPACE
Set-PSReadlineKeyHandler -Chord Tab -Function MenuComplete
# up&down arrow for history search
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward

# kubectl + stuff 
Import-Module-With-Measure PSKubectlCompletion
Set-Alias k -Value kubectl
Register-KubectlCompletion

Import-Module-With-Measure PSKubeContext
Set-Alias kubens -Value Select-KubeNamespace
Set-Alias kubectx -Value Select-KubeContext
Register-PSKubeContextComplete


# magic tooltip config
$global:MagicTooltipsSettings = @{
    VerticalOffset = 0
    HorizontalOffset = 4
    HorizontalAlignment = "Right"
    Providers= @{
        Kubernetes = @{
            Commands = "kubectl,helm,kubens,kubectx,k9s,k"
        }
    }
}
Import-Module MagicTooltips


# dotnet completion
Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock {
    param($commandName, $wordToComplete, $cursorPosition)
    dotnet complete --position $cursorPosition "$wordToComplete" | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
    }
}

# SUDO functions
function fcuk {
    $cmd = (Get-History ((Get-History).Count))[0].CommandLine
    Write-Host "Running $cmd in $PWD"
    start-process pwsh -verb runas -WorkingDirectory $PWD -ArgumentList "-NoExit -Command pushd $PWD; Write-host 'cmd to run: $cmd'; $cmd"
}

function sudo {
    if ($first -eq '!!') {
        fcuk;
    }
    else {
        $file=$args[0];
        [string]$arguments = "";
        if ($args.Count -gt 1) {
            $c = $args.Count - 1;
            [string]$arguments = $args[1..$c]
        }
        Write-Host "file = $file args = $arguments";
        start-process $file -verb runas -WorkingDirectory $PWD -ArgumentList $arguments;
    }
}

What comes next?

You can also find some interesting configurations at:

Maybe you have something useful in your setup? If yes please share!

This post is licensed under CC BY 4.0 by the author.