Write a plugin for IntelliJ IDEA, add the functionality to the code editor

Starting to work in IntelliJ IDEA, has found the lack of convenient shortcuts, which is used in Eclipse — Ctrl+Alt+Up. On this combination the allocated block of text or a string is copied up to move the cursor to the beginning of the copied block.
Idea is the default action on Ctrl+D which copies a block down (Ctrl+Alt+Down in Eclipse), but you cannot add the same action up. After gugleniya was specified question in the Q&A, unanswered. Opened issue on jetbrains. All of these actions had not responded therefore it was decided to write a small plugin for Idea.

Start


To get started is to download the source community version of the IDE, because the time it will take quite a lot, the total size of about 1.6 GB.
Git repository:
git://git.jetbrains.org/idea/community.git

/ > The action is optional, but very desirable, because here we find the java docks we are interested in the classes and methods as well as sources of ready-made plugins (almost all of the code below so I peeked into them).

Create project


In General, for the development of the plugin does not require anything other than IntelliJ IDEA. I used the commercial version, so all steps below are performed on it. Significant differences from the community edition should not be.
Create a plug-in project: File -> New Project...
Select IntelliJ Platform Plugin

If there is no Project SDK click New... and specify the folder where you installed the Idea.
Click Finish.

Adding java docks


This step is optional.
After downloading source IDE, click File- > Project Structure... and on the tab Sourcepath specify the path to the sources:

Now the development and debug of the plug-in will become easier.
For example, it was:

was:


structure of a plugin


About structure of the plug-in Idea, you can read here.
Any plugin for Idea, this .jar file that contains the configuration file plugin.xml in the folder META-INF and the code responsible for the operation of the plugin.

Need to fill some data in plugin.xml. At this stage, there is nothing difficult in completing.
plugin.xml
<idea-plugin version="2">
<id>org.idea.plugin.duplicatelines</id>
<name>Duplicate lines</name>
<version>1.0</version>
<vendor email="test@yourcompany.com">mobileDeveloper</vendor>

<description><![CDATA[
Plugin for intellij idea to allow copy lines<br>
and block of code like Eclipse IDE (Ctrl+Alt+Up and Ctrl+Alt+Down).
]]></description>

< idea-version since-build="107.105"/>

<actions></actions>

<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
</extensions>
</idea-plugin>


Actions


In Idea running a so-called Action System. It allows plugins to add their actions to menus, toolbar, etc. Actions are organized in groups, which in turn can contain other groups. Each Action has a unique identifier. Most of the standard identifiers defined in the file IdeActions.java

Action is a regular java class that inherits from abstaktnyh class AnAction. We will be inherited from the more specific EditorAction.
Action can be create through the graph. interface: St. vol. mouse on package -> New -> Action

After selecting the desired group, as needed you can specify a combination of keys on the new Action will be created class of the heir to the AnAction, and plugin.xml in section <actions/> will be added to the description of the Action class.
Give a name to our Action class — CopyLineUpAction.
Now inside the tag file plugin.xml the following code will be:
Description of Action

<actions>
<action id="CopyLineUpAction" class="org.idea.plugin.duplicatelines.CopyLineUpAction"

description="Copy line(s) up.">
<add-to-group group-id="EditorActions" anchor="last"/>
< keyboard-shortcut first-keystroke="control alt UP" keymap="$default"/>
</action>
</actions>


Please note, we have identified the key combination Ctrl+Alt+Up by default. I used a standard combination of Eclipse, because I used to it. The Idea settings this shortcut will override.

Code


If you used gui to create Action, in the specified package already exists on the class CopyLineUpAction, otherwise you need to create it manually.
The logic of our Action is very simple: by pressing a combination of keys, to determine copy a chunk of text, paste this text above the current line and move the cursor to the beginning of the copied block.
Actually the code itself CopyLineUpAction, its a bit and, in my opinion, it is quite clear. I will only add that the Action class must contain a constructor without parameters (default constructor):
CodeLineUpAction.java
package org.idea.plugin.duplicatelines;

import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
import com.intellij.openapi.util.TextRange;

public class CopyLineUpAction extends EditorAction {

public CopyLineUpAction(EditorActionHandler defaultHandler) {
super(defaultHandler);
}

public CopyLineUpAction() {
this(new UpHandler());
}

private static class UpHandler extends EditorWriteActionHandler {
private UpHandler() {
}

@Override
public void executeWriteAction(Editor editor, DataContext dataContext) {
Document document = editor.getDocument();

if (editor == null || document == null || !document.isWritable()) {
return;
}

// CaretModel used to find caret position
CaretModel caretModel = editor.getCaretModel();
// The SelectionModel is used to find selection ranges
SelectionModel selectionModel = editor.getSelectionModel();

// get the range of the selected characters
CharsRange TextRange = new TextRange(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
// get the range of the selected lines (block of code)
LinesRange TextRange = new TextRange(document.getLineNumber(charsRange.getStartOffset()), document.getLineNumber(charsRange.getEndOffset()));
// range of the duplicated string
LinesBlock TextRange = new TextRange(document.getLineStartOffset(linesRange.getStartOffset()), document.getLineEndOffset(linesRange.getEndOffset()));

// get the string to duplicate
String duplicatedString = document.getText().substring(linesBlock.getStartOffset(), linesBlock.getEndOffset());
duplicatedString += "\n";

// insert new duplicated string into the document
document.insertString(linesBlock.getStartOffset(), duplicatedString);

// select duplicated block
editor.getSelectionModel().setSelection(linesBlock.getStartOffset(), linesBlock.getStartOffset());
// move cursor to the start of copied block
caretModel.moveToOffset(linesBlock.getStartOffset());
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
}
}



Debugging


Debajit newly created plugin in the same way as any java application in Idea, with the only difference in the window Run/Debug Configurations - > Add New Configuration will need to specify the Plugin. After selecting Run/Debug will launch a new copy of the Idea with the already installed plug-in.
Screenshot


building and installing plugins


To build the plug-in, select the menu Build - > Prepare Plugin Module 'plugin name' For Deployment. Will be created .jar file in the project directory.
Installation pagina is made through File ->Settings... -> IDE Settings -> Plugins -> Install plugin from disk...
In the settings of Keymap we will see this line:

Check, enjoy the new functionality.

Upd. Replaced the hand Range in com.intellij.openapi.util.TextRange, thanks for the tip enDal

Useful links


Link to source
Plugin Development Documentation
tutorial on creating a plugin for Idea
Open API and Plugin Development — here you can find answers to many questions plugins for Idea.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

mSearch: search + filter for MODX Revolution

Emulator data from GNSS receiver NMEA

The game Let's Twist: the Path into the unknown