1

我正在编写一个小插件来将 Eclipse 文本编辑器的插入符号位置移动到选定块的另一侧。问题是我找不到一个很好的方法来发现选择是从左到右还是从右到左。

我知道有这些选择:

  • 以某种方式使用 CarretListener。这似乎没有必要,我不想这样做。
  • 抓住底层StyledText并将选择与插入符号位置进行比较。似乎打破了抽象,因为我必须知道编辑器是如何实现的。另一个缺点是您必须使用widgetOffset2ModelOffset文本查看器上的方法来调整位置。

我不能从我的ITextEditororISelectionProvider或其他东西中获得插入符号的位置吗?

这是我的代码:

public class SwapCursorSelectionHandler extends AbstractHandler {
    public Object execute( ExecutionEvent event )
    {
        ITextEditor editor;
        try {
            editor = (ITextEditor) HandlerUtil.getActivePartChecked( event );
        } catch ( ExecutionException exc ) {
            throw new RuntimeException( exc );
        }

        ITextSelection sel = (ITextSelection) editor.getSelectionProvider().getSelection();

        // How to find out if sel is left-to-right or right-to-left?!

        editor.selectAndReveal( ... );

        return null;
    }
}

更新:似乎没有办法在不使用StyledText. 我认为这很奇怪,我考虑放置一个错误报告,建议应该将选择方向信息添加到ITextSelection. 在我这样做之前,了解一下 SO 这里的人们对这个提案的看法会很有趣。

4

2 回答 2

2

编辑:这个解决方案原来是错误的!感谢 willkil 指出这一点。


这段不是很优雅的代码是我能找到的最规范的实现方式。它使用ITextEditor.getAdapter(ITextOperationTarget.class)JFaceTextUtil。这意味着它取决于特定的编辑器实现,但至少我不必自己触摸它或弄乱widget2model方法。

public Object execute(ExecutionEvent event) {
    try {
        ITextViewer viewer = (ITextViewer)
            ((ITextEditor) HandlerUtil.getActivePartChecked(event))
                .getAdapter(ITextOperationTarget.class);
        int caretOffset = JFaceTextUtil.getOffsetForCursorLocation(viewer);
    } catch (ExecutionException exc) {
        throw new RuntimeException(exc);
    }
    return null;
}
于 2013-05-03T13:18:51.947 回答
1

获取当前光标位置的最佳方法是通过ITextViewer.getTextWidget().getCaretOffset(). IContentAssistProcessor这是一个在我正在处理的实现中打印各种文本位置的示例:

public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
    int widgetCaretOffset = viewer.getTextWidget().getCaretOffset();
    if (viewer instanceof ITextViewerExtension5) {
        ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
        System.out.println(extension.widgetOffset2ModelOffset(widgetCaretOffset));
    }
    System.out.println(JFaceTextUtil.getOffsetForCursorLocation(viewer));
    System.out.println(offset);
    System.out.println(widgetCaretOffset);
    System.out.println(viewer.getSelectedRange());
}

我将插入符号放在文档中的任意位置,然后将鼠标移动到靠近第一行的开头,然后通过各种选择触发内容助手。在我的例子中,textViewer 没有实现 ITextViewerExtension5,所以只打印了四行。上面代码的输出如下:

未选择任何内容:

6
794
794
Point {794, 0}

通过右移创建从左到右的选择(插入符号在选择的右侧闪烁):

6
794
799
Point {794, 5}

请注意,插入符号的位置是 799,等于 794 + 5。

使用 shift-left 创建的从左到右的选择(选择左侧的插入符号闪烁):

6
794
794
Point {794, 5}

请注意,插入符号位置等于选择偏移量。

另请注意,尽管与此问题无关,但offset参数 inIContentAssistProcessor. computeCompletionProposals()始终是选择的偏移量,而不是插入符号。

如果您有 anITextEditor而不是 an ITextViewer,则可以ITextViewer通过该方法从该问题的另一个答案和另一个问题的答案获得

ITextEditor editor;
ITextOperationTarget target = (ITextOperationTarget) editor.getAdapter(ITextOperationTarget.class);
if (target instanceof ITextViewer) {
    ITextViewer viewer = (ITextViewer) target;

    int widgetCaretOffset = viewer.getTextWidget().getCaretOffset();
    if (viewer instanceof ITextViewerExtension5) {
        ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
        System.out.println(extension.widgetOffset2ModelOffset(widgetCaretOffset));
    }
    System.out.println(JFaceTextUtil.getOffsetForCursorLocation(viewer));
    System.out.println(offset);
    System.out.println(widgetCaretOffset);
    System.out.println(viewer.getSelectedRange());
}
于 2019-03-01T01:51:20.533 回答