Squashed 'contrib/linenoise/' content from commit 5d5d527

git-subtree-dir: contrib/linenoise
git-subtree-split: 5d5d5277d975f40b12167b478c0d79df00bda5a8
This commit is contained in:
Harshavardhana 2014-10-30 22:22:47 -07:00
commit 13412ca164
11 changed files with 1495 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*sublime*
/examplenoise/examplenoise

22
LICENSE Normal file
View File

@ -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.

14
README.md Normal file
View File

@ -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.

11
doc.go Normal file
View 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

View File

@ -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'.")
}

1105
linenoise.c Normal file

File diff suppressed because it is too large Load Diff

142
linenoise.go Normal file
View File

@ -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()
}

66
linenoise.h Normal file
View File

@ -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 */

View File

@ -0,0 +1,8 @@
#include "linenoiseCompletionCallbackHook.h"
extern void linenoiseGoCompletionCallbackHook(const char *, linenoiseCompletions *);
void linenoiseSetupCompletionCallbackHook() {
linenoiseSetCompletionCallback(linenoiseGoCompletionCallbackHook);
}

View File

@ -0,0 +1,5 @@
#include <stdlib.h>
#include "linenoise.h"
void linenoiseSetupCompletionCallbackHook();

8
windows.go Normal file
View File

@ -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."