Module p.u.v.vimcom

Part of pida.utils.vim

A library to control vim -g using its X protocol interface (with gdk).

How it works

=== General Communication ===

The Vim client/server protocol communicates by sending messages to and from an X communication window. The details are explained in the Vim source. Essentially, Vim understands two sorts of messages over this interface.

;asynchronous key sends : that are exactly equivalent to to the user of the remote Vim typing commands.

;synchronous expression evaluations : these are Vim expressions that are evaluated by the remote Vim, and an answer is replied with the result over the same protocol.

Although the synchronous messages are called synchronous, the reply itself, in programming terms is entirely asynchronous, in that there is no way of knowing when a reply will be received, and one cannot block for it.

Thus, this library allows you to make both of these calls to remote Vims. Synchronous expressions must provide a call back function that will be called when the message is replied to.

=== The Server List ===

(It has been an utter nightmare.)

The primary problem is that GTK does not actually know accurately whether a window with a given window ID has been destroyed. This is how Vim does it (using the X libraries) after checking an attribute for registered Vim sessions with the X root window. This way each Vim doesn't need to unregister itself with the X root window on dying, it just assumes that any other client attempting to connect to it will know that the window has been destroyed. As mentioned, GTK totally fails to do what the X library does, and ascertain whether the window is alive. It succeeds sometimes, but not at others. The result is a GDK window that appears alive, and ready to communicate with, but which causes an uncatchable and fatal application error.

Step in other potential methods of getting an accurate list of servers. Firstly, and most obviously, one can call the command 'vim --serverlist' on a simple system pipe and read the list off. This is entirely reliable, and effective, but the cost of forking a process and starting Vim each time is not fun, and effectively blocks.

Another option is to force users to start Vim through Pida and keep an account of the child processes. This would work very effectively, but it restricts the user, and the entire system.

The final, and current solution is to start Vim itself on a pseudoterminal as a hidden instance, and then communicate with that over the Vim protocol. The reason this can be reliably done, is that since the process is a child, it can be polled to check whether it is alive. This is performed each time the serverlist is requested, and if the hidden instance has been destroyed (eg by the user) a new one is spawned, thus preventing an attempt to communicate with an already-destroyed GDK window.

The cost of this solution is that we spawn an extra Vim process. I believe that the added solidity it brings to the entire system is easily worth it, and it ensures that Pida can communicate with Vim it started and Vim it didn't start.

Line # Kind Name Docs
104 Class poller DEPRECATED: WE DO NOT USE THIS ANYMORE
196 Class communication_window A GTK window that can communicate with any number Vim instances.
API Documentation for PIDA, generated by pydoctor.