Wire up basic readline history/completion.

This commit is contained in:
Sage Vaillancourt 2022-04-08 10:23:12 -04:00 committed by Sage Vaillancourt
parent 056ea9eb13
commit 13d1168401
2 changed files with 55 additions and 10 deletions

View File

@ -14,7 +14,11 @@
(def nl (ch 10))
(def fore (fn (f list) ((map f list) "")))
(def fore (fn (action list)
"Apply the given action to each element in list." (
(map f list)
""
)))
(def first (fn (list) (at 0 list)))
@ -23,6 +27,11 @@
(def config (cat ~ "/.pebblisp.pbl"))
(def loadfile (fn (file-name)
"Read and evaluate the file with the given name." (
(eval (rf file-name))
)))
(def reloadConfig (fn () (loadfile config)))
(def string (fn (a) (cat "" a)))
@ -65,7 +74,8 @@
(def clock (fn (ti) (cat (hour ti) ":" (zero ti.minute) ":" (zero ti.sec))))
(def cleanDir (fn () (
(def cleanDir (fn ()
"Get a string of the current directory" (
(def di (cwd))
(if (matches di (cat ~ "*"))
(cat "~" (substr (slen ~) 999 di))

View File

@ -8,6 +8,15 @@
#include <readline/history.h>
#include <unistd.h>
struct Settings {
int runTests;
int ignoreConfig;
int ignoreLib;
int moreToDo;
const char* configFile;
char historyFile[128];
} settings;
Object getPrompt(struct Environment* env)
{
Object prompt = fetchFromEnvironment("prompt", env);
@ -47,11 +56,39 @@ void sigintHandler(unused int signalNumber)
cleanObject(&p);
}
char* completionGenerator(const char* text, int state)
{
static size_t i;
static size_t completionLength;
if (state == 0) {
i = 0;
completionLength = strlen(text);
}
struct ObjectTable* table = &global()->table;
for (; i < table->capacity; i++) {
if (table->elements[i].symbol && strncmp(table->elements[i].symbol, text, completionLength) == 0) {
char* symbol = malloc(sizeof(char) * (strlen(table->elements[i].symbol) + 1));
strcpy(symbol, table->elements[i].symbol);
i++;
return symbol;
}
}
return NULL;
}
char** completer(const char* text, int start, int end)
{
return rl_completion_matches(text, completionGenerator);
}
void repl(struct Environment* env)
{
rl_attempted_completion_function = completer;
signal(SIGINT, sigintHandler);
char* buf;
using_history();
read_history(settings.historyFile);
while ((buf = prompt(env)) != NULL) {
if (strcmp("q", buf) == 0) {
@ -81,6 +118,7 @@ void repl(struct Environment* env)
cleanObject(&o);
system(buf);
free(buf);
write_history(settings.historyFile);
continue;
}
free(buf);
@ -91,6 +129,7 @@ void repl(struct Environment* env)
printColored(output);
free(output);
printf("\n");
write_history(settings.historyFile);
}
}
@ -144,14 +183,6 @@ void setupSegfaultHandler()
}
#endif
struct Settings {
int runTests;
int ignoreConfig;
int ignoreLib;
int moreToDo;
const char* configFile;
} settings;
#define RUN_TESTS_ARG "--run-tests"
#define RUN_DETAILED_TESTS "=detailed"
#define IGNORE_CONFIG_ARG "--ignore-config"
@ -160,12 +191,16 @@ struct Settings {
void getSettings(int argc, const char* argv[])
{
const char* const home = getenv("HOME");
settings.runTests = 0;
settings.ignoreConfig = 0;
settings.ignoreLib = 0;
settings.moreToDo = 0;
settings.configFile = NULL;
sprintf(settings.historyFile, "%s/.plhist", home);
size_t runTestsLen = strlen(RUN_TESTS_ARG);
size_t configFileLen = strlen(CONFIG_FILE_ARG);
for (int i = 1; i < argc; i++) {