aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-11-22 16:59:07 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-11-23 02:33:49 +0300
commit1cfe37610253c20a4fcb0d937c29e70894ecc4f5 (patch)
treeac05844c25fc0918e8fd451d8912fd7f1964acb7
parent07b52f78680858683acb4e40b158f8926285cae4 (diff)
downloadsciteco-1cfe37610253c20a4fcb0d937c29e70894ecc4f5.tar.gz
the search mode and current radix are mapped to __local__ Q-Registers ^X and ^R now (refs #17)
* This way the search mode and radix are local to the current macro frame, unless the macro was invoked with :Mq. If colon-modified, you can reproduce the same effect by calling [.^X 0^X ... ].^X * The radix register is cached in the Q-Reg table as an optimization. This could be done with the other "special" registers as well, but at the cost of larger stack frames. * In order to allow constructs like [.^X typed with upcarets, the Q-Register specification syntax has been extended: ^c is the corresponding control code instead of the register "^".
-rw-r--r--TODO21
-rw-r--r--doc/sciteco.7.template29
-rw-r--r--src/core-commands.c55
-rw-r--r--src/expressions.c25
-rw-r--r--src/expressions.h15
-rw-r--r--src/main.c7
-rw-r--r--src/parser.c4
-rw-r--r--src/qreg-commands.c5
-rw-r--r--src/qreg.c43
-rw-r--r--src/qreg.h7
-rw-r--r--src/search.c27
-rw-r--r--tests/testsuite.at3
12 files changed, 185 insertions, 56 deletions
diff --git a/TODO b/TODO
index 9a353eb..468c040 100644
--- a/TODO
+++ b/TODO
@@ -31,16 +31,6 @@ Known Bugs:
reverse of STYLE_DEFAULT.
Perhaps we must call init_color() before initializing color pairs
(currently done by Scinterm).
- * session.save should save and reset ^R. Perhaps ^R should be
- mapped to a Q-Reg to allow [^R. Currently, saving the buffer session
- fails if ^R != 10.
- On the other hand, given that almost any macro depends on the
- correct radix, __every__ portable macro would have to save the
- old radix. Perhaps it's better to make the radix a property of the
- current macro invocation frame and guarantee ^R == 10 at the beginning
- of macros.
- Since :M should probably inherit the radix, having a ^R register would
- still be useful.
* Saving another user's file will only preserve the user when run as root.
Generally, it is hard to ensure that a) save point files can be created
and b) the file mode and ownership of re-created files can be preserved.
@@ -582,6 +572,14 @@ Features:
This is because Groff decomposes characters in intermediate output.
Either we have to consult devutf8/R or use wrap g_unichar_compose().
This will be important once we want to localize documentation.
+ * Search and replace registers ("-" and "_") should probably be local
+ to the current macro frame, so you don't have to save and restore
+ them all the time in portable macros.
+ This however means they should be in local Q-Registers which
+ is a significant deviation from DEC TECO.
+ Perhaps a few select local Q-Registers (-, _, ^X, ^R) should be
+ accessible with the global reg syntax as well, so G- is equivalent
+ to G.-?
Optimizations:
* Use SC_DOCUMENTOPTION_STYLES_NONE in batch mode.
@@ -598,7 +596,8 @@ Optimizations:
roughly the same size.
Should be tested on Windows, though.
* commonly used (special) Q-Registers could be cached,
- saving the q-reg table lookup
+ saving the q-reg table lookup.
+ This is already done with ^R (radix) in teco_qreg_table_t.
* refactor search commands (create proper base class)
* undo__teco_interface_ssm() could always include the check for
teco_current_doc_must_undo().
diff --git a/doc/sciteco.7.template b/doc/sciteco.7.template
index 15247a5..8ded77c 100644
--- a/doc/sciteco.7.template
+++ b/doc/sciteco.7.template
@@ -1417,7 +1417,7 @@ textual and numeric cells \(em they overwrite default operations
with custom side-effects in order to support unique idioms.
Some of the registers with special significance are initialized
by \*(ST while others must be manually defined.
-The following list is an overview of all special global registers:
+The following list is an overview of all special \fIglobal\fP registers:
.TP 2
.SCITECO_TOPIC "search condition"
.BR _ " (underscore)"
@@ -1583,6 +1583,24 @@ in the \fBED\fP flags (see subsection \fBBuffer Editing Hooks\fP).
The numeric part of register \fBED\fP is currently unused and
the register is not automatically initialized on startup.
.LP
+Furthermore, \*(ST supports special local Q-Registers.
+The values of these properties will therefore be known at the beginning
+of macro calls (unless these calls are colon-modified).
+The following list is an overview of all special \fIlocal\fP registers:
+.TP 2
+.BR ^R " (CTRL+R)"
+The current radix as reported and configurable with the
+\fB^R\fP, \fB^O\fP and \fB^D\fP commands (10 by default).
+The string part of this register is currently unused.
+.TP
+.BR ^X " (CTRL+X)"
+The current search mode flag as set and reported by the
+.B ^X
+command.
+The default value of 0 means that searches are always
+case-insensitive at the beginning of macro calls.
+The string part of this register is currently unused.
+.LP
Some commands may create and initialize new registers if
necessary, while it is an error to access undefined registers
for some other commands.
@@ -1602,14 +1620,23 @@ specifications:
.BI . c
Refers to a one character Q-Register.
The one character name is upper-cased.
+All one character names except for \(lq.\(rq, \(lq^\(rq and \(lq#\(rq
+can be referenced this way.
If lead by a dot, the name refers to a local Q-Register,
otherwise to a global one.
.TP
+.BI ^ c
+.TQ
+.BI .^ c
+Refers to a Q-Register, whose name is a single byte control code.
+Those can be typed with upcarets as well.
+.TP
.BI # cc
.TQ
.BI .# cc
Refers to a two character global or local Q-Register whose
name is upper-cased.
+\# FIXME: Space characters could/should be disallowed here.
.TP
.BI [ name ]
.TQ
diff --git a/src/core-commands.c b/src/core-commands.c
index ca0245b..ba7aaa8 100644
--- a/src/core-commands.c
+++ b/src/core-commands.c
@@ -196,7 +196,8 @@ teco_state_start_backslash(teco_machine_main_t *ctx, GError **error)
return;
gchar buffer[TECO_EXPRESSIONS_FORMAT_LEN];
- gchar *str = teco_expressions_format(buffer, value);
+ gchar *str = teco_expressions_format(buffer, value,
+ ctx->qreg_table_locals->radix);
g_assert(*str != '\0');
teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0);
@@ -207,6 +208,12 @@ teco_state_start_backslash(teco_machine_main_t *ctx, GError **error)
if (teco_current_doc_must_undo())
undo__teco_interface_ssm(SCI_UNDO, 0, 0);
} else {
+ teco_qreg_t *qreg = ctx->qreg_table_locals->radix;
+ assert(qreg != NULL);
+ teco_int_t radix;
+ if (!qreg->vtable->get_integer(qreg, &radix, error))
+ return;
+
uptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0);
gchar c = (gchar)teco_interface_ssm(SCI_GETCHARAT, pos, 0);
teco_int_t v = 0;
@@ -219,11 +226,11 @@ teco_state_start_backslash(teco_machine_main_t *ctx, GError **error)
for (;;) {
c = teco_ascii_toupper((gchar)teco_interface_ssm(SCI_GETCHARAT, pos, 0));
- if (c >= '0' && c <= '0' + MIN(teco_radix, 10) - 1)
- v = (v*teco_radix) + (c - '0');
+ if (c >= '0' && c <= '0' + MIN(radix, 10) - 1)
+ v = (v*radix) + (c - '0');
else if (c >= 'A' &&
- c <= 'A' + MIN(teco_radix - 10, 26) - 1)
- v = (v*teco_radix) + 10 + (c - 'A');
+ c <= 'A' + MIN(radix - 10, 26) - 1)
+ v = (v*radix) + 10 + (c - 'A');
else
break;
@@ -1164,7 +1171,7 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
*/
case '0' ... '9':
if (ctx->mode == TECO_MODE_NORMAL)
- teco_expressions_add_digit(chr);
+ teco_expressions_add_digit(chr, ctx->qreg_table_locals->radix);
return &teco_state_start;
case '*':
@@ -1710,7 +1717,11 @@ teco_state_control_exit(teco_machine_main_t *ctx, GError **error)
static void
teco_state_control_octal(teco_machine_main_t *ctx, GError **error)
{
- teco_set_radix(8);
+ teco_qreg_t *qreg = ctx->qreg_table_locals->radix;
+ assert(qreg != NULL);
+ if (!qreg->vtable->undo_set_integer(qreg, error) ||
+ !qreg->vtable->set_integer(qreg, 8, NULL))
+ return;
}
/*$ ^D decimal
@@ -1719,7 +1730,11 @@ teco_state_control_octal(teco_machine_main_t *ctx, GError **error)
static void
teco_state_control_decimal(teco_machine_main_t *ctx, GError **error)
{
- teco_set_radix(10);
+ teco_qreg_t *qreg = ctx->qreg_table_locals->radix;
+ assert(qreg != NULL);
+ if (!qreg->vtable->undo_set_integer(qreg, error) ||
+ !qreg->vtable->set_integer(qreg, 10, NULL))
+ return;
}
/*$ ^R radix
@@ -1729,19 +1744,35 @@ teco_state_control_decimal(teco_machine_main_t *ctx, GError **error)
* Set current radix to arbitrary value <radix>.
* If <radix> is omitted, the command instead
* returns the current radix.
+ *
+ * An alternative way to access the radix is via the "^R" local Q-Register.
+ * Consequently, the radix is local to the current macro invocation frame,
+ * unless the macro call was colon-modified.
*/
static void
teco_state_control_radix(teco_machine_main_t *ctx, GError **error)
{
if (!teco_expressions_eval(FALSE, error))
return;
+
+ teco_qreg_t *qreg = ctx->qreg_table_locals->radix;
+ assert(qreg != NULL);
+ teco_int_t radix;
+
if (!teco_expressions_args()) {
- teco_expressions_push(teco_radix);
+ if (!qreg->vtable->get_integer(qreg, &radix, error))
+ return;
+ teco_expressions_push(radix);
} else {
- teco_int_t v;
- if (!teco_expressions_pop_num_calc(&v, 0, error))
+ /*
+ * FIXME: We should restrict the allowed values.
+ * 0^R 23\ crashes for instance.
+ * The ^R register should consequently also be "special".
+ */
+ if (!teco_expressions_pop_num_calc(&radix, 0, error) ||
+ !qreg->vtable->undo_set_integer(qreg, error) ||
+ !qreg->vtable->set_integer(qreg, radix, error))
return;
- teco_set_radix(v);
}
}
diff --git a/src/expressions.c b/src/expressions.c
index ee6b4dc..25213e9 100644
--- a/src/expressions.c
+++ b/src/expressions.c
@@ -23,6 +23,7 @@
#include "sciteco.h"
#include "error.h"
#include "undo.h"
+#include "qreg.h"
#include "expressions.h"
/*
@@ -57,7 +58,6 @@ teco_expressions_precedence(teco_operator_t op)
}
gint teco_num_sign = 1;
-gint teco_radix = 10;
void
teco_expressions_push_int(teco_int_t number)
@@ -114,12 +114,20 @@ teco_expressions_pop_num_calc(teco_int_t *ret, teco_int_t imply, GError **error)
}
void
-teco_expressions_add_digit(gunichar digit)
+teco_expressions_add_digit(gunichar digit, teco_qreg_t *qreg)
{
+ /*
+ * FIXME: We could just access qreg->integer here since
+ * we can assume that "^R" is a plain register.
+ */
+ assert(qreg != NULL);
+ teco_int_t radix = 10;
+ qreg->vtable->get_integer(qreg, &radix, NULL);
+
teco_int_t n = teco_expressions_args() > 0 ? teco_expressions_pop_num(0) : 0;
/* use g_unichar_digit_value()? */
- teco_expressions_push(n*teco_radix + (n < 0 ? -1 : 1)*((gint)digit - '0'));
+ teco_expressions_push(n*radix + (n < 0 ? -1 : 1)*((gint)digit - '0'));
}
void
@@ -378,21 +386,26 @@ teco_expressions_clear(void)
* @param buffer The output buffer of at least TECO_EXPRESSIONS_FORMAT_LEN characters.
* The output string will be null-terminated.
* @param number The number to format.
+ * @param table The local Q-Register table that contains the appropriate radix register (^R).
* @return A pointer into buffer to the beginning of the formatted number.
*/
gchar *
-teco_expressions_format(gchar *buffer, teco_int_t number)
+teco_expressions_format(gchar *buffer, teco_int_t number, teco_qreg_t *qreg)
{
+ assert(qreg != NULL);
+ teco_int_t radix = 10;
+ qreg->vtable->get_integer(qreg, &radix, NULL);
+
gchar *p = buffer + TECO_EXPRESSIONS_FORMAT_LEN;
teco_int_t v = ABS(number);
*--p = '\0';
do {
- *--p = '0' + (v % teco_radix);
+ *--p = '0' + (v % radix);
if (*p > '9')
*p += 'A' - '9' - 1;
- } while ((v /= teco_radix));
+ } while ((v /= radix));
if (number < 0)
*--p = '-';
diff --git a/src/expressions.h b/src/expressions.h
index 68d8ddb..caea1d7 100644
--- a/src/expressions.h
+++ b/src/expressions.h
@@ -19,6 +19,7 @@
#include <glib.h>
#include "sciteco.h"
+#include "qreg.h"
#include "undo.h"
/**
@@ -101,14 +102,6 @@ teco_set_num_sign(gint sign)
teco_undo_gint(teco_num_sign) = sign;
}
-extern gint teco_radix;
-
-static inline void
-teco_set_radix(gint r)
-{
- teco_undo_gint(teco_radix) = r;
-}
-
void teco_expressions_push_int(teco_int_t number);
/** Push characters of a C-string. */
@@ -123,7 +116,7 @@ teco_int_t teco_expressions_peek_num(guint index);
teco_int_t teco_expressions_pop_num(guint index);
gboolean teco_expressions_pop_num_calc(teco_int_t *ret, teco_int_t imply, GError **error);
-void teco_expressions_add_digit(gunichar digit);
+void teco_expressions_add_digit(gunichar digit, teco_qreg_t *radix);
void teco_expressions_push_op(teco_operator_t op);
gboolean teco_expressions_push_calc(teco_operator_t op, GError **error);
@@ -155,8 +148,8 @@ gboolean teco_expressions_brace_close(GError **error);
void teco_expressions_clear(void);
-/** Maximum size required to format a number if teco_radix == 2 */
+/** Maximum size required to format a number if radix == 2 */
#define TECO_EXPRESSIONS_FORMAT_LEN \
(1 + sizeof(teco_int_t)*8 + 1)
-gchar *teco_expressions_format(gchar *buffer, teco_int_t number);
+gchar *teco_expressions_format(gchar *buffer, teco_int_t number, teco_qreg_t *radix);
diff --git a/src/main.c b/src/main.c
index 4d0e4e9..40191b4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -390,6 +390,11 @@ main(int argc, char **argv)
teco_qreg_view = teco_view_new();
teco_view_setup(teco_qreg_view);
+ /*
+ * FIXME: "_" and "-" should perhaps be in the local Q-Reg table, so you don't
+ * have to back them up on the Q-Reg stack in portable macros.
+ * 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));
/* replacement string register */
@@ -402,7 +407,7 @@ main(int argc, char **argv)
teco_initialize_environment();
teco_qreg_table_t local_qregs;
- teco_qreg_table_init(&local_qregs, TRUE);
+ teco_qreg_table_init_locals(&local_qregs, TRUE);
if (!teco_ring_edit_by_name(NULL, &error)) {
g_fprintf(stderr, "Error editing unnamed file: %s\n",
diff --git a/src/parser.c b/src/parser.c
index 4ee6a90..9477b9a 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -176,7 +176,7 @@ teco_execute_macro(const gchar *macro, gsize macro_len,
teco_qreg_table_t macro_locals;
if (!qreg_table_locals)
- teco_qreg_table_init(&macro_locals, FALSE);
+ teco_qreg_table_init_locals(&macro_locals, FALSE);
guint parent_brace_level = teco_brace_level;
@@ -670,7 +670,7 @@ teco_state_stringbuilding_ctle_num_input(teco_machine_stringbuilding_t *ctx, gun
* NOTE: Numbers can always be safely formatted as null-terminated strings.
*/
gchar buffer[TECO_EXPRESSIONS_FORMAT_LEN];
- const gchar *num = teco_expressions_format(buffer, value);
+ const gchar *num = teco_expressions_format(buffer, value, ctx->qreg_table_locals->radix);
teco_machine_stringbuilding_append(ctx, num, strlen(num));
return &teco_state_stringbuilding_start;
diff --git a/src/qreg-commands.c b/src/qreg-commands.c
index d593af8..89618da 100644
--- a/src/qreg-commands.c
+++ b/src/qreg-commands.c
@@ -654,7 +654,7 @@ teco_state_macro_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg,
return NULL;
} else {
g_auto(teco_qreg_table_t) table;
- teco_qreg_table_init(&table, FALSE);
+ teco_qreg_table_init_locals(&table, FALSE);
if (!teco_qreg_execute(qreg, &table, error))
return NULL;
@@ -711,7 +711,8 @@ teco_state_macrofile_done(teco_machine_main_t *ctx, const teco_string_t *str, GE
return NULL;
} else {
g_auto(teco_qreg_table_t) table;
- teco_qreg_table_init(&table, FALSE);
+ teco_qreg_table_init_locals(&table, FALSE);
+
if (!teco_execute_file(filename, &table, error))
return NULL;
}
diff --git a/src/qreg.c b/src/qreg.c
index 487a725..2c5d4a5 100644
--- a/src/qreg.c
+++ b/src/qreg.c
@@ -893,6 +893,7 @@ teco_qreg_clipboard_new(const gchar *name)
void
teco_qreg_table_init(teco_qreg_table_t *table, gboolean must_undo)
{
+ memset(table, 0, sizeof(*table));
rb3_reset_tree(&table->tree);
table->must_undo = must_undo;
@@ -903,6 +904,20 @@ teco_qreg_table_init(teco_qreg_table_t *table, gboolean must_undo)
teco_qreg_table_insert(table, teco_qreg_plain_new(&q, sizeof(q)));
}
+/** @memberof teco_qreg_table_t */
+void
+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));
+ /* numeric radix ("^R") */
+ table->radix = teco_qreg_plain_new("\x12", 1);
+ table->radix->vtable->set_integer(table->radix, 10, NULL);
+ teco_qreg_table_insert(table, table->radix);
+}
+
static inline void
teco_qreg_table_remove(teco_qreg_t *reg)
{
@@ -1208,7 +1223,7 @@ teco_ed_hook(teco_ed_hook_t type, GError **error)
* since it runs all destructors.
*/
g_auto(teco_qreg_table_t) locals;
- teco_qreg_table_init(&locals, FALSE);
+ teco_qreg_table_init_locals(&locals, FALSE);
teco_qreg_t *qreg = teco_qreg_table_find(&teco_qreg_table_globals, "ED", 2);
if (!qreg) {
@@ -1297,6 +1312,7 @@ struct teco_machine_qregspec_t {
*/
TECO_DECLARE_STATE(teco_state_qregspec_start);
TECO_DECLARE_STATE(teco_state_qregspec_start_global);
+TECO_DECLARE_STATE(teco_state_qregspec_caret);
TECO_DECLARE_STATE(teco_state_qregspec_firstchar);
TECO_DECLARE_STATE(teco_state_qregspec_secondchar);
TECO_DECLARE_STATE(teco_state_qregspec_string);
@@ -1364,10 +1380,10 @@ TECO_DEFINE_STATE(teco_state_qregspec_start,
static teco_state_t *
teco_state_qregspec_start_global_input(teco_machine_qregspec_t *ctx, gunichar chr, GError **error)
{
- /*
- * FIXME: Disallow space characters?
- */
switch (chr) {
+ case '^':
+ return &teco_state_qregspec_caret;
+
case '#':
return &teco_state_qregspec_firstchar;
@@ -1397,6 +1413,25 @@ TECO_DEFINE_STATE(teco_state_qregspec_start_global,
);
static teco_state_t *
+teco_state_qregspec_caret_input(teco_machine_qregspec_t *ctx, gunichar chr, GError **error)
+{
+ chr = teco_ascii_toupper(chr);
+ if (chr < '@' || chr > '_') {
+ teco_error_syntax_set(error, chr);
+ return NULL;
+ }
+
+ if (!ctx->parse_only) {
+ if (ctx->parent.must_undo)
+ undo__teco_string_truncate(&ctx->name, ctx->name.len);
+ teco_string_append_wc(&ctx->name, TECO_CTL_KEY(chr));
+ }
+ return teco_state_qregspec_done(ctx, error);
+}
+
+TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_qregspec_caret);
+
+static teco_state_t *
teco_state_qregspec_firstchar_input(teco_machine_qregspec_t *ctx, gunichar chr, GError **error)
{
/*
diff --git a/src/qreg.h b/src/qreg.h
index e9a9b1b..4a7c15c 100644
--- a/src/qreg.h
+++ b/src/qreg.h
@@ -144,9 +144,16 @@ struct teco_qreg_table_t {
* b) The top-level local register table.
*/
gboolean must_undo;
+
+ /**
+ * The radix register in this local Q-Register table or NULL.
+ * This is an optimization to avoid frequent table lookups.
+ */
+ teco_qreg_t *radix;
};
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 */
static inline teco_qreg_t *
diff --git a/src/search.c b/src/search.c
index ec62d02..2059da3 100644
--- a/src/search.c
+++ b/src/search.c
@@ -52,8 +52,6 @@ TECO_DEFINE_UNDO_OBJECT_OWN(parameters, teco_search_parameters_t, /* don't delet
*/
static teco_search_parameters_t teco_search_parameters;
-static teco_bool_t teco_search_mode = TECO_FAILURE; /* case-insensitive */
-
/*$ ^X search-mode
* mode^X -- Set or get search mode flag
* -^X
@@ -65,17 +63,29 @@ static teco_bool_t teco_search_mode = TECO_FAILURE; /* case-insensitive */
* searches.
* "-^X" is equivalent to "-1^X" and also enables case-sensitive searches.
* Searches are case-insensitive by default.
+ *
+ * An alternative way to access the search mode is via the "^X" local Q-Register.
+ * Consequently, the search mode is local to the current macro invocation frame,
+ * unless the macro call was colon-modified.
*/
void
teco_state_control_search_mode(teco_machine_main_t *ctx, GError **error)
{
if (!teco_expressions_eval(FALSE, error))
return;
+
+ teco_qreg_t *reg = teco_qreg_table_find(ctx->qreg_table_locals, "\x18", 1); /* ^X */
+ g_assert(reg != NULL);
+ teco_bool_t search_mode;
+
if (!teco_expressions_args() && teco_num_sign > 0) {
- teco_expressions_push(teco_search_mode);
+ if (!reg->vtable->get_integer(reg, &search_mode, error))
+ return;
+ teco_expressions_push(search_mode);
} else {
- teco_undo_int(teco_search_mode);
- if (!teco_expressions_pop_num_calc(&teco_search_mode, teco_num_sign, error))
+ if (!teco_expressions_pop_num_calc(&search_mode, teco_num_sign, error) ||
+ !reg->vtable->undo_set_integer(reg, error) ||
+ !reg->vtable->set_integer(reg, search_mode, error))
return;
}
}
@@ -629,7 +639,12 @@ teco_state_search_process(teco_machine_main_t *ctx, const teco_string_t *str, gs
/* FIXME: Should G_REGEX_OPTIMIZE be added under certain circumstances? */
GRegexCompileFlags flags = G_REGEX_MULTILINE | G_REGEX_DOTALL;
- if (teco_is_failure(teco_search_mode))
+ teco_qreg_t *reg = teco_qreg_table_find(ctx->qreg_table_locals, "\x18", 1); /* ^X */
+ g_assert(reg != NULL);
+ teco_bool_t search_mode;
+ if (!reg->vtable->get_integer(reg, &search_mode, error))
+ return FALSE;
+ if (teco_is_failure(search_mode))
flags |= G_REGEX_CASELESS;
/* this is set in teco_state_search_initial() */
diff --git a/tests/testsuite.at b/tests/testsuite.at
index e7d50da..22f14e2 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -75,6 +75,7 @@ AT_CLEANUP
AT_SETUP([Q-Register definitions])
AT_CHECK([$SCITECO -e '0Ua'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U.a'], 0, ignore, ignore)
+AT_CHECK([$SCITECO -e '0U.^X'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U#ab'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U.#ab'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U[[AB]]'], 0, ignore, ignore)
@@ -97,6 +98,8 @@ AT_SETUP([Searches])
AT_CHECK([$SCITECO -e "@I/^Q\05/ J @:S/^Q^Q^Q\05/\"F(0/0)'"], 0, ignore, ignore)
# Canse-sensitive search
AT_CHECK([$SCITECO -e "@I/XXX/J -^X @:S/xxx/\"S(0/0)'"], 0, ignore, ignore)
+# Search mode should be local to the macro frame.
+AT_CHECK([$SCITECO -e "-^X @^Um{^X} Mm-0\"N(0/0)'"], 0, ignore, ignore)
AT_CLEANUP
AT_SETUP([Editing local registers in macro calls])