When moving around in my terminal, I use two commands in sequence all the time. You’ll know them, they are cd and ls. Change directory, then list the contents of that directory. I decided this was getting annoying. Why is there not a single command to do this? Why not make one? I first thought an alias might work, but then I realised you cannot call an alias, hand it a variable and have it do something after that variable. <alias> <user variable> <second action> is just not possible.
A function then. A simple one at that. In your ~/.zshrc or ~/.bashrc add the following.
|
|
Type cl <directory> and it changes to that directory, then runs ls right after. Exactly what I wanted.
A few small details in there are worth pointing out:
- The semicolon before the closing brace matters. zsh is happy to accept it without one, but bash reads that trailing
}as an argument tolsand bails out withsyntax error: unexpected end of file. The semicolon (or a newline) is what actually closes the function, and it does so in both shells. "$@"forwards everything, including nothing. Passing"$@"handscdall the arguments. This is important if you use zoxide (see below), as it allows more than one argument.
Zoxide
I am a zoxide user1. Zoxide is a cd replacement and “remembers which directories you use most frequently, so you can ‘jump’ to them in just a few keystrokes”, according to their git. I have eval "$(zoxide init zsh --cmd cd)" set in my .zshrc, which means that my normal cd command is replaced with zoxide’s behavior. My cl command works flawlessly with this, without needing adjustments.
The zsh-native way
If you’re on zsh there’s an even cleaner option, which I only found after writing the function above. zsh has a chpwd hook that fires every single time the working directory changes. That includes cd, cd .., pushd/popd, and zoxide too. Define it like this:
|
|
Now you never type a separate ls again, no matter how you got there. The tradeoff is that it is no longer opt-in. It lists on every directory change. I personally do not want this, as I do not want an ls after every cd, but you might like it. I’ll stick to my own function.