Menulis Plugin IntelliJ IDEA

1. Pengenalan

Sejak beberapa tahun kebelakangan ini, IntelliJ dari JetBrains dengan cepat menjadi IDE teratas untuk pembangun Java. Dalam laporan State of Java kami yang terbaru, IntelliJ adalah IDE pilihan untuk 55% responden, meningkat dari 48% tahun sebelumnya.

Salah satu ciri yang menjadikan IntelliJ begitu menarik bagi pengembang Java adalah kemampuan untuk memperluas dan membuat fungsi baru menggunakan plugin. Dalam tutorial ini, kita akan melihat menulis plugin IntelliJ untuk menunjukkan beberapa cara memperluas IDE.

Dan perhatikan bahawa sementara artikel ini difokuskan pada plugin IntelliJ, semua IDE JetBrains berkongsi kod biasa. Oleh itu, banyak teknik yang digunakan di sini dapat digunakan untuk IDE JetBrain lain seperti PyCharm, RubyMine, dan banyak lagi.

2. Fungsi Plugin

Fungsi pemalam untuk IntelliJ biasanya tergolong dalam salah satu daripada 4 kategori:

  • Bahasa khusus : keupayaan untuk menulis, mentafsir, dan menyusun kod yang ditulis dalam bahasa yang berbeza
  • Kerangka kerja : sokongan untuk kerangka pihak ketiga seperti Spring
  • Alat : penyatuan dengan alat luaran seperti Gradle
  • Alat tambah antara muka pengguna : item menu baru, tetingkap alat dan butang, dan banyak lagi

Pemalam selalunya akan tergolong dalam beberapa kategori . Sebagai contoh, pemalam Git yang dihantar dengan IntelliJ, berinteraksi dengan git yang boleh dilaksanakan yang dipasang pada sistem. Plugin menyediakan tetingkap alat dan item menu pop timbul, sementara juga mengintegrasikan ke dalam alur kerja pembuatan projek, tetingkap pilihan, dan banyak lagi.

3. Membuat Plugin

Cara termudah untuk memulakan dengan plugin IntelliJ adalah dengan menggunakan Plugin DevKit mereka. Ini dapat diakses dari menu Baru > Projek :

Perhatikan bahawa kita mesti menggunakan JetBrains JDK untuk memastikan kelas plugin yang diperlukan tersedia di classpath. IntelliJ harus dilengkapi dengan JDK yang sesuai secara lalai, tetapi jika tidak, kami boleh memuat turunnya dari sini.

Pada penulisan ini, kita hanya dapat menggunakan Java 8 untuk menulis plugin IntelliJ . Ini kerana JetBrains pada masa ini tidak menyediakan JDK rasmi untuk Java 9 atau lebih tinggi.

4. Contoh Pemalam

Untuk menunjukkan penulisan plugin IntelliJ, kami akan membuat plugin yang menyediakan akses cepat ke laman web Stack Overflow yang popular dari pelbagai kawasan di IDE. Kami akan menambah:

  • Item menu Alat untuk mengunjungi halaman Tanya Soalan
  • Item menu pop timbul di kedua editor teks dan output konsol untuk mencari Stack Overflow untuk teks yang diserlahkan.

4.1. Membuat Tindakan

Tindakan adalah komponen teras yang digunakan untuk menulis pemalam IntelliJ . Tindakan dipicu oleh peristiwa di IDE, seperti mengklik item menu atau butang bar alat.

Langkah pertama dalam membuat tindakan adalah membuat kelas Java yang memperluas AnAction . Untuk plugin Stack Overflow kami, kami akan membuat 2 tindakan.

Tindakan pertama membuka halaman Tanya Soalan di tetingkap penyemak imbas baru:

public class AskQuestionAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { BrowserUtil.browse("//stackoverflow.com/questions/ask"); } }

Kami menggunakan kelas BrowserUtil bawaan kerana ia menangani semua nuansa membuka laman web pada sistem operasi dan penyemak imbas yang berbeza.

Tindakan kedua membuka halaman carian Stack Overflow dan meneruskan teks carian sebagai rentetan pertanyaan. Kali ini kita akan melaksanakan dua kaedah.

