forked from mirror/ledisdb
use liner instead of linenoise
This commit is contained in:
parent
fdcaa0c4cc
commit
29df518dfd
4
Makefile
4
Makefile
|
@ -14,10 +14,10 @@ export GO_BUILD_TAGS
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
$(GO) install -tags 'linenoise $(GO_BUILD_TAGS)' ./...
|
$(GO) install -tags '$(GO_BUILD_TAGS)' ./...
|
||||||
|
|
||||||
build_lmdb:
|
build_lmdb:
|
||||||
$(GO) install -tags 'linenoise $(GO_BUILD_TAGS) lmdb' ./...
|
$(GO) install -tags '$(GO_BUILD_TAGS) lmdb' ./...
|
||||||
|
|
||||||
test:
|
test:
|
||||||
$(GO) test --race -tags '$(GO_BUILD_TAGS)' ./...
|
$(GO) test --race -tags '$(GO_BUILD_TAGS)' ./...
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
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.
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,76 +0,0 @@
|
||||||
// +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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
// +build linenoise
|
|
||||||
|
|
||||||
/* linenoise.h -- guerrilla line editing library against the idea that a
|
|
||||||
* line editing lib needs to be 20,000 lines of C code.
|
|
||||||
*
|
|
||||||
* See linenoise.c for more information.
|
|
||||||
*
|
|
||||||
* ------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
|
||||||
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
|
||||||
*
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* * 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
|
|
||||||
* HOLDER 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LINENOISE_H
|
|
||||||
#define __LINENOISE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct linenoiseCompletions {
|
|
||||||
size_t len;
|
|
||||||
char **cvec;
|
|
||||||
} linenoiseCompletions;
|
|
||||||
|
|
||||||
typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
|
|
||||||
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
|
|
||||||
void linenoiseAddCompletion(linenoiseCompletions *, const char *);
|
|
||||||
|
|
||||||
char *linenoise(const char *prompt);
|
|
||||||
int linenoiseHistoryAdd(const char *line);
|
|
||||||
int linenoiseHistorySetMaxLen(int len);
|
|
||||||
int linenoiseHistorySave(const char *filename);
|
|
||||||
int linenoiseHistoryLoad(const char *filename);
|
|
||||||
void linenoiseClearScreen(void);
|
|
||||||
void linenoiseSetMultiLine(int ml);
|
|
||||||
void linenoisePrintKeyCodes(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __LINENOISE_H */
|
|
|
@ -1,9 +0,0 @@
|
||||||
// +build linenoise
|
|
||||||
|
|
||||||
#include "linenoiseCompletionCallbackHook.h"
|
|
||||||
|
|
||||||
extern void linenoiseGoCompletionCallbackHook(const char *, linenoiseCompletions *);
|
|
||||||
|
|
||||||
void linenoiseSetupCompletionCallbackHook() {
|
|
||||||
linenoiseSetCompletionCallback(linenoiseGoCompletionCallbackHook);
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
// +build linenoise
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "linenoise.h"
|
|
||||||
|
|
||||||
void linenoiseSetupCompletionCallbackHook();
|
|
|
@ -1,14 +1,14 @@
|
||||||
// +build linenoise
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/peterh/liner"
|
||||||
"github.com/siddontang/goredis"
|
"github.com/siddontang/goredis"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,9 +17,24 @@ var port = flag.Int("p", 6380, "ledisdb server port (default 6380)")
|
||||||
var socket = flag.String("s", "", "ledisdb server socket, overwrite ip and port")
|
var socket = flag.String("s", "", "ledisdb server socket, overwrite ip and port")
|
||||||
var dbn = flag.Int("n", 0, "ledisdb database number(default 0)")
|
var dbn = flag.Int("n", 0, "ledisdb database number(default 0)")
|
||||||
|
|
||||||
|
var (
|
||||||
|
line *liner.State
|
||||||
|
historyPath = "/tmp/ledis-cli"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
line = liner.NewLiner()
|
||||||
|
defer line.Close()
|
||||||
|
|
||||||
|
line.SetCtrlCAborts(true)
|
||||||
|
|
||||||
|
setCompletionHandler()
|
||||||
|
loadHisotry()
|
||||||
|
|
||||||
|
defer saveHisotry()
|
||||||
|
|
||||||
var addr string
|
var addr string
|
||||||
if len(*socket) > 0 {
|
if len(*socket) > 0 {
|
||||||
addr = *socket
|
addr = *socket
|
||||||
|
@ -31,21 +46,18 @@ func main() {
|
||||||
c.SetMaxIdleConns(1)
|
c.SetMaxIdleConns(1)
|
||||||
sendSelect(c, *dbn)
|
sendSelect(c, *dbn)
|
||||||
|
|
||||||
SetCompletionHandler(completionHandler)
|
|
||||||
setHistoryCapacity(100)
|
|
||||||
|
|
||||||
reg, _ := regexp.Compile(`'.*?'|".*?"|\S+`)
|
reg, _ := regexp.Compile(`'.*?'|".*?"|\S+`)
|
||||||
|
|
||||||
prompt := ""
|
prompt := ""
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if *dbn > 0 && *dbn < 16 {
|
if *dbn > 0 && *dbn < 16 {
|
||||||
prompt = fmt.Sprintf("%s[%d]>", addr, *dbn)
|
prompt = fmt.Sprintf("%s[%d]> ", addr, *dbn)
|
||||||
} else {
|
} else {
|
||||||
prompt = fmt.Sprintf("%s>", addr)
|
prompt = fmt.Sprintf("%s> ", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd, err := line(prompt)
|
cmd, err := line.Prompt(prompt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%s\n", err.Error())
|
fmt.Printf("%s\n", err.Error())
|
||||||
return
|
return
|
||||||
|
@ -55,7 +67,7 @@ func main() {
|
||||||
if len(cmds) == 0 {
|
if len(cmds) == 0 {
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
addHistory(cmd)
|
line.AppendHistory(cmd)
|
||||||
|
|
||||||
args := make([]interface{}, len(cmds[1:]))
|
args := make([]interface{}, len(cmds[1:]))
|
||||||
|
|
||||||
|
@ -167,12 +179,29 @@ func sendSelect(client *goredis.Client, index int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func completionHandler(in string) []string {
|
func setCompletionHandler() {
|
||||||
var keyWords []string
|
line.SetCompleter(func(line string) (c []string) {
|
||||||
for _, i := range helpCommands {
|
for _, i := range helpCommands {
|
||||||
if strings.HasPrefix(i[0], strings.ToUpper(in)) {
|
if strings.HasPrefix(i[0], strings.ToLower(line)) {
|
||||||
keyWords = append(keyWords, i[0])
|
c = append(c, i[0])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return
|
||||||
return keyWords
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadHisotry() {
|
||||||
|
if f, err := os.Open(historyPath); err == nil {
|
||||||
|
line.ReadHistory(f)
|
||||||
|
f.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveHisotry() {
|
||||||
|
if f, err := os.Create(historyPath); err != nil {
|
||||||
|
fmt.Printf("Error writing history file: ", err)
|
||||||
|
} else {
|
||||||
|
line.WriteHistory(f)
|
||||||
|
f.Close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
// +build !linenoise
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
println("Please use linenoise to build again, or use redis-cli instead")
|
|
||||||
}
|
|
Loading…
Reference in New Issue