💾 Archived View for thrig.me › tech › openbsd › editline.gmi captured on 2024-07-09 at 01:40:59. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-07-10)

-=-=-=-=-=-=-

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);
    }

elpractice.c

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.

https://thrig.me/src/lingua.git