forked from govim/govim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
channel_cmds.go
133 lines (114 loc) · 3.42 KB
/
channel_cmds.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
126
127
128
129
130
131
132
133
package govim
import (
"encoding/json"
"fmt"
"io"
)
func (g *govimImpl) handleChannelError(ch unscheduledCallback, err error, format string, args ...interface{}) error {
_, err = g.handleChannelValueAndError(ch, err, format, args)
return err
}
func (g *govimImpl) handleChannelValueAndError(ch unscheduledCallback, err error, format string, args ...interface{}) (json.RawMessage, error) {
if err != nil {
return nil, err
}
args = append([]interface{}{}, args...)
select {
case <-g.tomb.Dying():
panic(ErrShuttingDown)
case resp := <-ch:
if resp.errString != "" {
args = append(args, resp.errString)
return nil, fmt.Errorf(format, args...)
}
return resp.val, nil
}
}
// ChannelRedraw implements Govim.ChannelRedraw
func (g *govimImpl) ChannelRedraw(force bool) error {
ch := make(unscheduledCallback)
err := g.channelRedrawImpl(ch, force)
return g.handleChannelError(ch, err, channelRedrawErrMsg, force)
}
const channelRedrawErrMsg = "failed to redraw (force = %v) in Vim: %v"
func (g *govimImpl) channelRedrawImpl(ch callback, force bool) error {
<-g.loaded
var sForce string
if force {
sForce = "force"
}
return g.DoProto(func() error {
return g.callVim(ch, "redraw", sForce)
})
}
// ChannelEx implements Govim.ChannelEx
func (g *govimImpl) ChannelEx(expr string) error {
ch := make(unscheduledCallback)
err := g.channelExImpl(ch, expr)
return g.handleChannelError(ch, err, channelExErrMsg, expr)
}
const channelExErrMsg = "failed to ex(%v) in Vim: %v"
func (g *govimImpl) channelExImpl(ch callback, expr string) error {
<-g.loaded
return g.DoProto(func() error {
return g.callVim(ch, "ex", expr)
})
}
// ChannelNormal implements Govim.ChannelNormal
func (g *govimImpl) ChannelNormal(expr string) error {
ch := make(unscheduledCallback)
err := g.channelNormalImpl(ch, expr)
return g.handleChannelError(ch, err, channelNormalErrMsg, expr)
}
const channelNormalErrMsg = "failed to normal(%v) in Vim: %v"
func (g *govimImpl) channelNormalImpl(ch callback, expr string) error {
<-g.loaded
return g.DoProto(func() error {
return g.callVim(ch, "normal", expr)
})
}
// ChannelExpr implements Govim.ChannelExpr
func (g *govimImpl) ChannelExpr(expr string) (json.RawMessage, error) {
ch := make(unscheduledCallback)
err := g.channelExprImpl(ch, expr)
return g.handleChannelValueAndError(ch, err, channelExprErrMsg, expr)
}
const channelExprErrMsg = "failed to expr(%v) in Vim: %v"
func (g *govimImpl) channelExprImpl(ch callback, expr string) error {
<-g.loaded
return g.DoProto(func() error {
return g.callVim(ch, "expr", expr)
})
}
// ChannelCall implements Govim.ChannelCall
func (g *govimImpl) ChannelCall(fn string, args ...interface{}) (json.RawMessage, error) {
ch := make(unscheduledCallback)
err := g.channelCallImpl(ch, fn, args...)
return g.handleChannelValueAndError(ch, err, channelCallErrMsg, fn, args)
}
const channelCallErrMsg = "failed to call %v(%v) in Vim: %v"
func (g *govimImpl) channelCallImpl(ch callback, fn string, args ...interface{}) error {
<-g.loaded
args = append([]interface{}{fn}, args...)
return g.DoProto(func() error {
return g.callVim(ch, "call", args...)
})
}
func (g *govimImpl) DoProto(f func() error) (err error) {
defer func() {
if r := recover(); r != nil {
switch r := r.(type) {
case errProto:
if r.underlying == io.EOF {
g.logVimEventf("closing connection\n")
return
}
err = r
default:
panic(r)
}
}
}()
err = f()
return
}