Beispiel #1
0
func format(v *nvim.Nvim, r [2]int, eval *struct {
	Env   context.Env
	Bufnr int `eval:"bufnr('%')"`
}) error {
	var (
		in    [][]byte
		fname string
	)
	buf := nvim.Buffer(eval.Bufnr)

	b := v.NewBatch()
	b.BufferLines(buf, 0, -1, true, &in)
	b.BufferName(buf, &fname)
	if err := b.Execute(); err != nil {
		return nil
	}

	var stdout, stderr bytes.Buffer
	c := exec.Command("goimports", "-srcdir", filepath.Dir(fname))
	c.Stdin = bytes.NewReader(bytes.Join(in, []byte{'\n'}))
	c.Stdout = &stdout
	c.Stderr = &stderr
	c.Env = context.Get(&eval.Env).Environ
	err := c.Run()
	if err == nil {
		out := bytes.Split(bytes.TrimSuffix(stdout.Bytes(), []byte{'\n'}), []byte{'\n'})
		return minUpdate(v, buf, in, out)
	}
	if _, ok := err.(*exec.ExitError); ok {
		var qfl []*nvim.QuickfixError
		for _, m := range errorPat.FindAllSubmatch(stderr.Bytes(), -1) {
			qfe := nvim.QuickfixError{}
			qfe.LNum, _ = strconv.Atoi(string(m[2]))
			qfe.Col, _ = strconv.Atoi(string(m[3]))
			qfe.Text = string(bytes.TrimSpace(m[4]))
			qfe.Bufnr = eval.Bufnr
			qfl = append(qfl, &qfe)
		}
		if len(qfl) > 0 {
			b := v.NewBatch()
			b.Call("setqflist", nil, qfl)
			b.Command("cc")
			return b.Execute()
		}
	}
	return err
}
Beispiel #2
0
func minUpdate(v *nvim.Nvim, b nvim.Buffer, in [][]byte, out [][]byte) error {

	// Find matching head lines.

	n := len(out)
	if len(in) < len(out) {
		n = len(in)
	}
	head := 0
	for ; head < n; head++ {
		if !bytes.Equal(in[head], out[head]) {
			break
		}
	}

	// Nothing to do?

	if head == len(in) && head == len(out) {
		return nil
	}

	// Find matching tail lines.

	n -= head
	tail := 0
	for ; tail < n; tail++ {
		if !bytes.Equal(in[len(in)-tail-1], out[len(out)-tail-1]) {
			break
		}
	}

	// Update the buffer.

	start := head
	end := len(in) - tail
	repl := out[head : len(out)-tail]
	return v.SetBufferLines(b, start, end, true, repl)
}