From a62323baa454b4a6ac698067043c8d4cf50c6561 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Tue, 7 Oct 2025 00:58:11 +0300 Subject: throw an error immediately after nEB if n != 0 * When typing nEBfilename$ (n != 0) you would find out that the construct is invalid only after typing out the entire command. We now throw an error immediately, ie. only Escape or string termination will be expected in interactive mode. * In batch mode, nothing should have changed. --- src/parser.h | 3 +++ src/ring.c | 41 +++++++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/parser.h b/src/parser.h index 095f523..2308925 100644 --- a/src/parser.h +++ b/src/parser.h @@ -494,6 +494,9 @@ struct teco_machine_main_t { * This is tracked even in parse-only mode. */ guint modifier_at : 1; + + /** whether command accepts a filename */ + guint allow_filename : 1; } flags; /** The nesting level of braces */ diff --git a/src/ring.c b/src/ring.c index d389e52..0dbe911 100644 --- a/src/ring.c +++ b/src/ring.c @@ -405,13 +405,6 @@ teco_ring_cleanup(void) * Command states */ -/* - * FIXME: Should be part of the teco_machine_main_t? - * Unfortunately, we cannot just merge initial() with done(), - * since we want to react immediately to xEB without waiting for $. - */ -static gboolean allow_filename = FALSE; - static gboolean teco_state_edit_file_initial(teco_machine_main_t *ctx, GError **error) { @@ -422,7 +415,7 @@ teco_state_edit_file_initial(teco_machine_main_t *ctx, GError **error) if (!teco_expressions_pop_num_calc(&id, -1, error)) return FALSE; - allow_filename = TRUE; + ctx->flags.allow_filename = TRUE; if (id == 0) { for (teco_buffer_t *cur = teco_ring_first(); cur; cur = teco_buffer_next(cur)) { @@ -433,7 +426,7 @@ teco_state_edit_file_initial(teco_machine_main_t *ctx, GError **error) teco_interface_popup_show(0); } else if (id > 0) { - allow_filename = FALSE; + ctx->flags.allow_filename = FALSE; if (!teco_current_doc_undo_edit(error) || !teco_ring_edit(id, error)) return FALSE; @@ -442,20 +435,31 @@ teco_state_edit_file_initial(teco_machine_main_t *ctx, GError **error) return TRUE; } +gboolean +teco_state_edit_file_process(teco_machine_main_t *ctx, const teco_string_t *str, + gsize new_chars, GError **error) +{ + g_assert(new_chars > 0); + + if (!ctx->flags.allow_filename) { + g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, + "If a buffer is selected by id, the " + "string argument must be empty"); + return FALSE; + } + + return TRUE; +} + static teco_state_t * teco_state_edit_file_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) { if (ctx->flags.mode > TECO_MODE_NORMAL) return &teco_state_start; - if (!allow_filename) { - if (str->len > 0) { - g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, - "If a buffer is selected by id, the " - "string argument must be empty"); - return NULL; - } - + if (!ctx->flags.allow_filename) { + /* process_cb() already throws error if str->len > 0 */ + g_assert(str->len == 0); return &teco_state_start; } @@ -536,7 +540,8 @@ teco_state_edit_file_done(teco_machine_main_t *ctx, const teco_string_t *str, GE * ecetera. */ TECO_DEFINE_STATE_EXPECTGLOB(teco_state_edit_file, - .initial_cb = (teco_state_initial_cb_t)teco_state_edit_file_initial + .initial_cb = (teco_state_initial_cb_t)teco_state_edit_file_initial, + .expectstring.process_cb = teco_state_edit_file_process ); static teco_state_t * -- cgit v1.2.3