From 06902e7f66be368975ca4c58607191cf36a68781 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 3 Feb 2003 11:05:53 +0000 Subject: 18174: New read-from-minibuffer and replace-string ZLE functions --- ChangeLog | 6 +++++ Doc/Zsh/contrib.yo | 52 ++++++++++++++++++++++++++++++++++++++ Functions/Zle/read-from-minibuffer | 20 +++++++++++++++ Functions/Zle/replace-string | 45 +++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 Functions/Zle/read-from-minibuffer create mode 100644 Functions/Zle/replace-string diff --git a/ChangeLog b/ChangeLog index 174ca2c9d..b1313e12d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2003-02-03 Peter Stephenson + + * 18174: Doc/Zsh/contrib.yo, Functions/Zle/read-from-minibuffer, + Functions/Zle/replace-string: New widgets for reading values + during editing and for performing string and pattern replacements. + 2003-01-30 Clint Adams * unposted: config.guess, config.sub: update to 2003-01-10 and diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 4f1995f6d..3dd398634 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -588,6 +588,58 @@ zle -N predict-off 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: diff --git a/Functions/Zle/read-from-minibuffer b/Functions/Zle/read-from-minibuffer new file mode 100644 index 000000000..93eec42a5 --- /dev/null +++ b/Functions/Zle/read-from-minibuffer @@ -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 diff --git a/Functions/Zle/replace-string b/Functions/Zle/replace-string new file mode 100644 index 000000000..2fe0da901 --- /dev/null +++ b/Functions/Zle/replace-string @@ -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 -- cgit 1.4.1