Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm
Precedence: bulk
X-No-Archive: yes
List-Id: Zsh Workers List <zsh-workers.zsh.org>
List-Post: <mailto:zsh-workers@zsh.org>
List-Help: <mailto:zsh-workers-help@zsh.org>
X-Qmail-Scanner-Diagnostics: from mailout1.w1.samsung.com by f.primenet.com.au (envelope-from <p.stephenson@samsung.com>, uid 7791) with qmail-scanner-2.11 
 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1.  
 Clear:RC:0(210.118.77.11):SA:0(-1.3/5.0):. 
 Processed in 0.275654 secs); 26 Jul 2016 15:51:26 -0000
X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au
X-Spam-Level: 
X-Spam-Status: No, score=-1.3 required=5.0 tests=RP_MATCHES_RCVD
	autolearn=unavailable autolearn_force=no version=3.4.1
X-Envelope-From: p.stephenson@samsung.com
X-Qmail-Scanner-Mime-Attachments: |
X-Qmail-Scanner-Zip-Files: |
Received-SPF: none (ns1.primenet.com.au: domain at samsung.com does not designate permitted sender hosts)
X-AuditID: cbfec7f4-f796c6d000001486-0d-579786f4d9b7
Date: Tue, 26 Jul 2016 16:51:14 +0100
From: Peter Stephenson <p.stephenson@samsung.com>
To: zsh-workers@zsh.org
Subject: Re: bug with camel case and delete-whole-word-match function
Message-id: <20160726165114.7ed32a3c@pwslap01u.europe.root.pri>
In-reply-to: <588168129.3340906.1467709726474.JavaMail.yahoo@mail.yahoo.com>
References: <588168129.3340906.1467709726474.JavaMail.yahoo.ref@mail.yahoo.com>
 <588168129.3340906.1467709726474.JavaMail.yahoo@mail.yahoo.com>
Organization: Samsung Cambridge Solution Centre
X-Mailer: Claws Mail 3.7.9 (GTK+ 2.22.0; i386-redhat-linux-gnu)
MIME-version: 1.0
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7bit
X-Brightmail-Tracker:
 H4sIAAAAAAAAA+NgFrrILMWRmVeSWpSXmKPExsVy+t/xa7pf2qaHGxzoMrE42PyQyYHRY9XB
	D0wBjFFcNimpOZllqUX6dglcGUeu9rAUvNSpON31nq2BcbVyFyMnh4SAicSMixMYIWwxiQv3
	1rN1MXJxCAksZZQ4uGoLO4Qzg0nixcyzrBDOOUaJmU8WQ5WdZZSYfr2BCaSfRUBVYsu3JWCz
	2AQMJaZumg1miwiIS5xde54FxBYWcJXo/HqUFcTmFbCXePe7E6yGU8BH4vnDl2C2kMBERokN
	93xAbH4BfYmrfz8xQdxnLzHzyhlGiF5BiR+T74HNZBbQkti8rYkVwpaX2LzmLTPEHHWJG3d3
	s09gFJ6FpGUWkpZZSFoWMDKvYhRNLU0uKE5KzzXUK07MLS7NS9dLzs/dxAgJ6C87GBcfszrE
	KMDBqMTDy5kyLVyINbGsuDL3EKMEB7OSCO/UlunhQrwpiZVVqUX58UWlOanFhxilOViUxHnn
	7nofIiSQnliSmp2aWpBaBJNl4uCUamB0jZ038e7Ce/8Wp/PaS2x5dPBC8OQLDx1e1qd4sS7e
	oe72faNm2HHXDf9Vn6w8tres/sqNsw4NyzdbrU8rlOz+N5ur0fxS89m/UQqqqfMywwSN1146
	1ld1cfZmvbd/P6buUS1fVHVKSN2I9agwb91pzp37mR7rPnUxXHA62JnNfVG5d9SmEK8IJZbi
	jERDLeai4kQA6zV9hmQCAAA=
X-Seq: zsh-workers 38951

On Tue, 05 Jul 2016 09:08:46 +0000 (UTC)
Oliver Kiddle <okiddle@yahoo.co.uk> wrote:
> On the first character of a camel case word, both the current and
> previous word are deleted.

This should fix this in a way that makes it easy to add new features.

pws

diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index c3dec34..5a7fc13 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -2132,6 +2132,15 @@ non-word characters following that word (7) the remainder of the line.  Any
 of the elements may be an empty string; the calling function should test
 for this to decide whether it can perform its function.
 
+If the option -A is given to tt(match-words-by-style), then
+tt(matched_words) is an associative array and the seven values
+given above should be retrieved from it as elements named tt(start),
+tt(word-before-cursor), tt(ws-before-cursor), tt(ws-after-cursor),
+tt(word-after-cursor), tt(ws-after-word), and tt(end).  In addition
+the element tt(is-word-start) is 1 if the cursor is on the start
+of a word or subword, and 0 otherwise.  This form is recommended
+for future compatibility.
+
 It is possible to pass options with arguments to tt(match-words-by-style)
 to override the use of styles.  The options are:
 startsitem()
