Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] _mac_applications: merge _retrieve_mac_apps + simplify



while i'm working on feedback here's a follow-up to w/54915

_retrieve_mac_apps is a 'type' function that does nothing but populate a
cache. most of its functionality has been obsolete for 15-20 years. this
simplifies it and merges it into its primary consumer, _mac_applications

in _firefox and _chromium i used this -0 option which is like -O except
it doesn't try to match, isn't as prone to parameter name collisions,
and supports multiple NUL-delimited fields. maybe it's not as useful
here (only one field) but i carried it over anyway. if i'm not stopped
it could spread further

also fixes a small issue with open -b

dana


diff --git a/Completion/Darwin/Command/_open b/Completion/Darwin/Command/_open
index 079dd2987..1a9758769 100644
--- a/Completion/Darwin/Command/_open
+++ b/Completion/Darwin/Command/_open
@@ -53,11 +53,10 @@ _open() {
       ;;
     bundle-ids)
       autoload -Uz zargs
-      _retrieve_mac_apps
-      tmp=( $_mac_apps )
+      _mac_applications -f0 tmp
       tmp=( ${(0)"$(
-        _call_program bundle-ids \
-          zargs -n300 -P2 -- ${(@q)tmp} -- mdls -rn kMDItemCFBundleIdentifier
+        _call_program -q bundle-ids \
+          zargs -r -- $tmp -- mdls -rn kMDItemCFBundleIdentifier
       )"} )
       tmp=( ${(@)tmp:#\(null\)} com.apple.TextEdit )
       _describe -t bundle-identifier 'bundle identifier' tmp && ret=0
@@ -65,7 +64,7 @@ _open() {
     arguments)
       local app exe
 
-      _retrieve_mac_apps
+      _mac_applications -f0 tmp
 
       # resolve bundle id or app name to path
       if (( $+opt_args[-b] )); then
diff --git a/Completion/Darwin/Type/_mac_applications b/Completion/Darwin/Type/_mac_applications
index 7b633579c..137ed9881 100644
--- a/Completion/Darwin/Type/_mac_applications
+++ b/Completion/Darwin/Type/_mac_applications
@@ -1,7 +1,57 @@
 #autoload
 
-_retrieve_mac_apps
+# complete names of macos applications
+# -0 <name>  like -O, but return all possible matches
+# -a         keep .app extension
+# -f         keep full path + extension
+
+local -a ca_opts expl apps ign_pats
+local -A opth
+
+zparseopts -A opth -D -F - \
+  {1,2,A+:,D+:,J+:,M+:,o+:,O+:,P+:,q+,r+:,R+:,S+:,V+:,x+:,X+:}=ca_opts \
+  0: a f \
+|| return
+
+apps=( ${(f)"$(
+  _call_program -q application-bundles \
+    mdfind "kMDItemContentType == 'com.apple.application-bundle'"
+)"} )
+
+# fall-back in case spotlight is disabled or something. 20 is arbitrary
+(( $#apps < 20 )) && apps+=(
+  {,/System,$HOME}/Applications/*.app(#qNoN-/)
+  {,/System,$HOME}/Applications/^*.app/*.app(#qNoN-/)
+  /Applications/Xcode.app/Contents/{,Developer/}Applications/*.app(#qNoN-/)
+  /System/Library/CoreServices/*.app(#qNoN-/)
+)
+
+# filter out some false positives. it's not clear to me what the search path is
+# for these, whether it varies between e.g. open and defaults. but these don't
+# seem useful in any case
+ign_pats=(
+  '/Library/Apple/System/Library/(|Private)Frameworks/*'
+  '/Library/Developer/CommandLineTools/*'
+  '/Library/Image Capture/*'
+  '/Library/PrivilegedHelperTools/*'
+  '/System/Library/Classroom/*'
+  /System/Library/CoreServices/liquiddetectiond.app # not a real app
+  '/System/Library/(|Private)Frameworks/*'
+  '/Users/*/Library/Application Support/*/Profiles/*/storage/*' # firefox garbage
+  '/Users/*/Library/HTTPStorages/*'
+)
+apps=( ${apps:#(${(j<|>)~ign_pats})} )
+
+if (( $+opth[-a] )); then
+  apps=( ${(@)apps:t} )
+elif (( ! $+opth[-f] )); then
+  apps=( ${(@)${(@)apps:t}%.app} )
+fi
+
+(( $+opth[-0] )) && {
+  trap "${opth[-0]}=( ${(j< >)${(@q+)apps}} )" EXIT
+  return $(( ! $#apps ))
+}
 
-local expl
 _wanted commands expl 'macOS application' \
-    compadd "$@" - "${(@)${_mac_apps[@]:t}%.app}"
+  compadd "${(@)ca_opts}" -a - apps
diff --git a/Completion/Darwin/Type/_retrieve_mac_apps b/Completion/Darwin/Type/_retrieve_mac_apps
deleted file mode 100644
index 8cfc3810e..000000000
--- a/Completion/Darwin/Type/_retrieve_mac_apps
+++ /dev/null
@@ -1,122 +0,0 @@
-#autoload
-
-# Find paths of applications and preserve them into _mac_apps.
-# Used by _mac_applications and _mac_files_for_application.
-
-_mac_apps_caching_policy () {
-  # Rebuild if cache is more than a day old
-  local -a oldp
-  oldp=( "$1"(Nmw+1) )
-  (( $#oldp ))
-}
-
-
-# _mac_apps_*_retrieve
-# 
-# Get search applications from directories specified in app_dir_root.
-# Paths to applications are stored in _mac_apps.
-
-_mac_apps_spotlight_retrieve () {
-  typeset mdfind_query="kMDItemContentType == 'com.apple.application-bundle'"
-
-  for i in ${app_dir_root}; do
-    _mac_apps+=(${(f)"$(_call_program command \
-        mdfind -onlyin ${(q)i} ${(q)mdfind_query})"})
-  done
-}
-
-_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
-
-  # Get application bundles
-  local -a app_result
-
-  if ! zstyle -t ":completion:${curcontext}:commands" ignore-bundle; then
-    app_result=( ${^app_dir}*/Contents/(MacOS|MacOSClassic)(N) )
-    _mac_apps+=( ${app_result[@]%/Contents/MacOS*} )
-  fi
-
-  # Get single file applications
-  if ! zstyle -t ":completion:${curcontext}:commands" ignore-single; then
-    autoload -Uz zargs
-    local app_cand nargs envvars
-    app_cand=( ${^app_dir}^*.[a-z]#/..namedfork/rsrc(.UrN,.RN^U) )
-    envvars="$(builtin typeset -x)"
-    nargs=$(( $(command sysctl -n kern.argmax) - $#envvars - 2048 ))
-    app_result="$(zargs --max-chars $nargs ${app_cand[@]} -- grep -l APPL)"
-    _mac_apps+=( ${${(f)app_result}%/..namedfork/rsrc} )
-  fi
-}
-
-
-_retrieve_mac_apps() {
-  local cache_policy
-  zstyle -s ":completion:*:*:$service:*" cache-policy cache_policy
-  if [[ -z "$cache_policy" ]]; then
-    zstyle ":completion:*:*:$service:*" cache-policy _mac_apps_caching_policy
-  fi
-
-  if ( (( ${#_mac_apps} == 0 )) || _cache_invalid Mac_applications ) \
-        && ! _retrieve_cache Mac_applications; then
-
-    # Get application search method
-    typeset retrieve
-    if ! zstyle -s ":completion:*:*:${service}:commands" search-method retrieve
-    then
-      if [[ "$( command mdutil -s / 2>&1 )" == *enabled* ]]; 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
-    fi
-
-    # Get root directories to search applications
-    typeset -a app_dir_root
-    if ! zstyle -a ":completion:${curcontext}:" application-path app_dir_root
-    then
-      if [[ $retrieve = _mac_apps_old_retrieve ]]; then
-        app_dir_root=(
-          {,/Developer,/Network,/System,$HOME}/{Applications*(N),Desktop}
-        )
-        app_dir_root=( $^app_dir_root(N) )
-      else
-        app_dir_root=( / )
-      fi
-
-      zstyle ":completion:*" application-path $app_dir_root
-    fi
-
-    typeset -g -Ua _mac_apps
-    $retrieve
-
-    # filter out some false positives
-    local -a ign_pats=(
-      '/Library/Apple/System/Library/(|Private)Frameworks/*'
-      '/Library/Developer/CommandLineTools/*'
-      '/Library/Image Capture/*'
-      '/Library/PrivilegedHelperTools/*'
-      '/System/Library/(|Private)Frameworks/*'
-      # firefox garbage
-      '/Users/*/Library/Application Support/*/Profiles/*/storage/*'
-      '/Users/*/Library/HTTPStorages/*'
-    )
-    _mac_apps=( ${_mac_apps:#(${(j<|>)~ign_pats})} )
-
-    _store_cache Mac_applications _mac_apps
-  fi
-}
-
-_retrieve_mac_apps "$@"




Messages sorted by: Reverse Date, Date, Thread, Author