Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: widget function must have zle codes



On Thu, Aug 17, 2023 at 6:27 PM Budi <budikusasi@xxxxxxxxx> wrote:
>
> bindkey -s "^m" "\e[H   2>/dev/null [[ $- =~ x ]]&&{ set +x;echo Trace
> OFF ;} ||{ set -x;echo Trace ON;};print -s '\e[F'\r\e[A"

To the best of my ability to interpret that ... literally:

binding-for-ctrl-m () {
  zle .beginning-of-line
  zle -I
  {
  if [[ -o xtrace ]]; then
    { set +x; echo Trace OFF }
  else
    { set -x; echo Trace ON }
  fi
  zle .end-of-line
  zle .accept-and-hold
  } 2>/dev/null
}
zle -N binding-for-ctrl-m
bindkey ^m binding-for-ctrl-m

This "works" but there's a problem not of your making:  ZLE widgets
are not allowed to change the global setting of XTRACE -- it is always
saved on entry to ZLE and restored again on exit -- so the set -x or
+x in the widget is useless.

Before I fix that, let me point out that the beginning/end-of-line
motions are not needed, I included them just to translate as closely
as possible.  Even with bind -x in bash the \e[H is not needed; I'm
not sure about the \e[F.  The "zle -I" is what tells zle that some
other output is coming, so it should get out of the way and then
repaint when it gets control again.  bind -x does that too, at least
in some simple experiments.

To avoid the XTRACE problem, if I'm following correctly what you
expect the \e[F\r\e[A part to accomplish, the shortest solution is
probably:

binding-for-ctrl-m() {
  zle -I
  print Trace ON
  eval "() { setopt localoptions xtrace; $BUFFER }"
  print Trace OFF
}

If you actually require the set -x to take global effect but be
invisible to the history etc., it gets a lot more complicated, so I
won't go there yet.

As a last note, "print -s" writes to the history list, not to the
editor, so you would never use that for editor control keystrokes.  If
you really need to send the key binding for an action instead of
calling it with "zle widget-name", that's what "zle -U" is for, but
anything sent that way is not looked at until the current widget
returns.




Messages sorted by: Reverse Date, Date, Thread, Author