zsh-users
 help / color / mirror / code / Atom feed
* Problem with motion commands defined using match-word-by-style used with vi-delete
@ 2006-04-21 23:10 Nikolai Weibull
  2006-04-22  5:00 ` Bart Schaefer
  0 siblings, 1 reply; 11+ messages in thread
From: Nikolai Weibull @ 2006-04-21 23:10 UTC (permalink / raw)
  To: Zsh Users

When a motion command defined using match-word-by-style, e.g.,
forward-word-match or backward-word-match, is used together with
vi-delete, they won't use the style assigned to the  command in
question.  The reason is that the $curcontext is set to zle:vi-delete,
not, for example, zle:forward-word-match.

It seems that this issue can be quite hard to fix, considering how
vi-delete is currently implemented.  But perhaps there's an easy
solution that I was unable to spot.

Until then I'm going to use my own vi-delete that uses
matach-word-by-style internally instead of whatever it uses by
default.  This allows me to define the rather useful text-object
motion-commands that Vim has, e.g., "daw" to delete a word.

  n.o.w.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
  2006-04-21 23:10 Problem with motion commands defined using match-word-by-style used with vi-delete Nikolai Weibull
@ 2006-04-22  5:00 ` Bart Schaefer
  2006-04-22 11:04   ` Nikolai Weibull
  0 siblings, 1 reply; 11+ messages in thread
From: Bart Schaefer @ 2006-04-22  5:00 UTC (permalink / raw)
  To: Zsh Users

On Apr 22,  1:10am, Nikolai Weibull wrote:
}
} [...] $curcontext is set to zle:vi-delete, not, for example,
} zle:forward-word-match.
}
} It seems that this issue can be quite hard to fix, considering how
} vi-delete is currently implemented.  But perhaps there's an easy
} solution that I was unable to spot.

Try applying this same small change to each of the *-match functions:

--- 8< ---
@@ -3,7 +3,7 @@
 
 autoload match-words-by-style
 
-local curcontext=":zle:$WIDGET" word
+local curcontext=":zle:$WIDGETFUNC" word
 local -a matched_words
 integer count=${NUMERIC:-1}
 
--- 8< ---

I didn't actually try that because I'm not a vi mode user and I'm in
a hurry :-/ but it seems like it should do the trick.  If it doesn't,
try ${WIDGETFUNC%-match} instead.

} Until then I'm going to use my own vi-delete

Creating a vi-delete-match function seems like the next best thing.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
  2006-04-22  5:00 ` Bart Schaefer
@ 2006-04-22 11:04   ` Nikolai Weibull
  2006-04-22 18:35     ` Bart Schaefer
  0 siblings, 1 reply; 11+ messages in thread
From: Nikolai Weibull @ 2006-04-22 11:04 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On 4/22/06, Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Apr 22,  1:10am, Nikolai Weibull wrote:
> }
> } [...] $curcontext is set to zle:vi-delete, not, for example,
> } zle:forward-word-match.
> }
> } It seems that this issue can be quite hard to fix, considering how
> } vi-delete is currently implemented.  But perhaps there's an easy
> } solution that I was unable to spot.
>
> Try applying this same small change to each of the *-match functions:
>
> --- 8< ---
> @@ -3,7 +3,7 @@
>
>  autoload match-words-by-style
>
> -local curcontext=":zle:$WIDGET" word
> +local curcontext=":zle:$WIDGETFUNC" word
>  local -a matched_words
>  integer count=${NUMERIC:-1}
>
> --- 8< ---
>
> I didn't actually try that because I'm not a vi mode user and I'm in
> a hurry :-/ but it seems like it should do the trick.  If it doesn't,
> try ${WIDGETFUNC%-match} instead.

Hm, that sets curcontext to :zle:forward-word-match (or
:zle:forward-word), which means it won't be possible to use zstyles
anymore.

The following is what I'm using:

autoload -U forward-word-match
autoload -U backward-word-match
zle -N forward-parameter forward-word-match
zle -N backward-parameter backward-word-match
zstyle ':zle:forward-parameter' word-style shell
zstyle ':zle:backward-parameter' word-style shell
bindkey -a ")" forward-parameter
bindkey -a "(" backward-parameter

