* ZLE Widget: Insert last word (except &)
[not found] <20000711140506.5143gmx1@mx14.gmx.net>
@ 2000-07-11 17:29 ` Christoph Lange
2000-07-11 22:05 ` Vincent Lefevre
2000-07-12 8:26 ` Bart Schaefer
0 siblings, 2 replies; 8+ messages in thread
From: Christoph Lange @ 2000-07-11 17:29 UTC (permalink / raw)
To: zsh-users
Hi there,
I found it annoying that the widget insert-last-word inserts `&' if the
previous command was a background job. I'd rather like the last word
*before* `&' to be inserted. So I wrote a custom widget:
smart-insert-last-word() {
emulate -L zsh
setopt extendedglob
if [[ -n "$NUMERIC" ]]
then
zle insert-last-word -n $NUMERIC
else
lastcmd=`fc -n -l -1`
lastcmd=${lastcmd%%[[:space:]]#}
if [[ $lastcmd[$#lastcmd] == '&' && $lastcmd[$#lastcmd-1] != '\' ]]
then
zle insert-last-word -n 2
else
zle insert-last-word
fi
fi
}
zle -N smart-insert-last-word
bindkey "^[." smart-insert-last-word
bindkey "^[_" smart-insert-last-word
If any numeric argument is given, the original function is called with
that argument. Otherwise, the previous command ist determined. If it
ends with `&', insert-last-word is invoked with an argument of 2,
which inserts the last but one word.
Example:
% myeditor *.txt &
% cp _ # press [Alt+.], _ is the cursor
% cp *.txt_ # result
Hope you find it useful.
Christoph
--
o o o o o <o <o> o> o
.|. \|. \|/ // X \ | <| <|>
/\ >\ /< >\ /< >\ /< >\ /<
Mr. Asciihead learns the Macarena
Christoph Lange, langec@gmx.de, http://www.cul.de/home/yaph/, ICQ #51191833
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ZLE Widget: Insert last word (except &)
2000-07-11 17:29 ` ZLE Widget: Insert last word (except &) Christoph Lange
@ 2000-07-11 22:05 ` Vincent Lefevre
2000-07-11 23:04 ` Bart Schaefer
2000-07-12 8:26 ` Bart Schaefer
1 sibling, 1 reply; 8+ messages in thread
From: Vincent Lefevre @ 2000-07-11 22:05 UTC (permalink / raw)
To: zsh-users
On Tue, Jul 11, 2000 at 19:29:55 +0200, Christoph Lange wrote:
> I found it annoying that the widget insert-last-word inserts `&' if the
> previous command was a background job. I'd rather like the last word
> *before* `&' to be inserted.
Me too!
> So I wrote a custom widget:
[snip]
IMHO, this behavior should be in zsh as standard.
--
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/> - 100%
validated HTML - Acorn Risc PC, Yellow Pig 17, Championnat International des
Jeux Mathématiques et Logiques, TETRHEX, etc.
Computer science / computer arithmetic / Arénaire project at LIP, ENS-Lyon
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ZLE Widget: Insert last word (except &)
2000-07-11 22:05 ` Vincent Lefevre
@ 2000-07-11 23:04 ` Bart Schaefer
0 siblings, 0 replies; 8+ messages in thread
From: Bart Schaefer @ 2000-07-11 23:04 UTC (permalink / raw)
To: zsh-users
On Jul 12, 12:05am, Vincent Lefevre wrote:
} Subject: Re: ZLE Widget: Insert last word (except &)
}
} On Tue, Jul 11, 2000 at 19:29:55 +0200, Christoph Lange wrote:
} > I found it annoying that the widget insert-last-word inserts `&' if the
} > previous command was a background job. I'd rather like the last word
} > *before* `&' to be inserted.
}
} Me too!
Presumably what you'd really rather is that the last non-separator word
is inserted. Even with Christoph's widget, if you type "echo foo;" and
then invoke smart-insert-last-word you get ";" inserted.
} IMHO, this behavior should be in zsh as standard.
But there's more; "echo foo 2>&1" followed by {smart-,}insert-last-word
inserts "1", and prefixing it with ESC 2 inserts "2>&".
Or "(echo foo)", where the last word is ")". What about "{ echo foo; }"
or the same suffixed with a redirection (inside or outside the braces)?
If we don't accept the shell syntax definition of a "word", how can we
choose a single definition of what constitutes a "word" that everyone
will agree on?
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ZLE Widget: Insert last word (except &)
2000-07-11 17:29 ` ZLE Widget: Insert last word (except &) Christoph Lange
2000-07-11 22:05 ` Vincent Lefevre
@ 2000-07-12 8:26 ` Bart Schaefer
2000-07-12 16:38 ` Christoph Lange
1 sibling, 1 reply; 8+ messages in thread
From: Bart Schaefer @ 2000-07-12 8:26 UTC (permalink / raw)
To: zsh-users
I wrote:
} If we don't accept the shell syntax definition of a "word", how can we
} choose a single definition of what constitutes a "word" that everyone
} will agree on?
The answer is, we don't, we use a style. Which isn't (presently) ever done
with the builtin widgets, so you aren't going to see this as the default
behavior of insert-last-word any time soon.
---- 8< ---- cut ---- 8< ----
# smart-insert-last-word
# Inspired by Christoph Lange <langec@gmx.de> from zsh-users/3265.
#
# This function as a ZLE widget can replace insert-last-word, like so:
#
# zle -N insert-last-word smart-insert-last-word
#
# With a numeric prefix, simply calls .insert-last-word, which is also the
# fall-through case in the event that "smart" word selection fails.
#
# Otherwise, the rightmost "interesting" word from the previous command is
# found and inserted. The default definition of "interesting" is that the
# word contains at least one alphabetic character, slash, or backslash.
# This definition can be overridden by use of a style like so:
#
# zstyle :insert-last-word match '*[[:alpha:]/\\]*'
#
# For example, you might want to include words that contain spaces:
#
# zstyle :insert-last-word match '*[[:alpha:][:space:]/\\]*'
#
# Or include numbers as long as the word is at least two characters long:
#
# zstyle :insert-last-word match '*([[:digit:]]?|[[:alpha:]/\\])*'
#
# That causes redirections like "2>" to be included.
#
# Note also that the style is looked up based on the widget name, so you
# can bind this function to different widgets to use different patterns:
#
# zle -N insert-last-assignment smart-insert-last-word
# zstyle :insert-last-assignment match '[[:alpha:]][][[:alnum:]]#=*'
# bindkey '\e=' insert-last-assignment
#
# (The above is a contrived example since it works only if the previous
# command line included an assignment, but you get the idea.)
if [[ -z "$NUMERIC" ]]
then
emulate -L zsh
setopt extendedglob
local lastcmd pattern
integer cursor=$CURSOR # Remember cursor position
zle up-history || return 1 # Retrieve previous command
lastcmd=( ${(z)BUFFER} ) # Split into shell words
zle down-history # Return to current command
CURSOR=$cursor # Restore cursor position
integer i=$#lastcmd
zstyle -s :$WIDGET match pattern ||
pattern='*[[:alpha:]/\\]*'
while ((i)); do
if [[ $lastcmd[i] == $~pattern ]]; then
LBUFFER="$LBUFFER$lastcmd[i]"
return 0
else
((--i))
fi
done
fi
zle .insert-last-word
---- 8< ---- cut ---- 8< ----
Note that this presently doesn't work right when the previous command line
contains a [[ ... ]] expression that uses one of the (#x) forms of extended
pattern matching, e.g. (#i) to ignore case. That's a bug in ${(z)...} (it
takes the # to be a comment introducer), so it should be fixed soon. If
this really bothers you in the meantime, try adding
local +h histchars=''
somewhere before the assignment to lastcmd -- but then it's broken for the
case of `setopt interactive_comments`, so choose your poison ...
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ZLE Widget: Insert last word (except &)
2000-07-12 8:26 ` Bart Schaefer
@ 2000-07-12 16:38 ` Christoph Lange
2000-07-12 18:54 ` Bart Schaefer
0 siblings, 1 reply; 8+ messages in thread
From: Christoph Lange @ 2000-07-12 16:38 UTC (permalink / raw)
To: Bart Schaefer; +Cc: zsh-users
> I wrote:
> } If we don't accept the shell syntax definition of a "word", how can we
> } choose a single definition of what constitutes a "word" that everyone
> } will agree on?
>
> The answer is, we don't, we use a style. Which isn't (presently) ever done
> with the builtin widgets, so you aren't going to see this as the default
> behavior of insert-last-word any time soon.
>
> ---- 8< ---- cut ---- 8< ----
> # smart-insert-last-word
>
> [...]
>
> Note that this presently doesn't work right when the previous command line
> contains a [[ ... ]] expression that uses one of the (#x) forms of extended
> pattern matching, e.g. (#i) to ignore case. That's a bug in ${(z)...} (it
> takes the # to be a comment introducer), so it should be fixed soon. If
> this really bothers you in the meantime, try adding
>
> local +h histchars=''
>
> somewhere before the assignment to lastcmd -- but then it's broken for the
> case of `setopt interactive_comments`, so choose your poison ...
There is another bug in your version of smart-insert-last-word: repeated
calls to it don't go back in the history. Rather than doing the word
splitting yourself, you should always call insert-last-word -- with an
argument of 2 or greater, when necessary.
The solution might be a synthesis of my first version and yours -- a widget
that is smarter than mine when determining the last word, but nevertheless
calls insert-last-word, so that the shell can go back the history on
subsequent calls.
Christoph
--
Descartes enters a pub. "Evening, Descartes. Same as usual?"
Descartes says: "No, I think not." -- and disappears.
Christoph Lange, langec@gmx.de, http://www.cul.de/home/yaph/, ICQ #51191833
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ZLE Widget: Insert last word (except &)
2000-07-12 16:38 ` Christoph Lange
@ 2000-07-12 18:54 ` Bart Schaefer
2000-07-12 21:18 ` Christoph Lange
0 siblings, 1 reply; 8+ messages in thread
From: Bart Schaefer @ 2000-07-12 18:54 UTC (permalink / raw)
To: Christoph Lange; +Cc: zsh-users
On Jul 12, 6:38pm, Christoph Lange wrote:
} Subject: Re: ZLE Widget: Insert last word (except &)
}
} There is another bug in your version of smart-insert-last-word: repeated
} calls to it don't go back in the history.
Oops, I forgot about that behavior.
} Rather than doing the word
} splitting yourself, you should always call insert-last-word
Nah.
The fiddling with NUMERIC below serves two purposes: One, it passes the
same value to both up-history and down-history without having to pass an
argument to each. Two, `zle WIDGET -n NUM' is broken for NUM > 9.
---- 8< ---- cut ---- 8< ----
# smart-insert-last-word
# Inspired by Christoph Lange <langec@gmx.de> from zsh-users/3265;
# rewritten to correct multiple-call behavior after zsh-users/3270.
#
# This function as a ZLE widget can replace insert-last-word, like so:
#
# zle -N insert-last-word smart-insert-last-word
#
# With a numeric prefix, behaves like insert-last-word, except that words
# in comments are ignored when interactive_comments is set.
#
# Otherwise, the rightmost "interesting" word from the previous command is
# found and inserted. The default definition of "interesting" is that the
# word contains at least one alphabetic character, slash, or backslash.
# This definition can be overridden by use of a style like so:
#
# zstyle :insert-last-word match '*[[:alpha:]/\\]*'
#
# For example, you might want to include words that contain spaces:
#
# zstyle :insert-last-word match '*[[:alpha:][:space:]/\\]*'
#
# Or include numbers as long as the word is at least two characters long:
#
# zstyle :insert-last-word match '*([[:digit:]]?|[[:alpha:]/\\])*'
#
# That causes redirections like "2>" to be included.
#
# Note also that the style is looked up based on the widget name, so you
# can bind this function to different widgets to use different patterns:
#
# zle -N insert-last-assignment smart-insert-last-word
# zstyle :insert-last-assignment match '[[:alpha:]][][[:alnum:]]#=*'
# bindkey '\e=' insert-last-assignment
emulate -L zsh
setopt extendedglob
# Not strictly necessary:
# (($+_ilw_hist)) || integer -g _ilw_hist _ilw_count _ilw_cursor _ilw_lcursor
integer cursor=$CURSOR lcursor=$CURSOR
local lastcmd pattern numeric=$NUMERIC
# Save state for repeated calls
if (( HISTNO == _ilw_hist && cursor == _ilw_cursor )); then
NUMERIC=$[_ilw_count+1]
lcursor=$_ilw_lcursor
else
NUMERIC=1
_ilw_lcursor=$lcursor
fi
_ilw_hist=$HISTNO
_ilw_count=$NUMERIC
zle up-history || return 1 # Retrieve previous command
lastcmd=( ${(z)BUFFER} ) # Split into shell words
zle down-history # Return to current command
CURSOR=$cursor # Restore cursor position
NUMERIC=${numeric:-1} # In case of fall through
(( NUMERIC > $#lastcmd )) && return 1
if [[ -z "$numeric" ]]
then
integer i=1
zstyle -s :$WIDGET match pattern ||
pattern='*[[:alpha:]/\\]*'
while ((i <= $#lastcmd)); do
if [[ $lastcmd[-i] == $~pattern ]]; then
NUMERIC=$i
break
else
((--i))
fi
done
fi
LBUFFER[lcursor+1,cursor+1]=$lastcmd[-NUMERIC]
_ilw_cursor=$CURSOR
---- 8< ---- cut ---- 8< ----
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ZLE Widget: Insert last word (except &)
2000-07-12 18:54 ` Bart Schaefer
@ 2000-07-12 21:18 ` Christoph Lange
2000-07-12 22:33 ` Bart Schaefer
0 siblings, 1 reply; 8+ messages in thread
From: Christoph Lange @ 2000-07-12 21:18 UTC (permalink / raw)
To: Bart Schaefer; +Cc: zsh-users
On Wed, 12 Jul 2000, Bart Schaefer wrote:
> On Jul 12, 6:38pm, Christoph Lange wrote:
> } Subject: Re: ZLE Widget: Insert last word (except &)
> }
> } There is another bug in your version of smart-insert-last-word: repeated
> } calls to it don't go back in the history.
>
> Oops, I forgot about that behavior.
>
> } Rather than doing the word
> } splitting yourself, you should always call insert-last-word
>
> Nah.
>
> The fiddling with NUMERIC below serves two purposes: One, it passes the
> same value to both up-history and down-history without having to pass an
> argument to each. Two, `zle WIDGET -n NUM' is broken for NUM > 9.
>
> ---- 8< ---- cut ---- 8< ----
> # smart-insert-last-word
>
> [...]
I didn't understand all of it, but now the functions even fails doing
elementar things:
% echo a &
a
% echo
^ [Alt+.] pressed
I found out another interesting thing about my first version. zsh goes up in
the history on subsequent calls of insert-last-word, but from the widget's
point of view, the position in the history remains the same. Either
determining the previous line with `fc -n -l -1' or -- like in your widget
-- going up the history and reading from $BUFFER always returns the previous
line relative from the position where the user started calling
insert-last-word. Just look at the following result:
% echo 1
% echo 1&
% [[Subsequent invocations of insert-last-word:]]
1. `1'
2. `echo'
lastcmd always contains `echo 1&', regardless of the shell going up the
history. Thus, the last but one word is inserted into the command line.
What to do?
Christoph
--
Q: After bootup, a linux machine hangs, showing the error
message `login:'. How can I fix this?
A: This system hang is a big enough problem to justify
replacing Linux with Windows 2000.
Christoph Lange, langec@gmx.de, http://www.cul.de/home/yaph/, ICQ #51191833
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ZLE Widget: Insert last word (except &)
2000-07-12 21:18 ` Christoph Lange
@ 2000-07-12 22:33 ` Bart Schaefer
0 siblings, 0 replies; 8+ messages in thread
From: Bart Schaefer @ 2000-07-12 22:33 UTC (permalink / raw)
To: Christoph Lange; +Cc: zsh-users
On Wed, 12 Jul 2000, Christoph Lange wrote:
> I didn't understand all of it, but now the functions even fails doing
> elementar things:
>
> % echo a &
> a
> % echo
> ^ [Alt+.] pressed
Oops; I tried to edit a cut'n'paste screwup in place, and accidentally
re-inserted a line from the old version. Change ((--i)) to ((++i)) in the
`else' inside the `while' loop. Sorry about that.
> I found out another interesting thing about my first version. zsh goes up in
> the history on subsequent calls of insert-last-word, but from the widget's
> point of view, the position in the history remains the same. Either
> determining the previous line with `fc -n -l -1' or -- like in your widget
> -- going up the history and reading from $BUFFER always returns the previous
> line relative from the position where the user started calling
> insert-last-word.
That's why I had to the goofy bit with ((NUMERIC=_ilw_count+1)) in my
revised version. That makes up-history go up the correct number of lines,
and down-history go back down the correct number.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2000-07-12 22:33 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20000711140506.5143gmx1@mx14.gmx.net>
2000-07-11 17:29 ` ZLE Widget: Insert last word (except &) Christoph Lange
2000-07-11 22:05 ` Vincent Lefevre
2000-07-11 23:04 ` Bart Schaefer
2000-07-12 8:26 ` Bart Schaefer
2000-07-12 16:38 ` Christoph Lange
2000-07-12 18:54 ` Bart Schaefer
2000-07-12 21:18 ` Christoph Lange
2000-07-12 22:33 ` 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).