怎么在自己的编辑器中添加模板(翻译)

如何在自己的编辑器中添加模板(翻译)

原文:http://eclipse.dzone.com/articles/how-enable-template-feature-cu

模板功能是Eclipse 编辑器中经常使用的功能,提供了自动生成功能。当你在Java 编辑器中输入"for"然后点击Ctrl+space,这种机制会自动完成循环相关的代码。这种特性节省了开发者的时间,而且使编辑器交互性更强。下面的步骤会帮你定制你自己的编辑器。

 

 

增加模板特性的步骤

步骤1:

 

你需要扩展"org.eclipse.ui.preferencePages" ,并添加模板的首选项页面。

 

<page category=”cat” class=”com.xyz.ABCTemplatePreferencePage” id=”TemplateID” name=”Templates”> 
</page>

 

public class CustomTemplatePreferencePage extends TemplatePreferencePage implements IWorkbenchPreferencePage {

public CustomTemplatePreferencePage() {
try {
 setPreferenceStore(Activator.getDefault().getPreferenceStore());
 setTemplateStore(CustomTemplateManager.getInstance().getTemplateStore());
 setContextTypeRegistry(CustomTemplateManager.getInstance().getContextTypeRegistry());
} catch(Exception ex){
 ex.printStackTrace();
 }
}

 protected boolean isShowFormatterSetting() {
 return false;
 }

public boolean performOk() {
 boolean ok = super.performOk();
 Activator.getDefault().savePluginPreferences();
 return ok;
 }

}

 

步骤2:

 

为模板定义上下文(context),需要扩展"org.eclipse.ui.editors.templates"

<contextType class=”com.xyz.CustomTemplateContextType” id=”editorType” name=”Test”>
</contextType>

<include file=”templates/default-templates.xml” translations=”templates/default-templates.xml”>
</include>
 

其中的include属性用来从xml文件中加载默认模板。在工作空间的(workspace)的生命周期中,它只加载一次,或者也可以在首选项页面中点击restore default。

public class CustomTemplateContextType extends 
 org.eclipse.jface.text.templates.TemplateContextType {

public static final String CONTEXT_TYPE 
  = Activator.getDefault().getPluginId() + ".preference.contextType.Custom";


public CustomTemplateContextType() {
 addResolver(new GlobalTemplateVariables.Cursor());
 addResolver(new GlobalTemplateVariables.WordSelection());
 addResolver(new GlobalTemplateVariables.LineSelection());
}

}

 

步骤3:

要在你的模板中添加更多的信息,你需要扩展TemplateProposal这个类,并且重写其中的getAdditionalProposalInfo方法。

public class CustomTemplateCompletionProposal extends TemplateProposal{
private final Template fTemplate;
private final TemplateContext fContext;
private final Image fImage;
private final IRegion fRegion;
private int fRelevance;
private String fDisplayString;



public CustomTemplateCompletionProposal(Template template,
TemplateContext context, IRegion region, Image image, int relevance) {
 super(template, context, region, image, relevance);
 fTemplate=template;
 fContext = context;
 fImage=image;
 fRegion=region;
 fRelevance=relevance;
 fDisplayString=null;
 }

@Override

public String getAdditionalProposalInfo() {
 return StringUtils.convertToHTMLContent(fTemplate.getPattern());

 }

}
 

步骤4:

定义一个模板管理器用来管理所有的进程。

public class CustomTemplateManager {
 private static final String CUSTOM_TEMPLATES_KEY 
 = Activator.getDefault().getPluginId() + ".customtemplates";
 private static CustomTemplateManager instance;
 private TemplateStore fStore;
 private ContributionContextTypeRegistry fRegistry;
 private TemplatePersistenceData[] templateData;
 private CustomTemplateManager(){}

public static CustomTemplateManager getInstance(){
 if(instance==null){
 instance = new CustomTemplateManager();
 }
 return instance;
}

public TemplateStore getTemplateStore(){

 if (fStore == null){
  fStore = new ContributionTemplateStore(getContextTypeRegistry(), 
  Activator.getDefault().getPreferenceStore(), CUSTOM_TEMPLATES_KEY);
  try {
  fStore.load();
  } catch (IOException e){
  e.printStackTrace();

 }
}
return fStore;
}



public ContextTypeRegistry getContextTypeRegistry(){
 if (fRegistry == null){
  fRegistry = new ContributionContextTypeRegistry();
 }
 fRegistry.addContextType(CustomTemplateContextType.CONTEXT_TYPE);
 return fRegistry;
}

public IPreferenceStore getPreferenceStore(){
 return Activator.getDefault().getPreferenceStore();
}

public void savePluginPreferences(){
 Activator.getDefault().savePluginPreferences();
}

}
 

