Some of you might wonder what is wrong with the Windows Terminal experience. Let me tell you a story.
Let's go back in time to where I was a wee junior developer. I was learning how to use git using the command line. I found myself spamming git status
trying to understand what I was doing and felt it was quite bothersome to do so.
Fast forward in time. Junior me trying to do basically anything on a unix based server and figuring out it's a whole different world out there in scary 'nix land.
Imagine there being solutions that let help you using git whilst also helping embrace that scary but sweet 'nix experience.
Windows Command Prompt, also known as CMD.
It is the defacto shell solution on Windows. It works well if you need to do simple routine operations, it will however disappoint you for your average day-to-day development tasks due to:
dir
PowerShell was supposed to fix some of the CMD shortcomings. In some ways it does, in others it does not. There is not doubt in my mind that PowerShell allows you to handle more complex operations and actions, but it seems like this introduced a hidden cost. With this added ability to execute these operations, the syntax complexity and verbosity absolutely skyrocketed. The commands you use in PowerShell to me look more like a programming language (a mix of a functional and object oriented one actually) than a scripting language, which is something I am personally not looking for. It feels even worse that I cannot even use these commands I spent time on learning in a unix environment.
I understand there are a lot of people that like and use PowerShell, and it's probably a great tool if you like the syntax and the problems it solves. It does however fall short for me due to the very nature of the tools provided by it as I was looking for a more 'unix-like terminal experience'.
If you like PowerShell and would like to spice up your experience, go take a look at Scott Hanselman's blog on how he set up PowerShell
Cmder is a lightweight third party solution for console emulation on Windows. It comes packed with a plethora of configuration options for theming, shell choice, shortcuts, tab support, startup tasks and more.
Cmder has built-in visual git support and comes paired with a set of common auto-completion tools which will help you with your everyday development tasks.
The newest terminal emulation addition developed by Microsoft which also comes distributed with Windows 11 by default. Regardless of what you think of the Windows Terminal advertisement Microsoft placed on Youtube (seriously how did they expect this would attract developers?), Windows Terminal is a solid contender if you are looking for a certain amount of customization. It may not have as many configuration options as Cmder does, but it will probably fill most people's needs regarding shell management (switching between different shells), tab management, shortcut management, and theming. Some people might see this as Windows Terminal having a more focused and less option bloated approach.
I am currently using Windows Terminal as my 'daily terminal emulation driver'.
As I was looking for a more 'unix-like terminal experience' my main usage resides in Git Bash. My setup current looks like this:
Several configuration options were customized:
I have set a custom color scheme named 'Tango Dark'.
I'm using a Powerline-patched font called Jetbrains Mono NL.
I'm using a Powerline theme which is referenced in my .bashrc.
I use lsd which is basically 'ls' on steroids.
I use bat 🦇 instead of cat 🐱 to view file contents quickly.
I use several completion scripts for tools I frequently use such as: bash, docker, docker-compose, kubectl, Azure CLI.
You can edit the config file by going into the Windows Terminal settings (CTRL + ,) and pressing the 'Open JSON file' button.
{
"$help": "https://aka.ms/terminal-documentation",
"$schema": "https://aka.ms/terminal-profiles-schema",
"actions": [
{
"command": {
"action": "copy",
"singleLine": false
},
"keys": "ctrl+c"
},
{
"command": "paste",
"keys": "ctrl+v"
},
{
"command": "unbound",
"keys": "ctrl+shift+t"
},
{
"command": "find",
"keys": "ctrl+shift+f"
},
{
"command": {
"action": "newTab"
},
"keys": "ctrl+t"
},
{
"command": {
"action": "splitPane",
"split": "auto",
"splitMode": "duplicate"
},
"keys": "alt+shift+d"
}
],
"copyFormatting": "none",
"copyOnSelect": false,
"defaultProfile": "{c3c26583-b525-43b5-a830-cab55baba518}",
"profiles": {
"defaults": {},
"list": [
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"hidden": false,
"name": "Command Prompt"
},
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"hidden": false,
"name": "Windows PowerShell"
},
{
"colorScheme": "Tango Dark",
"commandline": "\"%PROGRAMFILES%\\Git\\usr\\bin\\bash.exe\" -i -l",
"elevate": true,
"experimental.retroTerminalEffect": false,
"font": {
"face": "JetBrainsMonoNL Nerd Font"
},
"guid": "{c3c26583-b525-43b5-a830-cab55baba518}",
"icon": "C:\\Program Files\\Git\\mingw64\\share\\git\\git-for-windows.ico",
"name": "Git Bash",
"opacity": 90,
"startingDirectory": "C:\\repositories",
"useAcrylic": true
}
]
},
"schemes": [
{
"background": "#002B36",
"black": "#000000",
"blue": "#424242",
"brightBlack": "#555753",
"brightBlue": "#E82D72",
"brightCyan": "#E82D72",
"brightGreen": "#2FEBC4",
"brightPurple": "#AD7FA8",
"brightRed": "#EF2929",
"brightWhite": "#EEEEEC",
"brightYellow": "#FCE94F",
"cursorColor": "#FFFFFF",
"cyan": "#37FFB5",
"foreground": "#FAFFF6",
"green": "#B0D700",
"name": "Tango Dark",
"purple": "#75507B",
"red": "#FF5C5C",
"selectionBackground": "#FFFFFF",
"white": "#D3D7CF",
"yellow": "#C4A000"
}
]
}
# Theme
THEME=$HOME/.bash/themes/git_bash_windows_powerline/theme.bash
if [ -f $THEME ]; then
. $THEME
fi
unset THEME
# Simple PS1 without colors using format arg. Feel free to use PROMPT_COMMAND
export PS1="\u@\h \w \$(__fastgit_ps1 '[%s] ')$ "
# 100% pure Bash (no forking) function to determine the name of the current git branch
function __fastgit_ps1 () {
local headfile head branch
local dir="$PWD"
while [ -n "$dir" ]; do
if [ -e "$dir/.git/HEAD" ]; then
headfile="$dir/.git/HEAD"
break
fi
dir="${dir%/*}"
done
if [ -e "$headfile" ]; then
read -r head < "$headfile" || return
case "$head" in
ref:*) branch="${head##*/}" ;;
"") branch="" ;;
*) branch="${head:0:7}" ;; #Detached head. You can change the format for this too.
esac
fi
if [ -z "$branch" ]; then
return 0
fi
if [ -z "$1" ]; then
# Default format
printf "(%s) " "$branch"
else
# Use passed format string
printf "$1" "$branch"
fi
}
alias ls="TERM=dumb lsd"
source ~/bash_completion.d/bash_completion
source ~/bash_completion.d/docker-compose
alias python='winpty python.exe'
source ~/bash_completion.d/git
source ~/bash_completion.d/kubectl
alias az='az.cmd'
alias jq=~/jq-win64.exe
alias bat=~/bat/bat.exe
cat ~/raccoon
As always in development, there's some new stuff on the horizon. Things I will be looking at in the near future:
Do you know an upcoming tool or piece of tech I should be looking at? Let me know below!