[md] highlighting

This commit is contained in:
Anna Bulenkova 2015-01-27 11:01:53 +01:00
parent 94a94add85
commit 9a8fb93810

View File

@ -43,11 +43,13 @@ it will be available from the context menu when the focus is located in the edit
To determine conditions by which the action will be visible and available for being executed we need to override it's To determine conditions by which the action will be visible and available for being executed we need to override it's
*public void update(final AnActionEvent e)* method. *public void update(final AnActionEvent e)* method.
public class EditorIllustration extends AnAction { ```java
@Override public class EditorIllustration extends AnAction {
public void update(final AnActionEvent e) { @Override
} public void update(final AnActionEvent e) {
} }
}
```
If we want to work with a selected part of the text, it's reasonable to make the action available only when the following requirements are met: If we want to work with a selected part of the text, it's reasonable to make the action available only when the following requirements are met:
@ -61,16 +63,18 @@ Further steps will show how to check these conditions through obtaining instance
A reference to an instance of the Editor can be obtained by calling ```CommonDataKeys.EDITOR```, A reference to an instance of the Editor can be obtained by calling ```CommonDataKeys.EDITOR```,
obtaining a project reference is performed the same way ```CommonDataKeys.PROJECT```. obtaining a project reference is performed the same way ```CommonDataKeys.PROJECT```.
public class EditorIllustration extends AnAction { ```java
@Override public class EditorIllustration extends AnAction {
public void update(final AnActionEvent e) { @Override
//Get required data keys public void update(final AnActionEvent e) {
final Project project = e.getData(CommonDataKeys.PROJECT); //Get required data keys
final Editor editor = e.getData(CommonDataKeys.EDITOR); final Project project = e.getData(CommonDataKeys.PROJECT);
//Set visibility only in case of existing project and editor final Editor editor = e.getData(CommonDataKeys.EDITOR);
e.getPresentation().setVisible((project != null && editor != null)); //Set visibility only in case of existing project and editor
} e.getPresentation().setVisible((project != null && editor != null));
} }
}
```
------------------ ------------------
@ -90,17 +94,19 @@ After making sure we have a project open and an instance of the Editor we need t
[SelectionModel] () got from the Editor allows to do it by calling it's ```hasSelection()``` method. [SelectionModel] () got from the Editor allows to do it by calling it's ```hasSelection()``` method.
Here's how our ```update(final AnActionEvent e)``` method should look like at the end: Here's how our ```update(final AnActionEvent e)``` method should look like at the end:
public class EditorIllustration extends AnAction { ```java
@Override public class EditorIllustration extends AnAction {
public void update(final AnActionEvent e) { @Override
//Get required data keys public void update(final AnActionEvent e) {
final Project project = e.getData(CommonDataKeys.PROJECT); //Get required data keys
final Editor editor = e.getData(CommonDataKeys.EDITOR); final Project project = e.getData(CommonDataKeys.PROJECT);
//Set visibility only in case of existing project and editor and if some text in the editor is selected final Editor editor = e.getData(CommonDataKeys.EDITOR);
e.getPresentation().setVisible((project != null && editor != null //Set visibility only in case of existing project and editor and if some text in the editor is selected
&& editor.getSelectionModel().hasSelection())); e.getPresentation().setVisible((project != null && editor != null
} && editor.getSelectionModel().hasSelection()));
} }
}
```
------------ ------------
@ -123,15 +129,17 @@ package and include:
The action is visible and available now. In order to make it do something we need to override it's The action is visible and available now. In order to make it do something we need to override it's
```public void actionPerformed(final AnActionEvent anActionEvent)``` method. ```public void actionPerformed(final AnActionEvent anActionEvent)``` method.
public class EditorIllustration extends AnAction { ```java
@Override public class EditorIllustration extends AnAction {
public void update(final AnActionEvent e) { @Override
//code here public void update(final AnActionEvent e) {
} //code here
@Override
public void actionPerformed(final AnActionEvent anActionEvent) {
}
} }
@Override
public void actionPerformed(final AnActionEvent anActionEvent) {
}
}
```
To modify the text an instance of the To modify the text an instance of the
[Document] (https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/editor/Document.java) [Document] (https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/editor/Document.java)
@ -139,17 +147,19 @@ needs to be accessed. Document represents the contents of a text file loaded int
The instance of a Document will be use later when a text replacement is performed. The instance of a Document will be use later when a text replacement is performed.
We also need to figure out where the selected part of the text is located. We also need to figure out where the selected part of the text is located.
@Override ```java
public void actionPerformed(final AnActionEvent anActionEvent) { @Override
//Get all the required data from data keys public void actionPerformed(final AnActionEvent anActionEvent) {
final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); //Get all the required data from data keys
final Project project = anActionEvent.getRequiredData(CommonDataKeys.PROJECT); final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR);
//Access document, caret, and selection final Project project = anActionEvent.getRequiredData(CommonDataKeys.PROJECT);
final Document document = editor.getDocument(); //Access document, caret, and selection
final SelectionModel selectionModel = editor.getSelectionModel(); final Document document = editor.getDocument();
final int start = selectionModel.getSelectionStart(); final SelectionModel selectionModel = editor.getSelectionModel();
final int end = selectionModel.getSelectionEnd(); final int start = selectionModel.getSelectionStart();
} final int end = selectionModel.getSelectionEnd();
}
```
##Modifying text ##Modifying text
Generally replacement can be done by calling Generally replacement can be done by calling
@ -160,28 +170,30 @@ See
[Threading Issues](https://confluence.jetbrains.com/display/IDEADEV/IntelliJ+IDEA+Architectural+Overview#IntelliJIDEAArchitecturalOverview-Threading) [Threading Issues](https://confluence.jetbrains.com/display/IDEADEV/IntelliJ+IDEA+Architectural+Overview#IntelliJIDEAArchitecturalOverview-Threading)
section to know more about synchronization issues and changes safety in IntelliJ. section to know more about synchronization issues and changes safety in IntelliJ.
@Override ```java
public void actionPerformed(final AnActionEvent anActionEvent) { @Override
//Get all the required data from data keys public void actionPerformed(final AnActionEvent anActionEvent) {
final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); //Get all the required data from data keys
final Project project = anActionEvent.getRequiredData(CommonDataKeys.PROJECT); final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR);
//Access document, caret, and selection final Project project = anActionEvent.getRequiredData(CommonDataKeys.PROJECT);
final Document document = editor.getDocument(); //Access document, caret, and selection
final SelectionModel selectionModel = editor.getSelectionModel(); final Document document = editor.getDocument();
final SelectionModel selectionModel = editor.getSelectionModel();
final int start = selectionModel.getSelectionStart(); final int start = selectionModel.getSelectionStart();
final int end = selectionModel.getSelectionEnd(); final int end = selectionModel.getSelectionEnd();
//New instance of Runnable to make a replacement //New instance of Runnable to make a replacement
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
document.replaceString(start, end, "Replacement"); document.replaceString(start, end, "Replacement");
} }
}; };
//Making the replacement //Making the replacement
WriteCommandAction.runWriteCommandAction(project, runnable); WriteCommandAction.runWriteCommandAction(project, runnable);
selectionModel.removeSelection(); selectionModel.removeSelection();
} }
```
----------- -----------
@ -206,37 +218,39 @@ Access to the Editor is performed through an action.
##Accessing caret positions ##Accessing caret positions
To get an access to caret positions an instance of CaretModel should be obtained. To get an access to caret positions an instance of CaretModel should be obtained.
public class EditorAreaIllustration extends AnAction { ```java
@Override public class EditorAreaIllustration extends AnAction {
public void actionPerformed(AnActionEvent anActionEvent) { @Override
final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); public void actionPerformed(AnActionEvent anActionEvent) {
CaretModel caretModel = editor.getCaretModel(); final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR);
} CaretModel caretModel = editor.getCaretModel();
@Override
public void update(AnActionEvent e) {
//...
}
} }
@Override
public void update(AnActionEvent e) {
//...
}
}
```
##Logical position ##Logical position
[LogicalPosition.java] (https://github.com/JetBrains/intellij-community/blob/master/platform/editor-ui-api/src/com/intellij/openapi/editor/LogicalPosition.java) [LogicalPosition.java] (https://github.com/JetBrains/intellij-community/blob/master/platform/editor-ui-api/src/com/intellij/openapi/editor/LogicalPosition.java)
represents a line and a column of the current logical position of the caret. Logical positions ignore folding - represents a line and a column of the current logical position of the caret. Logical positions ignore folding -
for example, if the top 10 lines of the document are folded, the 10th line in the document will have the line number 10 in its logical position. for example, if the top 10 lines of the document are folded, the 10th line in the document will have the line number 10 in its logical position.
public class EditorAreaIllustration extends AnAction { ```java
@Override public class EditorAreaIllustration extends AnAction {
public void actionPerformed(AnActionEvent anActionEvent) { @Override
final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); public void actionPerformed(AnActionEvent anActionEvent) {
CaretModel caretModel = editor.getCaretModel(); final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR);
LogicalPosition logicalPosition = caretModel.getLogicalPosition(); CaretModel caretModel = editor.getCaretModel();
} LogicalPosition logicalPosition = caretModel.getLogicalPosition();
}
@Override @Override
public void update(AnActionEvent e) { public void update(AnActionEvent e) {
//... //...
} }
} }
```
Logical position may store additional parameters that define its mapping to Logical position may store additional parameters that define its mapping to
[VisualPosition.java] (https://github.com/JetBrains/intellij-community/blob/master/platform/editor-ui-api/src/com/intellij/openapi/editor/VisualPosition.java). [VisualPosition.java] (https://github.com/JetBrains/intellij-community/blob/master/platform/editor-ui-api/src/com/intellij/openapi/editor/VisualPosition.java).
@ -250,62 +264,65 @@ represent a visual position and may very from the corresponding logical position
Visual positions take folding into account - for example, Visual positions take folding into account - for example,
if the top 10 lines of the document are folded, the 10th line in the document will have the line number 1 in its visual position. if the top 10 lines of the document are folded, the 10th line in the document will have the line number 1 in its visual position.
public class EditorAreaIllustration extends AnAction { ```java
@Override public class EditorAreaIllustration extends AnAction {
public void actionPerformed(AnActionEvent anActionEvent) { @Override
final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); public void actionPerformed(AnActionEvent anActionEvent) {
CaretModel caretModel = editor.getCaretModel(); final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR);
LogicalPosition logicalPosition = caretModel.getLogicalPosition(); CaretModel caretModel = editor.getCaretModel();
VisualPosition visualPosition = caretModel.getVisualPosition(); LogicalPosition logicalPosition = caretModel.getLogicalPosition();
} VisualPosition visualPosition = caretModel.getVisualPosition();
}
@Override @Override
public void update(AnActionEvent e) { public void update(AnActionEvent e) {
//... //...
} }
} }
```
##Offset ##Offset
An absolute offset for a given caret position is accessible through CaretModel as well An absolute offset for a given caret position is accessible through CaretModel as well
public class EditorAreaIllustration extends AnAction { ```java
@Override public class EditorAreaIllustration extends AnAction {
public void actionPerformed(AnActionEvent anActionEvent) { @Override
final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); public void actionPerformed(AnActionEvent anActionEvent) {
CaretModel caretModel = editor.getCaretModel(); final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR);
LogicalPosition logicalPosition = caretModel.getLogicalPosition(); CaretModel caretModel = editor.getCaretModel();
VisualPosition visualPosition = caretModel.getVisualPosition(); LogicalPosition logicalPosition = caretModel.getLogicalPosition();
int offset = caretModel.getOffset(); VisualPosition visualPosition = caretModel.getVisualPosition();
} int offset = caretModel.getOffset();
@Override
public void update(AnActionEvent e) {
//...
}
} }
@Override
public void update(AnActionEvent e) {
//...
}
}
```
##Displaying position values ##Displaying position values
To display the actual values of logical anf visual positions we add an To display the actual values of logical anf visual positions we add an
```Messages.showInfoMessage()``` call that will show them in form of notification after the action is performed. ```Messages.showInfoMessage()``` call that will show them in form of notification after the action is performed.
public class EditorAreaIllustration extends AnAction { ```java
@Override public class EditorAreaIllustration extends AnAction {
public void actionPerformed(AnActionEvent anActionEvent) { @Override
final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); public void actionPerformed(AnActionEvent anActionEvent) {
CaretModel caretModel = editor.getCaretModel(); final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR);
LogicalPosition logicalPosition = caretModel.getLogicalPosition(); CaretModel caretModel = editor.getCaretModel();
VisualPosition visualPosition = caretModel.getVisualPosition(); LogicalPosition logicalPosition = caretModel.getLogicalPosition();
int offset = caretModel.getOffset(); VisualPosition visualPosition = caretModel.getVisualPosition();
Messages.showInfoMessage(logicalPosition.toString() + "\n" + int offset = caretModel.getOffset();
Messages.showInfoMessage(logicalPosition.toString() + "\n" +
visualPosition.toString() + "\n" + visualPosition.toString() + "\n" +
"Offset: " + offset, "Caret Parameters Inside The Editor"); "Offset: " + offset, "Caret Parameters Inside The Editor");
} }
@Override
@Override public void update(AnActionEvent e) {
public void update(AnActionEvent e) { //...
//... }
} }
} ```
Check out, compile, and run the Check out, compile, and run the
[Editor Basics Plugin] (https://github.com/JetBrains/intellij-sdk/tree/master/code_samples/editor_basics), [Editor Basics Plugin] (https://github.com/JetBrains/intellij-sdk/tree/master/code_samples/editor_basics),
@ -332,31 +349,35 @@ Series of steps below shows how to change standard behaviour of the editor and m
First we need to implement an instance of First we need to implement an instance of
[TypedActionHandler](): [TypedActionHandler]():
public class MyTypedHandler implements TypedActionHandler { ```java
@Override public class MyTypedHandler implements TypedActionHandler {
public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext) { @Override
} public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext) {
} }
}
```
###Implementing logic for handling keystrokes ###Implementing logic for handling keystrokes
```public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext);``` ```public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext);```
method should contain the main logical part for handling keystrokes. It will be called every time a key is pressed. method should contain the main logical part for handling keystrokes. It will be called every time a key is pressed.
In the following example our typed handler is meant insert a string at the zero offset in the editor after a keystroke occurs: In the following example our typed handler is meant insert a string at the zero offset in the editor after a keystroke occurs:
public class MyTypedHandler implements TypedActionHandler { ```java
@Override public class MyTypedHandler implements TypedActionHandler {
public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext) { @Override
final Document document = editor.getDocument(); public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext) {
Project project = editor.getProject(); final Document document = editor.getDocument();
Runnable runnable = new Runnable() { Project project = editor.getProject();
@Override Runnable runnable = new Runnable() {
public void run() { @Override
document.insertString(0, "Typed\n"); public void run() {
} document.insertString(0, "Typed\n");
}; }
WriteCommandAction.runWriteCommandAction(project, runnable); };
} WriteCommandAction.runWriteCommandAction(project, runnable);
} }
}
```
###Setting up *TypedActionHandler* ###Setting up *TypedActionHandler*
@ -365,13 +386,15 @@ To enable a custom implementation of *TypedActionHandler* in the plugin we need
[TypedAction]() [TypedAction]()
class. By doing it we replace the typing handler with the specified handler. class. By doing it we replace the typing handler with the specified handler.
public class EditorIllustration extends AnAction { ```java
static { public class EditorIllustration extends AnAction {
final EditorActionManager actionManager = EditorActionManager.getInstance(); static {
final TypedAction typedAction = actionManager.getTypedAction(); final EditorActionManager actionManager = EditorActionManager.getInstance();
typedAction.setupHandler(new MyTypedHandler()); final TypedAction typedAction = actionManager.getTypedAction();
} typedAction.setupHandler(new MyTypedHandler());
} }
}
```
After compiling and running the code snippet above typing in the editor will be handled with inserting an extra string at the 0 position. After compiling and running the code snippet above typing in the editor will be handled with inserting an extra string at the 0 position.
@ -385,40 +408,46 @@ In this example we will use *EditorActionHandler* to insert one extra caret abov
###Prerequirements ###Prerequirements
Create an action: Create an action:
public class EditorHandlerIllustration extends AnAction { ```java
@Override public class EditorHandlerIllustration extends AnAction {
public void actionPerformed(@NotNull AnActionEvent anActionEvent) { @Override
} public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
@Override
public void update(@NotNull final AnActionEvent anActionEvent) {
}
} }
@Override
public void update(@NotNull final AnActionEvent anActionEvent) {
}
}
```
Register action in Register action in
[plugin.xml](): [plugin.xml]():
<actions> ```xml
<action id="EditorBasics.EditorHandlerIllustration" class="org.jetbrains.tutorials.editor.basics.EditorHandlerIllustration" text="Editor Handler" <actions>
description="Illustrates how to plug an action in"> <action id="EditorBasics.EditorHandlerIllustration" class="org.jetbrains.tutorials.editor.basics.EditorHandlerIllustration" text="Editor Handler"
<add-to-group group-id="EditorPopupMenu" anchor="first"/> description="Illustrates how to plug an action in">
</action> <add-to-group group-id="EditorPopupMenu" anchor="first"/>
</action> </action>
</action>
```
###Setting visibility ###Setting visibility
Our action should be visible only in case if the following conditions are met: Our action should be visible only in case if the following conditions are met:
there's a project open, there's an editor available, and there's at least one caret active in the editor: there's a project open, there's an editor available, and there's at least one caret active in the editor:
public class EditorHandlerIllustration extends AnAction { ```java
@Override public class EditorHandlerIllustration extends AnAction {
public void actionPerformed(@NotNull AnActionEvent anActionEvent) { @Override
} public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
@Override
public void update(@NotNull final AnActionEvent anActionEvent) {
final Project project = anActionEvent.getData(CommonDataKeys.PROJECT);
final Editor editor = anActionEvent.getData(CommonDataKeys.EDITOR);
anActionEvent.getPresentation().setVisible((project != null && editor != null && !editor.getCaretModel().getAllCarets().isEmpty()));
}
} }
@Override
public void update(@NotNull final AnActionEvent anActionEvent) {
final Project project = anActionEvent.getData(CommonDataKeys.PROJECT);
final Editor editor = anActionEvent.getData(CommonDataKeys.EDITOR);
anActionEvent.getPresentation().setVisible((project != null && editor != null && !editor.getCaretModel().getAllCarets().isEmpty()));
}
}
```
###Obtaining *EditorActionHandler* ###Obtaining *EditorActionHandler*
@ -427,37 +456,40 @@ an instance of
[EditorActionHandler]() for the action we'd like to work with. Ih this case it will be an instance of [EditorActionHandler]() for the action we'd like to work with. Ih this case it will be an instance of
[CloneCaretActionHandler](). [CloneCaretActionHandler]().
public class EditorHandlerIllustration extends AnAction { ```java
@Override public class EditorHandlerIllustration extends AnAction {
public void actionPerformed(@NotNull AnActionEvent anActionEvent) { @Override
final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
EditorActionManager actionManager = EditorActionManager.getInstance(); final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR);
EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW); EditorActionManager actionManager = EditorActionManager.getInstance();
} EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW);
@Override
public void update(@NotNull final AnActionEvent anActionEvent) {
//...
}
} }
@Override
public void update(@NotNull final AnActionEvent anActionEvent) {
//...
}
}
```
###Making *EditorActionHandler* execute actions ###Making *EditorActionHandler* execute actions
To execute an action we need to call the ```public final void execute(@NotNull Editor editor, @Nullable final Caret contextCaret, final DataContext dataContext);``` To execute an action we need to call the ```public final void execute(@NotNull Editor editor, @Nullable final Caret contextCaret, final DataContext dataContext);```
method of a corresponding *EditorActionHandler* method of a corresponding *EditorActionHandler*
public class EditorHandlerIllustration extends AnAction { ```java
@Override public class EditorHandlerIllustration extends AnAction {
public void actionPerformed(@NotNull AnActionEvent anActionEvent) { @Override
final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
EditorActionManager actionManager = EditorActionManager.getInstance(); final Editor editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR);
EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW); EditorActionManager actionManager = EditorActionManager.getInstance();
actionHandler.execute(editor, editor.getCaretModel().getCurrentCaret(), anActionEvent.getDataContext()); EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW);
} actionHandler.execute(editor, editor.getCaretModel().getCurrentCaret(), anActionEvent.getDataContext());
@Override
public void update(@NotNull final AnActionEvent anActionEvent) {
//
}
} }
@Override
public void update(@NotNull final AnActionEvent anActionEvent) {
//
}
}
```
After compiling and running the following code sample, one extra caret will be placed in the editor below the current active caret. After compiling and running the following code sample, one extra caret will be placed in the editor below the current active caret.