英文:
How to start vim from go?
问题
我有一个用Golang编写的命令行工具,我需要从中启动vim。然而,它不起作用,也没有任何错误或其他可用的信息。我将代码简化为以下内容:
package main
import (
"fmt"
"os/exec"
)
func main() {
cmd := exec.Command("vim", "test.txt")
err := cmd.Run()
fmt.Println(err)
}
当我运行这段代码时,我可以看到vim进程持续运行2-3秒,但实际上应用程序并没有打开。然后程序简单地退出(vim进程关闭),并显示"exit status 1"。
我还尝试了以下代码来捕获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)
}
但在这种情况下,程序会无限期地停滞。
有任何想法是什么问题呢?
英文:
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?
答案1
得分: 24
将stdin
和stdout
从调用程序传递给它,如果调用程序是从终端运行的(通常是命令行程序),它将为您启动vim,并在用户完成编辑文件后返回控制。
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)
}
英文:
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)
}
答案2
得分: 7
VIM需要一个合适的终端,并会检测是否缺少终端。
如果你在vim运行时使用StderrPipe
并读取它,你会看到以下内容:
2014/02/02 20:25:49 Vim: 警告: 输出不是终端
2014/02/02 20:25:49 Vim: 警告: 输入不是终端
以下是在执行过程中读取stderr的示例(在playground上):
func logger(pipe io.ReadCloser) {
reader := bufio.NewReader(pipe)
for {
output, err := reader.ReadString('\n')
if err != nil {
log.Println(err)
return
}
log.Print(string(output))
}
}
pipe, err := cmd.StderrPipe()
go logger(pipe)
cmd.Run()
为了让vim正常运行,你可能需要模拟一个终端。
tty := term.NewTTY(os.Stdin)
cmd := exec.Command("vim", "test.txt")
cmd.Stdin = t
cmd.Stdout = t
// ...
英文:
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('\n')
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
// ...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论