zbell built into the prompt
authorJoerg Jaspert <joerg@debian.org>
Mon, 1 Apr 2013 22:33:51 +0000 (00:33 +0200)
committerJoerg Jaspert <joerg@debian.org>
Mon, 1 Apr 2013 22:33:51 +0000 (00:33 +0200)
Based on the zbell idea from Jean-Philippe Ouellet, see functions/zbell
for that, this is built into the prompt now. There are two zstyles to
control it, one to set the timeout (default 600), one to set the commands
to ignore (default '$EDITOR' '$PAGER' sleep man ssh, as well as the expanded
versions of the variables).

As all the variables and functions are renamed to fit in with all the rest of
the prompt, zbell and this can even be used together. zbells default time is
much shorter, so might make sense. Also, if the timeout is set to 0, none
of the prompt code is loaded, then you need zbell.

.zsh/functions/prompt_ganneff_setup
.zsh/zshenv.local.sample

index 7ab3a97..f434f25 100644 (file)
@@ -434,6 +434,31 @@ ${PR_SHIFT_IN}${PR_HBAR}${PR_CYAN}${PR_HBAR}${PR_SHIFT_OUT}${PR_NO_COLOR} '
 
     functions[TRAPWINCH]="${functions[TRAPWINCH]//prompt_ganneff_winch}
         prompt_ganneff_winch"
+
+    # Should we "ring the bell" when a command finishes?
+    zstyle -s ':prompt:ganneff' longbell _prompt_ganneff_belltime || \
+        _prompt_ganneff_belltime=600
+    if [[ ${_prompt_ganneff_belltime} -gt 0 ]]; then
+        # New shell, initialize the timestamp once
+        _prompt_ganneff_timestamp=${EPOCHSECONDS}
+        typeset -ga _prompt_ganneff_ignore
+        zstyle -a ':prompt:ganneff' bell_ignore _prompt_ganneff_ignore || \
+            _prompt_ganneff_ignore=( '$EDITOR' '$PAGER' sleep man ssh )
+        # In case the commands to ignore include variables (say $EDITOR), we want to
+        # store them once as variable - and once the variable expanded.
+        for (( i = 1; i <= ${#_prompt_ganneff_ignore}; i++ )) do
+            if (( ${${_prompt_ganneff_ignore[$i]}[(i)$]} <= ${#_prompt_ganneff_ignore[$i]} )); then
+                _prompt_ganneff_ignore+=(${(e)${_prompt_ganneff_ignore[$i]}})
+            fi
+        done
+        add-zsh-hook preexec prompt_ganneff_preexec
+    fi
+}
+
+# right before we begin to execute something, store the time it started at
+prompt_ganneff_preexec() {
+       _prompt_ganneff_timestamp=${EPOCHSECONDS}
+       _prompt_ganneff_lastcmd=${2}
 }
 
 prompt_ganneff_precmd () {
@@ -441,7 +466,7 @@ prompt_ganneff_precmd () {
     setopt nolocaltraps
 
     zstyle -t ':prompt:ganneff' vcs_info && vcs_info
-    local -a left_items right_items
+    local -a left_items right_items drop_words
 
     left_items=(ulcorner line openparantheses user at host colon pts closeparantheses line history
         line shell-level line flexline openparentheses path closeparentheses line urcorner newline
@@ -473,6 +498,29 @@ prompt_ganneff_precmd () {
         # And with a small prompt, we don't show the right size at all.
         RPS1=""
     fi
+
+    # Should we "ring the bell" when a command finishes?
+    if (( _prompt_ganneff_timestamp )); then
+        ran_long=$(( ${EPOCHSECONDS} - ${_prompt_ganneff_timestamp} >= ${_prompt_ganneff_belltime} ))
+        if (( ran_long )); then
+            has_ignored_cmd=0
+            drop_words=(builtin command nocorrect noglob)
+            for cmd in ${(s:;:)_prompt_ganneff_lastcmd//|/;}; do
+                words=(${(z)cmd})
+                util=${words[1]}
+                if (( ${drop_words[(i)$util]} <= ${#drop_words} )); then
+                    util=${words[2]}
+                fi
+                if (( ${_prompt_ganneff_ignore[(i)$util]} <= ${#_prompt_ganneff_ignore} )); then
+                    has_ignored_cmd=1
+                    break
+                fi
+            done
+            if (( ! ${has_ignored_cmd} )); then
+                print -n "\a"
+            fi
+        fi
+    fi
 }
 
 prompt_ganneff_length () {
index b870192..1eaf536 100644 (file)
@@ -167,6 +167,20 @@ zstyle ':prompt:ganneff' set_vcs_info_defaults true
 # zstyle ':vcs_info:*' actionformats "(${PR_YELLOW}%s${PR_NO_COLOR})-[${PR_GREEN}%b${PR_NO_COLOR}-${PR_RED}(%a)${PR_NO_COLOR}]%m%u%c "
 # zstyle ':vcs_info:*' disable cdv darcs mtn tla hg fossil p4
 
+## Similar to the zbell function included, this lets the prompt do it.
+## That way one can not forget to activate it. But as one might not want
+## it each and every time when a command runs a little longer, the
+## timeout here should be really high. I recommend something like 300 or
+## 600. Set it to 0 to turn this feature off entirely, default is 600
+# zstyle ':prompt:ganneff' longbell 600
+
+## The following list of commands is ignored, no bell is output if it
+## runs too long. $EDITOR, $PAGER, man and maybe ssh might be good
+## candidates and as such are the default.  If you put variables here,
+## we will additionally expand them at prompt setup time and so keep
+## both, the variable itself as well as the expanded command ignored.
+# zstyle ':prompt:ganneff' bell_ignore '$EDITOR' '$PAGER' sleep man ssh
+
 ## Use color in prompt.
 ## COLORS is defined as true/false in 01_Terminfo.zsh depending on
 ## capabilities of the terminal. If unset then defined by those.