Skip to content

Commit

Permalink
cmd/govim: move batch logic to separate file (#855)
Browse files Browse the repository at this point in the history
Keeps vimstate.go a bit smaller and tidier
  • Loading branch information
myitcv committed Apr 13, 2020
1 parent 9c78a05 commit 1689c93
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 178 deletions.
184 changes: 184 additions & 0 deletions cmd/govim/batch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package main

import (
"encoding/json"
"fmt"
)

type batch struct {
calls []interface{}
results []json.RawMessage
}

func (b *batch) result() batchResult {
i := len(b.calls) - 1
return func() json.RawMessage {
if b.results == nil {
panic(fmt.Errorf("tried to get result from incomplete Batch"))
}
return b.results[i]
}
}

func (v *vimstate) BatchStart() {
if v.currBatch != nil {
panic(fmt.Errorf("called BatchStart whilst in a batch"))
}
v.currBatch = &batch{}
}

func (v *vimstate) BatchStartIfNeeded() bool {
if v.currBatch != nil {
return false
}
v.currBatch = &batch{}
return true
}

type batchResult func() json.RawMessage

type AssertExpr struct {
Fn string
Args []interface{}
}

func AssertNoError() AssertExpr {
return AssertExpr{
Fn: "s:mustNoError",
}
}

func AssertIsZero() AssertExpr {
return AssertExpr{
Fn: "s:mustBeZero",
}
}

func AssertIsErrorOrNil(patterns ...string) AssertExpr {
args := make([]interface{}, 0, len(patterns))
for _, v := range patterns {
args = append(args, v)
}
return AssertExpr{
Fn: "s:mustBeErrorOrNil",
Args: args,
}
}

func (v *vimstate) BatchChannelExprf(format string, args ...interface{}) batchResult {
return v.BatchAssertChannelExprf(AssertNoError(), format, args...)
}

func (v *vimstate) BatchAssertChannelExprf(a AssertExpr, format string, args ...interface{}) batchResult {
if v.currBatch == nil {
panic(fmt.Errorf("cannot call BatchChannelExprf: not in batch"))
}
v.currBatch.calls = append(v.currBatch.calls, []interface{}{
"expr",
[2]interface{}{a.Fn, a.Args},
fmt.Sprintf(format, args...),
})
return v.currBatch.result()
}
func (v *vimstate) BatchChannelCall(name string, args ...interface{}) batchResult {
return v.BatchAssertChannelCall(AssertNoError(), name, args...)
}

func (v *vimstate) BatchAssertChannelCall(a AssertExpr, name string, args ...interface{}) batchResult {
if v.currBatch == nil {
panic(fmt.Errorf("cannot call BatchChannelCall: not in batch"))
}
callargs := []interface{}{
"call",
[2]interface{}{a.Fn, a.Args},
name,
}
callargs = append(callargs, args...)
v.currBatch.calls = append(v.currBatch.calls, callargs)
return v.currBatch.result()
}

func (v *vimstate) BatchCancelIfNotEnded() {
v.currBatch = nil
}

func (v *vimstate) BatchEnd() ([]json.RawMessage, error) {
return v.batchEndImpl(false)
}

func (v *vimstate) MustBatchEnd() (res []json.RawMessage) {
res, _ = v.batchEndImpl(true)
return
}

func (v *vimstate) batchEndImpl(must bool) (res []json.RawMessage, err error) {
if v.currBatch == nil {
panic(fmt.Errorf("called BatchEnd but not in a batch"))
}
b := v.currBatch
v.currBatch = nil
if len(b.calls) == 0 {
return
}
var vs json.RawMessage
if must {
vs = v.ChannelCall("s:batchCall", b.calls)
} else {
vs, err = v.Driver.Govim.ChannelCall("s:batchCall", b.calls)
if err != nil {
return
}
}
v.Parse(vs, &res)
b.results = res
return
}

func (v *vimstate) ChannelCall(name string, args ...interface{}) json.RawMessage {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelCall when in batch"))
}
return v.Driver.ChannelCall(name, args...)
}

func (v *vimstate) ChannelEx(expr string) {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelEx when in batch"))
}
v.Driver.ChannelEx(expr)
}

func (v *vimstate) ChannelExf(format string, args ...interface{}) {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelExf when in batch"))
}
v.Driver.ChannelExf(format, args...)
}

func (v *vimstate) ChannelExpr(expr string) json.RawMessage {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelExpr when in batch"))
}
return v.Driver.ChannelExpr(expr)
}

func (v *vimstate) ChannelExprf(format string, args ...interface{}) json.RawMessage {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelExprf when in batch"))
}
return v.Driver.ChannelExprf(format, args...)
}

func (v *vimstate) ChannelNormal(expr string) {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelNormal when in batch"))
}
v.Driver.ChannelNormal(expr)
}

