From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 108 invoked from network); 28 Mar 2003 19:09:31 -0000 Received: from sunsite.dk (130.225.247.90) by ns1.primenet.com.au with SMTP; 28 Mar 2003 19:09:31 -0000 Received: (qmail 13234 invoked by alias); 28 Mar 2003 19:09:23 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 18403 Received: (qmail 13227 invoked from network); 28 Mar 2003 19:09:23 -0000 Received: from localhost (HELO sunsite.dk) (127.0.0.1) by localhost with SMTP; 28 Mar 2003 19:09:23 -0000 X-MessageWall-Score: 0 (sunsite.dk) Received: from [62.189.183.235] by sunsite.dk (MessageWall 1.0.8) with SMTP; 28 Mar 2003 19:9:22 -0000 Received: from exchange01.csr.com (unverified) by (Content Technologies SMTPRS 4.2.1) with ESMTP id for ; Fri, 28 Mar 2003 19:17:32 +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 H5TXDJ8B; Fri, 28 Mar 2003 19:08:36 -0000 To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: Re: PATCH: enhanced word widgets In-reply-to: ""Bart Schaefer""'s message of "Fri, 28 Mar 2003 16:11:17 GMT." <1030328161117.ZM22723@candle.brasslantern.com> Date: Fri, 28 Mar 2003 19:09:19 +0000 Message-ID: <21083.1048878559@csr.com> From: Peter Stephenson "Bart Schaefer" wrote: > I want the definition of a "word" to be context-sensitive. For example: > If the cursor is within a shell word that contains a "/" character, then > I want "ZLE words" to be pathname components (and transpose-words should > transpose around the nearest "/" either under the cursor or to the left); > but if the cursor is between two shell words, then I want "words" to be > shell words, e.g., pathnames including the slashes. OK, I think this does pretty much what you want. (Luckily I was working on a scatternet scheduling problem, so I was easily diverted.) Zefram is quite right but his point leads to a complete rewrite of the parser rather than a quick ten-minute rewrite of the shell function... No documentation yet and it won't be committed until we decide what the neatest way of doing this is. Set the style word-context to pairs of words: a pattern, and a subcontext. The function then tests against the patterns in order. - If the cursor is in a command argument the pattern will be tested against the word (with any quotes stripped, so foo, \foo, 'foo' "foo" will all give you foo to match against --- I can remove this, but it seemed more convenient with it). - If the cursor is in whitespace between words, it will be tested against the whitespace character under the cursor. - If it is at the end of the buffer, it will be tested against the empty string. - For reasons best known to the lexical analyser, the pattern is tested against `;' if you are at the end of a line when there are more to follow (unfortunately due to the unquoting this looks the same as a real semicolon in quotes). I suppose I could sensibly trap this before the unquoting and turn it into a newline. If a pattern matches, the corresponding subcontext is appended (with the traditional colon) to the end of the current context. I tried this out with the context array: zstyle ':zle:*' word-context "[[:space:]]" whitespace "*/*" \ filename "" end "*" other (though all you need for the suggested use are the `filename' element plus a suitable default and `other' is completely redundant (it's an insignificant other)) and zstyle ':zle:transpose-words:whitespace' word-style shell zstyle ':zle:transpose-words:filename' word-style normal zstyle ':zle:transpose-words:filename' word-chars '' so if you are in a filename --- the character under the cursor is part of a word which includes a slash --- you get bash-style behaviour, if you are in whitespace, you get shell-word behaviour, and if you are in any other word you get the default behaviour. Index: Functions/Zle/match-words-by-style =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/Zle/match-words-by-style,v retrieving revision 1.1 diff -u -r1.1 match-words-by-style --- Functions/Zle/match-words-by-style 28 Mar 2003 11:34:30 -0000 1.1 +++ Functions/Zle/match-words-by-style 28 Mar 2003 18:46:56 -0000 @@ -62,12 +62,47 @@ emulate -L zsh setopt extendedglob -local wordstyle spacepat wordpat1 wordpat2 opt charskip +local wordstyle spacepat wordpat1 wordpat2 charskip local match mbegin mend pat1 pat2 word1 word2 ws1 ws2 ws3 skip -local MATCH MBEGIN MEND +local MATCH MBEGIN MEND pattern subcontext +local -a wordcontext if [[ -z $curcontext ]]; then local curcontext=:zle:match-words-by-style +fi + +if zstyle -a $curcontext word-context wordcontext; then + # Pretend line so far is a complete set of words... + bufwords=(${(z)LBUFFER}) + word1=${#bufwords} + # Word either before or including cursor + pat1=$bufwords[-1] + # If we get more words by adding in the cursor, we're at the + # start of the next word. + wordpat1="$LBUFFER$RBUFFER[1]" + bufwords=(${(z)wordpat1}) + word2=${#bufwords} + pat2=$bufwords[-1] + bufwords=(${(z)BUFFER}) + if (( word1 != word2 )); then + # At start of word2 + wordpat2=${(Q)bufwords[$word2]} + elif [[ ${#bufwords[$word1]} > ${#pat1} ]]; then + # Word is longer when including whole buffer. + # How beautiful life is now you're in the word. + # Strip quotes in order to test actual argument + # (except we haven't done expansion on it). + wordpat2=${(Q)bufwords[$word1]} + else + # We are not in the word. Just use character at cursor position. + wordpat2=$RBUFFER[1] + fi + for pattern subcontext in "${wordcontext[@]}"; do + if [[ $wordpat2 = ${~pattern} ]]; then + curcontext+=":$subcontext" + break + fi + done fi zstyle -s $curcontext word-style wordstyle -- 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. **********************************************************************