Kaedah pertama yang kami laksanakan adalah seperti tindakan pertama dan menangani membuka penyemak imbas web.

Pertama, kita perlu mengumpulkan dua nilai untuk StackOverflow. Salah satunya adalah tag bahasa, dan yang lain adalah teks yang akan dicari.

Untuk mendapatkan tanda bahasa, kami akan menggunakan Antaramuka Struktur Program. API ini menguraikan semua fail dalam projek dan menyediakan cara terprogram untuk memeriksanya.

Dalam kes ini, kami menggunakan PSI untuk menentukan bahasa pengaturcaraan fail:

PsiFile file = e.getData(CommonDataKeys.PSI_FILE); Language lang = e.getData(CommonDataKeys.PSI_FILE).getLanguage(); String languageTag = "+[" + lang.getDisplayName().toLowerCase() + "]";

Perhatikan bahawa PSI juga memberikan perincian khusus bahasa mengenai fail. Sebagai contoh, kita dapat menggunakan PSI untuk mencari semua kaedah awam di kelas Java.

To get the text to search for, we'll use the Editor API to retrieve highlighted text on the screen:

final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR); CaretModel caretModel = editor.getCaretModel(); String selectedText = caretModel.getCurrentCaret().getSelectedText();

Even though this action is the same for both editor and console windows, accessing the selected text works the same way.

Now, we can put this all together in an actionPerformed declaration:

@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("//stackoverflow.com/search?q=" + query); } 

This action also overrides a second method named update. This allows us to enable or disable the action under different conditions.

In this case, we disable the search action when there no selected text:

@Override public void update(AnActionEvent e) { Editor editor = e.getRequiredData(CommonDataKeys.EDITOR); CaretModel caretModel = editor.getCaretModel(); e.getPresentation().setEnabledAndVisible(caretModel.getCurrentCaret().hasSelection()); } 

4.2. Registering Actions

Once we have our actions written, we need to register them with the IDE. There are two ways to do this.

The first way is using the plugin.xml file, which is created for us when we start a new project.

By default the file will have an empty element, which is where we will add our actions:

Using the XML file to register actions will ensure they register during IDE startup, which is usually preferable.

The second way to register actions is programmatically using the ActionManager class:

ActionManager.getInstance().registerAction("StackOverflow.SearchAction", new SearchAction());

This has the advantage of letting us dynamically register actions. For example, if we write a plugin to integrate with a remote API, we might want to register a different set of actions based on the version of the API that we call.

The disadvantage to this approach is that actions do not register at startup. We have to create an instance of ApplicationComponent to manage actions, which requires more coding and XML configuration.

5. Testing the Plugin

As with any program, writing an IntelliJ plugin requires testing. For a small plugin like the one we have written, it's sufficient to ensure the plugin compiles and that the actions we created work as expected when we click them.

We can manually test (and debug) our plugin by using a Plugin run configuration:

This will launch a new instance of IntelliJ with our plugin activated. This allows us to click the different menu items we created and ensure the proper Stack Overflow pages open up.

If you wish to do more traditional unit testing, IntelliJ provides a headless environment to run unit tests. We can write tests using any test framework we want, and the tests run using real, unmocked components from the IDE.

6. Deploying the Plugin

The plugin DevKit provides a simple way to package plugins so we can install and distribute them. Simply right-click the plugin project and select “Prepare plugin module for Deployment”. This will generate a JAR file inside the project directory.

The generated JAR file contains the code and configuration files needed to load into IntelliJ. You can install it locally, or publish it to a plugin repository for use by others.

The screenshot below shows one of the new Stack Overflow menu items in action:

7. Conclusion

Dalam artikel ini, kami mengembangkan plugin sederhana yang menyoroti beberapa cara kami dapat meningkatkan IntelliJ IDE.

Walaupun kami terutama bekerja dengan tindakan, SDK plugin IntelliJ menawarkan beberapa cara untuk menambahkan fungsi baru ke IDE. Untuk membaca lebih lanjut, lihat panduan memulakan rasmi.

Seperti biasa, kod lengkap untuk plugin sampel kami boleh didapati di repositori GitHub kami.