about summary refs log tree commit diff
path: root/Functions/Prompts
diff options
context:
space:
mode:
Diffstat (limited to 'Functions/Prompts')
-rw-r--r--Functions/Prompts/promptinit154
1 files changed, 119 insertions, 35 deletions
diff --git a/Functions/Prompts/promptinit b/Functions/Prompts/promptinit
index 2cf2a4674..a07650500 100644
--- a/Functions/Prompts/promptinit
+++ b/Functions/Prompts/promptinit
@@ -1,27 +1,32 @@
-# zsh prompt themes extension
-#
-# Load with `autoload -U promptinit; promptinit'.
+##
+## zsh prompt themes extension
+## by Adam Spiers <adam@spiers.net>
+##
+## Load with `autoload -U promptinit; promptinit'.
+## Type `prompt -h' for help.
+##
 
 prompt_themes=()
 typeset -gU prompt_themes
-typeset -g prompt_theme
+typeset -g prompt_theme >/dev/null
 
 promptinit () {
   emulate -L zsh
-  local ppath='' name
+  setopt extendedglob
+  local ppath='' name theme
 
   # Autoload all prompt_*_setup functions in fpath
-  for theme in $fpath/prompt_*_setup(N); do
+  for theme in $^fpath/prompt_*_setup(N); do
     if [[ $theme == */prompt_(#b)(*)_setup ]]; then
       name="$match[1]"
       if [[ -r "$theme" ]]; then
-        prompt_themes=($name $prompt_themes)
+        prompt_themes=($prompt_themes $name)
         autoload -U prompt_${name}_setup
       else
-        print "Couldn't find theme $theme" 
+        print "Couldn't read file $theme containing theme $name."
       fi
     else
-      print "eh?"
+      print "Eh?  Mismatch between glob patterns in promptinit."
     fi
   done
 
@@ -30,29 +35,86 @@ promptinit () {
   colors
 
   # Variables common to all prompt styles
-  prompt_newline=$(echo -ne "\n%{\r%}")
+  prompt_newline=$'\n%{\r%}'
 }
 
-prompt () {
+prompt_preview_safely() {
+  print $reset_color
+  if [[ -z "$prompt_themes[(r)$1]" ]]; then
+    print "Unknown theme: $1"
+    return
+  fi
+
+  local -a psv; psv=($psvar); local -a +h psvar; psvar=($psv) # Ick
+  local +h PS1=$PS1 PS2=$PS2 PS3=$PS3 PS4=$PS4 RPS1=$RPS1
+  trap "${$(functions precmd):-:} ; ${$(functions preexec):-:}" 0
+
+  # The next line is a bit ugly.  It (perhaps unnecessarily)
+  # runs the prompt theme setup function to ensure that if
+  # the theme has a _preview function that it's been autoloaded.
+  prompt_${1}_setup
+
+  if typeset +f prompt_${1}_preview >&/dev/null; then
+    prompt_${1}_preview "$@[2,-1]"
+  else
+    prompt_preview_theme "$@"
+  fi
+}
+
+set_prompt() {
+  emulate -L zsh
   local opt preview theme usage old_theme
 
   usage='Usage: prompt <options>
 Options:
+    -c              Show currently selected theme and parameters
     -l              List currently available prompt themes
     -p [<themes>]   Preview given themes (defaults to all)
     -h [<theme>]    Display help (for given theme)
     -s <theme>      Set and save theme
-    <theme>         Switch to new theme immediately (changes not saved)'
+    <theme>         Switch to new theme immediately (changes not saved)
 
-  getopts "hlps" opt
+Use prompt -h <theme> for help on specific themes.'
+
+  getopts "chlps" opt
+  case "$opt" in
+    (h|p)
+      setopt localtraps
+      if [[ -z "$prompt_theme[1]" ]]; then
+        # Not using a prompt theme; save settings
+        local -a psv; psv=($psvar); local -a +h psvar; psvar=($psv) # Ick
+	local +h PS1=$PS1 PS2=$PS2 PS3=$PS3 PS4=$PS4 RPS1=$RPS1
+	trap "${$(functions precmd):-:} ; ${$(functions preexec):-:}" 0
+      else
+        trap 'prompt_${prompt_theme[1]}_setup "${(@)prompt_theme[2,-1]}"' 0
+      fi
+      ;;
+  esac
   case "$opt" in
+    c) if (( $+prompt_theme )); then
+         print -n "Current prompt theme"
+         (( $#prompt_theme > 1 )) && print -n " with parameters"
+         print " is:\n  $prompt_theme"
+       else
+         print "Current prompt is not a theme."
+       fi
+       return
+       ;;
     h) if [[ -n "$2" && -n $prompt_themes[(r)$2] ]]; then
+         if functions prompt_$2_setup >/dev/null; then
+	   # The next line is a bit ugly.  It (perhaps unnecessarily)
+	   # runs the prompt theme setup function to ensure that if
+	   # the theme has a _help function that it's been autoloaded.
+	   prompt_$2_setup
+	 fi
          if functions prompt_$2_help >/dev/null; then
-	   print "Help for $2 theme:\n"
+           print "Help for $2 theme:\n"
            prompt_$2_help
          else
-           print "No help available for $2 theme"
+           print "No help available for $2 theme."
          fi
+         print "\nType \`prompt -p $2' to preview the theme, \`prompt $2'"
+         print "to try it out, and \`prompt -s $2' to use it in future sessions."
        else
          print "$usage"
        fi
@@ -61,24 +123,13 @@ Options:
        print $prompt_themes
        return
        ;;
-    p) if (( ! $+prompt_theme )); then
-         print "Cannot preview; current prompt is non-themeable and would"
-	 print "be destroyed."
-	 return
-       fi
-       preview=( $prompt_themes )
-       [[ -n "$2" && -n $prompt_themes[(r)$2] ]] && preview=( $*[2,-1] )
+    p) preview=( $prompt_themes )
+       (( $#* > 1 )) && preview=( "$@[2,-1]" )
        for theme in $preview; do
-         [[ $theme == $prompt_theme[1] ]] && continue
-         print "\nTheme: $theme"
-         prompt_${theme}_setup
-	 precmd
-	 print -n -P "${PS1}"
-	 preexec
-	 print "command arg1 arg2 ... argn"
+         [[ "$theme" == "$prompt_theme[*]" ]] && continue
+         prompt_preview_safely "$=theme"
        done
-       print
-       prompt_${prompt_theme}_setup
+       print $reset_color
        ;;
     s) print "Set and save not yet implemented.  Please ensure your ~/.zshrc"
        print "contains something similar to the following:\n"
@@ -86,12 +137,21 @@ Options:
        print "  promptinit"
        print "  prompt $*[2,-1]"
        ;;
-    *) if [[ -z "$1" || -z $prompt_themes[(r)$1] ]]; then
+    *) if [[ "$1" == 'random' ]]; then
+         local random_themes
+         if (( $#* == 1 )); then
+           random_themes=( $prompt_themes )
+         else
+           random_themes=( "$@[2,-1]" )
+         fi
+         local i=$(( ( $RANDOM % $#random_themes ) + 1 ))
+         argv=( "${=random_themes[$i]}" )
+       fi
+       if [[ -z "$1" || -z $prompt_themes[(r)$1] ]]; then
          print "$usage"
          return
        fi
-       prompt_$1_setup "$*[2,-1]"
-       prompt_theme=( $* )
+       prompt_$1_setup "$@[2,-1]" && prompt_theme=( "$@" )
 
        # Avoid screwing up the environment listing
        PSZZZZ=$reset_color
@@ -103,5 +163,29 @@ Options:
   esac
 }
 
-promptinit "$@"
+prompt () {
+  local prompt_opts
+  
+  set_prompt "$@"
+ 
+  (( $#prompt_opts )) &&
+      setopt noprompt{bang,cr,percent,subst} prompt${^prompt_opts[@]}
+
+  true
+}
+
+prompt_preview_theme () {
+  local -a psv; psv=($psvar); local -a +h psvar; psvar=($psv) # Ick
+  local +h PS1=$PS1 PS2=$PS2 PS3=$PS3 PS4=$PS4 RPS1=$RPS1
+  trap "${$(functions precmd):-:} ; ${$(functions preexec):-:}" 0
+
+  print -n "$1 theme"
+  (( $#* > 1 )) && print -n " with parameters \`$*[2,-1]'"
+  print ":"
+  prompt_${1}_setup "$@[2,-1]"
+  precmd
+  print -P "${PS1}command arg1 arg2 ... argn"
+  preexec
+}
 
+[[ -o kshautoload ]] || promptinit "$@"