libcubescript/tools/edit_linenoise.hh

75 lines
1.9 KiB
C++
Raw Permalink Normal View History

#ifdef CS_REPL_USE_LINENOISE
#ifndef CS_REPL_HAS_EDIT
#define CS_REPL_HAS_EDIT
/* use the bundled linenoise library, default */
#include <errno.h>
#include <ctype.h>
#include <signal.h>
2017-01-30 19:38:11 +01:00
#include <optional>
#include "linenoise.hh"
2021-03-23 23:29:32 +01:00
static cs::state *ln_cs = nullptr;
2016-09-11 23:33:02 +02:00
inline void ln_complete(char const *buf, std::vector<std::string> &lc) {
std::string_view cmd = get_complete_cmd(buf);
for (std::size_t i = 0; i < ln_cs->ident_count(); ++i) {
auto &id = ln_cs->get_ident(i);
if (id.type() != cs::ident_type::COMMAND) {
continue;
}
std::string_view idname = id.name();
if (idname.size() <= cmd.size()) {
continue;
}
if (idname.substr(0, cmd.size()) == cmd) {
lc.emplace_back(idname);
}
}
}
inline std::string ln_hint(char const *buf, int &color, int &bold) {
2021-03-23 23:29:32 +01:00
cs::command *cmd = get_hint_cmd(*ln_cs, buf);
if (!cmd) {
return std::string{};
}
2017-01-30 01:18:55 +01:00
std::string args = " [";
fill_cmd_args(args, cmd->args());
args += ']';
color = 35;
bold = 1;
return args;
}
2021-03-23 23:29:32 +01:00
inline void init_lineedit(cs::state &cs, std::string_view) {
/* sensible default history size */
linenoise::SetHistoryMaxLen(1000);
2016-09-11 23:33:02 +02:00
ln_cs = &cs;
linenoise::SetCompletionCallback(ln_complete);
linenoise::SetHintsCallback(ln_hint);
}
inline std::optional<std::string> read_line(cs::state &s, cs::builtin_var &pr) {
std::string line;
auto quit = linenoise::Readline(pr.value().get_string(s).data(), line);
if (quit) {
/* linenoise traps ctrl-c, detect it and let the user exit */
if (errno == EAGAIN) {
raise(SIGINT);
2017-01-30 19:38:11 +01:00
return std::nullopt;
}
2017-01-30 01:18:55 +01:00
return std::string{};
}
return line;
}
2021-03-23 23:29:32 +01:00
inline void add_history(cs::state &, std::string_view line) {
2017-01-30 01:18:55 +01:00
/* backed by std::string so it's terminated */
linenoise::AddHistory(line.data());
}
#endif
#endif