aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/prompt.c
blob: b51e509c0aee151ee4cb26678ae718cf0f11c074 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "rc.h"
#include "fns.h"
#include "io.h"
#include "exec.h"
#include "getflags.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>

#include "linenoise.h"

#define DEBUG(f, a...) \
	if(0){}else{pfmt(err, "\n%s: "f,  __FUNCTION__, ## a);flush(err);}

#define HISTORY_PATH "~/.local/rc/history"

#define COMPLETE_FN 		"complete"
#define COMPLETE_RESULTS 	"rc_complete_results"

static
char*
completion_matches(const char *s, int i)
{
    word *w;

    for(w=vlook(COMPLETE_RESULTS)->val; w; w=w->next, i--)
        if(!i)
            return strdup(w->word);
    return nil;
}

static
void
completion(const char *text, linenoiseCompletions *lc)
{
    linenoiseAddCompletion(lc, "test");
}

static
void
savehist(void)
{
    linenoiseHistorySave(HISTORY_PATH);
}

static
void
readline(void)
{
    static int first = 1;
    io *f = runq->cmdfd;
    char *s;
    long n;

    if(first){
        linenoiseSetMultiLine(1);
        linenoiseSetCompletionCallback(completion);

        linenoiseHistorySetMaxLen(10000);

        /* history */
        if(linenoiseHistoryLoad(HISTORY_PATH)!=0 && errno!=ENOENT)
            pfmt(err, "rc: loadhistory: %s\n", strerror(errno));

        atexit(savehist);
        first = 0;
    }

    s = linenoise(promptstr);
    if(!s)
        return;

    n = strlen(s);
    assert(n < NBUF-1);
    strcpy(f->buf, s);
    f->buf[n++] = '\n';
    f->bufp = f->buf;
    f->ebuf = f->buf+n;

    linenoiseHistoryAdd(s);
    free(s);
}

void
pprompt(void)
{
	var *prompt;

	if(runq->iflag){
		flush(err);
		readline();
		prompt = vlook("prompt");
		if(prompt->val && prompt->val->next)
			promptstr = prompt->val->next->word;
		else
			promptstr="\t";
	}
	runq->lineno++;
	doprompt = 0;
}