Minor reformatting. No actual content changed

This commit is contained in:
Matt Ellis 2015-11-23 17:36:39 +00:00
parent ec56d47cbd
commit 005162aa48
34 changed files with 745 additions and 1188 deletions

View File

@ -109,6 +109,3 @@ DEPENDENCIES
jekyll-redirect-from
link-checker!
rake
BUNDLED WITH
1.10.6

View File

@ -2,168 +2,178 @@
title: Action System
---
## Executing and Updating Actions
## Executing and updating actions
The system of actions allows plugins to add their own items to IDEA menus and toolbars.
An action is a class, derived from the
[AnAction](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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.
For example, one of the action classes is responsible for the "File \| Open File..." menu item and for the "Open File" toolbar button.
The system of actions allows plugins to add their own items to IDEA menus and toolbars. An action is a class, derived from the [`AnAction`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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.
For example, one of the action classes is responsible for the **File \| Open File...** menu item and for the **Open File** toolbar button.
Actions are organized into groups, which, in turn, can contain other groups. A group of actions can form a toolbar or a menu.
Subgroups of the group can form submenus of the menu.
Every action and action group has an unique identifier.
Identifiers of many of the standard IDEA actions are defined in the
[IdeActions](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java)
class.
Every action and action group has an unique identifier. Identifiers of many of the standard IDEA actions are defined in the [IdeActions](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java) class.
Every action can be included in multiple groups, and thus appear in multiple places within the IDEA user interface.
Different places where actions can appear are defined by constants in the
[ActionPlaces](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java)
interface. For every place where the action appears, a new `Presentation` is created.
Thus, the same action can have different text or icons when it appears in different places of the user interface.
Different presentations for the action are created by copying the presentation returned by the `AnAction.getTemplatePresentation()` method.
Every action can be included in multiple groups, and thus appear in multiple places within the IDEA user interface. Different places where actions can appear are defined by constants in the [`ActionPlaces`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java) interface. For every place where the action appears, a new `Presentation` is created. Thus, the same action can have different text or icons when it appears in different places of the user interface. Different presentations for the action are created by copying the presentation returned by the `AnAction.getTemplatePresentation()` method.
To update the state of the action, the method `AnAction.update()` is periodically called by IDEA.
The object of type `AnActionEvent` passed to this method carries the information about the current context for the action, and in particular, the specific presentation which needs to be updated.
To update the state of the action, the method `AnAction.update()` is periodically called by IDEA. The `AnActionEvent` object passed to this method carries the information about the current context for the action, and in particular, the specific presentation which needs to be updated.
To retrieve the information about the current state of the IDE, including the active project, the selected file, the selection in the editor and so on, the method `AnActionEvent.getData()` can be used.
Different data keys that can be passed to that method are defined in the `DataKeys` class.
To retrieve the information about the current state of the IDE, including the active project, the selected file, the selection in the editor and so on, the method `AnActionEvent.getData()` can be used. Different data keys that can be passed to that method are defined in the `DataKeys` class.
The `AnActionEvent` instance is also passed to the `actionPerformed` method.
## Registering Actions
There are two main ways to register an action: either by listing it in the `<actions>` section of the plugin.xml file, or through Java code.
There are two main ways to register an action: either by listing it in the `<actions>` section of the `plugin.xml` file, or through Java code.
### Registering Actions in plugin.xml
Registering actions in plugin.xml is demonstrated in the following example. The example section of plugin.xml demonstrates all elements which can be used in the `<actions>` section, and describes the meaning of each element.
Registering actions in `plugin.xml` is demonstrated in the following example. The example section of `plugin.xml` demonstrates all elements which can be used in the `<actions>` section, and describes the meaning of each element.
```xml
<!-- Actions -->
<actions>
<!-- The <action> element defines an action to register.
The mandatory "id" attribute specifies an unique identifier for the action.
The mandatory "class" attribute specifies the full-qualified name of the class implementing the action.
The mandatory "text" attribute specifies the text of the action (tooltip for toolbar button or text for menu item).
The optional "use-shortcut-of" attribute specifies the ID of the action whose keyboard shortcut this action will use.
The optional "description" attribute specifies the text which is displayed in the status bar when the action is focused.
The optional "icon" attribute specifies the icon which is displayed on the toolbar button or next to the menu item. -->
<action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage" description="Run garbage collector"
icon="icons/garbage.png">
<!-- The <add-to-group> node specifies that the action should be added to an existing group. An action can be added to several groups.
The mandatory "group-id" attribute specifies the ID of the group to which the action is added.
The group must be implemented by an instance of the DefaultActionGroup class.
The mandatory "anchor" attribute specifies the position of the action in the group relative to other actions. It can have the values
"first", "last", "before" and "after".
The "relative-to-action" attribute is mandatory if the anchor is set to "before" and "after", and specifies the action before or after which
the current action is inserted. -->
<add-to-group group-id="ToolsMenu" relative-to-action="GenerateJavadoc" anchor="after"/>
<!-- The <keyboard-shortcut> node specifies the keyboard shortcut for the action. An action can have several keyboard shortcuts.
The mandatory "first-keystroke" attribute specifies the first keystroke of the action. The key strokes are specified according to the regular Swing rules.
The optional "second-keystroke" attribute specifies the second keystroke of the action.
The mandatory "keymap" attribute specifies the keymap for which the action is active. IDs of the standard keymaps are defined as
constants in the com.intellij.openapi.keymap.KeymapManager class. -->
<keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>
<!-- The <mouse-shortcut> node specifies the mouse shortcut for the action. An action can have several mouse shortcuts.
The mandatory "keystroke" attribute specifies the clicks and modifiers for the action. It is defined as a sequence of words separated by spaces:
"button1", "button2", "button3" for the mouse buttons; "shift", "control", "meta", "alt", "altGraph" for the modifier keys;
"doubleClick" if the action is activated by a double-click of the button.
The mandatory "keymap" attribute specifies the keymap for which the action is active. IDs of the standard keymaps are defined as
constants in the com.intellij.openapi.keymap.KeymapManager class. -->
<mouse-shortcut keystroke="control button3 doubleClick" keymap="$default"/>
</action>
<!-- The <group> element defines an action group. <action>, <group> and <separator> elements defined within it are automatically included in the group.
The mandatory "id" attribute specifies an unique identifier for the action.
The optional "class" attribute specifies the full-qualified name of the class implementing the group. If not specified,
com.intellij.openapi.actionSystem.DefaultActionGroup is used.
The optional "text" attribute specifies the text of the group (text for the menu item showing the submenu).
The optional "description" attribute specifies the text which is displayed in the status bar when the group is focused.
The optional "icon" attribute specifies the icon which is displayed on the toolbar button or next to the group.
The optional "popup" attribute specifies how the group is presented in the menu. If a group has popup="true", actions in it
are placed in a submenu; for popup="false", actions are displayed as a section of the same menu delimited by separators. -->
<group class="com.foo.impl.MyActionGroup" id="TestActionGroup" text="Test Group" description="Group with test actions"
icon="icons/testgroup.png" popup="true">
<action id="VssIntegration.TestAction" class="com.foo.impl.TestAction" text="My Test Action" description="My test action"/>
<!-- The <separator> element defines a separator between actions. It can also have an <add-to-group> child element. -->
<separator/>
<group id="TestActionSubGroup"/>
<!-- The <reference> element allows to add an existing action to the group. The mandatory "ref" attribute specifies the ID of the action to add. -->
<reference ref="EditorCopy"/>
<add-to-group group-id="MainMenu" relative-to-action="HelpMenu" anchor="before"/>
</group>
</actions>
<!-- Actions -->
<actions>
<!-- The <action> element defines an action to register.
The mandatory "id" attribute specifies an unique
identifier for the action.
The mandatory "class" attribute specifies the
full-qualified name of the class implementing the action.
The mandatory "text" attribute specifies the text of the
action (tooltip for toolbar button or text for menu item).
The optional "use-shortcut-of" attribute specifies the ID
of the action whose keyboard shortcut this action will use.
The optional "description" attribute specifies the text
which is displayed in the status bar when the action is focused.
The optional "icon" attribute specifies the icon which is
displayed on the toolbar button or next to the menu item. -->
<action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage" description="Run garbage collector" icon="icons/garbage.png">
<!-- The <add-to-group> node specifies that the action should be added
to an existing group. An action can be added to several groups.
The mandatory "group-id" attribute specifies the ID of the group
to which the action is added.
The group must be implemented by an instance of the DefaultActionGroup class.
The mandatory "anchor" attribute specifies the position of the
action in the group relative to other actions. It can have the values
"first", "last", "before" and "after".
The "relative-to-action" attribute is mandatory if the anchor
is set to "before" and "after", and specifies the action before or after which
the current action is inserted. -->
<add-to-group group-id="ToolsMenu" relative-to-action="GenerateJavadoc" anchor="after"/>
<!-- The <keyboard-shortcut> node specifies the keyboard shortcut
for the action. An action can have several keyboard shortcuts.
The mandatory "first-keystroke" attribute specifies the first
keystroke of the action. The key strokes are specified according
to the regular Swing rules.
The optional "second-keystroke" attribute specifies the second
keystroke of the action.
The mandatory "keymap" attribute specifies the keymap for which
the action is active. IDs of the standard keymaps are defined as
constants in the com.intellij.openapi.keymap.KeymapManager class. -->
<keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>
<!-- The <mouse-shortcut> node specifies the mouse shortcut for the
action. An action can have several mouse shortcuts.
The mandatory "keystroke" attribute specifies the clicks and
modifiers for the action. It is defined as a sequence of words
separated by spaces:
"button1", "button2", "button3" for the mouse buttons;
"shift", "control", "meta", "alt", "altGraph" for the modifier keys;
"doubleClick" if the action is activated by a double-click of the button.
The mandatory "keymap" attribute specifies the keymap for which
the action is active. IDs of the standard keymaps are defined as
constants in the com.intellij.openapi.keymap.KeymapManager class. -->
<mouse-shortcut keystroke="control button3 doubleClick" keymap="$default"/>
</action>
<!-- The <group> element defines an action group. <action>, <group> and
<separator> elements defined within it are automatically included in the group.
The mandatory "id" attribute specifies an unique identifier for the action.
The optional "class" attribute specifies the full-qualified name of
the class implementing the group. If not specified,
com.intellij.openapi.actionSystem.DefaultActionGroup is used.
The optional "text" attribute specifies the text of the group (text
for the menu item showing the submenu).
The optional "description" attribute specifies the text which is displayed
in the status bar when the group is focused.
The optional "icon" attribute specifies the icon which is displayed on
the toolbar button or next to the group.
The optional "popup" attribute specifies how the group is presented in
the menu. If a group has popup="true", actions in it are placed in a
submenu; for popup="false", actions are displayed as a section of the
same menu delimited by separators. -->
<group class="com.foo.impl.MyActionGroup" id="TestActionGroup" text="Test Group" description="Group with test actions" icon="icons/testgroup.png" popup="true">
<action id="VssIntegration.TestAction" class="com.foo.impl.TestAction" text="My Test Action" description="My test action"/>
<!-- The <separator> element defines a separator between actions.
It can also have an <add-to-group> child element. -->
<separator/>
<group id="TestActionSubGroup"/>
<!-- The <reference> element allows to add an existing action to the group.
The mandatory "ref" attribute specifies the ID of the action to add. -->
<reference ref="EditorCopy"/>
<add-to-group group-id="MainMenu" relative-to-action="HelpMenu" anchor="before"/>
</group>
</actions>
```
### Registering Actions from Code
## Registering Actions from Code
To register an action from code, two steps are required.
First, an instance of the class derived from `AnAction` must be passed to the `registerAction` method of the
[ActionManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java)
class, to associate the action with an ID.
Second, the action needs to be added to one or more groups.
To get an instance of an action group by ID, it is necessary to call `ActionManager.getAction()` and cast the returned value to the
[DefaultActionGroup](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java)
class.
* First, an instance of the class derived from `AnAction` must be passed to the `registerAction` method of the [ActionManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java) class, to associate the action with an ID.
* Second, the action needs to be added to one or more groups. To get an instance of an action group by ID, it is necessary to call `ActionManager.getAction()` and cast the returned value to the [DefaultActionGroup](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java) class.
You can create a plugin that registers actions on IDEA startup using the following procedure.
*To register an action on IDEA startup*
# Create a new class that implements the `ApplicationComponent` interface.
# In this class, override the `getComponentName`, `initComponent`, and `disposeComponent` methods.
# Register this class in the `<application-components>` section of the plugin.xml file.
**To register an action on IDEA startup**
* Create a new class that implements the `ApplicationComponent` interface.
* In this class, override the `getComponentName`, `initComponent`, and `disposeComponent` methods.
* Register this class in the `<application-components>` section of the plugin.xml file.
To clarify the above procedure, consider the following sample Java class `MyPluginRegistration` that registers an action defined in a custom `TextBoxes` class and adds a new menu command to the *Window* menu group on the main menu:
```java
public class MyPluginRegistration implements ApplicationComponent {
// Returns the component name (any unique string value).
@NotNull public String getComponentName() {
return "MyPlugin";
}
@NotNull public String getComponentName() {
return "MyPlugin";
}
// If you register the MyPluginRegistration class in the <application-components> section of
// the plugin.xml file, this method is called on IDEA start-up.
public void initComponent() {
ActionManager am = ActionManager.getInstance();
TextBoxes action = new TextBoxes();
// Passes an instance of your custom TextBoxes class to the registerAction method of the ActionManager class.
am.registerAction("MyPluginAction", action);
// Gets an instance of the WindowMenu action group.
DefaultActionGroup windowM = (DefaultActionGroup) am.getAction("WindowMenu");
// Adds a separator and a new menu command to the WindowMenu group on the main menu.
windowM.addSeparator();
windowM.add(action);
}
// If you register the MyPluginRegistration class in the <application-components> section of
// the plugin.xml file, this method is called on IDEA start-up.
public void initComponent() {
ActionManager am = ActionManager.getInstance();
TextBoxes action = new TextBoxes();
// Disposes system resources.
public void disposeComponent() {
}
// Passes an instance of your custom TextBoxes class to the registerAction method of the ActionManager class.
am.registerAction("MyPluginAction", action);
// Gets an instance of the WindowMenu action group.
DefaultActionGroup windowM = (DefaultActionGroup) am.getAction("WindowMenu");
// Adds a separator and a new menu command to the WindowMenu group on the main menu.
windowM.addSeparator();
windowM.add(action);
}
// Disposes system resources.
public void disposeComponent() {
}
}
```
Note, that the sample `TextBoxes` class is described in
[Getting Started with Plugin Development](/basics/getting_started.md).
Note, that the sample `TextBoxes` class is described in [Getting Started with Plugin Development](/basics/getting_started.md).
To ensure that your plugin is initialized on IDEA start-up, make the following changes to the `<application-components>` section of the plugin.xml file:
To ensure that your plugin is initialized on IDEA start-up, make the following changes to the `<application-components>` section of the `plugin.xml` file:
```xml
<application-components>
<!-- Add your application components here -->
<component>
<implementation-class>MypackageName.MyPluginRegistration</implementation-class>
</component>
<!-- Add your application components here -->
<component>
<implementation-class>MypackageName.MyPluginRegistration</implementation-class>
</component>
</application-components>
```
## Building UI from Actions
If a plugin needs to include a toolbar or popup menu built from a group of actions in its own user interface, that can be accomplished through the `ActionPopupMenu` and `ActionToolbar` classes. These objects can be created through calls to `ActionManager.createActionPopupMenu` and `ActionManager.createActionToolbar`.
To get a Swing component from such an object, simply call the getComponent() method.
If a plugin needs to include a toolbar or popup menu built from a group of actions in its own user interface, that can be accomplished through the `ActionPopupMenu` and `ActionToolbar` classes. These objects can be created through calls to `ActionManager.createActionPopupMenu` and `ActionManager.createActionToolbar`. To get a Swing component from such an object, simply call the getComponent() method.
If your action toolbar is attached to a specific component (for example, a panel in a toolwindow), you usually need to call `ActionToolbar.setTargetComponent()` and pass the instance of the related component as a parameter.
This ensures that the state of the toolbar buttons depends on the state of the related component, and not on the current focus location within the IDE frame.
If your action toolbar is attached to a specific component (for example, a panel in a toolwindow), you usually need to call `ActionToolbar.setTargetComponent()` and pass the instance of the related component as a parameter. This ensures that the state of the toolbar buttons depends on the state of the related component, and not on the current focus location within the IDE frame.

View File

@ -2,22 +2,15 @@
title: Architectural Overview
---
This topic describes the architecture of IntelliJ Platform from a plugin developer's point of view. It is organized in a task-based manner to answer specific questions like "what can I do with this object?", "how do I get to this object?" and so on.
This topic describes the architecture of the *IntelliJ Platform* from a plugin developer's point of view. It is organized in a task-based manner to answer specific questions like "what can I do with this object?", "how do I get to this object?" and so on.
Before proceeding please make sure you're familiar with the basic concepts of IntelliJ Platform plugin development. If not, consider starting with the live demo and tutorials at
[www.jetbrains.com/idea/plugins/](http://www.jetbrains.com/idea/plugins/)
and then returning to this document.
Before proceeding please make sure you're familiar with the basic concepts of IntelliJ Platform plugin development. If not, consider starting with the live demo and tutorials at [www.jetbrains.com/idea/plugins/](http://www.jetbrains.com/idea/plugins/) and then returning to this document.
The following subjects are covered:
* [General Threading Rules](architectural_overview/general_threading_rules.md)
* [Virtual Files](architectural_overview/virtual_file.md)
* [General threading rules](architectural_overview/general_threading_rules.md)
* [Virtual files](architectural_overview/virtual_file.md)
* [Documents](architectural_overview/documents.md)
* [PSI Files](architectural_overview/psi_files.md)
* [File View Providers](architectural_overview/file_view_providers.md)
* [Psi Elements](architectural_overview/psi_elements.md)
* [PSI files](architectural_overview/psi_files.md)
* [File view providers](architectural_overview/file_view_providers.md)
* [Psi elements](architectural_overview/psi_elements.md)

View File

@ -2,13 +2,13 @@
title: Documents
---
A document is an editable sequence of Unicode characters, which typically corresponds to the text contents of a virtual file. Line breaks in a document are always normalized to \n. IntelliJ Platform handles encoding and line break conversions when loading and saving documents transparently.
A document is an editable sequence of Unicode characters, which typically corresponds to the text contents of a virtual file. Line breaks in a document are _always_ normalized to `\n`. The *IntelliJ Platform* handles encoding and line break conversions when loading and saving documents transparently.
## How do I get a document?
* From an action: `e.getData(PlatformDataKeys.EDITOR).getDocument()`
* From a virtual file: `FileDocumentManager.getDocument()`. This call forces the document content to be loaded from disk if it wasn't loaded previously; if you're only interested in open documents or documents which may have been modified, use `FileDocumentManager.getCachedDocument()` instead.
* From a PSI file: `PsiDocumentManager.getInstance().getDocument()` or `PsiDocumentManager.getInstance().getCachedDocument()`
* From an action: `e.getData(PlatformDataKeys.EDITOR).getDocument()`
* From a virtual file: `FileDocumentManager.getDocument()`. This call forces the document content to be loaded from disk if it wasn't loaded previously; if you're only interested in open documents or documents which may have been modified, use `FileDocumentManager.getCachedDocument()` instead.
* From a PSI file: `PsiDocumentManager.getInstance().getDocument()` or `PsiDocumentManager.getInstance().getCachedDocument()`
## What can I do with a Document?
@ -20,22 +20,22 @@ Document instances are created when some operation needs to access the text cont
## How long does a Document persist?
Document instances are weakly referenced from VirtualFile instances. Thus, an unmodified Document instance can be garbage-collected if it isn't referenced by anyone, and a new instance will be created if the document contents is accessed again later. Storing Document references in long-term data structures of your plugin will cause memory leaks.
Document instances are weakly referenced from `VirtualFile` instances. Thus, an unmodified `Document` instance can be garbage-collected if it isn't referenced by anyone, and a new instance will be created if the document contents is accessed again later. Storing `Document` references in long-term data structures of your plugin will cause memory leaks.
## How do I create a Document?
If you need to create a new file on disk, you don't create a document: you create a PSI file and then get its document. If you need to create a document instance which isn't bound to anything, you can use `EditorFactory.createDocument`.
If you need to create a new file on disk, you don't create a `Document`: you create a PSI file and then get its `Document`. If you need to create a `Document` instance which isn't bound to anything, you can use `EditorFactory.createDocument`.
## How do I get notified when Documents change?
* `Document.addDocumentListener` allows you to receive notifications about changes in a particular Document instance.
* `EditorFactory.getEventMulticaster().addDocumentListener` allows you to receive notifications about changes in all open documents.
* `FileDocumentManager.addFileDocumentManagerListener` allows you to receive notifications when any document is saved or reloaded from disk.
* `Document.addDocumentListener` allows you to receive notifications about changes in a particular `Document` instance.
* `EditorFactory.getEventMulticaster().addDocumentListener` allows you to receive notifications about changes in all open documents.
* `FileDocumentManager.addFileDocumentManagerListener` allows you to receive notifications when any `Document` is saved or reloaded from disk.
## What are the rules of working with Documents?
The general read/write action rules are in effect. In addition to that, any operations which modify the contents of the document must be wrapped in a command (`CommandProcessor.getInstance().executeCommand()`). `executeCommand()` calls can be nested, and the outermost `executeCommand` call is added to the undo stack. If multiple documents are modified within a command, undoing this command will by default show a confirmation dialog to the user.
If the file corresponding to a document is read-only (for example, not checked out from the version control system), document modifications will fail. Thus, before modifying the document, it is necessary to call `ReadonlyStatusHandler.getInstance(project).ensureFilesWritable()` to check out the file if necessary.
If the file corresponding to a `Document` is read-only (for example, not checked out from the version control system), document modifications will fail. Thus, before modifying the `Document`, it is necessary to call `ReadonlyStatusHandler.getInstance(project).ensureFilesWritable()` to check out the file if necessary.
All text strings passed to document modification methods (`setText`, `insertString`, `replaceString`) must use only \n as line separators.
All text strings passed to `Document` modification methods (`setText`, `insertString`, `replaceString`) must use only \n as line separators.

View File

@ -2,44 +2,40 @@
title: File View Providers
---
A file view provider (see the [FileViewProvider](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/FileViewProvider.java) class) was introduced in IntelliJ IDEA 6.0. Its main purpose is to manage 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](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/java/jsp-openapi/src/com/intellij/psi/jsp/JspFile.java)).
A file view provider (see the [FileViewProvider](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/FileViewProvider.java) class) was introduced in *IntelliJ IDEA* 6.0. Its main purpose is to manage 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](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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.
A `FileViewProvider` instance corresponds to a single `VirtualFile`, a single `Document`, and can be used to retrieve multiple `PsiFile` instances.
## How do I get an FVP?
* From a VirtualFile: `PsiManager.getInstance(project).findViewProvider()`
* From a PSI file: `psiFile.getViewProvider()`
* From a VirtualFile: `PsiManager.getInstance(project).findViewProvider()`
* From a PSI file: `psiFile.getViewProvider()`
## What can I do with an FVP?
* To get the list of all languages for which PSI trees exist in a file: `fileViewProvider.getLanguages()`
* To get the PSI tree for a particular language: `fileViewProvider.getPsi(language)`, where the `language` parameter can take values of the
[Language](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/lang/Language.java)
type defined in
[StdLanguages](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/lang/StdLanguages.java)
class. For example, to get the PSI tree for XML, use `fileViewProvider.getPsi(StdLanguages.XML)`.
* To find an element of a particular language at the specified offset in the file: `fileViewProvider.findElementAt(offset,language)`
* To get the list of all languages for which PSI trees exist in a file: `fileViewProvider.getLanguages()`
* To get the PSI tree for a particular language: `fileViewProvider.getPsi(language)`, where the `language` parameter can take values of the [Language](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/lang/Language.java) type defined in [StdLanguages](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/lang/StdLanguages.java) class. For example, to get the PSI tree for XML, use `fileViewProvider.getPsi(StdLanguages.XML)`.
* To find an element of a particular language at the specified offset in the file: `fileViewProvider.findElementAt(offset,language)`
## How do I extend FVP?
## How do I extend the FileViewProvider?
To create a file type that has multiple interspersing trees for different languages, your plugin must contain an extension to the _fileType.fileViewProviderFactory_
[extension point](/basics/plugin_structure/plugin_extensions_and_extension_points.html)
available in the IntelliJ Platform core.
This extension point is declared using the
[FileTypeExtensionPoint](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionPoint.java)
To create a file type that has multiple interspersing trees for different languages, your plugin must contain an extension to the `fileType.fileViewProviderFactory` [extension point](/basics/plugin_structure/plugin_extensions_and_extension_points.html) available in the *IntelliJ Platform* core.
This extension point is declared using the [FileTypeExtensionPoint](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/fileTypes/FileTypeExtensionPoint.java)
bean class.
To access this extension point, create a Java class that implements the
[FileViewProviderFactory](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java)
interface, and in this class, override the `createFileViewProvider` method.
To declare the extension to the _fileType.fileViewProviderFactory_ extension point, to the `<extensions>` section of the plugin.xml file, add the following syntax:
```
<fileType.fileViewProviderFactory filetype=%file type% implementationClass=%class name%>
</fileType.fileViewProviderFactory>
To access this extension point, create a Java class that implements the [FileViewProviderFactory](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java) interface, and in this class, override the `createFileViewProvider` method.
To declare the extension to the `fileType.fileViewProviderFactory` extension point, to the `<extensions>` section of the plugin.xml file, add the following syntax:
```xml
<extensions>
<fileType.fileViewProviderFactory filetype="%file_type%" implementationClass="%class_name%" />
</extensions>
```
where the _%file type%_ refers to the type of the file being created (for example, to "JFS"), and the _%class name%_ refers to the name of your Java class that implements the `FileViewProviderFactory` interface.
Where `%file_type%` refers to the type of the file being created (for example, "JFS"), and the `%class_name%` refers to the name of your Java class that implements the `FileViewProviderFactory` interface.

View File

@ -2,11 +2,10 @@
title: General Threading Rules
---
In general, data structures in IntelliJ Platform are covered by a single "multiple readers / single writer" lock.
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()`.
Writing the data is only allowed from the UI thread, and write operations always need to be wrapped in a write action with `ApplicationManager.getApplication().runWriteAction()`.
In general, data structures in the *IntelliJ Platform* are covered by a single reader/writer lock.
To pass control from a background thread to the event dispatch thread, instead of the standard `SwingUtilities.invokeLater()`, plugins should use `ApplicationManager.getApplication().invokeLater()`.
The latter API allows specifying the _modality state_ for the call, i.e. the stack of modal dialogs under which the call is allowed to execute.
Passing `ModalityState.NON_MODAL` means that the operation will be executed after all modal dialogs are closed. Passing `ModalityState.stateForComponent()` means that the operation may be executed while the specified component (part of a dialog) is still visible.
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()`.
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()`.
To pass control from a background thread to the event dispatch thread, instead of the standard `SwingUtilities.invokeLater()`, plugins should use `ApplicationManager.getApplication().invokeLater()`. The latter API allows specifying the _modality state_ for the call, i.e. the stack of modal dialogs under which the call is allowed to execute. Passing `ModalityState.NON_MODAL` means that the operation will be executed after all modal dialogs are closed. Passing `ModalityState.stateForComponent()` means that the operation may be executed while the specified component (part of a dialog) is still visible.

View File

@ -3,21 +3,18 @@ title: PSI Elements
---
A PSI (Program Structure Interface) file represents a hierarchy of PSI elements (so-called _PSI trees_). A single PSI file may include several PSI trees in a particular programming language. A PSI element, in its turn, can have child PSI elements.
PSI elements and operations on the level of individual PSI elements are used to explore the internal structure of source code as it is interpreted by **IntelliJ IDEA**. For example, you can use PSI elements to perform code analysis, such as
[code inspections](http://www.jetbrains.com/idea/help/code-inspection.html)
or
[intention actions](http://www.jetbrains.com/idea/help/intention-actions.html).
The
[PsiElement](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/PsiElement.java)
class is the common base class for PSI elements.
PSI elements and operations on the level of individual PSI elements are used to explore the internal structure of source code as it is interpreted by **IntelliJ IDEA**. For example, you can use PSI elements to perform code analysis, such as [code inspections](http://www.jetbrains.com/idea/help/code-inspection.html) or [intention actions](http://www.jetbrains.com/idea/help/intention-actions.html).
The [PsiElement](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/PsiElement.java) class is the common base class for PSI elements.
## How do I get a PSI element?
* From an action: `e.getData(LangDataKeys.PSI_ELEMENT)`. Note: if an editor is currently open and the element under caret is a reference, this will return the result of resolving the reference. This may or may not be what you need.
* From a file by offset: `PsiFile.findElementAt()`. Note: this returns the lowest level element at the specified offset, which is normally a lexer token.
* From an action: `e.getData(LangDataKeys.PSI_ELEMENT)`. Note: if an editor is currently open and the element under caret is a reference, this will return the result of resolving the reference. This may or may not be what you need.
* From a file by offset: `PsiFile.findElementAt()`. Note: this returns the lowest level element at the specified offset, which is normally a lexer token.
Most likely you should use `PsiTreeUtil.getParentOfType()` to find the element you really need.
* By iterating through a PSI file: using a `PsiRecursiveElementWalkingVisitor`.
* By resolving a reference: `PsiReference.resolve()`
* By iterating through a PSI file: using a `PsiRecursiveElementWalkingVisitor`.
* By resolving a reference: `PsiReference.resolve()`
## What can I do with PSI elements?

View File

@ -3,24 +3,18 @@ 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](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/java/java-psi-api/src/com/intellij/psi/PsiJavaFile.java)
class represents a Java file, and the
[XmlFile](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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).
The [PsiFile](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/java/java-psi-api/src/com/intellij/psi/PsiJavaFile.java) class represents a Java file, and the [XmlFile](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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).
## How do I get a PSI file?
* From an action: `e.getData(LangDataKeys.PSI_FILE)`.
* From a VirtualFile: `PsiManager.getInstance(project).findFile()`
* From a Document: `PsiDocumentManager.getInstance(project).getPsiFile()`
* From an element inside the file: `psiElement.getContainingFile()`
* To find files with a specific name anywhere in the project, use `FilenameIndex.getFilesByName(project, name, scope)`
* From an action: `e.getData(LangDataKeys.PSI_FILE)`.
* From a VirtualFile: `PsiManager.getInstance(project).findFile()`
* From a Document: `PsiDocumentManager.getInstance(project).getPsiFile()`
* From an element inside the file: `psiElement.getContainingFile()`
* To find files with a specific name anywhere in the project, use `FilenameIndex.getFilesByName(project, name, scope)`
## What can I do with a PSI file?
@ -30,9 +24,7 @@ To iterate over the elements in a file, use `psiFile.accept(new PsiRecursiveElem
## Where does it a PSI file come from?
As PSI is language-dependent, PSI files are created through the
[Language](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/lang/Language.java)
object, by using the `LanguageParserDefinitions.INSTANCE.forLanguage(language).createFile(fileViewProvider)` method.
As PSI is language-dependent, PSI files are created through the [Language](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/lang/Language.java) object, by using the `LanguageParserDefinitions.INSTANCE.forLanguage(language).createFile(fileViewProvider)` method.
Like documents, PSI files are created on demand when the PSI is accessed for a particular file.
@ -42,23 +34,17 @@ Like documents, PSI files are weakly referenced from the corresponding `VirtualF
## How do I create a PSI file?
The
[PsiFileFactory](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/PsiFileFactory.java).
`getInstance(project).createFileFromText()` method creates an in-memory PSI file with the specified contents.
To save the PSI file to disk, use the
[PsiDirectory](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/PsiDirectory.java).
`add()` method.
The [`PsiFileFactory`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/PsiFileFactory.java)`.getInstance(project).createFileFromText()` method creates an in-memory PSI file with the specified contents.
To save the PSI file to disk, use the [`PsiDirectory`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/psi/PsiDirectory.java)`.add()` method.
## How do I get notified when PSI files change?
`PsiManager.getInstance(project).addPsiTreeChangeListener()` allows you to receive notifications about all changes to the PSI tree of a project.
## How do I extend PSI?
PSI can be extended to support additional languages through custom language plugins. For more details on developing custom language plugins, see the
[Custom Language Support](/reference_guide/custom_language_support.md)
reference guide.
PSI can be extended to support additional languages through custom language plugins. For more details on developing custom language plugins, see the [Custom Language Support](/reference_guide/custom_language_support.md) reference guide.
## What are the rules for working with PSI?

View File

@ -2,60 +2,47 @@
title: Virtual Files
---
A virtual file
[com.intellij.openapi.vfs.VirtualFile](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java) is IntelliJ IDEA's representation of a file in a file system (VFS). Most commonly, a virtual file is a file in your local file system. However, IntelliJ IDEA supports multiple pluggable file system implementations, so virtual files can also represent classes in a JAR file, old revisions of files loaded from the CVS repository, and so on.
A virtual file [com.intellij.openapi.vfs.VirtualFile](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java) is *IntelliJ IDEA's* representation of a file in a file system (VFS). Most commonly, a virtual file is a file in your local file system. However, *IntelliJ IDEA* supports multiple pluggable file system implementations, so virtual files can also represent classes in a JAR file, old revisions of files loaded from a version control repository, and so on.
The VFS level deals only with binary content. You can get or set the contents of a VirtualFile as a stream of bytes, but concepts like encodings and line separators are handled on higher system levels.
The VFS level deals only with binary content. You can get or set the contents of a `VirtualFile` as a stream of bytes, but concepts like encodings and line separators are handled on higher system levels.
#### How do I get a virtual file?
## How do I get a virtual file?
* From an action: `e.getData(PlatformDataKeys.VIRTUAL_FILE)`. If you are interested in multiple selection, you can also use `e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY)`.
* From an action: `e.getData(PlatformDataKeys.VIRTUAL_FILE)`. If you are interested in multiple selection, you can also use `e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY)`.
* From a path in the local file system: `LocalFileSystem.getInstance().findFileByIoFile()`
* From a PSI file: `psiFile.getVirtualFile()` (may return null if the PSI file exists only in memory)
* From a document: `FileDocumentManager.getInstance().getFile()`
* From a path in the local file system: `LocalFileSystem.getInstance().findFileByIoFile()`
## What can I do with it?
* From a PSI file: `psiFile.getVirtualFile()` (may return null if the PSI file exists only in memory)
Typical file operations are available, such as traverse the file system, get file contents, rename, move, or delete. Recursive iteration should be performed using `VfsUtilCore.iterateChildrenRecursively` to prevent endless loops caused by recursive symlinks.
* From a document: `FileDocumentManager.getInstance().getFile()`
## Where does it come from?
#### What can I do with it?
The VFS is built incrementally, by scanning the file system up and down starting from the project root. New files appearing in the file system are detected by VFS _refreshes_. A refresh operation can be initiated programmatically using (`VirtualFileManager.getInstance().refresh()` or `VirtualFile.refresh()`). VFS refreshes are also triggered whenever file system watchers receive file system change notifications (available on the Windows and Mac operating systems).
Typical file operations are available, such as traverse the file system, get file contents, rename, move, or delete.
Recursive iteration should be performed using `VfsUtilCore.iterateChildrenRecursively` to prevent endless loops caused by recursive symlinks.
#### Where does it come from?
The VFS is built incrementally, by scanning the file system up and down starting from the project root.
New files appearing in the file system are detected by VFS _refreshes_. A refresh operation can be initiated programmatically using (`VirtualFileManager.getInstance().refresh()` or `VirtualFile.refresh()`).
VFS refreshes are also triggered whenever file system watchers receive file system change notifications (available on the Windows and Mac operating systems).
As a plugin developer, you may want to invoke a VFS refresh if you need to access a file that has just been created by an external tool through IntelliJ IDEA APIs.
#### How long does a virtual file persist?
## How long does a virtual file persist?
A particular file on disk is represented by equal&nbsp;`VirtualFile` instances for the entire lifetime of the IDEA process. There may be several instances corresponding to the same file, and they can be garbage-collected.
The file is a `UserDataHolder`, and the user data is shared between those equal instances. If a file is deleted, its corresponding VirtualFile instance becomes invalid ( the `isValid()` method returns _false_ and operations cause exceptions).
A particular file on disk is represented by equal `VirtualFile` instances for the entire lifetime of the IDEA process. There may be several instances corresponding to the same file, and they can be garbage-collected. The file is a `UserDataHolder`, and the user data is shared between those equal instances. If a file is deleted, its corresponding VirtualFile instance becomes invalid (the `isValid()` method returns `false` and operations cause exceptions).
#### How do I create a virtual file?
## How do I create a virtual file?
Usually you don't. As a rule, files are created either through the PSI API or through the regular java.io.File API.
If you do need to create a file through VFS, you can use the `VirtualFile.createChildData()` method to create a `VirtualFile` instance and the `VirtualFile.setBinaryContent()` method to write some data to the file.
#### How do I get notified when VFS changes?
## How do I get notified when VFS changes?
The `VirtualFileManager.addVirtualFileListener()` method allows you to receive notifications about all changes in the VFS.
#### How do I extend VFS?
## How do I extend VFS?
To provide an alternative file system implementation (for example, an FTP file system), implement the
[VirtualFileSystem](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java)
class (most likely you'll also need to implement `VirtualFile`), and register your implementation as an
[application component](/basics/plugin_structure/plugin_components.md).
To hook into operations performed in the local file system (for example, if you are developing a version control system integration that needs custom rename/move handling), implement the
[LocalFileOperationsHandler](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/vfs/LocalFileOperationsHandler.java)
interface and register it through the`LocalFileSystem.registerAuxiliaryFileOperationsHandler` method.
To provide an alternative file system implementation (for example, an FTP file system), implement the [VirtualFileSystem](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java) class (most likely you'll also need to implement `VirtualFile`), and register your implementation as an [application component](/basics/plugin_structure/plugin_components.md).
#### What are the rules for working with VFS?
To hook into operations performed in the local file system (for example, if you are developing a version control system integration that needs custom rename/move handling), implement the [LocalFileOperationsHandler](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/vfs/LocalFileOperationsHandler.java) interface and register it through the`LocalFileSystem.registerAuxiliaryFileOperationsHandler` method.
See
[IntelliJ Platform Virtual File System](/basics/virtual_file_system.md)
for a detailed description of the VFS architecture and usage guidelines.
## What are the rules for working with VFS?
See [IntelliJ Platform Virtual File System](/basics/virtual_file_system.md) for a detailed description of the VFS architecture and usage guidelines.

View File

@ -3,71 +3,43 @@ title: Check Out And Build Community Edition
---
## Installing Git
The source code of IntelliJ IDEA Community Edition is stored in a Git repository.
Therefore, in order to check out the sources, you need to have Git installed.
We recommend using the
[msys git](https://msysgit.github.io)
distribution on Windows and
[git-osx-installer](http://code.google.com/p/git-osx-installer/)
on Mac.
The source code of IntelliJ IDEA Community Edition is stored in a Git repository. Therefore, in order to check out the sources, you need to have Git installed. We recommend using the [msys git](https://msysgit.github.io) distribution on Windows and [git-osx-installer](http://code.google.com/p/git-osx-installer/) on Mac.
## Checking Out the Code
You can check out the code either by using IntelliJ IDEA or from the command line.
**Checking out from IntelliJ IDEA:**
* Select **VCS \| Checkout from Version Control \| Git** from the main menu
* In the **Git Repository URL** field, enter `git://git.jetbrains.org/idea/community.git`
![Check Out Community](img/check_out_community.png)
**Checking out from the command line**
**Checking out from the command line:**
Please execute the following command:
```
git clone git://git.jetbrains.org/idea/community.git idea
```
The
[master](https://github.com/JetBrains/intellij-community/tree/master)
branch currently contains the code for the development version of IntelliJ IDEA 15.x.
Source code of older releases of IntelliJ IDEA can be found in the following branches:
The [master](https://github.com/JetBrains/intellij-community/tree/master) branch currently contains the code for the development version of IntelliJ IDEA 15.x. Source code of older releases of IntelliJ IDEA can be found in the following branches:
15.0.x -
[143](https://github.com/JetBrains/intellij-community/tree/143)
14.1.x -
[141](https://github.com/JetBrains/intellij-community/tree/141)
14.0.x -
[139](https://github.com/JetBrains/intellij-community/tree/139)
13.1.x -
[135](https://github.com/JetBrains/intellij-community/tree/135)
13.0.x -
[133](https://github.com/JetBrains/intellij-community/tree/133)
12.0.x -
[123](https://github.com/JetBrains/intellij-community/tree/123)
11.1.x -
[117](https://github.com/JetBrains/intellij-community/tree/117)
11.0.x -
[nika](https://github.com/JetBrains/intellij-community/tree/nika)
10.5.x -
[xena](https://github.com/JetBrains/intellij-community/tree/xena)
10.0.x -
[x0x](https://github.com/JetBrains/intellij-community/tree/x0x)
9.x -
[maia](https://github.com/JetBrains/intellij-community/tree/maia)
| IntelliJ Product version | Branch name/number |
|==========================|====================|
| 15.0.x | [143](https://github.com/JetBrains/intellij-community/tree/143) |
| 14.1.x | [141](https://github.com/JetBrains/intellij-community/tree/141) |
| 14.0.x | [139](https://github.com/JetBrains/intellij-community/tree/139) |
| 13.1.x | [135](https://github.com/JetBrains/intellij-community/tree/135) |
| 13.0.x | [133](https://github.com/JetBrains/intellij-community/tree/133) |
| 12.0.x | [123](https://github.com/JetBrains/intellij-community/tree/123) |
| 11.1.x | [117](https://github.com/JetBrains/intellij-community/tree/117) |
| 11.0.x | [nika](https://github.com/JetBrains/intellij-community/tree/nika) |
| 10.5.x | [xena](https://github.com/JetBrains/intellij-community/tree/xena) |
| 10.0.x | [x0x](https://github.com/JetBrains/intellij-community/tree/x0x) |
| 9.x | [maia](https://github.com/JetBrains/intellij-community/tree/maia) |
You can also browse the source code through the Web interface.
@ -75,52 +47,41 @@ You can also browse the source code through the Web interface.
As an alternative to checking out the official repository, you can fork the GitHub mirror of the IntelliJ IDEA source code, make changes in your own fork, and send us a pull request.
The GitHub mirror can be found at
[https://github.com/JetBrains/intellij-community](https://github.com/JetBrains/intellij-community)
The GitHub mirror can be found at [https://github.com/JetBrains/intellij-community](https://github.com/JetBrains/intellij-community).
## Building and Running from the IDE
To develop IntelliJ IDEA, you can use either
[IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download/)
or
[IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/download/).
To develop IntelliJ IDEA, you can use either [IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download/) or [IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/download/).
**Building and running the code**
* Make sure you have the
[Groovy plugin](https://plugins.jetbrains.com/plugin/1524)
enabled by going to **Settings \| Plugins** and enabling **Groovy** plugin checkbox.
* Make sure you have the [Groovy plugin](https://plugins.jetbrains.com/plugin/1524) enabled by going to **Settings \| Plugins** and enabling **Groovy** plugin checkbox.
![Groovy plugin](img/groovy_plugin_enabled.png)
Parts of IntelliJ IDEA are written in Groovy, and you will get compilation errors if you don't have the plugin enabled
Parts of IntelliJ IDEA are written in Groovy, and you will get compilation errors if you don't have the plugin enabled.
* Make sure you have the UI Designer plugin enabled.
Most of IntelliJ IDEA's UI is built using the UI Designer, and the version you build will not run correctly if you don't have the plugin enabled
* Make sure you have the UI Designer plugin enabled. Most of IntelliJ IDEA's UI is built using the UI Designer, and the version you build will not run correctly if you don't have the plugin enabled.
![UI Designer plugin](img/ui_designer_plugin_enabled.png)
* Open the directory with the source code as a directory-based project
* Open the directory with the source code as a directory-based project.
* Configure a Java SDK named *IDEA jdk* (case sensitive), pointing to an installation of JDK 1.8
![Configure SDK](img/configure_sdk.png)
* Add **lib\\tools.jar** from the JDK installation directory to the classpath of IDEA JDK
* Add `lib\\tools.jar` from the JDK installation directory to the classpath of IDEA JDK
![tools.jar](img/tools_jar.png)
* Use **Build \| Make Project** to build the code
* To run the code, use the provided shared run configuration *IDEA*
* Use **Build \| Make Project** to build the code.
* To run the code, use the *IDEA* shared run configuration provided by the project.
![IDEA Run Configuration](img/idea_run_configuration.png)
## Building and Running from the Command Line
To build the distribution archive of *IntelliJ IDEA Community Edition*, execute
[build.xml](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/build.xml)
Ant build script in the root directory of the source code.
To build the distribution archive of *IntelliJ IDEA Community Edition*, execute the [build.xml](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/build.xml) Ant build script in the root directory of the source code.
![Execute Ant Build Script](img/ant_build_xml.png)

View File

@ -2,27 +2,15 @@
title: Creating Your First Plugin
---
This documentation section will help you get started with developing plugins for *IntelliJ Platform*.
You can use either
[IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download/) or
[IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/download/) as your IDE.
Both include the complete set of plugin development tools.
To become more familiar with *IntelliJ IDEA*, please refer to
[IntelliJ IDEA Web Help](https://www.jetbrains.com/idea/help/)
This documentation section will help you get started with developing plugins for the *IntelliJ Platform*. You can use either [IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download/) or [IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/download/) as your IDE. Both include the complete set of plugin development tools. To become more familiar with *IntelliJ IDEA*, please refer to the [IntelliJ IDEA Web Help](https://www.jetbrains.com/idea/help/).
In this section:
* [Setting Up a Development Environment](getting_started/setting_up_environment.md)
* [Creating a Plugin Project](getting_started/creating_plugin_project.md)
* [Build Number Ranges](getting_started/build_number_ranges.md)
* [Creating an Action](getting_started/creating_an_action.md)
* [Running and Debugging a Plugin](getting_started/running_and_debugging_a_plugin.md)
* [Deploying a Plugin](getting_started/deploying_plugin.md)
* [Plugin Compatibility with IntelliJ Platform Products](getting_started/plugin_compatibility.md)
* [Publishing a plugin to plugin repository](getting_started/publishing_plugin.md)

View File

@ -4,7 +4,7 @@ title: Build Number Ranges
Use this reference of build number ranges to specify the correct `since-build` and `until-build` values in your plugin descriptor.
Starting with IntelliJ IDEA 9 beta, a multi-part build number is used:
Starting with IntelliJ IDEA 9 beta, a multi-part build number is used, such as:
```
IU-90.94
@ -13,14 +13,10 @@ IU-90.94
The number consists of the following parts:
* Product ID (IC for IDEA Community, IU for IDEA Ultimate, RM for RubyMine, PY for PyCharm, etc.)
* Branch number ("90")
* Build number in the branch ("94")
Every time a release branch is created for one of the products based on IntelliJ Platform, the branch number in the release branch is incremented by 1, and the branch number in the trunk is incremented by 2.
Accordingly, the trunk always has even branch numbers (90, 92, 94, etc.), while release branches have odd branch numbers (91, 93, etc.).
For example, the RubyMine 7 release branch has the branch number 139.
Every time a release branch is created for one of the products based on IntelliJ Platform, the branch number in the release branch is incremented by 1, and the branch number in the trunk is incremented by 2. Accordingly, the trunk always has even branch numbers (90, 92, 94, etc.), while release branches have odd branch numbers (91, 93, etc.). For example, the RubyMine 7 release branch has the branch number 139.
Multi-part build numbers can also be used in the `since-build` and `until-build` attributes of `idea-version`. Usually you should omit the product ID and use only the branch number and build number, for example:
@ -31,151 +27,70 @@ Multi-part build numbers can also be used in the `since-build` and `until-build`
The following branch numbers are used for IntelliJ Platform-based products and build numbers of recent IDE versions:
* branch 143 - IntelliJ IDEA 15, WebStorm 11, PyCharm 5, PhpStorm 10, RubyMine 8, AppCode 3.3, CLion 1.2
* branch 141 - IntelliJ IDEA 14.1, WebStorm 10, PyCharm 4.1, Android Studio 1.3
* branch 139 - IntelliJ IDEA 14, WebStorm 9, PyCharm 4, PhpStorm 8, RubyMine 7
* branch 135 - IntelliJ IDEA 13.1, WebStorm 8
* branch 133 - IntelliJ IDEA 13, PyCharm 3.1, WebStorm 7, PhpStorm 7
* branch 131 - WebStorm 7, PyCharm 3.0, PhpStorm 7
* branch 129 - IntelliJ IDEA 12.1, bug-fix updates for PyCharm 2.7, PhpStorm/WebStorm 6
* branch 127 - PhpStorm/WebStorm 6.0, AppCode 2.0
* branch 125 - PyCharm 2.7, RubyMine 5.0
* branch 123 - IntelliJ IDEA 12
* 12.0 - 123.72
* branch 121 - AppCode 1.6, PyCharm 2.6, PhpStorm/WebStorm 5.0
* branch 119 - RubyMine 4.5
* branch 117 - IntelliJ IDEA 11.1, PyCharm 2.5, RubyMine 4.0.x, AppCode 1.5, PhpStorm/WebStorm 4.0
* 11.1 - 117.105
* 11.1.1 - 117.117
* 11.1.2 - 117.418
* 11.1.3 - 117.798
* branch 111 - IntelliJ IDEA 11.0
* 11.0 - 111.69
* 11.0.1 - 111.167
* 11.0.2 - 111.277
* branch 107 - IDEA 10.5
* 10.5 - 107.105
* 10.5.1 - 107.322
* 10.5.2 - 107.587
* branch 103 - IDEA 10.0.2\+
* 10.0.2 - 103.72
* 10.0.3 - 103.255
* 10.0 - 99.18
* 10.0.1 - 99.32
* branch 95 - IDEA 9.0.2\+
* 9.0.2 - 95.66
* 9.0.3 - 95.429
* 9.0.4 - 95.627
* branch 99 - IDEA 10.0
* branch 93 - IDEA 9.0
* 9.0 - 93.13
* 9.0.1 - 93.94
---
Previous versions of IntelliJ IDEA use linear build numbers, with the following ranges:
* IntelliJ IDEA 8.1.x - 9500-9999
* IntelliJ IDEA 8.1 - 9732
* IntelliJ IDEA 8.0.x - 9100-9499
* IntelliJ IDEA 8.0.1 - 9164
* IntelliJ IDEA 8.0 - 8000-9099
* IntelliJ IDEA 8.0M1 - 8664
* IntelliJ IDEA 8.0 - 9013
* IntelliJ IDEA 7.0.2\+ - 7500-7999
* 7.0.2 - 7590
* 7.0.3 - 7757
* 7.0.5 - 7971
* IntelliJ IDEA 7.0 final - 7200-7499
* 7.0 final - 7361
* IntelliJ IDEA 7.0 pre-M2 - 6900-7199
* 7.0 M2 - 7126
* IntelliJ IDEA 7.0 pre-M1 - 6500-6899
* 7.0 M1 - 6813
* IntelliJ IDEA 6.0.2 branch - 6000-6499
* 6.0.5 - 6180
* 6.0.6 - 6197
* IntelliJ IDEA 6.0 branch - 5000-5999
* 6.0.1 - 5784
* IntelliJ IDEA 5.1 branch - 4000-4999
* 5.1.2 - 4267

View File

@ -4,7 +4,7 @@ title: Creating an action
Your plugins can customize the Intellij IDEA UI by adding new items to the menus and toolbars. Intellij IDEA provides the [AnAction.java](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java) class whose `actionPerformed` method is called each time you select a menu item or click a toolbar button.
To customize **IntelliJ IDEA**, you should perform two basic steps:
To customize *IntelliJ IDEA*, 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.
@ -13,7 +13,7 @@ This topic outlines the above steps. For detailed information and samples, refer
### 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.
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:
@ -23,10 +23,10 @@ public class TextBoxes extends AnAction {
// (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"));
// 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) {
@ -41,8 +41,7 @@ Note that optionally, you can define a set of classes derived from the `AnAction
### 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:
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.
@ -51,7 +50,7 @@ This section provides some examples that illustrate how to register actions. For
#### 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:
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:
![Sample Menu](img/sample_menu.jpg)
@ -86,7 +85,7 @@ Note that you can use this wizard only to add a new action to an existing 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: <Plugin name>.<ID>
* **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.
@ -95,4 +94,4 @@ Note that you can use this wizard only to add a new action to an existing action
![New Action Page](img/new_action_page.png)
IntelliJ IDEA 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.
IntelliJ IDEA 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.

View File

@ -2,11 +2,8 @@
title: Creating a Plugin Project
---
This section explains how you can create a new plugin project from a scratch using the New Project wizard.
Optionally, you can import an existing project or import a project from external models.
You can also add a new plugin module to an existing *Intellij IDEA* project.
For more information, refer to
[Intellij IDEA Web Help](https://www.jetbrains.com/idea/help/new-project-wizard.html).
This section explains how you can create a new plugin project from scratch using the New Project wizard. Optionally, you can import an existing project or import a project from external models. You can also add a new plugin module to an existing *Intellij IDEA* project.
For more information, refer to the [Intellij IDEA Web Help](https://www.jetbrains.com/idea/help/new-project-wizard.html).
## To create a plugin project:
@ -16,11 +13,7 @@ For more information, refer to
![New Project Wizard](img/new_project_wizard.png)
* Set *IntelliJ Platform Plugin* project type
* Click **Next**
* Set desired project name
* Click **Finish** to generate project structure files
* Go to **File \| Project Structure** to customize project settings if required

View File

@ -7,28 +7,20 @@ Before your custom plugin can be used, it must be deployed: built, installed, an
To deploy a plugin:
* Make your project by invoking **Build \| Make Project**.
* Prepare your plugin for deployment.
In the main menu, select **Build \| Prepare Plugin Module `<module name>` for Deployment**.
* Prepare your plugin for deployment. In the main menu, select **Build \| Prepare Plugin Module '<module name>' for Deployment**.
![Prepare Plugin for Deployment](deploying_plugin/img/prepare_plugin_for_deployment.png)
* If the plugin module does not depend on any libraries, a .jar archive will be created.
Otherwise, a .zip archive will be created including all the plugin libraries specified in the project settings.
* If the plugin module does not depend on any libraries, a `.jar` archive will be created. Otherwise, a `.zip` archive will be created including all the plugin libraries specified in the project settings.
![Jar Saved Notification](deploying_plugin/img/jar_saved_notification.png)
* Copy the newly created archive file to the *.IntelliJIDEAx0\config\plugins* folder, and then restart IntelliJ IDEA so the changes take effect.
To know how to locate your *plugins* directory, refer to [IDE Settings, Caches, Logs, and Plugins](/basics/settings_caches_logs.md).
* Copy the newly created archive file to the `.IntelliJIDEAx0\config\plugins` folder, and then restart IntelliJ IDEA so the changes take effect. To know how to locate your *plugins* directory, refer to [IDE Settings, Caches, Logs, and Plugins](/basics/settings_caches_logs.md).
![Jar File Location](deploying_plugin/img/jar_location.png)
* In the main menu, select **File \| Settings** to open the Settings dialog box.
* In the Settings dialog box, under **IDE Settings**, click **Plugins**.
* In the Plugins area, open the **Installed** tab, and then select the check-box next to your plugin name.
* When finished, click OK to close the Settings dialog box.
* Restart *IntelliJ IDEA* so that your changes take effect.

View File

@ -3,11 +3,10 @@ title: Plugin Compatibility with IntelliJ Platform Products
---
<!--TODO link to sample_plugin file-->
All products based on IntelliJ Platform (IntelliJ IDEA, RubyMine, WebStorm, PhpStorm, PyCharm, AppCode, etc.) share the same underlying platform API.
Thus, a plugin that does not use any Java-specific functionality may be marked as compatible with these other products in addition to IntelliJ IDEA.
This is done by specifying *module dependencies* in the `plugin.xml` file.
A module dependency is a `<depends>` tag where the contents of the tag starts with *com.intellij.modules*.
All products based on IntelliJ Platform (IntelliJ IDEA, RubyMine, WebStorm, PhpStorm, PyCharm, AppCode, etc.) share the same underlying platform API. Thus, a plugin that does not use any Java-specific functionality may be marked as compatible with these other products in addition to IntelliJ IDEA. This is done by specifying *module dependencies* in the `plugin.xml` file.
A module dependency is a `<depends>` tag where the contents of the tag starts with `com.intellij.modules`.
For example:
@ -20,47 +19,34 @@ For example:
```
<!--TODO link to sample_plugin file-->
If a plugin does not include any module dependency tags in its `plugin.xml`, it's assumed to be a legacy plugin and is loaded only in IntelliJ IDEA.
<!--TODO link to sample_plugin file-->
If a plugin does not include any module dependency tags in its `plugin.xml`, it's assumed to be a legacy plugin and is loaded only in IntelliJ IDEA.
If the `plugin.xml` includes one or more such tags, the plugin is loaded if the product contains all of the modules on which the plugin depends.
The following modules are currently available in all products based on IntelliJ Platform:
* *com.intellij.modules.platform*
* *com.intellij.modules.lang*
* *com.intellij.modules.vcs*
* *com.intellij.modules.xml*
* *com.intellij.modules.xdebugger*
* `com.intellij.modules.platform`
* `com.intellij.modules.lang`
* `com.intellij.modules.vcs`
* `com.intellij.modules.xml`
* `com.intellij.modules.xdebugger`
The following modules are only available in specific products:
* *com.intellij.modules.java* \- IntelliJ IDEA
* `com.intellij.modules.java` - IntelliJ IDEA
* `com.intellij.modules.ultimate` - IntelliJ IDEA Ultimate Edition
* `com.intellij.modules.ruby` - RubyMine
* `com.intellij.modules.python` - PyCharm
* `com.intellij.modules.appcode` - AppCode
* `com.intellij.modules.clion` - CLion
* `com.intellij.modules.cidr.lang` - AppCode, CLion
* `com.intellij.modules.cidr.debugger` - AppCode, CLion, RubyMotion
* `com.intellij.modules.androidstudio` - Android Studio
* *com.intellij.modules.ultimate* \- IntelliJ IDEA Ultimate Edition
PhpStorm does not have any modules specific to itself, but it includes the PHP plugin, which you can also use as a dependency: `com.jetbrains.php`
* *com.intellij.modules.ruby* \- RubyMine
* *com.intellij.modules.python* \- PyCharm
* *com.intellij.modules.appcode* \- AppCode
* *com.intellij.modules.clion* \- CLion
* *com.intellij.modules.cidr.lang* \- AppCode, CLion
* *com.intellij.modules.cidr.debugger* \- AppCode, CLion, RubyMotion
* *com.intellij.modules.androidstudio* \- Android Studio
PhpStorm does not have any modules specific to itself, but it includes the PHP plugin, which you can also use as a dependency: *com.jetbrains.php*
You can also specify optional module dependencies.
If your plugin works with all products but provides some Java-specific functionality, you can use a dependency tag like this:
You can also specify optional module dependencies. If your plugin works with all products but provides some Java-specific functionality, you can use a dependency tag like this:
```xml
<depends optional="true" config-file="my-java-features.xml">
@ -68,8 +54,6 @@ If your plugin works with all products but provides some Java-specific functiona
</depends>
```
Before marking a plugin as compatible with all products, you should verify that it doesn't use any APIs that are specific to IntelliJ IDEA. To do so, create an IntelliJ Platform SDK pointing to an installation of RubyMine/PyCharm/etc., compile your plugin against that SDK, and verify that everything compiles.
Before marking a plugin as compatible with all products, you should verify that it doesn't use any APIs that are specific to IntelliJ IDEA. To do so, create an IntelliJ Platform SDK pointing to an installation of RubyMine, PyCharm, etc., compile your plugin against that SDK, and verify that everything compiles.
The
[IntelliJ plugin repository](http://plugins.jetbrains.com/)
automatically detects the products with which a plugin is compatible, based on the rules above, and makes it available to users of those products.
The [IntelliJ plugin repository](http://plugins.jetbrains.com/) automatically detects the products with which a plugin is compatible, based on the rules above, and makes it available to users of those products.

View File

@ -2,7 +2,7 @@
title: Publishing a plugin
---
When your plugin is ready, you can upload it to [IntelliJ Plugin Repository](https://plugins.jetbrains.com). To perform this operation, you must login with your personal JetBrains account.
When your plugin is ready, you can upload it to the [IntelliJ Plugin Repository](https://plugins.jetbrains.com). To perform this operation, you must login with your personal JetBrains Account.
**To get your JetBrains account**

View File

@ -2,23 +2,16 @@
title: Running and Debugging a Plugin
---
The *IntelliJ Platform* allows you to run and debug a plugin without leaving the IDE. To run or debug the plugin from within *IntelliJ IDEA*, you need a configured special profile (a Run/Debug configuration) that specifies the class to run, VM parameters and other specific options. In most cases, you can use the default *Run/Debug* configuration profiles for your plugin projects.
For information on how to change the Run/Debug configuration profile, refer to [Run/Debug Configuration](http://www.jetbrains.com/idea/help/run-debug-configuration.html) and [Run/Debug Configuration: Plugin](http://www.jetbrains.com/idea/help/run-debug-configuration-plugin.html) in *Intellij IDEA* Web Help.
*IntelliJ Platform* allows you to run and debug a plugin without leaving the IDE.
To run or debug the plugin from within *IntelliJ IDEA*, you need a configured special profile (a Run/Debug configuration) that specifies the class to run, VM parameters and other specific options.
In most cases, you can use the default *Run/Debug* configuration profiles for your plugin projects.
For information on how to change the Run/Debug configuration profile, refer to
[Run/Debug Configuration](http://www.jetbrains.com/idea/help/run-debug-configuration.html)
and
[Run/Debug Configuration: Plugin](http://www.jetbrains.com/idea/help/run-debug-configuration-plugin.html)
in *Intellij IDEA* Web Help.
Using IntelliJ IDEA's debugger, you can find out the origin of the run-time errors and exceptions.
Using *IntelliJ IDEA*'s debugger, you can find out the origin of the run-time errors and exceptions.
**To debug a plugin**
* Select **Run \| Debug** in the main menu, or press *Shift + F9*.
* Select **Run \| Debug** in the main menu, or press <kbd>Shift</kbd> + <kbd>F9</kbd>.
**To run a plugin**
* Select **Run \| Run** in the main menu, or press *Shift + F10*.
* Select **Run \| Run** in the main menu, or press <kbd>Shift</kbd> + <kbd>F10</kbd>.

View File

@ -6,9 +6,9 @@ title: Setting Up a Development Environment
Use the following check list to ensure that you are ready to develop your custom plugins.
- [x] **IntelliJ IDEA** version 9.0 or later (either Community Edition or Ultimate) must be installed on your computer.
- [x] **IntelliJ IDEA CE source code** should be checked out to your local computer. This is not a requirement but will make it much easier for you to debug your plugins. For detailed instructions, refer to [Check Out And Build Community Edition](/basics/checkout_and_build_community.md).
- [x] **IntelliJ Platform SDK** must configured for your IDEA project. For more information, see [Configuring IntelliJ Platform SDK](#configuring-intellij-platform-sdk) below.
- **IntelliJ IDEA** version 9.0 or later (either Community Edition or Ultimate) must be installed on your computer.
- **IntelliJ IDEA CE source code** should be checked out to your local computer. This is not a requirement but will make it much easier for you to debug your plugins. For detailed instructions, refer to [Check Out And Build Community Edition](/basics/checkout_and_build_community.md).
- **IntelliJ Platform SDK** must configured for your IDEA project. For more information, see [Configuring IntelliJ Platform SDK](#configuring-intellij-platform-sdk) below.
### Configuring IntelliJ Platform SDK

View File

@ -2,17 +2,14 @@
title: Persisting State of Components
---
The *IntelliJ Platform* provides an API that allows components or services to persist their state between restarts of the IDE. You can use either a simple API to persist a few values, or persist the state of more complicated components using the [PersistentStateComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/PersistentStateComponent.java) interface.
The IntelliJ Platform provides an API that allows components or services to persist their state between restarts of the IDE.
You can use either a simple API to persist a few values, or persist the state of more complicated components using the
[PersistentStateComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/PersistentStateComponent.java)
interface.
## Using PropertiesComponent for simple non-roamable persistence
## Using PropertiesComponent for Simple non-roamable Persistence
If the only thing that your plugin needs to persist is a few simple values, the easiest way to do so is to use the `com.intellij.ide.util.PropertiesComponent` service. It can be used for saving both application level values and project level values (stored in the workspace file). Roaming is disabled for `PropertiesComponent`, so use it only for temporary, non-roamable properties.
If the only thing that your plugin needs to persist is a few simple values, the easiest way to do so is to use the `com.intellij.ide.util.PropertiesComponent` service. It can be used for saving both application-level values and project-level values (stored in the workspace file). Roaming is disabled for PropertiesComponent, so, use it only for temporary non-roamable properties.
Use the `PropertiesComponent.getInstance()` method for storing application level values, and the `PropertiesComponent.getInstance(Project)` method for storing project-level values.
Use the `PropertiesComponent.getInstance()` method for storing application-level values, and the `PropertiesComponent.getInstance(Project)` method for storing project-level values.
Since all plugins share the same namespace, it is highly recommended to prefix key names (e.g. using your plugin ID).
## Using PersistentStateComponent
@ -21,7 +18,7 @@ The `com.intellij.openapi.components.PersistentStateComponent` interface gives y
Note that instances of extensions cannot persist their state by implementing `PersistentStateComponent`. If your extension needs to have persistent state, you need to define a separate service responsible for managing that state.
### Implementing the PersistentStateComponent Interface
### Implementing the PersistentStateComponent interface
The implementation of `PersistentStateComponent` needs to be parameterized with the type of the state class. The state class can either be a separate JavaBean class, or the class implementing `PersistentStateComponent` itself.
@ -32,10 +29,13 @@ class MyService implements PersistentStateComponent<MyService.State> {
class State {
public String value;
}
State myState;
public State getState() {
return myState;
}
public void loadState(State state) {
myState = state;
}
@ -58,77 +58,64 @@ class MyService implements PersistentStateComponent<MyService> {
}
```
### Implementing the State Class
### Implementing the state class
The implementation of `PersistentStateComponent` works by serializing public fields,
[annotated](https://github.com/JetBrains/intellij-community/tree/master/platform/util/src/com/intellij/util/xmlb/annotations)
private fields and bean properties into an XML format. The following types of values can be persisted:
The implementation of `PersistentStateComponent` works by serializing public fields, [annotated](https://github.com/JetBrains/intellij-community/tree/master/platform/util/src/com/intellij/util/xmlb/annotations) private fields and bean properties into an XML format. The following types of values can be persisted:
* numbers (both primitive types, such as int, and boxed types, such as Integer);
* booleans;
* strings;
* collections;
* maps;
* enums.
* numbers (both primitive types, such as `int`, and boxed types, such as `Integer`)
* booleans
* strings
* collections
* maps
* enums
In order to exclude a public field or bean property from serialization, you can annotate the field or getter with the `@com.intellij.util.xmlb.annotations.Transient` annotation.
Note that the state class must have a default constructor.
It should return the default state of the component (one used if there is nothing persisted in the XML files yet).
Note that the state class must have a default constructor. It should return the default state of the component (one used if there is nothing persisted in the XML files yet).
State class should have a `equals` method, but if it is not implemented, state objects will be compared by fields.
If you write in Kotlin, use [Data](http://kotlinlang.org/docs/reference/data-classes.html).
State class should have a `equals` method, but if it is not implemented, state objects will be compared by fields. If you write in Kotlin, use [Data](http://kotlinlang.org/docs/reference/data-classes.html).
### Defining the Storage Location
### Defining the storage location
In order to specify where exactly the persisted values wiil be stored, you need to add a `@State` annotation to the `PersistentStateComponent` class.
It has the following fields:
In order to specify where exactly the persisted values will be stored, you need to add a `@State` annotation to the `PersistentStateComponent` class. It has the following fields:
* `name` (required) - specifies the name of the state (name of the root tag in XML)
* One or more of `@com.intellij.openapi.components.Storage` annotations (required) - specify the storage locations for .ipr and directory-based projects
* One or more of `@com.intellij.openapi.components.Storage` annotations (required) - specify the storage locations for `.ipr` and directory-based projects
* `reloadable` (optional) - if set to false, complete project reload is required when the XML file is changed externally and the state has changed.
The simplest ways of specifying the `@Storage` annotation are as follows:
* `@Storage(id="other", file = StoragePathMacros.APP_CONFIG + "/yourName.xml")` for application-level values
* `@Storage(id="other", file = StoragePathMacros.PROJECT_FILE)` for values stored in the project file (for .ipr based projects)
* `@Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/other.xml", scheme = StorageScheme.DIRECTORY_BASED)})` for values stored in the project directory (for directory-based projects)
* `@Storage(id="other", file = StoragePathMacros.WORKSPACE_FILE)` for values stored in the workspace file
By specifying a different value for the `file` parameter, you can cause the state to be persisted in a different file. For application-level components strongly recommended to use custom file, using of `other.xml` is deprecated.
The `roamingType` parameter of the `@Storage` annotation specifies the roaming type when the Settings Repository plugin is used.
The `id` parameter of the `@Storage` annotation can be used to exclude specific fields from serialization in specific formats.
If you do not need to exclude anything, you can set the `id` to an arbitrary string value.
If you need to specify where the values are stored when the directory-based project format is used, you need to add the second `@Storage` annotation with the scheme parameter set to StorageScheme.DIRECTORY_BASED, for example:
* `@Storage(id = "other", file = StoragePathMacros.APP_CONFIG + "/yourName.xml")` for application level values
* `@Storage(id = "other", file = StoragePathMacros.PROJECT_FILE)` for values stored in the project file (for `.ipr` based projects)
* `@Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/other.xml", scheme = StorageScheme.DIRECTORY_BASED)})` for values stored in the project directory (for directory based projects)
* `@Storage(id = "other", file = StoragePathMacros.WORKSPACE_FILE)` for values stored in the workspace file
The `id` parameter of the `@Storage` annotation can be used to exclude specific fields from serialization in specific formats. If you do not need to exclude anything, you can set the `id` to an arbitrary string value. If you need to specify where the values are stored when the directory-based project format is used, you need to add the second `@Storage` annotation with the scheme parameter set to `StorageScheme.DIRECTORY_BASED`, for example:
```java
@State(
name = "AntConfiguration",
storages = {
@Storage(id = "default", file = StoragePathMacros.PROJECT_FILE),
@Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/ant.xml", scheme = StorageScheme.DIRECTORY_BASED)
}
@State(name = "AntConfiguration",
storages = {
@Storage(id = "default", file = StoragePathMacros.PROJECT_FILE),
@Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/ant.xml", scheme = StorageScheme.DIRECTORY_BASED)
}
)
```
## Customizing the XML Format of Persisted Values
By specifying a different value for the `file` parameter, you can cause the state to be persisted in a different file. For application level components strongly recommended to use custom file, using of `other.xml` is deprecated.
Please consider to use annotation parameters only to achieve backward compatibility.
Otherwise feel free to file issues about serialization cosmetics.
The `roamingType` parameter of the `@Storage` annotation specifies the roaming type when the Settings Repository plugin is used.
## Customizing the XML format of persisted values
Please consider to use annotation parameters only to achieve backward compatibility. Otherwise feel free to file issues about serialization cosmetics.
If you want to use the default bean serialization but need to customize the storage format in XML (for example, for compatibility with previous versions of your plugin or externally defined XML formats), you can use the `@Tag`, `@Attribute`, `@Property`, `@MapAnnotation`, `@AbstractCollection` annotations.
You can look at the source code (`com.intellij.util.xmlb` package) to get more information about the meaning of these annotations.
If the state that you need to serialize doesn't map cleanly to a JavaBean, you can use `org.jdom.Element` as the state class.
In that case, you can use the `getState()` method to build an XML element with an arbitrary structure, which will then be saved directly in the state XML file.
In the `loadState()` method, you can deserialize the JDOM element tree using any custom logic.
But this way is not recommended and should be avoided.
If the state that you need to serialize doesn't map cleanly to a JavaBean, you can use `org.jdom.Element` as the state class. In that case, you can use the `getState()` method to build an XML element with an arbitrary structure, which will then be saved directly in the state XML file. In the `loadState()` method, you can deserialize the JDOM element tree using any custom logic. But this way is not recommended and should be avoided.
## Persistent Component Lifecycle
## Persistent component lifecycle
The `loadState()` method is called after the component has been created (only if there is some non-default state persisted for the component), and after the XML file with the persisted state is changed externally (for example, if the project file was updated from the version control system). In the latter case, the component is responsible for updating the UI and other related components according to the changed state.
@ -136,11 +123,11 @@ The `getState()` method is called every time the settings are saved (for example
## Legacy API (JDOMExternalizable)
Older IDEA components use the `JDOMExternalizable` interface for persisting state.
It uses the `readExternal()` method for reading the state from a JDOM element, and `writeExternal()` to write the state to it.
Older IDEA components use the `JDOMExternalizable` interface for persisting state. It uses the `readExternal()` method for reading the state from a JDOM element, and `writeExternal()` to write the state to it.
`JDOMExternalizable` implementations can store the state in attributes and sub-elements manually, and/or use the `DefaultJDOMExternalizer` class to store the values of all public fields automatically.
When the component's class implements the `JDOMExternalizable` interface, the components save their state in the following files:
* Project-level components save their state to the project (.ipr) file. However, if the workspace option in the plugin.xml file is set to _true_, the component saves its configuration to the workspace (.iws) file instead.
* Module-level components save their state to the module (.iml) file.
* Project level components save their state to the project (`.ipr`) file. However, if the workspace option in the `plugin.xml` file is set to `true`, the component saves its configuration to the workspace (`.iws`) file instead.
* Module level components save their state to the module (`.iml`) file.

View File

@ -2,21 +2,13 @@
title: Plugin Structure
---
Click the following topics to learn more about the plugin system structure and plugin lifecycles:
* [Plugin Content](plugin_structure/plugin_content.md)
* [Plugin Class Loaders](plugin_structure/plugin_class_loaders.md)
* [Plugin Components](plugin_structure/plugin_components.md)
* [Plugin Extensions and Extension Points](plugin_structure/plugin_extensions_and_extension_points.md)
* [Plugin Actions](plugin_structure/plugin_actions.md)
* [Plugin Services](plugin_structure/plugin_services.md)
* [Plugin Configuration File](plugin_structure/plugin_configuration_file.md)
* [Plugin Dependencies](plugin_structure/plugin_dependencies.md)

View File

@ -2,12 +2,6 @@
title: Plugin Actions
---
*Intellij IDEA* provides the concept of _actions_.
An action is a class, derived from the
[AnAction](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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 system of actions allows plugins to add their own items to IDEA menus and toolbars.
Actions are organized into groups, which, in turn, can contain other groups.
A group of actions can form a toolbar or a menu. Subgroups of the group can form submenus of the menu.
You can find detailed information on how to create and register your actions in
[IntelliJ IDEA Action System](/basics/action_system.md).
*Intellij IDEA* provides the concept of _actions_. An action is a class, derived from the [`AnAction`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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 system of actions allows plugins to add their own items to IDEA menus and toolbars. Actions are organized into groups, which, in turn, can contain other groups. A group of actions can form a toolbar or a menu. Subgroups of the group can form submenus of a menu. You can find detailed information on how to create and register your actions in [IntelliJ IDEA Action System](/basics/action_system.md).

View File

@ -2,10 +2,6 @@
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.
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 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.

View File

@ -2,203 +2,128 @@
title: Plugin Components
---
Components are the fundamental concept of plugin integration.
There are three kinds of components:
<!-- TODO Table Of Contents -->
Components are the fundamental concept of plugin integration. There are three kinds of components:
* Application-level
* **Application level components** are created and initialized when *IntelliJ IDEA* starts up. They can be acquired from the [Application](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/application/Application.java) instance by using the `getComponent(Class)` method.
* **Project level components** are created for each [`Project`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/project/Project.java) instance in *IntelliJ IDEA*. (Please note that components may be created even for unopened projects.) They can be acquired from the `Project` instance by using the `getComponent(Class)` method.
* **Module level components** are created for each [Module](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/Module.java) in every project loaded in *IntelliJ IDEA*.
Module level components can be acquired from a `Module` instance with the `getComponent(Class)` method.
* Project-level
Every component should have interface and implementation classes specified in the configuration file. The interface class will be used for retrieving the component from other components, and the implementation class will be used for component instantiation.
* Module-level
Note that two components of the same level ([Application](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/application/Application.java), [Project](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/project/Project.java) or [Module](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/Module.java)) cannot have the same interface class. The same class may be specified for both interface and Implementation.
Each component has a unique name which is used for its externalization and other internal needs. The name of a component is returned by its `getComponentName()` method.
Application-level components are created and initialized when IntelliJ IDEA starts up.
They can be acquired from the
[Application](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/application/Application.java)
instance by using the `getComponent(Class)` method.
## Components naming notation
Project-level components are created for each
[Project](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/project/Project.java)
instance in IntelliJ IDEA. (Please note that components may be created even for unopened projects.)
They can be acquired from the Project instance by using the `getComponent(Class)` method.
It is recommended to name components in the form `<plugin_name>.<component_name>`.
Module-level components are created for each
[Module](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/Module.java)
in every project loaded in IntelliJ IDEA.
Module-level components can be acquired from a Module instance with the same method.
## Application level components
Every component should have interface and implementation classes specified in the configuration file.
The interface class will be used for retrieving the component from other components, and the implementation class will be used for component instantiation.
Note that two components of the same level (
[Application](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/application/Application.java),
[Project](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/project/Project.java)
or
[Module](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/Module.java)
) cannot have the same interface class.
Interface and implementation classes may be the same.
Optionally, an application level component's implementation class may implement the [ApplicationComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ApplicationComponent.java) interface.
Each component has a unique name which is used for its externalization and other internal needs.
The name of a component is returned by its `getComponentName()` method.
An application component that has no dependencies should have a constructor with no parameters which will be used for its instantiation. If an application component depends on other application components, it can specify these components as constructor parameters. *IntelliJ IDEA* will ensure that the components are instantiated in the correct order to satisfy the dependencies.
### Components Naming Notation
Note that application level components must be registered in the `<application-components>` section of the plugin.xml file (see [Plugin Configuration File](plugin_configuration_file.md)).
It is recommended to name components in `<plugin_name>.<component_name>` form.
### Application Level Components
Optionally, application-level component's implementation class may implement the
[ApplicationComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ApplicationComponent.java)
interface.
An application component that has no dependencies should have a constructor with no parameters which will be used for its instantiation.
If an application component depends on other application components, it can specify these components as constructor parameters. IntelliJ IDEA will ensure that the components are instantiated in the correct order to satisfy the dependencies.
Note that application-level components must be registered in the `<application-components>` section of the plugin.xml file (see [Plugin Configuration File](plugin_configuration_file.md)).
#### Quick creation of application components
### Quick creation of application components
*IntelliJ IDEA* suggests a simplified way to create application components, with all the required infrastructure.
The IntelliJ interface will help you declare the application component's implementation class, and will automatically make appropriate changes to the `<application-components>` section of the *plugin.xml* file.
The IntelliJ interface will help you declare the application component's implementation class, and will automatically make appropriate changes to the `<application-components>` section of the `plugin.xml` file.
**To create and register an application component:**
1. In your project, open the context menu of the destination package and click *New* (or press *ALT + INSERT*).
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, click *Application Component*.
3. In the *New Application Component* dialog box that opens, enter the application component name, and then click *OK*.
2. In the *New* menu, click *Application Component*.
*IntelliJ IDEA* will generate a new Java class that implements the [ApplicationComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ApplicationComponent.java) interface; register the newly created component in the `plugin.xml` file; add a node to the module tree view; and open the created application component class file in the editor.
3. In the *New Application Component* dialog box that opens, enter the application component name, and then click *OK*.
## Project level components
*IntelliJ IDEA* will generate a new Java class that implements the
[ApplicationComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ApplicationComponent.java)
interface; register the newly created component in the *plugin.xml* file; add a node to the module tree view; and open the created application component class file in the editor.
A project level component's implementation class may implement the [ProjectComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ProjectComponent.java) interface.
### Project Level Components
The constructor of a project level component can have a parameter of the [Project](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/project/Project.java) type, if it needs the project instance. It can also specify other application-level or project-level components as parameters, if it depends on those components.
Project-level component's implementation class may implement the
[ProjectComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ProjectComponent.java)
interface.
The constructor of a project-level component can have a parameter of the
[Project](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/project/Project.java)
type, if it needs the project instance.
It can also specify other application-level or project-level components as parameters, if it depends on those components.
Note that project level components must be registered in the `<project-components>` section of the `plugin.xml` file (see [Plugin Configuration File](plugin_configuration_file.md)).
Note that project-level components must be registered in the `<project-components>` section of the *plugin.xml* file (see [Plugin Configuration File](plugin_configuration_file.md)).
#### Quick creation of project components
### Quick creation of project components
<!--TODO Link to demo source code -->
*IntelliJ IDEA* suggests a simplified way to create project components, with all the required infrastructure.
The IDEA interface will help you declare the project component's implementation class, and will automatically make appropriate changes to the `<project-components>` section of the `plugin.xml` file.
**To create and register a project component**
1. In your project, open the context menu of the destination package and click *New* (or press *ALT + INSERT*).
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, click *Project Component*.
3. In the *New Project Component* dialog box that opens, enter the project component name, and then click *OK*.
2. In the *New* menu, click *Project Component*.
*IntelliJ IDEA* will generate a new Java class that implements the [ProjectComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ProjectComponent.java) interface; register the newly created component in the `plugin.xml` file; add a node to the module tree view; and open the created application component class file in the editor.
3. In the *New Project Component* dialog box that opens, enter the project component name, and then click *OK*.
## Module level components
*IntelliJ IDEA* will generate a new Java class that implements the
[ProjectComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ProjectComponent.java)
interface; register the newly created component in the *plugin.xml* file; add a node to the module tree view; and open the created application component class file in the editor.
Optionally, a module level component's implementation class may implement the [ModuleComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/ModuleComponent.java) interface.
The constructor of a module level component can have a parameter of the Module type, if it needs the module instance. It can also specify other application level, project level or module level components as parameters, if it depends on those components.
### Module Level Components
Note that module level components must be registered in the `<module-components>` section of the `plugin.xml` file (see [Plugin Configuration File](plugin_configuration_file.md)).
Optionally, Module-level component's implementation class may implement the
[ModuleComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/ModuleComponent.java)
interface.
The constructor of a module-level component can have a parameter of the Module type, if it needs the module instance.
It can also specify other application-level, project-level or module-level components as parameters, if it depends on those components.
Note that module-level components must be registered in the `<module-components>` section of the `plugin.xml` file (see [Plugin Configuration File](plugin_configuration_file.md)).
#### Quick creation of module components
### Quick creation of module components
*IntelliJ IDEA* suggests a simplified way to create module components, with all the required infrastructure.
The IDEA interface will help you declare the module component's implementation class, and will automatically make appropriate changes to the `<module-components>` section of the `plugin.xml` file.
*To create and register a module component*
* In your project, open the context menu of the destination package and click *New* (or press *ALT + INSERT*).
* In the *New* menu, click *Module Component*.
* In the *New Module Component* dialog box that opens, enter the module component name, and then click *OK*.
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, click *Module Component*.
3. In the *New Module Component* dialog box that opens, enter the module component name, and then click *OK*.
*IntelliJ IDEA* will generate a new Java class that implements the
[ModuleComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/ModuleComponent.java)
interface; register the newly created component in the `plugin.xml` file; add a node to the module tree view; and open the created application component class file in the editor.
*IntelliJ IDEA* will generate a new Java class that implements the [ModuleComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/ModuleComponent.java) interface; register the newly created component in the `plugin.xml` file; add a node to the module tree view; and open the created application component class file in the editor.
### Persisting State of Components
## Persisting the state of components
The state of every component will be automatically saved and loaded if the component's class implements the
[JDOMExternalizable](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java)
(deprecated) or
[PersistentStateComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/PersistentStateComponent.java)
interface.
The state of every component will be automatically saved and loaded if the component's class implements the [JDOMExternalizable](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) (deprecated) or [PersistentStateComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/PersistentStateComponent.java) interface.
When the component's class implements the
[PersistentStateComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/PersistentStateComponent.java)
interface, the component state is saved in an XML file that you can specify using the
[@State](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/components/State.java)
and
[@Storage](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/components/Storage.java)
annotations in your Java code.
When the component's class implements the [PersistentStateComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/PersistentStateComponent.java) interface, the component state is saved in an XML file that you can specify using the [@State](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/components/State.java) and [@Storage](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/components/Storage.java) annotations in your Java code.
When the component's class implements the
[JDOMExternalizable](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java)
interface, the components save their state in the following files:
When the component's class implements the [JDOMExternalizable](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) interface, the components save their state in the following files:
* Project-level components save their state to the project (.ipr) file.
However, if the workspace option in the plugin.xml file is set to _true_, the component saves its configuration to the workspace (.iws) file instead.
* Project level components save their state to the project (`.ipr`) file.
However, if the workspace option in the `plugin.xml` file is set to `true`, the component saves its configuration to the workspace (`.iws`) file instead.
* Module-level components save their state to the module (.iml) file.
* Module level components save their state to the module (`.iml`) file.
For more information and samples, refer to
[Persisting State of Components](/basics/persisting_state_of_components.md).
For more information and samples, refer to [Persisting State of Components](/basics/persisting_state_of_components.md).
### Defaults
## Defaults
The defaults (components' predefined settings) should be placed in the `<component_name>.xml` file.
Place this file in the plugin's classpath in the folder corresponding to the default package.
The `readExternal()` method will be called on the `<component>` root tag.
The defaults (a component's predefined settings) should be placed in the `<component_name>.xml` file. Place this file in the plugin's classpath in the folder corresponding to the default package. The `readExternal()` method will be called on the `<component>` root tag.
If a component has defaults, the `readExternal()` method is called twice:
* the first time for defaults
* The first time for defaults
* The second time for saved configuration
* the second time for saved configuration
### Plugin Components Lifecycle
## Plugin components lifecycle
The components are loaded in the following order:
* Creation - constructor is invoked.
* Initialization - the `initComponent` method is invoked (if the component implements the
[ApplicationComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ApplicationComponent.java)
interface).
* Configuration - the `readExternal` method is invoked (if the component implements
[JDOMExternalizable](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java)
interface), or the `loadState` method is invoked (if the component implements
[PersistentStateComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/PersistentStateComponent.java)
and has non-default persisted state).
* For module components, the `moduleAdded` method of the
[ModuleComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/ModuleComponent.java)
interface is invoked to notify that a module has been added to the project.
* For project components, the `projectOpened` method of the
[ProjectComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ProjectComponent.java)
interface is invoked to notify that a project has been loaded.
* Creation - constructor is invoked.
* Initialization - the `initComponent` method is invoked (if the component implements the [ApplicationComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ApplicationComponent.java) interface).
* Configuration - the `readExternal` method is invoked (if the component implements [JDOMExternalizable](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) interface), or the `loadState` method is invoked (if the component implements [PersistentStateComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/PersistentStateComponent.java) and has non-default persisted state).
* For module components, the `moduleAdded` method of the [ModuleComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/ModuleComponent.java) interface is invoked to notify that a module has been added to the project.
* For project components, the `projectOpened` method of the [ProjectComponent](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ProjectComponent.java) interface is invoked to notify that a project has been loaded.
The components are unloaded in the following order:
* Saving configuration - the `writeExternal` method is invoked (if the component implements the
[JDOMExternalizable](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java)
interface), or the `getState` method is invoked (if the component implements PersistentStateComponent).
* Saving configuration - the `writeExternal` method is invoked (if the component implements the [JDOMExternalizable](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) interface), or the `getState` method is invoked (if the component implements PersistentStateComponent).
* Disposal - the `disposeComponent` method is invoked.
Note that you should not request any other components using the `getComponent()` method in the constructor of your component, otherwise you'll get an assertion.
If you need access to other components when initializing your component, you can specify them as constructor parameters or access them in the `initComponent` method.
Note that you should not request any other components using the `getComponent()` method in the constructor of your component, otherwise you'll get an assertion. If you need access to other components when initializing your component, you can specify them as constructor parameters or access them in the `initComponent` method.

View File

@ -1,100 +1,125 @@
---
title: Plugin Configuration File plugin.xml
title: Plugin Configuration File - plugin.xml
---
The following is a sample plugin configuration file.
This sample showcases and describes all elements that can be used in the plugin.xml file.
The following is a sample plugin configuration file. This sample showcases and describes all elements that can be used in the plugin.xml file.
```xml
<!-- url="" specifies the URL of the plugin homepage (displayed in the Welcome Screen and in "Plugins" settings dialog) -->
<idea-plugin url="http://www.jetbrains.com/idea">
<!-- Plugin name -->
<name>VssIntegration</name>
<!-- Plugin name -->
<name>VssIntegration</name>
<!-- Unique identifier of the plugin. Cannot be changed between the plugin versions. If not specified, assumed to be equal to <name>. -->
<id>VssIntegration</id>
<!-- Unique identifier of the plugin.
Cannot be changed between the plugin versions.
If not specified, assumed to be equal to <name>. -->
<id>VssIntegration</id>
<!-- Description of the plugin. -->
<description>Vss integration plugin</description>
<!-- Description of the plugin. -->
<description>Vss integration plugin</description>
<!-- Description of changes in the latest version of the plugin. Displayed in the "Plugins" settings dialog and in the plugin repository Web interface. -->
<change-notes>Initial release of the plugin.</change-notes>
<!-- Description of changes in the latest version of the plugin.
Displayed in the "Plugins" settings dialog and in the
plugin repository Web interface. -->
<change-notes>Initial release of the plugin.</change-notes>
<!-- Plugin version -->
<version>1.0</version>
<!-- Plugin version -->
<version>1.0</version>
<!-- The vendor of the plugin. The optional "url" attribute specifies the URL of the vendor homepage. The optional "email"
attribute specifies the e-mail address of the vendor. The optional "logo" attribute specifies the path within the plugin JAR
to a 16x16 icon to be displayed next to the plugin name in the welcome screen. -->
<vendor url="http://www.jetbrains.com" email="support@jetbrains.com" logo="icons/plugin.png">Foo Inc.</vendor>
<!-- The vendor of the plugin.
The optional "url" attribute specifies the URL of the vendor homepage.
The optional "email" attribute specifies the e-mail address of the vendor.
The optional "logo" attribute specifies the path within the plugin JAR
to a 16x16 icon to be displayed next to the plugin name in the welcome screen. -->
<vendor url="http://www.jetbrains.com" email="support@jetbrains.com" logo="icons/plugin.png">Foo Inc.</vendor>
<!-- The unique identifiers of the plugins on which this plugin depends. -->
<depends>MyFirstPlugin</depends>
<!-- Optional dependency on another plugin. If the plugin with the "MySecondPlugin" ID is installed, the contents of mysecondplugin.xml (the format of this file conforms to the format of plugin.xml) will be loaded. -->
<depends optional="true" config-file="mysecondplugin.xml">MySecondPlugin</depends>
<!-- The unique identifiers of the plugins on which this plugin depends. -->
<depends>MyFirstPlugin</depends>
<!-- Allows a plugin to integrate its help system (in JavaHelp format) with the IDEA help system. The "file" attribute specifies the name of the JAR file
in the "help" subdirectory of the plugin directory. The "path" attribute specifies the name of the helpset file within the JAR file.-->
<helpset file="myhelp.jar" path="/Help.hs" />
<!-- Optional dependency on another plugin.
If the plugin with the "MySecondPlugin" ID is installed,
the contents of mysecondplugin.xml (the format of this file
conforms to the format of plugin.xml) will be loaded. -->
<depends optional="true" config-file="mysecondplugin.xml">MySecondPlugin</depends>
<!-- Minimum and maximum build of IDEA compatible with the plugin -->
<idea-version since-build="3000" until-build="3999"/>
<!-- Allows a plugin to integrate its help system (in JavaHelp format)
with the IDEA help system. The "file" attribute specifies the name
of the JAR file in the "help" subdirectory of the plugin directory.
The "path" attribute specifies the name of the helpset file within
the JAR file.-->
<helpset file="myhelp.jar" path="/Help.hs" />
<!-- Resource bundle from which the text of plugin descriptions, action names and etc. will be loaded -->
<resource-bundle>messages.MyPluginBundle</resource-bundle>
<!-- Minimum and maximum build of IDEA compatible with the plugin -->
<idea-version since-build="3000" until-build="3999"/>
<!-- Plugin's application components -->
<application-components>
<component>
<!-- Component's interface class -->
<interface-class>com.foo.Component1Interface</interface-class>
<!-- Component's implementation class -->
<implementation-class>com.foo.impl.Component1Impl</implementation-class>
</component>
</application-components>
<!-- Resource bundle from which the text of plugin descriptions,
action names and etc. will be loaded -->
<resource-bundle>messages.MyPluginBundle</resource-bundle>
<!-- Plugin's project components -->
<project-components>
<component>
<!-- Interface and implementation classes are the same -->
<interface-class>com.foo.Component2</interface-class>
<!-- If the "workspace" option is set "true", the component saves its state to the .iws file
instead of the .ipr file. Note that the <option> element is used only if the component implements the JDOMExternalizable interface. Otherwise, the use of the <option> element takes no effect.
-->
<!-- Plugin's application components -->
<application-components>
<component>
<!-- Component's interface class -->
<interface-class>com.foo.Component1Interface</interface-class>
<option name="workspace" value="true" />
<!-- If the "loadForDefaultProject" tag is present, the project component is instantiated also for the default project. -->
<loadForDefaultProject>
</component>
</project-components>
<!-- Component's implementation class -->
<implementation-class>com.foo.impl.Component1Impl</implementation-class>
</component>
</application-components>
<!-- Plugin's module components -->
<module-components>
<component>
<interface-class>com.foo.Component3</interface-class>
</component>
</module-components>
<!-- Plugin's project components -->
<project-components>
<component>
<!-- Interface and implementation classes are the same -->
<interface-class>com.foo.Component2</interface-class>
<!-- Actions -->
<actions>
<action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage" description="Run garbage collector">
<keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>
</action>
</actions>
<!-- If the "workspace" option is set "true", the component
saves its state to the .iws file instead of the .ipr file.
Note that the <option> element is used only if the component
implements the JDOMExternalizable interface. Otherwise, the
use of the <option> element takes no effect. -->
<option name="workspace" value="true" />
<!-- Extension points defined by the plugin. Extension points are registered by a plugin so that other plugins can provide this plugin
with certain data. The "beanClass" attribute specifies the class the implementations of which can be used for the extension point. -->
<extensionPoints>
<extensionPoint name="testExtensionPoint" beanClass="com.foo.impl.MyExtensionBean"/>
</extensionPoints>
<!-- If the "loadForDefaultProject" tag is present, the project component is instantiated also for the default project. -->
<loadForDefaultProject>
</component>
</project-components>
<!-- Extensions which the plugin adds to extension points defined by the IDEA core or by other plugins. The "defaultExtensionNs " attribute must be set to the ID of the plugin defining the extension point,
or to "com.intellij" if the extension point is defined by the IDEA core. The name of the
tag within the <extensions> tag matches the name of the extension point, and the "implementation" class specifies the name of the
class added to the extension point. -->
<extensions xmlns="VssIntegration">
<testExtensionPoint implementation="com.foo.impl.MyExtensionImpl"/>
</extensions>
<!-- Plugin's module components -->
<module-components>
<component>
<interface-class>com.foo.Component3</interface-class>
</component>
</module-components>
<!-- Actions -->
<actions>
<action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage" description="Run garbage collector">
<keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>
</action>
</actions>
<!-- Extension points defined by the plugin.
Extension points are registered by a plugin so that other
plugins can provide this plugin with certain data. The
"beanClass" attribute specifies the class the implementations
of which can be used for the extension point. -->
<extensionPoints>
<extensionPoint name="testExtensionPoint" beanClass="com.foo.impl.MyExtensionBean"/>
</extensionPoints>
<!-- Extensions which the plugin adds to extension points
defined by the IDEA core or by other plugins.
The "defaultExtensionNs " attribute must be set to the
ID of the plugin defining the extension point, or to
"com.intellij" if the extension point is defined by the
IDEA core. The name of the tag within the <extensions>
tag matches the name of the extension point, and the
"implementation" class specifies the name of the class
added to the extension point. -->
<extensions xmlns="VssIntegration">
<testExtensionPoint implementation="com.foo.impl.MyExtensionImpl"/>
</extensions>
</idea-plugin>
```

View File

@ -2,40 +2,39 @@
title: Plugin Content
---
*There are two possible ways of organizing plugin content:*
There are two possible ways of organizing plugin content:
1. A plugin consisting of one .jar file placed in the plugins directory:
1. A plugin consisting of one `.jar` file placed in the plugins directory:
The archive should contain the configuration file (META-INF/plugin.xml) and classes that implement the plugin functionality.
The configuration file specifies the plugin name, description, version, vendor, the supported IntelliJ IDEA version, plugin components, actions and action groups, and action user interface placement.
The archive should contain the configuration file (`META-INF/plugin.xml`) and classes that implement the plugin functionality. The configuration file specifies the plugin name, description, version, vendor, the supported IntelliJ IDEA version, plugin components, actions and action groups, and action user interface placement.
```
.IntelliJIDEAx0
plugins
sample.jar/
com/foo/.....
...
...
META-INF
plugin.xml
plugins
sample.jar/
com/foo/...
...
...
META-INF
plugin.xml
```
2. Plugin files located in a jar-file that is placed in the lib folder:
2. Plugin files located in a `.jar` file that is placed in the lib folder:
```
.IntelliJIDEAx0
plugins
Sample
lib
libfoo.jar
libbar.jar
Sample.jar/
com/foo/.....
...
plugins
Sample
lib
libfoo.jar
libbar.jar
Sample.jar/
com/foo/...
...
...
META-INF
plugin.xml
```
All jars from the 'lib' folder are automatically added to the classpath.
All jars from the `lib` folder are automatically added to the classpath.

View File

@ -2,14 +2,13 @@
title: Plugin Dependencies
---
In your plugin, you may depend on classes from other plugins, either bundled, third-party or your own.
In order to do so, you need to perform the following two steps:
In your plugin, you may depend on classes from other plugins, either bundled, third-party or your own. In order to do so, you need to perform the following two steps:
* Add the jars of the plugin you're depending on to the classpath of your *IntelliJ Platform SDK*.
* Add the jars of the plugin you're depending on to the classpath of your *IntelliJ Platform SDK*.
> **warning** Do not add the plugin jars as a library: this will fail at runtime because IntelliJ Platform will load two separate copies of the dependency plugin classes.
* Add a `<depends>` tag to your plugin.xml, adding the ID of the plugin you're depending on as the contents of the tag.
* Add a `<depends>` tag to your plugin.xml, adding the ID of the plugin you're depending on as the contents of the tag.
For example:
```xml

View File

@ -2,40 +2,38 @@
title: Plugin Extensions and Extension Points
---
The IntelliJ Platform provides the concept of _extensions_ and _extension points_ that allows a plugin to interact with other plugins or with the IDE itself.
The *IntelliJ Platform* provides the concept of _extensions_ and _extension points_ that allows a plugin to interact with other plugins or with the IDE itself.
## Extension Points
## Extension points
If you want your plugin to allow other plugins to extend its functionality, in the plugin, you must declare one or several _extension points_.
Each extension point defines a class or an interface that is allowed to access this point.
If you want your plugin to allow other plugins to extend its functionality, in the plugin, you must declare one or several _extension points_. Each extension point defines a class or an interface that is allowed to access this point.
## Extensions
If you want your plugin to extend the functionality of other plugins or the IntelliJ Platform, you must declare one or several _extensions_.
If you want your plugin to extend the functionality of other plugins or the *IntelliJ Platform*, you must declare one or several _extensions_.
## How to Declare Extensions and Extension Points?
## How to declare extensions and extension points
You can declare extensions and extension points in the plugin configuration file `plugin.xml`, within the `<extensions>` and `<extensionPoints>` sections, respectively.
*To declare an extension point*
**To declare an extension point**
* In the `<extensionPoints>` section, insert a child element `<extensionPoint>` that defines the extension point name and the name of a bean class or an interface that is allowed to extend the plugin functionality in the *'name'*, *'beanClass'* and *'interface'* attributes, respectively.
In the `<extensionPoints>` section, insert a child element `<extensionPoint>` that defines the extension point name and the name of a bean class or an interface that is allowed to extend the plugin functionality in the `name`, `beanClass` and `interface` attributes, respectively.
To clarify this procedure, consider the following sample section of the plugin.xml file:
```xml
<extensionPoints>
<extensionPoint name="MyExtensionPoint1" beanClass="MyPlugin.MyBeanClass1">
<extensionPoint name="MyExtensionPoint2" interface="MyPlugin.MyInterface">
<extensionPoint name="MyExtensionPoint1" beanClass="MyPlugin.MyBeanClass1">
<extensionPoint name="MyExtensionPoint2" interface="MyPlugin.MyInterface">
</extensionPoints>
```
The *interface* attribute sets an interface the plugin that contributes to the extension point must implement.
* The `interface` attribute sets an interface the plugin that contributes to the extension point must implement.
* The `beanClass` attribute sets a bean class that specifies one or several properties annotated with the [@Attribute](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/xml/dom-openapi/src/com/intellij/util/xml/Attribute.java) annotation.
The *beanClass* attribute sets a bean class that specifies one or several properties annotated with the
[@Attribute](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/xml/dom-openapi/src/com/intellij/util/xml/Attribute.java)
annotation.
The plugin that contributes to the extension point will read those properties from the `plugin.xml` file.
To clarify this, consider the following sample `MyBeanClass1` bean class used in the above `plugin.xml` file:
```java
@ -52,63 +50,49 @@ public class MyBeanClass1 extends AbstractExtensionPointBean {
public String getClass() {
return implementationClass;
{
}
}
```
Note that to declare an extension designed to access the `MyExtensionPoint1` extension point, your `plugin.xml` file must contain the `<MyExtensionPoint1>` tag with the "key" and "implementationClass" attributes set to appropriate values (see sample below).
*To declare an extension*
Note that to declare an extension designed to access the `MyExtensionPoint1` extension point, your `plugin.xml` file must contain the `<MyExtensionPoint1>` tag with the `key` and `implementationClass` attributes set to appropriate values (see sample below).
1. For the `<extensions>` element, set the *xmlns* (deprecated) or *defaultExtensionNs* attribute to one of the following values:
* _com.intellij_, if your plugin extends the IntelliJ Platform core functionality.
* _ID of a plugin_, if your plugin extends a functionality of another plugin.
2. Add a new child element to the `<extensions>` element.
The child element name must match the name of the extension point you want the extension to access.
**To declare an extension**
1. For the `<extensions>` element, set the `xmlns` (deprecated) or `defaultExtensionNs` attribute to one of the following values:
* `com.intellij`, if your plugin extends the IntelliJ Platform core functionality.
* `{ID of a plugin}`, if your plugin extends a functionality of another plugin.
2. Add a new child element to the `<extensions>` element. The child element name must match the name of the extension point you want the extension to access.
3. Depending on the type of the extension point, do one of the following:
* If the extension point was declared using the `interface` attribute, for newly added child element, set the `implementation` attribute to the name of the class that implements the specified interface.
* If the extension point was declared using the `beanClass` attribute, for newly added child element, set all attributes annotated with the [@Attribute](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/xml/dom-openapi/src/com/intellij/util/xml/Attribute.java) annotations in the specified bean class.
* If the extension point was declared using the *interface* attribute, for newly added child element, set the *implementation* attribute to the name of the class that implements the specified interface.
* If the extension point was declared using the *beanClass* attribute, for newly added child element, set all attributes annotated with the
[@Attribute](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/xml/dom-openapi/src/com/intellij/util/xml/Attribute.java)
annotations in the specified bean class.
To clarify this procedure, consider the following sample section of the plugin.xml file that defines two extensions designed to access the _appStarter_ and _applicationConfigurable_ extension points in the IntelliJ Platform and one extension to access the _MyExtensionPoint1_ extension point in a test plugin:
To clarify this procedure, consider the following sample section of the `plugin.xml` file that defines two extensions designed to access the `appStarter` and `applicationConfigurable` extension points in the *IntelliJ Platform* and one extension to access the `MyExtensionPoint1` extension point in a test plugin:
```xml
<!-- Declare extensions to access extension points in the IntelliJ Platform. These extension points
have been declared using the "interface" attribute.
<!-- Declare extensions to access extension points in the IntelliJ Platform.
These extension points have been declared using the "interface" attribute.
-->
<extensions defaultExtensionNs="com.intellij">
<appStarter implementation="MyTestPackage.MyTestExtension1"></appStarter>
<applicationConfigurable implementation="MyTestPackage.MyTestExtension2"></applicationConfigurable>
<appStarter implementation="MyTestPackage.MyTestExtension1" />
<applicationConfigurable implementation="MyTestPackage.MyTestExtension2" />
</extensions>
<!-- Declare extensions to access extension points in a custom plugin
The MyExtensionPoint1 extension point has been declared using *beanClass* attribute.
-->
<!-- Declare extensions to access extension points in a custom plugin
The MyExtensionPoint1 extension point has been declared using *beanClass* attribute.
-->
<extensions defaultExtensionNs="MyPluginID">
<MyExtensionPoint1 key="keyValue" implementationClass="MyTestPackage.MyClassImpl"></MyExtensionPoint1>
</extensions>
```
## How to Get the Extension Points List?
## How to get the extension points list?
To get a list of extension points available in the *IntelliJ Platform* core, consult the `<extensionPoints>` section of the following XML configuration files:
* [LangExtensionPoints.xml](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-resources/src/META-INF/LangExtensionPoints.xml)
* [PlatformExtensionPoints.xml](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml)
* [VcsExtensionPoints.xml](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml)
* [`LangExtensionPoints.xml`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-resources/src/META-INF/LangExtensionPoints.xml)
* [`PlatformExtensionPoints.xml`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml)
* [`VcsExtensionPoints.xml`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml)
## Additional Information and Samples
For samples plugins and detailed instructions on how to create your plugin that contributes to the IDEA core, refer to
Customizing the IDEA Settings Dialog
and
Creation of Tool Windows.
For samples plugins and detailed instructions on how to create your plugin that contributes to the IDEA core, refer to Customizing the IDEA Settings Dialog and Creation of Tool Windows.

View File

@ -2,52 +2,44 @@
title: Plugin Services
---
*IntelliJ Platform* provides the concept of _services_.
A _service_ is a plugin component loaded on demand, when your plugin calls the `getService` method of the
[ServiceManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/components/ServiceManager.java)
class.
*IntelliJ Platform* ensures that only one instance of a service is loaded even though the service is called several times.
A service must have the interface and implementation classes specified in the plugin.xml file.
The service implementation class is used for service instantiation.
*IntelliJ Platform* offers three types of services: _application level_ services, _project level_ services and _module level_ services.
The *IntelliJ Platform* provides the concept of _services_.
A _service_ is a plugin component loaded on demand, when your plugin calls the `getService` method of the [ServiceManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/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 the interface and implementation classes specified in the `plugin.xml` file. The service implementation class is used for service instantiation.
The *IntelliJ Platform* offers three types of services: _application level_ services, _project level_ services and _module level_ services.
## How to Declare a Service?
To declare a service, you can use the following extension points in the IDEA core:
* *applicationService*: designed to declare an application level service.
* `applicationService`: designed to declare an application level service.
* `projectService`: designed to declare a project level service.
* `moduleService`: designed to declare a module level service.
* *projectService*: designed to declare a project level service.
* *moduleService*: designed to declare a module level service.
*To declare a service:*
**To declare a service:**
1. Add the appropriate child element (`<applicationService>`, `<projectService>` or `<moduleService>`) to the `<extensions>` section of the plugin.xml file.
2. For the newly added child element, set the following attributes:
* *serviceInterface*: specifies the service interface class.
* *serviceImplementation*: specifies the service implementation class.
2. For the newly added child element, set the following attributes:
* `serviceInterface`: specifies the service interface class.
* `serviceImplementation`: specifies the service implementation class.
Note that the interface and implementation classes can be the same.
To clarify the service declaration procedure, consider the following fragment of the plugin.xml file:
To clarify the service declaration procedure, consider the following fragment of the `plugin.xml` file:
```xml
<extensions defaultExtensionNs="com.intellij">
<!-- Declare the application level service -->
<applicationService serviceInterface="Mypackage.MyServiceInterfaceClass" serviceImplementation="Mypackage.MyServiceImplClass">
</applicationService>
<!-- Declare the application level service -->
<applicationService serviceInterface="Mypackage.MyServiceInterfaceClass" serviceImplementation="Mypackage.MyServiceImplClass" />
<!-- Declare the project level service -->
<projectService serviceInterface="Mypackage.MyProjectServiceInterfaceClass" serviceImplementation="Mypackage.MyProjectServiceImplClass">
</projectService>
</extensions>
<!-- Declare the project level service -->
<projectService serviceInterface="Mypackage.MyProjectServiceInterfaceClass" serviceImplementation="Mypackage.MyProjectServiceImplClass" />
</extensions>
```
### How It Works?
## Retrieving a service
To instantiate your service, in Java code, use the following syntax:
@ -55,24 +47,16 @@ To instantiate your service, in Java code, use the following syntax:
MyServiceImplClass service = ServiceManager.getService(MyServiceImplClass.class);
```
### Sample Plugin
This section allows you to download and install a sample plugin illustrating how to create and use a plugin service.
This plugin has a project component implementing a service that counts a number of currently opened projects in *IntelliJ IDEA*.
If this number exceeds the maximum allowed number of simultaneously opened projects, the plugin returns an error
message and closes the most recently opened project.
This section allows you to download and install a sample plugin illustrating how to create and use a plugin service. This plugin has a project component implementing a service that counts the number of currently opened projects in *IntelliJ IDEA*. If this number exceeds the maximum allowed number of simultaneously opened projects, the plugin returns an error message and closes the most recently opened project.
<!-- TODO Replace with other plugin URL when available-->
*To install and run the sample plugin*
**To install and run the sample plugin**
* Click [here](/attachments/MaxOpenedProjects.zip) to download the .Zip archive that contains the sample plugin project.
* Extract all files from the .Zip archive to a separate folder.
* Start *IntelliJ IDEA*, on the starting page, click *Open Project*, and then use the *Open Project* dialog box to open the downloaded project *MaxOpenedProjects*.
* On the main menu, choose *Run \| Run* or press *Shift + F10*.
* If necessary, change the [Run/Debug Configurations](http://www.jetbrains.com/idea/help/run-debug-configuration-plugin.html).
* Click [here](/attachments/MaxOpenedProjects.zip) to download the .Zip archive that contains the sample plugin project.
* Extract all files from the .Zip archive to a separate folder.
* Start *IntelliJ IDEA*, on the starting page, click *Open Project*, and then use the *Open Project* dialog box to open the downloaded project *MaxOpenedProjects*.
* On the main menu, choose *Run \| Run* or press <kbd>Shift</kbd>+<kbd>F10</kbd>.
* If necessary, change the [Run/Debug Configurations](http://www.jetbrains.com/idea/help/run-debug-configuration-plugin.html).

View File

@ -2,66 +2,47 @@
title: Project Structure
---
<!--TODO split into parts accordingly to the table of contents-->
This topic considers the concept of projects based on **IntelliJ Platform** and related subjects, such as _modules_, _facets_, _libraries_, _SDK_.
The project structure and Java classes you can use to manage projects and modules have been considered.
## Project and Its Components
This topic considers the concept of projects based on *IntelliJ Platform* and related subjects, such as _modules_, _facets_, _libraries_, _SDK_. The project structure and Java classes you can use to manage projects and modules have been considered.
This section briefly discusses the IDEA project structure, project components and related terms.
For more information about projects and their components, refer to
[Project](http://www.jetbrains.com/idea/help/project.html),
[Module](http://www.jetbrains.com/idea/help/module.html),
[Library](http://www.jetbrains.com/idea/help/library.html),
[Facet](http://www.jetbrains.com/idea/help/facet.html)
in **IntelliJ IDEA** Web Help.
## Project and its components
#### Project
This section briefly discusses the IDEA project structure, project components and related terms. For more information about projects and their components, refer to [Project](http://www.jetbrains.com/idea/help/project.html), [Module](http://www.jetbrains.com/idea/help/module.html), [Library](http://www.jetbrains.com/idea/help/library.html), [Facet](http://www.jetbrains.com/idea/help/facet.html) in *IntelliJ IDEA* Web Help.
In **IntelliJ Platform**, a _project_ encapsulates all your source code, libraries, build instructions into a single organizational unit.
Everything you do using **IntelliJ Platform SDK**, is done within the context of a project. A project defines some collections referred to as _modules_ and _libraries_.
Depending on the logical and functional requirements to the project, you can create a _single-module_ or a _multi-module_ project.
### Project
#### Module
In the *IntelliJ Platform*, a _project_ encapsulates all your source code, libraries, and build instructions into a single organizational unit. Everything you do using the *IntelliJ Platform SDK* is done within the context of a project. A project defines collections referred to as _modules_ and _libraries_. Depending on the logical and functional requirements to the project, you can create a _single-module_ or a _multi-module_ project.
### Module
A _module_ is a discrete unit of functionality that can be run, tested, and debugged independently. Modules includes such things as source code, build scripts, unit tests, deployment descriptors, etc. In the project, each module can use a specific SDK or inherit SDK defined on the project level (see the [SDK](/reference_guide/project_model/sdk.html) section later in this document). A module can depend on other modules of the project.
#### Library
### Library
A _library_ is an archive of compiled code (such as JAR files) that your modules depend on. **IntelliJ Platform** supports three types of libraries:
A _library_ is an archive of compiled code (such as JAR files) that your modules depend on. The *IntelliJ Platform* supports three types of libraries:
* **Module Library**: the library classes are visible only in this module and the library information is recorded in the module \*.iml file.
* **Module Library**: the library classes are visible only in this module and the library information is recorded in the module `.iml` file.
* **Project Library**: the library classes are visible within the project and the library information is recorded in the project `.ipr` file or in `.idea/libraries`.
* **Global Library**: the library information is recorded in the `applicationLibraries.xml` file into the `~/.IntelliJIdea/config/options` directory. Global libraries are similar to project libraries, but are visible for the different projects.
* **Project Library**: the library classes are visible within the project and the library information is recorded in the project \*.ipr file or in _.idea/libraries_.
For more information about libraries, refer to [Library](http://www.jetbrains.com/idea/help/library.html).
* **Global Library**: the library information is recorded in the _applicationLibraries.xml_ file into the `<User Home>/.IntelliJIdea/config/options` directory. Global libraries are similar to project libraries, but are visible for the different projects.
### SDK
For more information about libraries, refer to
[Library](http://www.jetbrains.com/idea/help/library.html).
Every project uses a Software Development Kit (_SDK_). For Java projects, SDK is referred to as JDK (Java Development Kit).
#### SDK
The SDK determines which API library is used to build the project. If your project is multi-module, the project SDK by default is common for all modules within the project.
Every project uses a Software Development Kit (_SDK_).
For Java projects, SDK is referred to as JDK (Java Development Kit).
SDK determines which API library is used to build the project.
If your project is multi-module, the project SDK by default is common for all modules within the project.
Optionally, you can configure individual SDK for each module.
For more information about SDKs, see
[Configuring Global, Project and Module SDKs](https://www.jetbrains.com/idea/help/configuring-global-project-and-module-sdks.html)
in **IntelliJ IDEA** Web Help.
For more information about SDKs, see [Configuring Global, Project and Module SDKs](https://www.jetbrains.com/idea/help/configuring-global-project-and-module-sdks.html) in *IntelliJ IDEA* Web Help.
#### Facet
### Facet
A _facet_ represents certain configuration, specific for a particular framework/technology, associated with a module.
A module can have multiple facets.
E.g. Spring specific configuration is stored in a Spring facet.
For more information about facets see
[Facet](http://www.jetbrains.com/idea/help/facet.html)
and
[Facet Dependencies](http://www.jetbrains.com/idea/help/available-facets-and-their-dependencies.html)
in **IntelliJ IDEA** Web Help.
A _facet_ represents certain configuration, specific for a particular framework/technology, associated with a module. A module can have multiple facets. E.g. Spring specific configuration is stored in a Spring facet.
For more information about facets see [Facet](http://www.jetbrains.com/idea/help/facet.html) and [Facet Dependencies](http://www.jetbrains.com/idea/help/available-facets-and-their-dependencies.html) in *IntelliJ IDEA* Web Help.
## Project Structure
@ -69,78 +50,65 @@ From the plugin developer's point of view, a project can be thought of as follow
![Project Structure](project_structure/img/IntelliJIDEA_ProjectStructure.png)
A **project** consists of one or several **modules**.
Each **module** includes the plugin source code and so called **order entries** that refer to **SDK** and **libraries** the module uses.
By default, all modules uses the project SDK. In adition, a **module** can optionally have a set of **facets**.
This document explains how you can explore and change the structure of projects using API.
A **project** consists of one or several **modules**. Each **module** includes the plugin source code and so called **order entries** that refer to **SDK** and **libraries** the module uses. By default, all modules uses the project SDK. In addition, a **module** can optionally have a set of **facets**.
This document explains how you can explore and change the structure of projects using API.
## Working with Projects
This section explains how to complete some common tasks related to management of projects.
The Java classes and interfaces that you can use to explore and change the project contents are discussed.
#### How to Work with Project Files?
### How to Work with Project Files?
**IntelliJ Platform** stores the project configuration data in XML files. The list of those files depends on the plugin
[project format](http://www.jetbrains.com/idea/help/project.html).
The *IntelliJ Platform* stores the project configuration data in XML files. The list of those files depends on the plugin [project format](http://www.jetbrains.com/idea/help/project.html).
For _file-based_ format projects, the information core to the project itself (e.g. location of the component modules, compiler settings, etc.) is stored in the _<%project name%>.IPR_ file.
The information about modules the project includes is stored in _<%module name%>.IML_ files.
Module files are created for each module.
For _file-based_ format projects, the information core to the project itself (e.g. location of the component modules, compiler settings, etc.) is stored in the `%project_name%.ipr` file.
For _directory-based_ format projects, the project and workspace settings are stored in a number of XML files under the _<%Project home directory%>/.idea_ directory.
Each XML file is responsible for its own set of settings and can be recognized by its name: _projectCodeStyle.xml_, _encodings.xml_, _vcs.xml_ etc.
As for the file-based format projects, .IML files describe modules.
The information about modules the project includes is stored in `%module_name%.iml` files. Module files are created for each module.
For _directory-based_ format projects, the project and workspace settings are stored in a number of XML files under the `%project_home_directory%/.idea` directory. Each XML file is responsible for its own set of settings and can be recognized by its name: `projectCodeStyle.xml`, `encodings.xml`, `vcs.xml` etc.
As for the file-based format projects, `.iml` files describe modules.
To work with projects and project files, you can use the following classes and interfaces:
* [Project](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/project/Project.java) interface.
* [ProjectRootManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java) abstract class.
* [ProjectManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/project/ProjectManager.java) abstract class.
* [ProjectFileIndex](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) interface.
* [`Project`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/project/Project.java) interface.
* [`ProjectRootManager`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java) abstract class.
* [`ProjectManager`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/project/ProjectManager.java) abstract class.
* [`ProjectFileIndex`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) interface.
Note that you don't need to access project files directly to load or save settings.
See
[Persisting State of Components](persisting_state_of_components.md)
for more information.
Note that you don't need to access project files directly to load or save settings. See [Persisting State of Components](persisting_state_of_components.md) for more information.
Note that hereafter, the `project` variable is of the `Project` type.
For example, for the opened project, you can get it from an action: `Project project = e.getProject();`
Note that hereafter, the `project` variable is of the `Project` type. For example, for the opened project, you can get it from an action: `Project project = e.getProject();`
#### How do I get a list of source roots for all modules in my project?
Use the `ProjectRootManager.getContentSourceRoots()` method.
To clarify this, consider the following code snippet:
### How do I get a list of source roots for all modules in my project?
Use the `ProjectRootManager.getContentSourceRoots()` method. To clarify this, consider the following code snippet:
```java
String projectName = project.getName();
StringBuilder sourceRootsList = new StringBuilder();
VirtualFile[] vFiles = ProjectRootManager.getInstance(project).getContentSourceRoots();
for (VirtualFile file : vFiles) {
sourceRootsList.append(file.getUrl()).append("\n");
sourceRootsList.append(file.getUrl()).append("\n");
}
Messages.showInfoMessage("Source roots for the " + projectName + " plugin:\n" + sourceRootsList, "Project Properties");
```
### How do I check whether a file is related to a project?
#### How do I check whether a file is related to a project?
The *IntelliJ Platform* provides the `ProjectFileIndex` interface you can use to verify whether a file or directory is related to the specified IDEA project. This section explains how you can use this interface.
**IntelliJ Platform** provides the `ProjectFileIndex` interface you can use to verify whether a file or directory is related to the specified IDEA project.
This section explains how you can use this interface.
##### How do I get an instance of the ProjectFileIndex interface?
#### How do I get an instance of the ProjectFileIndex interface?
Use the `ProjectRootManager.getFileIndex()` method. For example:
`ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();`
##### How do I get a module to which a file belongs?
#### How do I get a module to which a file belongs?
To determine a module in the project in question to which the specified
[virtual file](architectural_overview/virtual_file.md)
belongs, use the `ProjectFileIndex.getModuleForFile(virtualFile)` method:
To determine a module in the project in question to which the specified [virtual file](architectural_overview/virtual_file.md) belongs, use the `ProjectFileIndex.getModuleForFile(virtualFile)` method:
```java
Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);
@ -154,7 +122,7 @@ You can also use the `ProjectFileIndex.getContentRootForFile` method to get the
VirtualFile moduleContentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFileorDirectory);
```
##### How do I get the module source root or library source root to which the specified file or directory belongs?
#### How do I get the module source root or library source root to which the specified file or directory belongs?
Use the `ProjectFileIndex.getSourceRootForFile` method. For example:
@ -164,64 +132,51 @@ VirtualFile moduleSourceRoot = ProjectRootManager.getInstance(project).getFileIn
Note that this method returns `null` if the file or directory does not belong to any source root of modules in the project.
##### How do I check whether a file or directory is related to the project libraries?
#### 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.
##### How do I get the project SDK?
* To get the project-level SDK: `Sdk projectSDK = ProjectRootManager.getInstance(project).getProjectSdk();`
#### How do I get the project SDK?
* To get the project-level SDK: `Sdk projectSDK = ProjectRootManager.getInstance(project).getProjectSdk();`
* To get the project-level SDK name: `String projectSDKName = ProjectRootManager.getInstance(project).getProjectSdkName();`
##### How do I set the project SDK?
#### How do I set the project SDK?
##### To set the project-level SDK:
`ProjectRootManager.getInstance(project).setProjectSdk(Sdk jdk);`
##### To set the project-level SDK name:
`ProjectRootManager.getInstance(project).setProjectSdkName(String name);`
* To set the project-level SDK: `ProjectRootManager.getInstance(project).setProjectSdk(Sdk jdk);`
* To set the project-level SDK name: `ProjectRootManager.getInstance(project).setProjectSdkName(String name);`
Note that by default, the project modules use the project SDK. Optionally, you can configure individual SDK for each module.
## Working with Modules
*IntelliJ Platform* provides a number of Java classes and interfaces you can use to work with modules:
The *IntelliJ Platform* provides a number of Java classes and interfaces you can use to work with modules:
* [ModuleManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java) abstract class.
* [Module](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/Module.java) interface.
* [ModuleRootManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java) abstract class.
* [ModuleRootModel](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModel.java) interface.
* [ModuleUtil](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java) class.
* [ModifiableModuleModel](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/module/ModifiableModuleModel.java) interface.
* [ModifiableRootModel](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java) interface.
* [`ModuleManager`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java) abstract class.
* [`Module`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/core-api/src/com/intellij/openapi/module/Module.java) interface.
* [`ModuleRootManager`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java) abstract class.
* [`ModuleRootModel`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModel.java) interface.
* [`ModuleUtil`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java) class.
* [`ModifiableModuleModel`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/module/ModifiableModuleModel.java) interface.
* [`ModifiableRootModel`](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java) interface.
This section discusses how to complete some common tasks related to management of modules.
#### How do I get a list of modules the project includes?
### How do I get a list of modules the project includes?
Use the `ModuleManager.getModules()` method.
#### How do I get dependencies and classpath of a module?
### How do I get dependencies and classpath of a module?
_Order entries_ include SDK, libraries and other modules the module uses.
With the *IntelliJ IDEA* UI, you can view order entries for a module on the
[Dependencies](http://www.jetbrains.com/idea/help/dependencies-tab.html)
tab of the *Project Structure* dialog box.
To explore the
[module dependencies](http://www.jetbrains.com/idea/help/dependencies-tab.html),
use the
[OrderEnumerator](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/OrderEnumerator.java)
class.
_Order entries_ include SDK, libraries and other modules the module uses. With the *IntelliJ IDEA* UI, you can view order entries for a module on the [Dependencies](http://www.jetbrains.com/idea/help/dependencies-tab.html) tab of the *Project Structure* dialog box.
To explore the [module dependencies](http://www.jetbrains.com/idea/help/dependencies-tab.html), use the [OrderEnumerator](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/OrderEnumerator.java) class.
The following code snippet illustrates how you can get classpath (classes root of all dependencies) for a module:
@ -229,22 +184,20 @@ The following code snippet illustrates how you can get classpath (classes root o
VirtualFile[] roots = ModuleRootManager.getInstance(module).orderEntries().classes().getRoots();
```
#### How do I get the SDK the module uses?
### How do I get the SDK the module uses?
Use the `ModuleRootManager.getSdk()` method. This method returns a value of the [Sdk](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/projectRoots/Sdk.java) type.
Use the `ModuleRootManager.getSdk()` method.
This method returns a value of the
[Sdk](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/projectRoots/Sdk.java)
type.
The following code snippet illustrates how you can get detailed information on SDK the specified module uses:
```java
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
Sdk SDK = moduleRootManager.getSdk();
String jdkInfo = "Module: " + module.getName() + " SDK: " + SDK.getName() + " SDK version: "
+ SDK.getVersionString() + " SDK home directory: " + SDK.getHomePath();
+ SDK.getVersionString() + " SDK home directory: " + SDK.getHomePath();
```
#### How do I get a list of modules on which this module directly depends?
### How do I get a list of modules on which this module directly depends?
Use the `ModuleRootManager.getDependencies()` method to get an array of the `Module` type values or the `ModuleRootManager.getDependencyModuleNames()` to get an array of module names. To clarify, consider the following code snippet:
@ -254,75 +207,71 @@ Module[] dependentModules = moduleRootManager.getDependencies();
String[] dependentModulesNames = moduleRootManager.getDependencyModuleNames();
```
#### How do I get a list of modules that depend on this module?
### How do I get a list of modules that depend on this module?
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:
`boolean isDependent = ModuleManager.getInstance(project).isModuleDependent(module1,module2);`
#### How do I get a module to which the specified file or PSI element belongs?
* To get the project module to which the specified file belongs, use the `ModuleUtil.findModuleForFile()` static method.
To clarify, consider the following code snippet:
```java
String pathToFile = "C:\\users\\firstName.LastName\\plugins\\myPlugin\src\MyAction.java";
VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(pathToFile);
Module module = ModuleUtil.findModuleForFile(virtualFile,myProject);
String moduleName = module == null ? "Module not found" : module.getName();
boolean isDependent = ModuleManager.getInstance(project).isModuleDependent(module1,module2);
```
* To get the project module to which the specified
[PSI element](architectural_overview/psi_elements.md)
belongs, use the `ModuleUtil.findModuleForPsiElement(psiElement)` method.
### How do I get a module to which the specified file or PSI element belongs?
#### How do I work with libraries available within a module?
* To get the project module to which the specified file belongs, use the `ModuleUtil.findModuleForFile()` static method.
##### How do I get a list of libraries available within a module?
To clarify, consider the following code snippet:
To get the list of libraries, use `OrderEnumerator#forEachLibrary` method.
```java
String pathToFile = "C:\\users\\firstName.LastName\\plugins\\myPlugin\src\MyAction.java";
VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(pathToFile);
Module module = ModuleUtil.findModuleForFile(virtualFile,myProject);
String moduleName = module == null ? "Module not found" : module.getName();
```
* To get the project module to which the specified [PSI element](architectural_overview/psi_elements.md) belongs, use the `ModuleUtil.findModuleForPsiElement(psiElement)` method.
### How do I work with libraries available within a module?
#### How do I get a list of libraries available within a module?
To get the list of libraries, use `OrderEnumerator.forEachLibrary` method.
To clarify this, consider the following code snippet that illustrates how to output the list of libraries for the specified module:
```java
final List<String> libraryNames = new ArrayList<String>();
ModuleRootManager.getInstance(module).orderEntries().forEachLibrary(new Processor<Library>() {
@Override
public boolean process(Library library) {
libraryNames.add(library.getName());
return true;
}
@Override
public boolean process(Library library) {
libraryNames.add(library.getName());
return true;
}
});
Messages.showInfoMessage(StringUtil.join(libraryNames, "\n"), "Libraries in Module");
```
This sample code outputs a list of libraries for the `module` module.
##### How do I get the library content?
#### How do I get the library content?
The `Library` class provides the `getUrls` method you can use to get a list of source roots and classes the library includes.
To clarify, consider the following code snippet:
The `Library` class provides the `getUrls` method you can use to get a list of source roots and classes the library includes. To clarify, consider the following code snippet:
```java
StringBuilder roots = new StringBuilder("The " + lib.getName() + " library includes:\n");
roots.append("Sources:\n");
for (String each : lib.getUrls(OrderRootType.SOURCES)) {
roots.append(each).append("\n");
roots.append(each).append("\n");
}
roots.append"Classes:\n");
for (String each : lib.getUrls(OrderRootType.CLASSES)) {
strRoots.append(each).append("\n");
strRoots.append(each).append("\n");
}
Messages.showInfoMessage(roots.toString(), "Library Info");
```
In this sample code, `lib` is of the
[Library](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/Library.java)
type.
In this sample code, `lib` is of the [Library](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/Library.java) type.
#### How do I get a set of facets the module includes?
### How do I get a set of facets the module includes?
Use the
[FacetManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/lang-api/src/com/intellij/facet/FacetManager.java)
and
[Facet](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/lang-api/src/com/intellij/facet/Facet.java)
classes.
Use the [FacetManager](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/lang-api/src/com/intellij/facet/FacetManager.java) and [Facet](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/lang-api/src/com/intellij/facet/Facet.java) classes.

View File

@ -2,24 +2,21 @@
title: PSI Cookbook
---
This page gives a list of recipes for the most common operations for working with the PSI (Program Structure Interface). Unlike [Developing Custom Language Plugins](/reference_guide/custom_language_support.md), it talks about working with the PSI of existing languages (such as Java).
This page gives a list of recipes for the most common operations for working with the PSI (Program Structure Interface) of IntelliJ Platform. Unlike
[Developing Custom Language Plugins](/reference_guide/custom_language_support.md),
it talks about working with the PSI of existing languages (such as Java).
### How do I find a file if I know its name but don't know the path?
## How do I find a file if I know its name but don't know the path?
`FilenameIndex.getFilesByName()`
### How do I find where a particular PSI element is used?
## How do I find where a particular PSI element is used?
`ReferencesSearch.search()`
### How do I rename a PSI element?
## How do I rename a PSI element?
`RefactoringFactory.createRename()`
### How can I cause the PSI for a virtual file to be rebuilt?
## How can I cause the PSI for a virtual file to be rebuilt?
`FileContentUtil.reparseFiles()`

View File

@ -2,9 +2,7 @@
title: Main Types of Plugins
---
Products based on *IntelliJ Platform* can be modified and adjusted for custom purposes by adding plugins.
All downloadable plugins are available at
[JetBrains Plugin Repository](https://plugins.jetbrains.com/).
Products based on the *IntelliJ Platform* can be modified and adjusted for custom purposes by adding plugins. All downloadable plugins are available at the [JetBrains Plugin Repository](https://plugins.jetbrains.com/).
The most common types of plugins include:
@ -13,8 +11,6 @@ The most common types of plugins include:
* Tool integration
* User interface add-ons
The majority of existing plugins are complex and combine multiple functions, but typically fall under the following categories:
## Custom Language Support
Custom language support provides basic functionality for working with a particular programming language. This includes:
@ -27,21 +23,19 @@ Custom language support provides basic functionality for working with a particul
* Inspections and quick-fixes
* Intention actions
Refer to the
[Custom Language Support Tutorial](/tutorials/custom_language_support_tutorial.md)
to learn more about the topic.
Refer to the [Custom Language Support Tutorial](/tutorials/custom_language_support_tutorial.md) to learn more about the topic.
## Framework Integration
Framework integration consists of improved code insight features which are typical for a given framework, as well as the option to use framework-specific functionality directly from the IDE. Sometimes it also includes language support elements for a custom syntax or DSL.
* Specific code insight
* Direct access to framework-specific functionality
Refer to
[Struts 2 plugin](https://plugins.jetbrains.com/plugin/1698)
as an example of framework integration.
Refer to the [Struts 2 plugin](https://plugins.jetbrains.com/plugin/1698) as an example of framework integration.
## Tool Integration
Tool integration makes it possible to manipulate third-party tools and components directly from the IDE without switching contexts.
This implies:
@ -50,12 +44,8 @@ This implies:
* Related UI components
* Access to external resources
Refer to the
[Gerrit integration](https://plugins.jetbrains.com/plugin/7272?pr=idea)
plugin as an example.
Refer to the [Gerrit integration](https://plugins.jetbrains.com/plugin/7272?pr=idea) plugin as an example.
## User Interface Add-Ons
Plugins in this category apply various changes to the standard user interface of the IDE.
Some newly added components are interactive and provide new functionality, while others are limited to visual modifications only.
The following plugin may serve as an example: [Background Image](https://plugins.jetbrains.com/plugin/72)
Plugins in this category apply various changes to the standard user interface of the IDE. Some newly added components are interactive and provide new functionality, while others are limited to visual modifications only. The [Background Image](https://plugins.jetbrains.com/plugin/72) plugin may serve as an example.

View File

@ -2,104 +2,67 @@
title: Virtual File System
---
The virtual file system (VFS) is a component of *IntelliJ Platform* that encapsulates most of its activity for working with files. It serves the following main purposes:
The virtual file system - VFS - is a component of IntelliJ Platform that encapsulates most of its activity for working with files.
It serves the following main purposes:
* Providing a universal API for working with files regardless of their actual location (on disk, in archive, on a HTTP server etc.)
* Tracking file modifications and providing both old and new versions of the file content when a modification is detected.
* Providing a possibility to associate additional persistent data with a file in the VFS.
* Providing a universal API for working with files regardless of their actual location (on disk, in archive, on a HTTP server etc.)
In order to provide the last two features, the VFS manages a _persistent snapshot_ of some of the contents of the user's hard disk. The snapshot stores only those files which have been requested at least once through the VFS API, and is asynchronously updated to match the changes happening on the disk.
* Tracking file modifications and providing both old and new versions of the file content when a modification is detected
* Providing a possibility to associate additional persistent data with a file in the VFS
In order to provide the last two features, the VFS manages a _persistent snapshot_ of some of the contents of the user's hard disk.
The snapshot stores only those files which have been requested at least once through the VFS API, and is asynchronously updated to match the changes happening on the disk.
The snapshot is application-level, not project-level - so, if some file (for example, a class in the JDK) is referenced by multiple projects, only one copy of its contents will be stored in the VFS.
The snapshot is application level, not project level - so, if some file (for example, a class in the JDK) is referenced by multiple projects, only one copy of its contents will be stored in the VFS.
All VFS access operations go through the snapshot.
If some information is requested through the VFS APIs and is not available in the snapshot, it is loaded from disk and stored into the snapshot.
If the information is available in the snapshot, the snapshot data is returned.
The contents of files and the lists of files in directories are stored in the snapshot only if that specific information was accessed - otherwise, only file metadata like name, length, timestamp, attributes is stored.
If some information is requested through the VFS APIs and is not available in the snapshot, it is loaded from disk and stored into the snapshot. If the information is available in the snapshot, the snapshot data is returned. The contents of files and the lists of files in directories are stored in the snapshot only if that specific information was accessed - otherwise, only file metadata like name, length, timestamp, attributes is stored.
**Note:**
This means that the state of the file system and the file contents displayed in the IntelliJ IDEA UI comes from the snapshot, which may not always match the actual contents of the disk.
For example, in some cases deleted files can still be visible in the UI for some time before the deletion is picked up by IntelliJ IDEA.
> **Note** This means that the state of the file system and the file contents displayed in the IntelliJ IDEA UI comes from the snapshot, which may not always match the actual contents of the disk.
>
> For example, in some cases deleted files can still be visible in the UI for some time before the deletion is picked up by IntelliJ IDEA.
The snapshot is updated from disk during _refresh operations_, which generally happen asynchronously. All write operations made through the VFS are synchronous - i.e. the contents is saved to disk immediately.
The snapshot is updated from disk during _refresh operations_, which generally happen asynchronously.
All write operations made through the VFS are synchronous - i.e. the contents is saved to disk immediately.
A refresh operation synchronizes the state of a part of the VFS with the actual disk contents. Refresh operations are explicitly invoked from *IntelliJ IDEA* or plugin code - i.e. when a file is changed on disk while *IntelliJ IDEA* is running, the change will not be immediately picked up by the VFS. The VFS will be updated during the next refresh operation which includes the file in its scope.
A refresh operation synchronizes the state of a part of the VFS with the actual disk contents.
Refresh operations are explicitly invoked from the IntelliJ IDEA or plugin code - i.e. when a file is changed on disk while IntelliJ IDEA is running, the change will not be immediately picked up by the VFS.
The VFS will be updated during the next refresh operation which includes the file in its scope.
*IntelliJ Platform* refreshes the entire project contents asynchronously on startup. By default, it performs a refresh operation when the user switches to it from another app, but users can turn this off via **Settings \| Appearance & Behavior \| System Settings \| Synchronize files on frame activation**.
IntelliJ Platform refreshes the entire project contents asynchronously on startup.
By default, it performs a refresh operation when the user switches to it from another app, but users can turn this off via **Settings \| Appearance & Behavior \| System Settings \| Synchronize files on frame activation**.
On Windows, Mac and Linux, *IntelliJ Platform* starts a native file watcher process that receives file change notifications from the file system and reports them to *IntelliJ Platform*. If a file watcher is available, a refresh operation looks only at the files that have been reported as changed by the file watcher. If no file watcher is present, a refresh operation walks through all directories and files in the refresh scope.
On Windows, Mac and Linux IntelliJ Platform starts a native file watcher process that receives file change notifications from the file system and reports them to IntelliJ Platform.
If a file watcher is available, a refresh operation looks only at the files that have been reported as changed by the file watcher.
If no file watcher is present, a refresh operation walks through all directories and files in the refresh scope.
Refresh operations are based on file timestamps. If the contents of a file was changed but its timestamp remained the same, *IntelliJ Platform* will not pick up the updated contents.
Refresh operations are based on file timestamps.
If the contents of a file was changed but its timestamp remained the same, IntelliJ Platform will not pick up the updated contents.
There is currently no facility for removing files from the snapshot. If a file was loaded there once, it remains there forever unless it was deleted from the disk and a refresh operation was called on one of its parent directories.
There is currently no facility for removing files from the snapshot.
If a file was loaded there once, it remains there forever unless it was deleted from the disk and a refresh operation was called on one of its parent directories.
The VFS itself does not honor ignored files listed in **Settings \| File Types \| Files** and folders to ignore and excluded folders listed in **Project Structure \| Modules \| Sources \| Excluded**. If the application code accesses them, the VFS will load and return their contents. In most cases, the ignored files and excluded folders must be skipped from processing by higher level code.
The VFS itself does not honor ignored files listed in **Settings \| File Types \| Files** and folders to ignore and excluded folders listed in **Project Structure \| Modules \| Sources \| Excluded**.
If the application code accesses them, the VFS will load and return their contents.
In most cases, the ignored files and excluded folders must be skipped from processing by higher-level code.
During the lifetime of a running instance of *IntelliJ IDEA*, multiple `VirtualFile` instances may correspond to the same disk file. They are equal, have the same `hashCode` and share the user data.
During the lifetime of a running instance of IntelliJ IDEA, multiple VirtualFile instances may correspond to the same disk file.
They are equal, have the same hashCode and share the user data.
## Synchronous and asynchronous refreshes
## Synchronous and Asynchronous Refreshes
From the point of view of the caller, refresh operations can be either synchronous or asynchronous. In fact, the refresh operations are executed according to their own threading policy, and the synchronous flag simply means that the calling thread will be blocked until the refresh operation (which will most likely run on a different thread) is completed.
From the point of view of the caller, refresh operations can be either synchronous or asynchronous.
In fact, the refresh operations are executed according to their own threading policy, and the synchronous flag simply means that the calling thread will be blocked until the refresh operation (which will most likely run on a different thread) is completed.
Both synchronous and asynchronous refreshes can be initiated from any thread. If a refresh is initiated from a background thread, the calling thread must not hold a read action, because otherwise a deadlock would occur. See [IntelliJ Platform Architectural Overview](/basics/architectural_overview/general_threading_rules.html) for more details on the threading model and read/write actions.
Both synchronous and asynchronous refreshes can be initiated from any thread.
If a refresh is initiated from a background thread, the calling thread must not hold a read action, because otherwise a deadlock would occur.
See [IntelliJ Platform Architectural Overview](/basics/architectural_overview/general_threading_rules.html) for more details on the threading model and read/write actions.
The same threading requirements also apply to functions like
[LocalFileSystem.refreshAndFindFileByPath()](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/vfs/LocalFileSystem.java),
which perform a partial refresh if the file with the specified path is not found in the snapshot.
The same threading requirements also apply to functions like [LocalFileSystem.refreshAndFindFileByPath()](https://upsource.jetbrains.com/idea-community/file/1731d054af4ca27aa827c03929e27eeb0e6a8366/platform/platform-api/src/com/intellij/openapi/vfs/LocalFileSystem.java), which perform a partial refresh if the file with the specified path is not found in the snapshot.
In nearly all cases, using asynchronous refreshes is strongly preferred.
If there is some code that needs to be executed after the refresh is complete, the code should be passed as a postRunnable parameter to one of the refresh methods:
In nearly all cases, using asynchronous refreshes is strongly preferred. If there is some code that needs to be executed after the refresh is complete, the code should be passed as a `postRunnable` parameter to one of the refresh methods:
* [RefreshQueue.createSession()](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/RefreshQueue.java#L36)
* [VirtualFile.refresh()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java#L681)
* [RefreshQueue.createSession()](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/RefreshQueue.java#L36)
* [VirtualFile.refresh()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java#L681)
Synchronous refreshes can cause deadlocks in some cases, depending on which locks are held by the thread invoking the refresh operation.
## Virtual File System Events
## Virtual file system events
All changes happening in the virtual file system, either as a result of refresh operations or caused by user's actions, are reported as _virtual file system events_.
VFS events are always fired in the event dispatch thread, and in a write action.
All changes happening in the virtual file system, either as a result of refresh operations or caused by user's actions, are reported as _virtual file system events_. VFS events are always fired in the event dispatch thread, and in a write action.
The most efficient way to listen to VFS events is to implement the BulkFileListener interface and to subscribe with it to the
[VirtualFileManager.VFS_CHANGES](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java#L34)
topic.
The most efficient way to listen to VFS events is to implement the `BulkFileListener` interface and to subscribe with it to the [VirtualFileManager.VFS_CHANGES](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java#L34) topic.
This API gives you all the changes detected during the refresh operation in one list, and lets you process them in batch.
Alternatively, you can implement the VirtualFileListener interface and register it using
[VirtualFileManager.addVirtualFileListener()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java#L113).
This will let you process the events one by one.
This API gives you all the changes detected during the refresh operation in one list, and lets you process them in batch. Alternatively, you can implement the `VirtualFileListener` interface and register it using [VirtualFileManager.addVirtualFileListener()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java#L113). This will let you process the events one by one.
Note that the VFS listeners are application-level, and will receive events for changes happening in all the projects opened by the user.
You may need to filter out events which aren't relevant to your task.
Note that the VFS listeners are application level, and will receive events for changes happening in all the projects opened by the user. You may need to filter out events which aren't relevant to your task.
VFS events are sent both before and after each change, and you can access the old contents of the file in the before event.
Note that events caused by a refresh are sent after the changes have already occurred on disk - so when you process the beforeFileDeletion event, for example, the file has already been deleted from disk.
However, it is still present in the VFS snapshot, and you can access its last contents using the VFS API.
VFS events are sent both before and after each change, and you can access the old contents of the file in the before event. Note that events caused by a refresh are sent after the changes have already occurred on disk - so when you process the `beforeFileDeletion` event, for example, the file has already been deleted from disk. However, it is still present in the VFS snapshot, and you can access its last contents using the VFS API.
Note that a refresh operation fires events only for changes in files that have been loaded in the snapshot.
For example, if you accessed a VirtualFile for a directory but never loaded its contents using
[VirtualFile.getChildren()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java#L135),
you may not get fileCreated notifications when files are created in that directory.
If you loaded only a single file in a directory using VirtualFile.findChild(), you will get notifications for changes to that file, but you may not get created/deleted notifications for other files in the same directory.
Note that a refresh operation fires events only for changes in files that have been loaded in the snapshot. For example, if you accessed a `VirtualFile` for a directory but never loaded its contents using [VirtualFile.getChildren()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java#L135), you may not get `fileCreated` notifications when files are created in that directory.
If you loaded only a single file in a directory using `VirtualFile.findChild()`, you will get notifications for changes to that file, but you may not get created/deleted notifications for other files in the same directory.

View File

@ -5,36 +5,19 @@ title: IntelliJ Platform SDK Documentation
## Welcome to the IntelliJ Platform SDK Documentation!
Here you can find [basic information](basics.md) about the *IntelliJ Platform SDK*, in particular how to
**[get started](basics/getting_started.md)** with developing plugins for IntelliJ IDEA and other JetBrains IDEs.
Here you can find [basic information](basics.md) about the *IntelliJ Platform SDK*, in particular how to **[get started](basics/getting_started.md)** with developing plugins for IntelliJ IDEA and other JetBrains IDEs.
More details about specific development topics can be found in the
[Architecture Reference Guide](reference_guide.md).
More details about specific development topics can be found in the [Architecture Reference Guide](reference_guide.md).
A set of
**[step-by-step tutorials](tutorials.md)**
with code samples will lead you through the common use cases for *IntelliJ Platform SDK*.
A set of **[step-by-step tutorials](tutorials.md)** with code samples will lead you through the common use cases for the *IntelliJ Platform SDK*.
The [Plugin Development FAQ](faq.md) section contains a series of issues commonly discussed on our [Open API and Plugin Development](https://devnet.jetbrains.com/community/idea/open_api_and_plugin_development) forums.
The [Plugin Development FAQ](faq.md)
section contains a series of issues commonly discussed on our
[Open API and Plugin Development](https://devnet.jetbrains.com/community/idea/open_api_and_plugin_development) forums.
One of the ways to improve the *IntelliJ SDK* documentation is to **[contribute to the project](CONTRIBUTING.md)**. Any kind of content including tutorials, articles about *IntelliJ* architecture or code samples that can help plugin developers is kindly welcome. Please read the [Contribution Guidelines](CONTRIBUTING.md) if you would like to share your knowledge.
One of the ways to improve *IntelliJ SDK Documentation* is to
**[contribute to the project](CONTRIBUTING.md)**.
Any kind of content including tutorials, articles about *IntelliJ* architecture or code samples that can help plugin developers is kindly welcome.
Please read the
[Contribution Guidelines](CONTRIBUTING.md)
if you would like to share your knowledge.
Please let us know about any **content inconsistencies**, outdated materials, cosmetic issues, or other defects you may find by submitting an issue to [YouTrack](https://youtrack.jetbrains.com/issues/IJSDK). If you haven't found a documentation topic that answers your questions, feel free to file a **[request](https://youtrack.jetbrains.com/newIssue?project=IJSDK)**.
Please let us know about any **content inconsistencies**, outdated materials, cosmetic issues, or other defects you may find by submitting an issue to
[YouTrack](https://youtrack.jetbrains.com/issues/IJSDK).
If you haven't found a documentation topic that answers your questions, feel free to file a
**[request](https://youtrack.jetbrains.com/newIssue?project=IJSDK)**.
Please [give us your feedback](http://www.surveygizmo.com/s3/2149448/IntelliJ-SDK-Docs)
to help make *IntelliJ Platform* documentation better.
Please [give us your feedback](http://www.surveygizmo.com/s3/2149448/IntelliJ-SDK-Docs) to help make the *IntelliJ Platform* documentation better.