+ sendVimCommand(command, arguments);
+ }
+
+ /**
+ * Send a command to the Vim server. If the server isn't running, it will
+ * be started with the name VIMCODER#### where #### is the problem ID.
+ * @param command The command to send to the server.
+ * @param argument Arguments for the remote command.
+ * @throws Exception If the command could not be sent.
+ */
+ private void sendVimCommand(String command,
+ String[] arguments) throws Exception
+ {
+ String[] vimCommand = VimCoder.getVimCommand().split("\\s");
+ String[] flags = {"--servername", "VimCoder" + id, command};
+ vimCommand = Util.concat(vimCommand, flags);
+ vimCommand = Util.concat(vimCommand, arguments);
+ Process child = Runtime.getRuntime().exec(vimCommand, null, directory);
+
+ /* FIXME: This is a hack with a magic number. The problem is the Vim
+ * process doesn't fork to the background on some systems, so we can't
+ * wait on the child. At the same time, calling this method before the
+ * previous child could finish initializing the server may result in
+ * multiple editor windows popping up. We'd also like to be able to
+ * get the return code from the child if we can. The workaround here is
+ * to stall the thread for a little while or until we know the child
+ * does exit. If the child never exits before the timeout, we will
+ * assume it is not backgrounding and that everything worked. */
+ long expire = System.currentTimeMillis() + 250;
+ while (System.currentTimeMillis() < expire)
+ {
+ Thread.yield();
+ try
+ {
+ int exitCode = child.exitValue();
+ if (exitCode != 0) throw new Exception("Vim process returned exit code " + exitCode + ".");
+ break;
+ }
+ catch (IllegalThreadStateException exception)
+ {
+ // The child has not exited; intentionally ignoring exception.
+ }
+ }