#include "ml_util.h" #include "string.h" #include #include #include // #include std::vector commands {}; std::string history_file; // kryplove z applu a jejich problemy s filesystemem /* std::string get_history_file_dir() { std::string filename{".ml_history.txt"}; const char *t = std::getenv("HOME"); if (t == nullptr) return std::filesystem::temp_directory_path() / filename; else return std::filesystem::path(std::string{t}) /filename; } */ std::string get_history_filepath(const std::string &file) { const char *t = std::getenv("HOME"); if (t == nullptr) return "/tmp/" + file; else return std::string{t} + "/" + file; } MlEnvironment * repl_env = nullptr; void setup_linenoise() { history_file = get_history_filepath("/.ml_history.txt"); linenoiseHistoryLoad(history_file.c_str()); linenoiseHistorySetMaxLen(500); linenoiseSetMultiLine(1); } void setup_linenoise_repl(const MlEnvironment &env, const std::map &builtins) { // basic linenoise setup must be already set repl_env = (MlEnvironment*) &env; linenoiseSetCompletionCallback(completion); linenoiseSetHintsCallback(hints); commands.reserve(builtins.size()); for(auto it = builtins.begin(); it != builtins.end(); ++it) commands.push_back(it->first); } void linenoise_add_to_history(const std::string &line) { if (!line.empty()) linenoiseHistoryAdd(line.c_str()); } void close_linenoise() { linenoiseHistorySave(history_file.c_str()); } size_t last_token_index(std::string str) { // remove trailing white space while( !str.empty() && std::isspace( str.back() ) ) str.pop_back() ; // locate the last white space return str.find_last_of( "() \t\n" ) ; } void completion(const char *buf, linenoiseCompletions *lc) { if (buf != nullptr) { std::string str{buf}; const auto pos = last_token_index(str); if (pos == std::string::npos) return; // cannot find what to complete std::string token = str.substr(pos+1); std::string begining = str.substr(0, pos+1); 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; }); std::sort(suggestions.begin(), suggestions.end()); for (const auto &suggestion : suggestions) { std::string completion = begining + suggestion; linenoiseAddCompletion(lc, completion.c_str()); } } } char *hints(const char *buf, int *color, int *bold) { // if (!strcasecmp(buf,"hello")) { // *color = 35; // *bold = 0; // return " World"; // } return nullptr; }