diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Doc/Zsh/contrib.yo | 31 | ||||
-rw-r--r-- | Functions/Zle/delete-whole-word-match | 56 |
3 files changed, 93 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog index 12c13cebb..e5a37217a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2003-10-13 Peter Stephenson <pws@csr.com> + + * 19183: Doc/Zsh/contrib.yo, + Functions/Zle/delete-whole-word-match: New word-matching function + to delete entire word around cursor. + 2003-10-09 Oliver Kiddle <opk@zsh.org> * unposted: Completion/Unix/Command/_nmap: update for nmap 3.48 diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 82ed6da12..2648fd6c8 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -484,6 +484,21 @@ has been set, and tt(transpose-words-match) is called with the cursor on the var(X) of tt(foo)var(X)tt(bar), where var(X) can be any character, then the resulting expression is tt(bar)var(X)tt(foo). +Here are some examples of use of the styles, actually taken from the +simplified interface in tt(select-word-style): + +example(zstyle ':zle:*' word-style standard +zstyle ':zle:*' word-chars '') + +Implements bash-style word handling for all widgets, i.e. only +alphanumerics are word characters; equivalent to setting +the parameter tt(WORDCHARS) empty for the given context. + +example(style ':zle:*kill*' word-style space) + +Uses space-delimited words for widgets with the word `kill' in the name. +Neither of the styles tt(word-chars) nor tt(word-class) is used in this case. + The word matching and all the handling of tt(zstyle) settings is actually implemented by the function tt(match-words-by-style). This can be used to create new user-defined widgets. The calling function should set the local @@ -499,6 +514,22 @@ 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. ) +tindex(delete-whole-word-match) +item(tt(delete-whole-word-match))( +This is another function which works like the tt(-match) functions +described immediately above, i.e. using styles to decide the word +boundaries. However, it is not a replacement for any existing function. + +The basic behaviour is to delete the word around the cursor. There is no +numeric prefix handling; only the single word around the cursor is +considered. If the widget contains the string tt(kill), the removed text +will be placed in the cutbuffer for future yanking. This can be obtained +by defining tt(kill-whole-word-match) as follows: + +example(zle -N kill-whole-word-match delete-whole-word-match) + +and then binding the widget tt(kill-whole-word-match). +) tindex(copy-earlier-word) item(tt(copy-earlier-word))( This widget works like a combination of tt(insert-last-word) and diff --git a/Functions/Zle/delete-whole-word-match b/Functions/Zle/delete-whole-word-match new file mode 100644 index 000000000..9f7b29128 --- /dev/null +++ b/Functions/Zle/delete-whole-word-match @@ -0,0 +1,56 @@ +# Delete the entire word around the cursor. Does not handle +# a prefix argument; either the cursor is in the word or it isn't. +# The word may be just before the cursor, e.g. +# print this is a line +# ^ here +# and then the word before (i.e. `this') will be deleted. +# +# If the widget has the name `kill' in, the text deleted will be +# saved for future yanking in the normal way. + +emulate -L zsh +setopt extendedglob + +local curcontext=:zle:delete-whole-word +local -a matched_words +# Start and end of range of characters to remove. +integer pos1 pos2 + +autoload -U match-words-by-style +match-words-by-style + +if [[ -n "${matched_words[3]}" ]]; then + # There's whitespace before the cursor, so 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]}" +fi + +if [[ -n "${matched_words[4]}" ]]; then + # There's whitespace at the cursor position, so only delete + # up to the cursor position. + pos2=$CURSOR +else + # No whitespace at the cursor position, so delete the + # current character and any following wordcharacters. + (( pos2 = CURSOR + ${#matched_words[5]} + 1 )) +fi + +# Move the cursor then delete the block in one go for the +# purpose of undoing (and yanking, if appropriate). +(( CURSOR = pos1 )) + +# If the widget name includes the word `kill', the removed +# text goes into the cutbuffer in the standard way. +if [[ $WIDGET = *kill* ]]; then + local word="${BUFFER[pos1+1,pos2-1]}" + if [[ $LASTWIDGET = *kill* ]]; then + CUTBUFFER="$CUTBUFFER$word" + else + killring=("$CUTBUFFER" "${(@)killring[1,-2]}") + CUTBUFFER=$word + fi +fi +BUFFER="${BUFFER[1,pos1]}${BUFFER[pos2,-1]}" |