aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-09-23 11:35:15 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-09-23 11:45:25 +0200
commitc2887621a37f429e2e05b561631fff01da8bd462 (patch)
tree35ece0d6ab9593bc80d8d307a4c021cc307207b5
parentfbaa927a49694f771d770383bde3e1137fe172d4 (diff)
downloadsciteco-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.template25
-rw-r--r--sample.teco_ini2
-rw-r--r--src/core-commands.c7
-rw-r--r--src/interface-curses/interface.c41
-rw-r--r--src/sciteco.h2
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)
};