diff options
| author | Toby Goodwin <toby@paccrat.org> | 2015-10-23 11:17:53 +0100 |
|---|---|---|
| committer | Toby Goodwin <toby@paccrat.org> | 2015-10-23 11:17:53 +0100 |
| commit | 680d794205b9e7ec0f17732dd31fc231a84b0115 (patch) | |
| tree | c40c99d5272ee0e021ae55641842fbe9e2f37656 /edit-gnu.c | |
| parent | 85bdc54544a8b0f9f8c4b2103a7eced0dde69fb2 (diff) | |
| parent | c884da53a7c885d46ace2b92de78946855b18e92 (diff) | |
Merge branch 'master' into develop
Diffstat (limited to 'edit-gnu.c')
| -rw-r--r-- | edit-gnu.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/edit-gnu.c b/edit-gnu.c new file mode 100644 index 0000000..6a997c5 --- /dev/null +++ b/edit-gnu.c @@ -0,0 +1,87 @@ +#include "rc.h" + +#include <errno.h> +#include <stdio.h> +#include <readline/readline.h> +#include <readline/history.h> +#include <readline/rltypedefs.h> + +#include "edit.h" + +bool editing = 1; + +struct cookie { + char *buffer; +}; + +void *edit_begin(int fd) { + List *hist; + struct cookie *c; + + rl_catch_signals = 0; + rl_completer_quote_characters = "'"; + rl_filename_quote_characters = "\t\n !#$&'()*;<=>?@[\\]^`{|}~"; + + hist = varlookup("history"); + if (hist != NULL) + if (read_history(hist->w) != 0 && errno != ENOENT) /* ignore if missing */ + uerror(hist->w); + + c = ealloc(sizeof *c); + c->buffer = NULL; + return c; +} + +static void edit_catcher(int sig) { + write(2, "\n", 1); + rc_raise(eError); +} + +static char *prompt; + +char *edit_alloc(void *cookie, size_t *count) { + struct cookie *c = cookie; + void (*oldint)(int), (*oldquit)(int); + + oldint = sys_signal(SIGINT, edit_catcher); + oldquit = sys_signal(SIGQUIT, edit_catcher); + + c->buffer = readline(prompt); + + sys_signal(SIGINT, oldint); + sys_signal(SIGQUIT, oldquit); + + if (c->buffer) { + *count = strlen(c->buffer); + if (*count) + add_history(c->buffer); + c->buffer[*count] = '\n'; + ++*count; /* include the \n */ + } + return c->buffer; +} + +void edit_prompt(void *cookie, char *pr) { + prompt = pr; +} + +void edit_free(void *cookie) { + struct cookie *c = cookie; + + efree(c->buffer); + /* Set c->buffer to NULL, allowing us to "overfree" it. This + is a bit of a kludge, but it's otherwise hard to deal with + the case where a signal causes an early return from + readline. */ + c->buffer = NULL; +} + +void edit_end(void *cookie) { + struct cookie *c = cookie; + + efree(c); +} + +void edit_reset(void *cookie) { + rl_reset_terminal(NULL); +} |