Add zsh to ignored commands for the prompt bell
[zsh.git] / .zsh / functions / prompt_ganneff_setup
index f35ae2c..e9f18bf 100644 (file)
@@ -53,7 +53,9 @@ prompt_ganneff_help () {
     The available items are: at, battery, change-root, date, history,
     host, jobs, newline, path, percent, rc, rc-always, shell-level,
     time, user, vcs, ulcorner, llcorner, urcorner, lrcorner, line, pts,
-    openbracket, closebracket, pipe, space, flexline
+    privileges, openparentheses, closeparentheses, openbracket,
+    closebracket, openbraces, closebraces, openanglebracket,
+    closeanglebracket, colon, pipe, space, flexline
 
     Most of those should be self-explanatory, some may need more:
      line     - Draws a single line character
@@ -194,17 +196,28 @@ prompt_ganneff_setup () {
 
     # See if we can and should use extended characters to look nicer.
     if zstyle -t ':prompt:ganneff' nicelines; then
-        typeset -A altchar
-        set -A altchar ${(s..)terminfo[acsc]}
-        # Some stuff to help us draw nice lines
-        PR_SET_CHARSET="%{$terminfo[enacs]%}"
-        PR_SHIFT_IN="%{$terminfo[smacs]%}"
-        PR_SHIFT_OUT="%{$terminfo[rmacs]%}"
-        PR_HBAR=${altchar[q]:--}
-        PR_ULCORNER=${altchar[l]:--}
-        PR_LLCORNER=${altchar[m]:--}
-        PR_LRCORNER=${altchar[j]:--}
-        PR_URCORNER=${altchar[k]:--}
+        if [[ $(locale charmap) == "UTF-8" ]]; then
+            PR_SET_CHARSET=""
+            PR_SHIFT_IN=""
+            PR_SHIFT_OUT=""
+            PR_HBAR="─"
+            PR_ULCORNER="┌"
+            PR_LLCORNER="└"
+            PR_LRCORNER="┘"
+            PR_URCORNER="┐"
+        else
+            typeset -A altchar
+            set -A altchar ${(s..)terminfo[acsc]}
+            # Some stuff to help us draw nice lines
+            PR_SET_CHARSET="%{$terminfo[enacs]%}"
+            PR_SHIFT_IN="%{$terminfo[smacs]%}"
+            PR_SHIFT_OUT="%{$terminfo[rmacs]%}"
+            PR_HBAR=${altchar[q]:--}
+            PR_ULCORNER=${altchar[l]:--}
+            PR_LLCORNER=${altchar[m]:--}
+            PR_LRCORNER=${altchar[j]:--}
+            PR_URCORNER=${altchar[k]:--}
+        fi
     else
         PR_SET_CHARSET=""
         PR_SHIFT_IN=""
@@ -271,7 +284,11 @@ ${PR_SHIFT_IN}${PR_HBAR}${PR_CYAN}${PR_HBAR}${PR_SHIFT_OUT}${PR_NO_COLOR} '
     # selection prompt used within a select loop.
     PS3='?# '
     # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
-    PS4='+%N:%i:%_> '
+    # Not changed if the option xtrace is on, assuming that a trace prompt is then
+    # already defined.
+    if [[ ${options[xtrace]} == off ]]; then
+        PS4='+%N:%i:%_> '
+    fi
 
     if zstyle -t ':prompt:ganneff' vcs_info && \
         is439 && autoload -Uz vcs_info && vcs_info; then
@@ -386,7 +403,7 @@ ${PR_SHIFT_IN}${PR_HBAR}${PR_CYAN}${PR_HBAR}${PR_SHIFT_OUT}${PR_NO_COLOR} '
         jobs              '[%j running job(s)] '
         newline           $'\n'
         path              '%40<..<%~%<<'
-        percent           '% # '
+        percent           '%# '
         rc                '%(?..%? )'
         rc-always         '%?'
         shell-level       '%(2L.%L.)'
@@ -428,6 +445,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 zsh )
+        # 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 () {
@@ -435,36 +477,54 @@ prompt_ganneff_precmd () {
     setopt nolocaltraps
 
     zstyle -t ':prompt:ganneff' vcs_info && vcs_info
-    local -a left_items right_items
-    left_items=(ulcorner line openbracket user at host pts closebracket line history flexline
-                         openbracket path closebracket line urcorner newline
-                llcorner line rc openbracket time closebracket line vcs line change-root pipe space)
+    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
+        llcorner line rc openparentheses time closeparentheses line vcs line change-root pipe space)
     PR_PS1=""; nomore=0
     ganneff_prompt_addto PS1 full "${left_items[@]}"
     if zstyle -T ":prompt:ganneff:right:setup" use-rprompt; then
-        right_items=(space pipe line openbracket date closebracket line lrcorner)
+        right_items=(pipe line openparentheses date closeparentheses line lrcorner)
         ganneff_prompt_addto RPS1 full "${right_items[@]}"
     fi
 
     # Now a kind-of-hack to reduce the prompt when we run out of space.
     promptsize=${#PR_PS1}
     if [[ ${promptsize} -lt ${TERMWIDTH} ]]; then
-        # the q here should be ${PR_HBAR}, but for some reason zsh didn't like me,
-        # so meh
-        if zstyle -t ':prompt:ganneff' nicelines && [[ "$TERM" != dumb ]] \
-            && [[ "$TERM" != "linux" ]]; then
-            PR_FLEXLINE="${(l.(($TERMWIDTH - $promptsize ))..q.)}"
-        else
-            PR_FLEXLINE="${(l.(($TERMWIDTH - $promptsize ))..-.)}"
-        fi
+        PR_FLEXLINE=${${(el.(($TERMWIDTH - $promptsize ))..X.)}//X/$PR_HBAR}
     else
         # Small size prompt is needed
-        left_items=(ulcorner line openbracket user at host closebracket line openbracket path closebracket newline
-            llcorner line rc openbracket time closebracket line vcs line pipe space)
+        left_items=(ulcorner line openparentheses user at host closeparentheses line openparentheses
+            path closeparentheses newline
+            llcorner line rc openparentheses time closeparentheses line vcs line pipe space)
         ganneff_prompt_addto PS1 small "${left_items[@]}"
         # 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 () {
@@ -556,8 +616,8 @@ ganneff_prompt_addto () {
 prompt_ganneff_battery() {
     zstyle -s ':prompt:ganneff' battery pr_battery
     case $pr_battery in
-           ibam)
-                   local ACPIDATA=$(ibam --percentbattery 2>/dev/null || echo "")
+        ibam)
+            local ACPIDATA=$(ibam --percentbattery 2>/dev/null || echo "")
             PERCENT=${${ACPIDATA[(f)1]}[(w)-2]}
             ;;
         acpi)