> } Until then I'm going to use my own vi-delete
>
> Creating a vi-delete-match function seems like the next best thing.

That's what I meant (I think) :-).

  nikolai


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
  2006-04-22 11:04   ` Nikolai Weibull
@ 2006-04-22 18:35     ` Bart Schaefer
  2006-04-22 21:38       ` Nikolai Weibull
  0 siblings, 1 reply; 11+ messages in thread
From: Bart Schaefer @ 2006-04-22 18:35 UTC (permalink / raw)
  To: Zsh Users

On Apr 22,  1:04pm, Nikolai Weibull wrote:
}
} > +local curcontext=":zle:$WIDGETFUNC" word
} 
} Hm, that sets curcontext to :zle:forward-word-match (or
} :zle:forward-word), which means it won't be possible to use zstyles
} anymore.
} 
} The following is what I'm using:
} 
} zle -N forward-parameter forward-word-match
} zle -N backward-parameter backward-word-match

Oh, I see.  I didn't realize you meant you'd invented a completely new
widget name.  I assumed you were referring to e.g.

zle -N forward-word forward-word-match
zle -N backward-word backward-word-match

Note that you have to be careful (as you were) that the new names you
bind to {forward,backward}-word-match contain the corresponding string
"forward" or "backward", and that you always bind both of them.  If you
don't, negative values of $NUMERIC will cause errors.

} > } Until then I'm going to use my own vi-delete
} >
} > Creating a vi-delete-match function seems like the next best thing.
} 
} That's what I meant (I think) :-).

Yes, I was agreeing with you.

On further checking, however, the value of $WIDGETFUNC within the widget
called by vi-delete appears to be ".internal" which means that although
it's possible to determine *when* one of these functions has been called
from vi-delete, it's not possible to determine under which name it was
called.  So a custom vi-delete replacement appears to be required, and
perhaps we should consider adding one to the distribution.  The same is
going to be true of vi-change and any other widget that combines with a
motion widget in this way.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
  2006-04-22 18:35     ` Bart Schaefer
@ 2006-04-22 21:38       ` Nikolai Weibull
  2006-04-23  6:09         ` Bart Schaefer
  0 siblings, 1 reply; 11+ messages in thread
From: Nikolai Weibull @ 2006-04-22 21:38 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On 4/22/06, Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Apr 22,  1:04pm, Nikolai Weibull wrote:
> } > } Until then I'm going to use my own vi-delete
> } >
> } > Creating a vi-delete-match function seems like the next best thing.
> }
> } That's what I meant (I think) :-).
>
> Yes, I was agreeing with you.

Ah, :-).

> On further checking, however, the value of $WIDGETFUNC within the widget
> called by vi-delete appears to be ".internal" which means that although
> it's possible to determine *when* one of these functions has been called
> from vi-delete, it's not possible to determine under which name it was
> called.  So a custom vi-delete replacement appears to be required, and
> perhaps we should consider adding one to the distribution.  The same is
> going to be true of vi-change and any other widget that combines with a
> motion widget in this way.

I've begun writing one, but it won't work.  What I do is roughly the following:

vi-delete-match () {
  integer begin end

  local motion
  integer count=0
  read -k 1 motion
  while [[ $motion == [[:digit:]] ]]; do
    (( count = count * 10 + motion ))
    read -k 1 motion
  done
  (( count = (count == 0) ? 1 : count ))
  case $motion in
    (*)
      local motion_command="${${:-$(bindkey -a $motion)}##* }"
      if [[ -n $motion_command ]]; then
        (( begin = CURSOR ))
        zle $motion_command -n $count
        (( end = CURSOR + 1 ))
        (( CURSOR = begin ))
        BUFFER="${BUFFER[1,begin]}${BUFFER[end,-1]}"
      fi
      ;;
  esac
}
zle -N vi-delete-match

bindkey -a "d" vi-delete-match

The convoluted handling of $motion is for future expansion with what
Vim refers to as text objects, i.e., "aw" for "a word", which selects
the current word you're in.

