diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-05-24 01:31:22 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-05-24 01:31:22 +0300 |
commit | 4b266c9616f4eb359be71c44b9b2fa3373265bb0 (patch) | |
tree | 104da896ed48c01371d776e1add4962df1ff3066 | |
parent | 3fda29e44ee0c9ef2a0b81d91af568c7e1c35c1f (diff) | |
download | sciteco-4b266c9616f4eb359be71c44b9b2fa3373265bb0.tar.gz |
new string building construct ^P disables all further string building magic
* Now, `I^P` can replace `EI`.
EI is therefore now free to be repurposed as the new "mung file" command for improved TECO-11 compatibility.
* On the downside when inserting large blocks of TECO code, you will have to write something like
`@I{^P !...! }`
* The construct is also useful when searching for carets as in `S^P^Q^`.
-rw-r--r-- | doc/sciteco.7.template | 6 | ||||
-rw-r--r-- | src/parser.c | 45 | ||||
-rw-r--r-- | src/parser.h | 3 |
3 files changed, 31 insertions, 23 deletions
diff --git a/doc/sciteco.7.template b/doc/sciteco.7.template index 7c49e07..51a4da2 100644 --- a/doc/sciteco.7.template +++ b/doc/sciteco.7.template @@ -1787,6 +1787,12 @@ character and their case is insignificant. In the following list of supported expressions, the caret-notation thus refers to the corresponding control code: .TP +.SCITECO_TOPIC ^P +.B ^P +Disable interpretation of all further string building characters, +so all following characters will be taken verbatim. +There is no way to escape the string terminator after \(lq^P\(rq. +.TP .SCITECO_TOPIC ^Qc ^Rc quote .BI ^Q c .TQ diff --git a/src/parser.c b/src/parser.c index c1d22b2..8ef7a06 100644 --- a/src/parser.c +++ b/src/parser.c @@ -394,9 +394,6 @@ teco_machine_stringbuilding_append(teco_machine_stringbuilding_t *ctx, const gch g_assert(ctx->result != NULL); switch (ctx->mode) { - case TECO_STRINGBUILDING_MODE_NORMAL: - teco_string_append(ctx->result, str, len); - break; case TECO_STRINGBUILDING_MODE_UPPER: { g_autofree gchar *folded = ctx->codepage == SC_CP_UTF8 ? g_utf8_strup(str, len) : g_ascii_strup(str, len); @@ -409,6 +406,9 @@ teco_machine_stringbuilding_append(teco_machine_stringbuilding_t *ctx, const gch teco_string_append(ctx->result, folded, strlen(folded)); break; } + default: + teco_string_append(ctx->result, str, len); + break; } } @@ -436,19 +436,21 @@ TECO_DECLARE_STATE(teco_state_stringbuilding_ctle_n); static teco_state_t * teco_state_stringbuilding_start_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) { - switch (chr) { - case '^': - return &teco_state_stringbuilding_ctl; - case TECO_CTL_KEY('^'): - /* - * Ctrl+^ is inserted verbatim as code 30. - * Otherwise it would expand to a single caret - * just like caret+caret (^^). - */ - break; - default: - if (TECO_IS_CTL(chr)) - return teco_state_stringbuilding_ctl_input(ctx, TECO_CTL_ECHO(chr), error); + if (ctx->mode != TECO_STRINGBUILDING_MODE_DISABLED) { + switch (chr) { + case '^': + return &teco_state_stringbuilding_ctl; + case TECO_CTL_KEY('^'): + /* + * Ctrl+^ is inserted verbatim as code 30. + * Otherwise it would expand to a single caret + * just like caret+caret (^^). + */ + break; + default: + if (TECO_IS_CTL(chr)) + return teco_state_stringbuilding_ctl_input(ctx, TECO_CTL_ECHO(chr), error); + } } return teco_state_stringbuilding_escaped_input(ctx, chr, error); @@ -481,6 +483,11 @@ teco_state_stringbuilding_ctl_input(teco_machine_stringbuilding_t *ctx, gunichar * be abolished altogether. */ break; + case 'P': + if (ctx->parent.must_undo) + teco_undo_guint(ctx->mode); + ctx->mode = TECO_STRINGBUILDING_MODE_DISABLED; + return &teco_state_stringbuilding_start; case 'Q': case 'R': return &teco_state_stringbuilding_escaped; case 'V': return &teco_state_stringbuilding_lower; @@ -523,8 +530,6 @@ teco_state_stringbuilding_escaped_input(teco_machine_stringbuilding_t *ctx, guni * is that we don't try to casefold non-ANSI characters in single-byte mode. */ switch (ctx->mode) { - case TECO_STRINGBUILDING_MODE_NORMAL: - break; case TECO_STRINGBUILDING_MODE_UPPER: chr = ctx->codepage == SC_CP_UTF8 || chr < 0x80 ? g_unichar_toupper(chr) : chr; @@ -740,8 +745,6 @@ teco_state_stringbuilding_ctle_u_input(teco_machine_stringbuilding_t *ctx, gunic if (value < 0 || !g_unichar_validate(value)) goto error_codepoint; switch (ctx->mode) { - case TECO_STRINGBUILDING_MODE_NORMAL: - break; case TECO_STRINGBUILDING_MODE_UPPER: value = g_unichar_toupper(value); break; @@ -754,8 +757,6 @@ teco_state_stringbuilding_ctle_u_input(teco_machine_stringbuilding_t *ctx, gunic if (value < 0 || value > 0xFF) goto error_codepoint; switch (ctx->mode) { - case TECO_STRINGBUILDING_MODE_NORMAL: - break; case TECO_STRINGBUILDING_MODE_UPPER: value = g_ascii_toupper(value); break; diff --git a/src/parser.h b/src/parser.h index 5477150..41b960b 100644 --- a/src/parser.h +++ b/src/parser.h @@ -332,7 +332,8 @@ gboolean teco_machine_input(teco_machine_t *ctx, gunichar chr, GError **error); typedef enum { TECO_STRINGBUILDING_MODE_NORMAL = 0, TECO_STRINGBUILDING_MODE_UPPER, - TECO_STRINGBUILDING_MODE_LOWER + TECO_STRINGBUILDING_MODE_LOWER, + TECO_STRINGBUILDING_MODE_DISABLED } teco_stringbuilding_mode_t; /** |