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

在此处输入图像描述

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

4

3 回答 3

7

你应该做这个:

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

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


编辑

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

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

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

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

于 2012-05-04T20:12:03.543 回答
3

检测插入符号当前位置会不会更容易。拥有该位置可以让您轻松检测插入符号是否位于单词上(根据需要定义单词,例如空格分隔、java 标识符或使用正则表达式)。

我不能在这里运行 eclipse,但我会使用CaretListener类来检测插入符号的移动,从而提取它下面的单词。CaretEvent给定的方法参数将caretMoved包含偏移量。

CaretListener可以附加到Adapter您的组件StyledText,您可以从您的组件中获取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或使用库。

于 2012-05-04T19:31:18.043 回答
1

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

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

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

}
于 2012-05-11T21:02:33.373 回答