From c6dfb2999d51be6e71176358a2e14360fe6e6ee6 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 19 Apr 2007 14:16:22 +0000 Subject: users/11419: zle copy-region-as-kill adds text to the kill ring --- ChangeLog | 7 +++++++ Doc/Zsh/zle.yo | 14 ++++++++++--- Functions/Zle/backward-kill-word-match | 29 +++++++++++++------------- Functions/Zle/delete-whole-word-match | 3 +-- Functions/Zle/kill-word-match | 30 +++++++++++++-------------- Src/Zle/zle_misc.c | 21 ++++++++++++------- Src/Zle/zle_utils.c | 37 ++++++++++++++++++++++++++++------ 7 files changed, 92 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92e2820ba..b2cb75266 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2007-04-19 Peter Stephenson + * users/11419: Doc/Zsh/zle.yo, + Functions/Zle/backward-kill-word-match, + Functions/Zle/delete-whole-word-match, + Functions/Zle/kill-word-match, Src/Zle/zle_misc.c, + Src/Zle/zle_utils.c: allow zle copy-region-as-kill with an + argument to add text to the kill ring from a widget function. + * unposted: Functions/Misc/add-zsh-hook: should have been added ages ago but wasn't. diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index d600a49eb..cafb96e90 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -663,7 +663,10 @@ vindex(CUTBUFFER) item(tt(CUTBUFFER) (scalar))( The last item to be cut using one of the `tt(kill-)' commands; the string which the next yank would insert in the line. Later entries in -the kill ring are in the array tt(killring). +the kill ring are in the array tt(killring). Note that the +command `tt(zle copy-region-as-kill) var(string)' can be used to +set the text of the cut buffer from a shell function and cycle the kill +ring in the same way as interactively killing text. ) vindex(HISTNO) item(tt(HISTNO) (integer))( @@ -1296,6 +1299,11 @@ Kill the current line and enter insert mode. tindex(copy-region-as-kill) item(tt(copy-region-as-kill) (ESC-W ESC-w) (unbound) (unbound))( Copy the area from the cursor to the mark to the kill buffer. + +If called from a ZLE widget function in the form `tt(zle +copy-region-as-kill) var(string)' then var(string) will be taken as the +text to copy to the kill buffer. The cursor, the mark and the text on the +command line are not used in this case. ) tindex(copy-prev-word) item(tt(copy-prev-word) (ESC-^_) (unbound) (unbound))( @@ -1498,8 +1506,8 @@ Insert the contents of the kill buffer at the cursor position. ) tindex(yank-pop) item(tt(yank-pop) (ESC-y) (unbound) (unbound))( -Remove the text just yanked, rotate the kill-ring, -and yank the new top. Only works following +Remove the text just yanked, rotate the kill-ring (the history of +previously killed text) and yank the new top. Only works following tt(yank) or tt(yank-pop). ) tindex(vi-yank) diff --git a/Functions/Zle/backward-kill-word-match b/Functions/Zle/backward-kill-word-match index 77ad7bf1a..28f7e76ee 100644 --- a/Functions/Zle/backward-kill-word-match +++ b/Functions/Zle/backward-kill-word-match @@ -8,29 +8,28 @@ local -a matched_words integer count=${NUMERIC:-1} if (( count < 0 )); then - (( NUMERIC = -count )) - zle ${WIDGET##backward-} - return + (( NUMERIC = -count )) + zle ${WIDGET##backward-} + return fi while (( count-- )); do - match-words-by-style + match-words-by-style - word="$matched_words[2]$matched_words[3]" + word="$matched_words[2]$matched_words[3]" - if [[ -n $word ]]; then - if [[ -n $done || $LASTWIDGET = *kill* ]]; then - CUTBUFFER="$word$CUTBUFFER" - else - killring=("$CUTBUFFER" "${(@)killring[1,-2]}") - CUTBUFFER=$word - fi - LBUFFER=$matched_words[1] + if [[ -n $word ]]; then + if [[ -n $done || $LASTWIDGET = *kill* ]]; then + CUTBUFFER="$word$CUTBUFFER" else - return 1 + zle copy-region-as-kill "$word" fi - done=1 + LBUFFER=$matched_words[1] + else + return 1 + fi + done=1 done return 0 diff --git a/Functions/Zle/delete-whole-word-match b/Functions/Zle/delete-whole-word-match index 65e0cf044..978b95ee7 100644 --- a/Functions/Zle/delete-whole-word-match +++ b/Functions/Zle/delete-whole-word-match @@ -49,8 +49,7 @@ if [[ $WIDGET = *kill* ]]; then if [[ $LASTWIDGET = *kill* ]]; then CUTBUFFER="$CUTBUFFER$word" else - killring=("$CUTBUFFER" "${(@)killring[1,-2]}") - CUTBUFFER=$word + zle copy-region-as-kill "$word" fi fi BUFFER="${BUFFER[1,pos1]}${BUFFER[pos2,-1]}" diff --git a/Functions/Zle/kill-word-match b/Functions/Zle/kill-word-match index 1bee0708a..55e253dea 100644 --- a/Functions/Zle/kill-word-match +++ b/Functions/Zle/kill-word-match @@ -8,29 +8,27 @@ local -a matched_words integer count=${NUMERIC:-1} if (( count < 0 )); then - (( NUMERIC = -count )) - zle backward-$WIDGET - return + (( NUMERIC = -count )) + zle backward-$WIDGET + return fi while (( count-- )); do + match-words-by-style - match-words-by-style + word="${(j..)matched_words[4,5]}" - word="${(j..)matched_words[4,5]}" - - if [[ -n $word ]]; then - if [[ -n $done || $LASTWIDGET = *kill* ]]; then - CUTBUFFER="$CUTBUFFER$word" - else - killring=("$CUTBUFFER" "${(@)killring[1,-2]}") - CUTBUFFER=$word - fi - RBUFFER=${(j..)matched_words[6,7]} + if [[ -n $word ]]; then + if [[ -n $done || $LASTWIDGET = *kill* ]]; then + CUTBUFFER="$CUTBUFFER$word" else - return 1 + zle copy-region-as-kill $word fi - done=1 + RBUFFER=${(j..)matched_words[6,7]} + else + return 1 + fi + done=1 done return 0 diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index 30fa0cc5b..48739e531 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -337,14 +337,21 @@ killregion(UNUSED(char **args)) /**/ int -copyregionaskill(UNUSED(char **args)) +copyregionaskill(char **args) { - if (mark > zlell) - mark = zlell; - if (mark > zlecs) - cut(zlecs, mark - zlecs, 0); - else - cut(mark, zlecs - mark, 1); + if (*args) { + int len; + ZLE_STRING_T line = stringaszleline(*args, 0, &len, NULL, NULL); + cuttext(line, len, -1); + free(line); + } else { + if (mark > zlell) + mark = zlell; + if (mark > zlecs) + cut(zlecs, mark - zlecs, 0); + else + cut(mark, zlecs - mark, 1); + } return 0; } diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 9b769b5a0..6583ef503 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -420,9 +420,34 @@ forekill(int ct, int dir) shiftchars(i, ct); } + +/* + * Put the ct characters starting at zleline + i into the + * cutbuffer, circling the kill ring if necessary (it's + * not if we're dealing with vi buffers, which is detected + * internally). The text is not removed from zleline. + * + * dir indicates how the text is to be added to the cutbuffer, + * if the cutbuffer wasn't zeroed (this depends on the last + * command being a kill). If dir is 1, the new text goes + * to the front of the cut buffer. If dir is -1, the cutbuffer + * is completely overwritten. + */ + /**/ void cut(int i, int ct, int dir) +{ + cuttext(zleline + i, ct, dir); +} + +/* + * As cut, but explicitly supply the text together with its length. + */ + +/**/ +void +cuttext(ZLE_STRING_T line, int ct, int dir) { if (!ct) return; @@ -434,7 +459,7 @@ cut(int i, int ct, int dir) if (!(zmod.flags & MOD_VIAPP) || !b->buf) { free(b->buf); b->buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE); - ZS_memcpy(b->buf, zleline + i, ct); + ZS_memcpy(b->buf, line, ct); b->len = ct; b->flags = vilinerange ? CUTBUFFER_LINE : 0; } else { @@ -448,7 +473,7 @@ cut(int i, int ct, int dir) * ZLE_CHAR_SIZE); if (b->flags & CUTBUFFER_LINE) b->buf[len++] = ZWC('\n'); - ZS_memcpy(b->buf + len, zleline + i, ct); + ZS_memcpy(b->buf + len, line, ct); b->len = len + ct; } return; @@ -459,7 +484,7 @@ cut(int i, int ct, int dir) for(n=34; n>26; n--) vibuf[n] = vibuf[n-1]; vibuf[26].buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE); - ZS_memcpy(vibuf[26].buf, zleline + i, ct); + ZS_memcpy(vibuf[26].buf, line, ct); vibuf[26].len = ct; vibuf[26].flags = vilinerange ? CUTBUFFER_LINE : 0; } @@ -467,7 +492,7 @@ cut(int i, int ct, int dir) cutbuf.buf = (ZLE_STRING_T)zalloc(ZLE_CHAR_SIZE); cutbuf.buf[0] = ZWC('\0'); cutbuf.len = cutbuf.flags = 0; - } else if (!(lastcmd & ZLE_KILL)) { + } else if (!(lastcmd & ZLE_KILL) || dir < 0) { Cutbuffer kptr; if (!kring) { kringsize = KRINGCTDEF; @@ -485,7 +510,7 @@ cut(int i, int ct, int dir) if (dir) { ZLE_STRING_T s = (ZLE_STRING_T)zalloc((cutbuf.len + ct)*ZLE_CHAR_SIZE); - ZS_memcpy(s, zleline + i, ct); + ZS_memcpy(s, line, ct); ZS_memcpy(s + ct, cutbuf.buf, cutbuf.len); free(cutbuf.buf); cutbuf.buf = s; @@ -493,7 +518,7 @@ cut(int i, int ct, int dir) } else { cutbuf.buf = realloc((char *)cutbuf.buf, (cutbuf.len + ct) * ZLE_CHAR_SIZE); - ZS_memcpy(cutbuf.buf + cutbuf.len, zleline + i, ct); + ZS_memcpy(cutbuf.buf + cutbuf.len, line, ct); cutbuf.len += ct; } if(vilinerange) -- cgit 1.4.1