Escrevendo plugins do IntelliJ IDEA
*1. Introdução *
Nos últimos anos, IntelliJ do JetBrains tornou-se rapidamente o principal IDE para desenvolvedores de Java. Em nosso https://www..com/java-in-2018 [relatório do estado de Java] mais recente, o IntelliJ foi o IDE preferido por 55% dos entrevistados, contra 48% no ano anterior.
Um recurso que torna o IntelliJ tão atraente para os desenvolvedores Java é a capacidade de estender e criar novas funcionalidades usando plug-ins. Neste tutorial, veremos como escrever um plug-in IntelliJ para demonstrar algumas das maneiras de estender o IDE.
E observe que, embora este artigo seja focado nos plug-ins do IntelliJ, todos os IDEs do JetBrains compartilham código comum. Portanto,* muitas das técnicas usadas aqui podem ser aplicadas a outros IDEs do JetBrain *, como PyCharm, RubyMine e muito mais.
*2. Funcionalidade de plug-in *
A funcionalidade de plug-in para IntelliJ geralmente se enquadra em uma das 4 categorias:
-
Idiomas personalizados : a capacidade de escrever, interpretar e compilar código escrito em diferentes idiomas
-
Estruturas : suporte para estruturas de terceiros, como o Spring
-
Ferramentas : integração com ferramentas externas, como Gradle
-
Complementos da interface do usuário : novos itens de menu, janelas e botões de ferramentas e muito mais
Os plugins geralmente se enquadram em várias categorias. Por exemplo, o plugin Git fornecido com o IntelliJ, interage com o executável git instalado no sistema. O plug-in fornece sua janela de ferramenta e itens de menu pop-up, além de integrar-se ao fluxo de trabalho de criação de projeto, janela de preferências e muito mais.
*3. Criando um plug-in *
A maneira mais fácil de começar com os plug-ins do IntelliJ é usando o Plugin DevKit. Isso pode ser acessado no menu New> Project:
link:/wp-content/uploads/2018/08/intellij-plugin.jpg [imagem:/wp-content/uploads/2018/08/intellij-plugin.jpg [imagem, largura = 957, altura = 629]]
*Observe que devemos usar um JDK do JetBrains* para garantir que as classes de plug-in necessárias estejam disponíveis no caminho de classe. O IntelliJ deve vir com um JDK adequado por padrão, mas, se não, podemos fazer o download de https://bintray.com/jetbrains/intellij-jdk[here].
Até o momento em que escrevemos, podemos usar apenas o Java 8 para escrever plugins IntelliJ . Isso ocorre porque o JetBrains atualmente não fornece um JDK oficial para Java 9 ou superior.
*4. Exemplo de plug-in *
Para demonstrar a criação de um plug-in IntelliJ, criaremos um plug-in que fornece acesso rápido ao popular site Stack Overflow de várias áreas do IDE. Nós vamos adicionar:
-
Um item de menu Ferramentas para visitar a página Faça uma pergunta *Um item de menu pop-up no editor de texto e na saída do console para pesquisar o estouro de pilha em busca de texto destacado.
====* 4.1 Criando ações *
As ações são o componente principal usado para escrever os plugins do IntelliJ. As ações são acionadas por eventos no IDE, como clicar em um item de menu ou botão da barra de ferramentas.
A primeira etapa na criação de uma ação é criar uma classe Java que estenda AnAction. Para nosso plug-in Stack Overflow, criaremos 2 ações.
A primeira ação abre a página Faça uma pergunta em uma nova janela do navegador:
public class AskQuestionAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
BrowserUtil.browse("https://stackoverflow.com/questions/ask");
}
}
Usamos a classe BrowserUtil incorporada porque ela lida com todas as nuances da abertura de uma página da web em diferentes sistemas operacionais e navegadores.
A segunda ação abre a página de pesquisa Estouro de pilha e passa o texto de pesquisa como uma sequência de consultas. Desta vez, implementaremos dois métodos.
O primeiro método que implementamos é exatamente como nossa primeira ação e trata da abertura de um navegador da web.
Primeiro, porém, precisamos coletar dois valores para o StackOverflow. Um é a etiqueta do idioma e o outro é o texto a ser pesquisado.
Para obter a tag de idioma, usaremos a Interface de estrutura do programa.* Esta API analisa todos os arquivos em um projeto e fornece uma maneira programática de inspecioná-los. *
Nesse caso, usamos o PSI para determinar a linguagem de programação de um arquivo:
PsiFile file = e.getData(CommonDataKeys.PSI_FILE);
Language lang = e.getData(CommonDataKeys.PSI_FILE).getLanguage();
String languageTag = "+[" + lang.getDisplayName().toLowerCase() + "]";
Observe que o PSI também fornece detalhes específicos do idioma sobre um arquivo. Por exemplo,* poderíamos usar o PSI para encontrar todos os métodos públicos em uma classe Java. *
Para obter o texto a ser pesquisado, usaremos o Editor API para recuperar o texto destacado na tela:
final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
CaretModel caretModel = editor.getCaretModel();
String selectedText = caretModel.getCurrentCaret().getSelectedText();
Mesmo que essa ação seja a mesma para as janelas do editor e do console, o acesso ao texto selecionado funciona da mesma maneira.
Agora, podemos juntar tudo isso em uma declaração actionPerformed:
@Override
public void actionPerformed(AnActionEvent e) {
PsiFile file = e.getData(CommonDataKeys.PSI_FILE);
Language lang = e.getData(CommonDataKeys.PSI_FILE).getLanguage();
String languageTag = "+[" + lang.getDisplayName().toLowerCase() + "]";
Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
CaretModel caretModel = editor.getCaretModel();
String selectedText = caretModel.getCurrentCaret().getSelectedText()
String query = selectedText.replace(' ', '+') + languageTag;
BrowserUtil.browse("https://stackoverflow.com/search?q=" + query);
}
Essa ação também substitui um segundo método chamado update. Isso nos permite ativar ou desativar a ação sob diferentes condições.
Nesse caso, desabilitamos a ação de pesquisa quando não há texto selecionado:
@Override
public void update(AnActionEvent e) {
Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
CaretModel caretModel = editor.getCaretModel();
e.getPresentation().setEnabledAndVisible(caretModel.getCurrentCaret().hasSelection());
}
====* 4.2 Registrando ações *
Depois de escrevermos nossas ações,* precisamos registrá-las no IDE *. Existem duas maneiras de fazer isso.
A primeira maneira é usar o arquivo plugin.xml, criado para nós quando iniciamos um novo projeto.
Por padrão, o arquivo terá um elemento _ <actions> _ vazio, que é onde adicionaremos nossas ações:
<actions>
<action
id="StackOverflow.AskQuestion.ToolsMenu"
class="com..intellij.stackoverflowplugin.AskQuestionAction"
text="Ask Question on Stack Overflow"
description="Ask a Question on Stack Overflow">
<add-to-group group-id="ToolsMenu" anchor="last"/>
</action>
<action
id="StackOverflow.Search.Editor"
class="com..intellij.stackoverflowplugin.SearchAction"
text="Search on Stack Overflow"
description="Search on Stack Overflow">
<add-to-group group-id="EditorPopupMenu" anchor="last"/>
</action>
<action
id="StackOverflow.Search.Console"
class="com..intellij.stackoverflowplugin.SearchAction"
text="Search on Stack Overflow"
description="Search on Stack Overflow">
<add-to-group group-id="ConsoleEditorPopupMenu" anchor="last"/>
</action>
</actions>
O uso do arquivo XML para registrar ações garantirá que eles sejam registrados durante a inicialização do IDE, o que geralmente é preferível.
A segunda maneira de registrar ações é programaticamente usando a classe ActionManager:
ActionManager.getInstance().registerAction("StackOverflow.SearchAction", new SearchAction());
Isso tem a vantagem de nos permitir registrar ações dinamicamente. Por exemplo, se escrevermos um plug-in para integrar-se a uma API remota, convém registrar um conjunto diferente de ações com base na versão da API que chamamos.
A desvantagem dessa abordagem é que as ações não são registradas na inicialização. Temos que criar uma instância de ApplicationComponent para gerenciar ações, o que requer mais codificação e configuração XML.
*5. Testando o plug-in *
Como em qualquer programa, escrever um plugin IntelliJ requer teste. Para um plug-in pequeno como o que escrevemos, é suficiente garantir que o plug-in seja compilado e que as ações que criamos funcionem conforme o esperado quando clicamos neles.
Podemos testar manualmente (e depurar) nosso plug-in usando uma configuração de execução de plug-in:
link:/wp-content/uploads/2018/08/intellij-plugin-run-configuration.jpg [imagem:/wp-content/uploads/2018/08/intellij-plugin-run-configuration.jpg [imagem, largura = 680, altura = 486]]
Isso iniciará uma nova instância do IntelliJ com o nosso plugin ativado. Isso nos permite clicar nos diferentes itens de menu que criamos e garantir que as páginas de estouro de pilha adequadas sejam abertas.
Se você deseja fazer testes de unidade mais tradicionais, o IntelliJ fornece um ambiente sem cabeça para executar testes de unidade. Podemos escrever testes usando qualquer estrutura de teste que desejamos, e os testes são executados usando componentes reais e não desmontados do IDE.
===* 6. Implantando o plug-in *
O plugin DevKit fornece uma maneira simples de empacotar plugins para que possamos instalá-los e distribuí-los. Simplesmente clique com o botão direito do mouse no projeto do plug-in e selecione "Preparar o módulo do plug-in para implantação". Isso irá gerar um arquivo JAR dentro do diretório do projeto.
O arquivo JAR gerado contém os arquivos de código e configuração necessários para carregar no IntelliJ. Você pode instalá-lo localmente ou publicá-lo em um repositório de plugins para uso por outras pessoas.
A captura de tela abaixo mostra um dos novos itens de menu Estouro de pilha em ação:
link:/wp-content/uploads/2018/08/intellij-stackoverflow-pluginjpg.jpg [imagem:/wp-content/uploads/2018/08/intellij-stackoverflow-pluginjpg.jpg [imagem, largura = 728, altura = 295]]
===* 7. Conclusão*
Neste artigo, desenvolvemos um plug-in simples que destaca apenas algumas das maneiras de aprimorar o IDE do IntelliJ.
Enquanto trabalhamos principalmente com ações, o SDK do plugin IntelliJ oferece várias maneiras de adicionar novas funcionalidades ao IDE. Para uma leitura mais detalhada, consulte o guia oficial de primeiros passos.
Como sempre, o código completo do nosso exemplo de plug-in pode ser encontrado em nosso GitHub repositório.