Last active
April 5, 2018 23:46
-
-
Save mayoff/5498775 to your computer and use it in GitHub Desktop.
bash completion for the `-a` and `-b` flags of the Mac OS X `open` command
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# This is a set of bash function definitions, and a bash command, that | |
# set up bash completion for the Mac OS X "open" command. | |
# | |
# HOW TO USE | |
# | |
# Add this command to your .bashrc: | |
# | |
# . open.sh | |
# | |
# (Adjust the filename to wherever you put this file.) | |
# | |
# WHAT THIS ACTUALLY DOES | |
# | |
# When you try to complete a word after "open -a", bash will match the | |
# word against the names of the apps on your Mac. Example: | |
# | |
# $ open -a Ado<TAB> | |
# AdobePatchInstaller Adobe\ Bridge\ CS6 Adobe\ Media\ Player | |
# Adobe\ AIR\ Application\ Installer Adobe\ Encore\ CS6 Adobe\ Photoshop\ CS6 | |
# Adobe\ AIR\ Uninstaller Adobe\ Extension\ Manager\ CS6 Adobe\ Prelude\ CS6 | |
# Adobe\ AIR\ Updater Adobe\ Fireworks\ CS6 Adobe\ Premiere\ Pro\ CS6 | |
# Adobe\ After\ Effects\ CS6 Adobe\ Flash\ CS6 Adobe\ SpeedGrade\ CS6 | |
# Adobe\ After\ Effects\ Render\ Engine Adobe\ Help Adobe\ Story | |
# Adobe\ Application\ Manager Adobe\ Illustrator | |
# Adobe\ Audition\ CS6 Adobe\ Media\ Encoder\ CS6 | |
# $ open -a Adobe | |
# | |
# When you try to complete a word after "open -b", bash will match the | |
# word against the bundle identifiers of the apps on your Mac. Example: | |
# | |
# :; open -b com.ado | |
# com.adobe.AdobePremierePro com.adobe.air.Installer | |
# com.adobe.AdobeStory.4875E02D9FB21EE389F73B8D1702B320485DF8CE.1 com.adobe.air.NativeTemplate | |
# com.adobe.AfterEffects com.adobe.air.Template | |
# com.adobe.Audition.5.0 com.adobe.ame.application | |
# com.adobe.Encore com.adobe.amp.4875E02D9FB21EE389F73B8D1702B320485DF8CE.1 | |
# com.adobe.ExtensionManager com.adobe.bridge5 | |
# com.adobe.Installers.Redirector com.adobe.csi.CS6ServiceManager | |
# com.adobe.Installers.Setup com.adobe.director.projector | |
# com.adobe.PDApp com.adobe.dynamiclinkmanager | |
# com.adobe.PDApp.AAMRegistrationNotifier com.adobe.dynamiclinkmediaserver | |
# com.adobe.PDApp.AAMUpdatesNotifier com.adobe.estoolkit-3.8 | |
# com.adobe.Photoshop com.adobe.flash | |
# com.adobe.Prelude com.adobe.headlights.LogTransport2App | |
# com.adobe.adobe_licutil com.adobe.illustrator | |
# com.adobe.air.ApplicationInstaller com.adobe.switchboard-2.0 | |
# :; open -b com.adobe. | |
# | |
# CACHING | |
# | |
# These functions use Spotlight to find your applications and their | |
# bundle identifiers. Getting the list of applications is pretty fast | |
# (after it's done the first time). Getting the bundle identifiers is | |
# a little slower. To speed it up, you can set the shell variable | |
# CompleteOpenBundleCache to a path. The first time I need bundle | |
# identifiers, I will cache them at that path. On subsequent uses, I | |
# will use the cached identifiers. I don't invalidate the cache | |
# automatically. Just delete it when it gets out of date: | |
# | |
# rm -f "$CompleteOpenBundleCache" | |
# | |
_complete_open () { | |
local priorWord="$3" word="$2" | |
case "$priorWord" in | |
-a) _complete_open_app "$word" ;; | |
-b) _complete_open_bundle "$word" ;; | |
*) COMPREPLY=() ;; | |
esac | |
} | |
_complete_open_app () { | |
local word="$1*" appPath appName | |
declare -i i=0 | |
COMPREPLY=() | |
while IFS= read -r -d $'\0' appPath; do | |
appName="${appPath##*/}" | |
appName="${appName%.app}" | |
if [[ "$appName" == $word ]]; then | |
COMPREPLY[i++]="$(_complete_open_helper_escape "$appName")" | |
fi | |
done < <(mdfind -0 'kMDItemContentType == "com.apple.application-bundle"') | |
} | |
_complete_open_bundle () { | |
local word="$1*" bundle | |
declare -i i=0 | |
COMPREPLY=() | |
while IFS= read -r -d $'\0' bundle; do | |
if [[ "$bundle" != '' && "$bundle" == $word ]]; then | |
COMPREPLY[i++]="$(_complete_open_helper_escape "$bundle")" | |
fi | |
done < <(_complete_open_helper_bundles) | |
} | |
_complete_open_file () { | |
local file | |
} | |
_complete_open_helper_bundles () { | |
if [[ "$CompleteOpenBundleCache" == '' ]]; then | |
_complete_open_helper_bundles_uncached | |
else | |
if [[ ! -f "$CompleteOpenBundleCache" ]]; then | |
rm -f "$CompleteOpenBundleCache" | |
_complete_open_helper_bundles_uncached > "$CompleteOpenBundleCache" | |
fi | |
cat "$CompleteOpenBundleCache" | |
fi | |
} | |
_complete_open_helper_bundles_uncached () { | |
mdfind -0 'kMDItemContentType == "com.apple.application-bundle"' \ | |
| xargs -0 mdls -raw -nullMarker '' -name kMDItemCFBundleIdentifier | |
} | |
_complete_open_helper_escape () { | |
echo -n "$1" | sed 's/[^-A-Za-z0-9_.,:@%=+/]/\\&/g' | |
} | |
complete -o bashdefault -o default -F _complete_open open | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment