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

Re: Strange behavior when calling select-a-shell-word multiple times from the same user-defined widget



[ -workers@: see at the end ]

Daniel Parks wrote on Wed, 22 Dec 2021 21:20 +00:00:
> I'm trying to write a function that selects the nth argument in the
> buffer. I would use it like `3gva` to select the 3rd argument.
>
> Here's the widget I have so far:
>
> function select-n-shell-word {
> 	if [[ -z "$NUMERIC" ]]; then NUMERIC=1; fi
> 	zle vi-beginning-of-line
> 	zle visual-mode
> 	zle select-a-shell-word
> 	for ((i = 1; i < $NUMERIC; i = i + 1)); do
> 		zle deactivate-region
> 		zle vi-forward-char -n 2
> 		zle visual-mode
> 		zle select-a-shell-word
> 	done
> }
> zle -N select-n-shell-word
> bindkey -M vicmd "gva" select-n-shell-word
>

Adding «-N» to both select-a-shell-word calls does the trick.

While here, you can simplify the function a bit.  For one, you could use
a «repeat» loop — its repeat count is a math expression, so you can
actually do «repeat "NUMERIC - 1"; do …; done» — but I'm not sure why you
select-a-shell-word more than once.  Why not just this:

select-n-shell-word() {
  CURSOR=0
  repeat "${NUMERIC:-1} - 1" zle vi-forward-word
  zle visual-mode
  zle select-a-shell-word -N
}

«CURSOR=0» is not equivalent to «zle vi-beginning-of-line» when there's
a literal newline in $BUFFER.  Pick what you prefer.

Using «repeat» rather than «zle … -n» to handle the case (( NUMERIC == 1 ))
correctly.

>

Aside: «repeat 'foo+1'» works, but «repeat '$foo+1'» (with single quotes) errors:
.
    zsh: bad math expression: operator expected at `foo + 1'
.
So, apparently, the repeat count word does not undergo parameter
interpolation before being parsed as a math expression, the way
«$((…))» expansions do.  [To see the last bit, try «s='1+1'; echo $((s*2)) $(($s*2))».]




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