102 lines
2.8 KiB
C++
102 lines
2.8 KiB
C++
|
|
#include "ml_util.h"
|
|
#include "string.h"
|
|
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
// #include <filesystem>
|
|
|
|
std::vector<std::string> 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<const std::string, Builtin> &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;
|
|
}
|