Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZSH: Call in-built function from zsh function that uses the same name

I use zsh and would like to slightly extend the in-built cd function. I'd like that when I call cd, it changes directly and then lists the content of the directory.

function cd() {
    cd $1
    ls .
}

I'd have expected this code to work, but as it turns out, the call to cd refers to the function definition, resulting in an infinite loop.

Is there a work-around to solve this problem, apart from choosing a different name for my function?

UPDATE

Strangely enough, this worked

function cd() {
    `echo $1`
    ls .
}

No idea why.

like image 950
SamAko Avatar asked May 28 '16 11:05

SamAko


2 Answers

In order to use builtin commands from within functions of the same name, or anywhere else for that matter, you can use the builtin precommand modifier:

function cd() {
    builtin cd $1
    ls .
}

builtin COMMAND tells zsh to use the builtin with the name COMMAND instead of a alias, function or external command of the same name. If such a builtin does not exist an error message will be printed.


For cases where you want to use an external command instead of an alias, builtin or function of the same name, you can use the command precommand modifier. For example:

command echo foobar

This will use the binary echo (most likely /bin/echo) instead of zsh's builtin echo.


Unlike with functions builtin and command are usually not necessary with aliases to prevent recursions. While it is possible to use an alias in an alias definition

% alias xx="echo x:"
% alias yy="xx y:"
% yy foobar
y: x: foobar

each alias name will only expanded once. On the second occurence the alias will not be expanded and a function, builtin or external command will be used.

% alias echo="echo echo:"
% echo foobar
echo: foobar
% alias xx="yy x:"
% alias yy="xx y:"
% xx foobar
zsh: command not found: xx

Of course, you can still use builtin or command in aliases, if you want to prevent the use of another alias, or if you want to use a builtin or external command specifically. For example:

alias echo="command echo"

With this the binary echo will be used instead of the builtin.

like image 166
Adaephon Avatar answered Sep 22 '22 23:09

Adaephon


Why the echo command works is because you probably have the autocd option on. You can check this by typing setopt to get your list of options.

Then the echo-ing of the directory name and catching the output triggered the autocd and you went to that directory.

like image 41
Henno Brandsma Avatar answered Sep 24 '22 23:09

Henno Brandsma