2012-10-22 5 views
8

Mi piace quando Eclipse mi consente di saltare tra i parametri in una chiamata di metodo utilizzando un tasto Tab. Vorrei che il mio plugin fornisse una funzionalità simile. Per essere precisi, sto iniettando parte del testo nell'editor e vorrei evidenziare una sintassi specifica e lasciare che il programmatore salti alla prossima partita usando il tasto Tab.Aggiungi modello di codice Java a livello di codice

Ecco un esempio. Consente di supporre che dinamicamente creato il seguente frammento:

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

ho inietterà che nell'editor e vorrei che [?] viene evidenziato e pronto per la modifica (utente potrebbe digitare length()). Inoltre, se ci sono più frammenti [?], vorrei che l'utente usasse Tab per passare a quello successivo.

Dopo una ricerca un po ', ho scoperto che potrebbe essere fatto utilizzando templates. Tuttavia, non riesco a trovare esempi rilevanti sul Web. Qualcuno ha esperienza con questo?

UPDATE:

Ho trovato due link che potrebbero essere utili, anche se sono ancora in grado di trovare una soluzione.

link one

link two

risposta

8

codici di esempio Handler:

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

risultati:

enter image description here

ti suggerisco di utilizzare org.eclipse.jdt.ui.javaCompletionProposalComputer estensione. Ti permette di contribuire con Template in modo più legale.

Nei miei codici, ci sono hack perché non c'è modo di ottenere ISourceViewer legalmente. So che lo è lo stesso ITextTargetOperation, ma non è API (Illegal Casting). E il modello è progettato per essere utilizzato da TemplateCompletionProcessor o TemplateCompletionProposalComputer.

+0

Funziona come un fascino! – bellpeace

1

io non sono del tutto sicuro di quello che si vuole, ma si può essere in grado di fare quello che vuoi con i modelli.

Ad esempio, aprire un editor java, posizionare il cursore all'interno di un metodo, digitare arraya quindi ctlr-space e selezionare arrayadd dal menu a comparsa. Si otterrà un modello con String evidenziato, premendo tab salta alla variabile successiva. La fonte modello può essere visto in,

Preferenze -> Java -> Editor -> Modelli

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

tutto a partire l'un $ è una variabile che è possibile compilare, e si può scheda tra le variabili, mentre compilando il modello.

+0

Sì, questo è il modo in cui i modelli funzionano. Tuttavia, sto sviluppando un plugin che creerà frammenti di codice su runtime. Sto cercando di scoprire come, se possibile, utilizzare l'API dei modelli in modo che l'utente possa modificare e navigare tra i segnaposto. Ci sono altre informazioni che vorresti che io facessi? – bellpeace

+0

La soluzione migliore è rintracciare la fonte del plug-in del modello e vedere come funziona. – sbridges

+1

Hai controllato org.eclipse.jface.text.templates.TemplateProposal? Che cosa succede se si desidera inserire lo snippet senza utilizzare l'assistenza per i contenuti. È anche possibile esaminare il metodo # apply() di TemplateProposal. – jeeeyul

0

La mia risposta è basata sulla risposta di jeeeyul. La differenza è che volevo non solo il modello stesso, ma anche le importazioni per essere risolto e aggiunto automaticamente.Questo può essere fatto nel modo seguente, usando materiale 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);