Package org.vimplugin

Source Code of org.vimplugin.VimPlugin

/*
* Vimplugin
*
* Copyright (c) 2007 by The Vimplugin Project.
*
* Released under the GNU General Public License
* with ABSOLUTELY NO WARRANTY.
*
* See the file COPYING for more information.
*/
package org.vimplugin;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import java.text.MessageFormat;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;

import org.apache.tools.ant.taskdefs.condition.Os;

import org.eclim.logging.Logger;

import org.eclim.util.CommandExecutor;
import org.eclim.util.IOUtils;
import org.eclim.util.StringUtils;

import org.eclipse.core.runtime.Platform;

import org.eclipse.jface.dialogs.MessageDialog;

import org.eclipse.jface.resource.ImageDescriptor;

import org.eclipse.swt.widgets.Display;

import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;

import org.eclipse.ui.plugin.AbstractUIPlugin;

import org.osgi.framework.BundleContext;

import org.vimplugin.editors.VimEditorPartListener;

import org.vimplugin.preferences.PreferenceConstants;

/**
* The main plugin class to be used in the desktop.
*/
public class VimPlugin
  extends AbstractUIPlugin
{
  private static final Logger logger = Logger.getLogger(VimPlugin.class);

  private static final String GVIM_FEATURE_TEST =
    "redir! > <file> | silent! <command> | quit";
  private static final String FEATURES_COMMAND_UNIX =
    "echo 'embed:' . (v:version >= 700 && has('gui_gtk')) . " +
        "' netbeans:' . (has('netbeans_intg')) . " +
        "' netbeansDocumentListen:' . " +
            "(v:version > 702 || (v:version == 702 && has('patch359')))";
  private static final String FEATURES_COMMAND_WINDOWS =
    "echo 'embed:' . " +
            "(v:version > 701 || (v:version == 701 && has('patch091'))) . " +
        "' netbeans:' . (has('netbeans_intg')) . " +
        "' netbeansDocumentListen:' . " +
            "(v:version > 702 || (v:version == 702 && has('patch359')))";

  /**
   * The shared instance.
   */
  private static VimPlugin plugin;

  /**
   * ID of the default Vim instance.
   */
  public static final int DEFAULT_VIMSERVER_ID = 0;

  private HashMap<String,Boolean> features;
  private VimEditorPartListener partListener;

  /**
   * Returns the shared instance.
   *
   * @return the default plugin instance
   */
  public static VimPlugin getDefault() {
    return plugin;
  }

  /**
   * Returns an image descriptor for the image file at the given plug-in
   * relative path.
   *
   * @param path the path
   * @return the image descriptor
   */
  public static ImageDescriptor getImageDescriptor(String path) {
    return AbstractUIPlugin.imageDescriptorFromPlugin("VimNB", path);
  }

  /**
   * Counts number of instances of vimServerNewWindow
   */
  private int nextServerID;

  /**
   * Counts number of total buffers opened so far. If we close one buffer this
   * value doesn't change.
   */
  private int numberOfBuffers;

  /**
   * Counts number of commands executed so far. Will be useful for checking
   * functions and replies.
   */
  private int seqNo;

  /**
   * Store all the vim instances using their id as the key.
   */
  private final HashMap<Integer, VimServer> vimServers =
    new HashMap<Integer, VimServer>();

  /**
   * Properties instance for plugin.properties
   */
  private Properties properties;

  /**
   * ResourceBundle containing vimplugin messages.
   */
  private ResourceBundle messages;

  /**
   * The constructor.
   */
  public VimPlugin() {
    plugin = this;

    properties = new Properties();
    try{
      properties.load(getClass().getResourceAsStream("/plugin.properties"));
    }catch(IOException ioe){
      MessageDialog.openError(
          getWorkbench().getActiveWorkbenchWindow().getShell(),
          "Vimplugin", "Unable to load plugin.properties");
      ioe.printStackTrace();
    }

    messages = ResourceBundle.getBundle(
        "org/vimplugin/messages",
        Locale.getDefault(),
        getClass().getClassLoader());
  }

  /**
   * Creates a {@link VimServer} for each open action.
   *
   * @return the server instance
   */
  public int getDefaultVimServer() {
    return createVimServer(DEFAULT_VIMSERVER_ID);
  }

  /**
   * Creates a VimServer.
   *
   * @return The VimServer ID.
   */
  public int createVimServer() {
    return createVimServer(nextServerID++);
  }

  /**
   * Create a new VimServer with the ID Specified. If a VimServer with the ID
   * specified already exists, then don't do anything.
   *
   * @param id ID to use for the new VimServer.
   * @return ID of the new VimServer.
   */
  private int createVimServer(int id) {
    if (!vimServers.containsKey(id)) {
      VimServer vimserver = new VimServer(id);
      vimServers.put(id, vimserver);
    }
    return id;
  }

  /**
   * Stops the VimServer specified.
   *
   * @param id The ID of the VimServer to stop.
   * @return Success.
   */
  public boolean stopVimServer(int id) {
    boolean b = false;
    try {
      b = getVimserver(id).stop();
      vimServers.remove(id);
    } catch (IOException ioe) {
      MessageDialog.openError(
          getWorkbench().getActiveWorkbenchWindow().getShell(),
          "Vimplugin", "VimServer to stop not found.");
      ioe.printStackTrace();
    }
    return b;
  }

  /**
   * Returns VimServer with the id specified.
   *
   * @param id The ID of the VimServer.
   * @return The VimServer with the ID specified.
   */
  public VimServer getVimserver(int id) {
    return vimServers.get(id);
  }

  /**
   * starts the plugin.
   *
   * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
   */
  @Override
  public void start(BundleContext context) throws Exception {
    super.start(context);
    nextServerID = 1; // 0 is for the DEFAULT VimServer
    numberOfBuffers = 1; // Vim starts buffer count from 1
    seqNo = 0;

    partListener = new VimEditorPartListener();
    Display.getDefault().asyncExec(new Runnable(){
      public void run()
      {
        IWorkbench workbench = PlatformUI.getWorkbench();
        workbench.getActiveWorkbenchWindow()
          .getActivePage().addPartListener(partListener);
      }
    });
  }

  /**
   * stop the plugin.
   *
   * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
   */
  @Override
  public void stop(BundleContext context) throws Exception {
    super.stop(context);
    plugin = null;

    if (PlatformUI.isWorkbenchRunning()){
      IWorkbench workbench = PlatformUI.getWorkbench();
      if (workbench != null){
        workbench.getActiveWorkbenchWindow()
          .getActivePage().removePartListener(partListener);
      }
    }
  }

  /**
   * increment {@link #seqNo} by one.
   * @return the next sequence Number.
   */
  public int nextSeqNo() {
    return seqNo++;
  }

  /**
   * Simple Setter.
   * @param numberOfBuffers the numberOfBuffers to set
   */
  public void setNumberOfBuffers(int numberOfBuffers) {
    this.numberOfBuffers = numberOfBuffers;
  }

  /**
   * Simple Getter.
   * @return the numberOfBuffers
   */
  public int getNumberOfBuffers() {
    return numberOfBuffers;
  }

  /**
   * Determines if the configured gvim path exists.
   *
   * @return true if the configured gvim path exists, false otherwise.
   */
  public boolean gvimAvailable() {
    String gvim = VimPlugin.getDefault().getPreferenceStore()
      .getString(PreferenceConstants.P_GVIM);
    File file = new File(gvim);
    if (file.exists()){
      return true;
    }
    return false;
  }

  /**
   * Determines if the configured gvim instance supports embedding.
   *
   * @return true if embedding is supported, false otherwise.
   */
  public boolean gvimEmbedSupported() {
    return hasFeature("embed");
  }

  /**
   * Determines if the configured gvim instance supports the required netbeans
   * interface.
   *
   * @return true if netbeans supported, false otherwise.
   */
  public boolean gvimNbSupported() {
    return hasFeature("netbeans");
  }

  /**
   * Determines if the configured gvim can <a href="http://groups.google.com/group/vim_dev/browse_thread/thread/2126395af4137d4b">reliably</a>
   * support the netbeans document listening events:
   *
   * @return true if document listening is reliably supported.
   */
  public boolean gvimNbDocumentListenSupported() {
    return hasFeature("netbeansDocumentListen");
  }

  public void resetGvimState() {
    features = null;
  }

  /**
   * Gets the partListener used to monitor (un)focus of vim editors.
   *
   * @return The partListener.
   */
  public VimEditorPartListener getPartListener() {
    return this.partListener;
  }

  private boolean hasFeature(String name) {
    if (features == null){
      String gvim = VimPlugin.getDefault().getPreferenceStore()
        .getString(PreferenceConstants.P_GVIM);
      try{
        File tempFile = File.createTempFile("eclim_gvim", null);
        tempFile.deleteOnExit();
        String command = FEATURES_COMMAND_UNIX;
        if (Platform.getOS().equals(Platform.OS_WIN32)) {
          command = FEATURES_COMMAND_WINDOWS;
        }
        command = GVIM_FEATURE_TEST.replaceFirst("<command>", command);
        command = command.replaceFirst("<file>",
            tempFile.getAbsolutePath().replace('\\', '/').replaceAll(" ", "\\ "));

        String[] cmd = {
          gvim, "-f", "-X", "-u", "NONE", "-U", "NONE", "--cmd", command};
        logger.debug(Arrays.toString(cmd));
        CommandExecutor process = CommandExecutor.execute(cmd, 5000);
        if(process.getReturnCode() != 0){
          logger.error("Failed to execute gvim: " + process.getErrorMessage());
          return false;
        }

        FileInputStream in = null;
        try{
          String result = IOUtils.toString(in = new FileInputStream(tempFile));
          result = result.trim();
          logger.debug("gvim features supported: " + result);

          features = new HashMap<String,Boolean>();
          for(String f : StringUtils.split(result)){
            String[] keyVal = StringUtils.split(f, ":");
            if(keyVal.length != 2){
              logger.error("Invalid response from gvim: " + result);
              return false;
            }
            features.put(keyVal[0], Boolean.valueOf(keyVal[1].equals("1")));
          }
        }catch(IOException ioe){
          logger.error("Unable to read temp file.", ioe);
          IOUtils.closeQuietly(in);
          return false;
        }finally{
          IOUtils.closeQuietly(in);
          try{
            tempFile.delete();
          }catch(Exception ignore){
          }
        }
      }catch(Exception e){
        logger.error("Unable to execute gvim.", e);
        return false;
      }
    }
    return features.containsKey(name) && features.get(name).booleanValue();
  }

  /**
   * Gets the specified property from plugin.properties.
   *
   * @param name The property name.
   * @return The property value or null if not found.
   */
  public String getProperty(String name){
    return properties.getProperty(name);
  }

  /**
   * Gets the specified property from plugin.properties.
   *
   * @param name The property name.
   * @param def Default value if property is not found.
   * @return The property value or def if not found.
   */
  public String getProperty(String name, String def){
    return properties.getProperty(name, def);
  }

  /**
   * Used to obtain a message from the plugin's resource bundle.
   *
   * Supports optional var args which will be used to format the message via
   * MessageFormat.
   *
   * @param key The message key.
   * @param args Optional arguments to format the message with.
   * @return The message.
   */
  public String getMessage(String key, Object... args) {
    String message = messages.getString(key);
    if (Os.isFamily(Os.FAMILY_MAC)){
      message = message.replaceAll("\\bgvim\\b", "mvim/gvim");
    }
    if (args != null && args.length > 0){
      return MessageFormat.format(message, args);
    }
    return message;
  }
}
TOP

Related Classes of org.vimplugin.VimPlugin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.