This, however, doesn't work.  $WIDGET is set to vi-delete-match, which
is the top-level widget, not the widget run by the zle command in

        zle $motion_command -n $count

I guess this makes sense in almost all cases, but not here.

$WIDGETFUNC is set to vi-delete-match, which is correct, given the
value of $WIDGET.

I'm positive that there's a way to do this, but I can't see it, so any
help is welcome.

I'm sure it'll break all kinds of stuff, but one solution would be to
have getvirange() set bindk to k2 once it has been read and checked.

Also, it would be great if we had a switch for bindkey that made it
print the widgets name, nothing else.

  nikolai


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
  2006-04-22 21:38       ` Nikolai Weibull
@ 2006-04-23  6:09         ` Bart Schaefer
       [not found]           ` <dbfc82860604230157h52f91585ncfd5a984a1a08c67@mail.gmail.com>
  0 siblings, 1 reply; 11+ messages in thread
From: Bart Schaefer @ 2006-04-23  6:09 UTC (permalink / raw)
  To: Zsh Users

On Apr 22, 11:38pm, Nikolai Weibull wrote:
}
} I'm positive that there's a way to do this, but I can't see it, so any
} help is welcome.

In the short term, I think it'd work to reset $WIDGET yourself:

    local WIDGET=$motion_command
    zle $motion_command -n $count

} I'm sure it'll break all kinds of stuff, but one solution would be to
} have getvirange() set bindk to k2 once it has been read and checked.

I don't think that's sufficient.  getvirange() would have to fiddle with
saving and restoring some other state around the call to execzlefunc().

} Also, it would be great if we had a switch for bindkey that made it
} print the widgets name, nothing else.

It' be better if we had a $bindings associative array to go with $keymaps
and $widgets, and a zle function along the lines of recursive-edit except
it reads only one binding.  For example, it's rather messy to reimplement
describe-key-briefly in the shell:

  describe-key-briefly() {
    setopt localoptions extendedglob
    local -a bound rebound
    local b f=__-get-widget-name
    bindkey -N __ $KEYMAP
    bound=( ${${(f)"$(bindkey -M __ -L)"}/(#b)([^[:space:]]#)(#e)/__-$match} )
    rebound=( ${(u)bound##* } )
    function $f {
      zle -M "${(V)KEYS} is ${WIDGET#__-}"
      zle .accept-line	# end recursive-edit
    }
    for b in $rebound
    do
      zle -N $b $f
    done
    eval "${(j:;:)bound}"
    # Cf. read-from-minibuffer if you insist on having
    # correct cursor placement during this prompt
    zle -M "Describe key briefly: "
    zle .recursive-edit -K __
  }

This may suggest another way to implement vi-delete-match, though.  Hmm.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
       [not found]           ` <dbfc82860604230157h52f91585ncfd5a984a1a08c67@mail.gmail.com>
@ 2006-04-23 15:53             ` Bart Schaefer
  2006-04-23 16:13               ` Nikolai Weibull
  2006-04-23 23:08               ` Peter Stephenson
  0 siblings, 2 replies; 11+ messages in thread
From: Bart Schaefer @ 2006-04-23 15:53 UTC (permalink / raw)
  To: zsh-users

On Apr 23, 10:57am, Nikolai Weibull wrote:
} Subject: Re: Problem with motion commands defined using match-word-by-styl
}
} > In the short term, I think it'd work to reset $WIDGET yourself:
} >
} >     local WIDGET=$motion_command
} >     zle $motion_command -n $count
} 
} WIDGET is, sadly, a read-only variable.

Declaring it "local" should circumvent that.  You might need "local -h",
now that I think of it.

} I fear my time would be
} better spent implementing .recursive-edit-read-one-key.

There must be a better name for it than that.  GNU emacs appears to call
it read-key-sequence.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
  2006-04-23 15:53             ` Bart Schaefer
@ 2006-04-23 16:13               ` Nikolai Weibull
  2006-04-23 23:08               ` Peter Stephenson
  1 sibling, 0 replies; 11+ messages in thread
From: Nikolai Weibull @ 2006-04-23 16:13 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users

