editline
Some editline(3) practice code.
// elpractice.c - editline(3) pratice code
//
// CFLAGS="-ledit -lcurses" make elpractice
// ./elpractice
#include <err.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <histedit.h>
char *prompt(EditLine *e);
void resize(int nsig);
// in a more complicated program probably put this into an "app"
// struct or similar
EditLine *elp;
int
main(int argc, const char *argv[])
{
History *hsp;
HistEvent hev;
elp = el_init(getprogname(), stdin, stdout, stderr);
if (!elp) err(1, "el_init");
hsp = history_init();
if (!hsp) err(1, "history_init");
history(hsp, &hev, H_SETSIZE, 42);
el_parse(elp, argc, argv);
el_set(elp, EL_EDITOR, "vi");
el_set(elp, EL_HIST, history, hsp);
el_set(elp, EL_PROMPT, prompt);
//el_set(elp, EL_SIGNAL, 1); // install signal handlers
el_set(elp, EL_TERMINAL, NULL); // use $TERM
el_source(elp, NULL); // reads ~/.editrc
// a shell will probably want to ignore these; otherwise, for a
// program that runs under a shell the EL_SIGNAL option above
// is probably better, unless you do want your own custom
// signal handlers
signal(SIGINT, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
signal(SIGWINCH, resize);
#ifdef __OpenBSD__
if (pledge("stdio tty", NULL) == -1) err(1, "pledge");
#endif
while (1) {
const char *line;
int nchars;
line = el_gets(elp, &nchars);
if (!line) {
if (nchars == -1) err(1, "el_gets");
continue;
}
if (nchars == 1) continue; // blank line
history(hsp, &hev, H_ENTER, line);
// minus the trailing '\n' and a string we can mangle...
size_t len = (size_t) nchars - 1;
char *buf = strndup(line, len);
if (!buf) err(1, "strndup");
if (strcmp(buf, "quit") == 0) break;
printf("%s\n", buf);
free(buf);
}
history_end(hsp);
el_end(elp);
}
char *
prompt(EditLine *e)
{
return "EDLINE> ";
}
void
resize(int nsig)
{
el_resize(elp);
}
Presumably this could be adapted to do more interesting things, such as a simple shell.
$ CFLAGS=-ledit\ -lcurses make elpractice
cc -ledit -lcurses -o elpractice elpractice.c
$ ./elpractice
EDLINE> ls
ls
EDLINE> help
help
EDLINE> quit
$
See also editrc(5), or look under /usr/src for things that include "histedit.h"—sftp(1), for example.
midnoi under the following respository is what motivated this practice code.