Add zbell function
authorJoerg Jaspert <joerg@debian.org>
Sun, 31 Mar 2013 12:28:50 +0000 (14:28 +0200)
committerJoerg Jaspert <joerg@debian.org>
Sun, 31 Mar 2013 12:28:50 +0000 (14:28 +0200)
written by Jean-Philippe Ouellet

M .zsh/README
A .zsh/functions/zbell

.zsh/README
.zsh/functions/zbell [new file with mode: 0644]

index 5de736f..ac7bce0 100644 (file)
@@ -13,8 +13,9 @@ don't remember anymore. Also, many of which are probably small enough
 that no copyright would apply.
 
 Where I still remember where it is from, I tried to mark them as such,
-giving credit where its due. If you find something in here thats from
-you and want to be mentioned, just mail me.
+giving credit where its due. Those I know off are also listed at the end
+of this README file. If you find something in here thats from you and
+want to be mentioned, just mail me.
 
 For stuff that is from me, use the following license terms:
 
@@ -101,6 +102,10 @@ The prompt i use is based on various others.
 - The winch function as seen in the prompt theme "bart", delivered
   with zsh
 
+** Various
 - The is-{alias,builtin,callable,command,function} and zpgrep function
   have been taken from "zoppo", see [[https://github.com/zoppo][zoppo]] for more of it, which is
   licensed "under WTFPL unless otherwise noted".
+
+- zbell function is Written by Jean-Philippe Ouellet <jpo@vt.edu>
+  and available under the ISC license.
diff --git a/.zsh/functions/zbell b/.zsh/functions/zbell
new file mode 100644 (file)
index 0000000..a246dcd
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/env zsh
+
+# This script prints a bell character when a command finishes
+# if it has been running for longer than $zbell_duration seconds.
+# If there are programs that you know run long that you don't
+# want to bell after, then add them to $zbell_ignore.
+#
+# This script uses only zsh builtins so its fast, there's no needless
+# forking, and its only dependency is zsh and its standard modules
+#
+# Written by Jean-Philippe Ouellet <jpo@vt.edu>
+# Made available under the ISC license.
+
+# only do this if we're in an interactive shell
+[[ -o interactive ]] || exit
+
+# get $EPOCHSECONDS. builtins are faster than date(1)
+zmodload zsh/datetime || exit
+
+# make sure we can register hooks
+autoload -Uz add-zsh-hook || exit
+
+# initialize zbell_duration if not set
+(( ${+zbell_duration} )) || zbell_duration=15
+
+# initialize zbell_ignore if not set
+(( ${+zbell_ignore} )) || zbell_ignore=($EDITOR $PAGER)
+
+# initialize it because otherwise we compare a date and an empty string
+# the first time we see the prompt. it's fine to have lastcmd empty on the
+# initial run because it evaluates to an empty string, and splitting an
+# empty string just results in an empty array.
+zbell_timestamp=$EPOCHSECONDS
+
+# right before we begin to execute something, store the time it started at
+zbell_begin() {
+       zbell_timestamp=$EPOCHSECONDS
+       zbell_lastcmd=$1
+}
+
+# when it finishes, if it's been running longer than $zbell_duration,
+# and we dont have an ignored command in the line, then print a bell.
+zbell_end() {
+       ran_long=$(( $EPOCHSECONDS - $zbell_timestamp >= $zbell_duration ))
+
+       has_ignored_cmd=0
+       for cmd in ${(s:;:)zbell_lastcmd//|/;}; do
+               words=(${(z)cmd})
+               util=${words[1]}
+               if (( ${zbell_ignore[(i)$util]} <= ${#zbell_ignore} )); then
+                       has_ignored_cmd=1
+                       break
+               fi
+       done
+
+       if (( ! $has_ignored_cmd )) && (( ran_long )); then
+               print -n "\a"
+       fi
+}
+
+# register the functions as hooks
+add-zsh-hook preexec zbell_begin
+add-zsh-hook precmd zbell_end