On 4/23/06, Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Apr 23, 10:57am, Nikolai Weibull wrote:
> } WIDGET is, sadly, a read-only variable.
>
> Declaring it "local" should circumvent that.  You might need "local -h",
> now that I think of it.

Doesn't help.

> } I fear my time would be
> } better spent implementing .recursive-edit-read-one-key.
>
> There must be a better name for it than that.  GNU emacs appears to call
> it read-key-sequence.
>

Definitely better :-).

  nikolai


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
  2006-04-23 15:53             ` Bart Schaefer
  2006-04-23 16:13               ` Nikolai Weibull
@ 2006-04-23 23:08               ` Peter Stephenson
  2006-04-24 19:39                 ` Nikolai Weibull
  1 sibling, 1 reply; 11+ messages in thread
From: Peter Stephenson @ 2006-04-23 23:08 UTC (permalink / raw)
  To: zsh-users

Bart Schaefer wrote:
> } I fear my time would be
> } better spent implementing .recursive-edit-read-one-key.
> 
> There must be a better name for it than that.  GNU emacs appears to call
> it read-key-sequence.

Here's a simple internal widget that reads a key sequence and sets
REPLY to the command bound to it (so you can run zle on that).  The key
sequence reading is just like normal operation, so you can even use M-x.
I think this is better than reading just the key sequence, but no doubt
you'll let me know if this doesn't do the job.  It's so easy to
implement I'll commit it anyway.  (I called it read-command because a
command is what you get back, but pedantically it ought to be something
like read-key-sequence-and-return-command; that didn't seem very memorable.)

You need to use it something like:

  local REPLY
  
  if zle read-command && [[ $REPLY != undefined-key ]]; then
      zle $REPLY
      zle -M "I just executed $REPLY!"
  else
      zle -M "No such command"
  fi

Index: Doc/Zsh/zle.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/zle.yo,v
retrieving revision 1.51
diff -u -r1.51 zle.yo
--- Doc/Zsh/zle.yo	21 Mar 2006 19:19:15 -0000	1.51
+++ Doc/Zsh/zle.yo	23 Apr 2006 23:06:56 -0000
@@ -103,6 +103,12 @@
 detect loops the process will be stopped if there are twenty such replacements
 without a real command being read.
 
+A key sequence typed by the user can be turned into a command name for use
+in user-defined widgets with the tt(read-command) widget, described
+ifzman(below)\
+ifnzman(in noderef(Miscellaneous) below)\
+.
+
 texinode(Zle Builtins)(Zle Widgets)(Keymaps)(Zsh Line Editor)
 sect(Zle Builtins)
 cindex(zle, builtin commands)
@@ -1767,6 +1773,16 @@
 construct into the editor buffer.
 The latter is equivalent to tt(push-input) followed by tt(get-line).
 )
+tindex(read-command)
+item(tt(read-command))(
+Only useful from a user-defined widget.  A keystroke is read just as in
+normal operation, but instead of the command being executed the name
+of the command that would be executed is stored in the shell parameter
+tt(REPLY).  This can be used as the argument of a future tt(zle)
+command.  If the key sequence is not bound, status 1 is returned;
+typically, however, tt(REPLY) is set to tt(undefined-key) to indicate
+a useless key sequence.
+)
 tindex(recursive-edit)
 item(tt(recursive-edit))(
 Only useful from a user-defined widget.  At this point in the function,
Index: Src/Zle/iwidgets.list
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/iwidgets.list,v
retrieving revision 1.8
diff -u -r1.8 iwidgets.list
--- Src/Zle/iwidgets.list	24 Nov 2005 10:25:34 -0000	1.8
+++ Src/Zle/iwidgets.list	23 Apr 2006 23:06:56 -0000
@@ -86,6 +86,7 @@
 "quoted-insert", quotedinsert, ZLE_MENUCMP | ZLE_KEEPSUFFIX
 "quote-line", quoteline, 0
 "quote-region", quoteregion, 0
+"read-command", readcommand, 0
 "recursive-edit", recursiveedit, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
 "redisplay", redisplay, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
 "redo", redo, ZLE_KEEPSUFFIX
Index: Src/Zle/zle_keymap.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_keymap.c,v
retrieving revision 1.24
diff -u -r1.24 zle_keymap.c
--- Src/Zle/zle_keymap.c	28 Jan 2006 15:02:26 -0000	1.24
+++ Src/Zle/zle_keymap.c	23 Apr 2006 23:06:57 -0000
@@ -1441,3 +1441,16 @@
 	return;
     linkkeymap(km, "main", 0);
 }
