Intellij IDEA CodeReview插件開發1:理論篇

IntelliJ Platform SDK

可以讓我們開發插件,定製IDE,例如支持特定的語言

插件

在IntelliJ平臺上構建的產品是可組合的應用程序,插件可以通過多種方式擴展平臺,從添加簡單的菜單項到添加對完整語言,構建系統和調試器的支持。

分類

  • 自定義語言支持 (Kotlin)
  • 框架集成 (Spring)
  • 工具集成 (DBHelper)
  • 用戶界面加載項(背景圖片插件)

結構

  1. 組成部分
.IntelliJIDEAx0/
  plugins/
    sample.jar/
      com/foo/...
      ...
      ...
      META-INF/
        plugin.xml
        pluginIcon.svg
        pluginIcon_dark.svg

jar包+plugin.xml+圖標
plugin.xml

  • <depends>依賴於一個或多個其他插件
<!-- url="" specifies the URL of the plugin homepage (displayed in the Welcome Screen and in "Plugins" settings dialog) -->
<idea-plugin url="http://www.jetbrains.com/idea">

  <!-- Plugin name -->
  <name>VssIntegration</name>

  <!-- Unique identifier of the plugin.
       Cannot be changed between the plugin versions.
       If not specified, assumed to be equal to <name>. -->
  <id>VssIntegration</id>

  <!-- Description of the plugin. -->
  <description>Vss integration plugin</description>

  <!-- Description of changes in the latest version of the plugin.
       Displayed in the "Plugins" settings dialog and in the
       plugin repository Web interface. -->
  <change-notes>Initial release of the plugin.</change-notes>

  <!-- Plugin version -->
  <version>1.0</version>

  <!-- The vendor of the plugin.
       The optional "url" attribute specifies the URL of the vendor homepage.
       The optional "email" attribute specifies the e-mail address of the vendor.-->
  <vendor url="http://www.jetbrains.com" email="[email protected]" />

  <!-- The unique identifiers of the plugins on which this plugin depends. -->
  <depends>MyFirstPlugin</depends>

  <!-- Optional dependency on another plugin.
       If the plugin with the "MySecondPlugin" ID is installed,
       the contents of mysecondplugin.xml (the format of this file
       conforms to the format of plugin.xml) will be loaded. -->
  <depends optional="true" config-file="mysecondplugin.xml">MySecondPlugin</depends>

  <!-- Allows a plugin to integrate its help system (in JavaHelp format)
       with the IDEA help system. The "file" attribute specifies the name
       of the JAR file in the "help" subdirectory of the plugin directory.
       The "path" attribute specifies the name of the helpset file within
       the JAR file.-->
  <helpset file="myhelp.jar" path="/Help.hs" />

  <!-- Minimum and maximum build of IDEA compatible with the plugin -->
  <idea-version since-build="3000" until-build="3999"/>

  <!-- Resource bundle from which the text of plugin descriptions,
       action names and etc. will be loaded -->
  <resource-bundle>messages.MyPluginBundle</resource-bundle>

  <!-- Plugin's application components -->
  <application-components>
    <component>
      <!-- Component's interface class -->
      <interface-class>com.foo.Component1Interface</interface-class>

      <!-- Component's implementation class -->
      <implementation-class>com.foo.impl.Component1Impl</implementation-class>
    </component>
  </application-components>

  <!-- Plugin's project components -->
  <project-components>
    <component>
      <!-- Interface and implementation classes are the same -->
      <interface-class>com.foo.Component2</interface-class>

      <!-- If the "workspace" option is set "true", the component
           saves its state to the .iws file instead of the .ipr file.
           Note that the <option> element is used only if the component
           implements the JDOMExternalizable interface. Otherwise, the
           use of the <option> element takes no effect.  -->
      <option name="workspace" value="true" />

      <!-- If the "loadForDefaultProject" tag is present, the project component is instantiated also for the default project. -->
      <loadForDefaultProject>
    </component>
  </project-components>

  <!-- Plugin's module components -->
  <module-components>
    <component>
      <interface-class>com.foo.Component3</interface-class>
    </component>
  </module-components>

  <!-- Actions -->
  <actions>
    <action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage" description="Run garbage collector">
      <keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>
    </action>
  </actions>

  <!-- Extension points defined by the plugin.
       Extension points are registered by a plugin so that other
       plugins can provide this plugin with certain data. The
       "beanClass" attribute specifies the class the implementations
       of which can be used for the extension point. -->
  <extensionPoints>
    <extensionPoint name="testExtensionPoint" beanClass="com.foo.impl.MyExtensionBean"/>
  </extensionPoints>

  <!-- Extensions which the plugin adds to extension points
       defined by the IDEA core or by other plugins.
       The "defaultExtensionNs " attribute must be set to the
       ID of the plugin defining the extension point, or to 
       "com.intellij" if the extension point is defined by the
       IDEA core. The name of the tag within the <extensions>
       tag matches the name of the extension point, and the
       "implementation" class specifies the name of the class
       added to the extension point. -->
  <extensions xmlns="VssIntegration">
    <testExtensionPoint implementation="com.foo.impl.MyExtensionImpl"/>
  </extensions>
