#include "ml_util.h" #include #include #include #include // #include std::vector commands {}; // 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_file_dir() { std::string file{"/.ml_history.txt"}; 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(const MlEnvironment &env, const std::map &builtins) { repl_env = (MlEnvironment*) &env; std::string history_file = get_history_file_dir(); linenoiseHistorySetMaxLen(500); linenoiseSetCompletionCallback(completion); 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) { linenoiseHistoryAdd(line); } void close_linenoise() { std::string history_file = get_history_file_dir(); 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; }