mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-30 18:27:49 +08:00
Merge branch 'master' into IJSDK-672
This commit is contained in:
commit
bbfbb99a66
2
.idea/.gitignore
generated
vendored
Normal file
2
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
11
.idea/gradle.xml
generated
11
.idea/gradle.xml
generated
@ -104,6 +104,17 @@
|
||||
</option>
|
||||
<option name="useQualifiedModuleNames" value="true" />
|
||||
</GradleProjectSettings>
|
||||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$/code_samples/tree_structure_provider" />
|
||||
<option name="gradleJvm" value="1.8" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$/code_samples/tree_structure_provider" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="useQualifiedModuleNames" value="true" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -24,7 +24,6 @@
|
||||
* [Using DevKit](basics/getting_started/using_dev_kit.md)
|
||||
* [Setting Up a Development Environment](basics/getting_started/setting_up_environment.md)
|
||||
* [Creating a Plugin Project](basics/getting_started/creating_plugin_project.md)
|
||||
* [Creating an Action](basics/getting_started/creating_an_action.md)
|
||||
* [Running and Debugging a Plugin](basics/getting_started/running_and_debugging_a_plugin.md)
|
||||
* [Deploying a Plugin](basics/getting_started/deploying_plugin.md)
|
||||
* [Publishing a Plugin](basics/getting_started/publishing_plugin.md)
|
||||
@ -42,6 +41,7 @@
|
||||
* [Plugin Configuration File](basics/plugin_structure/plugin_configuration_file.md)
|
||||
* [Plugin Logo (Icon)](basics/plugin_structure/plugin_icon_file.md)
|
||||
* [Plugin Dependencies](basics/plugin_structure/plugin_dependencies.md)
|
||||
* [Dynamic Plugins](basics/plugin_structure/dynamic_plugins.md)
|
||||
* [IntelliJ Platform Artifacts Repositories](reference_guide/intellij_artifacts.md)
|
||||
* [Kotlin for Plugin Developers](tutorials/kotlin.md)
|
||||
* [Internal Actions Menu](reference_guide/internal_actions/internal_actions_intro.md)
|
||||
@ -240,8 +240,7 @@
|
||||
* [Tomcat Integration](reference_guide/tomcat_integration.md)
|
||||
* [Spring API](reference_guide/frameworks_and_external_apis/spring_api.md)
|
||||
* [PhpStorm](products/phpstorm/phpstorm.md)
|
||||
* [Setting-up the Environment](products/phpstorm/setting_up_environment.md)
|
||||
* [PHP Open API](products/phpstorm/php_open_api.md)
|
||||
* [Working with the PHP Open API](products/phpstorm/php_open_api.md)
|
||||
* [Existing Third Party Plugins](products/phpstorm/existing_plugins.md)
|
||||
* [PyCharm](products/pycharm.md)
|
||||
* [Rider](products/rider.md)
|
||||
|
@ -8,11 +8,11 @@ baseurl: /intellij/sdk/docs/
|
||||
|
||||
description: Documentation for working with and extending the IntelliJ Platform SDK
|
||||
|
||||
# This is tag 193.5233.102 (2019.3)
|
||||
# This is tag 193.5662.53 (2019.3.1)
|
||||
upsource:
|
||||
server: upsource.jetbrains.com
|
||||
repo: idea-ce
|
||||
commit: 37502bec42258b27d4547dbe8593ba3427bfcc49
|
||||
commit: 7cf49a16e4e15a18fa2f742635053647ae94abfb
|
||||
|
||||
github_repo: JetBrains/intellij-sdk-docs
|
||||
youtrack_project: IJSDK
|
||||
|
@ -4,7 +4,7 @@ title: File View Providers
|
||||
|
||||
A file view provider ([`FileViewProvider`](upsource:///platform/core-api/src/com/intellij/psi/FileViewProvider.java)) manages access to multiple PSI trees within a single file.
|
||||
|
||||
For example, a JSPX page has a separate PSI tree for the Java code in it (`PsiJavaFile`), a separate tree for the XML code (`XmlFile`), and a separate tree for JSP as a whole [`JspFile`](upsource:///java/jsp-openapi/src/com/intellij/psi/jsp/JspFile.java)).
|
||||
For example, a JSPX page has a separate PSI tree for the Java code in it (`PsiJavaFile`), a separate tree for the XML code (`XmlFile`), and a separate tree for JSP as a whole ([`JspFile`](upsource:///java/jsp-openapi/src/com/intellij/psi/jsp/JspFile.java)).
|
||||
|
||||
Each of the PSI trees covers the entire contents of the file, and contains special "outer language elements" in the places where contents in a different language can be found.
|
||||
|
||||
@ -29,7 +29,7 @@ Implement [`FileViewProviderFactory`](upsource:///platform/core-api/src/com/inte
|
||||
|
||||
Register as follows in `plugin.xml`:
|
||||
```xml
|
||||
<extensions>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<fileType.fileViewProviderFactory filetype="%file_type%" implementationClass="com.plugin.MyFileViewProviderFactory" />
|
||||
</extensions>
|
||||
```
|
||||
|
@ -8,9 +8,9 @@ In general, code-related data structures in the *IntelliJ Platform* are covered
|
||||
|
||||
Reading data is allowed from any thread. Reading data from the UI thread does not require any special effort. However, read operations performed from any other thread need to be wrapped in a read action by using `ApplicationManager.getApplication().runReadAction()` or, shorter, `ReadAction.run/compute`.
|
||||
|
||||
Writing data is only allowed from the UI thread, and write operations always need to be wrapped in a write action with `ApplicationManager.getApplication().runWriteAction()` or, shorter, `WriteAction.run/compute`.
|
||||
Writing data is only allowed from the UI thread, and write operations always need to be wrapped in a write action with `ApplicationManager.getApplication().runWriteAction()` or, shorter, `WriteAction.run()/compute()`.
|
||||
|
||||
In addition, modifying the model is only allowed from write-safe contexts, which include user actions, `invokeLater` calls from them (see the next section), and transactions (`TransactionGuard.submitTransaction`). You may not modify PSI, VFS or project model from inside UI renderers or `SwingUtilities.invokeLater` calls. See `TransactionGuard` documentation for more details.
|
||||
In addition, modifying the model is only allowed from write-safe contexts, which include user actions and `invokeLater()` calls from them (see the next section). You may not modify PSI, VFS or project model from inside UI renderers or `SwingUtilities.invokeLater()` calls.
|
||||
|
||||
You must not access the model outside a read or write action. The corresponding objects are not guaranteed to survive between several consecutive read actions. So as a rule of thumb, whenever you start a read action, you should check if your PSI/VFS/project/module are still valid.
|
||||
|
||||
@ -20,33 +20,33 @@ To pass control from a background thread to the event dispatch thread, instead o
|
||||
|
||||
* Passing `ModalityState.NON_MODAL` means that the operation will be executed after all modal dialogs are closed. Note that if any of the open (unrelated) project displays a per-project modal dialog, the action will be executed after the dialog is closed.
|
||||
* Passing `ModalityState.stateForComponent()` means that the operation can be executed when the topmost shown dialog is the one that contains the specified component, or is one of its parent dialogs.
|
||||
* If no modality state is passed, `ModalityState.defaultModalityState()` will be used. In most cases, this is the optimal choice, that uses current modality state when invoked from UI thread, and has a special handling for background processes started with `ProgressManager`: `invokeLater` from such a process may run in the same dialog that the process started.
|
||||
* `ModalityState.any()` means that the runnable will be executed as soon as possible regardless of modal dialogs. Please note that modifying PSI, VFS or project model is prohibited from such runnables. See `TransactionGuard` documentation for more details.
|
||||
* If no modality state is passed, `ModalityState.defaultModalityState()` will be used. In most cases, this is the optimal choice, that uses current modality state when invoked from UI thread, and has a special handling for background processes started with `ProgressManager`: `invokeLater()` from such a process may run in the same dialog that the process started.
|
||||
* `ModalityState.any()` means that the runnable will be executed as soon as possible regardless of modal dialogs. Please note that modifying PSI, VFS or project model is prohibited from such runnables.
|
||||
|
||||
If your UI thread activity needs to access [file-based index](../indexing_and_psi_stubs.md) (e.g. it's doing any kind of project-wide PSI analysis, resolves references, etc), please use `DumbService#smartInvokeLater`. That way, your activity will be run after all possible indexing processes have been completed.
|
||||
If your UI thread activity needs to access [file-based index](../indexing_and_psi_stubs.md) (e.g. it's doing any kind of project-wide PSI analysis, resolves references, etc), please use `DumbService.smartInvokeLater()`. That way, your activity will be run after all possible indexing processes have been completed.
|
||||
|
||||
## Background processes and `ProcessCanceledException`
|
||||
|
||||
Background progresses are managed by `ProgressManager` class, which has plenty of methods to execute the given code
|
||||
Background progresses are managed by [`ProgressManager`](upsource:///platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java) class, which has plenty of methods to execute the given code
|
||||
with a modal (dialog), non-modal (visible in the status bar) or invisible progress. In all cases, the code is
|
||||
executed on a background thread which is associated with a `ProgressIndicator` object.
|
||||
The current thread's indicator can be retrieved any time via `ProgressIndicatorProvider#getGlobalProgressIndicator`.
|
||||
executed on a background thread which is associated with a [`ProgressIndicator`](upsource:///platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java) object.
|
||||
The current thread's indicator can be retrieved any time via `ProgressIndicatorProvider.getGlobalProgressIndicator()`.
|
||||
|
||||
For visible progresses, threads can use `ProgressIndicator` to notify the user about current status:
|
||||
e.g. set text or visible fraction of the work done.
|
||||
|
||||
Progress indicators also provide means to handle cancellation of background processes, either by user (pressing "Cancel" button),
|
||||
or from code (e.g. when the current operation becomes obsolete due to some changes in the project).
|
||||
The progress can be marked as canceled by calling `ProgressIndicator#cancel`.
|
||||
The process reacts to this by calling `ProgressIndicator#checkCanceled` (or `ProgressManager#checkCanceled` if you don't have indicator instance at hand).
|
||||
This call throws a special unchecked `ProcessCanceledException` if the background process has been canceled.
|
||||
The progress can be marked as canceled by calling `ProgressIndicator.cancel()`.
|
||||
The process reacts to this by calling `ProgressIndicator.checkCanceled()` (or `ProgressManager.checkCanceled()` if you don't have indicator instance at hand).
|
||||
This call throws a special unchecked [`ProcessCanceledException`](upsource:///platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java) if the background process has been canceled.
|
||||
|
||||
All code working with PSI, or in other kinds of background processes, should be prepared to a `ProcessCanceledException` being thrown from any point.
|
||||
All code working with PSI, or in other kinds of background processes, should be prepared to a [`ProcessCanceledException`](upsource:///platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java) being thrown from any point.
|
||||
This exception should never be logged, it should be rethrown, and it'll be handled in the infrastructure that started the process.
|
||||
|
||||
The `checkCanceled` should be called often enough to guarantee smooth cancellation of the process. PSI internals
|
||||
have a lot of `checkCanceled` calls inside. But if your process does lengthy non-PSI activity, you might need to
|
||||
insert explicit `checkCanceled` calls so that it happens frequently, e.g. on each Nth loop iteration.
|
||||
The `checkCanceled()` should be called often enough to guarantee smooth cancellation of the process. PSI internals
|
||||
have a lot of `checkCanceled()` calls inside. But if your process does lengthy non-PSI activity, you might need to
|
||||
insert explicit `checkCanceled()` calls so that it happens frequently, e.g. on each _Nth_ loop iteration.
|
||||
|
||||
## Read action cancellability
|
||||
|
||||
@ -55,15 +55,15 @@ Background threads shouldn't take plain read actions for a long time. The reason
|
||||
The best known approach to that is to cancel background read actions whenever there's a write action about to occur, and restart that background read action later from the scratch. Editor highlighting, code completion, Goto Class/File/etc actions all work like this.
|
||||
To achieve that, the lengthy background operation is started with a `ProgressIndicator`, and a special listener
|
||||
cancels that indicator when write action is started.
|
||||
The next time the background thread calls `checkCanceled`, a `ProcessCanceledException` will be thrown,
|
||||
The next time the background thread calls `checkCanceled()`, a `ProcessCanceledException` will be thrown,
|
||||
and the thread should stop its operation (and finish the read action) as soon as possible.
|
||||
|
||||
There are two recommended ways of doing this:
|
||||
|
||||
* If you're on UI thread, call `ReadAction.nonBlocking`
|
||||
* If you're on UI thread, call `ReadAction.nonBlocking()` which returns [`NonBlockingReadAction`](upsource:///platform/core-api/src/com/intellij/openapi/application/NonBlockingReadAction.java)
|
||||
* If you're already in a background thread, use `ProgressManager.getInstance().runInReadActionWithWriteActionPriority()` in a loop, until it passes or the whole activity becomes obsolete.
|
||||
|
||||
In both approaches, you should always check at the start of each read action, if the objects you're working with are still valid, and if the whole operation still makes sense (i.e. not canceled by the user, the project isn't closed, etc.). With `ReadAction.nonBlocking`,
|
||||
`expireWhen` is a convenient place for that.
|
||||
In both approaches, you should always check at the start of each read action, if the objects you're working with are still valid, and if the whole operation still makes sense (i.e. not canceled by the user, the project isn't closed, etc.). With `ReadAction.nonBlocking()`,
|
||||
use `expireWith()` or `expireWhen()` for that.
|
||||
|
||||
If the activity you're doing has to access [file-based index](../indexing_and_psi_stubs.md) (e.g. it's doing any kind of project-wide PSI analysis, resolves references, etc), use `ReadAction.nonBlocking(...).inSmartMode()`.
|
||||
|
@ -37,7 +37,7 @@ In many cases, you can also use more specific APIs for top-down navigation. For
|
||||
all methods in a Java class, you can do that using a visitor, but a much easier way to do that is to call `PsiClass.getMethods()`.
|
||||
|
||||
[`PsiTreeUtil`](upsource:///platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java) contains a number of
|
||||
general-purpose, language-independent functions for PSI tree navigation, some of which (for example, `findChildrenOfType`)
|
||||
general-purpose, language-independent functions for PSI tree navigation, some of which (for example, `findChildrenOfType()`)
|
||||
perform top-down navigation.
|
||||
|
||||
## Bottom-up navigation
|
||||
|
@ -4,7 +4,7 @@ title: PSI Files
|
||||
|
||||
A PSI (Program Structure Interface) file is the root of a structure representing the contents of a file as a hierarchy of elements in a particular programming language.
|
||||
|
||||
The [`PsiFile`](upsource:///platform/core-api/src/com/intellij/psi/PsiFile.java) class is the common base class for all PSI files, while files in a specific language are usually represented by its subclasses. For example, the [PsiJavaFile](upsource:///java/java-psi-api/src/com/intellij/psi/PsiJavaFile.java) class represents a Java file, and the [XmlFile](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlFile.java) class represents an XML file.
|
||||
The [`PsiFile`](upsource:///platform/core-api/src/com/intellij/psi/PsiFile.java) class is the common base class for all PSI files, while files in a specific language are usually represented by its subclasses. For example, the [`PsiJavaFile`](upsource:///java/java-psi-api/src/com/intellij/psi/PsiJavaFile.java) class represents a Java file, and the [`XmlFile`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlFile.java) class represents an XML file.
|
||||
|
||||
Unlike `VirtualFile` and `Document`, which have application scope (even if multiple projects are open, each file is represented by the same `VirtualFile` instance), PSI has project scope (the same file is represented by multiple `PsiFile` instances if the file belongs to multiple projects open at the same time).
|
||||
|
||||
@ -34,9 +34,9 @@ Like documents, PSI files are weakly referenced from the corresponding `VirtualF
|
||||
|
||||
## How do I create a PSI file?
|
||||
|
||||
The [`PsiFileFactory`](upsource:///platform/core-api/src/com/intellij/psi/PsiFileFactory.java)`.getInstance(project).createFileFromText()` method creates an in-memory PSI file with the specified contents.
|
||||
The [`PsiFileFactory`](upsource:///platform/core-api/src/com/intellij/psi/PsiFileFactory.java) `createFileFromText()` method creates an in-memory PSI file with the specified contents.
|
||||
|
||||
To save the PSI file to disk, use the [`PsiDirectory`](upsource:///platform/core-api/src/com/intellij/psi/PsiDirectory.java)`.add()` method.
|
||||
To save the PSI file to disk, use the [`PsiDirectory`](upsource:///platform/core-api/src/com/intellij/psi/PsiDirectory.java) `add()` method.
|
||||
|
||||
## How do I get notified when PSI files change?
|
||||
|
||||
@ -48,4 +48,4 @@ PSI can be extended to support additional languages through custom language plug
|
||||
|
||||
## What are the rules for working with PSI?
|
||||
|
||||
Any changes done to the content of PSI files are reflected in documents, so all rules for working with documents (read/write actions, commands, read-only status handling) are in effect.
|
||||
Any changes done to the content of PSI files are reflected in documents, so all [rules for working with documents](documents.md#what-are-the-rules-of-working-with-documents) (read/write actions, commands, read-only status handling) are in effect.
|
||||
|
@ -36,7 +36,7 @@ The Gradle workflow offers these advantages:
|
||||
* [Developing plugins using DevKit](getting_started/using_dev_kit.md)
|
||||
* [Setting Up a Development Environment](getting_started/setting_up_environment.md)
|
||||
* [Creating a Plugin Project](getting_started/creating_plugin_project.md)
|
||||
* [Creating an Action](getting_started/creating_an_action.md)
|
||||
* [Creating an Action](/tutorials/action_system/working_with_custom_actions.md)
|
||||
* [Running and Debugging a Plugin](getting_started/running_and_debugging_a_plugin.md)
|
||||
* [Deploying a Plugin](getting_started/deploying_plugin.md)
|
||||
* [Publishing a plugin to plugin repository](getting_started/publishing_plugin.md)
|
||||
|
@ -1,102 +0,0 @@
|
||||
---
|
||||
title: Creating an action
|
||||
---
|
||||
|
||||
Your plugins can customize the IntelliJ Platform UI by adding new items to the menus and toolbars. The IntelliJ Platform provides the class [`AnAction`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java), whose `actionPerformed` method is called each time you select a menu item or click a toolbar button.
|
||||
|
||||
To create custom actions in the *IntelliJ Platform*, you should perform two basic steps:
|
||||
|
||||
1. In your plugin, define an action or a system of actions that add their own items to menus and toolbars.
|
||||
2. Register your actions.
|
||||
|
||||
This topic outlines the above steps. For detailed information and samples, refer to [IntelliJ Platform Action System](/basics/action_system.md).
|
||||
|
||||
### Defining actions
|
||||
|
||||
An action is a class derived from the `AnAction` class. To define your action, in your plugin, create a Java class derived from the `AnAction` class. In this class, override the `actionPerformed` method to be called when a menu item or a toolbar button is selected.
|
||||
|
||||
To clarify this procedure, consider the following code snippet that defines the `TextBoxes` class derived from the `AnAction` class:
|
||||
|
||||
```java
|
||||
public class TextBoxes extends AnAction {
|
||||
// If you register the action from Java code, this constructor is used to set the menu item name
|
||||
// (optionally, you can specify the menu description and an icon to display next to the menu item).
|
||||
// You can omit this constructor when registering the action in the plugin.xml file.
|
||||
public TextBoxes() {
|
||||
// Set the menu item name.
|
||||
super("Text _Boxes");
|
||||
// Set the menu item name, description and icon.
|
||||
// super("Text _Boxes","Item description",IconLoader.getIcon("/Mypackage/icon.png"));
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent event) {
|
||||
Project project = event.getData(PlatformDataKeys.PROJECT);
|
||||
String txt= Messages.showInputDialog(project, "What is your name?", "Input your name", Messages.getQuestionIcon());
|
||||
Messages.showMessageDialog(project, "Hello, " + txt + "!\n I am glad to see you.", "Information", Messages.getInformationIcon());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that optionally, you can define a set of classes derived from the `AnAction` class. In this case, your plugin will define a system of actions.
|
||||
|
||||
### Registering actions
|
||||
|
||||
Once you have defined an action or a system of actions, you must register them to specify the menu items or toolbar buttons associated with actions. You can register actions in one of the following ways:
|
||||
|
||||
* Register actions in the `<actions>` section of the `plugin.xml` file.
|
||||
* Register actions from Java code.
|
||||
|
||||
This section provides some examples that illustrate how to register actions. For more information, refer to [IntelliJ Platform Action System](/basics/action_system.md).
|
||||
|
||||
#### Registering actions in the plugin.xml file
|
||||
|
||||
To register your actions, make appropriate changes to the `<actions>` section of the plugin.xml file for your IDEA project. The following fragment of the plugin.xml file adds the Sample Menu group (item) to the main menu. Clicking this item allows you to access **Sample Menu \| Text Boxes and Sample Menu \| Show Dialog** menu commands:
|
||||
|
||||

|
||||
|
||||
```xml
|
||||
<actions>
|
||||
<group id="MyPlugin.SampleMenu" text="_Sample Menu" description="Sample menu">
|
||||
<add-to-group group-id="MainMenu" anchor="last" />
|
||||
<action id="Myplugin.Textboxes" class="Mypackage.TextBoxes" text="Text _Boxes" description="A test menu item" />
|
||||
<action id="Myplugin.Dialogs" class="Mypackage.MyShowDialog" text="Show _Dialog" description="A test menu item" />
|
||||
</group>
|
||||
</actions>
|
||||
```
|
||||
|
||||
This fragment of the plugin.xml file demonstrates only some elements you can use in the `<actions>` section to register your actions. For information about all elements designed to register your actions, refer to [IntelliJ Platform Action System](/basics/action_system.md).
|
||||
|
||||
#### Registering actions from Java code
|
||||
|
||||
Alternatively, you can register your actions from Java code. For more information and samples that illustrate how to register actions from Java code, see [IntelliJ Platform Action System](/basics/action_system.md).
|
||||
|
||||
### Quick creation of actions
|
||||
|
||||
The IntelliJ Platform provides the **New Action** wizard that suggests a simplified way of creating actions, with all the required infrastructure. The wizard helps you declare the action class and automatically makes appropriate changes to the `<actions>` section of the plugin.xml file.
|
||||
|
||||
Note that you can use this wizard only to add a new action to an existing action group on the main menu or toolbar. If you want to create a new action group, and then add an action to this group, follow instructions earlier in this document.
|
||||
|
||||
**To create and register an action with the New Action wizard**
|
||||
|
||||
1. In your project, on the context menu of the destination package click **New** or press **Alt + Insert**.
|
||||
2. On the **New** menu, click **Action**.
|
||||
|
||||

|
||||
|
||||
3. On the **New Action** page that opens, fill in the following fields, and then click **OK**:
|
||||
|
||||
* **Action ID**: Enter the unique ID of the action. Recommended format: `PluginName.ID`
|
||||
* **Class Name**: Enter the name of the action class to be created.
|
||||
* **Name**: Enter the name of the menu item or tooltip for toolbar button associated with action.
|
||||
* **Description**: Optionally, enter the action description. The IDEA status bar indicates this description when focusing the action.
|
||||
* In the **Add to Group** area, under **Groups**, **Actions** and **Anchor**, specify the action group to which to add a newly created action, and the position of the newly created action relative to other existing actions.
|
||||
* In the **Keyboard Shortcuts** area, optionally, specify the first and second keystrokes of the action.
|
||||
|
||||

|
||||
|
||||
The IntelliJ Platform generates a `.java` file with the specified class name, registers the newly created action in the plugin.xml file, adds a node to the module tree view, and opens the created action class file in the editor.
|
||||
|
||||
## More Information
|
||||
|
||||
For more information on working with actions, please check out the [action system documentation](/basics/action_system.md)
|
||||
and the [actions tutorial](/tutorials/action_system.md).
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Creating a Plugin Project
|
||||
redirect_from:
|
||||
- /basics/getting_started/creating_an_action.html
|
||||
---
|
||||
|
||||
> **NOTE** For new projects, it is recommend to use [Gradle](/tutorials/build_system.md).
|
||||
@ -32,3 +34,6 @@ For more information, refer to the [IntelliJ IDEA Web Help](https://www.jetbrain
|
||||
|
||||

|
||||
|
||||
### Adding Code to the Project
|
||||
Before running the new project add some code to provide simple functionality.
|
||||
See the [Creating Actions](/tutorials/action_system/working_with_custom_actions.md) tutorial for step-by-step instructions for adding a menu action.
|
||||
|
@ -25,7 +25,7 @@ To set up your plugin development environment:
|
||||

|
||||
<br/>
|
||||
<br/>
|
||||
* Select **1.8** as the default Java SDK. See the _IntelliJ Build Configuration_ section of [Check Out And Build Community Edition](upsource:///README.md) for instructions about creating **1.8** JSDK.
|
||||
* Select **1.8** as the default Java SDK. See the _IntelliJ Build Configuration_ section of [Check Out And Build Community Edition](upsource:///README.md) for instructions about creating **1.8** Java SDK.
|
||||
|
||||

|
||||
<br/>
|
||||
@ -41,7 +41,7 @@ To set up your plugin development environment:
|
||||
<br/>
|
||||
<br/>
|
||||
* Specify the **Sandbox Home** directory.
|
||||
The *Sandbox Home* directory stores the settings of the IDE development instance launched from a Plugin Project's **Run** configration.
|
||||
The *Sandbox Home* directory stores the settings of the IDE development instance launched from a Plugin Project's **Run** configuration.
|
||||
Shown below is the default *Sandbox Home* directory for a user on Mac OS X. Any directory can be chosen as the *Sandbox Home* location.
|
||||
Use the ellipsis button (shown below) to define a custom location.
|
||||
|
||||
|
@ -11,7 +11,7 @@ In this section:
|
||||
|
||||
* [Setting Up a Development Environment](setting_up_environment.md)
|
||||
* [Creating a Plugin Project](creating_plugin_project.md)
|
||||
* [Creating an Action](creating_an_action.md)
|
||||
* [Creating an Action](/tutorials/action_system/working_with_custom_actions.md)
|
||||
* [Running and Debugging a Plugin](running_and_debugging_a_plugin.md)
|
||||
* [Deploying a Plugin](deploying_plugin.md)
|
||||
* [Publishing a plugin to plugin repository](publishing_plugin.md)
|
||||
|
31
basics/plugin_structure/dynamic_plugins.md
Normal file
31
basics/plugin_structure/dynamic_plugins.md
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
title: Dynamic Plugins
|
||||
---
|
||||
|
||||
> **WARNING** Please note that the information on this page is preliminary and might change.
|
||||
|
||||
Starting with 2020.1 release, the ability to install, update and uninstall plugins without restarting the IDE is available in the IntelliJ Platform.
|
||||
|
||||
For a plugin to support this, all restrictions listed below must be met. To verify a plugin locally, run _Plugin DevKit | Plugin descriptor | Plugin.xml dynamic plugin verification_
|
||||
inspection on all plugin descriptor files (required `plugin.xml` as well as any additional files).
|
||||
|
||||
For plugins hosted on the [JetBrains plugin repository](/plugin_repository/index.md) the built-in [Plugin Verifier](https://blog.jetbrains.com/platform/2018/07/plugins-repository-now-integrates-with-the-plugin-verification-tool/)
|
||||
will run these checks automatically.
|
||||
|
||||
### No use of Components
|
||||
No Components must be used; existing ones [must be migrated](plugin_components.md) to services, extensions or listeners.
|
||||
|
||||
### Action Group requires ID
|
||||
All `<group>`s must declare a unique `id`.
|
||||
|
||||
### Use only dynamic Extensions
|
||||
All extensions, whether defined in the platform itself or coming from other plugins, must be marked as dynamic (see next paragraph).
|
||||
|
||||
### Mark Extension Points as dynamic
|
||||
All extension points provided by the plugin must adhere to specific usage rules and then [be declared](plugin_extension_points.md#dynamic-extension-points) ready for dynamic use explicitly.
|
||||
|
||||
### Configurables depending on Extension Points
|
||||
Any `Configurable` which depends on dynamic extension points must implement `Configurable.WithEpDependencies`.
|
||||
|
||||
## Plugin Load/Unload Events
|
||||
Register `com.intellij.ide.plugins.DynamicPluginListener` [listener](plugin_listeners.md) to receive updates on plugin load/unload events.
|
@ -2,7 +2,7 @@
|
||||
title: Plugin Actions
|
||||
---
|
||||
|
||||
The *IntelliJ Platform* provides the concept of _actions_. An action is a class, derived from the [`AnAction`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java) class, whose `actionPerformed` method is called when the menu item or toolbar button is selected.
|
||||
The *IntelliJ Platform* provides the concept of _actions_. An action is a class, derived from the [`AnAction`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java) class, whose `actionPerformed()` method is called when the menu item or toolbar button is selected.
|
||||
|
||||
Actions are the most common way for a user to invoke the functionality of your plugin. An action can be invoked from
|
||||
a menu or a toolbar, using a keyboard shortcut, or from the Find Action interface.
|
||||
|
@ -4,4 +4,4 @@ title: Plugin Class Loaders
|
||||
|
||||
A separate class loader is used to load the classes of each plugin. This allows each plugin to use a different version of a library, even if the same library is used by the IDE itself or by another plugin.
|
||||
|
||||
By default, the main IDE class loader loads classes that were not found in the plugin class loader. However, in the `plugin.xml` file, you may use the `<depends>` element to specify that a plugin depends on one or more other plugins. In this case the class loaders of those plugins will be used for classes not found in the current plugin. This allows a plugin to reference classes from other plugins.
|
||||
By default, the main IDE class loader loads classes that were not found in the plugin class loader. However, in the `plugin.xml` file, you may use the `<depends>` element to specify that a [plugin depends](plugin_class_loaders.md) on one or more other plugins. In this case the class loaders of those plugins will be used for classes not found in the current plugin. This allows a plugin to reference classes from other plugins.
|
||||
|
@ -5,7 +5,7 @@ title: Plugin Components
|
||||
> **WARNING** When writing new plugins, you should avoid creating components, and you should migrate existing components in your plugins to services, extensions or listeners (see below).
|
||||
|
||||
Plugin components are a legacy feature supported for compatibility with plugins created for older versions of the
|
||||
IntelliJ Platform. Plugins using components do not support dynamic loading (the ability to install, update and
|
||||
IntelliJ Platform. Plugins using components do not support [dynamic loading](dynamic_plugins.md) (the ability to install, update and
|
||||
uninstall plugins without restarting the IDE).
|
||||
|
||||
Plugin components are defined using `<application-components>`, `<project-components>` and `<module-components>`
|
||||
@ -19,8 +19,7 @@ To migrate your code from components to more modern APIs, please use the followi
|
||||
and implement the `PersistentStateComponent` interface. See [Persisting State of Components](/basics/persisting_state_of_components.md) for details.
|
||||
* To subscribe to events, use a [listener](plugin_listeners.md) or create an [extension](plugin_extensions.md) for a dedicated extension point (for example, `com.intellij.editorFactoryListener`) if one exists for the event you need to subscribe to.
|
||||
* Executing code on application startup should be avoided whenever possible because it slows down startup.
|
||||
Plugin code should only be executed when projects are opened or when the user invokes an action of your plugin. If you can't avoid this, create
|
||||
an [extension](plugin_extensions.md) for the `com.intellij.appLifecycleListener` extension point.
|
||||
Plugin code should only be executed when projects are opened or when the user invokes an action of your plugin. If you can't avoid this, add a [listener](plugin_listeners.md) subscribing to the [AppLifecycleListener](upsource:///platform/platform-impl/src/com/intellij/ide/AppLifecycleListener.java) topic.
|
||||
* To execute code when a project is being opened, provide [StartupActivity](upsource:///platform/core-api/src/com/intellij/openapi/startup/StartupActivity.java) implementation and register an [extension](plugin_extensions.md) for the `com.intellij.postStartupActivity` or `com.intellij.backgroundPostStartupActivity` extension point (the latter is supported starting with version 2019.3 of the platform).
|
||||
* To execute code on project closing or application shutdown, implement the `Disposable` interface in a [Service](plugin_services.md)
|
||||
and place the code in the `dispose()` method, or use `Disposer.register()` passing a `Project` or `Application` instance
|
||||
|
@ -25,8 +25,8 @@ _myPlugin/META-INF/plugin.xml_
|
||||
<id>my.plugin</id>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint name="myExtensionPoint1" beanClass="com.myplugin.MyBeanClass">
|
||||
<extensionPoint name="myExtensionPoint2" interface="com.myplugin.MyInterface">
|
||||
<extensionPoint name="myExtensionPoint1" beanClass="com.myplugin.MyBeanClass"/>
|
||||
<extensionPoint name="myExtensionPoint2" interface="com.myplugin.MyInterface"/>
|
||||
</extensionPoints>
|
||||
|
||||
</idea-plugin>
|
||||
@ -99,4 +99,19 @@ public class MyExtensionUsingService {
|
||||
}
|
||||
}
|
||||
```
|
||||
A gutter icon for the `ExtensionPointName` declaration allows navigating to the corresponding `<extensionPoint>` declaration in `plugin.xml`.
|
||||
A gutter icon for the `ExtensionPointName` declaration allows navigating to the corresponding `<extensionPoint>` declaration in `plugin.xml`.
|
||||
|
||||
## Dynamic extension points
|
||||
To support [Dynamic Plugins](dynamic_plugins.md) (2020.1 and later), an extension point must adhere to specific usage rules:
|
||||
|
||||
- extensions are enumerated on every use and extensions instances are not stored anywhere
|
||||
- alternatively, an `ExtensionPointChangeListener` can perform necessary updates of data structures (register via `ExtensionPointName#addExtensionPointListener()`)
|
||||
|
||||
Extension points matching these conditions can then be marked as _dynamic_ by adding `dynamic="true"` in their declaration:
|
||||
```xml
|
||||
<extensionPoints>
|
||||
<extensionPoint name="myDynamicExtensionPoint" beanClass="com.myplugin.MyBeanClass" dynamic="true" />
|
||||
</extensionPoints>
|
||||
```
|
||||
|
||||
> **NOTE** All non-dynamic extension points are highlighted via _Plugin DevKit \| Plugin descriptor \| Plugin.xml dynamic plugin verification_ inspection available in IntelliJ IDEA 2020.1 or later. Previous versions also highlight `dynamic` attribute as "experimental".
|
||||
|
@ -2,11 +2,30 @@
|
||||
title: Plugin Services
|
||||
---
|
||||
|
||||
A _service_ is a plugin component loaded on demand when your plugin calls the `getService` method of the [`ServiceManager`](upsource:///platform/core-api/src/com/intellij/openapi/components/ServiceManager.java) class.
|
||||
A _service_ is a plugin component loaded on demand when your plugin calls the `getService()` method of the [`ServiceManager`](upsource:///platform/core-api/src/com/intellij/openapi/components/ServiceManager.java) class.
|
||||
|
||||
The *IntelliJ Platform* ensures that only one instance of a service is loaded even though the service is called several times. A service must have an implementation class which is used for service instantiation. A service may also have an interface class which is used to obtain the service instance and provides API of the service. The interface and implementation classes are specified in the `plugin.xml` file.
|
||||
The *IntelliJ Platform* ensures that only one instance of a service is loaded even though the service is called several times.
|
||||
|
||||
The *IntelliJ Platform* offers three types of services: _application level_ services, _project level_ services and _module level_ services.
|
||||
A service must have an implementation class which is used for service instantiation.
|
||||
A service may also have an interface class which is used to obtain the service instance and provides API of the service. The interface and implementation classes are specified in the `plugin.xml` file.
|
||||
|
||||
The *IntelliJ Platform* offers three types of services: _application level_ services, _project level_ services, and _module level_ services.
|
||||
|
||||
Please consider not using module level services because it can lead to increased memory usage for projects with many modules.
|
||||
|
||||
## Light Services
|
||||
|
||||
> **NOTE** Light Services are available since IntelliJ Platform 2019.3.
|
||||
|
||||
A service not going to be overridden does not need to be registered in `plugin.xml` (see [How To Declare a Service](#how-to-declare-a-service)).
|
||||
|
||||
Instead, annotate service class with [@Service](upsource:///platform/core-api/src/com/intellij/openapi/components/Service.java). If service is written in Java and not Kotlin, mark class as `final`.
|
||||
|
||||
Restrictions:
|
||||
|
||||
* Constructor injection is not supported (since it is deprecated), but project level service can define a constructor that accepts `Project`, and module level service `Module` respectively.
|
||||
* If service is a [PersistentStateComponent](/basics/persisting_state_of_components.md), roaming must be disabled (`roamingType` is set to `RoamingType.DISABLED`).
|
||||
* Service class must be `final`.
|
||||
|
||||
## How to Declare a Service?
|
||||
|
||||
@ -20,9 +39,9 @@ To declare a service, you can use the following extension points in the IntelliJ
|
||||
|
||||
1. In your project, open the context menu of the destination package and click *New* (or press <kbd>Alt</kbd>+<kbd>Insert</kbd>).
|
||||
2. In the *New* menu, choose *Plugin DevKit* and click *Application Service*, *Project Service* or *Module Service* depending on the type of service you need to use.
|
||||
3. In the dialog box that opens, you can specify service interface and implementation, or just a service class if you uncheck *Separate interface from implementation* check box.
|
||||
3. In the dialog box that opens, you can specify service interface and implementation, or just a service class if you uncheck *Separate interface from implementation* checkbox.
|
||||
|
||||
The IDE will generate new Java interface and class (or just a class if you unchecked *Separate interface from implementation* check box) and register the new service in `plugin.xml` file.
|
||||
The IDE will generate new Java interface and class (or just a class if you unchecked *Separate interface from implementation* checkbox) and register the new service in `plugin.xml` file.
|
||||
|
||||
> **Note** Declaring a service via *New* context menu is available since version **2017.3**.
|
||||
|
||||
@ -32,12 +51,12 @@ To clarify the service declaration procedure, consider the following fragment of
|
||||
```xml
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<!-- Declare the application level service -->
|
||||
<applicationService serviceInterface="Mypackage.MyApplicationService"
|
||||
serviceImplementation="Mypackage.MyApplicationServiceImpl" />
|
||||
<applicationService serviceInterface="mypackage.MyApplicationService"
|
||||
serviceImplementation="mypackage.MyApplicationServiceImpl" />
|
||||
|
||||
<!-- Declare the project level service -->
|
||||
<projectService serviceInterface="Mypackage.MyProjectService"
|
||||
serviceImplementation="Mypackage.MyProjectServiceImpl" />
|
||||
<projectService serviceInterface="mypackage.MyProjectService"
|
||||
serviceImplementation="mypackage.MyProjectServiceImpl" />
|
||||
</extensions>
|
||||
```
|
||||
|
||||
@ -45,14 +64,21 @@ If `serviceInterface` isn't specified, it's supposed to have the same value as `
|
||||
|
||||
## Retrieving a service
|
||||
|
||||
To instantiate your service, in Java code, use the following syntax:
|
||||
Getting service doesn't need read action and can be performed from any thread. If service is requested from several threads, it will be initialized in the first thread, and other threads will be blocked until service is fully initialized.
|
||||
|
||||
To instantiate your service in Java code:
|
||||
|
||||
```java
|
||||
MyApplicationService applicationService = ServiceManager.getService(MyApplicationService.class);
|
||||
|
||||
MyProjectService projectService = ServiceManager.getService(project, MyProjectService.class);
|
||||
MyProjectService projectService = project.getService(MyProjectService.class)
|
||||
```
|
||||
|
||||
MyModuleService moduleService = ModuleServiceManager.getService(module, MyModuleService.class);
|
||||
In Kotlin code, you can use convenience methods:
|
||||
```kotlin
|
||||
MyApplicationService applicationService = service<MyApplicationService>()
|
||||
|
||||
MyProjectService projectService = project.service<MyProjectService>()
|
||||
```
|
||||
|
||||
### Sample Plugin
|
||||
|
@ -4,7 +4,7 @@ title: Test Project and Testdata Directories
|
||||
|
||||
The test fixture creates a *test project* environment. Unless you customize the project creation, the test project will have one module with one source root called `src`. The files for the test project exist either in a temporary directory or in an in-memory file system, depending on which implementation of [`TempDirTestFixture`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/TempDirTestFixture.java) is used.
|
||||
|
||||
[`LightPlatformCodeInsightFixtureTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/LightPlatformCodeInsightFixtureTestCase.java) (renamed to `BasePlatformTestCase` in 2019.2) uses an in-memory implementation; if you set up the test environment by calling `IdeaTestFixtureFactory.createCodeInsightFixture`, you can specify the implementation to use.
|
||||
[`LightPlatformCodeInsightFixtureTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/LightPlatformCodeInsightFixtureTestCase.java) (renamed to `BasePlatformTestCase` in 2019.2) uses an in-memory implementation; if you set up the test environment by calling `IdeaTestFixtureFactory.createCodeInsightFixture()`, you can specify the implementation to use.
|
||||
|
||||
> **WARNING** If your tests use the in-memory implementation, and you abort the execution of your tests, the persisted filesystem caches may get out of sync with the in-memory structures, and you may get spurious errors in your tests.
|
||||
> If you get an unexpected error after a series of successful runs, **try rerunning the test**, and if that doesn't help, **delete the "system" subdirectory** in your [sandbox directory](/basics/ide_development_instance.md#the-development-instance-sandbox-directory).
|
||||
|
@ -18,7 +18,7 @@ In a product with 15+ years of lifetime that has gone through a large number of
|
||||
Another consequence of our testing approach is what our test framework does not provide:
|
||||
|
||||
* We do not provide a recommended approach to mocking. We have a few tests in our codebase that use JMock, but in general, we find it difficult to mock all of the interactions with *IntelliJ Platform* components that your plugin class will need to have, and we recommend working with real components instead.
|
||||
* We do not provide a general-purpose framework for Swing UI testing. You can try using tools such as [FEST](https://code.google.com/p/fest/) or [Sikuli](http://sikulix.com/) for plugin UI testing, but we don't use either of them and cannot provide any guidelines for their use. Internally, we use manual testing for testing our Swing UIs.
|
||||
* We do not provide a general-purpose framework for Swing UI testing. You can try using tools such as [FEST](https://code.google.com/p/fest/) or [Sikuli](http://sikulix.com/) for plugin UI testing, but we don't use either of them and cannot provide any guidelines for their use. Internally, we use manual testing for testing our Swing UIs. Please do not use _platform/testGuiFramework_, it is reserved for internal use.
|
||||
|
||||
## Topics
|
||||
* [Tests and Fixtures](tests_and_fixtures.md)
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.15'
|
||||
id 'org.jetbrains.intellij' version '0.4.16'
|
||||
}
|
||||
|
||||
group 'org.intellij.sdk'
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.15'
|
||||
id 'org.jetbrains.intellij' version '0.4.16'
|
||||
}
|
||||
|
||||
group 'org.intellij.sdk'
|
||||
|
@ -14,20 +14,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @see com.intellij.openapi.actionSystem.AnAction
|
||||
*/
|
||||
public class EditorHandlerIllustration extends AnAction {
|
||||
|
||||
/**
|
||||
* This block of static code does not pertain to this class.
|
||||
* It registers the custom MyTypedHandler, a TypedActionHandler
|
||||
* that handles actions activated by typing in the editor.
|
||||
* This registration code just needs to appear in a class (like AnAction class)
|
||||
* that gets instantiated as part of IntelliJ startup.
|
||||
*/
|
||||
static {
|
||||
final EditorActionManager actionManager = EditorActionManager.getInstance();
|
||||
final TypedAction typedAction = actionManager.getTypedAction();
|
||||
typedAction.setupHandler(new MyTypedHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones a new caret at a higher Logical Position line number.
|
||||
* @param e Event related to this action
|
||||
|
@ -2,31 +2,30 @@
|
||||
|
||||
package org.intellij.sdk.editor;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* This is a custom TypedActionHandler that handles actions activated
|
||||
* This is a custom TypedHandlerDelegate that handles actions activated
|
||||
* keystrokes in the editor.
|
||||
* The execute method inserts a fixed string at Offset 0 of the document.
|
||||
* Document changes are made in the context of a write action.
|
||||
* MyTypedHandler is registered by static code in the EditorHandlerIllustration class.
|
||||
*
|
||||
* @see com.intellij.openapi.editor.actionSystem.TypedActionHandler
|
||||
*/
|
||||
class MyTypedHandler implements TypedActionHandler {
|
||||
class MyTypedHandler extends TypedHandlerDelegate {
|
||||
@NotNull
|
||||
@Override
|
||||
public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext) {
|
||||
public Result charTyped(char c, @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
|
||||
// Get the document and project
|
||||
final Document document = editor.getDocument();
|
||||
final Project project = editor.getProject();
|
||||
// Construct the runnable to substitute the string at offset 0 in the document
|
||||
Runnable runnable = () -> document.insertString(0, "editor_basics\n");
|
||||
// Make the document change in the context of a write action.
|
||||
WriteCommandAction.runWriteCommandAction(project, runnable);
|
||||
return Result.STOP;
|
||||
}
|
||||
}
|
||||
|
@ -61,4 +61,8 @@
|
||||
</action>
|
||||
</actions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<typedHandler implementation="org.intellij.sdk.editor.MyTypedHandler"/>
|
||||
</extensions>
|
||||
|
||||
</idea-plugin>
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.15'
|
||||
id 'org.jetbrains.intellij' version '0.4.16'
|
||||
}
|
||||
|
||||
group 'org.intellij.sdk'
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.15'
|
||||
id 'org.jetbrains.intellij' version '0.4.16'
|
||||
}
|
||||
|
||||
group 'org.intellij.sdk'
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id "org.jetbrains.intellij" version "0.4.15"
|
||||
id "org.jetbrains.intellij" version "0.4.16"
|
||||
}
|
||||
|
||||
group 'org.intellij.sdk'
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.15'
|
||||
id 'org.jetbrains.intellij' version '0.4.16'
|
||||
}
|
||||
|
||||
group 'org.intellij.sdk'
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.15'
|
||||
id 'org.jetbrains.intellij' version '0.4.16'
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.3.60'
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.15'
|
||||
id 'org.jetbrains.intellij' version '0.4.16'
|
||||
}
|
||||
|
||||
group 'com.intellij.sdk'
|
||||
|
@ -27,16 +27,19 @@ public class SimpleParserDefinition implements ParserDefinition {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TokenSet getCommentTokens() {
|
||||
return COMMENTS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TokenSet getStringLiteralElements() {
|
||||
return TokenSet.EMPTY;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiParser createParser(final Project project) {
|
||||
return new SimpleParser();
|
||||
}
|
||||
@ -46,16 +49,19 @@ public class SimpleParserDefinition implements ParserDefinition {
|
||||
return FILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile createFile(FileViewProvider viewProvider) {
|
||||
return new SimpleFile(viewProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode right) {
|
||||
return SpaceRequirements.MAY;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement createElement(ASTNode node) {
|
||||
return SimpleTypes.Factory.createElement(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
31
code_samples/tree_structure_provider/build.gradle
Normal file
31
code_samples/tree_structure_provider/build.gradle
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.16'
|
||||
}
|
||||
|
||||
group 'org.intellij.sdk'
|
||||
version '2.0.0'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
}
|
||||
|
||||
// See https://github.com/JetBrains/gradle-intellij-plugin/
|
||||
intellij {
|
||||
version '2019.2.4'
|
||||
updateSinceUntilBuild = false
|
||||
}
|
||||
patchPluginXml {
|
||||
version = project.version
|
||||
}
|
||||
|
||||
// Force javadoc rebuild before jar is built
|
||||
jar.dependsOn javadoc
|
BIN
code_samples/tree_structure_provider/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
code_samples/tree_structure_provider/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
code_samples/tree_structure_provider/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
code_samples/tree_structure_provider/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
188
code_samples/tree_structure_provider/gradlew
vendored
Executable file
188
code_samples/tree_structure_provider/gradlew
vendored
Executable file
@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
100
code_samples/tree_structure_provider/gradlew.bat
vendored
Normal file
100
code_samples/tree_structure_provider/gradlew.bat
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
2
code_samples/tree_structure_provider/settings.gradle
Normal file
2
code_samples/tree_structure_provider/settings.gradle
Normal file
@ -0,0 +1,2 @@
|
||||
rootProject.name = 'tree_structure_provider'
|
||||
|
@ -33,7 +33,7 @@ public class TextOnlyTreeStructureProvider implements TreeStructureProvider {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(Collection<AbstractTreeNode> collection, String s) {
|
||||
public Object getData(@NotNull Collection<AbstractTreeNode> selected, @NotNull String dataId) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PLUGIN_MODULE" version="4">
|
||||
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" />
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -12,20 +12,9 @@ That question might be broad or narrowly-focused, but either way, our goal is to
|
||||
|
||||
The style of the _Intellij Platform SDK_ documentation is captured by using a markup language named [_Markdown_](https://github.github.com/gfm/).
|
||||
The following sections describe the SDK documentation style in terms of the Markdown formats:
|
||||
* [Documentation Markup Style](#documentation-markup-style)
|
||||
* [Page Format](#page-format)
|
||||
* [Redirects](#redirects)
|
||||
* [Table of Contents for a Page](#table-of-contents-for-a-page)
|
||||
* [Text Format Conventions](#text-format-conventions)
|
||||
* [Liquid tags and filters](#liquid-tags-and-filters)
|
||||
* [Syntax highlighting](#syntax-highlighting)
|
||||
* [Tables](#tables)
|
||||
* [Links](#links)
|
||||
* [Callouts](#notes-and-callouts)
|
||||
* [Images](#images)
|
||||
* [_SUMMARY.md Site Table of Contents](#summary-site-table-of-contents)
|
||||
* [Repository Submodules](#repository-submodules)
|
||||
|
||||
* bullet list
|
||||
{:toc}
|
||||
|
||||
## Documentation Markup Style
|
||||
By default, when building the site, all files are copied to the destination `_site` folder.
|
||||
|
@ -27,7 +27,7 @@ As described in [Modules Specific to Functionality](/basics/getting_started/plug
|
||||
```
|
||||
|
||||
## Available CLion APIs
|
||||
Use the [Exploring APIs as a Consumer](/basics/getting_started/plugin_compatibility.html#exploring-apis-as-a-consumer) process to identify the JAR files under the External Library `Gradle:com.jetbrains:clion:<version>`.
|
||||
Use the [Exploring APIs as a Consumer](/basics/getting_started/plugin_compatibility.md#exploring-apis-as-a-consumer) process to identify the JAR files under the External Library `Gradle:com.jetbrains:clion:<version>`.
|
||||
Test your plugin with versions of CLion you intend to support.
|
||||
|
||||
## Open Source Plugins for CLion
|
||||
|
@ -2,17 +2,39 @@
|
||||
title: PhpStorm Plugin Development
|
||||
redirect_from:
|
||||
- /phpstorm/phpstorm.html
|
||||
- /phpstorm/setting_up_environment.html
|
||||
- /products/phpstorm/setting_up_environment.html
|
||||
---
|
||||
|
||||
### Development and Testing Tools
|
||||
Plugins for PhpStorm are developed in Java using either edition of IntelliJ IDEA. The Community Edition of IntelliJ IDEA can
|
||||
be used for developing, but not testing, a PhpStorm plugin. Although IntelliJ IDEA Ultimate Edition (with the PHP plugin) can be
|
||||
used for testing PhpStorm plugins, the recommended approach is to use PhpStorm for testing.
|
||||
|
||||
## Introduction
|
||||
PhpStorm is an IntelliJ Platform-based product.
|
||||
Plugins for PhpStorm are developed in Java using the Ultimate edition of IntelliJ IDEA.
|
||||
The [PsiViewer plugin](https://plugins.jetbrains.com/plugin/227-psiviewer) is also recommended.
|
||||
|
||||
### PhpStorm Specifics
|
||||
|
||||
* [Setting-up the environment](setting_up_environment.md)
|
||||
* [PHP Open API](php_open_api.md)
|
||||
This page describes configuring plugin projects targeting PhpStorm.
|
||||
See also:
|
||||
* [Working with the PHP Open API](php_open_api.md)
|
||||
* [Example Third Party PhpStorm plugins](existing_plugins.md)
|
||||
|
||||
## Configuring Plugin Projects Targeting PhpStorm
|
||||
The IntelliJ IDEA Ultimate Edition (with the PHP plugin) must be used for developing PhpStorm plugins because the PHP plugin is incompatible with IntelliJ IDEA Community Edition.
|
||||
However, this IntelliJ IDEA Ultimate configuration runs the risk of accidentally using some APIs that are not available in PhpStorm.
|
||||
The recommended best practice is to use PhpStorm for testing.
|
||||
|
||||
> **Note** The OpenAPI is available for PhpStorm 6 and above.
|
||||
|
||||
Configuration of a Gradle-based PhpStorm plugin project is used as a tutorial in the section [Configuring Plugin Projects using the IntelliJ IDEA Product Attribute](/products/dev_alternate_products.md#configuring-plugin-projects-using-the-intellij-idea-product-attribute).
|
||||
Many techniques are discussed, such as choosing a version of IntelliJ IDEA Ultimate given a targeted version of PhpStorm.
|
||||
The table below summarizes the `gradle-intellij-plugin` attributes to set in the `build.gradle` file for a PhpStorm plugin project:
|
||||
|
||||
| `gradle-intellij-plugin` Attribute | <br>Attribute Value |
|
||||
|-----------|-------|
|
||||
| [`intellij.type`](https://github.com/JetBrains/gradle-intellij-plugin/blob/master/README.md#intellij-platform-properties) | `IU` for IntelliJ IDEA Ultimate. (The required PHP plugin isn't compatible with IntelliJ IDEA Community Edition.) |
|
||||
| [`intellij.version`](https://github.com/JetBrains/gradle-intellij-plugin/blob/master/README.md#intellij-platform-properties) | Set to the same `IU` BRANCH.BUILD as the PhpStorm target version, e.g. `193.5233.102` |
|
||||
| [`intellij.plugins`](https://github.com/JetBrains/gradle-intellij-plugin/blob/master/README.md#intellij-platform-properties) | `com.jetbrains.php:193.5233.102` for the PHP plugin.<br>See below for PHP plugin version information. |
|
||||
| [`runIde.ideaDirectory`](https://github.com/JetBrains/gradle-intellij-plugin/blob/master/README.md#running-dsl) | Path to locally installed target version of PhpStorm. For example, on macOS:<br>`/Users/<user name>/Library/Application Support/JetBrains/Toolbox/apps/PhpStorm/ch-0/193.5233.101/PhpStorm.app/Contents` |
|
||||
|
||||
The version of the PHP plugin is explicitly declared because it isn't bundled with IntelliJ IDEA Ultimate Edition.
|
||||
Select a [version](https://plugins.jetbrains.com/plugin/6610-php/versions) of the PHP plugin that is compatible with the `intellij.version`.
|
||||
|
||||
The dependency on the PHP plugin APIs must be declared in the `plugin.xml` file, as shown in the tutorial [Configuring plugin.xml](/products/dev_alternate_products.md#configuring-pluginxml) section.
|
||||
|
@ -1,29 +0,0 @@
|
||||
---
|
||||
title: Setting-up the Environment for PhpStorm Plugin Development
|
||||
redirect_from:
|
||||
- /phpstorm/setting_up_environment.html
|
||||
---
|
||||
|
||||
### General information
|
||||
Please familiarize yourself with the [Getting Started with Plugin Development](/basics/getting_started.md)
|
||||
section of this guide.
|
||||
|
||||
If you are using a [DevKit](/basics/getting_started/using_dev_kit.md)
|
||||
workflow to develop plugins for PhpStorm, the recommended approach is to base the plugin project SDK on an installation
|
||||
of PhpStorm. An alternative approach is to base the plugin project SDK on an installation of IntelliJ IDEA Ultimate with the PHP plugin.
|
||||
However, this runs the risk of accidentally using some APIs which are not available in PhpStorm.
|
||||
|
||||
### How to use the PhpStorm OpenAPI Library for Plugin Development
|
||||
|
||||
> **Note** The OpenAPI is available for PhpStorm 6 and above.
|
||||
|
||||
The [Plugin Dependencies](/basics/plugin_structure/plugin_dependencies.md) page describes adding dependencies to the
|
||||
DevKit as well as Gradle development environments. Follow the instructions to:
|
||||
|
||||
* Add the PHP OpenAPI classes to the classpath of your plugin:
|
||||
* For Gradle-based plugin development, add the `com.jetbrains.php` plugin ID to your build.gradle file.
|
||||
* For DevKit-based plugin development, add the `php-openapi.jar` and `php.jar` libraries to the classpath of your project's SDK.
|
||||
These libraries are located in `<your_installation_of_PhpStorm>/plugins/php/lib` directory.
|
||||
|
||||
* Add the `com.jetbrains.php` and `com.intellij.modules.platform` dependencies
|
||||
to the your plugin project's `plugin.xml` file.
|
@ -24,7 +24,7 @@ As described in [Modules Specific to Functionality](/basics/getting_started/plug
|
||||
Consequently, without the `com.intellij.modules.platform` declaration the plugin is assumed to be a [legacy plugin](/basics/getting_started/plugin_compatibility.md#declaring-plugin-dependencies) and will not load in WebStorm.
|
||||
|
||||
## Available WebStorm APIs
|
||||
Use the [Exploring APIs as a Consumer](/basics/getting_started/plugin_compatibility.html#exploring-apis-as-a-consumer) process to identify the libraries `JavaScriptLanguage.jar`, and `javascript-openapi.jar`.
|
||||
Use the [Exploring APIs as a Consumer](/basics/getting_started/plugin_compatibility.md#exploring-apis-as-a-consumer) process to identify the libraries `JavaScriptLanguage.jar`, and `javascript-openapi.jar`.
|
||||
Test your plugin with any version of WebStorm you wish to support.
|
||||
|
||||
## Open Source Plugins for WebStorm
|
||||
|
@ -36,6 +36,7 @@ The following problem patterns are supported:
|
||||
<class name>.<field name> field type changed from <before> to <after>
|
||||
<class name>.<field name> field visibility changed from <before> to <after>
|
||||
|
||||
<class name>.<method name>(<human-readable parameters>) marked abstract
|
||||
<class name>.<method name>(<human-readable parameters>) abstract method added
|
||||
<class name> class moved to package <package name>
|
||||
|
||||
@ -69,6 +70,9 @@ Please see [Incompatible API Changes](/reference_guide/api_changes_list.md) on h
|
||||
`com.intellij.compiler.ant` package removed
|
||||
: 'Generate Ant build' functionality is removed from the IDE. Delete the code extending this or replace it with a dependency on the `generate-ant` plugin.
|
||||
|
||||
`org.jetbrains.jps.incremental.ModuleLevelBuilder.getCompilableFileExtensions` marked abstract
|
||||
: Implement it in `ModuleLevelBuilder`'s implementation.
|
||||
|
||||
`com.intellij.codeInsight.TargetElementUtilBase` class removed
|
||||
: Use `com.intellij.codeInsight.TargetElementUtil` instead.
|
||||
|
||||
@ -106,4 +110,10 @@ Please see [Incompatible API Changes](/reference_guide/api_changes_list.md) on h
|
||||
: This may break source-compatibility with inheritors written in Kotlin if they declare parameter type as nullable.
|
||||
|
||||
`com.intellij.codeInspection.unused.ImplicitPropertyUsageProvider.isUsed` method `Property` parameter marked `@NotNull`
|
||||
: This may break source-compatibility with inheritors written in Kotlin if they declare parameter type as nullable.
|
||||
: This may break source-compatibility with inheritors written in Kotlin if they declare parameter type as nullable.
|
||||
|
||||
`com.intellij.lang.ReadOnlyASTNode` class removed
|
||||
: Use `com.intellij.testFramework.ReadOnlyLightVirtualFile`-based PSI instead.
|
||||
|
||||
Java code migrated to use `TYPE_USE` nullability annotations
|
||||
: Due to some problems in Kotlin compiler existing Kotlin code might become incompilable in rare cases if a method written in Java returning an array and annotated as `@Nullable` or `@NotNull` is used or overridden.
|
||||
|
@ -38,6 +38,7 @@ The following problem patterns are supported:
|
||||
<class name>.<field name> field type changed from <before> to <after>
|
||||
<class name>.<field name> field visibility changed from <before> to <after>
|
||||
|
||||
<class name>.<method name>(<human-readable parameters>) marked abstract
|
||||
<class name>.<method name>(<human-readable parameters>) abstract method added
|
||||
<class name> class moved to package <package name>
|
||||
|
||||
|
@ -5,6 +5,9 @@ title: Notable Changes in IntelliJ Platform and Plugins API 2020.*
|
||||
# 2020.1
|
||||
|
||||
## Notable Changes in IntelliJ Platform 2020.1
|
||||
Dynamic Plugins
|
||||
: [Compatible plugins](/basics/plugin_structure/dynamic_plugins.md) can be installed, updated and uninstalled without requiring IDE restart.
|
||||
|
||||
[`com.intellij.openapi.application.TransactionGuard`](upsource:///platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java) deprecated
|
||||
: Usage is deprecated and can be replaced with `com.intellij.openapi.application.Application.invokeLater()` in most cases, please consult Javadoc for more details.
|
||||
|
||||
@ -12,3 +15,6 @@ title: Notable Changes in IntelliJ Platform and Plugins API 2020.*
|
||||
: Please see `RecursionManager.CachingPreventedException` Javadoc and [this issue](https://youtrack.jetbrains.com/issue/IDEA-228809) for details.
|
||||
|
||||
## Notable Changes in IntelliJ IDEA
|
||||
|
||||
EOL for JetBrains TFS Plugin
|
||||
: Please use [Azure DevOps](https://plugins.jetbrains.com/plugin/7981-azure-devops) plugin instead, see [blog post](https://blog.jetbrains.com/idea/2020/01/end-of-support-for-tfs-2014-and-older/) for more details.
|
@ -45,10 +45,10 @@ If the scheme designer doesn't have a language plug-in, he will not be able to f
|
||||
## Providing Attributes for Specific Schemes
|
||||
|
||||
A language plug-in may provide default text attributes for "Default" and "Darcula" bundled schemes or basically for any other scheme if the scheme's name is known.
|
||||
This can be done in `plugin.xml` by adding an extension with a name of the file containing desired text attributes, for example:
|
||||
This can be done in `plugin.xml` by adding an `com.intellij.additionalTextAttributes` extension providing the name of the file containing desired text attributes, for example:
|
||||
|
||||
```xml
|
||||
<extensions ...>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
..
|
||||
<additionalTextAttributes scheme="Default" file="colorSchemes/MyLangDefault.xml"/>
|
||||
..
|
||||
|
@ -16,6 +16,8 @@ source code.
|
||||
If you prefer a full example to the detailed description offered on this page, please check out a step-by-step tutorial how to define custom language support on example of ".properties" files:
|
||||
[Custom Language Support Tutorial](/tutorials/custom_language_support_tutorial.md)
|
||||
|
||||
The webinar [How We Built Comma, the Raku IDE, on the IntelliJ Platform](https://blog.jetbrains.com/platform/2020/01/webinar-recording-how-we-built-comma-the-raku-ide-on-the-intellij-platform/) offers an excellent introduction as well.
|
||||
|
||||
Providing custom language support includes the following major steps:
|
||||
|
||||
* [Registering File Type](/reference_guide/custom_language_support/registering_file_type.md)
|
||||
|
@ -40,7 +40,7 @@ The core scenario of using
|
||||
consists of calling the `extend()` method and passing in the *pattern* specifying the context in which this completion variant is applicable, as well as a *completion provider* which generates the items to show in the completion list.
|
||||
|
||||
Keep in mind that the pattern is checked against the leaf PSI element. If you
|
||||
want to match a composite element, use `withParent` or `withSuperParent`
|
||||
want to match a composite element, use `withParent()` or `withSuperParent()`
|
||||
methods.
|
||||
|
||||
**Examples**:
|
||||
|
@ -36,7 +36,6 @@ The intention classes need to implement the
|
||||
[`IntentionAction`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java)
|
||||
interface and to be registered using the `com.intellij.intentionAction` extension point in your *plugin.xml*.
|
||||
|
||||
**Example:**
|
||||
A
|
||||
[simple intention action](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitIfIntention.java)
|
||||
for Groovy
|
||||
**Examples:**
|
||||
- A [simple intention action](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitIfIntention.java) for Groovy
|
||||
- [Custom Language Support Tutorial: Quick Fix](/tutorials/custom_language_support/quick_fix.md)
|
||||
|
@ -50,7 +50,7 @@ mechanism to support plugins. There are several service interfaces (e.g. [`Build
|
||||
|
||||
### Registering a plugin for External Builder
|
||||
|
||||
Sources of a plugin for External Builder should be put in a separate module. By convention such module has name '...-jps-plugin' and its sources are placed under 'jps-plugin' directory in the main plugin directory. Use `<compileServer.plugin>` extension to add the plugin to classpath of external build process, the plugin jar should be named `<jps module name>.jar`. 'Build' \| 'Prepare Plugin Module for deployment' action will automatically pack 'jps-plugin' part to a separate jar accordingly.
|
||||
Sources of a plugin for External Builder should be put in a separate module. By convention such module has name '...-jps-plugin' and its sources are placed under 'jps-plugin' directory in the main plugin directory. Use `com.intellij.compileServer.plugin` extension to add the plugin to classpath of external build process, the plugin jar should be named `<jps module name>.jar`. 'Build' \| 'Prepare Plugin Module for deployment' action will automatically pack 'jps-plugin' part to a separate jar accordingly.
|
||||
|
||||
### Debugging a plugin for External Builder
|
||||
|
||||
@ -114,7 +114,7 @@ In IntelliJ Platform versions before version 14.1 log4j configuration was stored
|
||||
The project model in External Build process is provided by JPS (*JetBrains Project System*).
|
||||
A project is represented by [`JpsProject`](upsource:///jps/model-api/src/org/jetbrains/jps/model/JpsProject.java), a module by [`JpsModule`](upsource:///jps/model-api/src/org/jetbrains/jps/model/JpsProject.java) and so on.
|
||||
If your compiler depends on something that isn't added to the model yet (e.g. some facet settings),
|
||||
you need to extend the JPS model (use `JpsGwtModuleExtension` as a reference implementation) and provide implementation of
|
||||
you need to extend the JPS model (use `JpsOsmorcModuleExtension` as a reference implementation) and provide implementation of
|
||||
[`JpsModelSerializerExtension`](upsource:///jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java) to load the configuration from project files.
|
||||
|
||||
#### Implementing builder
|
||||
|
@ -22,7 +22,7 @@ That means that we can separate external system-specific logic and general IDE p
|
||||
## Project data domain
|
||||
|
||||
**General**
|
||||
External system wrapper is required to be able to build project info on the basis of the given external system config. That information is built using in terms of [`DataNode`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java), [Key](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/model/Key.java) and [ExternalEntityData](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalEntityData.java).
|
||||
External system wrapper is required to be able to build project info on the basis of the given external system config. That information is built using in terms of [`DataNode`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java), [`Key`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/model/Key.java) and [`ExternalEntityData`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalEntityData.java).
|
||||
|
||||

|
||||
|
||||
@ -46,7 +46,7 @@ The good thing is that we can separate project parsing and management here. That
|
||||
|
||||
## Importing from external model
|
||||
|
||||
IntelliJ platform provides standard API for that. Namely, [`ProjectImportBuilder`](upsource:///java/idea-ui/src/com/intellij/projectImport/ProjectImportBuilder.java) and [ProjectImportProvider](upsource:///java/idea-ui/src/com/intellij/projectImport/ProjectImportProvider.java). There are two classes built on *template method* pattern - [AbstractExternalProjectImportBuilder](upsource:///java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java) and [AbstractExternalProjectImportProvider](upsource:///java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportProvider.java). They might be sub-classes and that concrete implementations should be registered at IoC descriptor (plugin.xml).
|
||||
IntelliJ platform provides standard API for that. Namely, [`ProjectImportBuilder`](upsource:///java/idea-ui/src/com/intellij/projectImport/ProjectImportBuilder.java) and [`ProjectImportProvider`](upsource:///java/idea-ui/src/com/intellij/projectImport/ProjectImportProvider.java). There are two classes built on *template method* pattern - [`AbstractExternalProjectImportBuilder`](upsource:///java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java) and [`AbstractExternalProjectImportProvider`](upsource:///java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportProvider.java). They might be sub-classes and that concrete implementations should be registered at IoC descriptor (plugin.xml).
|
||||
|
||||
Here is an example from the gradle integration plugin:
|
||||
|
||||
@ -57,13 +57,27 @@ Note that [`AbstractExternalProjectImportBuilder`](upsource:///java/idea-ui/src/
|
||||
|
||||
## Auto-import
|
||||
|
||||
It's possible to configure external system integration to automatically refresh project structure when external project's config file is modified. Basically, end-user should check corresponding box at external system settings for that:
|
||||
It's possible to configure external system integration to automatically refresh project structure when external project's config files are modified.
|
||||
|
||||

|
||||
> **TIP** Since 2020.1, auto-import cannot be disabled by user.
|
||||
|
||||
Built-in support covers only root config files of linked external projects. However, there is a possible situation that particular external project has more config files which affect resulting project structure as well (for example, it might be a multi-project where every sub-project has its own config file). That's why it's possible to enhance that processing by making target external system implementation (*ExternalSystemManager*) implement *ExternalSystemAutoImportAware*. That allows to provide custom logic for mapping file modification events to the target external project affected by that.
|
||||
### Auto-Import for `ExternalSystemManager` implementation
|
||||
|
||||
Describe project's settings files to track by having external system `ExternalSystemManager` implement [`ExternalSystemAutoImportAware`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemAutoImportAware.java).
|
||||
|
||||
> **NOTE** `ExternalSystemAutoImportAware.getAffectedExternalProjectPath()` is called quite often, that’s why it’s expected to return control as soon as possible. Helper `CachingExternalSystemAutoImportAware` class might be used for caching, i.e. `ExternalSystemManager` which implements `ExternalSystemAutoImportAware` can have a field like `new CachingExternalSystemAutoImportAware(new MyExternalSystemAutoImportAware())` and delegate `ExternalSystemAutoImportAware.getAffectedExternalProjectPath()` calls to it.
|
||||
|
||||
### Auto-Import for standalone external systems
|
||||
|
||||
Some external systems don’t have `ExternalSystemManager` (e.g., Maven), but they also can use auto-import core to track changes in settings files. For this, implement `ExternalSystemProjectAware` interface that describes settings files for tracking and an action to reload project model.
|
||||
Then register the instance with `ExternalSystemProjectTracker` to start tracking.
|
||||
|
||||
> **NOTE** Multiple `ExternalSystemProjectAware` instances can correspond to a single external system. It allows performing project reload differently depending on the set of settings files (project aware per settings file, per module, per external project, etc.).
|
||||
|
||||
|
||||
### Icon for reload notification
|
||||
Since 2020.1, the icon for reload notification can be specified per external system. Implement `ExternalSystemIconProvider` and register via `com.intellij.externalIconProvider` extension point in `plugin.xml`. Alternatively, set `reloadIcon` field external system implements `ExternalSystemIconProvider` directly.
|
||||
|
||||
**Note:** *ExternalSystemAutoImportAware.getAffectedExternalProjectPath()* is called quite often, that's why it's expected to return control as soon as possible. Helper *CachingExternalSystemAutoImportAware* class might be used for caching, i.e. *ExternalSystemManager* which implements *ExternalSystemAutoImportAware* can have a field like *'new CachingExternalSystemAutoImportAware(new MyExternalSystemAutoImportAware())'* and delegate *ExternalSystemAutoImportAware.getAffectedExternalProjectPath()* calls to it.
|
||||
|
||||
# Settings
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 27 KiB |
@ -78,7 +78,7 @@ String[] dependentModulesNames = moduleRootManager.getDependencyModuleNames();
|
||||
|
||||
Use the `ModuleManager.getModuleDependentModules(module)` method.
|
||||
|
||||
Note that you can also check whether a module (*module1*) depends on another specified module (*module2*) using the `ModuleManager.isModuleDependent` method in the following way:
|
||||
Note that you can also check whether a module (*module1*) depends on another specified module (*module2*) using the `ModuleManager.isModuleDependent()` method in the following way:
|
||||
|
||||
```java
|
||||
boolean isDependent = ModuleManager.getInstance(project).isModuleDependent(module1,module2);
|
||||
@ -111,7 +111,7 @@ VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoo
|
||||
|
||||
### Checking belonging to a module source root
|
||||
|
||||
To check if a virtual file or directory belongs to a module source root, use the `ProjectFileIndex.getSourceRootForFile` method. This method returns `null` if the file or directory does not belong to any source root of modules in the project.
|
||||
To check if a virtual file or directory belongs to a module source root, use the `ProjectFileIndex.getSourceRootForFile()` method. This method returns `null` if the file or directory does not belong to any source root of modules in the project.
|
||||
|
||||
```java
|
||||
VirtualFile moduleSourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(virtualFileOrDirectory);
|
||||
|
@ -44,7 +44,7 @@ ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getF
|
||||
|
||||
### How do I get the content or source root to which the specified file or directory belongs?
|
||||
|
||||
Use the `ProjectFileIndex.getContentRootForFile` and `ProjectFileIndex.getSourceRootForFile` methods. For example:
|
||||
Use the `ProjectFileIndex.getContentRootForFile()` and `ProjectFileIndex.getSourceRootForFile()` methods. For example:
|
||||
|
||||
```java
|
||||
VirtualFile moduleContentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFileOrDirectory);
|
||||
@ -55,13 +55,10 @@ Note that this method returns `null` if the file or directory does not belong to
|
||||
|
||||
### How do I check whether a file or directory is related to the project libraries?
|
||||
|
||||
The `ProjectFileIndex` interface implements a number of methods you can use to check whether the specified file belongs to the project library classes or library sources.
|
||||
|
||||
You can use the following methods:
|
||||
|
||||
* `ProjectFileIndex.`**`isLibraryClassFile`**`(virtualFile)`: Returns `true` if the specified `virtualFile` is a compiled class file.
|
||||
* `ProjectFileIndex.`**`isInLibraryClasses`**`(virtualFileorDirectory)`: Returns `true` if the specified `virtualFileorDirectory` belongs to library classes.
|
||||
* `ProjectFileIndex.`**`isInLibrarySource`**`(virtualFileorDirectory)`: Returns `true` if the specified `virtualFileorDirectory` belongs to library sources.
|
||||
The `ProjectFileIndex` interface implements a number of methods you can use to check whether the specified file belongs to the project library classes or library sources:
|
||||
* `isLibraryClassFile(virtualFile)`: Returns `true` if the specified `virtualFile` is a compiled class file.
|
||||
* `isInLibraryClasses(virtualFileorDirectory)`: Returns `true` if the specified `virtualFileorDirectory` belongs to library classes.
|
||||
* `isInLibrarySource(virtualFileorDirectory)`: Returns `true` if the specified `virtualFileorDirectory` belongs to library sources.
|
||||
|
||||
### How do I get the project SDK?
|
||||
|
||||
@ -77,7 +74,7 @@ Note that by default, the project modules use the project SDK. Optionally, you c
|
||||
|
||||
## Changing the project structure
|
||||
|
||||
Utility classes used for modifying the project structure can be found in the package [projectModel-impl.openapi](upsource:///platform/projectModel-impl/src/com/intellij/openapi). Its [roots](upsource:///platform/projectModel-impl/src/com/intellij/openapi/roots/) subpackage contains instances and utilities intended for work with project and module source roots, including [ModuleRootModificationUtil](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java) and [ProjectRootUtil](upsource:///platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootUtil.java). Project structure
|
||||
Utility classes used for modifying the project structure can be found in the package [projectModel-impl.openapi](upsource:///platform/projectModel-impl/src/com/intellij/openapi). Its [roots](upsource:///platform/projectModel-impl/src/com/intellij/openapi/roots/) subpackage contains instances and utilities intended for work with project and module source roots, including [`ModuleRootModificationUtil`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java) and [`ProjectRootUtil`](upsource:///platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootUtil.java). Project structure
|
||||
changes need to be performed in a [write action](/basics/architectural_overview/general_threading_rules.md#readwrite-lock).
|
||||
|
||||
Refer to the [basic example](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/project_model/src/com/intellij/tutorials/project/model/ModificationAction.java) of on-the-fly project structure modification to learn how it can be implemented.
|
||||
|
@ -42,9 +42,9 @@ See the following [code sample](https://github.com/JetBrains/intellij-sdk-docs/t
|
||||
|
||||
## Working with your own SDK
|
||||
|
||||
To create your own SDK, provide a class extending [`SdkType`](upsource:///platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java), leave `saveAdditionalData` blank, and register it in the `com.intellij.sdkType` extension point.
|
||||
To create your own SDK, provide a class extending [`SdkType`](upsource:///platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java), leave `saveAdditionalData()` blank, and register it in the `com.intellij.sdkType` extension point.
|
||||
|
||||
To make SDK settings persistent, override `setupSdkPaths` and save settings by `modificator.commitChanges()`:
|
||||
To make SDK settings persistent, override `setupSdkPaths()` and save settings by `modificator.commitChanges()`:
|
||||
|
||||
```java
|
||||
@Override
|
||||
|
@ -50,8 +50,7 @@ To set up a new module environment
|
||||
class should be extended and registered as an extension point like the following snippet shows:
|
||||
|
||||
```xml
|
||||
<extensions>
|
||||
<!--Place your extensions here-->
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<moduleBuilder builderClass="org.jetbrains.plugins.ruby.rails.facet.versions.MyModuleBuilder"/>
|
||||
</extensions>
|
||||
```
|
||||
|
@ -2,8 +2,8 @@
|
||||
title: Custom UI Themes
|
||||
---
|
||||
|
||||
Beginning with the 2019.1 release, custom UI Themes are supported by IntelliJ IDEA.
|
||||
Custom UI Themes give designers control of the appearance of built-in IntelliJ IDEA UI elements.
|
||||
Beginning with the 2019.1 release, custom UI Themes are supported.
|
||||
Custom UI Themes give designers control of the appearance of built-in UI elements.
|
||||
The [UI Themes available for download](https://plugins.jetbrains.com/search?headline=164-theme&tags=Theme) illustrate the creative possibilities.
|
||||
|
||||
[Creating a new UI element](/user_interface_components/user_interface_components.md) for a plugin is distinctly different than Custom UI Themes.
|
||||
|
@ -112,7 +112,7 @@ The New Project Wizard produces the `my_gradle_plugin` project `build.gradle` fi
|
||||
```groovy
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.15'
|
||||
id 'org.jetbrains.intellij' version '0.4.16'
|
||||
}
|
||||
|
||||
group 'com.your.company'
|
||||
@ -166,43 +166,20 @@ Converting a DevKit-based plugin project to a Gradle-based plugin project can be
|
||||
|
||||
|
||||
## Running a Simple Gradle-Based IntelliJ Platform Plugin
|
||||
Before running [`my_gradle_project`](#components-of-a-wizard-generated-gradle-intellij-platform-plugin), some code needs to be added to provide simple functionality.
|
||||
* Using the code below, add a `HelloAction.java` class to the `src/main/java/` folder.
|
||||
For the sake of simplicity, no Java package is being used in this example.
|
||||
Gradle projects are run from the IDE's Gradle Tool window.
|
||||
|
||||
```java
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
|
||||
public class HelloAction extends AnAction {
|
||||
public HelloAction() {
|
||||
super("Hello");
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent event) {
|
||||
Project project = event.getProject();
|
||||
Messages.showMessageDialog(project, "Hello world!", "Greeting", Messages.getInformationIcon());
|
||||
}
|
||||
}
|
||||
```
|
||||
### Adding Code to the Project
|
||||
Before running [`my_gradle_project`](#components-of-a-wizard-generated-gradle-intellij-platform-plugin), some code could be added to provide simple functionality.
|
||||
See the [Creating Actions](/tutorials/action_system/working_with_custom_actions.md) tutorial for step-by-step instructions for adding a menu action.
|
||||
|
||||
* Add the code below to the `<actions>` section of the `plugin.xml` file:
|
||||
|
||||
```xml
|
||||
<group id="MyPlugin.SampleMenu" text="Greeting" description="Greeting menu">
|
||||
<add-to-group group-id="MainMenu" anchor="last"/>
|
||||
<action id="Myplugin.Textboxes" class="HelloAction" text="Hello" description="Says hello"/>
|
||||
</group>
|
||||
```
|
||||
|
||||
* Open the Gradle tool window and search for the `runIde` task.
|
||||
If it’s not in the list, hit the [Refresh](https://www.jetbrains.com/help/idea/jetgradle-tool-window.html#1eeec055) button at the top of the Gradle window.
|
||||
Or [Create a new Gradle Run Configuration](https://www.jetbrains.com/help/idea/create-run-debug-configuration-gradle-tasks.html).
|
||||
### Executing the plugin
|
||||
Open the Gradle tool window and search for the `runIde` task:
|
||||
* If it’s not in the list, hit the [Refresh](https://www.jetbrains.com/help/idea/jetgradle-tool-window.html#1eeec055) button at the top of the Gradle window.
|
||||
* Or [Create a new Gradle Run Configuration](https://www.jetbrains.com/help/idea/create-run-debug-configuration-gradle-tasks.html).
|
||||
|
||||
{:width="398px"}
|
||||
|
||||
* Double-click on the _runIde_ task to execute it.
|
||||
See the IntelliJ IDEA help for more information about [Working with Gradle tasks](https://www.jetbrains.com/help/idea/gradle.html#96bba6c3).
|
||||
Double-click on the _runIde_ task to execute it.
|
||||
See the IntelliJ IDEA help for more information about [Working with Gradle tasks](https://www.jetbrains.com/help/idea/gradle.html#96bba6c3).
|
||||
|
||||
Finally, when `my_gradle_plugin` launches in the IDE development instance, there should be a new **Greeting** main menu to the right of the **Help** menu.
|
||||
Finally, when `my_gradle_plugin` launches in the IDE development instance, there should be a new menu under the **Tools** menu.
|
||||
|
@ -22,7 +22,7 @@ In this example, we access the `Editor` from an action.
|
||||
The source code for the Java class in this example is [EditorIllustrationAction](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorIllustrationAction.java).
|
||||
|
||||
To register the action, we must add the corresponding elements to the `<actions>` section of the plugin configuration file [plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/editor_basics/src/main/resources/META-INF/plugin.xml).
|
||||
For more information, refer to the [Registering Actions](/tutorials/action_system/working_with_custom_actions.md#13-registering-actions) section of the Actions Tutorial.
|
||||
For more information, refer to the [Registering Actions](/tutorials/action_system/working_with_custom_actions.md#registering-a-custom-action) section of the Actions Tutorial.
|
||||
The `EditorIllustrationAction` action is registered in the group `EditorPopupMenu` so it will be available from the context menu when focus is on the editor:
|
||||
```xml
|
||||
<action id="EditorBasics.EditorIllustrationAction"
|
||||
@ -36,7 +36,7 @@ The `EditorIllustrationAction` action is registered in the group `EditorPopupMen
|
||||
|
||||
## Defining the Menu Action's Visibility
|
||||
To determine conditions by which the action will be visible and available requires `EditorIllustrationAction` to override the `AnAction.update()` method.
|
||||
For more information, refer to the [Setting an Action's Availability](/tutorials/action_system/working_with_custom_actions.md#16-setting-up-an-actions-visibility-and-availability) section of the Actions Tutorial.
|
||||
For more information, refer to [Extending the Update Method](/tutorials/action_system/working_with_custom_actions.md#extending-the-update-method) section of the Actions Tutorial.
|
||||
|
||||
To work with a selected part of the text, it's reasonable to make the menu action available only when the following requirements are met:
|
||||
* There is a [`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java) object,
|
||||
|
@ -84,7 +84,7 @@ buildscript {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("org.jetbrains.intellij") version "0.4.15"
|
||||
id("org.jetbrains.intellij") version "0.4.16"
|
||||
kotlin("jvm") version "1.2.30"
|
||||
}
|
||||
|
||||
|
@ -14,12 +14,12 @@ Series of step below show how to filter out and keep visible only text files and
|
||||
|
||||
Create an empty plugin project.
|
||||
See
|
||||
[Creating a Plugin Project](/basics/getting_started/creating_plugin_project.md).
|
||||
[Creating a Plugin Project](/tutorials/build_system/prerequisites.md).
|
||||
|
||||
## 1. Register Custom TreeStructure Provider
|
||||
|
||||
Add new *treeStructureProvider* extension to the
|
||||
[plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/tree_structure_provider/resources/META-INF/plugin.xml)
|
||||
[plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/tree_structure_provider/src/main/resources/META-INF/plugin.xml)
|
||||
|
||||
```java
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
@ -53,7 +53,7 @@ To implement Tree Structure nodes filtering logic, override `modify()` method.
|
||||
The example below shows how to filter out all the Project View nodes except those which correspond to text files and directories.
|
||||
|
||||
```java
|
||||
{% include /code_samples/tree_structure_provider/src/org/jetbrains/tutorials/tree/structure/TextOnlyTreeStructureProvider.java %}
|
||||
{% include /code_samples/tree_structure_provider/src/main/java/org/jetbrains/tutorials/tree/structure/TextOnlyTreeStructureProvider.java %}
|
||||
```
|
||||
|
||||
## 4. Compile and Run the Plugin
|
||||
|
Loading…
x
Reference in New Issue
Block a user