From cedd28ded91fa4b0b786fd17e94954e6afb66646 Mon Sep 17 00:00:00 2001 From: Kai Harries Date: Fri, 1 Nov 2019 15:02:17 +0100 Subject: [PATCH 1/2] repl: support auto-completion when compiled with READLINE --- src/nix/repl.cc | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/nix/repl.cc b/src/nix/repl.cc index f857b2e89c2..42839143b15 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -137,6 +137,30 @@ NixRepl::~NixRepl() static NixRepl * curRepl; // ugly +#ifdef READLINE +static char * completionFuncReadline(const char * text, int state) +{ + static StringSet matches = curRepl->completePrefix(text); + + if (state == 0) { + matches = curRepl->completePrefix(text); + } + + auto it = matches.begin(); + while (state > 0 && it != matches.end()) { + it++; + state--; + } + + if (it == matches.end()) { + return nullptr; + } + else { + return strdup(it->c_str()); + } +} + +#else static char * completionCallback(char * s, int *match) { auto possible = curRepl->completePrefix(s); if (possible.size() == 1) { @@ -198,6 +222,7 @@ static int listPossibleCallback(char *s, char ***avp) { return ac; } +#endif namespace { // Used to communicate to NixRepl::getLine whether a signal occurred in ::readline. @@ -227,7 +252,9 @@ void NixRepl::mainLoop(const std::vector & files) #endif read_history(historyFile.c_str()); curRepl = this; -#ifndef READLINE +#ifdef READLINE + rl_completion_entry_function = completionFuncReadline; +#else rl_set_complete_func(completionCallback); rl_set_list_possib_func(listPossibleCallback); #endif From 40df2d424b493f654992ed3bf5fea8be66cca542 Mon Sep 17 00:00:00 2001 From: Kai Harries Date: Fri, 1 Nov 2019 22:06:40 +0100 Subject: [PATCH 2/2] repl: support history when compiled with READLINE --- src/nix/repl.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nix/repl.cc b/src/nix/repl.cc index 42839143b15..7fbd2524bd3 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -329,6 +329,11 @@ bool NixRepl::getLine(string & input, const std::string &prompt) if (!s) return false; +#ifdef READLINE + if (*s) { + add_history(s); + } +#endif input += s; input += '\n'; return true;