Merge pull request #75 from kariya-mitsuru/fix-c-editline-history
[jackhill/mal.git] / c / readline.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4
5 #if USE_READLINE
6 #include <readline/readline.h>
7 #include <readline/history.h>
8 #include <readline/tilde.h>
9 #else
10 #include <editline/readline.h>
11 #endif
12
13 int history_loaded = 0;
14
15 char HISTORY_FILE[] = "~/.mal-history";
16
17 void load_history() {
18 if (history_loaded) { return; }
19 int ret;
20 char *hf = tilde_expand(HISTORY_FILE);
21 if (access(hf, F_OK) != -1) {
22 // TODO: check if file exists first, use non-static path
23 #if USE_READLINE
24 ret = read_history(hf);
25 #else
26 FILE *fp = fopen(hf, "r");
27 char *line = malloc(80); // getline reallocs as necessary
28 size_t sz = 80;
29 while ((ret = getline(&line, &sz, fp)) > 0) {
30 add_history(line); // Add line to in-memory history
31 }
32 free(line);
33 fclose(fp);
34 #endif
35 history_loaded = 1;
36 }
37 free(hf);
38 }
39
40 void append_to_history() {
41 char *hf = tilde_expand(HISTORY_FILE);
42 #ifdef USE_READLINE
43 append_history(1, hf);
44 #else
45 HIST_ENTRY *he = history_get(history_base+history_length-1);
46 FILE *fp = fopen(hf, "a");
47 if (fp) {
48 fprintf(fp, "%s\n", he->line);
49 fclose(fp);
50 }
51 #endif
52 free(hf);
53 }
54
55
56 // line must be freed by caller
57 char *_readline (char prompt[]) {
58 char *line;
59
60 load_history();
61
62 line = readline(prompt);
63 if (!line) return NULL; // EOF
64 add_history(line); // Add input to in-memory history
65
66 append_to_history(); // Flush new line of history to disk
67
68 return line;
69 }
70