问题
It was hard to phrase this as a question, but here is what I want to do:
I want vim to execute a process and to write to its stdin and read from its stdout file descriptors repeatedly. In other words, I want a back-and-forth dialogue between vim and another program.
I'll use cat as a simple example. If you run cat with no command-line arguments, then whatever you type on stdin is output to stdout after each newline character.
What I would like is to have a vim window which displays the most recent output of some program and to be able to write to its stdin upon certain events. So, unlike the following:
:read !cat
which waits for you to finish typing and press Ctrl-D to close cat's stdin, I want to display the output immediately after I press enter and to keep the process running so that I can type more.
Ultimately, I don't intend to be typing the input to the process; I want events (e.g. moving the cursor) to trigger vim to write specific commands to this process and display the output.
The reason I want the program to continue running instead of invoking the process once for each event is that the output to the program will be commands that generate state. If the program had to be invoked for each command, it would have to save the state to a file and read it in each time.
An alternative I am considering: writing the program to listen on a port. Then, vim invokes a command that simply opens the socket and passes the vim command to the program and returns the message from the program. This would require me writing two programs, though, which I hope is unnecessary.
What I am trying to do here is write a tool that analyses your code and provides an interactive command-line interface (e.g commands like that do things like "output a list of all the lines which set this variable). However, rather than running this program in a separate terminal or screen session, I would like vim to be able to integrate the output of this program in a window, if that is possible.
回答1:
You should check out vimproc. You can use vimproc#popen3
to start the process. vimproc#popen3
returns an object(=dictionary) with a stdin
member field that has a write
method and a stdout
member field that has a read
method.
The problem is how to trigger the reading and writing. Vim is single thread, so you'll have to rely on autocmd events. Obviously you'll want to try reading whenever you write something(just in case), but you should also use the CursorHold
event.
You can also use Python for IO. While it seems like you can use Python threading to trigger the reading, I would advise against it as Vim was never built for multithreading and from my experience, trying to hack multithreading into it with Python threads often causes race conditions and crashes Vim.
来源:https://stackoverflow.com/questions/21961876/how-do-i-read-and-write-repeatedly-from-a-process-in-vim