+
+/**/
+mod_export int
+readcommand(UNUSED(char **args))
+{
+    Thingy thingy = getkeycmd();
+
+    if (!thingy)
+	return 1;
+
+    setsparam("REPLY", ztrdup(thingy->nam));
+    return 0;
+}

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page still at http://www.pwstephenson.fsnet.co.uk/


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
  2006-04-23 23:08               ` Peter Stephenson
@ 2006-04-24 19:39                 ` Nikolai Weibull
  2006-04-25  3:06                   ` Bart Schaefer
  0 siblings, 1 reply; 11+ messages in thread
From: Nikolai Weibull @ 2006-04-24 19:39 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-users

On 4/24/06, Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> Bart Schaefer wrote:
> > } I fear my time would be
> > } better spent implementing .recursive-edit-read-one-key.
> >
> > There must be a better name for it than that.  GNU emacs appears to call
> > it read-key-sequence.
>
> Here's a simple internal widget that reads a key sequence and sets
> REPLY to the command bound to it (so you can run zle on that).

Seems to work just fine.  It does, however, only solve part of the
problem.  There's still no easy way to execute the command in the
right environment so that WIDGET is set to the read command that we
want to execute.

  nikolai


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Problem with motion commands defined using match-word-by-style used with vi-delete
  2006-04-24 19:39                 ` Nikolai Weibull
@ 2006-04-25  3:06                   ` Bart Schaefer
  0 siblings, 0 replies; 11+ messages in thread
From: Bart Schaefer @ 2006-04-25  3:06 UTC (permalink / raw)
  To: zsh-users

On Apr 24,  9:39pm, Nikolai Weibull wrote:
} Subject: Re: Problem with motion commands defined using match-word-by-styl
}
} On 4/24/06, Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
} >
} > Here's a simple internal widget that reads a key sequence and sets
} > REPLY to the command bound to it (so you can run zle on that).

[Hmm, somehow I managed to miss PWS's message.  I wonder if it was a
victim of Verizon's latest overeager spam-blocking fiasco.]

This is actually quite useful as it resets KEYS as well as sets REPLY,
so with this you can do

    describe-key-briefly() {
      zle -R "Describe key briefly: "
      zle read-command
      zle -M "${(V)KEYS} is $REPLY"
    }

That doesn't help with describe-binding, which needs to map in the
other direction, but it's a start.

Incidentally I just noticed that within a widget called by using
execute-named-command, the value of $KEYS is carriage return.  I'm not
sure what I expected it to be, but that wasn't it.

} There's still no easy way to execute the command in the right
} environment so that WIDGET is set to the read command that we want to
} execute.

It really *should* be the case that

    local -h WIDGET

creates a new parameter named WIDGET that is neither read-only nor
special, but apparently the usual parameter rules don't apply to the
ZLE specials.


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2006-04-25  3:06 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-21 23:10 Problem with motion commands defined using match-word-by-style used with vi-delete Nikolai Weibull
2006-04-22  5:00 ` Bart Schaefer
2006-04-22 11:04   ` Nikolai Weibull
2006-04-22 18:35     ` Bart Schaefer
2006-04-22 21:38       ` Nikolai Weibull
2006-04-23  6:09         ` Bart Schaefer
     [not found]           ` <dbfc82860604230157h52f91585ncfd5a984a1a08c67@mail.gmail.com>
2006-04-23 15:53             ` Bart Schaefer
2006-04-23 16:13               ` Nikolai Weibull
2006-04-23 23:08               ` Peter Stephenson
2006-04-24 19:39                 ` Nikolai Weibull
2006-04-25  3:06                   ` Bart Schaefer

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).