From 9966c961d191578e1dfd1a883ec5fca869dc6991 Mon Sep 17 00:00:00 2001 From: vaclavt Date: Tue, 1 Mar 2022 20:29:18 +0100 Subject: [PATCH] autocompletion update --- Readme.md | 1 - ml.cpp | 14 ++++++-------- ml.h | 2 +- ml_util.cpp | 35 +++++++++++++++-------------------- ml_util.h | 2 +- 5 files changed, 23 insertions(+), 31 deletions(-) diff --git a/Readme.md b/Readme.md index 616958a..19c141a 100644 --- a/Readme.md +++ b/Readme.md @@ -70,7 +70,6 @@ utils/local_install.sh ### TODO - add test for >>> (range 1.5 (inc 5.5)) => (1.500000 2.500000 3.500000 4.500000 5.500000) -- ml_utils.cpp add all commands into const std::vector commands - unify -f and -run options - add debug support, at least call stack - multiline editing (see kilocpp editor) diff --git a/ml.cpp b/ml.cpp index e690eac..ed47495 100644 --- a/ml.cpp +++ b/ml.cpp @@ -2135,7 +2135,7 @@ bool MlEnvironment::has(const std::string &name) const { -std::map builtin_funcs +std::map builtin_funcs { // Special forms std::make_pair("def", builtin::define), @@ -2287,14 +2287,12 @@ MlValue MlEnvironment::get(const std::string &name) const { } // Get vector of executables in this scope -std::vector MlEnvironment::get_lambdas_list() const { - std::vector lambdas{128}; +std::vector MlEnvironment::get_lambdas_list(const std::string &token) const { + std::vector lambdas{}; - for (auto it = defs.begin(); it != defs.end(); it++) { - if (it->second.get_type_name() == FUNCTION_TYPE) { + for (auto it = defs.begin(); it != defs.end(); it++) + if (it->second.get_type_name() == FUNCTION_TYPE && (token.empty() || it->first.find(token) == 0)) lambdas.push_back(it->first); - } - } return lambdas; } @@ -2306,7 +2304,7 @@ void repl(MlEnvironment &env) { MlValue tmp; std::vector parsed; - setup_linenoise(env); + setup_linenoise(env, builtin_funcs); while (true) { char *line = linenoise(">>> "); diff --git a/ml.h b/ml.h index 265bb5b..84ccaec 100644 --- a/ml.h +++ b/ml.h @@ -50,7 +50,7 @@ public: void setX(const std::string &name, const MlValue& value); // Get vector of executables in this scope - std::vector get_lambdas_list() const; + std::vector get_lambdas_list(const std::string &token) const; void combine(MlEnvironment const &other); diff --git a/ml_util.cpp b/ml_util.cpp index 006daff..f8d646c 100644 --- a/ml_util.cpp +++ b/ml_util.cpp @@ -3,19 +3,11 @@ #include #include +#include #include +#include -const std::vector commands { - "eval", "type", "parse", "do", "if", "for", "while", "scope", "quote", "defn", - "def", "lambda", "benchmark", "=", "!=", ">", "<", ">=", "<=", "+", "-", "*", "/", "%", - "list", "insert", "index", "remove", "len", "push", "pop", "head", "tail", "first", "last", - "range", "map", "filter", "reduce", "exit", "quit", "print", "input", "random", "include", - "read-file", "write-file", "read-url", "system-cmd", "ls-dir", "is-file?", "is-dir?", - "parse-csv", "parse-json", "get-universal-time", "date-to-str", "str-to-date", "date-add", "debug", - "sprintf", "display", "string-replace", "string-regex?", "string-pad", "int", "float", "string", - "benchmark", "thread-create", "thread-under-lock", "thread-sleep", "threads-join", "try", "throw", - "usql" - }; +std::vector commands {}; std::string get_history_file_dir() { std::string filename{".ml_history.txt"}; @@ -27,7 +19,7 @@ std::string get_history_file_dir() { MlEnvironment * repl_env = nullptr; -void setup_linenoise(const MlEnvironment &env) { +void setup_linenoise(const MlEnvironment &env, const std::map &builtins) { repl_env = (MlEnvironment*) &env; std::string history_file = get_history_file_dir(); @@ -37,6 +29,10 @@ void setup_linenoise(const MlEnvironment &env) { linenoiseSetHintsCallback(hints); linenoiseSetMultiLine(1); linenoiseHistoryLoad(history_file.c_str()); + + commands.reserve(builtins.size()); + for(auto it = builtins.begin(); it != builtins.end(); ++it) + commands.push_back(it->first); } void linenoise_line_read(char *line) { @@ -68,15 +64,14 @@ void completion(const char *buf, linenoiseCompletions *lc) { std::string token = str.substr(pos+1); std::string begining = str.substr(0, pos+1); - // PERF optimize not to get all lambdas, but those beginning with token - std::vector lambdas = repl_env->get_lambdas_list(); - lambdas.insert(end(lambdas), begin(commands), end(commands)); + auto suggestions = repl_env->get_lambdas_list(token); + std::copy_if(commands.begin(), commands.end(), std::back_inserter(suggestions), + [&token] (const std::string &cmd) { return token.empty() || cmd.find(token)==0; }); - for (const auto & lambda : lambdas) { - if(lambda.find(token) == 0) { - std::string completion_string = begining + lambda; - linenoiseAddCompletion(lc, completion_string.c_str()); - } + std::sort(suggestions.begin(), suggestions.end()); + for (const auto &suggestion : suggestions) { + std::string completion = begining + suggestion; + linenoiseAddCompletion(lc, completion.c_str()); } } } diff --git a/ml_util.h b/ml_util.h index a408917..f2415d1 100644 --- a/ml_util.h +++ b/ml_util.h @@ -4,7 +4,7 @@ #include "linenoise.h" -void setup_linenoise(const MlEnvironment &env); +void setup_linenoise(const MlEnvironment &env, const std::map &builtins); void linenoise_line_read(char *line); void close_linenoise();