@@ -3,6 +3,10 @@ package main
33/*
44#include <stdlib.h>
55#include <linenoise.h>
6+
7+void linenoise_setup();
8+
9+
610*/
711import "C"
812
@@ -11,7 +15,45 @@ import (
1115 "fmt"
1216)
1317
18+type Completer func(line string) []string
19+type Hinter func(line string) string
20+
21+
22+var completer Completer
23+var hinter Hinter
24+
25+//export linenoiseCompletionStub
26+func linenoiseCompletionStub(input *C.char, completions *C.linenoiseCompletions) {
27+ if completer == nil {
28+ return
29+ }
30+ completionsSlice := completer(C.GoString(input))
31+ completionsLen := len(completionsSlice)
32+ completions.len = C.size_t(completionsLen)
33+
34+ if completionsLen > 0 {
35+ cvec := C.malloc(C.size_t(int(unsafe.Sizeof(*(**C.char)(nil))) * completionsLen))
36+ cvecSlice := (*(*[999999]*C.char)(cvec))[:completionsLen]
37+
38+ for i, str := range completionsSlice {
39+ cvecSlice[i] = C.CString(str)
40+ }
41+ completions.cvec = (**C.char)(cvec)
42+ }
43+}
44+
45+//export linenoiseHintsStub
46+func linenoiseHintsStub(input *C.char, color *C.int, bold *C.int) *C.char {
47+ if hinter == nil {
48+ return nil
49+ }
50+ *color = 37
51+ *bold = 0
52+ return C.CString(hinter(C.GoString(input)))
53+}
54+
1455func Linenoise(prompt string) (string,error) {
56+ C.linenoise_setup()
1557 cprompt := C.CString(prompt)
1658 defer C.free(unsafe.Pointer(cprompt))
1759 cresult := C.linenoise(cprompt)
@@ -27,4 +69,13 @@ func LinenoiseHistoryAdd(line string) {
2769 data := C.CString(line)
2870 defer C.free(unsafe.Pointer(data))
2971 C.linenoiseHistoryAdd(data)
30−}
72+}
73+
74+func LinenoiseSetCompleter(newCompleter Completer) {
75+ completer = newCompleter
76+}
77+
78+func LinenoiseSetHinter(newHinter Hinter) {
79+ hinter = newHinter
80+}
81+