</idea-plugin>
  1. 組件
    分層
  • 應用層<application-components>
  • 項目層<project-components>
  • 模塊層<module-components>

常見組件

  • Menus and toolbars
  • Tool Windows
  • Dialogs
  • Popups
  • Notifications
  • File and Class Choosers
  • Editor Components
  • List and Tree Controls
  • Miscellaneous Swing Components
  1. 擴展
    如果您希望插件擴展其他插件或IntelliJ平臺的功能,則必須聲明一個或多個擴展。
    <extensions defaultExtensionNs="com.intellij">
        <toolWindow canCloseContents="true" anchor="bottom"
                    id="CodeReview"
                    factoryClass="org.codereview.gui.CodeReviewToolWindow">
        </toolWindow>
    </extensions>

平臺基礎

Action動作

    <actions>
        <action id="ReviewAction" class="org.codereview.action.ReviewAction" text="CodeReview"
                description="CodeReview">
            <add-to-group group-id="EditorPopupMenu" anchor="first"/>
            <keyboard-shortcut keymap="$default" first-keystroke="ctrl alt Q"/>
        </action>
    </actions>

開發步驟
a. 創建Action extends AnAction
b. 重寫actionPerformed方法
c. 在plugin.xml中註冊,包括分組配置
d. 設置可見性和能動性
e. 測試功能

文件

  • Virtual File System
    虛擬文件系統(VFS)是IntelliJ Platform的一個組件,它封裝了用於處理文件的大部分活動。 它有以下主要用途:
    • 提供用於處理文件的通用API,無論其實際位置如何(在磁盤上,存檔中,在HTTP服務器上等)
    • 在檢測到修改時跟蹤文件修改並提供文件內容的新舊版本。
      提供將附加持久數據與VFS中的文件相關聯的可能性。
  • Virtual File
    • 我如何獲得虛擬文件?

      • 來自一個動作:e.getData(PlatformDataKeys.VIRTUAL_FILE)如果您對多項選擇感興趣,還可以使用e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY)
      • 從本地文件系統中的路徑:LocalFileSystem.getInstance()findFileByIoFile()
      • 從PSI文件:psiFile.getVirtualFile()(如果PSI文件僅存在於內存中,則可能返回null)
      • 從文檔:FileDocumentManager.getInstance()。getFile()
    • 我該怎麼辦?
      可以使用典型的文件操作,例如遍歷文件系統,獲取文件內容,重命名,移動或刪除。應使用VfsUtilCore.iterateChildrenRecursively執行遞歸迭代,以防止由遞歸符號鏈接引起的無限循環。

    • 它從何而來?
      通過從項目根目錄開始上下掃描文件系統,可以逐步構建VFS。 VFS刷新檢測到文件系統中出現的新文件。可以使用(VirtualFileManager.getInstance()refresh()VirtualFile.refresh())以編程方式啓動刷新操作。每當文件系統觀察者收到文件系統更改通知時(Windows和Mac操作系統上都可用),也會觸發VFS刷新。
      作爲插件開發人員,如果需要訪問剛通過IntelliJ Platform API由外部工具創建的文件,則可能需要調用VFS刷新。

文檔

  • 我如何獲得文件?
    - 來自一個動作:e.getData(PlatformDataKeys.EDITOR).getDocument()
    - 從虛擬文件:FileDocumentManager.getDocument()。 如果之前未加載文檔內容,則此調用會強制從磁盤加載文檔內容; 如果您只對打開的文檔或可能已修改的文檔感興趣,請改用FileDocumentManager.getCachedDocument()
    - 從PSI文件:PsiDocumentManager.getInstance()getDocument()PsiDocumentManager.getInstance()getCachedDocument()
    • 我可以用文件做什麼?
      • 您可以執行在“純文本”級別上訪問或修改文件內容的任何操作(作爲字符序列,而不是Java元素樹)。

編輯器

獲得final Editor editor = e.getData(CommonDataKeys.EDITOR);
座標系

  • Logical position ignore folding
  • Visual position take folding into account

事件

  • TypedActionHandler
    TypedActionHandler接口旨在實現對編輯器中鍵入的鍵的自定義處理。
  • EditorActionHandler
    EditorActionHandler.java用於編輯器中按鍵激活的操作

參考:
sdk-docs on github

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章