summaryrefslogtreecommitdiffstatshomepage
path: root/unix/input.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-05-24 22:36:31 +0100
committerDamien George <damien.p.george@gmail.com>2015-05-27 15:59:43 +0100
commit9ae3fc65235303322ef5282d3cdd4ca99a2c37cc (patch)
tree5644437cc732a8a33f2ec8752610d4d55c8a740b /unix/input.c
parent4a10214be20cb8a51724913903678f4506358752 (diff)
downloadmicropython-9ae3fc65235303322ef5282d3cdd4ca99a2c37cc.tar.gz
micropython-9ae3fc65235303322ef5282d3cdd4ca99a2c37cc.zip
unix: Add option to use uPy readline, and enable by default.
This gets uPy readline working with unix port, with tab completion and history. GNU readline is still supported, configure using MICROPY_USE_READLINE variable.
Diffstat (limited to 'unix/input.c')
-rw-r--r--unix/input.c86
1 files changed, 79 insertions, 7 deletions
diff --git a/unix/input.c b/unix/input.c
index 0a02483f70..d41487c7ef 100644
--- a/unix/input.c
+++ b/unix/input.c
@@ -28,26 +28,50 @@
#include <stdlib.h>
#include <string.h>
-#include "py/nlr.h"
-#include "py/obj.h"
+#include "py/mpstate.h"
#include "input.h"
-#if MICROPY_USE_READLINE
+#if MICROPY_USE_READLINE == 1
+#include MICROPY_HAL_H
+#include "lib/mp-readline/readline.h"
+#elif MICROPY_USE_READLINE == 2
#include <readline/readline.h>
#include <readline/history.h>
#include <readline/tilde.h>
-#else
-#undef MICROPY_USE_READLINE_HISTORY
-#define MICROPY_USE_READLINE_HISTORY (0)
#endif
char *prompt(char *p) {
-#if MICROPY_USE_READLINE
+#if MICROPY_USE_READLINE == 1
+ // MicroPython supplied readline
+ vstr_t vstr;
+ vstr_init(&vstr, 16);
+ mp_hal_stdio_mode_raw();
+ int ret = readline(&vstr, p);
+ mp_hal_stdio_mode_orig();
+ if (ret != 0) {
+ vstr_clear(&vstr);
+ if (ret == CHAR_CTRL_D) {
+ // EOF
+ return NULL;
+ } else {
+ printf("\n");
+ char *line = malloc(1);
+ line[0] = '\0';
+ return line;
+ }
+ }
+ vstr_null_terminated_str(&vstr);
+ char *line = malloc(vstr.len + 1);
+ memcpy(line, vstr.buf, vstr.len + 1);
+ vstr_clear(&vstr);
+#elif MICROPY_USE_READLINE == 2
+ // GNU readline
char *line = readline(p);
if (line) {
add_history(line);
}
#else
+ // simple read string
static char buf[256];
fputs(p, stdout);
char *s = fgets(buf, sizeof(buf), stdin);
@@ -68,13 +92,61 @@ char *prompt(char *p) {
void prompt_read_history(void) {
#if MICROPY_USE_READLINE_HISTORY
+ #if MICROPY_USE_READLINE == 1
+ readline_init0(); // will clear history pointers
+ char *home = getenv("HOME");
+ if (home != NULL) {
+ vstr_t vstr;
+ vstr_init(&vstr, 50);
+ vstr_printf(&vstr, "%s/.micropython.history", home);
+ FILE *fp = fopen(vstr_null_terminated_str(&vstr), "r");
+ if (fp != NULL) {
+ vstr_reset(&vstr);
+ for (;;) {
+ int c = fgetc(fp);
+ if (c == EOF || c == '\n') {
+ readline_push_history(vstr_null_terminated_str(&vstr));
+ if (c == EOF) {
+ break;
+ }
+ vstr_reset(&vstr);
+ } else {
+ vstr_add_byte(&vstr, c);
+ }
+ }
+ fclose(fp);
+ }
+ vstr_clear(&vstr);
+ }
+ #elif MICROPY_USE_READLINE == 2
read_history(tilde_expand("~/.micropython.history"));
+ #endif
#endif
}
void prompt_write_history(void) {
#if MICROPY_USE_READLINE_HISTORY
+ #if MICROPY_USE_READLINE == 1
+ char *home = getenv("HOME");
+ if (home != NULL) {
+ vstr_t vstr;
+ vstr_init(&vstr, 50);
+ vstr_printf(&vstr, "%s/.micropython.history", home);
+ FILE *fp = fopen(vstr_null_terminated_str(&vstr), "w");
+ if (fp != NULL) {
+ for (int i = MP_ARRAY_SIZE(MP_STATE_PORT(readline_hist)) - 1; i >= 0; i--) {
+ const char *line = MP_STATE_PORT(readline_hist)[i];
+ if (line != NULL) {
+ fwrite(line, 1, strlen(line), fp);
+ fputc('\n', fp);
+ }
+ }
+ fclose(fp);
+ }
+ }
+ #elif MICROPY_USE_READLINE == 2
write_history(tilde_expand("~/.micropython.history"));
+ #endif
#endif
}