Page MenuHomeFreeBSD

D34544.id103810.diff
No OneTemporary

D34544.id103810.diff

Index: bin/sh/expand.h
===================================================================
--- bin/sh/expand.h
+++ bin/sh/expand.h
@@ -60,3 +60,4 @@
void expandarg(union node *, struct arglist *, int);
void rmescapes(char *);
int casematch(union node *, const char *);
+const char *tilde_expand(const char *);
Index: bin/sh/expand.c
===================================================================
--- bin/sh/expand.c
+++ bin/sh/expand.c
@@ -356,6 +356,19 @@
}
}
+const char *
+tilde_expand(const char *name)
+{
+ const char *next;
+
+ STARTSTACKSTR(expdest);
+ next = exptilde(name, 0);
+ STPUTS(next, expdest);
+ STACKSTRNUL(expdest);
+
+ return (stackblock());
+}
+
/*
* Perform tilde expansion, placing the result in the stack string and
* returning the next position in the input string to process.
Index: bin/sh/histedit.c
===================================================================
--- bin/sh/histedit.c
+++ bin/sh/histedit.c
@@ -45,6 +45,7 @@
#include <fcntl.h>
#include <limits.h>
#include <paths.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -63,6 +64,7 @@
#include "myhistedit.h"
#include "error.h"
#include "eval.h"
+#include "expand.h"
#include "memalloc.h"
#define MAXHISTLOOPS 4 /* max recursions through fc */
@@ -73,12 +75,14 @@
int displayhist;
static int savehist;
static FILE *el_in, *el_out;
+static bool in_command_completion;
static char *fc_replace(const char *, char *, char *);
static int not_fcnumber(const char *);
static int str_to_event(const char *, int);
static int comparator(const void *, const void *, void *);
static char **sh_matches(const char *, int, int);
+static const char *append_char_function(const char *);
static unsigned char sh_complete(EditLine *, int);
static const char *
@@ -603,8 +607,10 @@
size_t i = 0, size = 16, uniq;
size_t curpos = end - start, lcstring = -1;
+ in_command_completion = false;
if (start > 0 || memchr("/.~", text[0], 3) != NULL)
return (NULL);
+ in_command_completion = true;
if ((free_path = path = strdup(pathval())) == NULL)
goto out;
if ((matches = malloc(size * sizeof(matches[0]))) == NULL)
@@ -697,6 +703,29 @@
return (matches);
}
+/*
+ * If we don't specify this function as app_func in the call to fn_complete2,
+ * libedit will use the default one, which adds a " " to plain files and
+ * a "/" to directories regardless of whether it's a command name or a plain
+ * path (relative or absolute). We never want to add "/" to commands.
+ *
+ * For example, after I did "mkdir rmdir", "rmdi" would be autocompleted to
+ * "rmdir/" instead of "rmdir ".
+ */
+static const char *
+append_char_function(const char *name)
+{
+ struct stat stbuf;
+
+ if (name[0] == '~')
+ name = tilde_expand(name, 0);
+
+ if (!in_command_completion &&
+ stat(name, &stbuf) == 0 && S_ISDIR(stbuf.st_mode))
+ return ("/");
+ return (" ");
+}
+
/*
* This is passed to el_set(el, EL_ADDFN, ...) so that it's possible to
* bind a key (tab by default) to execute the function.
@@ -705,8 +734,8 @@
sh_complete(EditLine *sel, int ch __unused)
{
return (unsigned char)fn_complete2(sel, NULL, sh_matches,
- L" \t\n\"\\'`@$><=;|&{(", NULL, NULL, (size_t)100,
- NULL, &((int) {0}), NULL, NULL, FN_QUOTE_MATCH);
+ L" \t\n\"\\'`@$><=;|&{(", NULL, append_char_function,
+ (size_t)100, NULL, &((int) {0}), NULL, NULL, FN_QUOTE_MATCH);
}
#else

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 15, 1:11 PM (2 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27651226
Default Alt Text
D34544.id103810.diff (3 KB)

Event Timeline