git-subtree-dir: third_party/src/github.com/GeertJohan/go.linenoise git-subtree-split: 5d5d5277d975f40b12167b478c0d79df00bda5a8master
commit
0a65e23e3a
@ -0,0 +1,2 @@ |
||||
*sublime* |
||||
/examplenoise/examplenoise |
@ -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. |
@ -0,0 +1,14 @@ |
||||
## go.linenoise |
||||
|
||||
go.linenoise is a [go](http://golang.org) package wrapping the [linenoise](https://github.com/antirez/linenoise) C library. |
||||
|
||||
This package does not compile on windows. |
||||
|
||||
### Documentation |
||||
Documentation can be found at [godoc.org/github.com/GeertJohan/go.linenoise](http://godoc.org/github.com/GeertJohan/go.linenoise). |
||||
An example is located in the folder [examplenoise](examplenoise). |
||||
|
||||
### License |
||||
All code in this repository is licensed under a BSD license. |
||||
This project wraps [linenoise](https://github.com/antirez/linenoise) which is written by Salvatore Sanfilippo and Pieter Noordhuis. The license for linenoise is included in the files `linenoise.c` and `linenoise.h`. |
||||
For all other files please read the [LICENSE](LICENSE) file. |
@ -0,0 +1,11 @@ |
||||
// Package linenoise wraps the linenoise library (https://github.com/antirez/linenoise).
|
||||
//
|
||||
// The package is imported with "go." prefix
|
||||
// import "github.com/GeertJohan/go.linenoise"
|
||||
//
|
||||
// Simple readline usage:
|
||||
// linenoise.Line("prompt> ")
|
||||
//
|
||||
// Adding lines to history, you could simply do this for every line you read.
|
||||
// linenoise.AddHistory("This will be displayed in prompt when arrow-up is pressed")
|
||||
package linenoise |
@ -0,0 +1,112 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"github.com/GeertJohan/go.linenoise" |
||||
"os" |
||||
"strings" |
||||
) |
||||
|
||||
func main() { |
||||
fmt.Println("Welcome to go.linenoise example.") |
||||
writeHelp() |
||||
for { |
||||
str, err := linenoise.Line("prompt> ") |
||||
if err != nil { |
||||
if err == linenoise.KillSignalError { |
||||
quit() |
||||
} |
||||
fmt.Println("Unexpected error: %s", err) |
||||
quit() |
||||
} |
||||
fields := strings.Fields(str) |
||||
|
||||
// check if there is any valid input at all
|
||||
if len(fields) == 0 { |
||||
writeUnrecognized() |
||||
continue |
||||
} |
||||
|
||||
// switch on the command
|
||||
switch fields[0] { |
||||
case "help": |
||||
writeHelp() |
||||
case "echo": |
||||
fmt.Printf("echo: %s\n\n", str[5:]) |
||||
case "clear": |
||||
linenoise.Clear() |
||||
case "multiline": |
||||
fmt.Println("Setting linenoise to multiline") |
||||
linenoise.SetMultiline(true) |
||||
case "singleline": |
||||
fmt.Println("Setting linenoise to singleline") |
||||
linenoise.SetMultiline(false) |
||||
case "complete": |
||||
fmt.Println("Setting arguments as completion values for linenoise.") |
||||
fmt.Printf("%d arguments: %s\n", len(fields)-1, fields[1:]) |
||||
completionHandler := func(in string) []string { |
||||
return fields[1:] |
||||
} |
||||
linenoise.SetCompletionHandler(completionHandler) |
||||
case "printKeyCodes": |
||||
linenoise.PrintKeyCodes() |
||||
case "addHistory": |
||||
if len(str) < 12 { |
||||
fmt.Println("No argument given.") |
||||
} |
||||
err := linenoise.AddHistory(str[11:]) |
||||
if err != nil { |
||||
fmt.Printf("Error: %s\n", err) |
||||
} |
||||
case "save": |
||||
if len(fields) != 2 { |
||||
fmt.Println("Error. Expecting 'save <filename>'.") |
||||
continue |
||||
} |
||||
err := linenoise.SaveHistory(fields[1]) |
||||
if err != nil { |
||||
fmt.Printf("Error on save: %s\n", err) |
||||
} |
||||
case "load": |
||||
if len(fields) != 2 { |
||||
fmt.Println("Error. Expecting 'load <filename>'.") |
||||
continue |
||||
} |
||||
err := linenoise.LoadHistory(fields[1]) |
||||
if err != nil { |
||||
fmt.Printf("Error on load: %s\n", err) |
||||
} |
||||
case "quit": |
||||
quit() |
||||
default: |
||||
writeUnrecognized() |
||||
} |
||||
} |
||||
} |
||||
|
||||
func quit() { |
||||
fmt.Println("Thanks for running the go.linenoise example.") |
||||
fmt.Println("") |
||||
os.Exit(0) |
||||
} |
||||
|
||||
func writeHelp() { |
||||
fmt.Println("help write this message") |
||||
fmt.Println("echo ... echo the arguments") |
||||
fmt.Println("clear clear the screen") |
||||
fmt.Println("multiline set linenoise to multiline") |
||||
fmt.Println("singleline set linenoise to singleline") |
||||
fmt.Println("complete ... set arguments as completion values") |
||||
fmt.Println("addHistory ... add arguments to linenoise history") |
||||
fmt.Println("save <filename> save the history to file") |
||||
fmt.Println("load <filename> load the history from file") |
||||
fmt.Println("quit stop the program") |
||||
fmt.Println("") |
||||
fmt.Println("Use the arrow up and down keys to walk through history.") |
||||
fmt.Println("Note that you have to use addHistory to create history entries. Commands are not added to history in this example.") |
||||
fmt.Println("") |
||||
} |
||||
|
||||
func writeUnrecognized() { |
||||
fmt.Println("Unrecognized command. Use 'help'.") |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,142 @@ |
||||
package linenoise |
||||
|
||||
// -windows
|
||||
|
||||
// #include <stdlib.h>
|
||||
// #include "linenoise.h"
|
||||
// #include "linenoiseCompletionCallbackHook.h"
|
||||
import "C" |
||||
|
||||
import ( |
||||
"errors" |
||||
"unsafe" |
||||
) |
||||
|
||||
// KillSignalError is returned returned by Line() when a user quits from prompt.
|
||||
// This occurs when the user enters ctrl+C or ctrl+D.
|
||||
var KillSignalError = errors.New("prompt was quited with a killsignal") |
||||
|
||||
func init() { |
||||
C.linenoiseSetupCompletionCallbackHook() |
||||
} |
||||
|
||||
// Line displays given string and returns line from user input.
|
||||
func Line(prompt string) (string, error) { // char *linenoise(const char *prompt);
|
||||
promptCString := C.CString(prompt) |
||||
resultCString := C.linenoise(promptCString) |
||||
C.free(unsafe.Pointer(promptCString)) |
||||
defer C.free(unsafe.Pointer(resultCString)) |
||||
|
||||
if resultCString == nil { |
||||
return "", KillSignalError |
||||
} |
||||
|
||||
result := C.GoString(resultCString) |
||||
|
||||
return result, nil |
||||
} |
||||
|
||||
// AddHistory adds a line to history. Returns non-nil error on fail.
|
||||
func AddHistory(line string) error { // int linenoiseHistoryAdd(const char *line);
|
||||
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 |
||||
} |
||||
|
||||
// SetHistoryCapacity changes the maximum length of history. Returns non-nil error on fail.
|
||||
func SetHistoryCapacity(capacity int) error { // int linenoiseHistorySetMaxLen(int len);
|
||||
res := C.linenoiseHistorySetMaxLen(C.int(capacity)) |
||||
if res != 1 { |
||||
return errors.New("Could not set history max len.") |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// SaveHistory saves from file with given filename. Returns non-nil error on fail.
|
||||
func SaveHistory(filename string) error { // int linenoiseHistorySave(char *filename);
|
||||
filenameCString := C.CString(filename) |
||||
res := C.linenoiseHistorySave(filenameCString) |
||||
C.free(unsafe.Pointer(filenameCString)) |
||||
if res != 0 { |
||||
return errors.New("Could not save history to file.") |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// LoadHistory loads from file with given filename. Returns non-nil error on fail.
|
||||
func LoadHistory(filename string) error { // int linenoiseHistoryLoad(char *filename);
|
||||
filenameCString := C.CString(filename) |
||||
res := C.linenoiseHistoryLoad(filenameCString) |
||||
C.free(unsafe.Pointer(filenameCString)) |
||||
if res != 0 { |
||||
return errors.New("Could not load history from file.") |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// Clear clears the screen.
|
||||
func Clear() { // void linenoiseClearScreen(void);
|
||||
C.linenoiseClearScreen() |
||||
} |
||||
|
||||
// SetMultiline sets linenoise to multiline or single line.
|
||||
// In multiline mode the user input will be wrapped to a new line when the length exceeds the amount of available rows in the terminal.
|
||||
func SetMultiline(ml bool) { // void linenoiseSetMultiLine(int ml);
|
||||
if ml { |
||||
C.linenoiseSetMultiLine(1) |
||||
} else { |
||||
C.linenoiseSetMultiLine(0) |
||||
} |
||||
} |
||||
|
||||
// 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) |
||||
} |
||||
} |
||||
|
||||
// PrintKeyCodes puts linenoise in key codes debugging mode.
|
||||
// Press keys and key combinations to see key codes. Type 'quit' at any time to exit.
|
||||
// PrintKeyCodes blocks until user enters 'quit'.
|
||||
func PrintKeyCodes() { // void linenoisePrintKeyCodes(void);
|
||||
C.linenoisePrintKeyCodes() |
||||
} |
@ -0,0 +1,66 @@ |
||||
/* 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-2014, Salvatore Sanfilippo <antirez at gmail dot com> |
||||
* Copyright (c) 2010-2013, 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 */ |
@ -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(); |
@ -0,0 +1,8 @@ |
||||
package linenoise |
||||
|
||||
// #include <stdlib.h>
|
||||
// #include "linenoise.h"
|
||||
import "C" |
||||
|
||||
// this will break a go build on windows and display the string on console
|
||||
"go.linenoise does not support windows." |
Loading…
Reference in new issue