I am using ZSH with Oh My Zsh as my primary terminal shell. I am using it for couple of years already, and it’s really good. One of my favourite things about it is the possibility to tune up pretty much anything. However, i haven’t really gone deep into it.
And second thing I like is constantly imprving my workflow. If i can do something faster, I want to do it faster. Like James Clear said in hist book “Atomic Habits” (great book by the way):
“Small, consistent actions hold the key to remarkable transformations.”
So I’ve recently noticed a place in my system that can be improved. So, let’s do it.
Habit
When I’m changing the directory inside my current shell session, usually the first command I type is ls to see the content of the new directory.
I’ve recently noticed, that I’m doing it most times without event thinking about it. It’s habit. But I think, that it would be better to automate it.
But there is a catch - I would like to have it working, no matter what way I’m using to change the directory. I could use cd, i could use my aliases, or something like .. or ....
Dumbest way
First thing I thought about it - create an alias.
alias cd='cd $1 && ls'
Dumb way
Better idea would be creating a shell function. But from the very beginning, I knew that using it for all potential usecases would be a nightmare if even possible at all.
<Code not shown here because I don't want to waste your time>
Smart way
Then I’ve found out about zsh hooks, and one of the was chpwd, which was invoked every time the CWD (current working directory) was changed. Jackpot!
So I’m gonna need something like this:
# ~/.zshrc
ls_hook() {
ls
}
add-zsh-hook chpwd ls_hook
And that’s it. It’s working, and i don’t have to think about it anymore. Whenever I change the directory, the content is automatically listed.
One more adjustment
But wait a second. If i’m going to change my dirs pretty quickly, it may spil my whole space with output of ls. So maybe it should be done a bit smarter? Like list only the directory that has low amount of files? Or maybe only list the first 10 files?
I’ve chosen the first approach. And the arbitray number if files that i can accept is 40. So let’s change the hook a bit. Ans use a bit of ZSH magic as well.
ls_hook() {
local files=(*(N))
if (( ${#files} < 40 )); then
ls
fi
}
But I’m not going to leave this non-standard shellscript without any explaination. So let’s break it down:
local files- definition of local-scoped variable(*(N))- magic ZSH globbing. It means “all files in the current directory, but if there is no file, return empty array instead of literal string*(N)”if (( ${#files} < 40 ))- check if the number of files is less than 40.${#files}is the length of the array, so it returns the number of files in the current directory.
And that’s it. I’m satisfied, I’ve improved my workflow a bit. And this is what I’d like this series to be. Small improvements, that can be easily understood and implemented.