文本编辑

走着路睡觉大约 4 分钟

文本编辑

该教程包括以下内容:

  • 获取 文本插入符(caret) 相关信息

  • 使用 文本插入符(caret) 提供的信息替换 选择的文本

介绍

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

运行示例插件editor_basicsopen in new window ,然后选中一部分文本,在编辑器中会弹出相关操作对话框,如下图:

创建Action

editor_basicsopen in new window 示例中的EditorIllustrationActionopen in new window ,我们可以从Action中获取到编辑器。

public class EditorAreaIllustration extends AnAction {
  @Override
  public void actionPerformed(@NotNull final AnActionEvent e) {
    // 在Action中获取编辑器.
    final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
  }
}

然后在 plugin.xml 里注册 Action,如下:

<action
    id="EditorBasics.EditorIllustrationAction"
    class="org.intellij.sdk.editor.EditorIllustrationAction"
    text="Editor Replace Text"
    description="Replaces selected text with 'Replacement'."
    icon="SdkIcons.Sdk_default_icon">
    <!--    该Action添加到Edit组里-->
  <add-to-group group-id="EditorPopupMenu" anchor="first"/>
</action>

定义Action的适用范围

EditorIllustrationActionopen in new window 中重写 update() 方法可以定义它的可用范围。update() 方法介绍可查看文档:继承AnAction.update()方法

如果要启用该Action ,至少需要满足以下条件:

代码如下:

public class EditorIllustrationAction extends AnAction {
  @Override
  public void update(@NotNull AnActionEvent event) {
    // 获取 Project对象
    Project project = event.getProject();
    //获取编辑器实例
    Editor editor = event.getData(CommonDataKeys.EDITOR);
    // 当存在 Project对象 、编辑器实例,并选中文本的时候,启用该Action
    event.getPresentation().setEnabledAndVisible(project != null
        && editor != null && editor.getSelectionModel().hasSelection());
  }
}

注意:还能从编辑器(Editor) 中获取到如下信息:

CaretModelopen in new window,

FoldingModelopen in new window,

IndentsModelopen in new window,

ScrollingModelopen in new window,

SoftWrapModelopen in new window

替换文本

如果满足了上述Action 启用条件,将会执行 EditorIllustrationAction.actionPerformed() 方法。替换文本可以分为以下几步:

  • 获得Document的访问权限。

  • 获得选择文本的位置

  • 保证线程安全的情况下完成替换

必须先获取 Document 对象实例,然后才能修改选择的文本。可以从 Editor(编辑器) 对象中获取Document 对象实例。在编辑器中打开的文件,它的内容会被加载到内存中,封装为 Document 对象实例,替换文本的时候需要使用该 Document 对象实例。

CaretModel中获取到的文本插入符(caret) 对象可以提供 文本插入符(caret) 的相关信息。选择内容是通过偏移量来计算的,偏移量是从文档开头到文本插入符(caret) 位置的字符数。

DocumentreplaceString() 方法可以执行文本替换。为了保证文本替换不出错,Document 对象必须加锁,在一个write action里执行修改。可以在线程规则 文档了解同步执行。

示例如下,需要注意2点:

  • 为了保证线程安全,修改需要在 write action 里执行

  • 替换完成后,因为已选择文本已被替换,所以需要移除它的选择状态

public class EditorIllustrationAction extends AnAction {
  @Override
  public void actionPerformed(@NotNull AnActionEvent event) {
    // 获取修改所必须的对象
    Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
    Project project = event.getRequiredData(CommonDataKeys.PROJECT);
    Document document = editor.getDocument();

    // 从文本插入符(caret) 中获取已选择文本的相关信息
    Caret primaryCaret = editor.getCaretModel().getPrimaryCaret();
    int start = primaryCaret.getSelectionStart();
    int end = primaryCaret.getSelectionEnd();

    // 替换字符串
    // 必须在write action 里执行.
    WriteCommandAction.runWriteCommandAction(project, () ->
        document.replaceString(start, end, "editor_basics")
    );
    // 因为已选择文本已被替换,所以移除它的选择状态 
    primaryCaret.removeSelection();
  }
}
上次编辑于:
贡献者: zhaojingbo
Loading...