From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4304 invoked from network); 3 Feb 2003 10:57:28 -0000 Received: from sunsite.dk (130.225.247.90) by ns1.primenet.com.au with SMTP; 3 Feb 2003 10:57:28 -0000 Received: (qmail 20111 invoked by alias); 3 Feb 2003 10:57:14 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 18174 Received: (qmail 20104 invoked from network); 3 Feb 2003 10:57:14 -0000 Received: from localhost (HELO sunsite.dk) (127.0.0.1) by localhost with SMTP; 3 Feb 2003 10:57:14 -0000 X-MessageWall-Score: 0 (sunsite.dk) Received: from [62.189.183.235] by sunsite.dk (MessageWall 1.0.8) with SMTP; 3 Feb 2003 10:57:14 -0000 Received: from exchange01.csr.com (unverified) by (Content Technologies SMTPRS 4.2.1) with ESMTP id for ; Mon, 3 Feb 2003 11:03:31 +0000 Received: from csr.com (tinky-winky.csr.com [192.168.144.127]) by exchange01.csr.com with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2650.21) id DQ47KSLB; Mon, 3 Feb 2003 10:55:12 -0000 To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: PATCH: replace-string function Date: Mon, 03 Feb 2003 10:57:15 +0000 Message-ID: <14734.1044269835@csr.com> From: Peter Stephenson Here's a replace-string (and replace-pattern) widget implemented in terms of a read-from-minibuffer widget. The latter uses the new features of 4.1 for recursive editing and limiting the area of the editing buffer, so provides a better `user experience' than was possible in 4.0 --- read-from-minibuffer allows you to use all zle functions as normal. The replace-pattern variant was designed to have familiar-looking syntax for inserting the original string and parenthesised subexpressions. I'm not claiming familiar is necessarily optimal, however. There are other things that aren't optimal. The problem with `undo' is noted in the manual page. Completion in the `minibuffer' hasn't been handled --- I think there's some way of tweaking the context so that the completion system sees what you want it to at that point, but I can't remember how. Also, it doesn't perform replacements across the cursor position. This was the easiest way to ensure the cursor position was maintained if the length changed. Also, it ought to use a separate history, but actually refers to the standard line history. I'd like a mechanism which makes it easier to provide alternative sources for the history in special contexts. This is very hairy at the moment, as I discovered with zcalc. Index: Doc/Zsh/contrib.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/contrib.yo,v retrieving revision 1.24 diff -u -r1.24 contrib.yo --- Doc/Zsh/contrib.yo 27 Jan 2003 16:41:15 -0000 1.24 +++ Doc/Zsh/contrib.yo 3 Feb 2003 10:38:02 -0000 @@ -588,6 +588,58 @@ bindkey '^X^Z' predict-on bindkey '^Z' predict-off) ) +tindex(read-from-minibuffer) +item(tt(read-from-minibuffer))( +This is most useful when called as a function from inside a widget, but will +work correctly as a widget in its own right. It prompts for a value +below the current command line; a value may be input using all of the +standard zle operations (and not merely the restricted set available +when executing, for example, tt(execute-named-cmd)). The value is then +returned to the calling function in the parameter tt($REPLY) and the +editing buffer restored to its previous state. If the read was aborted +by a keyboard break (typically tt(^G)), the function returns status 1 +and tt($REPLY) is not set. If an argument is supplied to the function +it is taken as a prompt, otherwise `tt(? )' is used. + +The name is a slight misnomer, as in fact the shell's own minibuffer is +not used. Hence it is still possible to call tt(executed-named-cmd) and +similar functions while reading a value. +) +tindex(replace-string) +tindex(replace-pattern) +item(tt(replace-string), tt(replace-pattern))( +The function tt(replace-string) implements two widgets. +If defined under the same name as the function, it prompts for two +strings; the first (source) string will be replaced by the second +everywhere it occurs in the line editing buffer. + +If the widget name contains the word `tt(pattern)', for example by +defining the widget using the command `tt(zle -N replace-pattern +replace-string)', then the replacement is done by pattern matching. All +zsh extended globbing patterns can be used in the source string; note +that unlike filename generation the pattern does not need to match an +entire word, nor do glob qualifiers have any effect. In addition, the +replacement string can contain parameter or command substitutions. +Furthermore, a `tt(&)' in the replacement string will be replaced with +the matched source string, and a backquoted digit `tt(\)var(N)' will be +replaced by the var(N)th parenthesised expression matched. The form +`tt(\{)var(N)tt(})' may be used to protect the digit from following +digits. + +For example, starting from the line: + +example(print This line contains fan and fond) + +and invoking tt(replace-pattern) with the source string `tt(f(?)n)' and +the replacment string `tt(c\1r)' produces the not very useful line: + +example(print This line contains car and cord) + +The range of the replacement string can be limited by using the +tt(narrow-to-region-invisible) widget. One limitation of the current +version is that tt(undo) will cycle through changes to the replacement +and source strings before undoing the replacement itself. +) tindex(smart-insert-last-word) item(tt(smart-insert-last-word))( This function may replace the tt(insert-last-word) widget, like so: Index: Functions/Zle/read-from-minibuffer =================================================================== RCS file: Functions/Zle/read-from-minibuffer diff -N Functions/Zle/read-from-minibuffer --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Functions/Zle/read-from-minibuffer 3 Feb 2003 10:38:02 -0000 @@ -0,0 +1,20 @@ +local savelbuffer=$LBUFFER saverbuffer=$RBUFFER +local savepredisplay=$PREDISPLAY savepostdisplay=$POSTDISPLAY + +LBUFFER= +RBUFFER= +PREDISPLAY="$PREDISPLAY$savelbuffer$saverbuffer$POSTDISPLAY +${1:-? }" +POSTDISPLAY= + +zle recursive-edit +integer stat=$? + +(( stat )) || REPLY=$BUFFER + +LBUFFER=$savelbuffer +RBUFFER=$saverbuffer +PREDISPLAY=$savepredisplay +POSTDISPLAY=$savepostdisplay + +return $stat Index: Functions/Zle/replace-string =================================================================== RCS file: Functions/Zle/replace-string diff -N Functions/Zle/replace-string --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Functions/Zle/replace-string 3 Feb 2003 10:38:02 -0000 @@ -0,0 +1,45 @@ +emulate -L zsh +setopt extendedglob + +autoload read-from-minibuffer + +local p1="Replace: " p2=" with: " +local src rep REPLY MATCH MBEGIN MEND curwidget=$WIDGET +local -a match mbegin mend + +read-from-minibuffer $p1 || return 1 +src=$REPLY + +read-from-minibuffer "$p1$src$p2" || return 1 +rep=$REPLY + +if [[ $curwidget = *pattern* ]]; then + local rep2 + # The following horror is so that an & preceded by an even + # number of backslashes is active, without stripping backslashes, + # while preceded by an odd number of backslashes is inactive, + # with one backslash being stripped. A similar logic applies + # to \digit. + while [[ $rep = (#b)([^\\]#)(\\\\)#(\\|)(\&|\\<->|\\\{<->\})(*) ]]; do + if [[ -n $match[3] ]]; then + # Expression is quoted, strip quotes + rep2="${match[1]}${match[2]}${match[4]}" + else + rep2+="${match[1]}${match[2]}" + if [[ $match[4] = \& ]]; then + rep2+='${MATCH}' + elif [[ $match[4] = \\\{* ]]; then + rep2+='${match['${match[4][3,-2]}']}' + else + rep2+='${match['${match[4][2,-1]}']}' + fi + fi + rep=${match[5]} + done + rep2+=$rep + LBUFFER=${LBUFFER//(#bm)$~src/${(e)rep2}} + RBUFFER=${RBUFFER//(#bm)$~src/${(e)rep2}} +else + LBUFFER=${LBUFFER//$src/$rep} + RBUFFER=${RBUFFER//$src/$rep} +fi -- Peter Stephenson Software Engineer CSR Ltd., Science Park, Milton Road, Cambridge, CB4 0WH, UK Tel: +44 (0)1223 692070 ********************************************************************** The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer. **********************************************************************