zsh-users
 help / color / mirror / code / Atom feed
From: Peter Stephenson <pws@csr.com>
To: zsh-users@sunsite.dk (Zsh users list)
Subject: Function to describe keys not so briefly
Date: Tue, 15 Aug 2006 12:11:24 +0100	[thread overview]
Message-ID: <200608151111.k7FBBOKU012186@news01.csr.com> (raw)

This is sort of related to the thread in zsh-users/10180.

I've been wanting a function which probes zle key sequences in a bit
more depth than describe-key-briefly.  The following function can be
called from the command line or used as a zle widget.  It shows
details about the bound widget and how it's implemented.

If anyone likes it I'll add it to the distribution.

##start##
# Pass the function a key sequence in the normal form used by the
# first argument of "bindkey".  The key sequence is analysed to find
# out how it's bound and implemented.  The bindkey keymap selection
# options are understood.
#
# This can be used directly as a zle widget, in which case it prompts
# for and reads a key sequence and displays the information about it
# in the status area.
#
# The module zsh/zleparameter is requried for details of the widget,
# and the module zsh/parameter is required for details of the
# implementation function (if any).

emulate -L zsh
setopt extendedglob
local opt mapname desc widget func
local -a match mbegin mend keymap

if zle; then
  local REPLY
  zle -R 'Enter key sequence:'
  zle read-command && widget=$REPLY
  set -- $KEYS
  mapname="the keymap $KEYMAP"
else
  while getopts "M:" opt; do
    case $opt in
      (e)
      keymap=(-M emacs)
      ;;

      (v)
      keymap=(-M viins)
      ;;

      (a)
      keymap=(-M vicmd)
      ;;

      (M)
      keymap=(-M $OPTARG)
      ;;

      (*)
      return 1
      ;;
    esac
  done
  shift $(( OPTIND - 1 ))

  if (( ${#keymap} )); then
    mapname="the keymap ${keymap[-1]}"
  else
    mapname="the current keymap"
  fi
  widget=${${(Q)${(z)"$(bindkey $keymap $1)"}}[2]} || return
fi

if [[ -z $widget || $widget = undefined-key ]]; then
  desc="${(qqV)1} is not bound in $mapname"
else
  desc="${(qqV)1} is bound to the widget ${(qq)widget} in $mapname"

  zmodload -i zsh/zleparameter || return 1
  local details=$widgets[$widget]

  case $details in
    (builtin)
    desc+=$'\n'"${(qq)widget} is a builtin widget"
    ;;

    (user:(#b)(*))
    func=$match[1]
    desc+=$'\n'"${(qq)widget} is a user-defined widget"
    ;;

    (completion:(#b)([^:]#):(*))
    func=$match[2]
    desc+=$'\n'"${(qq)widget} is a completion widget with style $match[1]"
    ;;

    (*)
    desc+=$'\n'"${(qq)widget} is not registered as a widget"
    ;;
  esac

  if [[ -n $func ]]; then
    local -a where
    where=($^fpath/$func(N))

    desc+=$'\n'"${(qq)widget} is implemented by the function ${(qq)func}"
    if (( ${#where} )); then
      desc+=$'\n'"${(qq)func} is a function loaded from:"
      desc+=$'\n'"  ${where[1]}"
    else
      desc+=$'\n'"${(qq)func} is not in the function path"
    fi

    zmodload -i zsh/parameter || return

    if [[ -z $functions[$func] ]]; then
      desc+=$'\n'"${(qq)func} is not defined nor marked for autoload"
  elif [[ $functions[$func] = "builtin autoload -X"(#b)(*) ]]; then
      desc+=$'\n'"${(qq)func} is marked for autoload"
      if [[ -n $match[1] ]]; then
	desc+=" (flags -$match[1])"
      fi
    else
      desc+=$'\n'"${(qq)func} is already defined as a function"
    fi
  fi
fi

if zle; then
  zle -M $desc
else
  print -r -- $desc
fi
##end##

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php


                 reply	other threads:[~2006-08-15 11:11 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200608151111.k7FBBOKU012186@news01.csr.com \
    --to=pws@csr.com \
    --cc=zsh-users@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).