Reputation:
For my plugin I'm trying to access the selected code in a CompilationUnitEditor. Therefore I added a contribution to the context menu and use following code:
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);
}
}
}
Now the problem is that the method selectionChanged(...) is only called when i really select something so that I could copy/paste it. But I want to access the Code elements that are highlighted like this (here I would like to get the "IEditorPart")
Unfortunately, I have no idea what I should look for.
Upvotes: 6
Views: 2432
Reputation:
Using the inputs from the other answers, I ended up with the following solution:
@Override
public void setActiveEditor(IAction action, IEditorPart editorPart) {
((CompilationUnitEditor) editorPart).getViewer().addTextListener(new ITextListener() {
@Override
public void textChanged(TextEvent event) {
selectedText = event.getText();
}
});
}
Upvotes: 1
Reputation: 25613
Wouldn't it be easier to detect the caret current position. Having the position let you easily detect if the caret is on a word (define word as you like, for example space-separated, java identifier, or with a regular expression).
I'm not able to run eclipse here, but I would use the CaretListener class in order to detect caret movements and thus extracting the word under it. The CaretEvent
given as parameter to the caretMoved
method will contain the offset.
The CaretListener
can be attached to the Adapter
of your StyledText
component, that you can get from your EditorPart
(don't have any more info for the moment, as I don't have eclipse running here).
Hope it helps.
Edit: 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();
}
This is simple implementation to get the word under the cursor based on space character surrounding it. A more robust implementation should be used in order to detect valid Java identifiers etc. For example using Character.isJavaIdentifierStart
and Character.isJavaIdentifierPart
or using a library for this.
Upvotes: 3
Reputation: 28737
You should do this:
((CompilationUnitEditor) editorPart).getViewer().getSelectedRange();
The ISourceViewer
class has quite a few useful and interesting methods regarding source locations and the editor. You may also want to look at JavaSourceViewer
.
EDIT
It looks like I didn't quite answer your question. The problem is that selectionChanged events are only called when the length of the selection is > 0. I don't know why this is the case, but that is the way action delegates have always worked.
If you want to be notified whenever the caret changes, you should register a selection changed listener with the viewer for the editor. Do something like this:
((CompilationUnitEditor) editorPart).getViewer()
.addSelectionChangedListener(mySelectionListener);
mySelectionListener
is of type org.eclipse.jface.viewers.ISelectionChangedListener
. Registering in this way, should give you all the events you are looking for. Just be careful to unregister when the editor closes.
Upvotes: 7