#ifdef CS_REPL_USE_LIBEDIT #ifndef CS_REPL_HAS_EDIT #define CS_REPL_HAS_EDIT /* use the NetBSD libedit library */ #include #include #include static EditLine *els = nullptr; static History *elh = nullptr; static char *el_prompt(EditLine *el) { void *prompt = nullptr; el_get(el, EL_CLIENTDATA, &prompt); if (!prompt) { return const_cast(""); } return const_cast(static_cast(prompt)->get_value().data()); } static void init_lineedit(ostd::ConstCharRange progname) { els = el_init(progname.data(), stdin, stdout, stderr); elh = history_init(); /* init history with reasonable size */ HistEvent ev; history(elh, &ev, H_SETSIZE, 1000); el_set(els, EL_HIST, history, elh); el_set(els, EL_PROMPT, el_prompt); } static ostd::Maybe read_line(CsSvar *pr) { int count; el_set(els, EL_CLIENTDATA, static_cast(pr)); auto line = el_gets(els, &count); if (count > 0) { ostd::String ret = line; /* libedit keeps the trailing \n */ ret.resize(ret.size() - 1); return ostd::move(ret); } else if (!count) { return ostd::String(); } return ostd::nothing; } static void add_history(ostd::ConstCharRange line) { HistEvent ev; /* backed by ostd::String so it's terminated */ history(elh, &ev, H_ENTER, line.data()); } #endif #endif