diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | shed.h | 2 | ||||
-rw-r--r-- | shed_complete.c | 52 | ||||
-rw-r--r-- | shed_non_vi.c | 2 |
4 files changed, 57 insertions, 3 deletions
@@ -13,7 +13,7 @@ SOURCES=alias.c bg.c builtins.c cd.c command.c fc.c fg.c getopts.c \ dot.c eval.c exec.c exit.c export.c readonly.c shift.c times.c trap.c \ unset.c \ interactive.c parse.c init.c getopt.c unspecified.c \ - shed.c shed_commands.c shed_edit.c shed_history.o shed_insert.c shed_io.c shed_move.c shed_non_vi.c + shed.c shed_commands.c shed_edit.c shed_history.o shed_insert.c shed_io.c shed_move.c shed_non_vi.cshed_complete.c HEADERS=sh.h shed.h OBJECTS=alias.o bg.o builtins.o cd.o command.o fc.o fg.o getopts.o \ hash.o jobs.o kill.o newgrp.o pwd.o read.o set.o main.o type.o \ @@ -21,7 +21,7 @@ OBJECTS=alias.o bg.o builtins.o cd.o command.o fc.o fg.o getopts.o \ dot.o eval.o exec.o exit.o export.o readonly.o shift.o times.o trap.o \ unset.o \ interactive.o parse.o init.o getopt.o unspecified.o \ - shed.o shed_commands.o shed_edit.o shed_history.o shed_insert.o shed_io.o shed_move.o shed_non_vi.o \ + shed.o shed_commands.o shed_edit.o shed_history.o shed_insert.o shed_io.o shed_move.o shed_non_vi.o shed_complete.o \ sh.tab.o sh.yy.o BUILTINS=alias bg cd command fc fg getopts jobs newgrp read \ ulimit umask unalias wait @@ -77,6 +77,8 @@ int shed_replace(struct shed *e); int shed_start_over(struct shed *e); int shed_worderase(struct shed *e); +int shed_complete_wordexp(struct shed *e); + int shed_history_backward(struct shed *e); int shed_history_forward(struct shed *e); diff --git a/shed_complete.c b/shed_complete.c new file mode 100644 index 0000000..145e0a7 --- /dev/null +++ b/shed_complete.c @@ -0,0 +1,52 @@ +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wordexp.h> +#include "shed.h" + +static void shed_reprompt(struct shed *e) +{ + write(STDOUT_FILENO, e->prompt, strlen(e->prompt)); + size_t pos = e->cur->pos; + e->cur->pos = 0; + e->count = (int)pos + 1; + shed_move_column(e); + e->count = 0; +} + +int shed_complete_wordexp(struct shed *e) +{ + char *start = e->cur->buf + e->cur->pos; + while (!isblank(*start) && start != e->cur->buf) { + start--; + } + if (isblank(*start)) { + start++; + } + + char *word = calloc(1, strlen(start) + 2); + strcpy(word, start); + char *end = word; + while (!isblank(*end) && *end != '\0') { + end++; + } + *end = '\0'; + + if (strpbrk(word, "*?[") == NULL) { + strcat(word, "*"); + } + + wordexp_t we = { 0 }; + wordexp(word, &we, WRDE_NOCMD); + for (size_t i = 0; i < we.we_wordc; i++) { + write(STDOUT_FILENO, i == 0 ? "\n" : "\t", 1); + write(STDOUT_FILENO, we.we_wordv[i], strlen(we.we_wordv[i])); + } + write(STDOUT_FILENO, "\n", 2); + wordfree(&we); + + free(word); + shed_reprompt(e); + return 1; +} diff --git a/shed_non_vi.c b/shed_non_vi.c index b299122..b915bf3 100644 --- a/shed_non_vi.c +++ b/shed_non_vi.c @@ -76,7 +76,7 @@ int shed_handle_non_vi(struct shed *e, struct termios *t, char c) case CTRL_F: return shed_move_forward(e); case CTRL_G: break; // return abort(e)? case CTRL_H: return shed_backspace(e); - case CTRL_I: break; // return complete_wordexp(e); + case CTRL_I: return shed_complete_wordexp(e); case CTRL_J: return shed_execute(e); case CTRL_K: return shed_delete_toend(e); case CTRL_L: return shed_redraw(e); |