osx.plugin.zsh 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. # Open the current directory in a Finder window
  2. alias ofd='open_command $PWD'
  3. function _omz_osx_get_frontmost_app() {
  4. local the_app=$(
  5. osascript 2>/dev/null <<EOF
  6. tell application "System Events"
  7. name of first item of (every process whose frontmost is true)
  8. end tell
  9. EOF
  10. )
  11. echo "$the_app"
  12. }
  13. function tab() {
  14. # Must not have trailing semicolon, for iTerm compatibility
  15. local command="cd \\\"$PWD\\\"; clear"
  16. (( $# > 0 )) && command="${command}; $*"
  17. local the_app=$(_omz_osx_get_frontmost_app)
  18. if [[ "$the_app" == 'Terminal' ]]; then
  19. # Discarding stdout to quash "tab N of window id XXX" output
  20. osascript >/dev/null <<EOF
  21. tell application "System Events"
  22. tell process "Terminal" to keystroke "t" using command down
  23. end tell
  24. tell application "Terminal" to do script "${command}" in front window
  25. EOF
  26. elif [[ "$the_app" == 'iTerm' ]]; then
  27. osascript <<EOF
  28. tell application "iTerm"
  29. set current_terminal to current terminal
  30. tell current_terminal
  31. launch session "Default Session"
  32. set current_session to current session
  33. tell current_session
  34. write text "${command}"
  35. end tell
  36. end tell
  37. end tell
  38. EOF
  39. elif [[ "$the_app" == 'iTerm2' ]]; then
  40. osascript <<EOF
  41. tell application "iTerm2"
  42. tell current window
  43. create tab with default profile
  44. tell current session to write text "${command}"
  45. end tell
  46. end tell
  47. EOF
  48. else
  49. echo "tab: unsupported terminal app: $the_app"
  50. false
  51. fi
  52. }
  53. function vsplit_tab() {
  54. local command="cd \\\"$PWD\\\"; clear"
  55. (( $# > 0 )) && command="${command}; $*"
  56. local the_app=$(_omz_osx_get_frontmost_app)
  57. if [[ "$the_app" == 'iTerm' ]]; then
  58. osascript <<EOF
  59. -- tell application "iTerm" to activate
  60. tell application "System Events"
  61. tell process "iTerm"
  62. tell menu item "Split Vertically With Current Profile" of menu "Shell" of menu bar item "Shell" of menu bar 1
  63. click
  64. end tell
  65. end tell
  66. keystroke "${command} \n"
  67. end tell
  68. EOF
  69. elif [[ "$the_app" == 'iTerm2' ]]; then
  70. osascript <<EOF
  71. tell application "iTerm2"
  72. tell current session of first window
  73. set newSession to (split vertically with same profile)
  74. tell newSession
  75. write text "${command}"
  76. select
  77. end tell
  78. end tell
  79. end tell
  80. EOF
  81. else
  82. echo "$0: unsupported terminal app: $the_app" >&2
  83. false
  84. fi
  85. }
  86. function split_tab() {
  87. local command="cd \\\"$PWD\\\"; clear"
  88. (( $# > 0 )) && command="${command}; $*"
  89. local the_app=$(_omz_osx_get_frontmost_app)
  90. if [[ "$the_app" == 'iTerm' ]]; then
  91. osascript 2>/dev/null <<EOF
  92. tell application "iTerm" to activate
  93. tell application "System Events"
  94. tell process "iTerm"
  95. tell menu item "Split Horizontally With Current Profile" of menu "Shell" of menu bar item "Shell" of menu bar 1
  96. click
  97. end tell
  98. end tell
  99. keystroke "${command} \n"
  100. end tell
  101. EOF
  102. elif [[ "$the_app" == 'iTerm2' ]]; then
  103. osascript <<EOF
  104. tell application "iTerm2"
  105. tell current session of first window
  106. set newSession to (split horizontally with same profile)
  107. tell newSession
  108. write text "${command}"
  109. select
  110. end tell
  111. end tell
  112. end tell
  113. EOF
  114. else
  115. echo "$0: unsupported terminal app: $the_app" >&2
  116. false
  117. fi
  118. }
  119. function pfd() {
  120. osascript 2>/dev/null <<EOF
  121. tell application "Finder"
  122. return POSIX path of (target of window 1 as alias)
  123. end tell
  124. EOF
  125. }
  126. function pfs() {
  127. osascript 2>/dev/null <<EOF
  128. set output to ""
  129. tell application "Finder" to set the_selection to selection
  130. set item_count to count the_selection
  131. repeat with item_index from 1 to count the_selection
  132. if item_index is less than item_count then set the_delimiter to "\n"
  133. if item_index is item_count then set the_delimiter to ""
  134. set output to output & ((item item_index of the_selection as alias)'s POSIX path) & the_delimiter
  135. end repeat
  136. EOF
  137. }
  138. function cdf() {
  139. cd "$(pfd)"
  140. }
  141. function pushdf() {
  142. pushd "$(pfd)"
  143. }
  144. function quick-look() {
  145. (( $# > 0 )) && qlmanage -p $* &>/dev/null &
  146. }
  147. function man-preview() {
  148. man -t "$@" | open -f -a Preview
  149. }
  150. compdef _man man-preview
  151. function vncviewer() {
  152. open vnc://$@
  153. }
  154. # iTunes control function
  155. function itunes() {
  156. local opt=$1
  157. shift
  158. case "$opt" in
  159. launch|play|pause|stop|rewind|resume|quit)
  160. ;;
  161. mute)
  162. opt="set mute to true"
  163. ;;
  164. unmute)
  165. opt="set mute to false"
  166. ;;
  167. next|previous)
  168. opt="$opt track"
  169. ;;
  170. vol)
  171. opt="set sound volume to $1" #$1 Due to the shift
  172. ;;
  173. playing|status)
  174. local state=`osascript -e 'tell application "iTunes" to player state as string'`
  175. if [[ "$state" = "playing" ]]; then
  176. currenttrack=`osascript -e 'tell application "iTunes" to name of current track as string'`
  177. currentartist=`osascript -e 'tell application "iTunes" to artist of current track as string'`
  178. echo -E "Listening to $fg[yellow]$currenttrack$reset_color by $fg[yellow]$currentartist$reset_color";
  179. else
  180. echo "iTunes is" $state;
  181. fi
  182. return 0
  183. ;;
  184. shuf|shuff|shuffle)
  185. # The shuffle property of current playlist can't be changed in iTunes 12,
  186. # so this workaround uses AppleScript to simulate user input instead.
  187. # Defaults to toggling when no options are given.
  188. # The toggle option depends on the shuffle button being visible in the Now playing area.
  189. # On and off use the menu bar items.
  190. local state=$1
  191. if [[ -n "$state" && ! "$state" =~ "^(on|off|toggle)$" ]]
  192. then
  193. print "Usage: itunes shuffle [on|off|toggle]. Invalid option."
  194. return 1
  195. fi
  196. case "$state" in
  197. on|off)
  198. # Inspired by: http://stackoverflow.com/a/14675583
  199. osascript 1>/dev/null 2>&1 <<-EOF
  200. 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" )
  201. EOF
  202. return 0
  203. ;;
  204. toggle|*)
  205. osascript 1>/dev/null 2>&1 <<-EOF
  206. tell application "System Events" to perform action "AXPress" of (button 2 of process "iTunes"'s window "iTunes"'s scroll area 1)
  207. EOF
  208. return 0
  209. ;;
  210. esac
  211. ;;
  212. ""|-h|--help)
  213. echo "Usage: itunes <option>"
  214. echo "option:"
  215. echo "\tlaunch|play|pause|stop|rewind|resume|quit"
  216. echo "\tmute|unmute\tcontrol volume set"
  217. echo "\tnext|previous\tplay next or previous track"
  218. echo "\tshuf|shuffle [on|off|toggle]\tSet shuffled playback. Default: toggle. Note: toggle doesn't support the MiniPlayer."
  219. echo "\tvol\tSet the volume, takes an argument from 0 to 100"
  220. echo "\tplaying|status\tShow what song is currently playing in iTunes."
  221. echo "\thelp\tshow this message and exit"
  222. return 0
  223. ;;
  224. *)
  225. print "Unknown option: $opt"
  226. return 1
  227. ;;
  228. esac
  229. osascript -e "tell application \"iTunes\" to $opt"
  230. }
  231. # Spotify control function
  232. function spotify() {
  233. showHelp () {
  234. echo "Usage:";
  235. echo;
  236. echo " $(basename "$0") <command>";
  237. echo;
  238. echo "Commands:";
  239. echo;
  240. echo " play # Resumes playback where Spotify last left off.";
  241. echo " play [song name] # Finds a song by name and plays it.";
  242. echo " play album [album name] # Finds an album by name and plays it.";
  243. echo " play artist [artist name] # Finds an artist by name and plays it.";
  244. echo " play list [playlist name] # Finds a playlist by name and plays it.";
  245. echo " pause # Pauses Spotify playback.";
  246. echo " next # Skips to the next song in a playlist.";
  247. echo " prev # Returns to the previous song in a playlist.";
  248. echo " pos [time] # Jumps to a time (in secs) in the current song.";
  249. echo " quit # Stops playback and quits Spotify.";
  250. echo;
  251. echo " vol up # Increases the volume by 10%.";
  252. echo " vol down # Decreases the volume by 10%.";
  253. echo " vol [amount] # Sets the volume to an amount between 0 and 100.";
  254. echo " vol show # Shows the current Spotify volume.";
  255. echo;
  256. echo " status # Shows the current player status.";
  257. echo " share # Copies the current song URL to the clipboard."
  258. echo " info # Shows Full Information about song that is playing.";
  259. echo;
  260. echo " toggle shuffle # Toggles shuffle playback mode.";
  261. echo " toggle repeat # Toggles repeat playback mode.";
  262. }
  263. cecho(){
  264. bold=$(tput bold);
  265. green=$(tput setaf 2);
  266. reset=$(tput sgr0);
  267. echo "$bold$green$1$reset";
  268. }
  269. showStatus () {
  270. state=$(osascript -e 'tell application "Spotify" to player state as string');
  271. cecho "Spotify is currently $state.";
  272. if [ "$state" = "playing" ]; then
  273. artist=$(osascript -e 'tell application "Spotify" to artist of current track as string');
  274. album=$(osascript -e 'tell application "Spotify" to album of current track as string');
  275. track=$(osascript -e 'tell application "Spotify" to name of current track as string');
  276. duration=$(osascript -e 'tell application "Spotify" to duration of current track as string');
  277. duration=$(echo "scale=2; $duration / 60 / 1000" | bc);
  278. position=$(osascript -e 'tell application "Spotify" to player position as string' | tr ',' '.');
  279. position=$(echo "scale=2; $position / 60" | bc | awk '{printf "%0.2f", $0}');
  280. printf "$reset""Artist: %s\nAlbum: %s\nTrack: %s \nPosition: %s / %s" "$artist" "$album" "$track" "$position" "$duration";
  281. fi
  282. }
  283. if [ $# = 0 ]; then
  284. showHelp;
  285. else
  286. if [ "$(osascript -e 'application "Spotify" is running')" = "false" ]; then
  287. osascript -e 'tell application "Spotify" to activate'
  288. sleep 2
  289. fi
  290. fi
  291. while [ $# -gt 0 ]; do
  292. arg=$1;
  293. case $arg in
  294. "play" )
  295. if [ $# != 1 ]; then
  296. # There are additional arguments, so find out how many
  297. array=( $@ );
  298. len=${#array[@]};
  299. SPOTIFY_SEARCH_API="https://api.spotify.com/v1/search"
  300. SPOTIFY_PLAY_URI="";
  301. searchAndPlay() {
  302. type="$1"
  303. Q="$2"
  304. cecho "Searching ${type}s for: $Q";
  305. SPOTIFY_PLAY_URI=$( \
  306. curl -s -G $SPOTIFY_SEARCH_API --data-urlencode "q=$Q" -d "type=$type&limit=1&offset=0" -H "Accept: application/json" \
  307. | grep -E -o "spotify:$type:[a-zA-Z0-9]+" -m 1
  308. )
  309. }
  310. case $2 in
  311. "list" )
  312. _args=${array[*]:2:$len};
  313. Q=$_args;
  314. cecho "Searching playlists for: $Q";
  315. results=$( \
  316. curl -s -G $SPOTIFY_SEARCH_API --data-urlencode "q=$Q" -d "type=playlist&limit=10&offset=0" -H "Accept: application/json" \
  317. | grep -E -o "spotify:user:[a-zA-Z0-9_]+:playlist:[a-zA-Z0-9]+" -m 10 \
  318. )
  319. count=$( \
  320. echo "$results" | grep -c "spotify:user" \
  321. )
  322. if [ "$count" -gt 0 ]; then
  323. random=$(( RANDOM % count));
  324. SPOTIFY_PLAY_URI=$( \
  325. echo "$results" | awk -v random="$random" '/spotify:user:[a-zA-Z0-9]+:playlist:[a-zA-Z0-9]+/{i++}i==random{print; exit}' \
  326. )
  327. fi;;
  328. "album" | "artist" | "track" )
  329. _args=${array[*]:2:$len};
  330. searchAndPlay "$2" "$_args";;
  331. * )
  332. _args=${array[*]:1:$len};
  333. searchAndPlay track "$_args";;
  334. esac
  335. if [ "$SPOTIFY_PLAY_URI" != "" ]; then
  336. cecho "Playing ($Q Search) -> Spotify URL: $SPOTIFY_PLAY_URI";
  337. osascript -e "tell application \"Spotify\" to play track \"$SPOTIFY_PLAY_URI\"";
  338. else
  339. cecho "No results when searching for $Q";
  340. fi
  341. else
  342. # play is the only param
  343. cecho "Playing Spotify.";
  344. osascript -e 'tell application "Spotify" to play';
  345. fi
  346. break ;;
  347. "pause" )
  348. state=$(osascript -e 'tell application "Spotify" to player state as string');
  349. if [ "$state" = "playing" ]; then
  350. cecho "Pausing Spotify.";
  351. else
  352. cecho "Playing Spotify.";
  353. fi
  354. osascript -e 'tell application "Spotify" to playpause';
  355. break ;;
  356. "quit" )
  357. cecho "Quitting Spotify.";
  358. osascript -e 'tell application "Spotify" to quit';
  359. exit 1 ;;
  360. "next" )
  361. cecho "Going to next track." ;
  362. osascript -e 'tell application "Spotify" to next track';
  363. break ;;
  364. "prev" )
  365. cecho "Going to previous track.";
  366. osascript -e 'tell application "Spotify" to previous track';
  367. break ;;
  368. "vol" )
  369. vol=$(osascript -e 'tell application "Spotify" to sound volume as integer');
  370. if [[ "$2" = "show" || "$2" = "" ]]; then
  371. cecho "Current Spotify volume level is $vol.";
  372. break ;
  373. elif [ "$2" = "up" ]; then
  374. if [ "$vol" -le 90 ]; then
  375. newvol=$(( vol+10 ));
  376. cecho "Increasing Spotify volume to $newvol.";
  377. else
  378. newvol=100;
  379. cecho "Spotify volume level is at max.";
  380. fi
  381. elif [ "$2" = "down" ]; then
  382. if [ "$vol" -ge 10 ]; then
  383. newvol=$(( vol-10 ));
  384. cecho "Reducing Spotify volume to $newvol.";
  385. else
  386. newvol=0;
  387. cecho "Spotify volume level is at min.";
  388. fi
  389. elif [ "$2" -ge 0 ]; then
  390. newvol=$2;
  391. fi
  392. osascript -e "tell application \"Spotify\" to set sound volume to $newvol";
  393. break ;;
  394. "toggle" )
  395. if [ "$2" = "shuffle" ]; then
  396. osascript -e 'tell application "Spotify" to set shuffling to not shuffling';
  397. curr=$(osascript -e 'tell application "Spotify" to shuffling');
  398. cecho "Spotify shuffling set to $curr";
  399. elif [ "$2" = "repeat" ]; then
  400. osascript -e 'tell application "Spotify" to set repeating to not repeating';
  401. curr=$(osascript -e 'tell application "Spotify" to repeating');
  402. cecho "Spotify repeating set to $curr";
  403. fi
  404. break ;;
  405. "pos" )
  406. cecho "Adjusting Spotify play position."
  407. osascript -e "tell application \"Spotify\" to set player position to $2";
  408. break;;
  409. "status" )
  410. showStatus;
  411. break ;;
  412. "info" )
  413. info=$(osascript -e 'tell application "Spotify"
  414. set tM to round (duration of current track / 60) rounding down
  415. set tS to duration of current track mod 60
  416. set pos to player position as text
  417. set myTime to tM as text & "min " & tS as text & "s"
  418. set nM to round (player position / 60) rounding down
  419. set nS to round (player position mod 60) rounding down
  420. set nowAt to nM as text & "min " & nS as text & "s"
  421. set info to "" & "\nArtist: " & artist of current track
  422. set info to info & "\nTrack: " & name of current track
  423. set info to info & "\nAlbum Artist: " & album artist of current track
  424. set info to info & "\nAlbum: " & album of current track
  425. set info to info & "\nSeconds: " & duration of current track
  426. set info to info & "\nSeconds played: " & pos
  427. set info to info & "\nDuration: " & mytime
  428. set info to info & "\nNow at: " & nowAt
  429. set info to info & "\nPlayed Count: " & played count of current track
  430. set info to info & "\nTrack Number: " & track number of current track
  431. set info to info & "\nPopularity: " & popularity of current track
  432. set info to info & "\nId: " & id of current track
  433. set info to info & "\nSpotify URL: " & spotify url of current track
  434. set info to info & "\nArtwork: " & artwork of current track
  435. set info to info & "\nPlayer: " & player state
  436. set info to info & "\nVolume: " & sound volume
  437. set info to info & "\nShuffle: " & shuffling
  438. set info to info & "\nRepeating: " & repeating
  439. end tell
  440. return info')
  441. echo "$info";
  442. break ;;
  443. "share" )
  444. url=$(osascript -e 'tell application "Spotify" to spotify url of current track');
  445. remove='spotify:track:'
  446. url=${url#$remove}
  447. url="http://open.spotify.com/track/$url"
  448. cecho "Share URL: $url";
  449. cecho -n "$url" | pbcopy
  450. break;;
  451. -h|--help| *)
  452. showHelp;
  453. break ;;
  454. esac
  455. done
  456. }
  457. # Show/hide hidden files in the Finder
  458. alias showfiles="defaults write com.apple.finder AppleShowAllFiles -bool true && killall Finder"
  459. alias hidefiles="defaults write com.apple.finder AppleShowAllFiles -bool false && killall Finder"