ZSH Hangs on Open Application Tab Autocompletion
Asked Answered
M

1

7

I frequently open applications on my Mac by using the command open -a <application-name>. I also have been using tab autocompletion more recently to complete my commands. I tried to do this after writing, for example, open -a or open -a Safa, but when I hit tab, zsh hangs and I cannot type anything else in the window. This also does not provide the autocomplete options as it should. I tried this in both Terminal and iTerm2 and the problem persists.

I am using zsh 5.7.1. I also have Oh My Zsh installed on my computer.

Just in case it helps, here is my .zshrc file:

# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH

# Path to your oh-my-zsh installation.
export ZSH="/Users/noahwilder/.oh-my-zsh"

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="spaceship"
#"robbyrussell"
#"agnoster"

# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in ~/.oh-my-zsh/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )

# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"

# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"

# Uncomment the following line to disable bi-weekly auto-update checks.
# DISABLE_AUTO_UPDATE="true"

# Uncomment the following line to automatically update without prompting.
# DISABLE_UPDATE_PROMPT="true"

# Uncomment the following line to change how often to auto-update (in days).
# export UPDATE_ZSH_DAYS=13

# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS=true

# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"

# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"

# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"

# Uncomment the following line to display red dots whilst waiting for completion.
# COMPLETION_WAITING_DOTS="true"

# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"

# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
# HIST_STAMPS="mm/dd/yyyy"

# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder

# Which plugins would you like to load?
# Standard plugins can be found in ~/.oh-my-zsh/plugins/*
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(
  git
  zsh-autosuggestions
  zsh-syntax-highlighting
  Z
)

source $ZSH/oh-my-zsh.sh

# User configuration

# export MANPATH="/usr/local/man:$MANPATH"

# You may need to manually set your language environment
# export LANG=en_US.UTF-8

# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
#   export EDITOR='vim'
# else
#   export EDITOR='mvim'
# fi

# Compilation flags
# export ARCHFLAGS="-arch x86_64"

# Set personal aliases, overriding those provided by oh-my-zsh libs,
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"

# Other setup
autoload -U compinit && compinit
zmodload -i zsh/complist
eval $(thefuck --alias)
. /usr/local/etc/profile.d/z.sh

#prompt_context(){}

# Spaceship theme:
# 
ZSH_THEME="spaceship"
autoload -U promptinit; promptinit;
prompt spaceship
SPACESHIP_BATTERY_SHOW=false


# Use Pure theme:
#
# autoload -U promptinit; promptinit
# prompt pure

# This speeds up pasting w/ autosuggest
# https://github.com/zsh-users/zsh-autosuggestions/issues/238
pasteinit() {
  OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
  zle -N self-insert url-quote-magic # I wonder if you'd need `.url-quote-magic`?
}

pastefinish() {
  zle -N self-insert $OLD_SELF_INSERT
}
zstyle :bracketed-paste-magic paste-init pasteinit
zstyle :bracketed-paste-magic paste-finish pastefinish

How do I fix this and enable autocompletion for opening applications with zsh, as is available everywhere else in zsh?

Mcmillian answered 22/1, 2020 at 17:42 Comment(5)
when I hit tab, zsh hangs - for how long did you wait? Did you try ctrl+c?Biform
@Biform It goes indefinitely without intervention (max I left it for was like 15 minutes before shutting down Terminal and trying again). Control + c shows the message "Killed by signal in _mac_apps_old_retrieve after 2s" and after then proceeding to click enter, it just says that it is unable to find an application with the shortened name (which is not the full name because I am looking for it to be autocompleted).Mcmillian
@NoahWilder : I guess this is only in the context of open, i.e. when you do a simple cat <TAB>, you don't see this effect?Astylar
@1934428 This only ever occurs in the context of open -a <TAB>. Both open <TAB> and cat <TAB> perform as expected.Mcmillian
This does NOT answer your explicit question, but should address your use case -- VSCode comes with command line tools which you can install from the command dialog, which adds code as a command you can use from command line. To achieve your above purpose, just type code . to open the current dir in VSC!Easeful
H
6

This is actually a macOS bug! The problem is in Apple's own open compdef completion script.

In the past open -a completion was fast because the autocomplete script used the Spotlight index for super fast application fetching. You can find the relevant script here: /usr/share/zsh/5.7.1/functions/_retrieve_mac_apps (referenced from the _open script in the same directory)

However, to check if a Spotlight search index exists, it looks to see if the file /.Spotlight-V100 exists. In some macOS update the Spotlight index for user files was moved here: /System/Volumes/Data/.Spotlight-V100 but the autocomplete script wasn't updated! When it thinks no Spotlight index exists it falls back to a very slow manual application listing.

Specifically the bug is this check:

...
      if [[ -d /.Spotlight-V100 ]]; then
        # / is indexed to use Spotlight
         retrieve=_mac_apps_spotlight_retrieve
       else
         # Fall back to the old way
         retrieve=_mac_apps_old_retrieve
       fi
       zstyle ":completion:*:*:${service}:commands" search-method $retrieve

The slow implementation then does this arcane shell-fu. When experimenting it seems to hang forever for me.

 _mac_apps_old_retrieve () {
   # Get directories which may contain applications
   typeset -aU app_dir
   if [[ -z "$app_dir" ]] && \
     ! zstyle -a ":completion:${curcontext}:commands" application-dir app_dir
   then
     typeset -a app_dir_stop_pattern
     app_dir_stop_pattern=( "*.app" "contents#" "*data" "*plugins#" "*plug?ins#" "fonts#" "document[[:alpha:]]#" "*help" "resources#" "images#" "*configurations#" )
     typeset app_dir_pattern
     app_dir_pattern="(^(#i)(${(j/|/)app_dir_stop_pattern}))"
     app_dir=( ${^app_dir_root}/(${~app_dir_pattern}/)#(N) )
   fi
...

Sadly, since this bug is part of macOS itself, the file is protected by System Integrity Protection so it's very annoying to fix. You can copy it though, fix the bug, and replace open's compdef with your fixed version. Here's hoping Apple finally fixes this in Big Sur!

EDIT: Here's a gist that fixes the issue and has some instructions for how to install it: https://gist.github.com/varenc/d2c09c3ad5939774001c32fe5f7df41f

Also for reference Apple did not fix this issue in Big Sur or Monterey. 😑

Hallucinosis answered 26/7, 2020 at 8:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.