func (v *vimstate) ChannelRedraw(force bool) {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelRedraw when in batch"))
}
v.Driver.ChannelRedraw(force)
}
178 changes: 0 additions & 178 deletions cmd/govim/vimstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,181 +194,3 @@ func (v *vimstate) setUserBusy(args ...json.RawMessage) (interface{}, error) {

return nil, v.handleDiagnosticsChanged()
}

type batch struct {
calls []interface{}
results []json.RawMessage
}

func (b *batch) result() batchResult {
i := len(b.calls) - 1
return func() json.RawMessage {
if b.results == nil {
panic(fmt.Errorf("tried to get result from incomplete Batch"))
}
return b.results[i]
}
}

func (v *vimstate) BatchStart() {
if v.currBatch != nil {
panic(fmt.Errorf("called BatchStart whilst in a batch"))
}
v.currBatch = &batch{}
}

func (v *vimstate) BatchStartIfNeeded() bool {
if v.currBatch != nil {
return false
}
v.currBatch = &batch{}
return true
}

type batchResult func() json.RawMessage

type AssertExpr struct {
Fn string
Args []interface{}
}

func AssertNoError() AssertExpr {
return AssertExpr{
Fn: "s:mustNoError",
}
}

func AssertIsZero() AssertExpr {
return AssertExpr{
Fn: "s:mustBeZero",
}
}

func AssertIsErrorOrNil(patterns ...string) AssertExpr {
args := make([]interface{}, 0, len(patterns))
for _, v := range patterns {
args = append(args, v)
}
return AssertExpr{
Fn: "s:mustBeErrorOrNil",
Args: args,
}
}

func (v *vimstate) BatchChannelExprf(format string, args ...interface{}) batchResult {
return v.BatchAssertChannelExprf(AssertNoError(), format, args...)
}

func (v *vimstate) BatchAssertChannelExprf(a AssertExpr, format string, args ...interface{}) batchResult {
if v.currBatch == nil {
panic(fmt.Errorf("cannot call BatchChannelExprf: not in batch"))
}
v.currBatch.calls = append(v.currBatch.calls, []interface{}{
"expr",
[2]interface{}{a.Fn, a.Args},
fmt.Sprintf(format, args...),
})
return v.currBatch.result()
}
func (v *vimstate) BatchChannelCall(name string, args ...interface{}) batchResult {
return v.BatchAssertChannelCall(AssertNoError(), name, args...)
}

func (v *vimstate) BatchAssertChannelCall(a AssertExpr, name string, args ...interface{}) batchResult {
if v.currBatch == nil {
panic(fmt.Errorf("cannot call BatchChannelCall: not in batch"))
}
callargs := []interface{}{
"call",
[2]interface{}{a.Fn, a.Args},
name,
}
callargs = append(callargs, args...)
v.currBatch.calls = append(v.currBatch.calls, callargs)
return v.currBatch.result()
}

func (v *vimstate) BatchCancelIfNotEnded() {
v.currBatch = nil
}

func (v *vimstate) BatchEnd() ([]json.RawMessage, error) {
return v.batchEndImpl(false)
}

func (v *vimstate) MustBatchEnd() (res []json.RawMessage) {
res, _ = v.batchEndImpl(true)
return
}

func (v *vimstate) batchEndImpl(must bool) (res []json.RawMessage, err error) {
if v.currBatch == nil {
panic(fmt.Errorf("called BatchEnd but not in a batch"))
}
b := v.currBatch
v.currBatch = nil
if len(b.calls) == 0 {
return
}
var vs json.RawMessage
if must {
vs = v.ChannelCall("s:batchCall", b.calls)
} else {
vs, err = v.Driver.Govim.ChannelCall("s:batchCall", b.calls)
if err != nil {
return
}
}
v.Parse(vs, &res)
b.results = res
return
}

func (v *vimstate) ChannelCall(name string, args ...interface{}) json.RawMessage {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelCall when in batch"))
}
return v.Driver.ChannelCall(name, args...)
}

func (v *vimstate) ChannelEx(expr string) {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelEx when in batch"))
}
v.Driver.ChannelEx(expr)
}

func (v *vimstate) ChannelExf(format string, args ...interface{}) {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelExf when in batch"))
}
v.Driver.ChannelExf(format, args...)
}

func (v *vimstate) ChannelExpr(expr string) json.RawMessage {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelExpr when in batch"))
}
return v.Driver.ChannelExpr(expr)
}

func (v *vimstate) ChannelExprf(format string, args ...interface{}) json.RawMessage {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelExprf when in batch"))
}
return v.Driver.ChannelExprf(format, args...)
}

func (v *vimstate) ChannelNormal(expr string) {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelNormal when in batch"))
}
v.Driver.ChannelNormal(expr)
}

func (v *vimstate) ChannelRedraw(force bool) {
if v.currBatch != nil {
panic(fmt.Errorf("called ChannelRedraw when in batch"))
}
v.Driver.ChannelRedraw(force)
}

0 comments on commit 1689c93

Please sign in to comment.