aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-12-06 17:20:52 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-12-06 17:20:52 +0300
commite5884ab2166ab5a03294baa54601b8785e6d9727 (patch)
tree0013120eed3e407cd047b734082d7011b9bab94f /src
parentc4e73ae7ef24796cf1f24f0c30d93f2ab21a4572 (diff)
downloadsciteco-e5884ab2166ab5a03294baa54601b8785e6d9727.tar.gz
support the ::S anchored search (string comparison) command (and ::FD, ::FR, ::FS as well)
* The colon modifier can now occur 2 times. Specifying `@` more than once or `:` more than twice is an error now. * Commands do not check for excess colon modifiers - almost every command would have to check it. Instead, a double colon will simply behave like a single colon on most commands. * All search commands inherit the anchored semantics, but it's not very useful in some combinations like -::S, ::N or ::FK. That's why the `::` variants are not documented everywhere. * The lexer.checkheader macro could be simplified and should also be faster now, speeding up startup. Eventually this macro can be made superfluous, e.g. by using 1:FB or 0,1^Q::S.
Diffstat (limited to 'src')
-rw-r--r--src/core-commands.c54
-rw-r--r--src/error.h8
-rw-r--r--src/glob.c2
-rw-r--r--src/parser.c11
-rw-r--r--src/parser.h9
-rw-r--r--src/qreg-commands.c14
-rw-r--r--src/search.c88
-rw-r--r--src/spawn.c2
8 files changed, 120 insertions, 68 deletions
diff --git a/src/core-commands.c b/src/core-commands.c
index 4523923..6e39d9a 100644
--- a/src/core-commands.c
+++ b/src/core-commands.c
@@ -259,7 +259,7 @@ teco_state_start_loop_open(teco_machine_main_t *ctx, GError **error)
!teco_expressions_pop_num_calc(&lctx.counter, -1, error))
return;
lctx.brace_level = teco_brace_level;
- lctx.pass_through = teco_machine_main_eval_colon(ctx);
+ lctx.pass_through = teco_machine_main_eval_colon(ctx) > 0;
if (lctx.counter) {
/*
@@ -306,7 +306,7 @@ teco_state_start_loop_close(teco_machine_main_t *ctx, GError **error)
return;
}
- gboolean colon_modified = teco_machine_main_eval_colon(ctx);
+ gboolean colon_modified = teco_machine_main_eval_colon(ctx) > 0;
/*
* Colon-modified loop ends can be used to
@@ -387,7 +387,7 @@ teco_state_start_break(teco_machine_main_t *ctx, GError **error)
teco_bool_t rc;
if (!teco_expressions_pop_num_calc(&rc, v, error))
return;
- if (teco_machine_main_eval_colon(ctx))
+ if (teco_machine_main_eval_colon(ctx) > 0)
rc = ~rc;
if (teco_is_success(rc))
@@ -544,9 +544,9 @@ teco_state_start_jump(teco_machine_main_t *ctx, GError **error)
teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), 0);
teco_interface_ssm(SCI_GOTOPOS, pos, 0);
- if (teco_machine_main_eval_colon(ctx))
+ if (teco_machine_main_eval_colon(ctx) > 0)
teco_expressions_push(TECO_SUCCESS);
- } else if (teco_machine_main_eval_colon(ctx)) {
+ } else if (teco_machine_main_eval_colon(ctx) > 0) {
teco_expressions_push(TECO_FAILURE);
} else {
teco_error_move_set(error, "J");
@@ -588,7 +588,7 @@ teco_state_start_move(teco_machine_main_t *ctx, GError **error)
return;
teco_bool_t rc = teco_move_chars(v);
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
teco_expressions_push(rc);
} else if (teco_is_failure(rc)) {
teco_error_move_set(error, "C");
@@ -613,7 +613,7 @@ teco_state_start_reverse(teco_machine_main_t *ctx, GError **error)
return;
teco_bool_t rc = teco_move_chars(-v);
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
teco_expressions_push(rc);
} else if (teco_is_failure(rc)) {
teco_error_move_set(error, "R");
@@ -664,7 +664,7 @@ teco_state_start_line(teco_machine_main_t *ctx, GError **error)
return;
teco_bool_t rc = teco_move_lines(v);
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
teco_expressions_push(rc);
} else if (teco_is_failure(rc)) {
teco_error_move_set(error, "L");
@@ -690,7 +690,7 @@ teco_state_start_back(teco_machine_main_t *ctx, GError **error)
return;
teco_bool_t rc = teco_move_lines(-v);
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
teco_expressions_push(rc);
} else if (teco_is_failure(rc)) {
teco_error_move_set(error, "B");
@@ -745,7 +745,7 @@ teco_state_start_word(teco_machine_main_t *ctx, GError **error)
if (v < 0) {
if (teco_current_doc_must_undo())
undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0);
- if (teco_machine_main_eval_colon(ctx))
+ if (teco_machine_main_eval_colon(ctx) > 0)
teco_expressions_push(TECO_SUCCESS);
} else {
teco_interface_ssm(SCI_GOTOPOS, pos, 0);
@@ -841,7 +841,7 @@ teco_state_start_delete_words(teco_machine_main_t *ctx, GError **error)
return;
teco_bool_t rc = teco_delete_words(v);
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
teco_expressions_push(rc);
} else if (teco_is_failure(rc)) {
teco_error_words_set(error, "V");
@@ -866,7 +866,7 @@ teco_state_start_delete_words_back(teco_machine_main_t *ctx, GError **error)
return;
teco_bool_t rc = teco_delete_words(-v);
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
teco_expressions_push(rc);
} else if (teco_is_failure(rc)) {
teco_error_words_set(error, "Y");
@@ -941,7 +941,7 @@ teco_state_start_kill(teco_machine_main_t *ctx, const gchar *cmd, gboolean by_li
rc = teco_bool(len >= 0 && from >= 0 && to >= 0);
}
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
teco_expressions_push(rc);
} else if (teco_is_failure(rc)) {
teco_error_range_set(error, cmd);
@@ -1251,6 +1251,10 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
* Modifiers
*/
case '@':
+ if (ctx->modifier_at) {
+ teco_error_modifier_set(error, '@');
+ return NULL;
+ }
/*
* @ modifier has syntactic significance, so set it even
* in PARSE_ONLY* modes.
@@ -1263,11 +1267,15 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
return &teco_state_start;
case ':':
- if (ctx->mode == TECO_MODE_NORMAL) {
- if (ctx->parent.must_undo)
- teco_undo_guint(ctx->__flags);
- ctx->modifier_colon = TRUE;
+ if (ctx->mode > TECO_MODE_NORMAL)
+ return &teco_state_start;
+ if (ctx->modifier_colon >= 2) {
+ teco_error_modifier_set(error, ':');
+ return NULL;
}
+ if (ctx->parent.must_undo)
+ teco_undo_guint(ctx->__flags);
+ ctx->modifier_colon++;
return &teco_state_start;
default:
@@ -1314,7 +1322,7 @@ teco_state_fcommand_loop_start(teco_machine_main_t *ctx, GError **error)
teco_loop_context_t *lctx = &g_array_index(teco_loop_stack, teco_loop_context_t,
teco_loop_stack->len-1);
- gboolean colon_modified = teco_machine_main_eval_colon(ctx);
+ gboolean colon_modified = teco_machine_main_eval_colon(ctx) > 0;
if (!lctx->pass_through) {
if (colon_modified) {
@@ -1816,7 +1824,7 @@ teco_state_control_glyphs2bytes(teco_machine_main_t *ctx, GError **error)
if (!teco_expressions_eval(FALSE, error))
return;
- gboolean colon_modified = teco_machine_main_eval_colon(ctx);
+ gboolean colon_modified = teco_machine_main_eval_colon(ctx) > 0;
if (!teco_expressions_args()) {
/*
@@ -2487,7 +2495,7 @@ teco_state_ecommand_eol(teco_machine_main_t *ctx, GError **error)
if (teco_expressions_args() > 0) {
teco_int_t eol_mode;
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
teco_int_t v1, v2;
if (!teco_expressions_pop_num_calc(&v1, 0, error))
return;
@@ -2533,7 +2541,7 @@ teco_state_ecommand_eol(teco_machine_main_t *ctx, GError **error)
undo__teco_interface_ssm(SCI_SETEOLMODE,
teco_interface_ssm(SCI_GETEOLMODE, 0, 0), 0);
teco_interface_ssm(SCI_SETEOLMODE, eol_mode, 0);
- } else if (teco_machine_main_eval_colon(ctx)) {
+ } else if (teco_machine_main_eval_colon(ctx) > 0) {
const gchar *eol_seq = teco_eol_get_seq(teco_interface_ssm(SCI_GETEOLMODE, 0, 0));
teco_expressions_push(eol_seq);
} else {
@@ -2644,7 +2652,7 @@ teco_state_ecommand_encoding(teco_machine_main_t *ctx, GError **error)
if (!teco_expressions_eval(FALSE, error))
return;
- gboolean colon_modified = teco_machine_main_eval_colon(ctx);
+ gboolean colon_modified = teco_machine_main_eval_colon(ctx) > 0;
guint old_cp = teco_interface_get_codepage();
@@ -2829,7 +2837,7 @@ teco_state_ecommand_encoding(teco_machine_main_t *ctx, GError **error)
static void
teco_state_ecommand_exit(teco_machine_main_t *ctx, GError **error)
{
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
if (!teco_ring_save_all_dirty_buffers(error))
return;
} else {
diff --git a/src/error.h b/src/error.h
index 2df7b89..c51f528 100644
--- a/src/error.h
+++ b/src/error.h
@@ -39,6 +39,7 @@ typedef enum {
* They will mainly be different in their error message.
*/
TECO_ERROR_SYNTAX,
+ TECO_ERROR_MODIFIER,
TECO_ERROR_ARGEXPECTED,
TECO_ERROR_CODEPOINT,
TECO_ERROR_MOVE,
@@ -74,6 +75,13 @@ teco_error_syntax_set(GError **error, gunichar chr)
}
static inline void
+teco_error_modifier_set(GError **error, gchar modifier)
+{
+ g_set_error(error, TECO_ERROR, TECO_ERROR_MODIFIER,
+ "Excess \"%c\"-modifier", modifier);
+}
+
+static inline void
teco_error_argexpected_set(GError **error, const gchar *cmd)
{
g_set_error(error, TECO_ERROR, TECO_ERROR_ARGEXPECTED,
diff --git a/src/glob.c b/src/glob.c
index a69aa81..e338975 100644
--- a/src/glob.c
+++ b/src/glob.c
@@ -466,7 +466,7 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str
GFileTest file_flags = G_FILE_TEST_EXISTS;
gboolean matching = FALSE;
- gboolean colon_modified = teco_machine_main_eval_colon(ctx);
+ gboolean colon_modified = teco_machine_main_eval_colon(ctx) > 0;
teco_int_t teco_test_mode;
diff --git a/src/parser.c b/src/parser.c
index e1bf576..018e35f 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -320,16 +320,17 @@ teco_machine_main_init(teco_machine_main_t *ctx, teco_qreg_table_t *qreg_table_l
teco_machine_stringbuilding_init(&ctx->expectstring.machine, '\e', qreg_table_locals, must_undo);
}
-gboolean
+guint
teco_machine_main_eval_colon(teco_machine_main_t *ctx)
{
- if (!ctx->modifier_colon)
- return FALSE;
+ guint c = ctx->modifier_colon;
+ if (c == 0)
+ return 0;
if (ctx->parent.must_undo)
teco_undo_guint(ctx->__flags);
- ctx->modifier_colon = FALSE;
- return TRUE;
+ ctx->modifier_colon = 0;
+ return c;
}
gboolean
diff --git a/src/parser.h b/src/parser.h
index 1127dcd..20f73fb 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -460,7 +460,12 @@ struct teco_machine_main_t {
struct {
teco_mode_t mode : 8;
- bool modifier_colon : 1;
+ /** number of `:`-modifiers detected */
+ guint modifier_colon : 2;
+ /**
+ * Whether the `@`-modifier has been detected.
+ * This is tracked even in parse-only mode.
+ */
bool modifier_at : 1;
};
guint __flags;
@@ -503,7 +508,7 @@ void teco_machine_main_init(teco_machine_main_t *ctx,
teco_qreg_table_t *qreg_table_locals,
gboolean must_undo);
-gboolean teco_machine_main_eval_colon(teco_machine_main_t *ctx);
+guint teco_machine_main_eval_colon(teco_machine_main_t *ctx);
gboolean teco_machine_main_eval_at(teco_machine_main_t *ctx);
gboolean teco_machine_main_step(teco_machine_main_t *ctx,
diff --git a/src/qreg-commands.c b/src/qreg-commands.c
index c36a6b7..0a64b2f 100644
--- a/src/qreg-commands.c
+++ b/src/qreg-commands.c
@@ -256,7 +256,7 @@ teco_state_queryqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg,
if (!teco_expressions_eval(FALSE, error))
return NULL;
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
/* Query Q-Register's existence or string size */
if (qreg) {
/* get_string() would return the size in bytes */
@@ -366,7 +366,7 @@ teco_state_setqregstring_nobuilding_done(teco_machine_main_t *ctx,
if (ctx->mode > TECO_MODE_NORMAL)
return &teco_state_start;
- gboolean colon_modified = teco_machine_main_eval_colon(ctx);
+ gboolean colon_modified = teco_machine_main_eval_colon(ctx) > 0;
if (!teco_expressions_eval(FALSE, error))
return NULL;
@@ -578,9 +578,9 @@ teco_state_setqreginteger_got_register(teco_machine_main_t *ctx, teco_qreg_t *qr
!qreg->vtable->set_integer(qreg, v, error))
return NULL;
- if (teco_machine_main_eval_colon(ctx))
+ if (teco_machine_main_eval_colon(ctx) > 0)
teco_expressions_push(TECO_SUCCESS);
- } else if (teco_machine_main_eval_colon(ctx)) {
+ } else if (teco_machine_main_eval_colon(ctx) > 0) {
teco_expressions_push(TECO_FAILURE);
} else {
teco_error_argexpected_set(error, "U");
@@ -653,7 +653,7 @@ teco_state_macro_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg,
if (ctx->mode > TECO_MODE_NORMAL)
return &teco_state_start;
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
/* don't create new local Q-Registers if colon modifier is given */
if (!teco_qreg_execute(qreg, ctx->qreg_table_locals, error))
return NULL;
@@ -710,7 +710,7 @@ teco_state_macrofile_done(teco_machine_main_t *ctx, const teco_string_t *str, GE
g_autofree gchar *filename = teco_file_expand_path(str->data);
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
/* don't create new local Q-Registers if colon modifier is given */
if (!teco_execute_file(filename, ctx->qreg_table_locals, error))
return NULL;
@@ -803,7 +803,7 @@ teco_state_copytoqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg,
};
teco_interface_ssm(SCI_GETTEXTRANGEFULL, 0, (sptr_t)&range);
- if (teco_machine_main_eval_colon(ctx)) {
+ if (teco_machine_main_eval_colon(ctx) > 0) {
if (!qreg->vtable->append_string(qreg, str, len, error))
return NULL;
} else {
diff --git a/src/search.c b/src/search.c
index c0398dc..e05a6b9 100644
--- a/src/search.c
+++ b/src/search.c
@@ -686,6 +686,9 @@ teco_state_search_process(teco_machine_main_t *ctx, const teco_string_t *str, gs
if (teco_is_failure(search_mode))
flags |= G_REGEX_CASELESS;
+ if (ctx->modifier_colon == 2)
+ flags |= G_REGEX_ANCHORED;
+
/* this is set in teco_state_search_initial() */
if (ctx->expectstring.machine.codepage != SC_CP_UTF8) {
/* single byte encoding */
@@ -835,7 +838,7 @@ teco_state_search_done(teco_machine_main_t *ctx, const teco_string_t *str, GErro
if (!search_reg->vtable->get_integer(search_reg, &search_state, error))
return FALSE;
- if (teco_machine_main_eval_colon(ctx))
+ if (teco_machine_main_eval_colon(ctx) > 0)
teco_expressions_push(search_state);
else if (teco_is_failure(search_state) &&
!teco_loop_stack->len /* not in loop */)
@@ -860,19 +863,20 @@ teco_state_search_done(teco_machine_main_t *ctx, const teco_string_t *str, GErro
##__VA_ARGS__ \
)
-/*$ S search pattern
- * S[pattern]$ -- Search for pattern
- * [n]S[pattern]$
+/*$ S search pattern compare
+ * [n]S[pattern]$ -- Search for pattern
* -S[pattern]$
* from,toS[pattern]$
- * :S[pattern]$ -> Success|Failure
* [n]:S[pattern]$ -> Success|Failure
* -:S[pattern]$ -> Success|Failure
* from,to:S[pattern]$ -> Success|Failure
+ * [n]::S[pattern]$ -> Success|Failure
+ * -::S[pattern]$ -> Success|Failure
+ * from,to::S[pattern]$ -> Success|Failure
*
* Search for <pattern> in the current buffer/Q-Register.
* Search order and range depends on the arguments given.
- * By default without any arguments, S will search forward
+ * By default without any arguments, \fBS\fP will search forward
* from dot till file end.
* The optional single argument specifies the occurrence
* to search (1 is the first occurrence, 2 the second, etc.).
@@ -906,10 +910,23 @@ teco_state_search_done(teco_machine_main_t *ctx, const teco_string_t *str, GErro
* .EX
* <Sfoo$; ...>
* .EE
- * Alternatively, S may be colon-modified in which case it returns
+ * Alternatively, \fBS\fP may be colon-modified in which case it returns
* a condition boolean that may be directly evaluated by a
* conditional or break-command.
*
+ * When modified with two colons, the search will be anchored in addition
+ * to returning a condition boolean, i.e. it can be used to perform a string
+ * comparison.
+ * \(lq::S\(rq without arguments compares the pattern against the current
+ * buffer position.
+ * With a single positive integer <n>, \(lq::S\(rq matches <n> repititions
+ * of the given pattern.
+ * With a negative integer <n>, \(lq::S\(rq will match the \fIn\fP-th last
+ * occurrence of the pattern from the beginning of the buffer
+ * (which is not really useful).
+ * With two integer arguments, \(lq::S\(rq compares the pattern against
+ * the corresponding part of the buffer.
+ *
* In interactive mode, searching will be performed immediately
* (\(lqsearch as you type\(rq) highlighting matched text
* on the fly.
@@ -996,12 +1013,12 @@ teco_state_search_all_done(teco_machine_main_t *ctx, const teco_string_t *str, G
*
* Search for <pattern> over buffer boundaries.
* This command is similar to the regular search command
- * (S) but will continue to search for occurrences of
+ * (\fBS\fP) but will continue to search for occurrences of
* pattern when the end or beginning of the current buffer
* is reached.
* Occurrences of <pattern> spanning over buffer boundaries
* will not be found.
- * When searching forward N will start in the current buffer
+ * When searching forward \fBN\fP will start in the current buffer
* at dot, continue with the next buffer in the ring searching
* the entire buffer until it reaches the end of the buffer
* ring, continue with the first buffer in the ring until
@@ -1009,7 +1026,7 @@ teco_state_search_all_done(teco_machine_main_t *ctx, const teco_string_t *str, G
* beginning of the buffer up to its current dot.
* Searching backwards does the reverse.
*
- * N also differs from S in the interpretation of two arguments.
+ * \fBN\fP also differs from \fBS\fP in the interpretation of two arguments.
* Using two arguments the search will be bounded between the
* buffer with number <from>, up to the buffer with number
* <to>.
@@ -1024,6 +1041,13 @@ teco_state_search_all_done(teco_machine_main_t *ctx, const teco_string_t *str, G
* buffer numbers greater than the number of buffers in the
* ring.
*/
+/*
+ * Since N inherits the double-colon semantics from S,
+ * f,t::N will match at the beginning of the given buffers.
+ * [n]::N will behave similar to [n]::S, but can search across
+ * buffer boundaries.
+ * This is probably not very useful in practice, so it's not documented.
+ */
TECO_DEFINE_STATE_SEARCH(teco_state_search_all,
.initial_cb = (teco_state_initial_cb_t)teco_state_search_all_initial
);
@@ -1088,8 +1112,8 @@ teco_state_search_kill_done(teco_machine_main_t *ctx, const teco_string_t *str,
* -:FK[pattern]$ -> Success|Failure
* from,to:FK[pattern]$ -> Success|Failure
*
- * FK searches for <pattern> just like the regular search
- * command (S) but when found deletes all text from dot
+ * \fBFK\fP searches for <pattern> just like the regular search
+ * command (\fBS\fP) but when found deletes all text from dot
* up to but not including the found text instance.
* When searching backwards the characters beginning after
* the occurrence of <pattern> up to dot are deleted.
@@ -1097,6 +1121,9 @@ teco_state_search_kill_done(teco_machine_main_t *ctx, const teco_string_t *str,
* In interactive mode, deletion is not performed
* as-you-type but only on command termination.
*/
+/*
+ * ::FK is possible but doesn't make much sense, so it's undocumented.
+ */
TECO_DEFINE_STATE_SEARCH(teco_state_search_kill);
static teco_state_t *
@@ -1127,17 +1154,18 @@ teco_state_search_delete_done(teco_machine_main_t *ctx, const teco_string_t *str
}
/*$ FD
- * FD[pattern]$ -- Delete occurrence of pattern
- * [n]FD[pattern]$
+ * [n]FD[pattern]$ -- Delete occurrence of pattern
* -FD[pattern]$
* from,toFD[pattern]$
- * :FD[pattern]$ -> Success|Failure
* [n]:FD[pattern]$ -> Success|Failure
* -:FD[pattern]$ -> Success|Failure
* from,to:FD[pattern]$ -> Success|Failure
+ * [n]::FD[pattern]$ -> Success|Failure
+ * -::FD[pattern]$ -> Success|Failure
+ * from,to::FD[pattern]$ -> Success|Failure
*
* Searches for <pattern> just like the regular search command
- * (S) but when found deletes the entire occurrence.
+ * (\fBS\fP) but when found deletes the entire occurrence.
*/
TECO_DEFINE_STATE_SEARCH(teco_state_search_delete);
@@ -1187,22 +1215,23 @@ teco_state_replace_done(teco_machine_main_t *ctx, const teco_string_t *str, GErr
}
/*$ FS
- * FS[pattern]$[string]$ -- Search and replace
- * [n]FS[pattern]$[string]$
+ * [n]FS[pattern]$[string]$ -- Search and replace
* -FS[pattern]$[string]$
* from,toFS[pattern]$[string]$
- * :FS[pattern]$[string]$ -> Success|Failure
* [n]:FS[pattern]$[string]$ -> Success|Failure
* -:FS[pattern]$[string]$ -> Success|Failure
* from,to:FS[pattern]$[string]$ -> Success|Failure
+ * [n]::FS[pattern]$[string]$ -> Success|Failure
+ * -::FS[pattern]$[string]$ -> Success|Failure
+ * from,to::FS[pattern]$[string]$ -> Success|Failure
*
* Search for <pattern> just like the regular search command
- * (S) does but replace it with <string> if found.
+ * (\fBS\fP) does but replace it with <string> if found.
* If <string> is empty, the occurrence will always be
- * deleted so \(lqFS[pattern]$$\(rq is similar to
+ * deleted so \(lqFS[pattern]\fB$$\fP\(rq is similar to
* \(lqFD[pattern]$\(rq.
* The global replace register is \fBnot\fP touched
- * by the FS command.
+ * by the \fBFS\fP command.
*
* In interactive mode, the replacement will be performed
* immediately and interactively.
@@ -1291,20 +1320,21 @@ teco_state_replace_default_done(teco_machine_main_t *ctx, const teco_string_t *s
}
/*$ FR
- * FR[pattern]$[string]$ -- Search and replace with default
- * [n]FR[pattern]$[string]$
+ * [n]FR[pattern]$[string]$ -- Search and replace with default
* -FR[pattern]$[string]$
* from,toFR[pattern]$[string]$
- * :FR[pattern]$[string]$ -> Success|Failure
* [n]:FR[pattern]$[string]$ -> Success|Failure
* -:FR[pattern]$[string]$ -> Success|Failure
* from,to:FR[pattern]$[string]$ -> Success|Failure
+ * [n]::FR[pattern]$[string]$ -> Success|Failure
+ * -::FR[pattern]$[string]$ -> Success|Failure
+ * from,to::FR[pattern]$[string]$ -> Success|Failure
*
- * The FR command is similar to the FS command.
+ * The \fBFR\fP command is similar to the \fBFS\fP command.
* It searches for <pattern> just like the regular search
- * command (S) and replaces the occurrence with <string>
- * similar to what FS does.
- * It differs from FS in the fact that the replacement
+ * command (\fBS\fP) and replaces the occurrence with <string>
+ * similar to what \fBFS\fP does.
+ * It differs from \fBFS\fP in the fact that the replacement
* string is saved in the global replacement register
* \(lq-\(rq.
* If <string> is empty the string in the global replacement
diff --git a/src/spawn.c b/src/spawn.c
index a0bc7a9..fb7a946 100644
--- a/src/spawn.c
+++ b/src/spawn.c
@@ -463,7 +463,7 @@ teco_state_execute_done(teco_machine_main_t *ctx, const teco_string_t *str, GErr
goto gerror;
}
- if (teco_machine_main_eval_colon(ctx))
+ if (teco_machine_main_eval_colon(ctx) > 0)
teco_expressions_push(TECO_SUCCESS);
goto cleanup;