commit 922362de863e7b93a87fdbcfe2d03bb10ea7597c
parent bfc5891f81e9235934c929848957ee0af92a34c1
Author: hhvn <dev@hhvn.uk>
Date: Mon, 2 May 2022 13:41:02 +0100
Complete files/directories correctly
Diffstat:
1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/complete.c b/src/complete.c
@@ -19,7 +19,9 @@
#include <string.h>
#include <libgen.h>
+#include <limits.h>
#include <dirent.h>
+#include <sys/stat.h>
#include "hirc.h"
void complete_stitch(wchar_t *dest, size_t dsize, unsigned *counter, unsigned coff,
@@ -32,7 +34,7 @@ void complete_cmds(char *str, size_t len, char **ret, int *fullcomplete);
void complete_settings(char *str, size_t len, char **ret, int *fullcomplete);
void complete_nicks(struct Channel *chan, char *str, size_t len, char **ret, int *fullcomplete);
void complete_servers(struct Server **head, char *str, size_t len, char **ret, int *fullcomplete);
-void complete_files(char *str, size_t len, char **ret, int *fullcomplete);
+void complete_files(char *str, char **ret, int *fullcomplete);
void
complete_stitch(wchar_t *dest, size_t dsize, unsigned *counter, unsigned coff,
@@ -101,27 +103,44 @@ complete_servers(struct Server **head, char *str, size_t len, char **ret, int *f
}
void
-complete_files(char *str, size_t len, char **ret, int *fullcomplete) {
- char *cpy[2], *dir, *file;
+complete_files(char *str, char **ret, int *fullcomplete) {
+ char *cpy[2], *dir, *base;
+ char path[PATH_MAX], *p;
struct dirent **dirent;
+ struct stat st;
int dirs, i;
+ size_t len;
cpy[0] = estrdup(str);
cpy[1] = estrdup(str);
- dir = dirname(cpy[0]);
- file = basename(cpy[1]);
+ dir = estrdup(dirname(cpy[0]));
+ base = basename(cpy[1]);
+ len = strlen(base);
if ((dirs = scandir(dir, &dirent, NULL, alphasort)) >= 0) {
+ if (*(p = dir + strlen(dir) - 1) == '/')
+ *p = '\0';
for (i = 0; i < dirs; i++) {
- if (strncmp(dirent[i]->d_name, str, len) == 0)
- complete_add(ret, dirent[i]->d_name, fullcomplete);
+ if (strncmp(dirent[i]->d_name, base, len) == 0) {
+ snprintf(path, sizeof(path), "%s/%s", dir, dirent[i]->d_name);
+ complete_add(ret, path, fullcomplete);
+ }
pfree(&dirent[i]);
}
pfree(&dirent);
}
+ /* A directory isn't a full completion */
+ if (*fullcomplete && stat(*ret, &st) == 0 && S_ISDIR(st.st_mode)) {
+ snprintf(path, sizeof(path), "%s/", *ret);
+ pfree(ret); /* already a pointer to the pointer */
+ *ret = estrdup(path);
+ *fullcomplete = 0;
+ }
+
pfree(&cpy[0]);
pfree(&cpy[1]);
+ pfree(&dir);
}
void
@@ -311,7 +330,7 @@ getcmd:
stem = wctos(wstem);
len = strlen(stem);
- complete_files(stem, len, &found, &fullcomplete);
+ complete_files(stem, &found, &fullcomplete);
pfree(&stem);
if (found) {