Как создать подменю для шаблонов файлов в Intellij IDEA Plugin DevKit?

#intellij-idea #jetbrains-ide #intellij-plugin

Вопрос:

Фон

Я работаю над плагином, в котором пользователи могут создавать новые файлы из существующего шаблона файла. Цель состоит в том, чтобы объединить несколько шаблонов файлов в новом подменю в меню «Основной файл». Если возможно, я хотел бы создать вложенное подменю на основе категории шаблона. Например:

 New -> New Option -> Option A ->
                                  Sub-Option A
                                  Sub-Option B
                                  Sub-Option C
                     Option B ->
                     Option C ->
 

Текущий Прогресс

До сих пор я мог успешно добавлять шаблоны файлов в меню файл. Однако все они не сгруппированы и помещены непосредственно в меню файл. По мере того как количество шаблонов продолжает расти, управлять ими становится все труднее.

 New -> Option A 
       Option B 
       Option C
 

Для создания шаблонов файлов я использовал CreateFileFromTemplateAction класс

 class NewFile : CreateFileFromTemplateAction(TEXT, TEST_DESCRIPTION, ICON) {

    companion object {
        fun createProperties(project: Project, className: String): Properties {
            val properties = FileTemplateManager.getInstance(project).defaultProperties
            properties  = "VERSION" to "1.0.0"
            properties  = "NAME" to className
            return properties
        }
    }

    override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) {
        builder.addKind("Option A", null, "Option A.kt.ft")
        builder.addKind("Option B", null, "Option B.kt.ft")
        builder.addKind("Option C", null, "Option C.kt.ft")
    }

    override fun getActionName(project: PsiDirectory?, directory: String, builder: String?): String {
        return NEW_FILE_ACTION
    }

    override fun createFileFromTemplate(name: String, template: FileTemplate, dir: PsiDirectory) = try {
        val className = FileUtilRt.getNameWithoutExtension(name)
        val project = dir.project
        val properties = createProperties(project, className)
        CreateFromTemplateDialog(project, dir, template, AttributesDefaults(className).withFixedName(true), properties)
            .create()
            .containingFile
    } catch (e: Exception) {
        LOG.error("Error while creating new file", e)
        null
    }

}
 

И позже зарегистрировал action и internalFileTemplate внутри plugin.xml файла

 <idea-plugin>

    <extensions defaultExtensionNs="com.intellij">
        <internalFileTemplate name="Option A"/>
        <internalFileTemplate name="Option B"/>
        <internalFileTemplate name="Option C"/>
    </extensions>

    <actions>
        <action
                id="NewFileAction"
                class="NewFile">
            <add-to-group group-id="NewGroup" anchor="after" relative-to-action="NewFile"/>
        </action>
    </actions>

</idea-plugin>
 

Ожидания

Я буду очень признателен за любые предложения или фрагмент кода. Если это требование невыполнимо, я также могу использовать альтернативное решение, например, всплывающее диалоговое окно.

Обновить

После изменения plugin.xml кода Меню Подменю отображается правильно.

 <actions>
        <group id="MyGroup.FileMenu"
               popup="true"
               class="com.intellij.ide.actions.NonTrivialActionGroup"
               text="New Option"
               description="New Option Description">
            <add-to-group group-id="NewGroup" anchor="after" relative-to-action="NewFile"/>
            <separator/>
            <action id="NewFileAction"
                    class="NewFile"
                    text="My Action"
                    description="My Action Description"/>
        </group>
    </actions>
 

Меню файлов отображаются следующим образом:

 New -> New Option -> Option A
                     Option B
                     Option C
 

Однако:

Диалоговое окно ввода по умолчанию принимает пользовательские переменные отдельно. Например, сначала он принимает входные данные для $NAME переменной имени класса, а затем принимает дополнительные переменные

введите описание изображения здесь

Я искал способ ввести входные данные для всех пользовательских переменных в одном диалоговом окне. Вот пример диалогового окна ввода при использовании обычного шаблона файла без использования плагина.

введите описание изображения здесь

Комментарии:

1. RE 2: Похоже, вы переопределяете createFileFromTemplate() свое действие, но не создаете никакого файла. Переопределение этого метода не кажется необходимым.

2. @BasLeijdekkers Спасибо. Теперь у меня возникли трудности с пользовательскими переменными внутри шаблона файла. Пожалуйста, взгляните на обновленный ответ.

3. Если вам нужен диалог пользовательского шаблона файла, взгляните на com.intellij.ide.fileTemplates.actions.CreateFromTemplateAction .

Ответ №1:

Вы можете зарегистрировать свою собственную группу в plugin.xml новой группе в файле и добавить в нее свои действия. Например:

 <group id="MyNewGroup" popup="true" class="com.intellij.ide.actions.NonTrivialActionGroup">
  <add-to-group group-id="NewGroup"/>
</group>
 

Комментарии:

1. Спасибо. Я внес предложенные изменения. Не могли бы вы, пожалуйста, проверить обновленный вопрос?