diff options
| author | Joel Martin <github@martintribe.org> | 2014-10-09 18:27:47 -0500 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2014-10-09 18:27:47 -0500 |
| commit | ad7e866ea1d4d035d876e58bca681a72099449af (patch) | |
| tree | cbd73a7cda5adc4aba7293231ab0efa3f107edb0 /go/src/readline | |
| parent | d667a1bb2e7294f8722bb31f1e6e8207b971c913 (diff) | |
| download | mal-ad7e866ea1d4d035d876e58bca681a72099449af.tar.gz mal-ad7e866ea1d4d035d876e58bca681a72099449af.zip | |
go: add readline.go that wraps libreadline/libedit
Diffstat (limited to 'go/src/readline')
| -rw-r--r-- | go/src/readline/readline.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/go/src/readline/readline.go b/go/src/readline/readline.go new file mode 100644 index 0000000..2777cb4 --- /dev/null +++ b/go/src/readline/readline.go @@ -0,0 +1,70 @@ +package readline + +/* +// IMPORTANT: choose one +#cgo LDFLAGS: -ledit +//#cgo LDFLAGS: -lreadline // NOTE: libreadline is GPL + +// free() +#include <stdlib.h> +// readline() +#include <readline/readline.h> +// add_history() +#include <readline/history.h> +*/ +import "C" + +import ( + "errors" + "unsafe" + "strings" + "io/ioutil" + "os" + "path/filepath" + "fmt" +) + +var HISTORY_FILE = ".mal-history" + +var rl_history_loaded = false + +func Readline(prompt string) (string, error) { + history_path := filepath.Join(os.Getenv("HOME"), "/", HISTORY_FILE) + + if !rl_history_loaded { + rl_history_loaded = true + content, e := ioutil.ReadFile(history_path) + if e != nil { return "", e } + + for _, add_line := range strings.Split(string(content), "\n") { + if add_line == "" { continue } + c_add_line := C.CString(add_line) + C.add_history(c_add_line) + C.free(unsafe.Pointer(c_add_line)) + } + } + + + c_prompt := C.CString(prompt) + defer C.free(unsafe.Pointer(c_prompt)) + + c_line := C.readline(c_prompt) + defer C.free(unsafe.Pointer(c_line)) + line := C.GoString(c_line) + + if c_line == nil { + return "", errors.New("C.readline call failed") + } + C.add_history(c_line) + + // append to file + f, e := os.OpenFile(history_path, os.O_APPEND|os.O_WRONLY, 0600) + if e == nil { + defer f.Close() + + _, e = f.WriteString(line+"\n") + if e != nil { fmt.Printf("error writing to history") } + } + + return line, nil +} |
