Bug reported from Martin Dietze:
The place to change the completion_append_character is usually somewhere in the `rl_completion_entry_function' callback which is where one usually can distinguish between file- or dir-like entries to append a slash for dirs etc. This does no longer work since `fn_complete()' takes the `append_character' as argument before the callback is executed, so that changes to the variable `rl_completion_append_character' have in fact no effect for the current completion. Fix by adding a function that returns the rl_completion_append_character, when it gets passed in a filename in readline emulation.
This commit is contained in:
parent
0320b64715
commit
3cfbfdb2ef
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: filecomplete.c,v 1.5 2005/05/18 22:34:41 christos Exp $ */
|
||||
/* $NetBSD: filecomplete.c,v 1.6 2005/06/10 20:21:00 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#if !defined(lint) && !defined(SCCSID)
|
||||
__RCSID("$NetBSD: filecomplete.c,v 1.5 2005/05/18 22:34:41 christos Exp $");
|
||||
__RCSID("$NetBSD: filecomplete.c,v 1.6 2005/06/10 20:21:00 christos Exp $");
|
||||
#endif /* not lint && not SCCSID */
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -81,7 +81,7 @@ static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
|
||||
* it's callers's responsibility to free() returned string
|
||||
*/
|
||||
char *
|
||||
tilde_expand(char *txt)
|
||||
tilde_expand(const char *txt)
|
||||
{
|
||||
struct passwd pwres, *pass;
|
||||
char *temp;
|
||||
@ -226,27 +226,17 @@ filename_completion_function(const char *text, int state)
|
||||
}
|
||||
|
||||
if (entry) { /* match found */
|
||||
struct stat stbuf;
|
||||
const char *isdir = "";
|
||||
|
||||
#if defined(__SVR4) || defined(__linux__)
|
||||
len = strlen(entry->d_name);
|
||||
#else
|
||||
len = entry->d_namlen;
|
||||
#endif
|
||||
temp = malloc(strlen(dirpath) + len + 1);
|
||||
if (temp == NULL)
|
||||
return NULL;
|
||||
(void)sprintf(temp, "%s%s", dirpath, entry->d_name); /* safe */
|
||||
|
||||
/* test, if it's directory */
|
||||
if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode))
|
||||
isdir = "/";
|
||||
free(temp);
|
||||
temp = malloc(strlen(dirname) + len + 1 + 1);
|
||||
temp = malloc(strlen(dirname) + len + 1);
|
||||
if (temp == NULL)
|
||||
return NULL;
|
||||
(void)sprintf(temp, "%s%s%s", dirname, entry->d_name, isdir);
|
||||
(void)sprintf(temp, "%s%s", dirname, entry->d_name);
|
||||
} else {
|
||||
(void)closedir(dir);
|
||||
dir = NULL;
|
||||
@ -257,7 +247,22 @@ filename_completion_function(const char *text, int state)
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
append_char_function(const char *name)
|
||||
{
|
||||
struct stat stbuf;
|
||||
char *expname = *name == '~' ? tilde_expand(name) : NULL;
|
||||
const char *rs = "";
|
||||
|
||||
if (stat(expname ? expname : name, &stbuf) == -1)
|
||||
goto out;
|
||||
if (S_ISDIR(stbuf.st_mode))
|
||||
rs = "/";
|
||||
out:
|
||||
if (expname)
|
||||
free(expname);
|
||||
return rs;
|
||||
}
|
||||
/*
|
||||
* returns list of completions for text given
|
||||
* non-static for readline.
|
||||
@ -385,7 +390,7 @@ fn_complete(EditLine *el,
|
||||
char *(*complet_func)(const char *, int),
|
||||
char **(*attempted_completion_function)(const char *, int, int),
|
||||
const char *word_break, const char *special_prefixes,
|
||||
char append_character, int query_items,
|
||||
const char *(*app_func)(const char *), int query_items,
|
||||
int *completion_type, int *over, int *point, int *end)
|
||||
{
|
||||
const LineInfo *li;
|
||||
@ -403,6 +408,8 @@ fn_complete(EditLine *el,
|
||||
|
||||
if (!complet_func)
|
||||
complet_func = filename_completion_function;
|
||||
if (!app_func)
|
||||
app_func = append_char_function;
|
||||
|
||||
/* We now look backwards for the start of a filename/variable word */
|
||||
li = el_line(el);
|
||||
@ -459,15 +466,7 @@ fn_complete(EditLine *el,
|
||||
* it, unless we do filename completion and the
|
||||
* object is a directory.
|
||||
*/
|
||||
size_t alen = strlen(matches[0]);
|
||||
if ((complet_func != filename_completion_function
|
||||
|| (alen > 0 && (matches[0])[alen - 1] != '/'))
|
||||
&& append_character) {
|
||||
char buf[2];
|
||||
buf[0] = append_character;
|
||||
buf[1] = '\0';
|
||||
el_insertstr(el, buf);
|
||||
}
|
||||
el_insertstr(el, (*append_char_function)(matches[0]));
|
||||
} else if (what_to_do == '!') {
|
||||
display_matches:
|
||||
/*
|
||||
@ -535,6 +534,6 @@ unsigned char
|
||||
_el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
|
||||
{
|
||||
return (unsigned char)fn_complete(el, NULL, NULL,
|
||||
break_chars, NULL, ' ', 100,
|
||||
break_chars, NULL, NULL, 100,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: filecomplete.h,v 1.2 2005/05/07 16:28:32 dsl Exp $ */
|
||||
/* $NetBSD: filecomplete.h,v 1.3 2005/06/10 20:21:00 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -41,11 +41,11 @@
|
||||
int fn_complete(EditLine *,
|
||||
char *(*)(const char *, int),
|
||||
char **(*)(const char *, int, int),
|
||||
const char *, const char *, char, int,
|
||||
const char *, const char *, const char *(*)(const char *), int,
|
||||
int *, int *, int *, int *);
|
||||
|
||||
void fn_display_match_list(EditLine *, char **, int, int);
|
||||
char *tilde_expand(char *txt);
|
||||
char *tilde_expand(const char *);
|
||||
char *filename_completion_function(const char *, int);
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: readline.c,v 1.55 2005/05/27 14:01:46 agc Exp $ */
|
||||
/* $NetBSD: readline.c,v 1.56 2005/06/10 20:21:00 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#if !defined(lint) && !defined(SCCSID)
|
||||
__RCSID("$NetBSD: readline.c,v 1.55 2005/05/27 14:01:46 agc Exp $");
|
||||
__RCSID("$NetBSD: readline.c,v 1.56 2005/06/10 20:21:00 christos Exp $");
|
||||
#endif /* not lint && not SCCSID */
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -1408,6 +1408,16 @@ rl_display_match_list(char **matches, int len, int max)
|
||||
fn_display_match_list(e, matches, len, max);
|
||||
}
|
||||
|
||||
static const char *
|
||||
/*ARGSUSED*/
|
||||
_rl_completion_append_character_function(const char *dummy
|
||||
__attribute__((__unused__)))
|
||||
{
|
||||
static char buf[2];
|
||||
buf[1] = rl_completion_append_character;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* complete word at current point
|
||||
@ -1432,7 +1442,7 @@ rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
|
||||
(CPFunction *)rl_completion_entry_function,
|
||||
rl_attempted_completion_function,
|
||||
rl_basic_word_break_characters, rl_special_prefixes,
|
||||
rl_completion_append_character, rl_completion_query_items,
|
||||
_rl_completion_append_character_function, rl_completion_query_items,
|
||||
&rl_completion_type, &rl_attempted_completion_over,
|
||||
&rl_point, &rl_end);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user