A few months ago I switched to Windows. The biggest thing I missed - ZSH and Oh My Zsh.
Working with windows cmd or Powershell is just pathetic. You try to execute ls
command and turned out, it is not
supported.
What do I need from a command prompt?
Following are all the capabilities from a shell/prompt/terminal
- Tabs and Tiling (I used Tilix in Ubuntu/PopOs)
- A bit of Jazz (Colors, Icons, Emojis) (OhMyZ suffice this and following all things)
- Information about current dir (Example, using git plugin, shell shows current branch, number of commits to push, etc.)
- Autocompletion (Folder structure)
- Autocompletion (Commands based on history) (This is most important for me)
- Familiarity (It should support relatively same commands. Example
ls
) - Interaction with other tools (Like opening VSCode, editing file, installing pieces of software)
Windows alternative
After installing a few components, the shell in windows became so powerful that I don’t desire to switch back to linux.
Turned out, the only thing I missed about linux is its terminal capability.
Which alternatives in windows solved all issues
- Tabs and Tiling (Windows Terminal)
- Jazz (Starship, Nerd Fonts)
- Plugin (Starship Plugins)
- Autocompletion (Powershell 7 native feature)
- Autocompletion (Commands based on history - Powershell 7 native feature)
- Familiarity (Powershell 7 supports many such commands;
ls
,curl
are two examples) - Interaction (Powershell 7, chocolatey)
Steps to install
Powershell 7
Follow this link and from the releases page, download .msi
and double
click install.
Nerd Fonts
It powers all the Jazz for terminal like showing icons, emojis, and ligatures. Follow this link and download any font you like. Fira Code is the most popular.
Extract fonts, select all, right-click, and select install for all.
Windows Terminal
Follow this link. It will open a web page that will redirect to Windows store. Install from Windows store.
Set default profile to Powershell 7: Open Windows terminal π‘ͺ Open settings (That down arrow in the top bar) π‘ͺ Set Default Profile as “Powershell” (the black icon one, not the blue “Windows Powershell”)
Set Fonts: Settings π‘ͺ Profiles (left menu) π‘ͺ Powershell π‘ͺ Appearance π‘ͺ Font face π‘ͺ Select the installed Nerd font. You can change the color scheme too, Solarized Dark was my favorite one time.
Chocolatey
This step is optional, but it will help installing software from terminal easily.
Install chocolatey from the link.
Usage π‘ͺ choco install jre8
Starship
Before installing Starship, I tried Oh My Posh. It was good, it can totally emulate Oh My Zsh. However, I found Starship more elegant.
The best way to install Starship is using chocolatey. Or follow starship docs and install via some other way.
choco install starship
Create or Open profile file.
code $PROFILE
// OR if VS Code is not installed
notepad $PROFILE
This will create a file named Microsoft.PowerShell_profile.ps1
in your Users π‘ͺ < User > π‘ͺ Documents π‘ͺ Powershell
directory. This file is the same as .zshrc
or .bashrc
file. You can provide initial commands, aliases, etc.
Set Starship as the default shell. Put this inside the profile file so that every time you open the terminal, it loads Starship.
Invoke-Expression (&starship init powershell)
Customize (Add Jazz) to Starship. However, I won’t recommend doing this right away. First, setup everything and start using it all and then come back to this and tweak however you like.
If you still want to configure, I will add my configuration file below. Paste that code to
your C:\Users\<username>\.config\starship.toml
file. Or some presets are
available here
add_newline = true
# Replace the "β―" symbol in the prompt with "β"
[character] # The name of the module we are configuring is "character"
success_symbol = "[β](bold green)" # The "success_symbol" segment is being set to "β" with the color "bold green"
# Disable the package module, hiding it from the prompt completely
[package]
disabled = true
[cmd_duration]
min_time = 1_000 # Show command duration over 10,000 milliseconds (=10 sec)
format = " took [$duration]($style)"
[git_commit]
commit_hash_length = 8
style = "bold white"
[git_state]
format = '[\($state( $progress_current of $progress_total)\)]($style) '
[git_status]
conflicted = "βοΈ "
ahead = "ποΈ π¨ Γ${count}"
behind = "π’ Γ${count}"
diverged = "π± ποΈ π¨ Γ${ahead_count} π’ Γ${behind_count}"
untracked = "π€οΈ Γ${count}"
stashed = "π¦ "
modified = "π Γ${count}"
staged = "ποΈ Γ${count}"
renamed = "π Γ${count}"
deleted = "ποΈ Γ${count}"
style = "bright-white"
format = "$all_status$ahead_behind"
[memory_usage]
format = "$symbol[${ram}( | ${swap})]($style) "
threshold = 70
style = "bold dimmed white"
disabled = false
[golang]
format = "via [ππ¨ $version](bold cyan) "
[kubernetes]
format = 'k8s [β΅ ($user on )($cluster in )$context \($namespace\)](green) '
disabled = false
[kubernetes.context_aliases]
"arn:aws:eks:<REGION_HERE>:ACCOUNT_ID_HERE:cluster/dev" = "dev"
"arn:aws:eks:<REGION_HERE>:ACCOUNT_ID_HERE:cluster/test" = "test"
".*/openshift-cluster/.*" = "openshift"
"gke_.*_(?P<var_cluster>[\\w-]+)" = "gke-$var_cluster"
[battery]
full_symbol = "π "
charging_symbol = "β‘οΈ "
discharging_symbol = "π "
[[battery.display]]
threshold = 30
style = "bold red"
Autocompletion
Put the following lines in your profile file and you are done
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward
Controversial opinion, after using this for some time, I found this autocompletion better than what we had in ZSH.
If you want to execute commands from history then type a few characters from command the hit β¬οΈ
it will show all the
commands from history.
For example, if you type docker
+ β¬οΈ
then it will show docker build .
(in case you executed that in history)
The best thing, using tab
you can have auto suggest for the commands you never executed. Like if I type git
and tab
, it will show git fetch
, git pull
, basically all the possible commands I can execute using git. (Update, I
might have installed posh git
and that might be doing it)
Alias
If you want to set up an alias then open the profile file and set alias like
Set-Alias k kubectl;
Set-Alias ka getAllKubernetes;
function getAllKubernetes(){
kubectl get po,no,svc,ing --all-namespaces;
kubectl get cm,secret -n app
}
Search
We miss grep
in Windows. There is almost similar utility in Windows called findstr
. Usage β¬οΈβ¬
cat file.txt | findstr "search"
Env variable
This is not directly related but this comes a lot. It is easy to set env variable in Linux. export ENV_A="ABC"
. Also,
all the setup guideline of any software assume that you are on Linux and will provide the export
based command in the
example.
However, powershell has different syntax; Use following syntax if you want to set any environment variable.
$env:MY_ENV_VARIABLE = "VALUE" // to set
$env:MY_ENV_VARIABLE // to print/get
Back Search
Cltr + r
will do the back search the same as Linux terminal
Tabs and Tiling
Tabs are by default available in Windows Powershell. The shortcuts are,
Crtl + Shift + T
to open a new tab
Crtl + Shift + W
to close a tab
Crtl + Shift + Tab
to switch to the previous tab
Crtl + Tab
to switch to the next tab
Tiling is by default available as well. The shortcuts are,
Alt + Shift + D
or Alt + Shift + +
to split the terminal vertically
Alt + Shift + -
to split the terminal horizontally
Alt + Arrow
to move the focus to the next pane
Alt + Shift + Arrow
to resize the pane
Linux inside windows
You can still enable wsl 2
inside windows and make use of all the features of Windows terminal and still can use Linux
under the hood. It is a different topic and requires its own post.
I sometimes use git bash
where someone has written a linux specific script and I don’t want to spin off WSL just for
one command.
HTTP client
This is probably a different topic. But we need to use CURL a lot. There are multiple ways.
- Install
curl
usingchoco
and use it.choco install curl
- Use
Invoke-WebRequest
in powershell. It is a built-in command. (though it is not that good) - Use
HTTPie
.choco install httpie
. It is way more convenient thancurl
andInvoke-WebRequest
. Example β¬οΈβ¬
http :8080/api/v1/health a=b
Here it will automatically consider localhost as host. Also, as we have passed a=b
it will automatically consider it
as a POST request with Content-Type: application/json
and body as {"a":"b"}
.
Conclusion
Maybe it might look complex to set up, and it might not be as powerful as other alternatives. But these things are tools not toys. If those help me get things done then I am happy.