This repository was archived by the owner on Apr 2, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtecla.go
102 lines (74 loc) · 2.11 KB
/
tecla.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
This package is a wrapper for Martin Shepherd's, libtecla, command-line
editing library (www.astro.caltech.edu/~mcs/tecla/).
The latest version of libtecla may be obtained from:
www.astro.caltech.edu/~mcs/tecla/libtecla.tar.gz
This package is released under an MIT-style license. See LICENSE for details.
*/
package tecla
/*
#include <ctype.h>
#include <stdlib.h>
#include <libtecla.h>
static CPL_MATCH_FN(complete) {
const char* start = line;
int size = word_end;
while(*start && size--) {
if (isspace(*start++))
continue;
if (line[word_end] && !isspace(line[word_end]))
return 0;
return cpl_file_completions(cpl, NULL, line, word_end);
}
cpl_add_completion(cpl, line, word_end, word_end, " ", NULL, NULL);
return 0;
}
static GetLine* init(void) {
GetLine* reader = new_GetLine(1024, 16384);
gl_ignore_signal(reader, SIGINT);
gl_ignore_signal(reader, SIGTSTP);
gl_customize_completion(reader, NULL, complete);
return reader;
}
#cgo LDFLAGS:-ltecla
#cgo darwin LDFLAGS:-lncurses
#cgo freebsd LDFLAGS:-lcurses
#cgo linux LDFLAGS:-lncurses
*/
import "C"
import "errors"
import "unsafe"
type Tecla struct {
creader *C.GetLine
cprompt *C.char
prompts map[string]*C.char
}
func New(prompt string) *Tecla {
prompts := make(map[string]*C.char)
return &Tecla{C.init(), intern(prompts, prompt), prompts}
}
func (self *Tecla) ChangePrompt(prompt string) {
self.cprompt = intern(self.prompts, prompt)
}
func (self *Tecla) ReadString(delim byte) (line string, err error) {
var null *C.char
cline := C.gl_get_line(self.creader, self.cprompt, null, 0)
if cline == nil && C.gl_return_status(self.creader) == C.GLR_EOF {
for k, v := range self.prompts {
C.free(unsafe.Pointer(v))
self.prompts[k] = null
}
self.cprompt = null
self.creader = C.del_GetLine(self.creader)
return "", errors.New("EOF")
}
return C.GoString(cline), nil
}
func intern(prompts map[string]*C.char, prompt string) *C.char {
cprompt, ok := prompts[prompt]
if !ok {
cprompt = C.CString(prompt)
prompts[prompt] = cprompt
}
return cprompt
}