rc

[fork] interactive rc shell
Log | Files | Refs | README | LICENSE

commit 8ab057499c351655fc4d93d5e997b1fe816416eb
parent 20fc20c568171045b1844dffc0f023fe427753fc
Author: Bert Münnich <ber.t@posteo.de>
Date:   Sun, 29 Sep 2019 23:01:09 +0200

Unify call to completion generators

Filename completion is not a special case anymore. The generated filenames are
quoted like the matches of the custom completion generators.

Diffstat:
Medit-readline.c | 48++++++++++++++++++++----------------------------
1 file changed, 20 insertions(+), 28 deletions(-)

diff --git a/edit-readline.c b/edit-readline.c @@ -19,18 +19,6 @@ struct cookie { char *buffer; }; -/* Teach readline how to quote a filename in rc. "text" is the filename to be - * quoted. "type" is either SINGLE_MATCH, if there is only one completion - * match, or MULT_MATCH. "qp" is a pointer to any opening quote character the - * user typed. - */ -static char *quote(char *text, int type, char *qp) { - char *r = mprint("%#S", text); - if (type != SINGLE_MATCH) - r[strlen(r)-1] = '\0'; - return r; -} - /* Join two strings with a "/" between them, into a malloc string */ static char *dir_join(const char *a, const char *b) { size_t l; @@ -157,6 +145,14 @@ static char *compl_command(const char *text, int state) { return name; } +static char *compl_filename(const char *text, int state) { + char *name = rl_filename_completion_function(text, state); + struct stat st; + if (name != NULL && stat(name, &st) == 0 && S_ISDIR(st.st_mode)) + rl_completion_append_character = '/'; + return name; +} + static rl_compentry_func_t *compl_func(const char *text, int start, int end) { int quote = FALSE; char last = ';', *s, *t; @@ -174,7 +170,7 @@ static rl_compentry_func_t *compl_func(const char *text, int start, int end) { case '$': return compl_var; } - return NULL; + return compl_filename; } static rl_compentry_func_t *compentry_func; @@ -189,19 +185,17 @@ static char **rc_completion(const char *text, int start, int end) { compentry_func = NULL; } else func = compl_func(text, start, end); - if (func != NULL) { - matches = rl_completion_matches(text, func); - if (matches) { - if (matches[1]) - rl_completion_suppress_quote = 1; - if (rl_completion_type != '?') - matches[0] = maybe_quote(matches[0]); - if (rl_completion_type == '*') - for (i = 1; matches[i]; i++) - matches[i] = maybe_quote(matches[i]); - } - rl_attempted_completion_over = 1; + matches = rl_completion_matches(text, func); + if (matches) { + if (matches[1]) + rl_completion_suppress_quote = 1; + if (rl_completion_type != '?') + matches[0] = maybe_quote(matches[0]); + if (rl_completion_type == '*') + for (i = 1; matches[i]; i++) + matches[i] = maybe_quote(matches[i]); } + rl_attempted_completion_over = 1; return matches; } @@ -217,7 +211,7 @@ static int rc_complete_command(int count, int key) { } static int rc_complete_filename(int count, int key) { - return expl_complete(rl_filename_completion_function, count, key); + return expl_complete(compl_filename, count, key); } static int rc_complete_variable(int count, int key) { @@ -235,8 +229,6 @@ void *edit_begin(int fd) { rl_basic_word_break_characters = " \t\n`@$><=;|&{("; rl_catch_signals = 0; rl_completer_quote_characters = "'"; - rl_filename_quote_characters = quote_chars; - rl_filename_quoting_function = quote; rl_readline_name = "rc"; rl_add_funmap_entry("rc-complete-command", rc_complete_command);