forked from elves/elvish
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
125 lines (106 loc) · 2.18 KB
/
main.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// elvish is an experimental Unix shell. It tries to incorporate a powerful
// programming language with an extensible, friendly user interface.
package main
import (
"fmt"
"io/ioutil"
"os"
"os/signal"
"os/user"
"unicode/utf8"
"github.com/xiaq/elvish/edit"
"github.com/xiaq/elvish/eval"
"github.com/xiaq/elvish/parse"
"github.com/xiaq/elvish/util"
)
const (
sigchSize = 32
)
// TODO(xiaq): Currently only the editor deals with signals.
func interact() {
ev := eval.NewEvaluator()
cmdNum := 0
username := "???"
user, err := user.Current()
if err == nil {
username = user.Username
}
hostname, err := os.Hostname()
if err != nil {
hostname = "???"
}
rpromptStr := username + "@" + hostname
sigch := make(chan os.Signal, sigchSize)
signal.Notify(sigch)
ed := edit.NewEditor(os.Stdin, ev, sigch)
for {
cmdNum++
name := fmt.Sprintf("<tty %d>", cmdNum)
prompt := func() string {
return util.Getwd() + "> "
}
rprompt := func() string {
return rpromptStr
}
lr := ed.ReadLine(prompt, rprompt)
if lr.EOF {
break
} else if lr.Err != nil {
fmt.Println("Editor error:", lr.Err)
fmt.Println("My pid is", os.Getpid())
}
n, pe := parse.Parse(name, lr.Line)
if pe != nil {
fmt.Print(pe.(*util.ContextualError).Pprint())
continue
}
ee := ev.Eval(name, lr.Line, n)
if ee != nil {
fmt.Print(ee.(*util.ContextualError).Pprint())
continue
}
}
}
func script(name string) {
file, err := os.Open(name)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
bytes, err := ioutil.ReadAll(file)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if !utf8.Valid(bytes) {
fmt.Fprintf(os.Stderr, "source %v is not valid UTF-8\n", name)
os.Exit(1)
}
src := string(bytes)
ev := eval.NewEvaluator()
n, pe := parse.Parse(name, src)
if pe != nil {
fmt.Print(pe.(*util.ContextualError).Pprint())
os.Exit(1)
}
ee := ev.Eval(name, src, n)
if ee != nil {
fmt.Print(ee.(*util.ContextualError).Pprint())
os.Exit(1)
}
}
var usage = `Usage:
elvish
elvish <script>
`
func main() {
switch len(os.Args) {
case 1:
interact()
case 2:
script(os.Args[1])
default:
fmt.Fprintf(os.Stderr, usage)
os.Exit(1)
}
}