赞
踩
idea中可操作的文件一种是Document,另一种是PSI,其中Editor组件就是操作Document的载体,在程序层面Editor组件实现为一个名为Editor的对象称为编辑器。Editor可以实现文件打开、定位文档等功能。本章将通过一个例子来完成以下功能:1、使用文本;2、编辑坐标系;3、编辑器事件;4、文本选择;5、文本编辑。完成后的效果如下图所示:
其底层实现就是Swing的JTextArea,IntelliJ 平台给编辑器组件增加了:语法高亮支持、代码完成、代码折叠等功能。
Editor组件在初始化进可以指定以下设置:
还可以通过EditorCustomization实现定制化:
一个示例程序如下:
- PsiFile psiFile = PsiDocumentManager.getInstance(project)
- .getPsiFile(editor.getDocument());
- PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset());
-
- PsiExpressionCodeFragment code =
- JavaCodeFragmentFactory.getInstance(project)
- .createExpressionCodeFragment("", element, null, true);
-
- Document document =
- PsiDocumentManager.getInstance(project).getDocument(code);
-
- EditorTextField myInput =
- new EditorTextField(document, project, JavaFileType.INSTANCE);
复写update()方法
- public void update(@NotNull final AnActionEvent e) {
- // 得到当前打开的project
- final Project project = e.getProject();
- //也可以用这行代码代替:FileEditorManager.getInstance(project).getSelectedTextEditor()
- final Editor editor = e.getData(CommonDataKeys.EDITOR);
- // 设置菜单的可见性
- e.getPresentation().setEnabledAndVisible(
- project != null && editor != null && editor.getSelectionModel().hasSelection()
- );
- }
上述代码中可能过以下两种方式取得Editor中的数据模型DataContext:
Editor可选择的数据模型:CaretModel、FoldingModel、IndentsModel、ScrollingModel、SoftWrapModel、SelectionModel
复写actionPerformed()方法
- @Override
- public void actionPerformed(@NotNull final AnActionEvent e) {
- final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
- final Project project = e.getRequiredData(CommonDataKeys.PROJECT);
- final Document document = editor.getDocument();
-
- // 获取选择信息,Caret是一种文本表示方法
- Caret primaryCaret = editor.getCaretModel().getPrimaryCaret();
- int start = primaryCaret.getSelectionStart();
- int end = primaryCaret.getSelectionEnd();
-
- // 替换鼠标选择的文本内容为editor_basics
- WriteCommandAction.runWriteCommandAction(project, () ->
- document.replaceString(start, end, "editor_basics")
- );
- // 移除选择操作
- primaryCaret.removeSelection();
- }
- <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">
- <add-to-group group-id="EditorPopupMenu" anchor="first"/>
- </action>
最后runide,打开一个文件,鼠标选择文本|右键|Editor Replace Text,会把选择的文本替换为editor_basics。
在系统底层,如果想操作文档中的文本需要知识其坐标位置。坐标系统在idea中有一些比较复杂的逻辑,坐标是当前鼠标插入的位置(即鼠标闪烁处)具体分为:
Document
开头到插入符号位置的字符数,需要注意换行符算1个字符,而tab一般为4字符,从1开始计数;update()方法参考EditorIllustrationAction.java类的写法
- @Override
- public void actionPerformed(@NotNull final AnActionEvent e) {
- final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
- final CaretModel caretModel = editor.getCaretModel();
- final Caret primaryCaret = caretModel.getPrimaryCaret();
-
- // 得到当前鼠标光标的坐标信息
- 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");
- }
- <action id="EditorBasics.LogicalPositionIllustration"
- class="org.intellij.sdk.editor.EditorAreaIllustration"
- text="Caret Position"
- description="Reports information about the caret position."
- icon="SdkIcons.Sdk_default_icon">
- <keyboard-shortcut keymap="$default" first-keystroke="control alt G"/>
- <add-to-group group-id="EditorPopupMenu" anchor="first"/>
- </action>
最后runide,打开一个文件,鼠标放在文本的任意位置|右键|Caret Position,如下:
本例中实现的功能是任意一次键盘事件都会在文档开头插入一个固定的字符串,详细可参考EditorActionHandler 和 TypedActionHandler 之两个实现。
- public class EditorHandlerIllustration extends AnAction {
-
- /**
- * Clones a new caret at a higher Logical Position line number.
- */
- @Override
- public void actionPerformed(@NotNull final AnActionEvent e) {
- // Editor is known to exist from update, so it's not null
- final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
- // Get the action manager in order to get the necessary action handler...
- final EditorActionManager actionManager = EditorActionManager.getInstance();
- // Get the action handler registered to clone carets
- final EditorActionHandler actionHandler =
- actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW);
- // Clone one caret below the active caret
- actionHandler.execute(editor, editor.getCaretModel().getPrimaryCaret(), e.getDataContext());
- }
-
-
- @Override
- public void update(@NotNull final AnActionEvent e) {
- final Project project = e.getProject();
- final Editor editor = e.getData(CommonDataKeys.EDITOR);
- // Make sure at least one caret is available
- boolean menuAllowed = false;
- if (editor != null && project != null) {
- // Ensure the list of carets in the editor is not empty
- menuAllowed = !editor.getCaretModel().getAllCarets().isEmpty();
- }
- e.getPresentation().setEnabledAndVisible(menuAllowed);
- }
-
- }
需要注意上述代码.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW); 中IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW的描述。在一个editor中有很多处理器,这些全是全局性的。
- <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>
- public class MyTypedHandler extends TypedHandlerDelegate {
-
- @NotNull
- @Override
- public Result charTyped(char c, @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
- // Get the document and project
- final Document document = editor.getDocument();
- // Construct the runnable to substitute the string at offset 0 in the document
- Runnable runnable = () -> document.insertString(0, "editor_basics\n");
- // Make the document change in the context of a write action.
- WriteCommandAction.runWriteCommandAction(project, runnable);
- return Result.STOP;
- }
-
- }
实现方式有两种,两种二选一:
- <extensions defaultExtensionNs="com.intellij">
- <typedHandler implementation="org.intellij.sdk.editor.MyTypedHandler"/>
- </extensions>
- public class EditorHandlerIllustration extends AnAction {
- static {
- EditorActionManager actionManager = EditorActionManager.getInstance();
- TypedAction typedAction = actionManager.getTypedAction();
- typedAction.setupHandler(new MyTypedHandler());
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。