Функция шаблона — одна из наиболее часто используемых функций в редакторах Eclipse, обеспечивающая автозаполнение синтаксиса кода. Когда вы набираете «for» в редакторе Java и нажимаете «Ctrl + пробел», вы получаете специальное вспомогательное предложение для завершения цикла for. Это экономит время разработчика, а также делает редактор более интерактивным. Если вы заинтересованы в создании шаблона для своего пользовательского редактора, вам помогут следующие шаги.
Шаги для включения функции шаблона
Шаг 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:
Определите контекст для вашего шаблона. Для этого вам нужно расширить точку расширения с именем 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-файла. Оно загружается только один раз для жизненного цикла вашего рабочего пространства или когда вы нажимаете кнопку восстановления по умолчанию на странице настроек.
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: Теперь вам нужно определить логику процесса завершения шаблона. Для этого вам нужно расширить TemplateCompletionProcessor, предоставляемый Eclipse API, и вы должны написать свою собственную логику.
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;
}
Теперь вы можете запустить приложение, и это активирует функцию шаблона для вашего редактора.