Unverified Commit d47447a5 authored by Marc Cornellà's avatar Marc Cornellà Committed by GitHub
Browse files

osx: refactor plugin and add a few features (#9026)


Co-authored-by: default avatarCapybara <git.capybara@gmail.com>
Co-authored-by: default avatardrootang <drootang@users.noreply.github.com>
Co-authored-by: default avatarAugusto Souza <augustorsouza@gmail.com>
Co-authored-by: default avatarPatrBal <44707588+PatrBal@users.noreply.github.com>
parent 3f6e87df
...@@ -22,14 +22,17 @@ Original author: [Sorin Ionescu](https://github.com/sorin-ionescu) ...@@ -22,14 +22,17 @@ Original author: [Sorin Ionescu](https://github.com/sorin-ionescu)
| `pfs` | Return the current Finder selection | | `pfs` | Return the current Finder selection |
| `cdf` | `cd` to the current Finder directory | | `cdf` | `cd` to the current Finder directory |
| `pushdf` | `pushd` to the current Finder directory | | `pushdf` | `pushd` to the current Finder directory |
| `pxd` | Return the current Xcode project directory |
| `cdx` | `cd` to the current Xcode project directory |
| `quick-look` | Quick-Look a specified file | | `quick-look` | Quick-Look a specified file |
| `man-preview` | Open a specified man page in Preview app | | `man-preview` | Open a specified man page in Preview app |
| `showfiles` | Show hidden files | | `showfiles` | Show hidden files in Finder |
| `hidefiles` | Hide the hidden files | | `hidefiles` | Hide the hidden files in Finder |
| `itunes` | DEPRECATED. Use `music` from macOS Catalina on | | `itunes` | _DEPRECATED_. Use `music` from macOS Catalina on |
| `music` | Control Apple Music. Use `music -h` for usage details | | `music` | Control Apple Music. Use `music -h` for usage details |
| `spotify` | Control Spotify and search by artist, album, track… | | `spotify` | Control Spotify and search by artist, album, track… |
| `rmdsstore` | Remove .DS\_Store files recursively in a directory | | `rmdsstore` | Remove .DS\_Store files recursively in a directory |
| `btrestart` | Restart the Bluetooth daemon |
## Acknowledgements ## Acknowledgements
......
#compdef security
local -a _1st_arguments
_1st_arguments=(
'help:Show all commands, or show usage for a command'
'list-keychains:Display or manipulate the keychain search list'
'default-keychain:Display or set the default keychain'
'login-keychain:Display or set the login keychain'
'create-keychain:Create keychains and add them to the search list'
'delete-keychain:Delete keychains and remove them from the search list'
'lock-keychain:Lock the specified keychain'
'lock-keychain:Unlock the specified keychain'
'set-keychain-settings:Set settings for a keychain'
'set-keychain-password:Set password for a keychain'
'show-keychain-info:Show the settings for keychain'
'dump-keychain:Dump the contents of one or more keychains'
'create-keypair:Create an asymmetric key pair'
'add-generic-password:Add a generic password item'
'add-internet-password:Add an internet password item'
'add-certificates:Add certificates to a keychain'
'find-generic-password:Find a generic password item'
'delete-generic-password:Delete a generic password item'
'find-internet-password:Find an internet password item'
'delete-internet-password:Delete an internet password item'
'find-certificate:Find a certificate item'
'find-identity:Find an identity certificate + private key'
'delete-certificate:Delete a certificate from a keychain'
'set-identity-preference:Set the preferred identity to use for a service'
'get-identity-preference:Get the preferred identity to use for a service'
'create-db:Create a db using the DL'
'export:Export items from a keychain'
'import:Import items into a keychain'
'cms:Encode or decode CMS messages'
'install-mds:MDS database'
'add-trusted-cert:Add trusted certificates:'
'remove-trusted-cert:Remove trusted certificates:'
'dump-trust-settings:Display contents of trust settings'
'user-trust-settings-enable:Display or manipulate user-level trust settings'
'trust-settings-export:Export trust settings'
'trust-settings-import:Import trust settings'
'verify-cert:Verify certificates:'
'authorize:Perform authorization operations'
'authorizationdb:Make changes to the authorization policy database'
'execute-with-privileges:Execute tool with privileges'
'leaks:Run /usr/bin/leaks on this process'
'error:Display a descriptive message for the given error codes:'
'create-filevaultmaster-keychain:"Create a keychain containing a key pair for FileVault recovery use'
)
_arguments '*:: :->command'
if (( CURRENT == 1 )); then
_describe -t commands "security command" _1st_arguments
return
fi
case "$words[1]" in
find-(generic|internet)-password)
_values \
'Usage: find-[internet/generic]-password [-a account] [-s server] [options...] [-g] [keychain...]' \
'-a[Match "account" string]' \
'-c[Match "creator" (four-character code)]' \
'-C[Match "type" (four-character code)]' \
'-D[Match "kind" string]' \
'-G[Match "value" string (generic attribute)]' \
'-j[Match "comment" string]' \
'-l[Match "label" string]' \
'-s[Match "service" string]' \
'-g[Display the password for the item found]' \
'-w[Display only the password on stdout]' ;;
add-(generic|internet)-password)
_values \
'Usage: add-[internet/generic]-password [-a account] [-s server] [-w password] [options...] [-A|-T appPath] [keychain]]' \
'-a[Specify account name (required)]' \
'-c[Specify item creator (optional four-character code)]' \
'-C[Specify item type (optional four-character code)]' \
'-d[Specify security domain string (optional)]' \
'-D[Specify kind (default is "Internet password")]' \
'-j[Specify comment string (optional)]' \
'-l[Specify label (if omitted, server name is used as default label)]' \
'-p[Specify path string (optional)]' \
'-P[Specify port number (optional)]' \
'-r[Specify protocol (optional four-character SecProtocolType, e.g. "http", "ftp ")]' \
'-s[Specify server name (required)]' \
'-t[Specify authentication type (as a four-character SecAuthenticationType, default is "dflt")]' \
'-w[Specify password to be added]' \
'-A[Allow any application to access this item without warning (insecure, not recommended!)]' \
'-T[Specify an application which may access this item (multiple -T options are allowed)]' \
'-U[Update item if it already exists (if omitted, the item cannot already exist) ]' \
'utils)]' ;;
esac
#!/usr/bin/env zsh
function music itunes() {
local APP_NAME=Music sw_vers=$(sw_vers -productVersion 2>/dev/null)
autoload is-at-least
if [[ -z "$sw_vers" ]] || is-at-least 10.15 $sw_vers; then
if [[ $0 = itunes ]]; then
echo >&2 The itunes function name is deprecated. Use \'music\' instead.
return 1
fi
else
APP_NAME=iTunes
fi
local opt=$1 playlist=$2
(( $# > 0 )) && shift
case "$opt" in
launch|play|pause|stop|rewind|resume|quit)
;;
mute)
opt="set mute to true"
;;
unmute)
opt="set mute to false"
;;
next|previous)
opt="$opt track"
;;
vol)
local new_volume volume=$(osascript -e "tell application \"$APP_NAME\" to get sound volume")
if [[ $# -eq 0 ]]; then
echo "Current volume is ${volume}."
return 0
fi
case $1 in
up) new_volume=$((volume + 10 < 100 ? volume + 10 : 100)) ;;
down) new_volume=$((volume - 10 > 0 ? volume - 10 : 0)) ;;
<0-100>) new_volume=$1 ;;
*) echo "'$1' is not valid. Expected <0-100>, up or down."
return 1 ;;
esac
opt="set sound volume to ${new_volume}"
;;
playlist)
# Inspired by: https://gist.github.com/nakajijapan/ac8b45371064ae98ea7f
if [[ -n "$playlist" ]]; then
osascript 2>/dev/null <<EOF
tell application "$APP_NAME"
set new_playlist to "$playlist" as string
play playlist new_playlist
end tell
EOF
if [[ $? -eq 0 ]]; then
opt="play"
else
opt="stop"
fi
else
opt="set allPlaylists to (get name of every playlist)"
fi
;;
playing|status)
local currenttrack currentartist state=$(osascript -e "tell application \"$APP_NAME\" to player state as string")
if [[ "$state" = "playing" ]]; then
currenttrack=$(osascript -e "tell application \"$APP_NAME\" to name of current track as string")
currentartist=$(osascript -e "tell application \"$APP_NAME\" to artist of current track as string")
echo -E "Listening to ${fg[yellow]}${currenttrack}${reset_color} by ${fg[yellow]}${currentartist}${reset_color}"
else
echo "$APP_NAME is $state"
fi
return 0
;;
shuf|shuff|shuffle)
# The shuffle property of current playlist can't be changed in iTunes 12,
# so this workaround uses AppleScript to simulate user input instead.
# Defaults to toggling when no options are given.
# The toggle option depends on the shuffle button being visible in the Now playing area.
# On and off use the menu bar items.
local state=$1
if [[ -n "$state" && "$state" != (on|off|toggle) ]]; then
print "Usage: $0 shuffle [on|off|toggle]. Invalid option."
return 1
fi
case "$state" in
on|off)
# Inspired by: https://stackoverflow.com/a/14675583
osascript >/dev/null 2>&1 <<EOF
tell application "System Events" to perform action "AXPress" of (menu item "${state}" of menu "Shuffle" of menu item "Shuffle" of menu "Controls" of menu bar item "Controls" of menu bar 1 of application process "iTunes" )
EOF
return 0
;;
toggle|*)
osascript >/dev/null 2>&1 <<EOF
tell application "System Events" to perform action "AXPress" of (button 2 of process "iTunes"'s window "iTunes"'s scroll area 1)
EOF
return 0
;;
esac
;;
""|-h|--help)
echo "Usage: $0 <option>"
echo "option:"
echo "\t-h|--help\tShow this message and exit"
echo "\tlaunch|play|pause|stop|rewind|resume|quit"
echo "\tmute|unmute\tMute or unmute $APP_NAME"
echo "\tnext|previous\tPlay next or previous track"
echo "\tshuf|shuffle [on|off|toggle]\tSet shuffled playback. Default: toggle. Note: toggle doesn't support the MiniPlayer."
echo "\tvol [0-100|up|down]\tGet or set the volume. 0 to 100 sets the volume. 'up' / 'down' increases / decreases by 10 points. No argument displays current volume."
echo "\tplaying|status\tShow what song is currently playing in Music."
echo "\tplaylist [playlist name]\t Play specific playlist"
return 0
;;
*)
print "Unknown option: $opt"
return 1
;;
esac
osascript -e "tell application \"$APP_NAME\" to $opt"
}
function _music() {
local app_name
case "$words[1]" in
itunes) app_name="iTunes" ;;
music|*) app_name="Music" ;;
esac
local -a cmds subcmds
cmds=(
"launch:Launch the ${app_name} app"
"play:Play ${app_name}"
"pause:Pause ${app_name}"
"stop:Stop ${app_name}"
"rewind:Rewind ${app_name}"
"resume:Resume ${app_name}"
"quit:Quit ${app_name}"
"mute:Mute the ${app_name} app"
"unmute:Unmute the ${app_name} app"
"next:Skip to the next song"
"previous:Skip to the previous song"
"vol:Change the volume"
"playlist:Play a specific playlist"
{playing,status}":Show what song is currently playing"
{shuf,shuff,shuffle}":Set shuffle mode"
{-h,--help}":Show usage"
)
if (( CURRENT == 2 )); then
_describe 'command' cmds
elif (( CURRENT == 3 )); then
case "$words[2]" in
vol) subcmds=( 'up:Raise the volume' 'down:Lower the volume' )
_describe 'command' subcmds ;;
shuf|shuff|shuffle) subcmds=('on:Switch on shuffle mode' 'off:Switch off shuffle mode' 'toggle:Toggle shuffle mode (default)')
_describe 'command' subcmds ;;
esac
elif (( CURRENT == 4 )); then
case "$words[2]" in
playlist) subcmds=('play:Play the playlist (default)' 'stop:Stop the playlist')
_describe 'command' subcmds ;;
esac
fi
return 0
}
compdef _music music itunes
# Open the current directory in a Finder window # Open the current directory in a Finder window
alias ofd='open_command $PWD' alias ofd='open_command $PWD'
# Show/hide hidden files in the Finder
alias showfiles="defaults write com.apple.finder AppleShowAllFiles -bool true && killall Finder"
alias hidefiles="defaults write com.apple.finder AppleShowAllFiles -bool false && killall Finder"
# Bluetooth restart
function btrestart() {
sudo kextunload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport
sudo kextload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport
}
function _omz_osx_get_frontmost_app() { function _omz_osx_get_frontmost_app() {
local the_app=$( osascript 2>/dev/null <<EOF
osascript 2>/dev/null <<EOF tell application "System Events"
tell application "System Events" name of first item of (every process whose frontmost is true)
name of first item of (every process whose frontmost is true) end tell
end tell
EOF EOF
)
echo "$the_app"
} }
function tab() { function tab() {
...@@ -27,7 +34,6 @@ function tab() { ...@@ -27,7 +34,6 @@ function tab() {
end tell end tell
tell application "Terminal" to do script "${command}" in front window tell application "Terminal" to do script "${command}" in front window
EOF EOF
elif [[ "$the_app" == 'iTerm' ]]; then elif [[ "$the_app" == 'iTerm' ]]; then
osascript <<EOF osascript <<EOF
tell application "iTerm" tell application "iTerm"
...@@ -41,32 +47,29 @@ EOF ...@@ -41,32 +47,29 @@ EOF
end tell end tell
end tell end tell
EOF EOF
elif [[ "$the_app" == 'iTerm2' ]]; then elif [[ "$the_app" == 'iTerm2' ]]; then
osascript <<EOF osascript <<EOF
tell application "iTerm2" tell application "iTerm2"
tell current window tell current window
create tab with default profile create tab with default profile
tell current session to write text "${command}" tell current session to write text "${command}"
end tell
end tell end tell
end tell
EOF EOF
elif [[ "$the_app" == 'Hyper' ]]; then elif [[ "$the_app" == 'Hyper' ]]; then
osascript >/dev/null <<EOF osascript >/dev/null <<EOF
tell application "System Events" tell application "System Events"
tell process "Hyper" to keystroke "t" using command down tell process "Hyper" to keystroke "t" using command down
end tell end tell
delay 1 delay 1
tell application "System Events" tell application "System Events"
keystroke "${command}" keystroke "${command}"
key code 36 #(presses enter) key code 36 #(presses enter)
end tell end tell
EOF EOF
else else
echo "tab: unsupported terminal app: $the_app" echo "$0: unsupported terminal app: $the_app" >&2
false return 1
fi fi
} }
...@@ -79,7 +82,6 @@ function vsplit_tab() { ...@@ -79,7 +82,6 @@ function vsplit_tab() {
if [[ "$the_app" == 'iTerm' ]]; then if [[ "$the_app" == 'iTerm' ]]; then
osascript <<EOF osascript <<EOF
-- tell application "iTerm" to activate -- tell application "iTerm" to activate
tell application "System Events" tell application "System Events"
tell process "iTerm" tell process "iTerm"
tell menu item "Split Vertically With Current Profile" of menu "Shell" of menu bar item "Shell" of menu bar 1 tell menu item "Split Vertically With Current Profile" of menu "Shell" of menu bar item "Shell" of menu bar 1
...@@ -89,37 +91,33 @@ function vsplit_tab() { ...@@ -89,37 +91,33 @@ function vsplit_tab() {
keystroke "${command} \n" keystroke "${command} \n"
end tell end tell
EOF EOF
elif [[ "$the_app" == 'iTerm2' ]]; then elif [[ "$the_app" == 'iTerm2' ]]; then
osascript <<EOF osascript <<EOF
tell application "iTerm2" tell application "iTerm2"
tell current session of first window tell current session of first window
set newSession to (split vertically with same profile) set newSession to (split vertically with same profile)
tell newSession tell newSession
write text "${command}" write text "${command}"
select select
end tell
end tell end tell
end tell end tell
end tell
EOF EOF
elif [[ "$the_app" == 'Hyper' ]]; then elif [[ "$the_app" == 'Hyper' ]]; then
osascript >/dev/null <<EOF osascript >/dev/null <<EOF
tell application "System Events" tell application "System Events"
tell process "Hyper" tell process "Hyper"
tell menu item "Split Vertically" of menu "Shell" of menu bar 1 tell menu item "Split Vertically" of menu "Shell" of menu bar 1
click click
end tell
end tell end tell
delay 1
keystroke "${command} \n"
end tell end tell
delay 1
keystroke "${command} \n"
end tell
EOF EOF
else else
echo "$0: unsupported terminal app: $the_app" >&2 echo "$0: unsupported terminal app: $the_app" >&2
false return 1
fi fi
} }
...@@ -142,44 +140,40 @@ function split_tab() { ...@@ -142,44 +140,40 @@ function split_tab() {
keystroke "${command} \n" keystroke "${command} \n"
end tell end tell
EOF EOF
elif [[ "$the_app" == 'iTerm2' ]]; then elif [[ "$the_app" == 'iTerm2' ]]; then
osascript <<EOF osascript <<EOF
tell application "iTerm2" tell application "iTerm2"
tell current session of first window tell current session of first window
set newSession to (split horizontally with same profile) set newSession to (split horizontally with same profile)
tell newSession tell newSession
write text "${command}" write text "${command}"
select select
end tell
end tell end tell
end tell end tell
end tell
EOF EOF
elif [[ "$the_app" == 'Hyper' ]]; then elif [[ "$the_app" == 'Hyper' ]]; then
osascript >/dev/null <<EOF osascript >/dev/null <<EOF
tell application "System Events" tell application "System Events"
tell process "Hyper" tell process "Hyper"
tell menu item "Split Horizontally" of menu "Shell" of menu bar 1 tell menu item "Split Horizontally" of menu "Shell" of menu bar 1
click click
end tell
end tell end tell
delay 1
keystroke "${command} \n"
end tell end tell
delay 1
keystroke "${command} \n"
end tell
EOF EOF
else else
echo "$0: unsupported terminal app: $the_app" >&2 echo "$0: unsupported terminal app: $the_app" >&2
false return 1
fi fi
} }
function pfd() { function pfd() {
osascript 2>/dev/null <<EOF osascript 2>/dev/null <<EOF
tell application "Finder" tell application "Finder"
return POSIX path of (target of window 1 as alias) return POSIX path of (insertion location as alias)
end tell end tell
EOF EOF
} }
...@@ -205,6 +199,21 @@ function pushdf() { ...@@ -205,6 +199,21 @@ function pushdf() {
pushd "$(pfd)" pushd "$(pfd)"
} }
function pxd() {
dirname $(osascript 2>/dev/null <<EOF
if application "Xcode" is running then
tell application "Xcode"
return path of active workspace document
end tell
end if
EOF
)
}
function cdx() {
cd "$(pxd)"
}
function quick-look() { function quick-look() {
(( $# > 0 )) && qlmanage -p $* &>/dev/null & (( $# > 0 )) && qlmanage -p $* &>/dev/null &
} }
...@@ -218,133 +227,13 @@ function vncviewer() { ...@@ -218,133 +227,13 @@ function vncviewer() {
open vnc://$@ open vnc://$@
} }
# iTunes control function
function itunes music() {
local APP_NAME=Music
autoload is-at-least
if is-at-least 10.15 $(sw_vers -productVersion); then
if [[ $0 = itunes ]]; then
echo >&2 The itunes function name is deprecated. Use \`music\' instead.
return 1
fi
else
APP_NAME=iTunes
fi
local opt=$1
local playlist=$2
shift
case "$opt" in
launch|play|pause|stop|rewind|resume|quit)
;;
mute)
opt="set mute to true"
;;
unmute)
opt="set mute to false"
;;
next|previous)
opt="$opt track"
;;
vol)
local new_volume volume=$(osascript -e "tell application \"$APP_NAME\" to get sound volume")
if [[ $# -eq 0 ]]; then
echo "Current volume is ${volume}."
return 0
fi
case $1 in
up) new_volume=$((volume + 10 < 100 ? volume + 10 : 100)) ;;
down) new_volume=$((volume - 10 > 0 ? volume - 10 : 0)) ;;
<0-100>) new_volume=$1 ;;
*) echo "'$1' is not valid. Expected <0-100>, up or down."
return 1 ;;
esac
opt="set sound volume to ${new_volume}"
;;
playlist)
# Inspired by: https://gist.github.com/nakajijapan/ac8b45371064ae98ea7f
if [[ ! -z "$playlist" ]]; then
osascript -e "tell application \"$APP_NAME\"" -e "set new_playlist to \"$playlist\" as string" -e "play playlist new_playlist" -e "end tell" 2>/dev/null;
if [[ $? -eq 0 ]]; then
opt="play"
else
opt="stop"
fi
else
opt="set allPlaylists to (get name of every playlist)"
fi
;;
playing|status)
local state=`osascript -e "tell application \"$APP_NAME\" to player state as string"`
if [[ "$state" = "playing" ]]; then
currenttrack=`osascript -e "tell application \"$APP_NAME\" to name of current track as string"`
currentartist=`osascript -e "tell application \"$APP_NAME\" to artist of current track as string"`
echo -E "Listening to $fg[yellow]$currenttrack$reset_color by $fg[yellow]$currentartist$reset_color";
else
echo "$APP_NAME is" $state;
fi
return 0
;;
shuf|shuff|shuffle)
# The shuffle property of current playlist can't be changed in iTunes 12,
# so this workaround uses AppleScript to simulate user input instead.
# Defaults to toggling when no options are given.
# The toggle option depends on the shuffle button being visible in the Now playing area.
# On and off use the menu bar items.
local state=$1
if [[ -n "$state" && ! "$state" =~ "^(on|off|toggle)$" ]]
then
print "Usage: $0 shuffle [on|off|toggle]. Invalid option."
return 1
fi
case "$state" in
on|off)
# Inspired by: https://stackoverflow.com/a/14675583
osascript 1>/dev/null 2>&1 <<-EOF
tell application "System Events" to perform action "AXPress" of (menu item "${state}" of menu "Shuffle" of menu item "Shuffle" of menu "Controls" of menu bar item "Controls" of menu bar 1 of application process "iTunes" )
EOF
return 0
;;
toggle|*)
osascript 1>/dev/null 2>&1 <<-EOF
tell application "System Events" to perform action "AXPress" of (button 2 of process "iTunes"'s window "iTunes"'s scroll area 1)
EOF
return 0
;;
esac
;;
""|-h|--help)
echo "Usage: $0 <option>"
echo "option:"
echo "\tlaunch|play|pause|stop|rewind|resume|quit"
echo "\tmute|unmute\tcontrol volume set"
echo "\tnext|previous\tplay next or previous track"
echo "\tshuf|shuffle [on|off|toggle]\tSet shuffled playback. Default: toggle. Note: toggle doesn't support the MiniPlayer."
echo "\tvol [0-100|up|down]\tGet or set the volume. 0 to 100 sets the volume. 'up' / 'down' increases / decreases by 10 points. No argument displays current volume."
echo "\tplaying|status\tShow what song is currently playing in Music."
echo "\tplaylist [playlist name]\t Play specific playlist"
echo "\thelp\tshow this message and exit"
return 0
;;
*)
print "Unknown option: $opt"
return 1
;;
esac
osascript -e "tell application \"$APP_NAME\" to $opt"
}
# Spotify control function
source ${ZSH}/plugins/osx/spotify
# Show/hide hidden files in the Finder
alias showfiles="defaults write com.apple.finder AppleShowAllFiles -bool true && killall Finder"
alias hidefiles="defaults write com.apple.finder AppleShowAllFiles -bool false && killall Finder"
# Remove .DS_Store files recursively in a directory, default . # Remove .DS_Store files recursively in a directory, default .
function rmdsstore() { function rmdsstore() {
find "${@:-.}" -type f -name .DS_Store -delete find "${@:-.}" -type f -name .DS_Store -delete
} }
# Music / iTunes control function
source "${0:h:A}/music"
# Spotify control function
source "${0:h:A}/spotify"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment