aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core-commands.c35
-rw-r--r--tests/testsuite.at4
2 files changed, 31 insertions, 8 deletions
diff --git a/src/core-commands.c b/src/core-commands.c
index cd9a8fa..ee3c46c 100644
--- a/src/core-commands.c
+++ b/src/core-commands.c
@@ -1739,8 +1739,10 @@ TECO_DEFINE_STATE(teco_state_ascii,
/*$ ^[^[ ^[$ $$ ^C terminate return
* [a1,a2,...]$$ -- Terminate command line or return from macro
+ * -$$
* [a1,a2,...]^[$
* [a1,a2,...]^C
+ * -^C
*
* Returns from the current macro invocation.
* This will pass control to the calling macro immediately
@@ -1754,6 +1756,8 @@ TECO_DEFINE_STATE(teco_state_ascii,
* All braces opened in the current macro invocation will
* be closed and their values discarded.
* Only the direct arguments to \fB$$\fP will be kept.
+ * If the prefix sign is set (\(lq-\fB$$\fP\(rq) the command
+ * will always leave -1 on the stack.
*
* Returning from the top-level macro in batch mode
* will exit the program or start up interactive mode depending
@@ -1806,6 +1810,9 @@ teco_return(teco_machine_main_t *ctx, GError **error)
ctx->parent.current = &teco_state_start;
if (!teco_expressions_eval(FALSE, error))
return NULL;
+ if (teco_num_sign < 0)
+ /* only if you wrote -$$ */
+ teco_expressions_push(1);
teco_error_return_set(error, teco_expressions_args());
return NULL;
}
@@ -1873,6 +1880,18 @@ TECO_DEFINE_STATE_START(teco_state_escape,
.end_of_macro_cb = teco_state_escape_end_of_macro
);
+static gboolean
+teco_state_ctlc_initial(teco_machine_main_t *ctx, GError **error)
+{
+ if (G_UNLIKELY(ctx == &teco_cmdline.machine)) {
+ g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED,
+ "<^C> is not allowed to terminate command-lines");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/*
* Just like ^[, ^C actually implements a lookahead,
* so a ^C itself does nothing.
@@ -1892,20 +1911,20 @@ teco_state_ctlc_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
}
static gboolean
-teco_state_ctlc_initial(teco_machine_main_t *ctx, GError **error)
+teco_state_ctlc_end_of_macro(teco_machine_main_t *ctx, GError **error)
{
- if (G_UNLIKELY(ctx == &teco_cmdline.machine)) {
- g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED,
- "<^C> is not allowed to terminate command-lines");
- return FALSE;
- }
-
+ if (ctx->flags.mode > TECO_MODE_NORMAL)
+ return TRUE;
+ if (teco_num_sign < 0)
+ /* only if you wrote -^C */
+ teco_expressions_push(1);
return TRUE;
}
TECO_DEFINE_STATE_START(teco_state_ctlc,
.initial_cb = (teco_state_initial_cb_t)teco_state_ctlc_initial,
- .input_cb = (teco_state_input_cb_t)teco_state_ctlc_input
+ .input_cb = (teco_state_input_cb_t)teco_state_ctlc_input,
+ .end_of_macro_cb = (teco_state_end_of_macro_cb_t)teco_state_ctlc_end_of_macro
);
static teco_state_t *
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 8145e3d..d688c6e 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -301,6 +301,10 @@ AT_DATA([test.txt], [[0123456789
TE_CHECK([[@ER"test.txt" ^S+11"N(0/0)']], 0, ignore, ignore)
AT_CLEANUP
+AT_SETUP([Macro calls])
+TE_CHECK([[@^Ua{-$$} Ma+1"N(0/0)']], 0, ignore, ignore)
+AT_CLEANUP
+
AT_SETUP([Editing local registers in macro calls])
TE_CHECK([[@^Ua{@EQ.x//} :Ma @^U.x/FOO/]], 0, ignore, ignore)
TE_CHECK([[@^Ua{@EQ.x//} Ma @^U.x/FOO/]], 1, ignore, ignore)