users/11419: zle copy-region-as-kill <string>

adds text to the kill ring
This commit is contained in:
Peter Stephenson 2007-04-19 14:16:22 +00:00
parent 0d101890d0
commit c6dfb2999d
7 changed files with 92 additions and 49 deletions

View file

@ -1,5 +1,12 @@
2007-04-19 Peter Stephenson <pws@csr.com>
* 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.

View file

@ -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)

View file

@ -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

View file

@ -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]}"

View file

@ -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

View file

@ -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;
}

View file

@ -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)