dtujfmfs06058
dtujfmfs06058
2014-02-02 16:55

如何从一开始就启动vim?

已采纳

I've got a command line tool written in Golang and I need to start vim from it. However it's not working, and there's not any error or much else to work with. I've reduced the code to just this:

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    cmd := exec.Command("vim", "test.txt")
    err := cmd.Run()
    fmt.Println(err)
}

When I run this, I can see the vim process for a 2-3 seconds but the application doesn't actually open. Then the program simply exits (and the vim process closes) with an "exit status 1".

I've also tried this to capture stderr:

package main

import (
    "bytes"
    "fmt"
    "os/exec"
)

func main() {
    cmd := exec.Command("vim", "test.txt")
    var stderr bytes.Buffer
    cmd.Stderr = &stderr
    err := cmd.Run()
    fmt.Println(err)
    fmt.Println(stderr)
}

But in this case, the program gets stuck indefinitely.

Any idea what could be the issue?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • douwenpin0428 douwenpin0428 7年前

    Pass on stdin and stdout from the calling program which, provided it was run from a terminal (likely for a command line program) will start vim for you and return control when the user has finished editing the file.

    package main
    
    import (
        "fmt"
        "os"
        "os/exec"
    )
    
    func main() {
        cmd := exec.Command("vim", "test.txt")
        cmd.Stdin = os.Stdin
        cmd.Stdout = os.Stdout
        err := cmd.Run()
        fmt.Println(err)
    }
    
    点赞 评论 复制链接分享
  • dtc66318 dtc66318 7年前

    VIM needs a proper terminal and detects the absence of one.

    If you use the StderrPipe and read it while vim is running you will see this:

    2014/02/02 20:25:49 Vim: Warning: Output is not to a terminal
    2014/02/02 20:25:49 Vim: Warning: Input is not from a terminal
    

    Example for reading stderr while executing (on play):

    func logger(pipe io.ReadCloser) {
        reader := bufio.NewReader(pipe)
    
        for {
            output, err := reader.ReadString('
    ')
    
            if err != nil {
                log.Println(err)
                return
            }
    
            log.Print(string(output))
        }
    }
    
    pipe, err := cmd.StderrPipe()
    
    go logger(pipe)
    cmd.Run()
    

    For vim to run you probably need to emulate a terminal.

    Maybe goat (doc) can help you out:

    tty := term.NewTTY(os.Stdin)
    
    cmd := exec.Command("vim", "test.txt")
    cmd.Stdin = t
    cmd.Stdout = t
    
    // ...
    
    点赞 评论 复制链接分享