2012-05-04 15 views
6

Dla mojej wtyczki próbuję uzyskać dostęp do wybranego kodu w CompilationUnitEditor. Dlatego dodałem wkład do menu kontekstowego i wykorzystania następującego kodu:Jak mogę uzyskać wybrany kod w Eclipse?

public class ContextMenuHandler implements IEditorActionDelegate { 

    private IEditorPart editorPart; 

    @Override 
    public void setActiveEditor(IAction action, IEditorPart editorPart) { 
     this.editorPart = editorPart; 
    } 

    @Override 
    public void run(IAction action) { 
     JavaUI.getEditorInputJavaElement(editorPart.getEditorInput()); 
    } 

    @Override 
    public void selectionChanged(IAction action, ISelection selection) { 
     if (selection instanceof TextSelection) { 
      TextSelection text = (TextSelection) selection; 
      System.out.println("Text: " + text.getText()); 
     } else { 
      System.out.println(selection); 
     } 
    } 

} 

Teraz problem jest, że metoda SelectionChanged (...) jest wywoływana tylko wtedy, gdy naprawdę wybrać coś tak, że mogę skopiować/wkleić go . Ale chcę, aby uzyskać dostęp do elementów kodu, które są podświetlone tak (tu chciałbym uzyskać „IEditorPart”)

enter image description here

Niestety, nie mam pojęcia, co należy zwracać uwagę.

Odpowiedz

1

Korzystanie wejść od innych odpowiedzi, skończyło się następujące rozwiązanie:

@Override 
public void setActiveEditor(IAction action, IEditorPart editorPart) { 
    ((CompilationUnitEditor) editorPart).getViewer().addTextListener(new ITextListener() { 

     @Override 
     public void textChanged(TextEvent event) { 
      selectedText = event.getText(); 
     } 
    }); 

} 
3

Nie byłoby łatwiej wykryć aktualną pozycję karetki. Posiadanie pozycji pozwala łatwo wykryć, czy karetka jest na słowie (zdefiniować słowo tak, jak lubisz, na przykład oddzielone spacjami, identyfikator java lub wyrażenie regularne).

Nie jestem w stanie uruchomić tutaj zaćmienia, ale użyłbym klasy CaretListener w celu wykrycia ruchów karetki i tym samym wyodrębnienia słowa pod nią. Parametr CaretEvent podany jako parametr metody caretMoved będzie zawierał przesunięcie.

CaretListener może być dołączony do Adapter swojego komponentu StyledText, które można uzyskać od EditorPart (nie ma żadnych więcej informacji o tej chwili, ponieważ nie mam zaćmienie działa tutaj).

Mam nadzieję, że to pomaga.

Edycja: Some code.

final StyledText text = (StyledText)editorPart.getAdapter(Control.class); 
text.addCaretListener(new CaretListener() { 
     public void caretMoved(CaretEvent event) { 
      int offset = event.caretOffset; 
      String word = findWord(offset, text); 
      if (word.length() > 0) { 
       System.out.println("Word under caret: " + word); 
      } 
     } 
}); 

private String findWord(int offset, StyledText text) { 
    int lineIndex = text.getLineAtOffset(offset); 
    int offsetInLine = offset - text.getOffsetAtLine(lineIndex); 
    String line = text.getLine(lineIndex); 
    StringBuilder word = new StringBuilder(); 
    if (offsetInLine > 0 && offsetInLine < line.length()) { 
     for (int i = offsetInLine; i >= 0; --i) { 
      if (!Character.isSpaceChar(line.charAt(i))) { 
       word.append(line.charAt(i)); 
      } else { 
       break; 
      } 
     } 
     word = word.reverse(); 
    } 
    if (offsetInLine < line.length()) { 
     for (int i = offsetInLine; i < line.length(); ++i) { 
      if (i == offsetInLine) 
       continue; // duplicate 
      if (!Character.isSpaceChar(line.charAt(i))) { 
       word.append(line.charAt(i)); 
      } else { 
       break; 
      } 
     } 
    } 
    return word.toString(); 
} 

To jest prosta implementacja, aby uzyskać słowo pod kursorem na podstawie otaczającego go znaku spacji. W celu wykrycia poprawnych identyfikatorów Javy należy użyć bardziej wydajnej implementacji, na przykład przy użyciu Character.isJavaIdentifierStart i Character.isJavaIdentifierPart lub przy użyciu biblioteki do tego.

+0

To będzie działać Myślę jednak zdecydowanie założyć, że nie musi być lepszym rozwiązaniem. – RoflcoptrException

+0

To może zadziałać, ale zaleciłbym odradzanie tego rozwiązania, ponieważ byłby to dostęp do interfejsu API o bardzo niskim poziomie. Użytkownik powinien wchodzić w interakcje z edytorem za pośrednictwem interfejsów API JFace, takich jak przeglądarka źródła. –

+0

Edytowane w celu dodania kodu. – Alex

7

Należy to zrobić:

 ((CompilationUnitEditor) editorPart).getViewer().getSelectedRange(); 

ISourceViewer klasa ma sporo przydatnych i ciekawych metod dotyczących lokalizacji źródła i edytor. Możesz również spojrzeć na JavaSourceViewer.


EDIT

Wygląda na to, że nie dość odpowiedzieć na to pytanie. Problem polega na tym, że zdarzenia selectionChanged są wywoływane tylko wtedy, gdy długość wyboru wynosi> 0. Nie wiem, dlaczego tak się dzieje, ale w ten sposób delegaci akcji zawsze pracowali.

Jeśli chcesz otrzymywać powiadomienia o zmianie karetki, powinieneś zarejestrować selekcję zmienionego słuchacza w przeglądarce dla edytora. Zrobić coś takiego:

((CompilationUnitEditor) editorPart).getViewer() 
    .addSelectionChangedListener(mySelectionListener); 

mySelectionListener jest typu org.eclipse.jface.viewers.ISelectionChangedListener. Rejestracja w ten sposób powinna dać ci wszystkie wydarzenia, których szukasz. Uważaj, aby wyrejestrować się po zamknięciu edytora.

+0

Następnie otrzymuję punkt zwrotny. Co mam z tym zrobić? – RoflcoptrException

+0

jeśli czytasz JavaDoc, zobaczysz: "Zwraca zakres bieżącego zaznaczenia we współrzędnych dokumentu tego widza Zwraca: punkt zx jako przesunięciem i y jako długość bieżącego zaznaczenia" –

+0

Właściwie , ponownie czytając twoje pytanie i nie jestem już pewien, czego szukasz. Czy chcesz wybrany zakres? Czy chcesz element Java zawierający wybrany tekst? Czy chcesz rozwiązać problem, który jest aktualnie wybrany, aby określić jego deklarację? –

Powiązane problemy