@@ -3,6 +3,10 @@ package main
4#include <stdlib.h>
4#include <stdlib.h>
5#include <linenoise.h>
5#include <linenoise.h>
7+void linenoise_setup();
@@ -11,7 +15,45 @@ import (
18+type Completer func(line string) []string
19+type Hinter func(line string) string
22+var completer Completer
25+//export linenoiseCompletionStub
26+func linenoiseCompletionStub(input *C.char, completions *C.linenoiseCompletions) {
27+ if completer == nil {
30+ completionsSlice := completer(C.GoString(input))
31+ completionsLen := len(completionsSlice)
32+ completions.len = C.size_t(completionsLen)
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]
38+ for i, str := range completionsSlice {
39+ cvecSlice[i] = C.CString(str)
41+ completions.cvec = (**C.char)(cvec)
45+//export linenoiseHintsStub
46+func linenoiseHintsStub(input *C.char, color *C.int, bold *C.int) *C.char {
52+ return C.CString(hinter(C.GoString(input)))
14func Linenoise(prompt string) (string,error) {
55func Linenoise(prompt string) (string,error) {
15 cprompt := C.CString(prompt)
57 cprompt := C.CString(prompt)
16 defer C.free(unsafe.Pointer(cprompt))
58 defer C.free(unsafe.Pointer(cprompt))
17 cresult := C.linenoise(cprompt)
59 cresult := C.linenoise(cprompt)
@@ -27,4 +69,13 @@ func LinenoiseHistoryAdd(line string) {
27 data := C.CString(line)
69 data := C.CString(line)
28 defer C.free(unsafe.Pointer(data))
70 defer C.free(unsafe.Pointer(data))
29 C.linenoiseHistoryAdd(data)
71 C.linenoiseHistoryAdd(data)
74+func LinenoiseSetCompleter(newCompleter Completer) {
75+ completer = newCompleter
78+func LinenoiseSetHinter(newHinter Hinter) {