aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/glob.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glob.c')
-rw-r--r--src/glob.c56
1 files changed, 29 insertions, 27 deletions
diff --git a/src/glob.c b/src/glob.c
index 5e013e4..d15f601 100644
--- a/src/glob.c
+++ b/src/glob.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2025 Robin Haberkorn
+ * Copyright (C) 2012-2026 Robin Haberkorn
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,10 +38,7 @@
#include "undo.h"
#include "glob.h"
-/*
- * FIXME: This state could be static.
- */
-TECO_DECLARE_STATE(teco_state_glob_filename);
+static teco_state_t teco_state_glob_filename;
/** @memberof teco_globber_t */
void
@@ -308,13 +305,13 @@ teco_globber_compile_pattern(const gchar *pattern)
*/
static teco_state_t *
-teco_state_glob_pattern_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error)
+teco_state_glob_pattern_done(teco_machine_main_t *ctx, teco_string_t str, GError **error)
{
if (ctx->flags.mode > TECO_MODE_NORMAL)
return &teco_state_glob_filename;
- if (str->len > 0) {
- g_autofree gchar *filename = teco_file_expand_path(str->data);
+ if (str.len > 0) {
+ g_autofree gchar *filename = teco_file_expand_path(str.data);
teco_qreg_t *glob_reg = teco_qreg_table_find(&teco_qreg_table_globals, "_", 1);
g_assert(glob_reg != NULL);
@@ -327,7 +324,7 @@ teco_state_glob_pattern_done(teco_machine_main_t *ctx, const teco_string_t *str,
return &teco_state_glob_filename;
}
-/*$ EN glob
+/*$ "EN" ":EN" glob
* [type]EN[pattern]$[filename]$ -- Glob files or match filename and check file type
* [type]:EN[pattern]$[filename]$ -> Success|Failure
*
@@ -373,7 +370,7 @@ teco_state_glob_pattern_done(teco_machine_main_t *ctx, const teco_string_t *str,
* \fIfilename\fP does not necessarily have to exist in the
* file system for the match to succeed (unless a file type check
* is also specified).
- * For instance, \(lqENf??/\[**].c\fB$\fPfoo/bar.c\fB$\fP\(rq will
+ * For instance, \(lqENf??\[sl]*.c\fB$\fPfoo/bar.c\fB$\fP\(rq will
* always match and the string \(lqfoo/bar.c\(rq will be inserted
* (see below).
*
@@ -454,11 +451,12 @@ teco_state_glob_pattern_done(teco_machine_main_t *ctx, const teco_string_t *str,
* have to edit that register anyway.
*/
TECO_DEFINE_STATE_EXPECTGLOB(teco_state_glob_pattern,
- .expectstring.last = FALSE
+ .expectstring.last = FALSE,
+ .expectstring.done_cb = teco_state_glob_pattern_done
);
static teco_state_t *
-teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error)
+teco_state_glob_filename_done(teco_machine_main_t *ctx, teco_string_t str, GError **error)
{
if (ctx->flags.mode > TECO_MODE_NORMAL)
return &teco_state_start;
@@ -470,8 +468,7 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str
teco_int_t teco_test_mode;
- if (!teco_expressions_eval(FALSE, error) ||
- !teco_expressions_pop_num_calc(&teco_test_mode, 0, error))
+ if (!teco_expressions_pop_num_calc(&teco_test_mode, 0, error))
return NULL;
switch (teco_test_mode) {
/*
@@ -498,35 +495,36 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str
if (!glob_reg->vtable->get_string(glob_reg, &pattern_str.data, &pattern_str.len,
NULL, error))
return NULL;
- if (teco_string_contains(&pattern_str, '\0')) {
+ if (teco_string_contains(pattern_str, '\0')) {
teco_error_qregcontainsnull_set(error, "_", 1, FALSE);
return NULL;
}
- if (str->len > 0) {
+ if (str.len > 0) {
/*
* Match pattern against provided file name
*/
- g_autofree gchar *filename = teco_file_expand_path(str->data);
+ g_autofree gchar *filename = teco_file_expand_path(str.data);
g_autoptr(GRegex) pattern = teco_globber_compile_pattern(pattern_str.data);
if (g_regex_match(pattern, filename, 0, NULL) &&
(teco_test_mode == 0 || g_file_test(filename, file_flags))) {
if (!colon_modified) {
- gsize len = strlen(filename);
-
- teco_undo_gsize(teco_ranges[0].from) = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0);
- teco_undo_gsize(teco_ranges[0].to) = teco_ranges[0].from + len + 1;
- teco_undo_guint(teco_ranges_count) = 1;
+ sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0);
/*
* FIXME: Filenames may contain linefeeds.
* But if we add them null-terminated, they will be relatively hard to parse.
*/
+ gsize len = strlen(filename);
filename[len] = '\n';
teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0);
teco_interface_ssm(SCI_ADDTEXT, len+1, (sptr_t)filename);
teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0);
+
+ teco_undo_int(teco_ranges[0].from) = teco_interface_bytes2glyphs(pos);
+ teco_undo_int(teco_ranges[0].to) = teco_interface_bytes2glyphs(pos + len + 1);
+ teco_undo_guint(teco_ranges_count) = 1;
}
matching = TRUE;
@@ -550,16 +548,15 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str
g_auto(teco_globber_t) globber;
teco_globber_init(&globber, pattern_str.data, file_flags);
- teco_undo_gsize(teco_ranges[0].from) = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0);
- teco_undo_gsize(teco_ranges[0].to) = teco_ranges[0].from;
- teco_undo_guint(teco_ranges_count) = 1;
+ sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0);
+ teco_undo_int(teco_ranges[0].from) = teco_interface_bytes2glyphs(pos);
teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0);
gchar *globbed_filename;
while ((globbed_filename = teco_globber_next(&globber))) {
gsize len = strlen(globbed_filename);
- teco_ranges[0].to += len+1;
+ pos += len+1;
/*
* FIXME: Filenames may contain linefeeds.
@@ -573,6 +570,9 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str
}
teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0);
+
+ teco_undo_int(teco_ranges[0].to) = teco_interface_bytes2glyphs(pos);
+ teco_undo_guint(teco_ranges_count) = 1;
}
if (colon_modified) {
@@ -591,4 +591,6 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str
return &teco_state_start;
}
-TECO_DEFINE_STATE_EXPECTFILE(teco_state_glob_filename);
+static TECO_DEFINE_STATE_EXPECTFILE(teco_state_glob_filename,
+ .expectstring.done_cb = teco_state_glob_filename_done
+);