ledisdb/cmd/ledis-cli/linenoise.go

77 lines
1.8 KiB
Go

// +build linenoise
package main
//#include <stdlib.h>
//#include "linenoise.h"
//#include "linenoiseCompletionCallbackHook.h"
import "C"
import (
"errors"
"unsafe"
)
func init() {
C.linenoiseSetupCompletionCallbackHook()
}
func line(prompt string) (string, error) {
promptCString := C.CString(prompt)
resultCString := C.linenoise(promptCString)
C.free(unsafe.Pointer(promptCString))
defer C.free(unsafe.Pointer(resultCString))
if resultCString == nil {
return "", errors.New("exiting due to signal")
}
result := C.GoString(resultCString)
return result, nil
}
func addHistory(line string) error {
lineCString := C.CString(line)
res := C.linenoiseHistoryAdd(lineCString)
C.free(unsafe.Pointer(lineCString))
if res != 1 {
return errors.New("Could not add line to history.")
}
return nil
}
func setHistoryCapacity(capacity int) error {
res := C.linenoiseHistorySetMaxLen(C.int(capacity))
if res != 1 {
return errors.New("Could not set history max len.")
}
return nil
}
// typedef struct linenoiseCompletions {
// size_t len;
// char **cvec;
// } linenoiseCompletions;
// typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
// void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
// void linenoiseAddCompletion(linenoiseCompletions *, char *);
//export linenoiseGoCompletionCallbackHook
func linenoiseGoCompletionCallbackHook(input *C.char, completions *C.linenoiseCompletions) {
completionsSlice := complHandler(C.GoString(input))
completionsLen := len(completionsSlice)
completions.len = C.size_t(completionsLen)
if completionsLen > 0 {
cvec := C.malloc(C.size_t(int(unsafe.Sizeof(*(**C.char)(nil))) * completionsLen))
cvecSlice := (*(*[999999]*C.char)(cvec))[:completionsLen]
for i, str := range completionsSlice {
cvecSlice[i] = C.CString(str)
}
completions.cvec = (**C.char)(cvec)
}
}