forked from mirror/ledisdb
add completion hook
This commit is contained in:
parent
31a069653f
commit
41d7db664b
|
@ -0,0 +1,22 @@
|
||||||
|
Copyright (c) 2013, Geert-Johan Riemer
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
//#include <stdlib.h>
|
//#include <stdlib.h>
|
||||||
//#include "linenoise.h"
|
//#include "linenoise.h"
|
||||||
|
//#include "linenoiseCompletionCallbackHook.h"
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -9,6 +10,10 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
C.linenoiseSetupCompletionCallbackHook()
|
||||||
|
}
|
||||||
|
|
||||||
func line(prompt string) (string, error) {
|
func line(prompt string) (string, error) {
|
||||||
promptCString := C.CString(prompt)
|
promptCString := C.CString(prompt)
|
||||||
resultCString := C.linenoise(promptCString)
|
resultCString := C.linenoise(promptCString)
|
||||||
|
@ -41,3 +46,44 @@ func setHistoryCapacity(capacity int) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompletionHandler provides possible completions for given input
|
||||||
|
type CompletionHandler func(input string) []string
|
||||||
|
|
||||||
|
// DefaultCompletionHandler simply returns an empty slice.
|
||||||
|
var DefaultCompletionHandler = func(input string) []string {
|
||||||
|
return make([]string, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
var complHandler = DefaultCompletionHandler
|
||||||
|
|
||||||
|
// SetCompletionHandler sets the CompletionHandler to be used for completion
|
||||||
|
func SetCompletionHandler(c CompletionHandler) {
|
||||||
|
complHandler = c
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
#include "linenoiseCompletionCallbackHook.h"
|
||||||
|
|
||||||
|
extern void linenoiseGoCompletionCallbackHook(const char *, linenoiseCompletions *);
|
||||||
|
|
||||||
|
void linenoiseSetupCompletionCallbackHook() {
|
||||||
|
linenoiseSetCompletionCallback(linenoiseGoCompletionCallbackHook);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "linenoise.h"
|
||||||
|
|
||||||
|
void linenoiseSetupCompletionCallbackHook();
|
|
@ -30,6 +30,7 @@ func main() {
|
||||||
|
|
||||||
sendSelect(c, *dbn)
|
sendSelect(c, *dbn)
|
||||||
|
|
||||||
|
SetCompletionHandler(completionHandler)
|
||||||
setHistoryCapacity(100)
|
setHistoryCapacity(100)
|
||||||
|
|
||||||
reg, _ := regexp.Compile(`'.*?'|".*?"|\S+`)
|
reg, _ := regexp.Compile(`'.*?'|".*?"|\S+`)
|
||||||
|
@ -157,3 +158,13 @@ func sendSelect(client *ledis.Client, index int) {
|
||||||
fmt.Println("index out of range, should less than 16")
|
fmt.Println("index out of range, should less than 16")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func completionHandler(in string) []string {
|
||||||
|
var keyWords []string
|
||||||
|
for _, i := range helpCommands {
|
||||||
|
if strings.HasPrefix(i[0], strings.ToUpper(in)) {
|
||||||
|
keyWords = append(keyWords, i[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keyWords
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue