78cfe75c12bbca3ce9f950b4a760bab90649e282

Author
Robby Russell <robby@planetargon.com>
Committer
Robby Russell <robby@planetargon.com>
Date

Message

Merge pull request #3301 from t413/master

Background notifications on long-running commands

Diff

  1diff --git a/plugins/bgnotify/README.md b/plugins/bgnotify/README.md
  2new file mode 100644
  3index 0000000000000000000000000000000000000000..b154916d61f2d0b2b1d1f1cb63e93fb69066e6c9
  4--- /dev/null
  5+++ b/plugins/bgnotify/README.md
  6@@ -0,0 +1,54 @@
  7+# bgnotify zsh plugin
  8+
  9+cross-platform background notifications for long running commands! Supports OSX and Ubuntu linux.
 10+
 11+Standalone homepage: [t413/zsh-background-notify](https://github.com/t413/zsh-background-notify)
 12+
 13+----------------------------------
 14+
 15+## How to use!
 16+
 17+Just add bgnotify to your plugins list in your `.zshrc`
 18+
 19+- On OS X you'll need [terminal-notifer](https://github.com/alloy/terminal-notifier)
 20+  * `brew install terminal-notifier` (or `gem install terminal-notifier`)
 21+- On ubuntu you're already all set!
 22+- On windows you can use [notifu](http://www.paralint.com/projects/notifu/) or the Cygwin Ports libnotify package
 23+
 24+
 25+## Screenshots
 26+
 27+**Linux**
 28+
 29+![screenshot from 2014-11-07 15 58 36](https://cloud.githubusercontent.com/assets/326829/4962187/256b465c-66da-11e4-927d-cc2fc105e31f.png)
 30+
 31+**OS X**
 32+
 33+![screenshot 2014-11-08 14 15 12](https://cloud.githubusercontent.com/assets/326829/4965780/19fa3eac-6795-11e4-8ed6-0355711123a9.png)
 34+
 35+**Windows**
 36+
 37+![screenshot from 2014-11-07 15 55 00](https://cloud.githubusercontent.com/assets/326829/4962159/a2625ca0-66d9-11e4-9e91-c5834913190e.png)
 38+
 39+
 40+## Configuration
 41+
 42+One can configure a few things:
 43+
 44+- `bgnotify_threshold` sets the notification threshold time (default 6 seconds)
 45+- `function bgnotify_formatted` lets you change the notification
 46+
 47+Use these by adding a function definition before the your call to source. Example:
 48+
 49+~~~ sh
 50+bgnotify_threshold=4  ## set your own notification threshold
 51+
 52+function bgnotify_formatted {
 53+  ## $1=exit_status, $2=command, $3=elapsed_time
 54+  [ $1 -eq 0 ] && title="Holy Smokes Batman!" || title="Holy Graf Zeppelin!"
 55+  bgnotify "$title -- after $3 s" "$2";
 56+}
 57+
 58+plugins=(git bgnotify)  ## add to plugins list
 59+source $ZSH/oh-my-zsh.sh  ## existing source call
 60+~~~
 61diff --git a/plugins/bgnotify/bgnotify.plugin.zsh b/plugins/bgnotify/bgnotify.plugin.zsh
 62new file mode 100755
 63index 0000000000000000000000000000000000000000..259d27424c8e18edef9e98affad2d902f3892851
 64--- /dev/null
 65+++ b/plugins/bgnotify/bgnotify.plugin.zsh
 66@@ -0,0 +1,68 @@
 67+#!/usr/bin/env zsh
 68+
 69+
 70+## setup ##
 71+
 72+[[ -o interactive ]] || return #interactive only!
 73+zmodload zsh/datetime || { print "can't load zsh/datetime"; return } # faster than date()
 74+autoload -Uz add-zsh-hook || { print "can't add zsh hook!"; return }
 75+
 76+(( ${+bgnotify_threshold} )) || bgnotify_threshold=5 #default 10 seconds
 77+
 78+
 79+## definitions ##
 80+
 81+if ! (type bgnotify_formatted | grep -q 'function'); then
 82+  function bgnotify_formatted {
 83+    ## exit_status, command, elapsed_time
 84+    [ $1 -eq 0 ] && title="#win (took $3 s)" || title="#fail (took $3 s)"
 85+    bgnotify "$title" "$2"
 86+  }
 87+fi
 88+
 89+currentWindowId () {
 90+  if hash notify-send 2>/dev/null; then #ubuntu!
 91+    xprop -root | awk '/NET_ACTIVE_WINDOW/ { print $5; exit }'
 92+  elif hash osascript 2>/dev/null; then #osx
 93+    osascript -e 'tell application (path to frontmost application as text) to id of front window' 2&> /dev/null || echo "0"
 94+  else
 95+    echo $EPOCHSECONDS #fallback for windows
 96+  fi
 97+}
 98+
 99+bgnotify () {
100+  if hash notify-send 2>/dev/null; then #ubuntu!
101+    notify-send $1 $2
102+  elif hash terminal-notifier 2>/dev/null; then #osx
103+    terminal-notifier -message $2 -title $1
104+  elif hash growlnotify 2>/dev/null; then #osx growl
105+    growlnotify -m $1 $2
106+  elif hash notifu 2>/dev/null; then #cygwyn support!
107+    notifu /m "$2" /p "$1"
108+  fi
109+}
110+
111+
112+## Zsh hooks ##
113+
114+bgnotify_begin() {
115+  bgnotify_timestamp=$EPOCHSECONDS
116+  bgnotify_lastcmd=$1
117+  bgnotify_windowid=$(currentWindowId)
118+}
119+
120+bgnotify_end() {
121+  didexit=$?
122+  elapsed=$(( EPOCHSECONDS - bgnotify_timestamp ))
123+  past_threshold=$(( elapsed >= bgnotify_threshold ))
124+  if (( bgnotify_timestamp > 0 )) && (( past_threshold )); then
125+    if [ $(currentWindowId) != "$bgnotify_windowid" ]; then
126+      print -n "\a"
127+      bgnotify_formatted "$didexit" "$bgnotify_lastcmd" "$elapsed"
128+    fi
129+  fi
130+  bgnotify_timestamp=0 #reset it to 0!
131+}
132+
133+add-zsh-hook preexec bgnotify_begin
134+add-zsh-hook precmd bgnotify_end