edit-edit.c (1600B)
1 #include "rc.h" 2 3 #include <stdio.h> 4 5 #include <histedit.h> 6 7 #include "edit.h" 8 9 bool editing = 1; 10 11 struct cookie { 12 EditLine *el; 13 History *hist; 14 }; 15 16 static char *prompt; 17 18 void *edit_begin(int fd) { 19 FILE *f; 20 HistEvent he; 21 struct cookie *c; 22 23 c = ealloc(sizeof *c); 24 if (fd == 0) 25 f = stdin; 26 else 27 f = fdopen(fd, "r"); 28 c->el = el_init("rc", f, stdout, stderr); 29 el_set(c->el, EL_SIGNAL, 0); 30 el_source(c->el, NULL); 31 32 c->hist = history_init(); 33 history(c->hist, &he, H_SETSIZE, 20); 34 el_set(c->el, EL_HIST, history, c->hist); 35 36 return c; 37 } 38 39 40 static void (*oldint)(int), (*oldquit)(int); 41 42 static void edit_catcher(int sig) { 43 sys_signal(SIGINT, oldint); 44 sys_signal(SIGQUIT, oldquit); 45 write(2, "\n", 1); 46 rc_raise(eError); 47 } 48 49 char *edit_alloc(void *cookie, size_t *count) { 50 const char *r; 51 HistEvent he; 52 struct cookie *c = cookie; 53 54 oldint = sys_signal(SIGINT, edit_catcher); 55 oldquit = sys_signal(SIGQUIT, edit_catcher); 56 57 r = el_gets(c->el, count); 58 59 sys_signal(SIGINT, oldint); 60 sys_signal(SIGQUIT, oldquit); 61 62 if (r) 63 history(c->hist, &he, H_ENTER, r); 64 return (char *)r; /* cast to avoid gcc warning */ 65 } 66 67 static char *edit_prompter(EditLine *e) { 68 return prompt; 69 } 70 71 void edit_prompt(void *cookie, char *pr) { 72 struct cookie *c = cookie; 73 74 prompt = pr; 75 el_set(c->el, EL_PROMPT, edit_prompter); 76 } 77 78 void edit_free(void *cookie) { 79 /* this function deliberately left blank */ 80 } 81 82 void edit_end(void *cookie) { 83 struct cookie *c = cookie; 84 85 el_end(c->el); 86 history_end(c->hist); 87 efree(c); 88 } 89 90 void edit_reset(void *cookie) { 91 struct cookie *c = cookie; 92 93 el_set(c->el, EL_TERMINAL, NULL); 94 }