zsh completion installation results in "command not found: compdef"
Command
other
Is this a regression?
- [ ] Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was
No response
Description
During the angular install, I said yes to the completion features. Shortly thereafter, I launched a new terminal window and received the error
/dev/fd/12:18: command not found: compdef
Searching uncovered a pair of stackoverflows that led to a fix of sorts. https://unix.stackexchange.com/questions/339954/zsh-command-not-found-compinstall-compinit-compdef https://unix.stackexchange.com/questions/383365/zsh-compinit-insecure-directories-run-compaudit-for-list
Adding the two rows in the accepted answer to the .zshrc got further:
autoload -Uz compinit
compinit
On a fresh install of Ventura + Homebrew + Npm from homebrew + angular from npm, this solves the problem.
However, you may run into further errors if you've installed other brew packages:
Last login: Tue Dec 13 20:18:09 on ttys008
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]? ncompinit: initialization aborted
/dev/fd/12:18: command not found: compdef
mscs@max ~ % compaudit
There are insecure directories:
/usr/local/share/zsh/site-functions
/usr/local/share/zsh
mscs@max ~ %
This lead to workaround #2 in the second stack overflow link:
compaudit | xargs chmod g-w
Removing write permission from the listed folders appears to have resolved the issue.
Minimal Reproduction
- Install macOS Ventura (latest), in my case 13.0.1. This may work for other versions of macOS
- Install homebrew from brew.sh
- Install npm via
brew install npm - install angular via
npm install -g @angular/cli - run
ng new - When prompted with:
? Would you like to enable autocompletion? This will set up your terminal so
pressing TAB while typing Angular CLI commands will show possible options and
autocomplete arguments. (Enabling autocompletion will modify configuration files
in your home directory.)
choose "yes"
Once the command echos back source <(ng completion script) any new terminals with throw the error.
Exception or Error
/dev/fd/12:18: command not found: compdef```
Your Environment
mscs@max ~ % ng version
Node.js version v19.2.0 detected.
Odd numbered Node.js versions will not enter LTS status and should not be used for production. For more information, please see https://nodejs.org/en/about/releases/.
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 15.0.3
Node: 19.2.0 (Unsupported)
Package Manager: npm 8.19.3
OS: darwin arm64
Angular:
...
Package Version
------------------------------------------------------
@angular-devkit/architect 0.1500.3 (cli-only)
@angular-devkit/core 15.0.3 (cli-only)
@angular-devkit/schematics 15.0.3 (cli-only)
@schematics/angular 15.0.3 (cli-only)
Warning: The current version of Node (19.2.0) is not supported by Angular.
Anything else relevant?
my .zshrc after the fix now reads:
autoload -Uz compinit
compinit
# Load Angular CLI autocompletion.
source <(ng completion script)
I've never heard of compinit before, but looking around it seems like Zsh requires autocompletion to be initialized before it can be used. Seems like oh-my-zsh does this for most users, but it's not installed by default on most systems (particularly Mac).
My main concern with generating autoload and compinit is that I'm not totally sure they are safe to run in a library context. We don't have knowledge of the rest of the user's .zshrc to know if they expect Angular to run it or if that can break something else.
Looking around for prior art: It seems like NVM does check and run autoload with compinit, so maybe we can just do the same thing? I don't fully understand the flags being given to these commands to know how well it applies to Angular.
I couldn't find a man page, and it doesn't have a --help or -h or anything as far as I could find randomly trying things. Searching didn't turn up much, but a which compinit spit out shell code. It looks like compinit is a zsh builtin!
autoload is a helper function but the comments say:
Note that this need not include `-U' and `-z'. yet the script itself is full of autoload -RUzs and stuff. Hm... In any case, I removed the -U and -z from my .zshrc and it's still working. If I remove autoload and/or compinit entirely it stops working.
The NVM prior art uses '-u' in some cases which I'd recommend against doing in the fix.
the -u flag causes all directories found by
# compaudit to be used (without security checking). Otherwise the user is
# queried for whether to use or ignore the insecure directories (which
# means compinit should not be called from non-interactive shells).
This appears to relate to the second error I received about permissions on directories that were created in /usr/. Rather than using the -u flag, I fixed the permissions. It also appears there's some discussion about this in the nvm issues. This usage of -u in their script may not be intended. In the meantime, I also found this issue which indicates maybe it should just be a check if autocompletions are in their .zshrc and offer to add the neccesary lines if autoload.*compinit and compinit don't already show up?
Thanks, I'm not on mac os but my I've manually set up my zsh shell, very usefull. Cheers.