Wire up basic readline history/completion.
This commit is contained in:
parent
056ea9eb13
commit
13d1168401
|
@ -14,7 +14,11 @@
|
||||||
|
|
||||||
(def nl (ch 10))
|
(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)))
|
(def first (fn (list) (at 0 list)))
|
||||||
|
|
||||||
|
@ -23,6 +27,11 @@
|
||||||
|
|
||||||
(def config (cat ~ "/.pebblisp.pbl"))
|
(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 reloadConfig (fn () (loadfile config)))
|
||||||
|
|
||||||
(def string (fn (a) (cat "" a)))
|
(def string (fn (a) (cat "" a)))
|
||||||
|
@ -65,7 +74,8 @@
|
||||||
|
|
||||||
(def clock (fn (ti) (cat (hour ti) ":" (zero ti.minute) ":" (zero ti.sec))))
|
(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))
|
(def di (cwd))
|
||||||
(if (matches di (cat ~ "*"))
|
(if (matches di (cat ~ "*"))
|
||||||
(cat "~" (substr (slen ~) 999 di))
|
(cat "~" (substr (slen ~) 999 di))
|
||||||
|
|
51
src/main.c
51
src/main.c
|
@ -8,6 +8,15 @@
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#include <unistd.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 getPrompt(struct Environment* env)
|
||||||
{
|
{
|
||||||
Object prompt = fetchFromEnvironment("prompt", env);
|
Object prompt = fetchFromEnvironment("prompt", env);
|
||||||
|
@ -47,11 +56,39 @@ void sigintHandler(unused int signalNumber)
|
||||||
cleanObject(&p);
|
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)
|
void repl(struct Environment* env)
|
||||||
{
|
{
|
||||||
|
rl_attempted_completion_function = completer;
|
||||||
signal(SIGINT, sigintHandler);
|
signal(SIGINT, sigintHandler);
|
||||||
char* buf;
|
char* buf;
|
||||||
using_history();
|
using_history();
|
||||||
|
read_history(settings.historyFile);
|
||||||
|
|
||||||
while ((buf = prompt(env)) != NULL) {
|
while ((buf = prompt(env)) != NULL) {
|
||||||
if (strcmp("q", buf) == 0) {
|
if (strcmp("q", buf) == 0) {
|
||||||
|
@ -81,6 +118,7 @@ void repl(struct Environment* env)
|
||||||
cleanObject(&o);
|
cleanObject(&o);
|
||||||
system(buf);
|
system(buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
write_history(settings.historyFile);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
|
@ -91,6 +129,7 @@ void repl(struct Environment* env)
|
||||||
printColored(output);
|
printColored(output);
|
||||||
free(output);
|
free(output);
|
||||||
printf("[0m\n");
|
printf("[0m\n");
|
||||||
|
write_history(settings.historyFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,14 +183,6 @@ void setupSegfaultHandler()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Settings {
|
|
||||||
int runTests;
|
|
||||||
int ignoreConfig;
|
|
||||||
int ignoreLib;
|
|
||||||
int moreToDo;
|
|
||||||
const char* configFile;
|
|
||||||
} settings;
|
|
||||||
|
|
||||||
#define RUN_TESTS_ARG "--run-tests"
|
#define RUN_TESTS_ARG "--run-tests"
|
||||||
#define RUN_DETAILED_TESTS "=detailed"
|
#define RUN_DETAILED_TESTS "=detailed"
|
||||||
#define IGNORE_CONFIG_ARG "--ignore-config"
|
#define IGNORE_CONFIG_ARG "--ignore-config"
|
||||||
|
@ -160,12 +191,16 @@ struct Settings {
|
||||||
|
|
||||||
void getSettings(int argc, const char* argv[])
|
void getSettings(int argc, const char* argv[])
|
||||||
{
|
{
|
||||||
|
const char* const home = getenv("HOME");
|
||||||
|
|
||||||
settings.runTests = 0;
|
settings.runTests = 0;
|
||||||
settings.ignoreConfig = 0;
|
settings.ignoreConfig = 0;
|
||||||
settings.ignoreLib = 0;
|
settings.ignoreLib = 0;
|
||||||
settings.moreToDo = 0;
|
settings.moreToDo = 0;
|
||||||
settings.configFile = NULL;
|
settings.configFile = NULL;
|
||||||
|
|
||||||
|
sprintf(settings.historyFile, "%s/.plhist", home);
|
||||||
|
|
||||||
size_t runTestsLen = strlen(RUN_TESTS_ARG);
|
size_t runTestsLen = strlen(RUN_TESTS_ARG);
|
||||||
size_t configFileLen = strlen(CONFIG_FILE_ARG);
|
size_t configFileLen = strlen(CONFIG_FILE_ARG);
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
|
|
Loading…
Reference in New Issue