diff options
author | Oliver Kiddle <opk@zsh.org> | 2022-11-17 20:05:12 +0100 |
---|---|---|
committer | Oliver Kiddle <opk@zsh.org> | 2022-11-17 20:05:12 +0100 |
commit | c4d557bb0a9cf6a7241f760ad466e2d91359ceb2 (patch) | |
tree | 9441513ef4b6f3fabdeb1a9a31ed1a971c3b63d1 /Src | |
parent | b1533066ca7d50c88b37ce72093c12cf19807818 (diff) | |
download | zsh-c4d557bb0a9cf6a7241f760ad466e2d91359ceb2.tar.gz zsh-c4d557bb0a9cf6a7241f760ad466e2d91359ceb2.zip |
50934: use OSC 52 escape sequence when copying to "* or "+ vi buffers
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Zle/zle.h | 3 | ||||
-rw-r--r-- | Src/Zle/zle_utils.c | 32 | ||||
-rw-r--r-- | Src/Zle/zle_vi.c | 9 |
3 files changed, 40 insertions, 4 deletions
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index 391586c4a..f59545397 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -258,6 +258,9 @@ struct modifier { #define MOD_NULL (1<<5) /* throw away text for the vi cut buffer */ #define MOD_CHAR (1<<6) /* force character-wise movement */ #define MOD_LINE (1<<7) /* force line-wise movement */ +#define MOD_PRI (1<<8) /* OS primary selection for the vi cut buffer */ +#define MOD_CLIP (1<<9) /* OS clipboard for the vi cut buffer */ +#define MOD_OSSEL (MOD_PRI | MOD_CLIP) /* either system selection */ /* current modifier status */ diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 526216fa7..3d9017dcf 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -936,6 +936,28 @@ cut(int i, int ct, int flags) cuttext(zleline + i, ct, flags); } +static char* +base64_encode(const char *src, size_t len) { + static const char* base64_table = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + const unsigned char *end = (unsigned char *)src + len; + const unsigned char *in = (unsigned char *)src; + char *ret = zhalloc(1 + 4 * ((len + 2) / 3)); /* 4 bytes out for 3 in */ + char *cur = ret; + + for (; end - in > 0; in += 3, cur += 4) { + unsigned int n = *in << 16; + cur[3] = end - in > 2 ? base64_table[(n |= in[2]) & 0x3f] : '='; + cur[2] = end - in > 1 ? base64_table[((n |= in[1]<<8) >> 6) & 0x3f] : '='; + cur[1] = base64_table[(n >> 12) & 0x3f]; + cur[0] = base64_table[n >> 18]; + } + *cur = '\0'; + + return ret; +} + /* * As cut, but explicitly supply the text together with its length. */ @@ -948,7 +970,15 @@ cuttext(ZLE_STRING_T line, int ct, int flags) return; UNMETACHECK(); - if (zmod.flags & MOD_VIBUF) { + if (zmod.flags & MOD_OSSEL) { + int cutll; + char *mbcut = zlelineasstring(line, ct, 0, &cutll, NULL, 1); + unmetafy(mbcut, &cutll); + mbcut = base64_encode(mbcut, cutll); + + fprintf(shout, "\e]52;%c;%s\a", zmod.flags & MOD_CLIP ? 'c' : 'p', + mbcut); + } else if (zmod.flags & MOD_VIBUF) { struct cutbuffer *b = &vibuf[zmod.vibuf]; if (!(zmod.flags & MOD_VIAPP) || !b->buf) { diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c index 0f198d0e8..24d9de6ea 100644 --- a/Src/Zle/zle_vi.c +++ b/Src/Zle/zle_vi.c @@ -1014,6 +1014,9 @@ int visetbuffer(char **args) { ZLE_INT_T ch; + ZLE_CHAR_T *match = ZWS("_*+"); + int registermod[] = { MOD_NULL, MOD_PRI, MOD_CLIP }; + ZLE_CHAR_T *found; if (*args) { ch = **args; @@ -1022,12 +1025,12 @@ visetbuffer(char **args) } else { ch = getfullchar(0); } - if (ch == ZWC('_')) { - zmod.flags |= MOD_NULL; + if ((found = ZS_strchr(match, ch))) { + zmod.flags |= registermod[found - match]; prefixflag = 1; return 0; } else - zmod.flags &= ~MOD_NULL; + zmod.flags &= ~(MOD_NULL | MOD_OSSEL); if ((ch < ZWC('0') || ch > ZWC('9')) && (ch < ZWC('a') || ch > ZWC('z')) && (ch < ZWC('A') || ch > ZWC('Z'))) |