2012-10-22 3 views
8

Lubię, gdy Eclipse pozwala mi przeskakiwać pomiędzy parametrami w wywołaniu metody za pomocą klawisza Tab. Chciałbym, aby moja wtyczka zapewniała podobną funkcjonalność. Mówiąc dokładniej, wstrzykiwam jakiś fragment tekstu do edytora i chciałbym podkreślić konkretną składnię i pozwolić programiście przejść do następnego dopasowania za pomocą klawisza Tab.Dodaj programowo szablon kodu Java

Oto przykład. Pozwala przypuszczać, że dynamicznie tworzony następujący fragment:

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

że będę wstrzyknąć do edytora i chciałbym że [?] jest podświetlony i gotowy do modyfikacji (użytkownik może wpisać length()). Co więcej, jeśli istnieje więcej fragmentów [?], chciałbym, aby użytkownik używał Tab, aby przejść do następnego.

Po krótkich poszukiwaniach okazało się, że można to zrobić za pomocą templates. Jednak nie mogę znaleźć żadnych odpowiednich przykładów w sieci. Czy ktoś ma z tym doświadczenie?

UPDATE:

znalazłem dwa linki, które mogą być przydatne, chociaż nadal nie jestem w stanie wymyślić rozwiązanie.

link one

link two

Odpowiedz

8

Kody Handler Próbka:

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); 

Wynik:

enter image description here

Proponuję użyć org.eclipse.jdt.ui.javaCompletionProposalComputer rozszerzenie. Pozwala na wnoszenie szablonu w bardziej legalny sposób.

W moich kodach są hacki, ponieważ nie ma sposobu, aby legalnie uzyskać ISourceViewer. Wiem, że ISourceViewer sam w sobie jest ITextTargetOperation, ale to nie jest API (nielegalne przesyłanie). Szablon jest przeznaczony do użycia przez TemplateCompletionProcessor lub TemplateCompletionProposalComputer.

+0

Działa jak urok! – bellpeace

1

Nie jestem do końca pewien, co chcesz, ale może być w stanie robić to, co chcesz z szablonów.

Na przykład otwórz edytor java, umieść kursor wewnątrz metody, wpisz arraya następnie ctlr-space i wybierz arrayadd z wyskakującego menu. Otrzymasz szablon z podświetlonym napisem, naciskając klawisz przeskakuje do następnej zmiennej. Źródło szablon widać,

Preferencje -> Java -> Edytor -> Szablony

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

Wszystko zaczynające się na A $ jest zmienną, która można wypełnić i możesz zakładka pomiędzy zmiennymi podczas wypełnienie szablonu.

+0

Tak, tak działają szablony. Opracowuję jednak wtyczkę, która utworzy fragmenty kodu w środowisku wykonawczym. Próbuję dowiedzieć się, jak w miarę możliwości korzystać z szablonów API, aby użytkownik mógł modyfikować i nawigować między symbolami zastępczymi. Czy jest więcej informacji, które chciałbym przekazać? – bellpeace

+0

Najlepszym rozwiązaniem jest wyśledzenie źródła wtyczki szablonu i sprawdzenie, jak działa. – sbridges

+1

Czy sprawdziłeś org.eclipse.jface.text.templates.TemplateProposal? Co zrobić, jeśli chcesz wstawić fragment nie korzystając z pomocy do treści, możesz również sprawdzić metodę TemplateProposal # apply(). – jeeeyul

0

Moja odpowiedź opiera się na odpowiedzi jeeeyula. Różnica polega na tym, że chciałem nie tylko samego szablonu, ale także importu, aby został on rozwiązany i dodany automatycznie.Można to zrobić w następujący sposób, używając rzeczy 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);