summaryrefslogtreecommitdiff
path: root/edit-readline.c
diff options
context:
space:
mode:
authorToby Goodwin <toby@paccrat.org>2015-04-07 22:22:56 +0100
committerToby Goodwin <toby@paccrat.org>2015-05-16 21:23:25 +0100
commit8ca9f57a797e425205e08bce8355cf953d6be16b (patch)
treefc93e67a501ef5323ef5bee8fcc2a9a698245a3e /edit-readline.c
parentfbeb8501cdbf8f640605e3c05551fd71e5cc33a3 (diff)
edit shims: better naming, editline and vrl added
Diffstat (limited to 'edit-readline.c')
-rw-r--r--edit-readline.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/edit-readline.c b/edit-readline.c
new file mode 100644
index 0000000..6a997c5
--- /dev/null
+++ b/edit-readline.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);
+}