From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17830 invoked by alias); 18 Jan 2010 12:42:56 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 27604 Received: (qmail 809 invoked from network); 18 Jan 2010 12:42:43 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-3.0 required=5.0 tests=AWL,BAYES_00, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS autolearn=ham version=3.2.5 Received-SPF: none (ns1.primenet.com.au: domain at csr.com does not designate permitted sender hosts) X-Authentication-Warning: news01.csr.com: pws owned process doing -bs To: zsh-workers@zsh.org (Zsh hackers list) Subject: PATCH: function support for regular expression substitution X-Mailer: MH-E 8.0.3; nmh 1.3; GNU Emacs 22.1.1 Date: Mon, 18 Jan 2010 12:42:35 +0000 Message-ID: <17224.1263818555@csr.com> From: Peter Stephenson X-OriginalArrivalTime: 18 Jan 2010 12:42:35.0698 (UTC) FILETIME=[B5F93120:01CA983B] Content-Type: text/plain MIME-Version: 1.0 X-Scanned-By: MailControl A-09-22-10 (www.mailcontrol.com) on 10.68.0.125 While I'm at it. Index: Functions/Misc/.distfiles =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/Misc/.distfiles,v retrieving revision 1.16 diff -u -r1.16 .distfiles --- Functions/Misc/.distfiles 16 Dec 2009 12:12:57 -0000 1.16 +++ Functions/Misc/.distfiles 18 Jan 2010 12:40:45 -0000 @@ -10,6 +10,7 @@ mere nslookup promptnl +regexp-replace relative run-help run-help-git Index: Functions/Misc/regexp-replace =================================================================== RCS file: Functions/Misc/regexp-replace diff -N Functions/Misc/regexp-replace --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Functions/Misc/regexp-replace 18 Jan 2010 12:40:45 -0000 @@ -0,0 +1,35 @@ +# Replace all occurrences of a regular expression in a variable. The +# variable is modified directly. Respects the setting of the +# option RE_MATCH_PCRE. +# +# First argument: *name* (not contents) of variable. +# Second argument: regular expression +# Third argument: replacement string. This can contain all forms of +# $ and backtick substitutions; in particular, $MATCH will be replaced +# by the portion of the string matched by the regular expression. + +integer pcre + +[[ -o re_match_pcre ]] && pcre=1 + +emulate -L zsh +(( pcre )) && setopt re_match_pcre + +# $4 is the string to be matched +4=${(P)1} +# $5 is the final string +5= +local MATCH MBEGIN MEND +local -a match mbegin mend + +while [[ -n $4 ]]; do + if [[ $4 =~ $2 ]]; then + 5+=${4[1,MBEGIN-1]}${(e)3} + 4=${4[MEND+1,-1]} + else + break + fi +done +5+=$4 + +eval ${1}=${(q)5} Index: Functions/Zle/replace-string-again =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/Zle/replace-string-again,v retrieving revision 1.2 diff -u -r1.2 replace-string-again --- Functions/Zle/replace-string-again 3 Apr 2008 11:39:11 -0000 1.2 +++ Functions/Zle/replace-string-again 18 Jan 2010 12:40:46 -0000 @@ -13,7 +13,7 @@ return 1 fi -if [[ $curwidget = *pattern* ]]; then +if [[ $curwidget = *(pattern|regex)* ]]; then local rep2 # The following horror is so that an & preceded by an even # number of backslashes is active, without stripping backslashes, @@ -38,8 +38,14 @@ rep=${match[5]} done rep2+=$rep - LBUFFER=${LBUFFER//(#bm)$~_replace_string_src/${(e)rep2}} - RBUFFER=${RBUFFER//(#bm)$~_replace_string_src/${(e)rep2}} + if [[ $curwidget = *regex* ]]; then + autoload -U regexp-replace + regexp-replace LBUFFER $_replace_string_src $rep2 + regexp-replace RBUFFER $_replace_string_src $rep2 + else + LBUFFER=${LBUFFER//(#bm)$~_replace_string_src/${(e)rep2}} + RBUFFER=${RBUFFER//(#bm)$~_replace_string_src/${(e)rep2}} + fi else LBUFFER=${LBUFFER//$_replace_string_src/$_replace_string_rep} RBUFFER=${RBUFFER//$_replace_string_src/$_replace_string_rep} Index: Doc/Zsh/contrib.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/contrib.yo,v retrieving revision 1.106 diff -u -r1.106 contrib.yo --- Doc/Zsh/contrib.yo 16 Jan 2010 16:28:30 -0000 1.106 +++ Doc/Zsh/contrib.yo 18 Jan 2010 12:40:46 -0000 @@ -1570,14 +1570,14 @@ tindex(replace-pattern) xitem(tt(replace-string), tt(replace-pattern)) item(tt(replace-string-again), tt(replace-pattern-again))( -The function tt(replace-string) implements two widgets. +The function tt(replace-string) implements three 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 +replace-string)', then the matching is performed using zsh patterns. 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 @@ -1588,6 +1588,12 @@ `tt(\{)var(N)tt(})' may be used to protect the digit from following digits. +If the widget instead contains the word `tt(regex)' (or `tt(regexp)'), +then the matching is performed using regular expressions, respecting +the setting of the option tt(RE_MATCH_PCRE) (see the description of the +function tt(regexp-replace) below). The facilities described +for pattern matching are also available. + By default the previous source or replacement string will not be offered for editing. However, this feature can be activated by setting the style tt(edit-previous) in the context tt(:zle:)var(widget) (for example, @@ -1595,12 +1601,12 @@ numeric argument forces the previous values to be offered, a negative or zero argument forces them not to be. -The function tt(replace-string-again) can be used to repeat the -previous replacement; no prompting is done. As with tt(replace-string), if -the name of the widget contains the word `tt(pattern)', pattern matching -is performed, else a literal string replacement. Note that the -previous source and replacement text are the same whether pattern or string -matching is used. +The function tt(replace-string-again) can be used to repeat the previous +replacement; no prompting is done. As with tt(replace-string), if the name +of the widget contains the word `tt(pattern)' or `tt(regex)', pattern or +regular expression matching is performed, else a literal string +replacement. Note that the previous source and replacement text are the +same whether pattern, regular expression or string matching is used. For example, starting from the line: @@ -2574,6 +2580,25 @@ See also the tt(pager), tt(prompt) and tt(rprompt) styles below. ) +findex(regexp-replace) +item(tt(regexp-replace) var(var) var(regexp) var(replace))( +Use regular expressions to perform a global search and replace operation +on a variable. If the option tt(RE_MATCH_PCRE) is not set, POSIX +extended regular expressions are used, else Perl-compatible regular +expressions (this requires the shell to be linked against the tt(pcre) +library). + +var(var) is the name of the variable containing the string to be matched. +The variable will be modified directly by the function. The +variables tt(MATCH), tt(MBEGIN), tt(MEND), tt(match), tt(mbegin), tt(mend) +should be avoided as these are used by the regular expression code. + +var(regexp) is the regular expression to match against the string. + +var(replace) is the replacement text. This can contain parameter, command +and arithmetic expressions which will be replaced: in particular, a +reference to tt($MATCH) will be replaced by the text matched by the pattern. +) findex(run-help) item(tt(run-help) var(cmd))( This function is designed to be invoked by the tt(run-help) ZLE widget, -- Peter Stephenson Software Engineer Tel: +44 (0)1223 692070 Cambridge Silicon Radio Limited Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom