diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-09-11 16:01:51 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-09-11 16:14:27 +0200 |
commit | cc63f3b25cd449573fe9b6b7d0c88f5dd0ed2f4d (patch) | |
tree | 1be1dc8d53e133ec1e0e1610e6248dc5619b2ec5 /src/cmdline.c | |
parent | 2a050759ab621b87d0782cc8235907a1757b46cc (diff) | |
download | sciteco-cc63f3b25cd449573fe9b6b7d0c88f5dd0ed2f4d.tar.gz |
improved file name autocompletion
* pressing ^W in FG now deletes the entire directory component as in EB
* commands without glob patterns (eg. EW) can now autocomplete file names containing
glob patterns
* When the autocompletion contains a glob character in commands accepting
glob patterns like EB or EN, we now escape the glob pattern.
This already helps if the remaining file name can be autocompleted in one go.
Unfortunately, this is still insufficient if we can only partially complete
and the partial completion contains glob characters.
For instance, if there are 2 files: `file?.txt` and `file?.foo`,
completing after `f` will insert `ile[?].`.
The second try to press Tab will already do nothing.
To fully support these cases, we need a version of teco_file_auto_complete()
accepting glob patterns.
Perhaps we can simply append `*` to the given glob pattern.
Diffstat (limited to 'src/cmdline.c')
-rw-r--r-- | src/cmdline.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/src/cmdline.c b/src/cmdline.c index be7a5b1..2236872 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -52,6 +52,7 @@ #include "eol.h" #include "error.h" #include "qreg.h" +#include "glob.h" #include "cmdline.h" #if defined(HAVE_MALLOC_TRIM) && !defined(HAVE_DECL_MALLOC_TRIM) @@ -762,6 +763,60 @@ teco_state_expectfile_process_edit_cmd(teco_machine_main_t *ctx, teco_machine_t } gboolean +teco_state_expectglob_process_edit_cmd(teco_machine_main_t *ctx, teco_machine_t *parent_ctx, gunichar key, GError **error) +{ + teco_machine_stringbuilding_t *stringbuilding_ctx = &ctx->expectstring.machine; + teco_state_t *stringbuilding_current = stringbuilding_ctx->parent.current; + + /* + * NOTE: We don't just define teco_state_stringbuilding_start_process_edit_cmd(), + * as it would be hard to subclass/overwrite for different main machine states. + */ + if (!stringbuilding_current->is_start) + return stringbuilding_current->process_edit_cmd_cb(&stringbuilding_ctx->parent, &ctx->parent, key, error); + + switch (key) { + case '\t': { /* autocomplete file name */ + if (teco_cmdline.modifier_enabled) + break; + + if (teco_interface_popup_is_shown()) { + /* cycle through popup pages */ + teco_interface_popup_show(); + return TRUE; + } + + if (teco_string_contains(&ctx->expectstring.string, '\0')) + /* null-byte not allowed in file names */ + return TRUE; + + /* + * We do not support autocompleting glob patterns. + * + * FIXME: What if the last autocompletion inserted escaped glob + * characters? + * Perhaps teco_file_auto_complete() should natively support glob patterns. + */ + if (teco_globber_is_pattern(ctx->expectstring.string.data)) + return TRUE; + + g_auto(teco_string_t) new_chars, new_chars_escaped; + gboolean unambiguous = teco_file_auto_complete(ctx->expectstring.string.data, G_FILE_TEST_EXISTS, &new_chars); + g_autofree gchar *pattern_escaped = teco_globber_escape_pattern(new_chars.data); + teco_machine_stringbuilding_escape(stringbuilding_ctx, pattern_escaped, strlen(pattern_escaped), &new_chars_escaped); + if (unambiguous && ctx->expectstring.nesting == 1) + teco_string_append_wc(&new_chars_escaped, + ctx->expectstring.machine.escape_char == '{' ? '}' : ctx->expectstring.machine.escape_char); + + return teco_cmdline_insert(new_chars_escaped.data, new_chars_escaped.len, error); + } + } + + /* ^W should behave like in commands accepting files */ + return teco_state_expectfile_process_edit_cmd(ctx, parent_ctx, key, error); +} + +gboolean teco_state_expectdir_process_edit_cmd(teco_machine_main_t *ctx, teco_machine_t *parent_ctx, gunichar key, GError **error) { teco_machine_stringbuilding_t *stringbuilding_ctx = &ctx->expectstring.machine; @@ -800,7 +855,8 @@ teco_state_expectdir_process_edit_cmd(teco_machine_main_t *ctx, teco_machine_t * } } - return stringbuilding_current->process_edit_cmd_cb(&stringbuilding_ctx->parent, &ctx->parent, key, error); + /* ^W should behave like in commands accepting files */ + return teco_state_expectfile_process_edit_cmd(ctx, parent_ctx, key, error); } gboolean |