以编程方式添加Java代码模板

时间:2012-10-22 04:32:26

标签: java eclipse eclipse-plugin

我喜欢Eclipse允许我使用Tab键在方法调用中跳转参数。我希望我的插件提供类似的功能。确切地说,我正在向编辑器中注入一些文本,我想强调特定的语法,让程序员使用Tab键跳转到下一个匹配。

这是一个例子。让我们假设我动态创建了以下代码段:

String a = "bogus string";
int i = a.[?]

我会将其注入编辑器中,我希望[?]突出显示并准备好进行修改(用户可以键入length())。此外,如果有更多[?]个片段,我希望用户使用Tab移动到下一个片段。

经过一番研究后,我发现可以使用templates完成。但是,我在网上找不到任何相关的例子。有人有这方面的经验吗?

更新

我找到了两个可能有用的链接,但我仍然无法提出解决方案。

link one

link two

3 个答案:

答案 0 :(得分:8)

样本处理程序代码:

AbstractTextEditor activeEditor = 
        (AbstractTextEditor) HandlerUtil.getActiveEditor(event);

ISourceViewer sourceViewer = 
        (ISourceViewer) activeEditor.getAdapter(ITextOperationTarget.class);

Point range = sourceViewer.getSelectedRange();

// You can generate template dynamically here!
Template template = new Template("sample", 
        "sample description", 
        "no-context", 
        "private void ${name}(){\r\n" + 
        "\tSystem.out.println(\"${name}\")\r\n"
        + "}\r\n", true);

IRegion region = new Region(range.x, range.y);
TemplateContextType contextType = new TemplateContextType("test");
TemplateContext ctx =
    new DocumentTemplateContext(contextType, 
        sourceViewer.getDocument(), 
        range.x, 
        range.y);

TemplateProposal proposal 
    = new TemplateProposal(template, ctx, region, null);

proposal.apply(sourceViewer, (char) 0, 0, 0);

结果:

enter image description here

我建议你使用org.eclipse.jdt.ui.javaCompletionProposalComputer扩展名。它允许您以更合法的方式贡献模板。

在我的代码中,由于无法合法获取ISourceViewer,因此存在黑客攻击。我知道ISourceViewer本身就是ITextTargetOperation,但它不是API(非法投射)。模板旨在供TemplateCompletionProcessorTemplateCompletionProposalComputer使用。

答案 1 :(得分:1)

我不完全确定你想要什么,但你可以用模板做你想做的事。

例如,打开java编辑器,将光标放在方法中,键入arraya然后键入ctlr-space,然后从弹出菜单中选择arrayadd。您将获得一个突出显示String的模板,按Tab键跳转到下一个变量。模板源可以在

中看到

偏好设置 - > java - >编辑器 - >模板

${array_type}[] ${result:newName(array)} = new ${array_type}[${array}.length + 1];
System.arraycopy(${array}, 0, ${result}, 0, ${array}.length);
${result}[${array}.length]= ${var};

以$开头的所有内容都是您可以填写的变量,您可以在填写模板时在变量之间进行制表。

答案 2 :(得分:0)

我的回答是基于jeeeyul的回答。不同之处在于,我不仅需要模板本身,还需要导入以便自动解析和添加。这可以通过以下方式完成,使用JDT:

AbstractTextEditor activeEditor = 
            (AbstractTextEditor) HandlerUtil.getActiveEditor(event);
    if (activeEditor == null) {
        return null;
    }
    ITypeRoot element = EditorUtility.getEditorInputJavaElement(activeEditor, true);
    if (element == null) {
        return null;
    }
    ICompilationUnit unit = element.getAdapter(ICompilationUnit.class);
    if (unit == null) {
        return null;
    }
    ISourceViewer sourceViewer = (ISourceViewer) activeEditor.getAdapter(ITextOperationTarget.class);
    Point range = sourceViewer.getSelectedRange();
    // You can generate template dynamically here!
    Template template = new Template("new List", "Add new list creation", JavaContextType.ID_STATEMENTS,
            "List<${type}> ${name:newName(java.util.List)} = new ArrayList<${type}>();${:import(java.util.List, java.util.ArrayList)}",
            true);
    IRegion region = new Region(range.x, range.y);
    JavaContextType contextType = new JavaContextType();
    contextType.setId(JavaContextType.ID_STATEMENTS); //Set context type, for which we apply this template
    contextType.addResolver(new ImportsResolver("import","import")); //Add imports resolver if we want imports to be added automatically for some template
    CompilationUnitContext ctx = new JavaContext(contextType, sourceViewer.getDocument(), range.x,
            range.y, unit);
    TemplateProposal proposal = new TemplateProposal(template, ctx, region, null);
    proposal.apply(sourceViewer, (char) 0, 0, 0);