aboutsummaryrefslogtreecommitdiff
path: root/c/readline.c
blob: b981ee7482fed88b56f8af4cf4b0f18f3848b0ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#if USE_READLINE
  #include <readline/readline.h>
  #include <readline/history.h>
  #include <readline/tilde.h>
#else
  #include <editline/readline.h>
  #include <editline/history.h>
#endif

int history_loaded = 0;

char HISTORY_FILE[] = "~/.mal-history";

int load_history() {
    if (history_loaded) { return 0; }
    int ret;
    char *hf = tilde_expand(HISTORY_FILE);
    if (access(hf, F_OK) != -1) {
        // TODO: check if file exists first, use non-static path
#if USE_READLINE
        ret = read_history(hf);
#else
        FILE *fp = fopen(hf, "r");
        char *line = malloc(80); // getline reallocs as necessary
        size_t sz = 80;
        while ((ret = getline(&line, &sz, fp)) > 0) {
            add_history(line); // Add line to in-memory history
        }
        free(line);
        fclose(fp);
#endif
        history_loaded = 1;
    }
    free(hf);
}

int append_to_history() {
    char *hf = tilde_expand(HISTORY_FILE);
#ifdef USE_READLINE
    append_history(1, hf);
#else
    HIST_ENTRY *he = history_get(history_length-1);
    FILE *fp = fopen(hf, "a");
    fprintf(fp, "%s\n", he->line);
    fclose(fp);
#endif
    free(hf);
}


// line must be freed by caller
char *_readline (char prompt[]) {
    char *line;

    load_history();

    line = readline(prompt);
    if (!line) return NULL; // EOF
    add_history(line); // Add input to in-memory history

    append_to_history(); // Flush new line of history to disk

    return line;
}