Reputation: 1547
I like when Eclipse lets me jump between parameters in a method call using a Tab key. I would like my plugin to provide a similar functionality. To be precise, I am injecting some piece of text into the editor and I would like to highlight specific syntax and let the programmer jump to the next match using the Tab key.
Here is an example. Lets suppose I dynamically created the following snippet:
String a = "bogus string";
int i = a.[?]
I will inject that into the editor and I would like that [?]
is highlighted and ready for modification (user might type length()
). Moreover, if there is more [?]
fragments, I would like user to use Tab to move to the next one.
After researching a bit, I found that it might be done using templates. However, I can't find any relevant examples on the Web. Does anybody have experience with this?
UPDATE:
I found two links that might be useful, although I am still not able to come up with a solution.
Upvotes: 7
Views: 2190
Reputation: 63
My answer is based on jeeeyul's answer. The difference is that I wanted not only template itself, but also imports for it to be resolved and added automatically. This can be done in following way, using JDT stuff:
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);
Upvotes: 0
Reputation: 3787
Sample Handler Codes:
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);
Result:
I suggest you use org.eclipse.jdt.ui.javaCompletionProposalComputer
extension. It allows you can contribute Template more legal way.
In my codes, there are hacks since there is no way to get ISourceViewer
legally. I know ISourceViewer
is ITextTargetOperation
itself, but it is not API(Illegal Casting). And Template is intended to designed to be used by TemplateCompletionProcessor
or TemplateCompletionProposalComputer
.
Upvotes: 8
Reputation: 25150
I'm not entirely sure what you want, but you may be able to do what you want with templates.
For example, open a java editor, place the cursor inside a method, type arraya
then ctlr-space, and select arrayadd from the pop up menu. You will get a template with String highlighted, pressing tab jumps to the next variable. The template source can be seen in,
Preferences -> java -> editor ->templates
${array_type}[] ${result:newName(array)} = new ${array_type}[${array}.length + 1];
System.arraycopy(${array}, 0, ${result}, 0, ${array}.length);
${result}[${array}.length]= ${var};
Everything starting the a $ is a variable that you can fill in, and you can tab between variables while filling in the template.
Upvotes: 1