summaryrefslogtreecommitdiff
path: root/plugins/osx
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/osx')
-rw-r--r--plugins/osx/README.md51
-rw-r--r--plugins/osx/_security90
-rw-r--r--plugins/osx/music170
-rw-r--r--plugins/osx/osx.plugin.zsh246
-rw-r--r--plugins/osx/spotify80
5 files changed, 444 insertions, 193 deletions
diff --git a/plugins/osx/README.md b/plugins/osx/README.md
index 3559dee02..ecc9327d0 100644
--- a/plugins/osx/README.md
+++ b/plugins/osx/README.md
@@ -1,8 +1,6 @@
# OSX plugin
-## Description
-
-This plugin provides a few utilities to make it more enjoyable on OSX.
+This plugin provides a few utilities to make it more enjoyable on macOS (previously named OSX).
To start using it, add the `osx` plugin to your plugins array in `~/.zshrc`:
@@ -12,13 +10,37 @@ plugins=(... osx)
Original author: [Sorin Ionescu](https://github.com/sorin-ionescu)
+## Commands
+
+| Command | Description |
+| :-------------- | :---------------------------------------------------- |
+| `tab` | Open the current directory in a new tab |
+| `split_tab` | Split the current terminal tab horizontally |
+| `vsplit_tab` | Split the current terminal tab vertically |
+| `ofd` | Open the current directory in a Finder window |
+| `pfd` | Return the path of the frontmost Finder window |
+| `pfs` | Return the current Finder selection |
+| `cdf` | `cd` 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 |
+| `man-preview` | Open a specified man page in Preview app |
+| `showfiles` | Show hidden files in Finder |
+| `hidefiles` | Hide the hidden files in Finder |
+| `itunes` | _DEPRECATED_. Use `music` from macOS Catalina on |
+| `music` | Control Apple Music. Use `music -h` for usage details |
+| `spotify` | Control Spotify and search by artist, album, track… |
+| `rmdsstore` | Remove .DS\_Store files recursively in a directory |
+| `btrestart` | Restart the Bluetooth daemon |
+
## Acknowledgements
This application makes use of the following third party scripts:
[shpotify](https://github.com/hnarayanan/shpotify)
-Copyright (c) 2012–2017 [Harish Narayanan](https://harishnarayanan.org/).
+Copyright (c) 2012–2019 [Harish Narayanan](https://harishnarayanan.org/).
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -38,24 +60,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-## Commands
-
-| Command | Description |
-| :-------------- | :-------------------------------------------------- |
-| `tab` | Open the current directory in a new tab |
-| `split_tab` | Split the current terminal tab horizontally |
-| `vsplit_tab` | Split the current terminal tab vertically |
-| `ofd` | Open the current directory in a Finder window |
-| `pfd` | Return the path of the frontmost Finder window |
-| `pfs` | Return the current Finder selection |
-| `cdf` | `cd` to the current Finder directory |
-| `pushdf` | `pushd` to the current Finder directory |
-| `quick-look` | Quick-Look a specified file |
-| `man-preview` | Open a specified man page in Preview app |
-| `showfiles` | Show hidden files |
-| `hidefiles` | Hide the hidden files |
-| `itunes` | Control iTunes. Use `itunes -h` for usage details |
-| `spotify` | Control Spotify and search by artist, album, track… |
-| `rmdsstore` | Remove .DS\_Store files recursively in a directory |
diff --git a/plugins/osx/_security b/plugins/osx/_security
new file mode 100644
index 000000000..e4ed585ac
--- /dev/null
+++ b/plugins/osx/_security
@@ -0,0 +1,90 @@
+#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
diff --git a/plugins/osx/music b/plugins/osx/music
new file mode 100644
index 000000000..50566797b
--- /dev/null
+++ b/plugins/osx/music
@@ -0,0 +1,170 @@
+#!/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
diff --git a/plugins/osx/osx.plugin.zsh b/plugins/osx/osx.plugin.zsh
index 6a4b6eec4..7842e9f73 100644
--- a/plugins/osx/osx.plugin.zsh
+++ b/plugins/osx/osx.plugin.zsh
@@ -1,15 +1,22 @@
# Open the current directory in a Finder window
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() {
- local the_app=$(
- osascript 2>/dev/null <<EOF
- tell application "System Events"
- name of first item of (every process whose frontmost is true)
- end tell
+ osascript 2>/dev/null <<EOF
+ tell application "System Events"
+ name of first item of (every process whose frontmost is true)
+ end tell
EOF
- )
- echo "$the_app"
}
function tab() {
@@ -27,7 +34,6 @@ function tab() {
end tell
tell application "Terminal" to do script "${command}" in front window
EOF
-
elif [[ "$the_app" == 'iTerm' ]]; then
osascript <<EOF
tell application "iTerm"
@@ -41,21 +47,29 @@ EOF
end tell
end tell
EOF
-
elif [[ "$the_app" == 'iTerm2' ]]; then
- osascript <<EOF
- tell application "iTerm2"
- tell current window
- create tab with default profile
- tell current session to write text "${command}"
- end tell
+ osascript <<EOF
+ tell application "iTerm2"
+ tell current window
+ create tab with default profile
+ tell current session to write text "${command}"
end tell
+ end tell
+EOF
+ elif [[ "$the_app" == 'Hyper' ]]; then
+ osascript >/dev/null <<EOF
+ tell application "System Events"
+ tell process "Hyper" to keystroke "t" using command down
+ end tell
+ delay 1
+ tell application "System Events"
+ keystroke "${command}"
+ key code 36 #(presses enter)
+ end tell
EOF
-
else
- echo "tab: unsupported terminal app: $the_app"
- false
-
+ echo "$0: unsupported terminal app: $the_app" >&2
+ return 1
fi
}
@@ -68,7 +82,6 @@ function vsplit_tab() {
if [[ "$the_app" == 'iTerm' ]]; then
osascript <<EOF
-- tell application "iTerm" to activate
-
tell application "System Events"
tell process "iTerm"
tell menu item "Split Vertically With Current Profile" of menu "Shell" of menu bar item "Shell" of menu bar 1
@@ -78,24 +91,33 @@ function vsplit_tab() {
keystroke "${command} \n"
end tell
EOF
-
elif [[ "$the_app" == 'iTerm2' ]]; then
- osascript <<EOF
- tell application "iTerm2"
- tell current session of first window
- set newSession to (split vertically with same profile)
- tell newSession
- write text "${command}"
- select
- end tell
+ osascript <<EOF
+ tell application "iTerm2"
+ tell current session of first window
+ set newSession to (split vertically with same profile)
+ tell newSession
+ write text "${command}"
+ select
end tell
end tell
+ end tell
+EOF
+ elif [[ "$the_app" == 'Hyper' ]]; then
+ osascript >/dev/null <<EOF
+ tell application "System Events"
+ tell process "Hyper"
+ tell menu item "Split Vertically" of menu "Shell" of menu bar 1
+ click
+ end tell
+ end tell
+ delay 1
+ keystroke "${command} \n"
+ end tell
EOF
-
else
echo "$0: unsupported terminal app: $the_app" >&2
- false
-
+ return 1
fi
}
@@ -118,31 +140,40 @@ function split_tab() {
keystroke "${command} \n"
end tell
EOF
-
elif [[ "$the_app" == 'iTerm2' ]]; then
- osascript <<EOF
- tell application "iTerm2"
- tell current session of first window
- set newSession to (split horizontally with same profile)
- tell newSession
- write text "${command}"
- select
- end tell
+ osascript <<EOF
+ tell application "iTerm2"
+ tell current session of first window
+ set newSession to (split horizontally with same profile)
+ tell newSession
+ write text "${command}"
+ select
end tell
end tell
+ end tell
+EOF
+ elif [[ "$the_app" == 'Hyper' ]]; then
+ osascript >/dev/null <<EOF
+ tell application "System Events"
+ tell process "Hyper"
+ tell menu item "Split Horizontally" of menu "Shell" of menu bar 1
+ click
+ end tell
+ end tell
+ delay 1
+ keystroke "${command} \n"
+ end tell
EOF
-
else
echo "$0: unsupported terminal app: $the_app" >&2
- false
-
+ return 1
fi
}
function pfd() {
osascript 2>/dev/null <<EOF
tell application "Finder"
- return POSIX path of (target of window 1 as alias)
+ return POSIX path of (insertion location as alias)
end tell
EOF
}
@@ -168,6 +199,21 @@ function pushdf() {
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() {
(( $# > 0 )) && qlmanage -p $* &>/dev/null &
}
@@ -181,109 +227,13 @@ function vncviewer() {
open vnc://$@
}
-# iTunes control function
-function itunes() {
- 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)
- opt="set sound volume to $1" #$1 Due to the shift
- ;;
- playlist)
- # Inspired by: https://gist.github.com/nakajijapan/ac8b45371064ae98ea7f
-if [[ ! -z "$playlist" ]]; then
- osascript -e 'tell application "iTunes"' -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 "iTunes" to player state as string'`
- if [[ "$state" = "playing" ]]; then
- currenttrack=`osascript -e 'tell application "iTunes" to name of current track as string'`
- currentartist=`osascript -e 'tell application "iTunes" to artist of current track as string'`
- echo -E "Listening to $fg[yellow]$currenttrack$reset_color by $fg[yellow]$currentartist$reset_color";
- else
- echo "iTunes 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: itunes 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: itunes <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\tSet the volume, takes an argument from 0 to 100"
- echo "\tplaying|status\tShow what song is currently playing in iTunes."
- 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 \"iTunes\" to $opt"
+# Remove .DS_Store files recursively in a directory, default .
+function rmdsstore() {
+ find "${@:-.}" -type f -name .DS_Store -delete
}
-# 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"
+# Music / iTunes control function
+source "${0:h:A}/music"
-# Remove .DS_Store files recursively in a directory, default .
-rmdsstore() {
- find "${@:-.}" -type f -name .DS_Store -delete
-}
+# Spotify control function
+source "${0:h:A}/spotify"
diff --git a/plugins/osx/spotify b/plugins/osx/spotify
index 2ab98d3a0..663215a74 100644
--- a/plugins/osx/spotify
+++ b/plugins/osx/spotify
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
function spotify() {
-# Copyright (c) 2012--2017 Harish Narayanan <mail@harishnarayanan.org>
+# Copyright (c) 2012--2019 Harish Narayanan <mail@harishnarayanan.org>
#
# Contains numerous helpful contributions from Jorge Colindres, Thomas
# Pritchard, iLan Epstein, Gabriele Bonetti, Sean Heller, Eric Martin
@@ -70,7 +70,7 @@ showHelp () {
echo;
echo " next # Skips to the next song in a playlist.";
echo " prev # Returns to the previous song in a playlist.";
- echo " replay # Replays the current track from the begining.";
+ echo " replay # Replays the current track from the beginning.";
echo " pos <time> # Jumps to a time (in secs) in the current song.";
echo " pause # Pauses (or resumes) Spotify playback.";
echo " stop # Stops playback.";
@@ -82,6 +82,9 @@ showHelp () {
echo " vol [show] # Shows the current Spotify volume.";
echo;
echo " status # Shows the current player status.";
+ echo " status artist # Shows the currently playing artist.";
+ echo " status album # Shows the currently playing album.";
+ echo " status track # Shows the currently playing track.";
echo;
echo " share # Displays the current song's Spotify URL and URI."
echo " share url # Displays the current song's Spotify URL and copies it to the clipboard."
@@ -99,12 +102,21 @@ cecho(){
echo $bold$green"$1"$reset;
}
+showArtist() {
+ echo `osascript -e 'tell application "Spotify" to artist of current track as string'`;
+}
+
+showAlbum() {
+ echo `osascript -e 'tell application "Spotify" to album of current track as string'`;
+}
+
+showTrack() {
+ echo `osascript -e 'tell application "Spotify" to name of current track as string'`;
+}
+
showStatus () {
state=`osascript -e 'tell application "Spotify" to player state as string'`;
cecho "Spotify is currently $state.";
- artist=`osascript -e 'tell application "Spotify" to artist of current track as string'`;
- album=`osascript -e 'tell application "Spotify" to album of current track as string'`;
- track=`osascript -e 'tell application "Spotify" to name of current track as string'`;
duration=`osascript -e 'tell application "Spotify"
set durSec to (duration of current track / 1000) as text
set tM to (round (durSec / 60) rounding down) as text
@@ -128,14 +140,19 @@ showStatus () {
end tell
return nowAt'`;
- echo -e $reset"Artist: $artist\nAlbum: $album\nTrack: $track \nPosition: $position / $duration";
+ echo -e $reset"Artist: $(showArtist)\nAlbum: $(showAlbum)\nTrack: $(showTrack) \nPosition: $position / $duration";
}
if [ $# = 0 ]; then
showHelp;
else
+ if [ ! -d /Applications/Spotify.app ] && [ ! -d $HOME/Applications/Spotify.app ]; then
+ echo "The Spotify application must be installed."
+ return 1
+ fi
+
if [ $(osascript -e 'application "Spotify" is running') = "false" ]; then
- osascript -e 'tell application "Spotify" to activate'
+ osascript -e 'tell application "Spotify" to activate' || return 1
sleep 2
fi
fi
@@ -153,14 +170,14 @@ while [ $# -gt 0 ]; do
if [ -z "${CLIENT_ID}" ]; then
cecho "Invalid Client ID, please update ${USER_CONFIG_FILE}";
showAPIHelp;
- exit 1;
+ return 1
fi
if [ -z "${CLIENT_SECRET}" ]; then
cecho "Invalid Client Secret, please update ${USER_CONFIG_FILE}";
showAPIHelp;
- exit 1;
+ return 1
fi
- SHPOTIFY_CREDENTIALS=$(printf "${CLIENT_ID}:${CLIENT_SECRET}" | base64 | tr -d "\n");
+ SHPOTIFY_CREDENTIALS=$(printf "${CLIENT_ID}:${CLIENT_SECRET}" | base64 | tr -d "\n"|tr -d '\r');
SPOTIFY_PLAY_URI="";
getAccessToken() {
@@ -177,7 +194,7 @@ while [ $# -gt 0 ]; do
cecho "Autorization failed, please check ${USER_CONFG_FILE}"
cecho "${SPOTIFY_TOKEN_RESPONSE_DATA}"
showAPIHelp
- exit 1
+ return 1
fi
SPOTIFY_ACCESS_TOKEN=$( \
printf "${SPOTIFY_TOKEN_RESPONSE_DATA}" \
@@ -218,18 +235,18 @@ while [ $# -gt 0 ]; do
results=$( \
curl -s -G $SPOTIFY_SEARCH_API --data-urlencode "q=$Q" -d "type=playlist&limit=10&offset=0" -H "Accept: application/json" -H "Authorization: Bearer ${SPOTIFY_ACCESS_TOKEN}" \
- | grep -E -o "spotify:user:[a-zA-Z0-9_]+:playlist:[a-zA-Z0-9]+" -m 10 \
+ | grep -E -o "spotify:playlist:[a-zA-Z0-9]+" -m 10 \
)
count=$( \
- echo "$results" | grep -c "spotify:user" \
+ echo "$results" | grep -c "spotify:playlist" \
)
if [ "$count" -gt 0 ]; then
random=$(( $RANDOM % $count));
SPOTIFY_PLAY_URI=$( \
- echo "$results" | awk -v random="$random" '/spotify:user:[a-zA-Z0-9]+:playlist:[a-zA-Z0-9]+/{i++}i==random{print; exit}' \
+ echo "$results" | awk -v random="$random" '/spotify:playlist:[a-zA-Z0-9]+/{i++}i==random{print; exit}' \
)
fi;;
@@ -290,7 +307,7 @@ while [ $# -gt 0 ]; do
"quit" ) cecho "Quitting Spotify.";
osascript -e 'tell application "Spotify" to quit';
- exit 1 ;;
+ break ;;
"next" ) cecho "Going to next track." ;
osascript -e 'tell application "Spotify" to next track';
@@ -341,7 +358,7 @@ while [ $# -gt 0 ]; do
echo " vol down # Decreases the volume by 10%.";
echo " vol [amount] # Sets the volume to an amount between 0 and 100.";
echo " vol # Shows the current Spotify volume.";
- break
+ return 1
fi
osascript -e "tell application \"Spotify\" to set sound volume to $newvol";
@@ -360,7 +377,25 @@ while [ $# -gt 0 ]; do
break ;;
"status" )
- showStatus;
+ if [ $# != 1 ]; then
+ # There are additional arguments, a status subcommand
+ case $2 in
+ "artist" )
+ showArtist;
+ break ;;
+
+ "album" )
+ showAlbum;
+ break ;;
+
+ "track" )
+ showTrack;
+ break ;;
+ esac
+ else
+ # status is the only param
+ showStatus;
+ fi
break ;;
"info" )
@@ -423,16 +458,21 @@ while [ $# -gt 0 ]; do
cecho "Spotify URI: $uri";
echo -n $uri | pbcopy
fi
- break;;
+ break ;;
"pos" )
cecho "Adjusting Spotify play position."
osascript -e "tell application \"Spotify\" to set player position to $2";
- break;;
+ break ;;
- "help" | * )
+ "help" )
showHelp;
break ;;
+
+ * )
+ showHelp;
+ return 1 ;;
+
esac
done
}