zsh-users
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: zsh-users@zsh.org
Subject: Re: Zle history feature like that of many IRC clients?
Date: Mon, 19 Dec 2011 19:17:58 -0800	[thread overview]
Message-ID: <111219191758.ZM9817@torch.brasslantern.com> (raw)
In-Reply-To: <CALu3U4-Lq7jKK+YPv-0a2mQ5EAqQu2+NXgQFFfWfi_NCoB6PXg@mail.gmail.com>

On Dec 19, 10:39pm, milk wrote:
:
: Specifically, if I were to type something, then
: press the down arrow and get a blank input line

So what you're asking for is to bind down-arrow to a sort of "put this
in the history but don't send it" action?

Presumably, though, if you've already pressed up-arrow at least once so
you are in the middle of the history, then you just want down-arrow to
move through the history like it normally does.

Let's build it up from some pieces.  First, a "fake-accept-line" to
not really execute the command, but put it on the history.  There are
several different ways to do this with preexec hooks etc., but let's
just do it the old-fashioned way:

    fake-accept-line() {
      if [[ -n "$BUFFER" ]];
      then
	print -S "$BUFFER"
	zle .send-break
      fi
      return 0
    }
    zle -N fake-accept-line

If your version of zsh doesn't have "print -S", use "-s" instead.  It's
not perfect but it'll do.  Using "zle .send-break" at the end sets the
correct return value and makes the history from "print -S" immediately
available for recall, but interrupts whatever else you have going on so
it does mean that fake-accept-line has to be the last thing you want to
do before getting a new prompt.

The leading dot in ".send-break" tells zle to call the widget by its
unalterable name, so you won't be messed up by some other configuration
rebinding the widget.  Make note of this for below.  Also note that you
can't create an unalterable name for a user-defined widget, those are
only for builtins.

Next you want a function that does down-line-or-history [probably; you
might want down-history instead, but I can't tell from your description]
unless there is nowhere to go, in which case it does fake-accept-line.

    down-or-fake-accept-line() {
      (( HISTNO == HISTCMD )) && zle fake-accept-line
      zle .down-line-or-history "$@"                     
    }
    zle -N down-or-fake-accept-line

There I've done a shortcut:  I know fake-accept-line is going to break
out of the surrounding function if it does anything at all, so there's
no need for an else-case, I can fall through to down-line-or-history.

Finally you just need to bind it to a key.  To avoid all the messiness
of figuring out what sequence of characters your down-arrow key may
send, it's often easier to simply grab the widget that is already bound
to that key and alias it to your new widget.

    zle -N down-line-or-history down-or-fake-accept-line

This has now swapped out down-line-or history for this widget anywhere
that down-line-or-history was used (such as, all the default keymaps),
but not inside down-or-fake-accept-line itself, where we have avoided
infinite recursion by using the unalterable name.

If you prefer not to do it this way, add a bindkey command such as

    bindkey '^[[B' down-or-fake-accept-line

which depending on your terminal might mean down-arrow.


  reply	other threads:[~2011-12-20  3:18 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-19 22:39 milk
2011-12-20  3:17 ` Bart Schaefer [this message]
2011-12-20 16:24   ` Bart Schaefer
2011-12-21  6:33     ` milk
2011-12-21  9:07       ` Bart Schaefer

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=111219191758.ZM9817@torch.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-users@zsh.org \
    /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).