Начиная работать в IntelliJ IDEA, обнаружил отсутствие удобной комбинации клавиш, которой пользуюсь в Eclipse — Ctrl+Alt+Up. По этой комбинации выделенный блок текста или строка, копируется вверх с перемещением курсора в начало скопированного блока.
В Idea есть действие по умолчанию на Ctrl+D, которое копирует блок вниз (Ctrl+Alt+Down в Eclipse), но невозможно добавить аналогичное действие вверх. После гугления был задан вопрос в Q&A, оставшийся без ответа. Заведён issue на jetbrains. Все эти действия не дали ответа, поэтому решено было написать небольшой плагин для Idea.
Для начала стоит скачать исходники community версии IDE, т.к. времени это займёт достаточно много, общий размер около 1,6 Гб.
Репозиторий git:
Действие это необязательное, но очень желательное, т.к. здесь мы найдём java доки интересующих нас классов и методов, а также исходники готовых плагинов (практически весь код ниже я подглядел в них).
В целом, для разработки плагина не требуется ничего, кроме IntelliJ IDEA. Я использовал коммерческую версию, поэтому все действия далее проводятся на ней. Значительных отличий от community редакции быть не должно.
Создаём проект плагина: File -> New Project…
Выбираем пункт IntelliJ Platform Plugin
Если отсутствует Project SDK, нажимаем New… и указываем папку, куда установлена Idea.
Жмём Finish.
Необязательный шаг.
После закачки исходников IDE, жмём File -> Project Structure… и на закладке Sourcepath указываем путь к исходникам:
Теперь разработка и дебаг плагина станет проще.
Например, было:
стало:
Про структуру плагина в Idea можно почитать здесь.
Любой плагин для Idea, это .jar файл, содержащий конфигурационный файл plugin.xml в папке META-INF и код, отвечающий за работу плагина.
Необходимо заполнить некоторые данные в plugin.xml. На этом этапе, ничего сложного в заполнении нет.
В Idea работает так называемая Action System. Она позволяет плагинам добавлять свои действия в меню, на тулбар и т.д. Actions организованы в группы, которые в свою очередь могут содержать другие группы. Каждый Action имеет уникальный идентификатор. Большинство стандартных идентификаторов определено в файле IdeActions.java
Action является обычным java классом, который наследуется от абстактного класса
Action можно создать через граф. интерфейс: пр. кн. мыши на package -> New -> Action:
Выбрав необходимую группу, по необходимости можно задать комбинацию клавиш на новый Action, будет создан класс наследник
Дадим имя нашему Action классу — CopyLineUpAction.
Теперь внутри тега файла plugin.xml будет следующий код:
Обратите внимание, мы определили комбинацию клавиш Ctrl+Alt+Up по умолчанию. Я использовал стандартную комбинацию Eclipse, т.к. привык к ней. В настройках Idea эту комбинацию можно будет переопределить.
Если вы использовали gui для создания Action, то в указанном пакете уже присутствует класс
Логика работы нашего Action очень простая: по нажатию комбинации клавиш, определить копируемый кусок текста, вставить этот текст выше текущей строки и переместить курсор в начало скопированного блока.
Собственно сам код CopyLineUpAction, его немного и, по-моему, он достаточно ясен. Добавлю лишь, что Action класс должен содержать конструктор без параметров (конструктор по умолчанию):
Дебажить вновь создаваемый плагин можно точно также, как и любое java приложение в Idea, с единственным отличием, в окне Run/Debug Configurations -> Add New Configuration, нужно будет указать Plugin. После выбора Run/Debug будет запущена новая копия Idea с уже установленным плагином.
Чтобы собрать плагин, выбираем в меню Build -> Prepare Plugin Module 'plugin name' For Deployment. Будет создан .jar файл в директории проекта.
Установка прагина производится через File ->Settings… -> IDE Settings -> Plugins -> Install plugin from disk…
В настройках Keymap мы увидим такую строчку:
Проверяем, радуемся новому функционалу.
Upd. Заменил самописный
Ссылка на исходники
Plugin Development Documentation
Урок по созданию плагина для Idea
Open API and Plugin Development — здесь можно найти ответ на многие вопросы по плагинам для Idea.
В Idea есть действие по умолчанию на Ctrl+D, которое копирует блок вниз (Ctrl+Alt+Down в Eclipse), но невозможно добавить аналогичное действие вверх. После гугления был задан вопрос в Q&A, оставшийся без ответа. Заведён issue на jetbrains. Все эти действия не дали ответа, поэтому решено было написать небольшой плагин для Idea.
Начало
Для начала стоит скачать исходники community версии IDE, т.к. времени это займёт достаточно много, общий размер около 1,6 Гб.
Репозиторий git:
git://git.jetbrains.org/idea/community.git
Действие это необязательное, но очень желательное, т.к. здесь мы найдём java доки интересующих нас классов и методов, а также исходники готовых плагинов (практически весь код ниже я подглядел в них).
Создание проекта
В целом, для разработки плагина не требуется ничего, кроме IntelliJ IDEA. Я использовал коммерческую версию, поэтому все действия далее проводятся на ней. Значительных отличий от community редакции быть не должно.
Создаём проект плагина: File -> New Project…
Выбираем пункт IntelliJ Platform Plugin
Если отсутствует Project SDK, нажимаем New… и указываем папку, куда установлена Idea.
Жмём Finish.
Добавление java доков
Необязательный шаг.
После закачки исходников IDE, жмём File -> Project Structure… и на закладке Sourcepath указываем путь к исходникам:
Теперь разработка и дебаг плагина станет проще.
Например, было:
стало:
Структура плагина
Про структуру плагина в Idea можно почитать здесь.
Любой плагин для Idea, это .jar файл, содержащий конфигурационный файл plugin.xml в папке META-INF и код, отвечающий за работу плагина.
Необходимо заполнить некоторые данные в plugin.xml. На этом этапе, ничего сложного в заполнении нет.
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
В Idea работает так называемая Action System. Она позволяет плагинам добавлять свои действия в меню, на тулбар и т.д. Actions организованы в группы, которые в свою очередь могут содержать другие группы. Каждый Action имеет уникальный идентификатор. Большинство стандартных идентификаторов определено в файле IdeActions.java
Action является обычным java классом, который наследуется от абстактного класса
AnAction
. Мы будем наследоваться от более конкретного EditorAction
.Action можно создать через граф. интерфейс: пр. кн. мыши на package -> New -> Action:
Выбрав необходимую группу, по необходимости можно задать комбинацию клавиш на новый Action, будет создан класс наследник
AnAction
, а в plugin.xml, в секцию <actions/> будет добавлено описание Action класса.Дадим имя нашему Action классу — CopyLineUpAction.
Теперь внутри тега файла plugin.xml будет следующий код:
Описание Action
<actions>
<action id="CopyLineUpAction" class="org.idea.plugin.duplicatelines.CopyLineUpAction"
text="Copy line(s) up."
description="Copy line(s) up.">
<add-to-group group-id="EditorActions" anchor="last"/>
<keyboard-shortcut first-keystroke="control alt UP" keymap="$default"/>
</action>
</actions>
Обратите внимание, мы определили комбинацию клавиш Ctrl+Alt+Up по умолчанию. Я использовал стандартную комбинацию Eclipse, т.к. привык к ней. В настройках Idea эту комбинацию можно будет переопределить.
Код
Если вы использовали gui для создания Action, то в указанном пакете уже присутствует класс
CopyLineUpAction
, в противном случае нужно создать его вручную.Логика работы нашего Action очень простая: по нажатию комбинации клавиш, определить копируемый кусок текста, вставить этот текст выше текущей строки и переместить курсор в начало скопированного блока.
Собственно сам код CopyLineUpAction, его немного и, по-моему, он достаточно ясен. Добавлю лишь, что Action класс должен содержать конструктор без параметров (конструктор по умолчанию):
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();
// SelectionModel used to find selection ranges
SelectionModel selectionModel = editor.getSelectionModel();
// get the range of the selected characters
TextRange charsRange = new TextRange(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
// get the range of the selected lines (block of code)
TextRange linesRange = new TextRange(document.getLineNumber(charsRange.getStartOffset()), document.getLineNumber(charsRange.getEndOffset()));
// range of the duplicated string
TextRange linesBlock = 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);
}
}
}
Отладка
Дебажить вновь создаваемый плагин можно точно также, как и любое java приложение в Idea, с единственным отличием, в окне Run/Debug Configurations -> Add New Configuration, нужно будет указать Plugin. После выбора Run/Debug будет запущена новая копия Idea с уже установленным плагином.
Скриншот
Сборка и установка плагина
Чтобы собрать плагин, выбираем в меню Build -> Prepare Plugin Module 'plugin name' For Deployment. Будет создан .jar файл в директории проекта.
Установка прагина производится через File ->Settings… -> IDE Settings -> Plugins -> Install plugin from disk…
В настройках Keymap мы увидим такую строчку:
Проверяем, радуемся новому функционалу.
Upd. Заменил самописный
Range
на com.intellij.openapi.util.TextRange
, спасибо за подсказку enDalПолезные ссылки
Ссылка на исходники
Plugin Development Documentation
Урок по созданию плагина для Idea
Open API and Plugin Development — здесь можно найти ответ на многие вопросы по плагинам для Idea.