【问题标题】:How can I get the selected code in Eclipse?如何在 Eclipse 中获取选定的代码?
【发布时间】:2012-05-04 17:40:20
【问题描述】:

对于我的插件,我正在尝试访问 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(...) 仅在我真正选择某些内容时才被调用,以便我可以复制/粘贴它。但我想访问像这样突出显示的代码元素(这里我想获得“IEditorPart”)

很遗憾,我不知道我应该寻找什么。

【问题讨论】:

    标签: java eclipse eclipse-plugin


    【解决方案1】:

    你应该这样做:

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

    ISourceViewer 类有很多关于源位置和编辑器的有用和有趣的方法。您可能还想查看JavaSourceViewer


    编辑

    看来我没有完全回答你的问题。问题是 selectionChanged 事件仅在选择的长度大于 0 时才被调用。我不知道为什么会这样,但动作委托一直是这样工作的。

    如果您想在插入符号更改时收到通知,您应该向编辑器的查看器注册一个选择更改侦听器。做这样的事情:

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

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

    【讨论】:

    • 然后我得到一个点。我该怎么办?
    • 如果您阅读 JavaDoc,您将看到:“返回当前选择的范围,以该查看器文档的坐标表示。返回:一个 Point,其中 x 作为偏移量,y 作为当前选择的长度选择”
    • 实际上,重新阅读您的问题,我不再确定您在寻找什么。您想要选定的范围吗?您想要包含所选文本的 Java 元素吗?还是要解决当前选择的事物以确定其声明?
    • 我认为他想检索插入符号下的单词或 Java 标识符,但实际上并没有选择文本。我还假设他希望在这样的更改上触发一个事件(ala selectionChanged()),这就是我提出CaretListener的原因。
    • 在我的 Eclipse 中,我可以突出显示类似的类型和方法。然后我可以按 F2 来获取文档。现在我想为这个事件注册一个监听器。我只想要这个词。这对我来说已经足够了。
    【解决方案2】:

    检测插入符号的当前位置不是更容易吗?有了这个位置,您可以轻松检测插入符号是否在一个单词上(根据需要定义单词,例如空格分隔、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 或为此使用库。

    【讨论】:

    • 我认为这可行,但我强烈认为必须有更好的选择。
    • 这可能可行,但我建议不要使用此解决方案,因为这样做会访问非常低级的 API。您应该通过 JFace API(例如源查看器)与编辑器进行交互。
    • 谢谢,我现在就去测试一下。然而,要让它工作,变量文本必须是最终的。我在你的回答中编辑了它。
    【解决方案3】:

    使用其他答案的输入,我最终得到了以下解决方案:

    @Override
    public void setActiveEditor(IAction action, IEditorPart editorPart) {
        ((CompilationUnitEditor) editorPart).getViewer().addTextListener(new ITextListener() {
    
            @Override
            public void textChanged(TextEvent event) {
                selectedText = event.getText();
            }
        });
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-22
      • 1970-01-01
      • 1970-01-01
      • 2016-10-11
      • 1970-01-01
      • 2023-04-05
      • 2022-08-19
      相关资源
      最近更新 更多