Hello I've attached a new widget "transpose-segments". Works like "transpose-words", but the "words" are what I call "segments" – parts of a command obtained by (z) flag. This allows to comfortably swap arbitrarily quoted things at prompt, http://asciinema.org/a/5tkda9lr7dju4lh3vt5sj35wi Can this be commited? Best regards, Sebastian Gniazdowski
diff --git a/Functions/Zle/transpose-segments b/Functions/Zle/transpose-segments
new file mode 100644
index 0000000..313febf
--- /dev/null
+++ b/Functions/Zle/transpose-segments
@@ -0,0 +1,82 @@
+# Transpose segments, i.e. parts of line obtained by (z) flag, i.e.
+# as if zsh parsed the line.
+#
+# Code to activate the functionality with Alt-t:
+# autoload transpose-segments
+# zle -N transpose-segments
+# bindkey "^[t" transpose-segments
+
+local curcontext=":zle:$WIDGET" skip
+local MATCH MBEGIN MEND
+
+# Will remember white spaces before each segment
+typeset -a spaces
+spaces=()
+
+# Working variable for $BUFFER
+local buf="$BUFFER"
+
+# Split the buffer
+typeset -a bufarr
+bufarr=( "${(z)buf}" )
+
+# (z) handles spaces nicely, but we need them for the user
+integer size="$#bufarr"
+integer char_count=0
+integer selected_segment=0
+
+for (( i=1; i<=size; i++ )); do
+ local segment="$bufarr[i]"
+
+ # In general, $buf can start with white spaces
+ # We will not search for them, but instead
+ # search for any char that's current segment's
+ # leading character. So this is an approach that
+ # doesn't trust [::space::]
+
+ local leadchar="$segment[1]"
+ buf="${buf##(#m)[^$leadchar]#}"
+
+ # Remember the spaces
+ spaces[$i]="$MATCH"
+
+ # Count all characters being processed, remove the spaces, then remove segment
+ char_count=char_count+"$#MATCH"+"$#segment"
+ buf="${buf#$MATCH}"
+ MATCH=""
+ buf="${buf#(#m)$segment}"
+
+ # If segment not found, return from the function doing nothing
+ # This of course shoudln't happen
+ [ -z "$MATCH" ] && return 0
+
+ # Detect which segment is active
+ [[ "$selected_segment" -eq 0 && "$char_count" -ge "$CURSOR" ]] && selected_segment=i
+done
+
+
+# What's left in $buf can be only white spaces
+spaces[i]="$buf"
+char_count=char_count+"$#buf"
+
+[[ "$selected_segment" -eq 0 && "$char_count" -ge "$CURSOR" ]] && selected_segment=i-1
+# No active segment found, or it's a first segment? Return. (this shouldn't happen)
+[[ "$selected_segment" -eq "0" || "$selected_segment" -eq "1" ]] && return 0
+
+# Swap segments
+local tmp="$bufarr[selected_segment]"
+bufarr[selected_segment]="$bufarr[selected_segment-1]"
+bufarr[selected_segment-1]="$tmp"
+
+# Build BUFFER
+integer curbkp="$CURSOR"
+BUFFER=""
+for (( i=1; i<=size; i++ )); do
+ BUFFER+="$spaces[i]$bufarr[i]"
+done
+CURSOR="$curbkp"
+
+# Append final white spaces
+BUFFER+="$spaces[i]"
+
+return 0
Attachment:
transpose-segments
Description: Binary data