Skip to content

Commit cb4ccf1

Browse files
committed
Document PUSHD_IGNORE_DUPS setting
1 parent 9a918e2 commit cb4ccf1

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

FAQ.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ _If you don't find what you're looking for, and you think it should be covered b
3737
- [Some commands no longer work after installing Oh My Zsh](#some-commands-no-longer-work-after-installing-oh-my-zsh)
3838
- [Other problems](#other-problems)
3939
- [`kill-word` or `backward-kill-word` do / don't delete a symbol (`WORDCHARS`)](#kill-word-or-backward-kill-word-do--dont-delete-a-symbol-wordchars)
40+
- [Why is `PUSHD_IGNORE_DUPS` set by default?](#why-is-pushd_ignore_dups-set-by-default)
4041
- [Why shouldn't I install Oh My Zsh as root?](#why-shouldnt-i-install-oh-my-zsh-as-root)
4142

4243
<!-- /TOC -->
@@ -145,7 +146,8 @@ If you want to manually update Oh My Zsh, you have 2 options:
145146
- If you want to update Oh My Zsh as part of an automated script, its better to use the `upgrade.sh` script directly. You can call it with any of these alternatives:
146147

147148
```sh
148-
"$ZSH/tools/upgrade.sh" # $ZSH needs to be defined within the script
149+
# $ZSH needs to be defined within the automated script you created
150+
"$ZSH/tools/upgrade.sh"
149151
zsh "$ZSH/tools/upgrade.sh"
150152
/path/to/ohmyzsh/tools/upgrade.sh
151153
```
@@ -382,6 +384,12 @@ There are many solutions, some temporary, some permanent:
382384

383385
If you installed software from outside the default system package manager, and therefore made changes to the `PATH` variable to be able to use them, you need to re-add those PATH changes to `~/.zshrc` to get the commands to work. This is required as the PATH variable determines where the shell looks for binaries, and without the changes from your previous shell(s), it can't find the commands. The software this affects includes, but is not limited to, nvm, rustup, Anaconda, and many others. If it works in bash, or worked before you installed Oh My Zsh, it's probably a path issue.
384386

387+
This might result in errors such as this:
388+
389+
```
390+
zsh: command not found: npm
391+
```
392+
385393
This applies even if you were using zsh, and not some other shell, prior to installing Oh My Zsh, as your original zshrc is not modified; it's replaced, but backed up before it's installed. If you used zsh prior to installing Oh My Zsh, you can retrieve your old zshrc from `~/.zshrc.pre-oh-my-zsh`, and copy the changes you made from there.
386394

387395
If you weren't using zsh before, you need to copy over any changes to the PATH from the config file for your previous shell. Note that certain programs, such as Anaconda, may have initialisation functions that are shell-dependent, and that cannot be copied directly. For these, it's recommended you try to re-initialise the config using the software's own installation/initialisation system. For example, for Anaconda, you can use `conda init zsh` to regenerate the initialisation block correctly. See the documentation for the specific software you're using for more details about your alternatives when changing shells.
@@ -440,6 +448,32 @@ If you want this behavior to change, set the `WORDCHARS` variable in your zshrc
440448
WORDCHARS='_-*'
441449
```
442450

451+
## Why is `PUSHD_IGNORE_DUPS` set by default?
452+
453+
`PUSHD_IGNORE_DUPS` is a setting that tells `pushd` to ignore duplicates in the directory stack. This means that if you try to push a directory that is already in the stack, it will not be added again. This is useful because it avoids having the same directory multiple times in the stack, which can be confusing and make it harder to navigate the stack.
454+
455+
This behavior makes sense when in an interactive session, especially paired with plugins such as `dircycle` or `dirhistory`, which allow you to cycle the directory stack with a simple keyboard shortcut. Having duplicates in there would make the UX worse and more confusing.
456+
457+
However, this behavior is not recommended when you are using `pushd` and `popd` in a script, as it can lead to unexpected behavior, as documented in [the official Zsh guide](https://zsh.sourceforge.io/Guide/zshguide03.html#:~:text=Setting%20PUSHD_IGNORE_DUPS%20means%20that%20if,entry%20will%20be%20silently%20removed.):
458+
459+
> Setting PUSHD_IGNORE_DUPS means that if you pushd to a directory which is already somewhere in the list, the duplicate entry will be silently removed. This is useful for most human operations --- however, if you are using pushd in a function or script to remember previous directories for a future matching popd, this can be dangerous and **you probably want to turn it off locally inside the function**.
460+
461+
If you are running a script non-interactively, i.e. spawning a new zsh process (via `./script.sh` or `zsh script.sh`), you should not encounter this issue, as Oh My Zsh does not get loaded at all. However, if you are running it via `source`, which is not recommended, you will have this issue. If so, the solution is to unset the option locally in the script within a function:
462+
463+
```zsh
464+
#!/usr/bin/env zsh
465+
466+
function main() {
467+
emulate -L zsh # sets all options to their zsh default
468+
# or
469+
setopt localoptions nopushdignoredups
470+
471+
# your script here
472+
}
473+
474+
main # run main
475+
```
476+
443477
## Why shouldn't I install Oh My Zsh as root?
444478

445479
If something goes wrong with your config or Oh My Zsh, you risk breaking your system without a way to get back in, at least not without spinning up a live environment or doing a clean install. While this is rare, rare it's far more likely than with an OS stock config for the root user.

0 commit comments

Comments
 (0)