// vim makes a call to Vim. args[0:2] are expected to be quoted
// strings. args[2:] are expected to be string literals representing
// JSON
vim makes a call to Vim. args[0:2] are expected to be quoted
strings. args[2:] are expected to be string literals representing
JSON
// vim makes a call to Vim . args [ 0 : 2 ] are expected to be quoted // strings . args [ 2 : ] are expected to be string literals representing // JSON
func vim(args []string) (resp vimResponse, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = r.(error)
		}
	}()
	fn := args[0]
	var jsonArgs []string
	for i, a := range args {
		if i <= 1 {
			uq, err := strconv.Unquote("\"" + a + "\"")
			if err != nil {
				ef("failed to unquote %q: %v", a, err)
			}
			jsonArgs = append(jsonArgs, strconv.Quote(uq))
		} else {
			var buf bytes.Buffer
			json.HTMLEscape(&buf, []byte(a))
			jsonArgs = append(jsonArgs, buf.String())
		}
	}
	jsonArgString := "[" + strings.Join(jsonArgs, ", ") + "]"
	var i []interface{}
	if err := json.Unmarshal([]byte(jsonArgString), &i); err != nil {
		ef("failed to json Unmarshal %q: %v", jsonArgString, err)
	}
	switch fn {
	case "redraw":
		switch l := len(args[1:]); l {
		case 0:
		case 1:
			if args[1] != "force" {
				ef("unknown argument %q to redraw", args[1])
			}
		default:
			ef("redraw has a single optional argument: force; we saw %v", l)
		}
	case "ex", "normal", "expr":
		switch l := len(args[1:]); l {
		case 1:
			if _, ok := i[1].(string); !ok {
				ef("%v takes a string argument; saw %T", fn, i[1])
			}
		default:
			ef("%v takes a single argument: we saw %v", fn, l)
		}
	case "call":
		switch l := len(args[1:]); l {
		case 1:
			if _, ok := i[1].(string); !ok {
				ef("%v takes a string as its first argument; saw %T", fn, i[1])
			}
		case 2:
			if _, ok := i[1].(string); !ok {
				ef("%v takes a string as its first argument; saw %T", fn, i[1])
			}
			vs, ok := i[2].([]interface{})
			if !ok {
				ef("%v takes a slice of values as its second argument; saw %T", fn, i[2])
			}
			i = append(i[:2], vs...)
		default:
			ef("%v takes a two arguments: we saw %v", fn, l)
		}
	}
	if bs, err := json.Marshal(i); err != nil {
		ef("failed to remarshal json args: %v", err)
	} else {
		jsonArgString = string(bs)
	}
	addr := os.Getenv("GOVIMTESTDRIVER_SOCKET")
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		ef("failed to connect to driver on %v: %v", addr, err)
	}
	if _, err := fmt.Fprintln(conn, jsonArgString); err != nil {
		ef("failed to send command %q to driver on: %v", jsonArgString, err)
	}
	dec := json.NewDecoder(conn)
	var protoResp []interface{}
	if err := dec.Decode(&protoResp); err != nil {
		ef("failed to decode response: %v", err)
	}
	if v := protoResp[0].(string); v != "" {
		ef("protocol error: %v", v)
	}
	vimResp := protoResp[1].([]interface{})
	if v := vimResp[0].(string); v != "" {
		resp.error = fmt.Errorf("vim error: %v", v)
	}
	if len(vimResp) == 2 {
		resp.value = &vimResp[1]
	}
	return resp, nil
}
func vim ( args [ ] string ) ( resp vimResponse , err error ) { defer func ( ) { if r := recover ( ) ; r != nil { err = r . ( error ) } } ( ) fn := args [ 0 ] var jsonArgs [ ] string for i , a := range args { if i <= 1 { uq , err := strconv . Unquote ( " \" " + a + " \" " ) if err != nil { ef ( " " , a , err ) } jsonArgs = append ( jsonArgs , strconv . Quote ( uq ) ) } else { var buf bytes . Buffer json . HTMLEscape ( & buf , [ ] byte ( a ) ) jsonArgs = append ( jsonArgs , buf . String ( ) ) } } jsonArgString := " " + strings . Join ( jsonArgs , " " ) + " " var i [ ] interface { } if err := json . Unmarshal ( [ ] byte ( jsonArgString ) , & i ) ; err != nil { ef ( " " , jsonArgString , err ) } switch fn { case " " : switch l := len ( args [ 1 : ] ) ; l { case 0 : case 1 : if args [ 1 ] != " " { ef ( " " , args [ 1 ] ) } default : ef ( " " , l ) } case " " , " " , " " : switch l := len ( args [ 1 : ] ) ; l { case 1 : if _ , ok := i [ 1 ] . ( string ) ; ! ok { ef ( " " , fn , i [ 1 ] ) } default : ef ( " " , fn , l ) } case " " : switch l := len ( args [ 1 : ] ) ; l { case 1 : if _ , ok := i [ 1 ] . ( string ) ; ! ok { ef ( " " , fn , i [ 1 ] ) } case 2 : if _ , ok := i [ 1 ] . ( string ) ; ! ok { ef ( " " , fn , i [ 1 ] ) } vs , ok := i [ 2 ] . ( [ ] interface { } ) if ! ok { ef ( " " , fn , i [ 2 ] ) } i = append ( i [ : 2 ] , vs ... ) default : ef ( " " , fn , l ) } } if bs , err := json . Marshal ( i ) ; err != nil { ef ( " " , err ) } else { jsonArgString = string ( bs ) } addr := os . Getenv ( " " ) conn , err := net . Dial ( " " , addr ) if err != nil { ef ( " " , addr , err ) } if _ , err := fmt . Fprintln ( conn , jsonArgString ) ; err != nil { ef ( " " , jsonArgString , err ) } dec := json . NewDecoder ( conn ) var protoResp [ ] interface { } if err := dec . Decode ( & protoResp ) ; err != nil { ef ( " " , err ) } if v := protoResp [ 0 ] . ( string ) ; v != " " { ef ( " " , v ) } vimResp := protoResp [ 1 ] . ( [ ] interface { } ) if v := vimResp [ 0 ] . ( string ) ; v != " " { resp . error = fmt . Errorf ( " " , v ) } if len ( vimResp ) == 2 { resp . value = & vimResp [ 1 ] } return resp , nil }
vim makes a call to Vim.
vim makes a call to Vim .
// optional argument of force // no args // on the command line we require the args to be specified as an array // for ease of explanation/documentation, but now we splat the slice // vimResp[0] is a string representing any protocol error // vimResp[1] is a []interface such that: //   vimResp[1][0] is a string representing any Vim error //   vimResp[1][1] (if supplied) is the value returned by Vim