Eclipse プラグインの popup メニューの複数 variables の表示条件設定


経緯

plugin.xml に popup メニューの表示を追加した時のメモ。

パッケージエクスプローラーやエディタ上で popup メニューを開いた時に、特定のファイルの時だけ表示させるための設定。
一つの variable に対しての設定はネットを検索するといくつも見つかったが、今回は、 selection と adoptEditorInput の二つについての条件を、 popup メニューにつけようという時の情報が見つからなかったのでメモしておく。

基本的な方法についは以下を参考にさせてもらった。

やりたいことの具体的な内容

  1. 自分の作成するツールの入力ファイルの拡張子のファイルが選択されている時のみ popup メニューにそのファイルを処理するメニューを追加したい
  2. 選択されている時とは次の二つ
    1. パッケージエクスプローラー等のツリー表示上でファイルを選択した状態
    2. 編集中のエディター画面がアクティブな時

実際にやったこと

前提:Eclipse 上のプロジェクトは plugin プロジェクトで、テンプレートに Hello World Command を指定した。このプロジェクトで予め存在している、メインメニューの実行コマンドを popup で起動させる形に機能拡張を施す流れで、自分のやりたいことを確認する。

  1. 拡張ポイント org.eclipse.core.expressions.definitions に条件を二つ定義
    1. パッケージエクスプローラー等のツリービューの条件判定用定義
      1. definition を追加
        1. id: org.ironya.tools.training.visibleWhen1
      2. definition に with を追加
        1. variable: selection
      3. with に iterate を追加
        1. ifEmpty: false
      4. iterate に adopt を追加
        1. type: org.eclipse.core.resources.IFile
      5. adopt に or を追加
      6. or に対象とする拡張子を追加(今回は三つ)
        1. property: org.eclipse.core.resources.extension
        2. value: ファイルの拡張子
    2. エディターの条件判定用定義
      1. definition を追加
        1. id: org.ironya.tools.training.visibleWhen2
      2. definition に with を追加
        1. variable: selection
      3. with に adopt を追加
        1. type: org.eclipse.core.resources.IFile
      4. adopt に or を追加
      5. or に対象とする拡張子を追加(今回は三つ)
        1. property: org.eclipse.core.resources.extension
        2. value: ファイルの拡張子
  2. 拡張ポイント org.eclipse.ui.menus にポップアップメニューを追加
    1. menuContribution として popup メニューを追加
      1. location: popup:org.eclipse.ui.popup.any?after=additions
    2. 作成した popup の menuContribution にメニュー選択時に実行するコマンドを追加
      1. commandId: org.ironya.tools.training.commands.sampleCommand (既存のid)
      2. label: hello
    3. 追加したコマンドに visibleWhen を追加
      1. checkEnabled: false
    4. 追加した visibleWhen に or を追加
    5. or に最初に作成した条件の参照 (reference) を二つ追加
      1. definitionId: 上で作成した definition に設定した id

実際の plugin.xml全体

plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
   <extension
         point="org.eclipse.ui.commands">
      <category
            name="Sample Category"
            id="org.ironya.tools.training.commands.category">
      </category>
      <command
            name="Sample Command"
            categoryId="org.ironya.tools.training.commands.category"
            id="org.ironya.tools.training.commands.sampleCommand">
      </command>
   </extension>
   <extension
         point="org.eclipse.ui.handlers">
      <handler
            commandId="org.ironya.tools.training.commands.sampleCommand"
            class="org.ironya.tools.training.handlers.SampleHandler">
      </handler>
   </extension>
   <extension
         point="org.eclipse.ui.bindings">
      <key
            commandId="org.ironya.tools.training.commands.sampleCommand"
            contextId="org.eclipse.ui.contexts.window"
            sequence="M1+6"
            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
      </key>
   </extension>
   <extension
         point="org.eclipse.ui.menus">
      <menuContribution
            locationURI="menu:org.eclipse.ui.main.menu?after=additions">
         <menu
               label="Sample Menu"
               mnemonic="M"
               id="org.ironya.tools.training.menus.sampleMenu">
            <command
                  commandId="org.ironya.tools.training.commands.sampleCommand"
                  mnemonic="S"
                  id="org.ironya.tools.training.menus.sampleCommand">
            </command>
         </menu>
      </menuContribution>
      <menuContribution
            locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions">
         <toolbar
               id="org.ironya.tools.training.toolbars.sampleToolbar">
            <command
                  commandId="org.ironya.tools.training.commands.sampleCommand"
                  icon="icons/sample.gif"
                  tooltip="Say hello world"
                  id="org.ironya.tools.training.toolbars.sampleCommand">
            </command>
         </toolbar>
      </menuContribution>
      <menuContribution
            allPopups="false"
            locationURI="popup:org.eclipse.ui.popup.any?after=additions">
         <command
               commandId="org.ironya.tools.training.commands.sampleCommand"
               label="hello"
               style="push">
            <visibleWhen
                  checkEnabled="false">
              <or> <!-- ここの二つの reference を囲うような or が可能かどうかについて言及している情報が見つからなかった -->
                <reference
                     definitionId="org.ironya.tools.training.visibleWhen1">
                </reference>
                <reference
                     definitionId="org.ironya.tools.training.visibleWhen2">
                </reference>
              </or>
            </visibleWhen>
         </command>
      </menuContribution>
   </extension>
   <extension
         point="org.eclipse.core.expressions.definitions">
      <definition
            id="org.ironya.tools.training.visibleWhen1">
         <with
               variable="selection">
            <iterate
                  ifEmpty="false">
               <adapt
                     type="org.eclipse.core.resources.IFile">
                  <or>
                    <test
                        property="org.eclipse.core.resources.extension"
                        value="yaml">
                    </test>
                    <test
                        property="org.eclipse.core.resources.extension"
                        value="yml">
                    </test>
                    <test
                        property="org.eclipse.core.resources.extension"
                        value="xml">
                    </test>
                  </or>
               </adapt>
            </iterate>
         </with>
      </definition>
      <definition
            id="org.ironya.tools.training.visibleWhen2">
         <with
               variable="activeEditorInput">
            <adapt
                  type="org.eclipse.core.resources.IFile">
               <or>
                  <test
                        property="org.eclipse.core.resources.extension"
                        value="yaml">
                  </test>
                  <test
                        property="org.eclipse.core.resources.extension"
                        value="yml">
                  </test>
                  <test
                        property="org.eclipse.core.resources.extension"
                        value="xml">
                  </test>
               </or>
            </adapt>
         </with>
      </definition>
   </extension>
</plugin>

念のため Eclipse のオンラインドキュメントのページでスキーマを確認。
場所: help.eclipse.org/neon/index.html > Platform Plug-in Developer Guide -> Reference -> Extension Point Reference -> org.eclipse.ui.menus と辿り、ページ内を visibleWhen で検索して見つかったページ内のリンク。

visibleWhen

以下の通りの記載があった。

<!ELEMENT visibleWhen (not | or | and | instanceof | test | systemTest | equals | count | with | resolve | adapt | iterate | reference)?>

で、 or の説明のところは次の通り。

<!ELEMENT or (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate , reference)*>

ということで、 or には(最後のアスタリスクが示すように) reference を複数指定できることが仕様として確認できた。