aboutsummaryrefslogtreecommitdiff
path: root/go/src/readline
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-10-09 18:27:47 -0500
committerJoel Martin <github@martintribe.org>2014-10-09 18:27:47 -0500
commitad7e866ea1d4d035d876e58bca681a72099449af (patch)
treecbd73a7cda5adc4aba7293231ab0efa3f107edb0 /go/src/readline
parentd667a1bb2e7294f8722bb31f1e6e8207b971c913 (diff)
downloadmal-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.go70
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
+}