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