编辑器坐标系:位置和偏移

走着路睡觉大约 6 分钟

编辑器坐标系:位置和偏移

在上一个文本编辑 教程中,展示了如何从Document 对象中获取到 文本插入符(caret) 相关信息。这个示例展示如何使用 文本插入符(caret) 替换 选择的文本

每个文本插入符(caret) 都包含一些描述它位置的信息。这个教程将带你了解如何从编辑器中获取文本插入符(caret) ,及如何从文本插入符(caret) 中获取信息。

简介

看这部分内容之前,需要了解如何创建和注册Actions,可以查看Action教程

该教程中,使用了示例插件editor_basicsopen in new window 来演示如何获取文本插入符(caret)。示例插件editor_basicsopen in new window 中注册了一个 Caret Position Action。

Caret Position Action 的源码是editor_basicsopen in new window 示例中的EditorIllustrationActionopen in new window 类,主要看这个类的 EditorAreaIllustration.actionPerformed() 方法,代码如下:

public class EditorAreaIllustration extends AnAction {

  public void actionPerformed(@NotNull AnActionEvent event) {
    //获取 编辑器 对象
    Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
     //获取 文本插入符(caret) 对象
    CaretModel caretModel = editor.getCaretModel();

    // 获取 primary 文本插入符对象
    Caret primaryCaret = caretModel.getPrimaryCaret();
    //从 文本插入符(caret) 对象 中获取相关信息
    //视觉位置 详见下文
    LogicalPosition logicalPos = primaryCaret.getLogicalPosition();
    //视觉位置 详见下文
    VisualPosition visualPos = primaryCaret.getVisualPosition();
    int caretOffset = primaryCaret.getOffset();

    // 拼接并显示位置信息
    String report = logicalPos.toString() + "\n" +
        visualPos.toString() + "\n" +
        "Offset: " + caretOffset;
    Messages.showInfoMessage(report, "Caret Parameters Inside The Editor");
  }

}

下面将分步骤介绍上述代码:

获取文本插入符位置

CaretModelopen in new window 对象封装了 文本插入符(caret) 的信息,示例代码如下:

public class EditorAreaIllustration extends AnAction {
  @Override
  public void actionPerformed(@NotNull AnActionEvent event) {
    //获取 编辑器 对象
    Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
     //获取 文本插入符(caret) 对象
    CaretModel caretModel = editor.getCaretModel();
  }
}

编辑器坐标系统

打开一个Document 时,编辑器会分配一个从0开始 的坐标系。Document 中的第1行和每一行的第1个字符坐标都是从0开始。

每一个字符都会分配一个偏移量对象Offsetopen in new window ,偏移量对象封装了从Document 第一个字符到当前位置的字符数量。

逻辑位置(LogicalPositionopen in new window )坐标系统包含了当前字符所在行的行号,以及在当前行的位置。注意:逻辑位置坐标系是从0开始的,但是在编辑器的UI上显示的是从1开始

从编辑器(Editor)还可以通过 HintManager.getHintPosition()open in new window 获取代码补全 提示框位置。

还可以获取到编辑器中显示的自定义视觉元素位置,它们被封装为 Inlayopen in new window 对象。

下面的图表显示了逻辑位置坐标系。下图文本插入符(caret) 选中的红框中的 "s" 的的行号=1 ,列号=9,偏移量=28(注意:行尾的换行符计数,而换行符后的空格不计数),可以从 Offsetsopen in new window 对象中获取到更多的位置信息。

在同一个编辑器中如果只有一个文本插入符(caret),那就是 Primary Caret 对象。 可以在 多个文本插入符 文档中查看多文本插入符 相关内容。

文本插入符逻辑位置

文本插入符的逻辑位置从0开始计数,逻辑位置信息被封装为LogicalPositionopen in new window 对象。

代码折叠open in new window软换行open in new window不会 修改字符的逻辑位置。

文本插入符视觉位置

文本插入符的视觉位置从0开始计数,视觉位置信息被封装为VisualPositionopen in new window 对象。

和逻辑位置不同,代码折叠open in new window软换行open in new window都会 修改字符视觉位置。

如下图:代码折叠后,文本插入符(caret) 的逻辑位置(LogicalPosition)没有改变,但是视觉位置(VisualPosition)第6行在视觉上变成了第2行

如下图:软换行后,文本插入符(caret) 的逻辑位置(LogicalPosition)没有改变,但是视觉位置(VisualPosition)第5行在视觉上变成了第6行

文本插入符(caret)( Caretopen in new window) 对象里获取逻辑位置(LogicalPosition)和视觉位置(VisualPosition)对象,代码如下:

public class EditorAreaIllustration extends AnAction {
  @Override
  public void actionPerformed(@NotNull AnActionEvent event) {
    //获取 编辑器 和 文本插入符(caret) 对象
    Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
    CaretModel caretModel = editor.getCaretModel();
    Caret primaryCaret = caretModel.getPrimaryCaret();
    //逻辑位置
    LogicalPosition logicalPos = primaryCaret.getLogicalPosition();
    //视觉位置
    VisualPosition visualPos = primaryCaret.getVisualPosition();
  }
}

文本插入符列位置

列位置指的是从当前行的开头当前插入符 的位置。从0开始计数。注意:注意:列位置从0开始计算的,但是在编辑器的UI上显示的是从1开始的

列位置包含以下信息:

  • 空格,例如 Tabs。Tab占用的列数 等于 Tab设置的占用字符数

  • 文本插入符(caret) 选中的文本

文本插入符倾向(lean)-(还没明白有什么用...)

文本插入符(caret) 位于2个字符中间时,文本插入符(caret) 可能会关联到它的上一个字符,也可能会关联到它的下一个字符。这个关系很重要,因为视觉位置(VisualPosition)和逻辑位置(LogicalPosition) 并不是完全相等的。

在逻辑位置(LogicalPositionopen in new window )类中,如果 文本插入符(caret) 跟它的下一个字符有关联性,它就是 Leans Forward 。如果不是Leans Forward文本插入符(caret) 就跟它的前一个字符有关联性。

在视觉位置(VisualPositionopen in new window )类中,如果 文本插入符(caret) 跟它的下一个字符有关联性,它就是 Leans Right 。如果不是Leans Right文本插入符(caret) 就跟它的前一个字符有关联性。

文本插入符偏移量(Offset)

文本插入符的偏移量(Offset)指的是从 Document 开始到文本插入符位置的字符数。偏移量(Offset)是通过逻辑位置(LogicalPosition)计算的,偏移量(Offset)包括以下信息:

  • Document 第一个字符

  • 空白字符,包括换行符和制表符(Tab)

  • Settings/Preferences | Editor | General | Virtual Space 里配置after end-of-line的字符

  • 文本插入符(caret) 选中的字符

下图示例中,文本插入符(caret) 选中的第2行(逻辑位置从0开始计数,逻辑位置是第1行时,在ui上显示为第2行) 第一个 "/" ,显示的偏移量=22,是因为第1行的换行符也占用了一个字符。

上次编辑于:
贡献者: zhaojingbo
Loading...