diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-07-13 00:53:58 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-07-13 00:53:58 +0300 |
commit | 8c6de6cc718debf44f6056a4c34c4fbb13bc5020 (patch) | |
tree | a522cb6d5608b3a4ba08fdb8a3f840514eb07281 /src/qreg.c | |
parent | 078c1927cffc6514168566c267151a8d6eca7367 (diff) | |
download | sciteco-8c6de6cc718debf44f6056a4c34c4fbb13bc5020.tar.gz |
allow changing the default clipboard by setting the `~` integer
* It continues to default to 67 (C), which is the system clipboard.
But you can now overwrite it e.g. by adding `^^PU~` to the profile.
* This fixes a minor memory leak:
If you set one of the clipboard registers in the profile (initializing
them as plain registers), the clipboard register had been leaked.
The clipboard registers now replace any existing register,
while at the same time preserving the numeric part.
* All remaining Q-Reg table insertions use a new function
teco_qreg_table_insert_unique() which adds an assertion, so that
we notice any future possible memory leaks.
Diffstat (limited to 'src/qreg.c')
-rw-r--r-- | src/qreg.c | 75 |
1 files changed, 60 insertions, 15 deletions
@@ -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; |