* About insert-last-word and "command args | less" @ 2006-10-14 11:56 Vincent Lefevre 2006-10-14 21:27 ` Bart Schaefer 0 siblings, 1 reply; 12+ messages in thread From: Vincent Lefevre @ 2006-10-14 11:56 UTC (permalink / raw) To: zsh-users Hi, I often do something like svn log file | m (where m is an alias for less). But when I use insert-last-word, I get the "m" instead of "file". Is there a way to ignore the one-character words? Alternatively, is there a way to make svn log file | behave a bit like "< file", i.e. using READNULLCMD instead of getting another prompt (and use "... | \" to get the prompt)? -- Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/> Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: About insert-last-word and "command args | less" 2006-10-14 11:56 About insert-last-word and "command args | less" Vincent Lefevre @ 2006-10-14 21:27 ` Bart Schaefer 2006-10-15 0:50 ` Vincent Lefevre 0 siblings, 1 reply; 12+ messages in thread From: Bart Schaefer @ 2006-10-14 21:27 UTC (permalink / raw) To: zsh-users On Oct 14, 1:56pm, Vincent Lefevre wrote: } } I often do something like } } svn log file | m } } (where m is an alias for less). But when I use insert-last-word, I get } the "m" instead of "file". Is there a way to ignore the one-character } words? Use smart-insert-last-word. autoload -U smart-insert-last-word zle -N insert-last-word smart-insert-last-word zstyle :insert-last-word match '*[[:alnum:]]*[[:alnum:]]*' That example says that a word must contain at least two alphanumeric characters, so neither 'm' nor '|' qualifies and "file" is inserted. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: About insert-last-word and "command args | less" 2006-10-14 21:27 ` Bart Schaefer @ 2006-10-15 0:50 ` Vincent Lefevre 2006-10-15 4:04 ` Bart Schaefer 0 siblings, 1 reply; 12+ messages in thread From: Vincent Lefevre @ 2006-10-15 0:50 UTC (permalink / raw) To: zsh-users On 2006-10-14 14:27:41 -0700, Bart Schaefer wrote: > Use smart-insert-last-word. > > autoload -U smart-insert-last-word > zle -N insert-last-word smart-insert-last-word > zstyle :insert-last-word match '*[[:alnum:]]*[[:alnum:]]*' > > That example says that a word must contain at least two alphanumeric > characters, so neither 'm' nor '|' qualifies and "file" is inserted. Thanks, but this is buggy with setopt HIST_IGNORE_DUPS: prunille:~> zsh -f prunille% setopt HIST_IGNORE_DUPS prunille% autoload -U smart-insert-last-word prunille% zle -N insert-last-word smart-insert-last-word prunille% zstyle :insert-last-word match '*[[:alnum:]]*[[:alnum:]]*' prunille% true prunille% : prunille% echo | : prunille% true prunille% : true prunille% On this new line, I start by typing ^]_ and I get "true" as expected, but on the second ^]_ I get "echoue" with the cursor over the "u". -- Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/> Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: About insert-last-word and "command args | less" 2006-10-15 0:50 ` Vincent Lefevre @ 2006-10-15 4:04 ` Bart Schaefer 2006-10-15 10:39 ` Vincent Lefevre 2006-10-15 15:58 ` smart-insert-last-word bugs Vincent Lefevre 0 siblings, 2 replies; 12+ messages in thread From: Bart Schaefer @ 2006-10-15 4:04 UTC (permalink / raw) To: zsh-users On Oct 15, 2:50am, Vincent Lefevre wrote: } } Thanks, but this is buggy with setopt HIST_IGNORE_DUPS: Hrm. It's not *just* HIST_IGNORE_DUPS, because it works fine as long as you're not inserting the word in command position. In fact, it works fine as long as $BUFFER is not empty when you begin using it. This implies that the bug is in one of up-history or down-history. smart-insert-last-word sets NUMERIC and assumes that thereafter a call to .up-history followed by one to .down-history will return the editor to the current line. This appears not to work when $BUFFER starts out empty and there are duplicate history items to skip. The simple workaround is to change setopt extendedglob to setopt extendedglob nohistignoredups in smart-insert-last-word, on the second line. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: About insert-last-word and "command args | less" 2006-10-15 4:04 ` Bart Schaefer @ 2006-10-15 10:39 ` Vincent Lefevre 2006-10-15 18:30 ` Bart Schaefer 2006-10-15 18:49 ` Bart Schaefer 2006-10-15 15:58 ` smart-insert-last-word bugs Vincent Lefevre 1 sibling, 2 replies; 12+ messages in thread From: Vincent Lefevre @ 2006-10-15 10:39 UTC (permalink / raw) To: zsh-users On 2006-10-14 21:04:51 -0700, Bart Schaefer wrote: > The simple workaround is to change > > setopt extendedglob > > to > > setopt extendedglob nohistignoredups > > in smart-insert-last-word, on the second line. OK. But is it possible * to skip a history line when all its words match the pattern? * to always get a word that wasn't proposed before (when one uses ^]_ several times) by skipping history lines when needed? -- Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/> Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: About insert-last-word and "command args | less" 2006-10-15 10:39 ` Vincent Lefevre @ 2006-10-15 18:30 ` Bart Schaefer 2006-10-15 18:49 ` Bart Schaefer 1 sibling, 0 replies; 12+ messages in thread From: Bart Schaefer @ 2006-10-15 18:30 UTC (permalink / raw) To: zsh-users On Oct 15, 12:39pm, Vincent Lefevre wrote: } } OK. But is it possible } * to skip a history line when all its words match the pattern? This is difficult because of handling a numeric argument, e.g. when called as "zle smart-insert-last-word 7" [%] it's supposed to back up exactly 7 commands and take the last word from that one. The pattern is not matched against the words until after the history line to examine is chosen. I believe the patch below does this the way you want ... however, it makes a liar of the documentation, which implies that line-selection takes precedence over interesting-word-selection; so it's not suitable to be committed without some more work. [%] As contrasted with "zle smart-insert-last-word -n 7" which is supposed to select the 7th-from-last word of the previous command. } * to always get a word that wasn't proposed before (when one uses } ^]_ several times) by skipping history lines when needed? That would require both that we solve the previous problem *and* store somewhere all previous words that have been offered *and* do some kind of negated match (e.g., the $lastcmd[(I)$pattern] change in the patch below would have to be made back into a loop with two comparisons on every word). Index: smart-insert-last-word =================================================================== diff -c -r1.2 smart-insert-last-word --- smart-insert-last-word 15 Mar 2003 17:43:15 -0000 1.2 +++ smart-insert-last-word 15 Oct 2006 18:16:30 -0000 @@ -35,7 +35,7 @@ # bindkey '\e=' insert-last-assignment emulate -L zsh -setopt extendedglob +setopt extendedglob nohistignoredups # Not strictly necessary: # (($+_ilw_hist)) || integer -g _ilw_hist _ilw_count _ilw_cursor _ilw_lcursor @@ -64,27 +64,34 @@ _ilw_hist=$HISTNO _ilw_count=$NUMERIC +if [[ -z "$numeric" ]] +then + zstyle -s :$WIDGET match pattern || + pattern='*[[:alpha:]/\\]*' +fi + zle .up-history || return 1 # Retrieve previous command lastcmd=( ${${(z)BUFFER}:#\;} ) # Split into shell words +if [[ -n "$pattern" ]] +then + integer n=0 found=$lastcmd[(I)$pattern] + while (( found == 0 && ++n )) + do + zle .up-history || return 1 + lastcmd=( ${${(z)BUFFER}:#\;} ) + found=$lastcmd[(I)$pattern] + done + (( found-- && ( NUMERIC += n ) )) +fi 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" ]] +if [[ -n "$pattern" ]] 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 + NUMERIC=$(( $#lastcmd - found )) fi LBUFFER[lcursor+1,cursor+1]=$lastcmd[-NUMERIC] _ilw_cursor=$CURSOR -- ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: About insert-last-word and "command args | less" 2006-10-15 10:39 ` Vincent Lefevre 2006-10-15 18:30 ` Bart Schaefer @ 2006-10-15 18:49 ` Bart Schaefer 2006-10-15 21:14 ` Vincent Lefevre 1 sibling, 1 reply; 12+ messages in thread From: Bart Schaefer @ 2006-10-15 18:49 UTC (permalink / raw) To: zsh-users On Oct 15, 12:39pm, Vincent Lefevre wrote: } } * to skip a history line when all its words match the pattern? } * to always get a word that wasn't proposed before (when one uses } ^]_ several times) by skipping history lines when needed? Maybe what you really want here is not smart-insert-last-word, but a variant of _history_complete_word that considers only the rightmost "interesting" word of each command in the history? ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: About insert-last-word and "command args | less" 2006-10-15 18:49 ` Bart Schaefer @ 2006-10-15 21:14 ` Vincent Lefevre 2006-10-16 5:26 ` Bart Schaefer 0 siblings, 1 reply; 12+ messages in thread From: Vincent Lefevre @ 2006-10-15 21:14 UTC (permalink / raw) To: zsh-users On 2006-10-15 11:49:43 -0700, Bart Schaefer wrote: > Maybe what you really want here is not smart-insert-last-word, but a > variant of _history_complete_word that considers only the rightmost > "interesting" word of each command in the history? Perhaps (not sure if smart-insert-last-word was supposed to do that). Also, I've seen another bug in smart-insert-last-word: When I recall a previous history line, e.g. with up-line-or-history or with history-incremental-search-backward, then kill the last word and use insert-last-word, instead of getting the last word of the lastest history line, I get the last word of the history line that was entered just before the recalled history line. -- Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/> Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: About insert-last-word and "command args | less" 2006-10-15 21:14 ` Vincent Lefevre @ 2006-10-16 5:26 ` Bart Schaefer 0 siblings, 0 replies; 12+ messages in thread From: Bart Schaefer @ 2006-10-16 5:26 UTC (permalink / raw) To: zsh-users On Oct 15, 11:14pm, Vincent Lefevre wrote: } Subject: Re: About insert-last-word and "command args | less" } } On 2006-10-15 11:49:43 -0700, Bart Schaefer wrote: } > Maybe what you really want here is not smart-insert-last-word, but a } > variant of _history_complete_word that considers only the rightmost } > "interesting" word of each command in the history? } } Perhaps (not sure if smart-insert-last-word was supposed to do that). Well, no, it really wasn't supposed to do that. It was supposed to find an "interesting" word if there was one, and otherwise behave just like insert-last-word. I'm not sure the behavior of continuing to search up through additional history lines is always wanted. } Also, I've seen another bug in smart-insert-last-word: When I recall } a previous history line, e.g. with up-line-or-history or with } history-incremental-search-backward, then kill the last word and use } insert-last-word, instead of getting the last word of the lastest } history line, I get the last word of the history line that was } entered just before the recalled history line. Hrm. This reveals two problems. (1) The definition of the "current" history line, where [builtin] insert-last-word begins, does not mean the line currently displayed in the editor buffer. (2) Parsing $BUFFER to find words for insertion isn't safe, because BUFFER reflects edits made to any history lines during the current zle session, but insert-last-word looks at the original unedited lines. I'm a bit annoyed by the remifications of this, namely that to emulate insert-last-word it's necessary to load the zsh/parameter module and pull lines out of the $history hash. Here's a new copy of smart-insert-last-word (the diff is only 9 lines shorter than the entire function) which attempts to address all of this. It introduces a new zstyle "auto-previous" to control the behavior that Vincent wants, and employs an "always" block and the side-effects of assignment to HISTNO to handle invocations on history lines other than the most recent. It requires my auto-suffix-retain patch; comment out that line if you want to try it with something less than the latest CVS HEAD checkout. If this looks OK, I'll commit it along with a documentation update. --- 8< --- snip --- 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; # modified to work with copy-earlier-word after zsh-users/5832. # Edited further per zsh-users/10881 and zsh-users/10884. # # 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 any 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 "auto-previous" style, if set to a true value, causes the search to # proceed upward through the history until an interesting word is found. # If auto-previous is unset or false and there is no interesting word, the # last word is returned. emulate -L zsh setopt extendedglob nohistignoredups # Begin by preserving completion suffix if any zle auto-suffix-retain # 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 # Handle the up to three arguments of .insert-last-word if (( $+1 )); then if (( $+3 )); then ((NUMERIC = -($1))) else ((NUMERIC = _ilw_count - $1)) fi (( NUMERIC )) || LBUFFER[lcursor+1,cursor+1]='' numeric=$((-(${2:--numeric}))) fi _ilw_hist=$HISTNO _ilw_count=$NUMERIC if [[ -z "$numeric" ]] then zstyle -s :$WIDGET match pattern || pattern='*[[:alpha:]/\\]*' fi # Note that we must use .up-history for navigation here because of # possible "holes" in the $history hash (the result of dup expiry). # We need $history because $BUFFER retains edits in progress as the # user moves around the history, but we search the unedited lines. { zmodload -i zsh/parameter zle .end-of-history # Start from final command zle .up-history || return 1 # Retrieve previous command local buffer=$history[$HISTNO] # Get unedited history line lastcmd=( ${${(z)buffer}:#\;} ) # Split into shell words if [[ -n "$pattern" ]] then # This is the "smart" part -- search right-to-left and # latest-to-earliest through the history for a word. integer n=0 found=$lastcmd[(I)$pattern] if zstyle -t :$WIDGET auto-previous then while (( found == 0 && ++n )) do zle .up-history || return 1 buffer=$history[$HISTNO] lastcmd=( ${${(z)buffer}:#\;} ) found=$lastcmd[(I)$pattern] done fi (( found-- > 0 && # Account for 1-based index (numeric = $#lastcmd - found) )) fi } always { HISTNO=$_ilw_hist # Return to current command CURSOR=$cursor # Restore cursor position NUMERIC=${numeric:-1} # In case of fall-through } (( NUMERIC > $#lastcmd )) && return 1 LBUFFER[lcursor+1,cursor+1]=$lastcmd[-NUMERIC] _ilw_cursor=$CURSOR ^ permalink raw reply [flat|nested] 12+ messages in thread
* smart-insert-last-word bugs 2006-10-15 4:04 ` Bart Schaefer 2006-10-15 10:39 ` Vincent Lefevre @ 2006-10-15 15:58 ` Vincent Lefevre 2006-10-15 18:46 ` Bart Schaefer 1 sibling, 1 reply; 12+ messages in thread From: Vincent Lefevre @ 2006-10-15 15:58 UTC (permalink / raw) To: zsh-users On 2006-10-14 21:04:51 -0700, Bart Schaefer wrote: > The simple workaround is to change > > setopt extendedglob > > to > > setopt extendedglob nohistignoredups > > in smart-insert-last-word, on the second line. In addition to this bug, here's another one: after I type a command and use completion, smart-insert-last-word removes the space between the command and the argument. -- Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/> Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: smart-insert-last-word bugs 2006-10-15 15:58 ` smart-insert-last-word bugs Vincent Lefevre @ 2006-10-15 18:46 ` Bart Schaefer 2006-10-15 23:15 ` Bart Schaefer 0 siblings, 1 reply; 12+ messages in thread From: Bart Schaefer @ 2006-10-15 18:46 UTC (permalink / raw) To: zsh-users On Oct 15, 5:58pm, Vincent Lefevre wrote: } } ... another one: after I type a command and use completion, } smart-insert-last-word removes the space between the command and the } argument. I think this is the generic problem with user-defined widgets and autoremoval, to wit, whether to do autoremoval is a property of the *next* widget executed (*after* the one that did the auto-insertion) and there's no way to tell zle what the autoremoval property should be for a user-defined widget. This can be worked around by arranging that the first thing the user- defined widget does is execute a built-in widget that thas the desired autoremoval behavior. So perhaps a reasonable fix would be to create a couple of built-in widgets that do nothing *except* autoremoval. E.g., zle remove-preceding-auto-suffix and zle retain-preceding-auto-suffix (choose other names as appropriate). ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: smart-insert-last-word bugs 2006-10-15 18:46 ` Bart Schaefer @ 2006-10-15 23:15 ` Bart Schaefer 0 siblings, 0 replies; 12+ messages in thread From: Bart Schaefer @ 2006-10-15 23:15 UTC (permalink / raw) To: zsh-users On Oct 15, 11:46am, Bart Schaefer wrote: } } ... there's no way to tell zle what the autoremoval property should } be for a user-defined widget. } } ... perhaps a reasonable fix would be to create } a couple of built-in } widgets that do nothing *except* autoremoval. Here's a patch. I'm not entirely certain whether we also need versions of these that have the ZLE_MENUCMP or ZLE_ISCMP flags, or whether instead of ZLE_NOTCOMMAND these should have ZLE_MENUCMP. I chose to call them auto-suffix-remove and auto-suffix-retain. Better suggestions welcome. Index: Src/Zle/iwidgets.list =================================================================== --- iwidgets.list 31 May 2006 14:11:59 -0000 1.6 +++ iwidgets.list 15 Oct 2006 23:05:04 -0000 @@ -14,6 +14,8 @@ "accept-line", acceptline, 0 "accept-line-and-down-history", acceptlineanddownhistory, 0 "argument-base", argumentbase, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND +"auto-suffix-remove", handlesuffix, ZLE_NOTCOMMAND +"auto-suffix-retain", handlesuffix, ZLE_KEEPSUFFIX | ZLE_NOTCOMMAND "backward-char", backwardchar, 0 "backward-delete-char", backwarddeletechar, ZLE_KEEPSUFFIX "backward-delete-word", backwarddeleteword, ZLE_KEEPSUFFIX Index: Src/Zle/zle_utils.c =================================================================== --- zle_utils.c 1 Oct 2006 02:38:53 -0000 1.10 +++ zle_utils.c 15 Oct 2006 22:11:16 -0000 @@ -865,6 +865,15 @@ return 0; } +/* user control of auto-suffixes -- see iwidgets.list */ + +/**/ +int +handlesuffix(UNUSED(char **args)) +{ + return 0; +} + /***************/ /* undo system */ /***************/ Index: Doc/Zsh/zle.yo =================================================================== --- zle.yo 31 May 2006 14:11:59 -0000 1.20 +++ zle.yo 15 Oct 2006 22:56:54 -0000 @@ -1665,6 +1665,24 @@ Execute the current line, and push the next history event on the the buffer stack. ) +tindex(auto-suffix-remove) +item(tt(auto-suffix-remove))( +If the previous action added a suffix (space, slash, etc.) to the word on +the command line, remove it. Otherwise do nothing. Removing the suffix +ends any active menu completion or menu selection. + +This widget is intended to be called from user-defined widgets to enforce +a desired suffix-removal behavior. +) +tindex(auto-suffix-retain) +item(tt(auto-suffix-retain))( +If the previous action added a suffix (space, slash, etc.) to the word on +the command line, force it to be preserved. Otherwise do nothing. +Retaining the suffix ends any active menu completion or menu selection. + +This widget is intended to be called from user-defined widgets to enforce +a desired suffix-preservation behavior. +) tindex(beep) item(tt(beep))( Beep, unless the tt(BEEP) option is unset. -- ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-10-16 5:26 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-10-14 11:56 About insert-last-word and "command args | less" Vincent Lefevre 2006-10-14 21:27 ` Bart Schaefer 2006-10-15 0:50 ` Vincent Lefevre 2006-10-15 4:04 ` Bart Schaefer 2006-10-15 10:39 ` Vincent Lefevre 2006-10-15 18:30 ` Bart Schaefer 2006-10-15 18:49 ` Bart Schaefer 2006-10-15 21:14 ` Vincent Lefevre 2006-10-16 5:26 ` Bart Schaefer 2006-10-15 15:58 ` smart-insert-last-word bugs Vincent Lefevre 2006-10-15 18:46 ` Bart Schaefer 2006-10-15 23:15 ` 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).