diff --git a/Functions/Zle/delete-whole-word-match b/Functions/Zle/delete-whole-word-match
index aece860..a07f236 100644
--- a/Functions/Zle/delete-whole-word-match
+++ b/Functions/Zle/delete-whole-word-match
@@ -12,30 +12,29 @@ emulate -L zsh
 setopt extendedglob
 
 local curcontext=:zle:$WIDGET
-local -a matched_words
+local -A matched_words
 # Start and end of range of characters to remove.
 integer pos1 pos2
 
 autoload -Uz match-words-by-style
-match-words-by-style
+match-words-by-style -A
 
-if [[ -n "${matched_words[3]}" ]]; then
-    # There's whitespace before the cursor, so the word we are deleting
-    # starts at the cursor position.
+if (( ${matched_words[is-word-start]} )); then
+    # The word we are deleting starts at the cursor position.
     pos1=$CURSOR
 else
-    # No whitespace before us, so delete any wordcharacters there.
-    pos1="${#matched_words[1]}"
+    # Not, so delete any wordcharacters before, too
+    pos1="${#matched_words[start]}"
 fi
 
-if [[ -n "${matched_words[4]}" ]]; then
+if [[ -n "${matched_words[ws-after-cursor]}" ]]; then
     # There's whitespace at the cursor position, so only delete
     # up to the cursor position.
     (( pos2 = CURSOR + 1 ))
 else
     # No whitespace at the cursor position, so delete the
     # current character and any following wordcharacters.
-    (( pos2 = CURSOR + ${#matched_words[5]} + 1 ))
+    (( pos2 = CURSOR + ${#matched_words[word-after-cursor]} + 1 ))
 fi
 
 # Move the cursor then delete the block in one go for the
diff --git a/Functions/Zle/match-words-by-style b/Functions/Zle/match-words-by-style
index 6cdec75..1110f76 100644
--- a/Functions/Zle/match-words-by-style
+++ b/Functions/Zle/match-words-by-style
@@ -5,8 +5,16 @@
 #    <whitespace-after-cursor> <word-after-cursor> <whitespace-after-word>
 #    <stuff-at-end>
 # where the cursor position is always after the third item and `after'
-# is to be interpreted as `after or on'.  Some
-# of the array elements will be empty; this depends on the style.
+# is to be interpreted as `after or on'.
+#
+# With the option -A, matched_words is an associative array; the
+# values above are now given by the elements named start, word-before-cursor,
+# ws-before-cursor, ws-after-cursor, word-after-cursor, ws-after-word,
+# end.  In addition, the element is-word-start is 1 if the cursor
+# is on the start of a word; this is non-trivial in the case of subword
+# (camel case) matching as there may be no white space to test.
+#
+# Some of the array elements will be empty; this depends on the style.
 # For example
 #    foo bar  rod stick
 #            ^
@@ -70,14 +78,19 @@ setopt extendedglob
 local wordstyle spacepat wordpat1 wordpat2 opt charskip wordchars wordclass
 local match mbegin mend pat1 pat2 word1 word2 ws1 ws2 ws3 skip
 local nwords MATCH MBEGIN MEND subwordrange
+integer use_assoc
 
 local curcontext=${curcontext:-:zle:match-words-by-style}
 
 autoload -Uz match-word-context
 match-word-context
 
-while getopts "w:s:c:C:r:" opt; do
+while getopts "Aw:s:c:C:r:" opt; do
   case $opt in
+    (A)
+    use_assoc=1
+    ;;
+
     (w)
     wordstyle=$OPTARG
     ;;
@@ -229,6 +242,8 @@ ws2=$match[1]
 word2=$match[2]
 ws3=$match[3]
 
+integer wordstart
+[[ -n $ws1 || -n $ws2 ]] && wordstart=1
 if [[ $wordstyle = *subword* ]]; then
   # Do we have a group of upper case characters at the start
   # of word2 (that don't form the entire word)?
@@ -249,6 +264,7 @@ if [[ $wordstyle = *subword* ]]; then
     # if it wants.
   elif [[ $word2 = (#b)(?[^${~subwordrange}]##)[${~subwordrange}]* ]]; then
     (( epos = ${#match[1]} ))
+    (( wordstart = 1 ))
   else
     (( epos = 0 ))
   fi
@@ -262,4 +278,21 @@ if [[ $wordstyle = *subword* ]]; then
   fi
 fi
 
-matched_words=("$pat1" "$word1" "$ws1" "$ws2" "$word2" "$ws3" "$pat2")
+# matched_words should be local to caller.
+# Just fix type here.
+if (( use_assoc )); then
+  typeset -gA matched_words
+  matched_words=(
+    start              "$pat1"
+    word-before-cursor "$word1"
+    ws-before-cursor   "$ws1"
+    ws-after-cursor    "$ws2"
+    word-after-cursor  "$word2"
+    ws-after-word      "$ws3"
+    end                "$pat2"
+    is-word-start      $wordstart
+  )
+else
+  typeset -ga matched_words
+  matched_words=("$pat1" "$word1" "$ws1" "$ws2" "$word2" "$ws3" "$pat2")
+fi

