diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-09-23 11:35:15 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-09-23 11:45:25 +0200 |
commit | c2887621a37f429e2e05b561631fff01da8bd462 (patch) | |
tree | 35ece0d6ab9593bc80d8d307a4c021cc307207b5 | |
parent | fbaa927a49694f771d770383bde3e1137fe172d4 (diff) | |
download | sciteco-c2887621a37f429e2e05b561631fff01da8bd462.tar.gz |
allow OSC-52 clipboards on all terminal emulators
* The XTerm version is still checked if we detect running under XTerm.
* Actually, the XTerm implementation is broken for Unicode clipboard contents.
* Kitty supports OSC-52, but you __must__ enable read-clipboard.
With read-clipboard-ask, there will be a timeout.
But we cannot read without a timeout since otherwise we would hang indefinitely
if the escape sequence turns out to not work.
* For urxvt, I have hacked an existing extension:
https://gist.github.com/rhaberkorn/d7406420b69841ebbcab97548e38b37d
* st currently supports only setting the clipboard, but not querying it.
-rw-r--r-- | doc/sciteco.7.template | 25 | ||||
-rw-r--r-- | sample.teco_ini | 2 | ||||
-rw-r--r-- | src/core-commands.c | 7 | ||||
-rw-r--r-- | src/interface-curses/interface.c | 41 | ||||
-rw-r--r-- | src/sciteco.h | 2 |
5 files changed, 50 insertions, 27 deletions
diff --git a/doc/sciteco.7.template b/doc/sciteco.7.template index 193d029..a476091 100644 --- a/doc/sciteco.7.template +++ b/doc/sciteco.7.template @@ -1525,16 +1525,27 @@ The existence of a clipboard register can thus be checked in macros to determine whether getting and modifying that particular clipboard is supported natively. .br -.SCITECO_TOPIC xterm +.SCITECO_TOPIC OSC-52 xterm \*(ST does \fBnot\fP generally support clipboards on ncurses, -but has special support when used with a sufficiently recent version -of \fBxterm\fP(1). -Since the operability of XTerm clipboards cannot be tested +but has special support for OSC-52 escape sequences, as were +introduced by sufficiently recent versions of +.BR xterm (1) +and have since been adopted by several other terminal emulators. +Since the operability of OSC-52 clipboards cannot be tested automatically, users will have to set the flag 256 of the -\fBED\fP flags if and only if their XTerm is configured for allowing +\fBED\fP flags if and only if their terminal emulator is properly +configured. +.BR xterm (1) +for instance must be configured for allowing the \fISetSelection\fP and \fIGetSelection\fP window operations. -\*(ST will still check whether XTerm is actually used in -a particular session. +If running under +.BR xterm (1), +\*(ST will still check whether the XTerm version is sufficient. +.SCITECO_TOPIC Kitty +Other terminal emulators like Kitty may ask for permission to read the +clipboard (\fBread-clipboard-ask\fP). +This is not supported by \*(ST and must be disabled +(use \fBread-clipboard\fP instead). .SCITECO_TOPIC xclip If native clipboard support is unavailable, users may still fall back to using external tools like \fBxclip\fP(1) diff --git a/sample.teco_ini b/sample.teco_ini index 869bfb9..2935d95 100644 --- a/sample.teco_ini +++ b/sample.teco_ini @@ -56,7 +56,7 @@ EMQ[$SCITECOPATH]/session.tes ! Enable default function key macros ! EMQ[$SCITECOPATH]/fnkeys.tes -! Uncomment if XTerm allows clipboard operations ! +! Uncomment if terminal supports OSC-52 clipboards ! ! 0,256ED ! ! Uncomment to enable Unicode icons in the Curses UI ! diff --git a/src/core-commands.c b/src/core-commands.c index 300ffef..abe5604 100644 --- a/src/core-commands.c +++ b/src/core-commands.c @@ -2061,10 +2061,9 @@ teco_state_ecommand_close(teco_machine_main_t *ctx, GError **error) * - 128: Enable/Disable enforcement of UNIX98 * \(lq/bin/sh\(rq emulation for operating system command * executions - * - 256: Enable/Disable \fBxterm\fP(1) clipboard support. - * Should only be enabled if XTerm allows the - * \fIGetSelection\fP and \fISetSelection\fP window - * operations. + * - 256: Enable/Disable OSC-52 clipboard support. + * Must only be enabled if the terminal emulator is configured + * properly. * - 512: Enable/Disable Unicode icons in the Curses UI. * This requires a capable font, like the ones provided * by the \(lqNerd Fonts\(rq project. diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index 370fc27..039577f 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -560,7 +560,7 @@ teco_interface_init_screen(void) g_assert(teco_interface.screen_tty != NULL); teco_interface.screen = newterm(NULL, teco_interface.screen_tty, teco_interface.screen_tty); - if (!teco_interface.screen) { + if (G_UNLIKELY(!teco_interface.screen)) { g_fprintf(stderr, "Error initializing interactive mode. " "$TERM may be incorrect.\n"); exit(EXIT_FAILURE); @@ -1255,9 +1255,17 @@ teco_interface_init_clipboard(void) * must be enabled. * There is no way to find out if they are but we must * not register the clipboard registers if they aren't. - * Therefore, a special XTerm clipboard ED flag an be set by the user. + * Still, XTerm clipboards are broken with Unicode characters. + * Also, there are other terminal emulators supporting OSC-52, + * so the XTerm version is only checked if the terminal identifies as XTerm. + * Also, a special clipboard ED flag must be set by the user. + * + * NOTE: Apparently there is also a terminfo entry Ms, but it's probably + * not worth using it since it won't always be set and even if set, does not + * tell you whether the terminal will actually answer to the escape sequence or not. */ - if (!(teco_ed & TECO_ED_XTERM_CLIPBOARD) || teco_xterm_version() < 203) + if (!(teco_ed & TECO_ED_OSC52) || + (teco_xterm_version() >= 0 && teco_xterm_version() < 203)) return; teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("")); @@ -1323,6 +1331,8 @@ teco_interface_set_clipboard(const gchar *name, const gchar *str, gsize str_len, gboolean teco_interface_get_clipboard(const gchar *name, gchar **str, gsize *len, GError **error) { + gboolean ret = TRUE; + /* * Query the clipboard -- XTerm will reply with the * OSC-52 command that would set the current selection. @@ -1350,11 +1360,12 @@ teco_interface_get_clipboard(const gchar *name, gchar **str, gsize *len, GError * Skip "\e]52;x;" (7 characters). */ for (gint i = 0; i < 7; i++) { - if (wgetch(teco_interface.input_pad) == ERR) { + ret = wgetch(teco_interface.input_pad) != ERR; + if (!ret) { /* timeout */ g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, "Timed out reading XTerm clipboard"); - goto error; + goto cleanup; } } @@ -1371,15 +1382,21 @@ teco_interface_get_clipboard(const gchar *name, gchar **str, gsize *len, GError gchar buffer[MAX(3, 7)]; gchar c = (gchar)wgetch(teco_interface.input_pad); - if (c == ERR) { + ret = c != ERR; + if (!ret) { /* timeout */ g_string_free(str_base64, TRUE); g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, "Timed out reading XTerm clipboard"); - goto error; + goto cleanup; } if (c == '\a') break; + if (c == '\e') { + /* OSC escape sequence can also be terminated by "\e\\" */ + c = (gchar)wgetch(teco_interface.input_pad); + break; + } /* * This could be simplified using sscanf() and @@ -1394,20 +1411,16 @@ teco_interface_get_clipboard(const gchar *name, gchar **str, gsize *len, GError g_string_append_len(str_base64, buffer, out_len); } - cbreak(); - keypad(teco_interface.input_pad, TRUE); - if (str) *str = str_base64->str; *len = str_base64->len; g_string_free(str_base64, !str); - return TRUE; -error: - cbreak(); +cleanup: keypad(teco_interface.input_pad, TRUE); - return FALSE; + nodelay(teco_interface.input_pad, TRUE); + return ret; } #else /* !PDCURSES && !CURSES_TTY */ diff --git a/src/sciteco.h b/src/sciteco.h index 1597439..7fe09d4 100644 --- a/src/sciteco.h +++ b/src/sciteco.h @@ -91,7 +91,7 @@ enum { TECO_ED_HOOKS = (1 << 5), //TECO_ED_MOUSEKEY = (1 << 6), TECO_ED_SHELLEMU = (1 << 7), - TECO_ED_XTERM_CLIPBOARD = (1 << 8), + TECO_ED_OSC52 = (1 << 8), TECO_ED_ICONS = (1 << 9) }; |