如何在Eclipse中获取所选代码?

时间:2012-05-04 17:40:20

标签: java eclipse eclipse-plugin

对于我的插件,我正在尝试访问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 个答案:

答案 0 :(得分:7)

你应该这样做:

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

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


修改

看起来我没有完全回答你的问题。问题是只有当选择的长度> 1时才调用selectionChanged事件。 0.我不知道为什么会这样,但这就是行动代表一直以来的工作方式。

如果您希望在插入符更改时收到通知,则应该使用编辑器的查看器注册选择更改的侦听器。做这样的事情:

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

mySelectionListener的类型为org.eclipse.jface.viewers.ISelectionChangedListener。以这种方式注册,应该为您提供您正在寻找的所有活动。编辑关闭时,请注意取消注册。

答案 1 :(得分: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或使用库来实现此目的。

答案 2 :(得分:1)

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

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

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

}