1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 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);
}
|