编辑器事件

走着路睡觉大约 3 分钟

编辑器事件

本教程主要是介绍处理编辑器按键事件Editor Action 系统。示例插件editor_basicsopen in new window 主要使用了下面2个类:

EditorActionHandler介绍

示例插件editor_basicsopen in new window 演示了克隆文本插入符(caret) 。一个自定义的 Action 使用 EditorActionManager 获取到的 EditorActionHandler 对象来克隆文本插入符(caret) 。示例插件editor_basicsopen in new window 注册了一个 Editor Add Caret Action

创建"Editor Add Caret" Action

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

在示例插件editor_basicsopen in new window 中定义了 AnAction 的子类 EditorHandlerIllustrationopen in new window ,并在 plugin.xml 里进行了注册,注册代码如下:

<actions>
  <action
      id="EditorBasics.EditorHandlerIllustration"
      class="org.intellij.sdk.editor.EditorHandlerIllustration"
      text="Editor Add Caret"
      description="Adds a second caret below the existing one."
      icon="SdkIcons.Sdk_default_icon">
    <add-to-group group-id="EditorPopupMenu" anchor="first"/>
  </action>
</action>

下面分步介绍EditorHandlerIllustrationopen in new window

启用"Editor Add Caret" Action

只有同时满足下面的条件,才能启用"Editor Add Caret" Action

  • 存在一个打开的项目
  • 存在一个可用的编辑器(editor)
  • 编辑器上至少存在一个文本插入符(caret)

代码如下:

public class EditorHandlerIllustration extends AnAction {
  @Override
  public void update(@NotNull AnActionEvent event) {
    Project project = event.getProject();
    Editor editor = event.getData(CommonDataKeys.EDITOR);

    // 确定是否至少存在一个文本插入符(caret)
    boolean menuAllowed = false;
    if (editor != null && project != null) {
      // 确定 文本插入符(caret) 数组不为空
      menuAllowed = !editor.getCaretModel().getAllCarets().isEmpty();
    }
    event.getPresentation().setEnabledAndVisible(menuAllowed);
  }
}

获取正确的 EditorActionHandler

克隆文本插入符(caret) 时,可以从 EditorActionManageropen in new window 中获取正确的 EditorActionHandleropen in new window ,代码如下:

// Snippet from EditorHandlerIllustration.actionPerformed()
EditorActionManager actionManager = EditorActionManager.getInstance();
// 实际返回的的EditorActionHandler 的子类  CloneCaretActionHandler
EditorActionHandler actionHandler =
    actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW);

使用EditorActionHandler克隆文本插入符(caret)

public class EditorHandlerIllustration extends AnAction {
  @Override
  public void actionPerformed(@NotNull AnActionEvent event) {
    Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
    EditorActionManager actionManager = EditorActionManager.getInstance();
    EditorActionHandler actionHandler =
        actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW);
     //克隆文本插入符(caret)
    actionHandler.execute(editor,
        editor.getCaretModel().getPrimaryCaret(), event.getDataContext());
  }
}

创建TypedActionHandler

TypedActionHandleropen in new window 接口是处理编辑器中按键事件的基础接口。自定义并注册该接口的实现类来处理编辑器按键事件,并接收每一次按键的回调。下面进行详细介绍。

实现TypedActionHandler接口

第一步,定义TypedActionHandleropen in new window 的子类 MyTypedHandler ,重写处理编辑器按键事件的回调方法:TypedActionHandler.execute()

开发回调事件处理逻辑

在编辑器中每一次按键都会调用 MyTypedHandler.execute() 方法,代码如下:

class MyTypedHandler implements TypedActionHandler {
  @Override
  public void execute(@NotNull Editor editor,
                      char c,
                      @NotNull DataContext dataContext) {
    Document document = editor.getDocument();
    Project project = editor.getProject();
    //每一次按键都在 Document 的开头插入 ”editor_basics“ 字符串
    Runnable runnable = () -> document.insertString(0, "editor_basics\n");
    //写操作必须保证线程安全,所以使用 WriteCommandAction.runWriteCommandAction()
    WriteCommandAction.runWriteCommandAction(project, runnable);
  }
}

注册TypedActionHandler

自定义的TypedActionHandler 子类需要进行注册,以替换已存在的TypedActionHandler ,可以使用 TypedActionopen in new window 进行注册。

注册可以使用代码注册,也可以在 plugin.xml 里注册

使用代码注册

public class EditorHandlerIllustration extends AnAction {
   //静态代码将在系统启动时执行
  static {
  //获取 actionManager
    EditorActionManager actionManager = EditorActionManager.getInstance();
    TypedAction typedAction = actionManager.getTypedAction();
    // 注册TypedActionHandler
    typedAction.setupHandler(new MyTypedHandler());
  }
}

在 plugin.xml 里注册

 <extensions defaultExtensionNs="com.intellij">
    <typedHandler implementation="org.intellij.sdk.editor.MyTypedHandler"/>
  </extensions>
上次编辑于:
贡献者: zhaojingbo
Loading...