diff options
-rw-r--r-- | doc/sciteco.7.template | 11 | ||||
-rw-r--r-- | fallback.teco_ini | bin | 2141 -> 2221 bytes | |||
-rw-r--r-- | src/interface-curses/interface.c | 19 | ||||
-rw-r--r-- | src/interface-gtk/interface.c | 16 | ||||
-rw-r--r-- | src/main.c | 18 | ||||
-rw-r--r-- | src/qreg.c | 75 | ||||
-rw-r--r-- | src/qreg.h | 19 |
7 files changed, 122 insertions, 36 deletions
diff --git a/doc/sciteco.7.template b/doc/sciteco.7.template index ba43ac2..16a54a6 100644 --- a/doc/sciteco.7.template +++ b/doc/sciteco.7.template @@ -1591,6 +1591,15 @@ 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 +If there are multiple clipboard registers, you can choose +the default one via the ASCII code in the numeric cell of +register \(lq~\(rq, which defaults to 67 (\(lq~C\(rq). +For instance if setting \(lq^^PU~\(rq, register \(lq~\(rq +and register \(lq~P\(rq will refer to the same primary +clipboard. +The numeric parts of all the other clipboard registers are +currently not used by \*(ST. +.br \*(ST supports two ways of driving the clipboard on ncurses. .SCITECO_TOPIC OSC-52 xterm First of all, there is built-in support for OSC-52 escape sequences, @@ -1638,8 +1647,6 @@ EOL normalization will take place (if enabled), so that pasting clipboards does not introduce unexpected EOL sequences. The Q-Register view's EOL mode will \fBnot\fP be guessed from the original clipboard contents, though. -The numeric parts of the clipboard registers are currently -not used by \*(ST. .TP .BI ^K key Key macro registers as documented in section diff --git a/fallback.teco_ini b/fallback.teco_ini Binary files differindex 72c13f7..cee87dc 100644 --- a/fallback.teco_ini +++ b/fallback.teco_ini diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index 54ed1d6..1b04f47 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -1239,7 +1239,8 @@ teco_interface_init_clipboard(void) if (rc == PDC_CLIP_SUCCESS) PDC_freeclipboard(contents); - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("")); + teco_qreg_table_replace(&teco_qreg_table_globals, + teco_qreg_clipboard_new(""), TRUE, NULL); } gboolean @@ -1303,8 +1304,10 @@ get_selection_by_name(const gchar *name) * (everything gets passed down), but currently we * only register the three standard registers * "~", "~P", "~S" and "~C". + * (We are never called with "~", though.) */ - return g_ascii_tolower(*name) ? : 'c'; + g_assert(*name != '\0'); + return g_ascii_tolower(*name); } /* @@ -1503,10 +1506,14 @@ teco_interface_init_clipboard(void) !teco_qreg_table_find(&teco_qreg_table_globals, "$SCITECO_CLIPBOARD_GET", 22))) return; - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("")); - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("P")); - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("S")); - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("C")); + teco_qreg_table_replace(&teco_qreg_table_globals, + teco_qreg_clipboard_new(""), TRUE, NULL); + teco_qreg_table_replace(&teco_qreg_table_globals, + teco_qreg_clipboard_new("P"), TRUE, NULL); + teco_qreg_table_replace(&teco_qreg_table_globals, + teco_qreg_clipboard_new("S"), TRUE, NULL); + teco_qreg_table_replace(&teco_qreg_table_globals, + teco_qreg_clipboard_new("C"), TRUE, NULL); } gboolean diff --git a/src/interface-gtk/interface.c b/src/interface-gtk/interface.c index 3d33972..6c22590 100644 --- a/src/interface-gtk/interface.c +++ b/src/interface-gtk/interface.c @@ -160,10 +160,14 @@ teco_interface_init(void) * clipboards/selections are supported on this system, * so we register only some default ones. */ - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("")); - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("P")); - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("S")); - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_clipboard_new("C")); + teco_qreg_table_replace(&teco_qreg_table_globals, + teco_qreg_clipboard_new(""), TRUE, NULL); + teco_qreg_table_replace(&teco_qreg_table_globals, + teco_qreg_clipboard_new("P"), TRUE, NULL); + teco_qreg_table_replace(&teco_qreg_table_globals, + teco_qreg_clipboard_new("S"), TRUE, NULL); + teco_qreg_table_replace(&teco_qreg_table_globals, + teco_qreg_clipboard_new("C"), TRUE, NULL); teco_interface.event_queue = g_queue_new(); @@ -606,6 +610,8 @@ teco_interface_cmdline_update(const teco_cmdline_t *cmdline) static GdkAtom teco_interface_get_selection_by_name(const gchar *name) { + g_assert(*name != '\0'); + /* * We can use gdk_atom_intern() to support arbitrary X11 selection * names. However, since we cannot find out which selections are @@ -614,11 +620,9 @@ teco_interface_get_selection_by_name(const gchar *name) * Checking them here avoids expensive X server roundtrips. */ switch (*name) { - case '\0': return GDK_NONE; case 'P': return GDK_SELECTION_PRIMARY; case 'S': return GDK_SELECTION_SECONDARY; case 'C': return GDK_SELECTION_CLIPBOARD; - default: break; } return gdk_atom_intern(name, FALSE); @@ -419,15 +419,20 @@ main(int argc, char **argv) * DEC TECO has them in the global table, though. */ /* search string and status register */ - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_plain_new("_", 1)); + teco_qreg_table_insert_unique(&teco_qreg_table_globals, + teco_qreg_plain_new("_", 1)); /* replacement string register */ - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_plain_new("-", 1)); + teco_qreg_table_insert_unique(&teco_qreg_table_globals, + teco_qreg_plain_new("-", 1)); /* current document's dot (":") */ - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_dot_new()); + teco_qreg_table_insert_unique(&teco_qreg_table_globals, + teco_qreg_dot_new()); /* current buffer name and number ("*") */ - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_bufferinfo_new()); + teco_qreg_table_insert_unique(&teco_qreg_table_globals, + teco_qreg_bufferinfo_new()); /* current working directory ("$") */ - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_workingdir_new()); + teco_qreg_table_insert_unique(&teco_qreg_table_globals, + teco_qreg_workingdir_new()); /* environment defaults and registers */ teco_initialize_environment(); @@ -513,7 +518,8 @@ main(int argc, char **argv) * If munged file didn't quit, switch into interactive mode */ /* commandline replacement string register */ - teco_qreg_table_insert(&teco_qreg_table_globals, teco_qreg_plain_new("\e", 1)); + teco_qreg_table_insert_unique(&teco_qreg_table_globals, + teco_qreg_plain_new("\e", 1)); teco_undo_enabled = TRUE; teco_ring_set_scintilla_undo(TRUE); @@ -25,6 +25,8 @@ #include <Scintilla.h> +//#include <rb3ptr.h> + #include "sciteco.h" #include "string-utils.h" #include "file-utils.h" @@ -39,6 +41,7 @@ #include "ring.h" #include "eol.h" #include "error.h" +#include "rb3str.h" #include "qreg.h" /** @@ -794,19 +797,25 @@ teco_qreg_workingdir_new(void) * the "\e" register also exists. * Not to mention that environment variable regs also start with dollar. * Perhaps "~" would be a better choice, although it is also already used? - * Most logical would be ".", but this should probably map to to Dot and - * is also ugly to write in practice. + * Most logical would be ".", but it is also ugly to write in practice. * Perhaps "@"... */ return teco_qreg_new(&vtable, "$", 1); } +static inline gchar +teco_qreg_clipboard_get_name(const teco_qreg_t *qreg) +{ + g_assert(1 <= qreg->head.name.len && qreg->head.name.len <= 2 && + *qreg->head.name.data == '~'); + return qreg->head.name.len < 2 ? qreg->integer : qreg->head.name.data[1]; +} + static gboolean teco_qreg_clipboard_set_string(teco_qreg_t *qreg, const gchar *str, gsize len, guint codepage, GError **error) { - g_assert(!teco_string_contains(&qreg->head.name, '\0')); - const gchar *clipboard_name = qreg->head.name.data + 1; + gchar clipboard_name[] = {teco_qreg_clipboard_get_name(qreg), '\0'}; if (teco_ed & TECO_ED_AUTOEOL) { /* @@ -866,8 +875,7 @@ teco_qreg_clipboard_undo_set_string(teco_qreg_t *qreg, GError **error) if (!teco_undo_enabled) return TRUE; - g_assert(!teco_string_contains(&qreg->head.name, '\0')); - const gchar *clipboard_name = qreg->head.name.data + 1; + gchar clipboard_name[] = {teco_qreg_clipboard_get_name(qreg), '\0'}; /* * Ownership of str is passed to the undo token. @@ -885,8 +893,7 @@ static gboolean teco_qreg_clipboard_get_string(teco_qreg_t *qreg, gchar **str, gsize *len, guint *codepage, GError **error) { - g_assert(!teco_string_contains(&qreg->head.name, '\0')); - const gchar *clipboard_name = qreg->head.name.data + 1; + gchar clipboard_name[] = {teco_qreg_clipboard_get_name(qreg), '\0'}; if (!(teco_ed & TECO_ED_AUTOEOL)) /* @@ -930,8 +937,7 @@ teco_qreg_clipboard_get_string(teco_qreg_t *qreg, gchar **str, gsize *len, static gboolean teco_qreg_clipboard_load(teco_qreg_t *qreg, const gchar *filename, GError **error) { - g_assert(!teco_string_contains(&qreg->head.name, '\0')); - const gchar *clipboard_name = qreg->head.name.data + 1; + gchar clipboard_name[] = {teco_qreg_clipboard_get_name(qreg), '\0'}; g_auto(teco_string_t) str = {NULL, 0}; @@ -954,6 +960,12 @@ teco_qreg_clipboard_new(const gchar *name) teco_qreg_t *qreg = teco_qreg_new(&vtable, "~", 1); teco_string_append(&qreg->head.name, name, strlen(name)); + /* + * Register "~" is the default clipboard, which defaults to "~C". + * This is configurable via the integer cell. + */ + if (qreg->head.name.len == 1) + qreg->integer = 'C'; return qreg; } @@ -967,9 +979,9 @@ teco_qreg_table_init(teco_qreg_table_t *table, gboolean must_undo) /* general purpose registers */ for (gchar q = 'A'; q <= 'Z'; q++) - teco_qreg_table_insert(table, teco_qreg_plain_new(&q, sizeof(q))); + teco_qreg_table_insert_unique(table, teco_qreg_plain_new(&q, sizeof(q))); for (gchar q = '0'; q <= '9'; q++) - teco_qreg_table_insert(table, teco_qreg_plain_new(&q, sizeof(q))); + teco_qreg_table_insert_unique(table, teco_qreg_plain_new(&q, sizeof(q))); } /** @memberof teco_qreg_table_t */ @@ -979,10 +991,43 @@ teco_qreg_table_init_locals(teco_qreg_table_t *table, gboolean must_undo) teco_qreg_table_init(table, must_undo); /* search mode ("^X") */ - teco_qreg_table_insert(table, teco_qreg_plain_new("\x18", 1)); + teco_qreg_table_insert_unique(table, teco_qreg_plain_new("\x18", 1)); /* numeric radix ("^R") */ table->radix = teco_qreg_radix_new(); - teco_qreg_table_insert(table, table->radix); + teco_qreg_table_insert_unique(table, table->radix); +} + +/** + * Insert Q-register into table, possibly replacing a register with the same name. + * + * This is useful for initializing Q-registers late when the user could have + * already created one in the profile. + * + * @param table Table to insert into + * @param qreg Q-Register to insert + * @param inherit_int Whether to preserve the numeric part of + * any Q-register found in the table. + * @param error GError + * @return TRUE if error occurred + * @memberof teco_qreg_table_t + */ +gboolean +teco_qreg_table_replace(teco_qreg_table_t *table, teco_qreg_t *qreg, + gboolean inherit_int, GError **error) +{ + teco_qreg_t *found = teco_qreg_table_insert(table, qreg); + if (!found) + return TRUE; + + teco_int_t v; + if (inherit_int && + (!found->vtable->get_integer(found, &v, error) || + !qreg->vtable->set_integer(qreg, v, error))) + return FALSE; + + rb3_replace(&found->head.head, &qreg->head.head); + teco_qreg_free(found); + return TRUE; } static inline void @@ -1409,7 +1454,7 @@ teco_state_qregspec_done(teco_machine_qregspec_t *ctx, GError **error) case TECO_QREG_OPTIONAL_INIT: if (!ctx->result) { ctx->result = teco_qreg_plain_new(ctx->name.data, ctx->name.len); - teco_qreg_table_insert(ctx->result_table, ctx->result); + teco_qreg_table_insert_unique(ctx->result_table, ctx->result); teco_qreg_table_undo_remove(ctx->result); } break; @@ -156,7 +156,13 @@ struct teco_qreg_table_t { void teco_qreg_table_init(teco_qreg_table_t *table, gboolean must_undo); void teco_qreg_table_init_locals(teco_qreg_table_t *table, gboolean must_undo); -/** @memberof teco_qreg_table_t */ +/** + * Insert Q-Register into table. + * + * @return If non-NULL a register with the same name as qreg already + * existed in table. In this case qreg is __not__ automatically freed. + * @memberof teco_qreg_table_t + */ static inline teco_qreg_t * teco_qreg_table_insert(teco_qreg_table_t *table, teco_qreg_t *qreg) { @@ -165,6 +171,17 @@ teco_qreg_table_insert(teco_qreg_table_t *table, teco_qreg_t *qreg) } /** @memberof teco_qreg_table_t */ +static inline void +teco_qreg_table_insert_unique(teco_qreg_table_t *table, teco_qreg_t *qreg) +{ + G_GNUC_UNUSED teco_qreg_t *found = teco_qreg_table_insert(table, qreg); + g_assert(found == NULL); +} + +gboolean teco_qreg_table_replace(teco_qreg_table_t *table, teco_qreg_t *qreg, + gboolean inherit_int, GError **error); + +/** @memberof teco_qreg_table_t */ static inline teco_qreg_t * teco_qreg_table_find(teco_qreg_table_t *table, const gchar *name, gsize len) { |