步骤5:

 

现在需要定义模板完成的逻辑,这需要扩展由eclipse提供的API TemplateCompletionProcessor,并且写下你自己的逻辑。

public class CustomTemplateAssistProcessor extends TemplateCompletionProcessor{
 @Override
 protected String extractPrefix(ITextViewer viewer, int offset) {
  int i= offset;
  IDocument document= viewer.getDocument();
  if (i > document.getLength())
   return ""; 
 try {
  while (i > 0) {
   char ch= document.getChar(i - 1);
    if (!Character.isJavaIdentifierPart(ch))
     break;
   i--;
  }
 if(i>0){
 int j=i;
 if(document.getChar(j-1)=='<')
 i--;
 } 
 return document.get(i, offset - i);
 } catch (BadLocationException e) {
 return ""; 
}
}

protected Template[] getTemplates(String contextTypeId) {
 CustomTemplateManager manager = CustomTemplateManager.getInstance();
 return manager.getTemplateStore().getTemplates();
}

protected TemplateContextType getContextType(ITextViewer viewer, IRegion region) {
 CustomTemplateManager manager = CustomTemplateManager.getInstance();
 return manager.getContextTypeRegistry().getContextType(CustomTemplateContextType.CONTEXT_TYPE);
}

protected Image getImage(Template template) {
 return Activator.getDefault().getImageRegistry().get(Activator.ICON_TEMPLATE);
}

public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
 ITextSelection selection= (ITextSelection) viewer.getSelectionProvider().getSelection();
 // adjust offset to end of normalized selection
 if (selection.getOffset() == offset)
  offset= selection.getOffset() + selection.getLength();
 String prefix= extractPrefix(viewer, offset);
 Region region= new Region(offset - prefix.length(), prefix.length());
 TemplateContext context= createContext(viewer, region);
 if (context == null)
  return new ICompletionProposal[0];
 context.setVariable("selection", selection.getText()); // name of the selection variables {line, word_selection //$NON-NLS-1$
 Template[] templates= getTemplates(context.getContextType().getId());
 List<ICompletionProposal> matches= new ArrayList<ICompletionProposal>();
 for (int i= 0; i < templates.length; i++) {
  Template template= templates[i];
  try {
   context.getContextType().validate(template.getPattern());
  } catch (TemplateException e) {
 continue;
 }
 if(!prefix.equals("") &&prefix.charAt(0)=='<')
   prefix=prefix.substring(1);
 if (!prefix.equals("")&&(template.getName().startsWith(prefix) && 
   template.matches(prefix, context.getContextType().getId())))
 matches.add(createProposal(template, context, (IRegion) region, getRelevance(template, prefix)));
}
return matches.toArray(new ICompletionProposal[matches.size()]);
}

}
 

步骤6:

 

现在你必须调整你的内容帮助程序以使你的模板添加到自动帮助的列表里面。这需要你扩展CustomTemplateAssistProcessor 并调用它的super.computeCompletionProposals方法来获取模板列表。

public class CustomContentAssistProcessor extends CustomTemplateAssistProcessor {
 private CustomEditor editor;
 this.editor = editor;
 public boolean enableTemplate(){
  return true;
 }

 public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
  int offset) {
   ICompletionProposal[] completionProposals = null;
   IEditorInput editorInput = editor.getEditorInput();
   String text = viewer.getTextWidget().getText();
   List<Object> modList = new ArrayList<Object>();
   if(enableTemplate()){
     ICompletionProposal[] templates = super.computeCompletionProposals(viewer, offset);
   if(templates!=null){
    for(int i=0;i<templates.length;i){
     modList.add(templates[i]);
    }

   }
   if(completionProposals!=null){
     for(int i=0;i<completionProposals.length;i){
      modList.add(completionProposals[i]);
     }
    }
}

if(modList.size()>0)
   return (ICompletionProposal[])modList.toArray(new ICompletionProposal[modList.size()]);

return completionProposals;
}