为什么要开发QuickCompare Plugin?
没有QuickCompare Plugin的时候:
intellij打开多个Project的时候,我们想比较其中两个Project的任意文件,intellij自带和指定的外部比较工具会比较麻烦。右键当前文件,选择Compare with,然后弹出繁琐的文件选择框,再选择想比较的文件。公司的项目,会经常遇到比较同步多个Project文件的情形,这个时候用intellij自带的文件比较就会很浪费时间啦。都说了时间比金钱更宝贵,我们怎么能在这上面浪费时间呢?
使用QuickCompare Plugin之后:
- 右键弹出菜单,选择Select left file for compare,锁定左侧文件
- 打开第二个文件,右键选择Compare to “***”。So easy 有木有?
开发QuickCompare Plugin Step:
1)前期准备:开发环境搭建及插件工程建立。具体参见官方tutorial:
开发环境搭建
http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/setting_up_environment.html
创建插件工程
http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/creating_plugin_project.html
2)在intellij编辑器右键加入菜单
在Plugin中一个菜单项对应一个Action。建立一个Action的最简单方法就是利用Intellij右键的new Action向导。
Action对应的菜单在编辑器中哪个地方显示,可以在plugin.xml中配置。plugin.xml是intellij插件的描述文件,有点相当于AndroidManifest.xml对于Android APP的作用。
action节点的class表明由哪个class进行初始化。
add-to-group 节点表明action会在intellij UI上哪个区域进行显示。一个action可以加在多个地方。
<actions>
<group id="QuickCompareGroup" text="" description="">
<separator/>
<action id="MyPlugin.SelectLeft" class="SelectLeft" text="Select Left for Compare" description="SelectLeft">
</action>
<action id="MyPlugin.CompareTo" class="CompareTo" text="CompareTo" description="CompareTo">
</action>
<!-- The <separator> element defines a separator between actions.
It can also have an <add-to-group> child element. -->
<separator/>
<add-to-group group-id="NavbarPopupMenu" anchor="before" relative-to-action="FindUsages"/>
<add-to-group group-id="EditorPopupMenu" anchor="before" relative-to-action="Github.Create.Gist"/>
<add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="Github.Create.Gist"/>
</group>
</actions>
action对应的class需集成Action类,action菜单被点击后actionPerformed会被执行
action的update方法,会时不时的被intellij IDE SDK框架调用,用来更新自身的状态及UI
public class SelectLeft extends AnAction {
private BC mInstance = (BC) ApplicationManager.getApplication().getComponent("BC");
@Override
public void update(AnActionEvent e) {
super.update(e);
}
@Override
public void actionPerformed(AnActionEvent e) {
// TODO: insert action logic here
VirtualFile vFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
mInstance.setLeftFile(vFile);
mInstance.setCurrentState(BC.SelectState.WAITFORCOMPARE);
}
}
3)在Settings中加入intellij插件设置
插件自身配置同样可以在plugin.xml中声明
一个配置类需实现 Configurable接口,Configurable一个有7个方法,分别简单介绍下:
- public String getDisplayName();
显示在设置中心的设置项名称 - public String getHelpTopic();
帮助提示文字,具体显示在哪,暂时还没测试过 - public JComponent createComponent();
重点方法!创建配置UI布局 - public boolean isModified();
返回是否配置修改过,这个方法会经常被系统框架调用 - public void apply() throws ConfigurationException ;
设置下面的apply按钮被点击时调用 - public void reset();
设置界面的reset点击时调用 - public void disposeUIResources();
界面关闭释放资源
4)配置保存
intellij插件有多种持久化数据的方法。在我们插件中我们只需要保存外部比较工具Beyond compare的可执行文件地址。因此我们使用PropertiesComponent 保存设置。PropertiesComponent使用方法非常简单:
- 获取PropertiesComponent单例实例
PropertiesComponent component = PropertiesComponent.getInstance(); - 设置键值对
component.setValue("bc", mPathTextField.getText());
5)调用外部工具进行比较
本质上QuickCompare Plugin还是调用外部工具进行比较的,所以我们需要通过命令行方式调用Beyond Compare。
JAVA调用外部可执行程序使用Runtime.getRuntime().exec 接口。
注意:给可执行程序传递参数的时候最好使用字符串数组方式传递,不要直接使用字符串拼接写在一个字符串中,否则可能会遇到路径中的空格等奇葩问题。
private void compare(VirtualFile leftFile,VirtualFile rightFile){
Process p = null;
try {
System.out.println("before compare...");
PropertiesComponent component = PropertiesComponent.getInstance();
if (StringUtil.isEmpty(component.getValue("bc"))){
System.out.println("pls set bc path first...");
}else {
String comparePath = component.getValue("bc");
String[] execStringArray = new String[]{comparePath,leftFile.getPath(),rightFile.getPath()};
Runtime.getRuntime().exec(execStringArray);
System.out.println("after compare...");
}
} catch (IOException e) {
System.out.println("compare exception...");
e.printStackTrace();
} catch (Exception e){
System.out.println("compare exception...");
e.printStackTrace();
}
}
QuickCompare Plugin github https://github.com/nziyouren/QuickComparePlugin
欢迎Fork & Contribute