如何在Eclipse中获取选定的代码?

6

为了访问CompilationUnitEditor中选定的代码,我正在编写一个插件。因此我添加了一个贡献到上下文菜单,并使用以下代码:

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

}

现在的问题是,当我真正选择某些内容以便复制/粘贴时,方法selectionChanged(...)才会被调用。但我想访问像这样高亮显示的Code元素(这里我想获取"IEditorPart")

enter image description here

不幸的是,我不知道应该寻找什么。

3个回答

7
你应该这样做:
        ((CompilationUnitEditor) editorPart).getViewer().getSelectedRange();
ISourceViewer类有许多关于源位置和编辑器的有用和有趣的方法。您可能还想查看JavaSourceViewer

编辑

看起来我没有完全回答您的问题。问题在于只有在选择的长度大于0时才会调用selectionChanged事件。我不知道为什么会这样,但这就是操作委托始终起作用的方式。

如果您希望在插入符号更改时得到通知,应该向编辑器的viewer注册一个选择更改侦听器。像这样做:

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

mySelectionListener 是类型为 org.eclipse.jface.viewers.ISelectionChangedListener 的。以这种方式注册,应该会给你所有你正在寻找的事件。只需注意在编辑器关闭时取消注册。


然后我得到了一个点(Point)。我应该怎么处理它? - RoflcoptrException
如果您阅读JavaDoc,您将看到:“以此查看器文档的坐标返回当前选择范围。返回: 一个点,其中x为偏移量,y为当前选择的长度。” - Andrew Eisenberg
在我的Eclipse中,我可以像这样突出显示类型和方法。然后我可以按F2键获取文档。现在我想为此事件注册一个监听器。而且我只需要这个单词。对我来说已经足够了。 - RoflcoptrException
@AndrewEisenberg 但是 CompilationUnitEditor 类没有 getSourceViewer 方法? - RoflcoptrException
谢谢,有了你的帮助我成功解决了问题。这就是为什么我会给你悬赏并添加我的答案的原因。 - RoflcoptrException
显示剩余4条评论

3
检测插入符当前位置会不会更容易。有了位置,您可以轻松检测插入符是否在单词上(将单词定义为您喜欢的方式,例如用空格分隔、Java标识符或正则表达式)。
我无法在这里运行eclipse,但我会使用CaretListener类来检测插入符移动并从而提取其下方的单词。作为caretMoved方法参数给出的CaretEvent将包含偏移量。 CaretListener可附加到StyledText组件的Adapter,该组件可以从EditorPart中获取(目前没有更多信息,因为我没有在这里运行eclipse)。
希望对您有所帮助。
编辑:一些代码。
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();
}

这是一个简单的实现,可以根据空格字符来获取光标下的单词。为了检测有效的Java标识符等,应使用更健壮的实现。例如,使用Character.isJavaIdentifierStartCharacter.isJavaIdentifierPart或使用库进行此操作。

我认为那个方法可以行得通,但是我强烈认为一定有更好的选择。 - RoflcoptrException
这个方法可能可行,但我建议不要使用这种解决方案,因为这样做将访问非常低级别的API。你应该通过JFace API(例如源代码查看器)与编辑器进行交互。 - Andrew Eisenberg
谢谢,我现在就要测试一下。但是为了让它正常工作,变量text必须是final的。我已经在你的答案中进行了编辑。 - RoflcoptrException

1
使用其他答案的输入,我最终得出了以下解决方案:
@Override
public void setActiveEditor(IAction action, IEditorPart editorPart) {
    ((CompilationUnitEditor) editorPart).getViewer().addTextListener(new ITextListener() {

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

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接