mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-28 01:07:49 +08:00
convert upsource://
links to generic variable-based notation, add gh-ic-master and gh-sdk-samples setup
This commit is contained in:
parent
e68d947772
commit
09648db712
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
<variables>
|
<variables>
|
||||||
<web-root>https://plugins.jetbrains.com/docs</web-root>
|
<web-root>https://plugins.jetbrains.com/docs</web-root>
|
||||||
|
<product-web-url>https://plugins.jetbrains.com/docs/intellij/</product-web-url>
|
||||||
<web-community-path>Developer Community:https://intellij-support.jetbrains.com/hc/en-us/community/topics/200366979</web-community-path>
|
<web-community-path>Developer Community:https://intellij-support.jetbrains.com/hc/en-us/community/topics/200366979</web-community-path>
|
||||||
<download-page/>
|
<download-page/>
|
||||||
<search-scope/>
|
<search-scope/>
|
||||||
@ -26,12 +27,6 @@
|
|||||||
<noindex-content-in-deprecated>false</noindex-content-in-deprecated>
|
<noindex-content-in-deprecated>false</noindex-content-in-deprecated>
|
||||||
<noindex-content-in-eap>false</noindex-content-in-eap>
|
<noindex-content-in-eap>false</noindex-content-in-eap>
|
||||||
<noindex-content-in-release>false</noindex-content-in-release>
|
<noindex-content-in-release>false</noindex-content-in-release>
|
||||||
|
|
||||||
<upsource-commit-hash>e35169da4fa72ef807b9e3995bb9e6343f5db02c</upsource-commit-hash>
|
|
||||||
<upsource-tag>222.3345.118</upsource-tag> <!-- synchronize with entries in v.list -->
|
|
||||||
<upsource-repo-name>idea-ce</upsource-repo-name>
|
|
||||||
<upsource-server-address>upsource.jetbrains.com</upsource-server-address>
|
|
||||||
<product-web-url>https://plugins.jetbrains.com/docs/intellij/</product-web-url>
|
|
||||||
</variables>
|
</variables>
|
||||||
|
|
||||||
<build-profile product="ijs"/>
|
<build-profile product="ijs"/>
|
||||||
|
@ -389,7 +389,7 @@ Add implementation for `com.intellij.openapi.fileEditor.FileEditor.getFile()`
|
|||||||
: Project is now only accessible via `com.intellij.openapi.ui.playback.PlaybackContext.getProject()` since it may change during script execution.
|
: Project is now only accessible via `com.intellij.openapi.ui.playback.PlaybackContext.getProject()` since it may change during script execution.
|
||||||
|
|
||||||
JSON Widget suppressor EP `com.intellij.json.jsonWidgetSuppressor`
|
JSON Widget suppressor EP `com.intellij.json.jsonWidgetSuppressor`
|
||||||
: Override new method [`JsonWidgetSuppressor.isCandidateForSuppress(VirtualFile, Project)`](upsource:///json/src/com/jetbrains/jsonSchema/extension/JsonWidgetSuppressor.java) for quick check in EDT before `suppressSwitcherWidget()` is called on background thread.
|
: Override new method [`JsonWidgetSuppressor.isCandidateForSuppress(VirtualFile, Project)`](%gh-ic%/json/src/com/jetbrains/jsonSchema/extension/JsonWidgetSuppressor.java) for quick check in EDT before `suppressSwitcherWidget()` is called on background thread.
|
||||||
|
|
||||||
### HTTP Client Plugin 2021.1
|
### HTTP Client Plugin 2021.1
|
||||||
|
|
||||||
|
@ -33,24 +33,24 @@ Each entry is mapped to its corresponding _Replacement_, pointing to recommended
|
|||||||
| `BuildNumber.currentVersion()` | Use `ApplicationInfo.getBuild()` |
|
| `BuildNumber.currentVersion()` | Use `ApplicationInfo.getBuild()` |
|
||||||
| `CompactVirtualFileSet` | Use `VfsUtilCore.createCompactVirtualFileSet()` |
|
| `CompactVirtualFileSet` | Use `VfsUtilCore.createCompactVirtualFileSet()` |
|
||||||
| `DefaultPicoContainer` | Use [extension points](plugin_extensions.md) and [services](plugin_services.md) |
|
| `DefaultPicoContainer` | Use [extension points](plugin_extensions.md) and [services](plugin_services.md) |
|
||||||
| `EdtDataContext` | [See Doc](upsource:///platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/EdtDataContext.java) |
|
| `EdtDataContext` | [See Doc](%gh-ic%/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/EdtDataContext.java) |
|
||||||
| `FileTypeIndex.NAME` | Use static methods in `FileTypeIndex` directly |
|
| `FileTypeIndex.NAME` | Use static methods in `FileTypeIndex` directly |
|
||||||
| `IElementType.getDebugName()` | Override/use `IElementType.toString()` |
|
| `IElementType.getDebugName()` | Override/use `IElementType.toString()` |
|
||||||
| `IconLoader.CachedImageIcon` | Use methods exposed in `IconLoader` |
|
| `IconLoader.CachedImageIcon` | Use methods exposed in `IconLoader` |
|
||||||
| `IconLoader.LazyIcon` | Use `IconLoader.createLazy()` |
|
| `IconLoader.LazyIcon` | Use `IconLoader.createLazy()` |
|
||||||
| `IndexingDataKeys` | [See Doc](upsource:///platform/core-impl/src/com/intellij/util/indexing/IndexingDataKeys.java) |
|
| `IndexingDataKeys` | [See Doc](%gh-ic%/platform/core-impl/src/com/intellij/util/indexing/IndexingDataKeys.java) |
|
||||||
| `Module.getModuleFile()` | [See Doc](upsource:///platform/core-api/src/com/intellij/openapi/module/Module.java) |
|
| `Module.getModuleFile()` | [See Doc](%gh-ic%/platform/core-api/src/com/intellij/openapi/module/Module.java) |
|
||||||
| `Module.getModuleFilePath()` | [See Doc](upsource:///platform/core-api/src/com/intellij/openapi/module/Module.java) |
|
| `Module.getModuleFilePath()` | [See Doc](%gh-ic%/platform/core-api/src/com/intellij/openapi/module/Module.java) |
|
||||||
| `Module.getModuleTypeName()` | [See Doc](upsource:///platform/core-api/src/com/intellij/openapi/module/Module.java) |
|
| `Module.getModuleTypeName()` | [See Doc](%gh-ic%/platform/core-api/src/com/intellij/openapi/module/Module.java) |
|
||||||
| `ModuleTypeManager.registerModuleType()` | Use `com.intellij.moduleType` extension point instead, [`ModuleType`](upsource:///platform/lang-core/src/com/intellij/openapi/module/ModuleType.java) |
|
| `ModuleTypeManager.registerModuleType()` | Use `com.intellij.moduleType` extension point instead, [`ModuleType`](%gh-ic%/platform/lang-core/src/com/intellij/openapi/module/ModuleType.java) |
|
||||||
| `PathMacros.setMacro()` | Use `com.intellij.pathMacroContributor` extension point, [`PathMacroContributor`](upsource:///platform/core-api/src/com/intellij/openapi/application/PathMacroContributor.java) |
|
| `PathMacros.setMacro()` | Use `com.intellij.pathMacroContributor` extension point, [`PathMacroContributor`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/PathMacroContributor.java) |
|
||||||
| `PlatformUtils` | [See Doc](upsource:///platform/core-api/src/com/intellij/util/PlatformUtils.java) |
|
| `PlatformUtils` | [See Doc](%gh-ic%/platform/core-api/src/com/intellij/util/PlatformUtils.java) |
|
||||||
| `PluginClassLoader` | Cast to [`PluginAwareClassLoader`](upsource:///platform/extensions/src/com/intellij/ide/plugins/cl/PluginAwareClassLoader.java) |
|
| `PluginClassLoader` | Cast to [`PluginAwareClassLoader`](%gh-ic%/platform/extensions/src/com/intellij/ide/plugins/cl/PluginAwareClassLoader.java) |
|
||||||
| `PluginManager.getLogger()` | Use own logger, see [](ide_infrastructure.md#logging) |
|
| `PluginManager.getLogger()` | Use own logger, see [](ide_infrastructure.md#logging) |
|
||||||
| `ProjectLibraryTable` | Use `LibraryTablesRegistrar.getLibraryTable()` |
|
| `ProjectLibraryTable` | Use `LibraryTablesRegistrar.getLibraryTable()` |
|
||||||
| `SVGLoader` | Use `ImageLoader.loadFromResource()` |
|
| `SVGLoader` | Use `ImageLoader.loadFromResource()` |
|
||||||
| `ScrollBarPainter` | [See Doc](upsource:///platform/platform-api/src/com/intellij/ui/components/ScrollBarPainter.java) |
|
| `ScrollBarPainter` | [See Doc](%gh-ic%/platform/platform-api/src/com/intellij/ui/components/ScrollBarPainter.java) |
|
||||||
| `UtilKt.targetPresentation()` | [See Doc](upsource:///platform/lang-impl/src/com/intellij/codeInsight/navigation/util.kt) |
|
| `UtilKt.targetPresentation()` | [See Doc](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/navigation/util.kt) |
|
||||||
|
|
||||||
## Plugins
|
## Plugins
|
||||||
|
|
||||||
@ -66,13 +66,13 @@ Each entry is mapped to its corresponding _Replacement_, pointing to recommended
|
|||||||
The API listed in this table is currently (or was previously) marked with `@ApiStatus.Internal`, but its status has changed in the meantime (or will change).
|
The API listed in this table is currently (or was previously) marked with `@ApiStatus.Internal`, but its status has changed in the meantime (or will change).
|
||||||
Therefore, any reported violations can be disregarded.
|
Therefore, any reported violations can be disregarded.
|
||||||
|
|
||||||
| Internal API | Note |
|
| Internal API | Note |
|
||||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|
|
|---------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|
|
||||||
| [`BundleBase`](upsource:///platform/util/src/com/intellij/BundleBase.java) | Made public in 2022.1 |
|
| [`BundleBase`](%gh-ic%/platform/util/src/com/intellij/BundleBase.java) | Made public in 2022.1 |
|
||||||
| [`IdFilter`](upsource:///platform/indexing-api/src/com/intellij/util/indexing/IdFilter.java) | Reverted in 2021.2/3 |
|
| [`IdFilter`](%gh-ic%/platform/indexing-api/src/com/intellij/util/indexing/IdFilter.java) | Reverted in 2021.2/3 |
|
||||||
| [`RunAnythingCommandLineProvider`](upsource:///platform/lang-impl/src/com/intellij/ide/actions/runAnything/activity/RunAnythingCommandLineProvider.kt) | Made public in 2021.3 |
|
| [`RunAnythingCommandLineProvider`](%gh-ic%/platform/lang-impl/src/com/intellij/ide/actions/runAnything/activity/RunAnythingCommandLineProvider.kt) | Made public in 2021.3 |
|
||||||
| `org.jetbrains.yaml.meta.*` | YAML Metadata API will be made public in 2022.2 |
|
| `org.jetbrains.yaml.meta.*` | YAML Metadata API will be made public in 2022.2 |
|
||||||
| `PhpExpectedFunctionArgument` | Made public in 2022.1 |
|
| `PhpExpectedFunctionArgument` | Made public in 2022.1 |
|
||||||
|
|
||||||
> Missing entries? Please let us know via the "**Was this page helpful?**" feedback form below or [other channels](getting_help.md#problems-with-the-guide).
|
> Missing entries? Please let us know via the "**Was this page helpful?**" feedback form below or [other channels](getting_help.md#problems-with-the-guide).
|
||||||
>
|
>
|
||||||
|
@ -101,4 +101,4 @@ Unbundled plugins
|
|||||||
: Assert references are created for the given underlying `PsiElement`. [Issue](https://youtrack.jetbrains.com/issue/IDEA-203954)
|
: Assert references are created for the given underlying `PsiElement`. [Issue](https://youtrack.jetbrains.com/issue/IDEA-203954)
|
||||||
|
|
||||||
`CachedValue` more strict assertions
|
`CachedValue` more strict assertions
|
||||||
: Enabled in tests and EAP/internal mode, see [`CachedValueStabilityChecker`](upsource:///platform/core-impl/src/com/intellij/util/CachedValueStabilityChecker.java) Javadoc.
|
: Enabled in tests and EAP/internal mode, see [`CachedValueStabilityChecker`](%gh-ic%/platform/core-impl/src/com/intellij/util/CachedValueStabilityChecker.java) Javadoc.
|
||||||
|
@ -105,14 +105,14 @@ Unbundled plugins
|
|||||||
Dynamic Plugins
|
Dynamic Plugins
|
||||||
: [Compatible plugins](dynamic_plugins.md) can be installed, updated and uninstalled without requiring IDE restart.
|
: [Compatible plugins](dynamic_plugins.md) can be installed, updated and uninstalled without requiring IDE restart.
|
||||||
|
|
||||||
[`com.intellij.openapi.application.TransactionGuard`](upsource:///platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java) deprecated
|
[`com.intellij.openapi.application.TransactionGuard`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java) deprecated
|
||||||
: Usage is deprecated and can be replaced with `com.intellij.openapi.application.Application.invokeLater()` in most cases, please consult Javadoc for more details.
|
: Usage is deprecated and can be replaced with `com.intellij.openapi.application.Application.invokeLater()` in most cases, please consult Javadoc for more details.
|
||||||
|
|
||||||
`RecursionManager.assertOnMissedCache()` enabled by default in tests
|
`RecursionManager.assertOnMissedCache()` enabled by default in tests
|
||||||
: Please see `RecursionManager.CachingPreventedException` Javadoc and [this issue](https://youtrack.jetbrains.com/issue/IDEA-228809) for details.
|
: Please see `RecursionManager.CachingPreventedException` Javadoc and [this issue](https://youtrack.jetbrains.com/issue/IDEA-228809) for details.
|
||||||
|
|
||||||
`ResolveCache` using `IdempotenceChecker` in tests
|
`ResolveCache` using `IdempotenceChecker` in tests
|
||||||
: Reports when the same reference resolves non-equivalent results in different threads, see [`IdempotenceChecker`](upsource:///platform/core-impl/src/com/intellij/util/IdempotenceChecker.java).
|
: Reports when the same reference resolves non-equivalent results in different threads, see [`IdempotenceChecker`](%gh-ic%/platform/core-impl/src/com/intellij/util/IdempotenceChecker.java).
|
||||||
|
|
||||||
Refactoring dialog: builtin "Open in editor" option
|
Refactoring dialog: builtin "Open in editor" option
|
||||||
: Set `addOpenInEditorCheckbox` constructor parameter to enable it in custom `RefactoringDialog` implementation.
|
: Set `addOpenInEditorCheckbox` constructor parameter to enable it in custom `RefactoringDialog` implementation.
|
||||||
@ -127,7 +127,7 @@ Override text presentation for actions depending on menu context
|
|||||||
: Set the [`<override-text>`](basic_action_system.md#setting-the-override-text-element) element within the `<action>` declaration in <path>plugin.xml</path>.
|
: Set the [`<override-text>`](basic_action_system.md#setting-the-override-text-element) element within the `<action>` declaration in <path>plugin.xml</path>.
|
||||||
|
|
||||||
Changes in Project Open/Import
|
Changes in Project Open/Import
|
||||||
: **Import from Existing Sources** has been removed from the Welcome Screen, leaving only **Open or Import**, which calls a different extension than the one previously used to contribute a wizard step to **Import from Existing Sources** (which is still available in the <control>File</control> menu). To support **Open or Import**, a plugin must provide [`ProjectOpenProcessor`](upsource:///platform/platform-api/src/com/intellij/projectImport/ProjectOpenProcessor.java).
|
: **Import from Existing Sources** has been removed from the Welcome Screen, leaving only **Open or Import**, which calls a different extension than the one previously used to contribute a wizard step to **Import from Existing Sources** (which is still available in the <control>File</control> menu). To support **Open or Import**, a plugin must provide [`ProjectOpenProcessor`](%gh-ic%/platform/platform-api/src/com/intellij/projectImport/ProjectOpenProcessor.java).
|
||||||
`ProjectOpenProcessor.canOpenProject()` should return `true` for the folder selected by the user only if it guarantees `doOpenProject()` can handle it. If there are several matching processors, a simple chooser dialog is shown. If additional manual configuration is necessary, a modal dialog can be shown in `doOpenProject()` - however, it is highly recommended performing all setup automatically (like Maven and Gradle plugins do).
|
`ProjectOpenProcessor.canOpenProject()` should return `true` for the folder selected by the user only if it guarantees `doOpenProject()` can handle it. If there are several matching processors, a simple chooser dialog is shown. If additional manual configuration is necessary, a modal dialog can be shown in `doOpenProject()` - however, it is highly recommended performing all setup automatically (like Maven and Gradle plugins do).
|
||||||
|
|
||||||
### IntelliJ IDEA 2020.1
|
### IntelliJ IDEA 2020.1
|
||||||
|
@ -28,7 +28,7 @@ Constructor Injection disabled for Extensions
|
|||||||
: Please obtain necessary components only when needed (logged as ERROR now).
|
: Please obtain necessary components only when needed (logged as ERROR now).
|
||||||
|
|
||||||
Language Injection
|
Language Injection
|
||||||
: Use [`LanguageInjectionContributor`](upsource:///platform/core-api/src/com/intellij/lang/injection/general/LanguageInjectionContributor.java) (EP `com.intellij.languageInjectionContributor`) and [`LanguageInjectionPerformer`](upsource:///platform/core-api/src/com/intellij/lang/injection/general/LanguageInjectionPerformer.java) (EP `com.intellij.languageInjectionPerformer`) to customize language injection.
|
: Use [`LanguageInjectionContributor`](%gh-ic%/platform/core-api/src/com/intellij/lang/injection/general/LanguageInjectionContributor.java) (EP `com.intellij.languageInjectionContributor`) and [`LanguageInjectionPerformer`](%gh-ic%/platform/core-api/src/com/intellij/lang/injection/general/LanguageInjectionPerformer.java) (EP `com.intellij.languageInjectionPerformer`) to customize language injection.
|
||||||
|
|
||||||
### IntelliJ IDEA 2021.2
|
### IntelliJ IDEA 2021.2
|
||||||
|
|
||||||
@ -40,13 +40,13 @@ Unbundled plugins
|
|||||||
### IntelliJ Platform 2021.1
|
### IntelliJ Platform 2021.1
|
||||||
|
|
||||||
_Add unambiguous imports on the fly_ for custom languages
|
_Add unambiguous imports on the fly_ for custom languages
|
||||||
: Override [`ReferenceImporter#isAddUnambiguousImportsOnTheFlyEnabled()`](upsource:///platform/analysis-impl/src/com/intellij/codeInsight/daemon/ReferenceImporter.java) and provide corresponding user setting. Implement `HintAction` with `fixSilently()` and hook it up to highlighting as a quick fix for unresolved reference.
|
: Override [`ReferenceImporter#isAddUnambiguousImportsOnTheFlyEnabled()`](%gh-ic%/platform/analysis-impl/src/com/intellij/codeInsight/daemon/ReferenceImporter.java) and provide corresponding user setting. Implement `HintAction` with `fixSilently()` and hook it up to highlighting as a quick fix for unresolved reference.
|
||||||
|
|
||||||
Ability to override encoding per `VirtualFile`
|
Ability to override encoding per `VirtualFile`
|
||||||
: Implement [`FileEncodingProvider`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/encoding/FileEncodingProvider.java) and register in `com.intellij.fileEncodingProvider` extension point.
|
: Implement [`FileEncodingProvider`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/encoding/FileEncodingProvider.java) and register in `com.intellij.fileEncodingProvider` extension point.
|
||||||
|
|
||||||
[JCEF](jcef.md): wrapper for `CefBrowser`
|
[JCEF](jcef.md): wrapper for `CefBrowser`
|
||||||
: [`JBCefOsrHandlerBrowser`](upsource:///platform/platform-api/src/com/intellij/ui/jcef/JBCefOsrHandlerBrowser.java) forwards to custom `CefRenderHandler`, e.g., for off-screen rendering.
|
: [`JBCefOsrHandlerBrowser`](%gh-ic%/platform/platform-api/src/com/intellij/ui/jcef/JBCefOsrHandlerBrowser.java) forwards to custom `CefRenderHandler`, e.g., for off-screen rendering.
|
||||||
|
|
||||||
### Java Plugin 2021.1
|
### Java Plugin 2021.1
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ K
|
|||||||
### IntelliJ Platform 2022.1
|
### IntelliJ Platform 2022.1
|
||||||
|
|
||||||
New Project Wizard
|
New Project Wizard
|
||||||
: The <control>New Project</control> wizard has been refreshed and some base [`ModuleBuilder`](upsource:///platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java) classes return `false` from the `isAvailable()` method. If your module builder extends a base class and is hidden in the 2022.1 wizard, override the method to return `true`.
|
: The <control>New Project</control> wizard has been refreshed and some base [`ModuleBuilder`](%gh-ic%/platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java) classes return `false` from the `isAvailable()` method. If your module builder extends a base class and is hidden in the 2022.1 wizard, override the method to return `true`.
|
||||||
|
|
||||||
External System Test Framework
|
External System Test Framework
|
||||||
: Available as `com.jetbrains.intellij.platform:external-system-test-framework` from [](intellij_artifacts.md), see [](external_system_integration.md#testing).
|
: Available as `com.jetbrains.intellij.platform:external-system-test-framework` from [](intellij_artifacts.md), see [](external_system_integration.md#testing).
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||||
|
|
||||||
A [`Document`](upsource:///platform/core-api/src/com/intellij/openapi/editor/Document.java) is an editable sequence of Unicode characters, typically corresponding to the text contents of a [virtual file](virtual_file.md).
|
A [`Document`](%gh-ic%/platform/core-api/src/com/intellij/openapi/editor/Document.java) is an editable sequence of Unicode characters, typically corresponding to the text contents of a [virtual file](virtual_file.md).
|
||||||
|
|
||||||
Line breaks in a document are _always_ normalized to `\n`.
|
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.
|
The IntelliJ Platform handles encoding and line break conversions when loading and saving documents transparently.
|
||||||
@ -11,9 +11,9 @@ The IntelliJ Platform handles encoding and line break conversions when loading a
|
|||||||
|
|
||||||
| Context | API |
|
| Context | API |
|
||||||
|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [Action](basic_action_system.md) | [`AnActionEvent.getData(CommonDataKeys.EDITOR).getDocument()`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) |
|
| [Action](basic_action_system.md) | [`AnActionEvent.getData(CommonDataKeys.EDITOR).getDocument()`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) |
|
||||||
| [PSI File](psi_files.md) | [`PsiDocumentManager.getDocument()`/`getCachedDocument()`](upsource:///platform/core-api/src/com/intellij/psi/PsiDocumentManager.java) |
|
| [PSI File](psi_files.md) | [`PsiDocumentManager.getDocument()`/`getCachedDocument()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java) |
|
||||||
| [Virtual File](virtual_file.md) | [`FileDocumentManager.getDocument()`](upsource:///platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java) (forces the document content to be loaded from a disk if it wasn't loaded previously)<br/>[`FileDocumentManager.getCachedDocument()`](upsource:///platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java) (use if only open or possibly modified documents are relevant) |
|
| [Virtual File](virtual_file.md) | [`FileDocumentManager.getDocument()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java) (forces the document content to be loaded from a disk if it wasn't loaded previously)<br/>[`FileDocumentManager.getCachedDocument()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java) (use if only open or possibly modified documents are relevant) |
|
||||||
|
|
||||||
## What can I do with a Document?
|
## What can I do with a Document?
|
||||||
|
|
||||||
@ -36,23 +36,23 @@ Thus, an unmodified `Document` instance can be garbage-collected if no one refer
|
|||||||
## How do I create a Document?
|
## How do I create a Document?
|
||||||
|
|
||||||
For creating a new file on disk, please do not create a `Document` but a PSI file and get its `Document` (see [](psi_files.md#how-do-i-create-a-psi-file)).
|
For creating a new file on disk, please do not create a `Document` but a PSI file and get its `Document` (see [](psi_files.md#how-do-i-create-a-psi-file)).
|
||||||
To create a `Document` instance that isn't bound to anything, use [`EditorFactory.createDocument()`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/EditorFactory.java).
|
To create a `Document` instance that isn't bound to anything, use [`EditorFactory.createDocument()`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/editor/EditorFactory.java).
|
||||||
|
|
||||||
## How do I get notified when Documents change?
|
## How do I get notified when Documents change?
|
||||||
|
|
||||||
* `Document.addDocumentListener()` allows receiving notifications about changes in a particular `Document` instance.
|
* `Document.addDocumentListener()` allows receiving notifications about changes in a particular `Document` instance.
|
||||||
* `EditorFactory.getEventMulticaster().addDocumentListener()` allows receiving notifications about changes in all open documents.
|
* `EditorFactory.getEventMulticaster().addDocumentListener()` allows receiving notifications about changes in all open documents.
|
||||||
* Register [`FileDocumentManagerListener`](upsource:///platform/platform-api/src/com/intellij/openapi/fileEditor/FileDocumentManagerListener.java) [listener](plugin_listeners.md) or subscribe to `AppTopics.FILE_DOCUMENT_SYNC` on any level bus to receive notifications when a `Document` is saved or reloaded from disk.
|
* Register [`FileDocumentManagerListener`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/fileEditor/FileDocumentManagerListener.java) [listener](plugin_listeners.md) or subscribe to `AppTopics.FILE_DOCUMENT_SYNC` on any level bus to receive notifications when a `Document` is saved or reloaded from disk.
|
||||||
|
|
||||||
## What are the rules of working with Documents?
|
## What are the rules of working with Documents?
|
||||||
|
|
||||||
The general read/write action rules are in effect (see [](general_threading_rules.md)).
|
The general read/write action rules are in effect (see [](general_threading_rules.md)).
|
||||||
Besides, any operations which modify the contents of the document must be wrapped in a command ([`CommandProcessor.executeCommand()`](upsource:///platform/core-api/src/com/intellij/openapi/command/CommandProcessor.java)).
|
Besides, any operations which modify the contents of the document must be wrapped in a command ([`CommandProcessor.executeCommand()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/command/CommandProcessor.java)).
|
||||||
`executeCommand()` calls can be nested, and the outermost `executeCommand()` call is added to the undo stack.
|
`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 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.
|
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.ensureFilesWritable()`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java) to check out the file.
|
Thus, before modifying the `Document`, it is necessary to call [`ReadonlyStatusHandler.ensureFilesWritable()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java) to check out the file.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
@ -60,6 +60,6 @@ See also [Working with Text](working_with_text.md#safely-replacing-selected-text
|
|||||||
|
|
||||||
## Are there any utilities available for working with Documents?
|
## Are there any utilities available for working with Documents?
|
||||||
|
|
||||||
[`DocumentUtil`](upsource:///platform/core-impl/src/com/intellij/util/DocumentUtil.java) contains utility methods for `Document` processing.
|
[`DocumentUtil`](%gh-ic%/platform/core-impl/src/com/intellij/util/DocumentUtil.java) contains utility methods for `Document` processing.
|
||||||
This allows you to get information like the text offsets of particular lines.
|
This allows you to get information like the text offsets of particular lines.
|
||||||
This is particularly useful when you need text location/offset information about a given `PsiElement`.
|
This is particularly useful when you need text location/offset information about a given `PsiElement`.
|
||||||
|
@ -13,24 +13,24 @@ Their two main applications inside the IntelliJ Platform are:
|
|||||||
1. Specifying where auto-completion should occur when implementing [a completion contributor](completion_contributor.md) for a custom language.
|
1. Specifying where auto-completion should occur when implementing [a completion contributor](completion_contributor.md) for a custom language.
|
||||||
2. Specifying PSI elements that provide further references via [a PSI reference contributor](psi_references.md#contributed-references).
|
2. Specifying PSI elements that provide further references via [a PSI reference contributor](psi_references.md#contributed-references).
|
||||||
|
|
||||||
However, plugin authors rarely implement the [`ElementPattern`](upsource:///platform/core-api/src/com/intellij/patterns/ElementPattern.java) interface directly.
|
However, plugin authors rarely implement the [`ElementPattern`](%gh-ic%/platform/core-api/src/com/intellij/patterns/ElementPattern.java) interface directly.
|
||||||
Instead, we recommend using the high-level pattern classes provided by the IntelliJ Platform:
|
Instead, we recommend using the high-level pattern classes provided by the IntelliJ Platform:
|
||||||
|
|
||||||
| Class | Main Contents | Notable Examples |
|
| Class | Main Contents | Notable Examples |
|
||||||
|---------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|---------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [`StandardPatterns`](upsource:///platform/core-api/src/com/intellij/patterns/StandardPatterns.java) | Factory for string and char pattern (see below); Logical operations like and, or, not | [`LogbackReferenceContributor`](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/ext/logback/LogbackReferenceContributor.kt), [`RegExpCompletionContributor`](upsource:///RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java) |
|
| [`StandardPatterns`](%gh-ic%/platform/core-api/src/com/intellij/patterns/StandardPatterns.java) | Factory for string and char pattern (see below); Logical operations like and, or, not | [`LogbackReferenceContributor`](%gh-ic%/plugins/groovy/src/org/jetbrains/plugins/groovy/ext/logback/LogbackReferenceContributor.kt), [`RegExpCompletionContributor`](%gh-ic%/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java) |
|
||||||
| [`PlatformPatterns`](upsource:///platform/core-api/src/com/intellij/patterns/PlatformPatterns.java) | Factory for PSI-, IElement-, and VirtualFile-patterns | [`FxmlReferencesContributor`](upsource:///plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java), [`PyDataclassCompletionContributor`](upsource:///python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyDataclassCompletionContributor.kt) |
|
| [`PlatformPatterns`](%gh-ic%/platform/core-api/src/com/intellij/patterns/PlatformPatterns.java) | Factory for PSI-, IElement-, and VirtualFile-patterns | [`FxmlReferencesContributor`](%gh-ic%/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java), [`PyDataclassCompletionContributor`](%gh-ic%/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyDataclassCompletionContributor.kt) |
|
||||||
| [`PsiElementPattern`](upsource:///platform/core-api/src/com/intellij/patterns/PsiElementPattern.java) | Patterns for PSI; Checks for children, parents, or neighboring leaves | [`XmlCompletionContributor`](upsource:///xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java) |
|
| [`PsiElementPattern`](%gh-ic%/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java) | Patterns for PSI; Checks for children, parents, or neighboring leaves | [`XmlCompletionContributor`](%gh-ic%/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java) |
|
||||||
| [`CollectionPattern`](upsource:///platform/core-api/src/com/intellij/patterns/CollectionPattern.java) | Filter and check pattern collections; Mainly used to provide functionality for other high-level pattern classes | [`PsiElementPattern`](upsource:///platform/core-api/src/com/intellij/patterns/PsiElementPattern.java) |
|
| [`CollectionPattern`](%gh-ic%/platform/core-api/src/com/intellij/patterns/CollectionPattern.java) | Filter and check pattern collections; Mainly used to provide functionality for other high-level pattern classes | [`PsiElementPattern`](%gh-ic%/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java) |
|
||||||
| [`TreeElementPattern`](upsource:///platform/core-api/src/com/intellij/patterns/TreeElementPattern.java) | Patterns specifically for checking (PSI) tree structure | [`PyMetaClassCompletionContributor`](upsource:///python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyMetaClassCompletionContributor.java) |
|
| [`TreeElementPattern`](%gh-ic%/platform/core-api/src/com/intellij/patterns/TreeElementPattern.java) | Patterns specifically for checking (PSI) tree structure | [`PyMetaClassCompletionContributor`](%gh-ic%/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyMetaClassCompletionContributor.java) |
|
||||||
| [`StringPattern`](upsource:///platform/core-api/src/com/intellij/patterns/StringPattern.java) | Check if strings match, have a certain length, have a specific beginning or ending, or are one of a collection of strings | [`AbstractGradleCompletionContributor`](upsource:///plugins/gradle/java/src/codeInsight/AbstractGradleCompletionContributor.kt) |
|
| [`StringPattern`](%gh-ic%/platform/core-api/src/com/intellij/patterns/StringPattern.java) | Check if strings match, have a certain length, have a specific beginning or ending, or are one of a collection of strings | [`AbstractGradleCompletionContributor`](%gh-ic%/plugins/gradle/java/src/codeInsight/AbstractGradleCompletionContributor.kt) |
|
||||||
| [`CharPattern`](upsource:///platform/core-api/src/com/intellij/patterns/CharPattern.java) | Check if characters are whitespace, digits, or Java identifier parts | [`CompletionUtil`](upsource:///platform/analysis-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java) |
|
| [`CharPattern`](%gh-ic%/platform/core-api/src/com/intellij/patterns/CharPattern.java) | Check if characters are whitespace, digits, or Java identifier parts | [`CompletionUtil`](%gh-ic%/platform/analysis-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java) |
|
||||||
|
|
||||||
Some built-in languages in the IntelliJ Platform implement their own pattern classes and can provide additional examples:
|
Some built-in languages in the IntelliJ Platform implement their own pattern classes and can provide additional examples:
|
||||||
|
|
||||||
- [`XmlPatterns`](upsource:///xml/xml-psi-api/src/com/intellij/patterns/XmlPatterns.java) provides patterns for XML attributes, values, entities, and texts.
|
- [`XmlPatterns`](%gh-ic%/xml/xml-psi-api/src/com/intellij/patterns/XmlPatterns.java) provides patterns for XML attributes, values, entities, and texts.
|
||||||
- [`PythonPatterns`](upsource:///python/src/com/jetbrains/python/patterns/PythonPatterns.java) provides patterns for literals, strings, arguments, and function/method arguments for Python.
|
- [`PythonPatterns`](%gh-ic%/python/src/com/jetbrains/python/patterns/PythonPatterns.java) provides patterns for literals, strings, arguments, and function/method arguments for Python.
|
||||||
- [`DomPatterns`](upsource:///xml/dom-openapi/src/com/intellij/patterns/DomPatterns.java) builds upon `XmlPatterns` and acts as a wrapper to provide further patterns for [DOM-API](xml_dom_api.md).
|
- [`DomPatterns`](%gh-ic%/xml/dom-openapi/src/com/intellij/patterns/DomPatterns.java) builds upon `XmlPatterns` and acts as a wrapper to provide further patterns for [DOM-API](xml_dom_api.md).
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ They are used in the [completion](completion_contributor.md#define-a-completion-
|
|||||||
However, the IntelliJ Platform source code provides many more examples of element patterns for built-in languages like JSON, XML, Groovy, Markdown, and so on.
|
However, the IntelliJ Platform source code provides many more examples of element patterns for built-in languages like JSON, XML, Groovy, Markdown, and so on.
|
||||||
Checking the references in the table above or searching for usages of the high-level pattern classes will provide a comprehensive list that shows how element patterns are used in production code.
|
Checking the references in the table above or searching for usages of the high-level pattern classes will provide a comprehensive list that shows how element patterns are used in production code.
|
||||||
|
|
||||||
For instance, an example can be found in [`MarkdownReferenceProvider`](upsource:///plugins/markdown/core/src/org/intellij/plugins/markdown/lang/references/MarkdownReferenceProvider.java) that tests if a PSI element is an instance of the `MarkdownLinkDestinationImpl` class and appears in a Markdown file.
|
For instance, an example can be found in [`MarkdownReferenceProvider`](%gh-ic%/plugins/markdown/core/src/org/intellij/plugins/markdown/lang/references/MarkdownReferenceProvider.java) that tests if a PSI element is an instance of the `MarkdownLinkDestinationImpl` class and appears in a Markdown file.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
PsiElementPattern.Capture<MarkdownLinkDestinationImpl> linkDestinationCapture =
|
PsiElementPattern.Capture<MarkdownLinkDestinationImpl> linkDestinationCapture =
|
||||||
@ -48,7 +48,7 @@ PsiElementPattern.Capture<MarkdownLinkDestinationImpl> linkDestinationCapture =
|
|||||||
```
|
```
|
||||||
|
|
||||||
As shown in the code above, element patterns can be stacked and combined to create more complex conditions.
|
As shown in the code above, element patterns can be stacked and combined to create more complex conditions.
|
||||||
[`JsonCompletionContributor`](upsource:///json/src/com/intellij/json/codeinsight/JsonCompletionContributor.java) contains another example with more requirements on the PSI element.
|
[`JsonCompletionContributor`](%gh-ic%/json/src/com/intellij/json/codeinsight/JsonCompletionContributor.java) contains another example with more requirements on the PSI element.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
PsiElementPattern.Capture<PsiElement> AFTER_COMMA_OR_BRACKET_IN_ARRAY =
|
PsiElementPattern.Capture<PsiElement> AFTER_COMMA_OR_BRACKET_IN_ARRAY =
|
||||||
@ -112,5 +112,5 @@ toString().contains("MarkdownLinkDestinationImpl")
|
|||||||
```
|
```
|
||||||
|
|
||||||
Now start a debug session and open a Markdown file.
|
Now start a debug session and open a Markdown file.
|
||||||
When the breakpoint hits, the call stack in the [debug tool window](https://www.jetbrains.com/help/idea/debug-tool-window.html) shows that reference-providers are checked in the method `doGetReferencesFromProviders` within [`ReferenceProvidersRegistryImpl`](upsource:///platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistryImpl.java).
|
When the breakpoint hits, the call stack in the [debug tool window](https://www.jetbrains.com/help/idea/debug-tool-window.html) shows that reference-providers are checked in the method `doGetReferencesFromProviders` within [`ReferenceProvidersRegistryImpl`](%gh-ic%/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistryImpl.java).
|
||||||
This provides a good starting point for further investigation.
|
This provides a good starting point for further investigation.
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||||
|
|
||||||
A file view provider ([`FileViewProvider`](upsource:///platform/core-api/src/com/intellij/psi/FileViewProvider.java)) manages access to multiple PSI trees within a single file.
|
A file view provider ([`FileViewProvider`](%gh-ic%/platform/core-api/src/com/intellij/psi/FileViewProvider.java)) manages access to multiple PSI trees within a single file.
|
||||||
|
|
||||||
For example, a JSPX page has a separate PSI tree for the Java code in it (`PsiJavaFile`), a separate tree for the XML code (`XmlFile`), and a separate tree for JSP as a whole ([`JspFile`](upsource:///java/jsp-openapi/src/com/intellij/psi/jsp/JspFile.java)).
|
For example, a JSPX page has a separate PSI tree for the Java code in it (`PsiJavaFile`), a separate tree for the XML code (`XmlFile`), and a separate tree for JSP as a whole ([`JspFile`](%gh-ic%/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.
|
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.
|
||||||
|
|
||||||
@ -14,8 +14,8 @@ A `FileViewProvider` instance corresponds to a single `VirtualFile`, a single `D
|
|||||||
|
|
||||||
| Context | API |
|
| Context | API |
|
||||||
|---------------------------------|----------------------------------------------------------------------------------------------------------------------------|
|
|---------------------------------|----------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [PSI File](psi_files.md) | [`PsiFile.getViewProvider()`](upsource:///platform/core-api/src/com/intellij/psi/PsiFile.java) |
|
| [PSI File](psi_files.md) | [`PsiFile.getViewProvider()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiFile.java) |
|
||||||
| [Virtual File](virtual_file.md) | [`PsiManager.getInstance(project).findViewProvider()`](upsource:///platform/core-api/src/com/intellij/psi/PsiManager.java) |
|
| [Virtual File](virtual_file.md) | [`PsiManager.getInstance(project).findViewProvider()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiManager.java) |
|
||||||
|
|
||||||
## What can I do with a FileViewProvider?
|
## What can I do with a FileViewProvider?
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ A `FileViewProvider` instance corresponds to a single `VirtualFile`, a single `D
|
|||||||
|
|
||||||
To create a file type that has multiple interspersing trees for different languages, a plugin must contain an extension to the `com.intellij.fileType.fileViewProviderFactory` extension point.
|
To create a file type that has multiple interspersing trees for different languages, a plugin must contain an extension to the `com.intellij.fileType.fileViewProviderFactory` extension point.
|
||||||
|
|
||||||
Implement [`FileViewProviderFactory`](upsource:///platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java) and return your `FileViewProvider` implementation from `createFileViewProvider()` method.
|
Implement [`FileViewProviderFactory`](%gh-ic%/platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java) and return your `FileViewProvider` implementation from `createFileViewProvider()` method.
|
||||||
|
|
||||||
Register as follows in <path>plugin.xml</path>:
|
Register as follows in <path>plugin.xml</path>:
|
||||||
|
|
||||||
|
@ -17,18 +17,18 @@ You must not access the model outside a read or write action for the following s
|
|||||||
|
|
||||||
**Reading** data is allowed from any thread.
|
**Reading** data is allowed from any thread.
|
||||||
Reading data from the UI thread does not require any special effort.
|
Reading data from the UI thread does not require any special effort.
|
||||||
However, read operations performed from any other thread need to be wrapped in a read action by using `ApplicationManager.getApplication().runReadAction()` or, shorter, [`ReadAction`](upsource:///platform/core-api/src/com/intellij/openapi/application/ReadAction.java) `run()`/`compute()`.
|
However, read operations performed from any other thread need to be wrapped in a read action by using `ApplicationManager.getApplication().runReadAction()` or, shorter, [`ReadAction`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/ReadAction.java) `run()`/`compute()`.
|
||||||
The corresponding objects are not guaranteed to survive between several consecutive read actions.
|
The corresponding objects are not guaranteed to survive between several consecutive read actions.
|
||||||
As a rule of thumb, whenever starting a read action, check if the PSI/VFS/project/module is still valid.
|
As a rule of thumb, whenever starting a read action, check if the PSI/VFS/project/module is still valid.
|
||||||
|
|
||||||
**Writing** data is only allowed from the UI thread, and write operations always need to be wrapped in a write action with `ApplicationManager.getApplication().runWriteAction()` or, shorter, [`WriteAction`](upsource:///platform/core-api/src/com/intellij/openapi/application/WriteAction.java) `run()`/`compute()`.
|
**Writing** data is only allowed from the UI thread, and write operations always need to be wrapped in a write action with `ApplicationManager.getApplication().runWriteAction()` or, shorter, [`WriteAction`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/WriteAction.java) `run()`/`compute()`.
|
||||||
Modifying the model is only allowed from write-safe contexts, including user actions and `invokeLater()` calls from them (see the next section).
|
Modifying the model is only allowed from write-safe contexts, including user actions and `invokeLater()` calls from them (see the next section).
|
||||||
You may not modify PSI, VFS, or project model from inside UI renderers or `SwingUtilities.invokeLater()` calls.
|
You may not modify PSI, VFS, or project model from inside UI renderers or `SwingUtilities.invokeLater()` calls.
|
||||||
|
|
||||||
## Modality and `invokeLater()`
|
## Modality and `invokeLater()`
|
||||||
|
|
||||||
To pass control from a background thread to the [Event Dispatch Thread](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html) (EDT), instead of the standard `SwingUtilities.invokeLater()`, plugins should use `ApplicationManager.getApplication().invokeLater()`.
|
To pass control from a background thread to the [Event Dispatch Thread](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html) (EDT), instead of the standard `SwingUtilities.invokeLater()`, plugins should use `ApplicationManager.getApplication().invokeLater()`.
|
||||||
The latter API allows specifying the _modality state_ ([`ModalityState`](upsource:///platform/core-api/src/com/intellij/openapi/application/ModalityState.java)) for the call, i.e., the stack of modal dialogs under which the call is allowed to execute:
|
The latter API allows specifying the _modality state_ ([`ModalityState`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/ModalityState.java)) for the call, i.e., the stack of modal dialogs under which the call is allowed to execute:
|
||||||
|
|
||||||
#### `ModalityState.NON_MODAL`
|
#### `ModalityState.NON_MODAL`
|
||||||
The operation will be executed after all modal dialogs are closed.
|
The operation will be executed after all modal dialogs are closed.
|
||||||
@ -51,8 +51,8 @@ That way, it is run after all possible indexing processes have been completed.
|
|||||||
|
|
||||||
## Background Processes and `ProcessCanceledException`
|
## Background Processes and `ProcessCanceledException`
|
||||||
|
|
||||||
Background progresses are managed by [`ProgressManager`](upsource:///platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java) class, which has plenty of methods to execute the given code with a modal (dialog), non-modal (visible in the status bar), or invisible progress.
|
Background progresses are managed by [`ProgressManager`](%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java) class, which has plenty of methods to execute the given code with a modal (dialog), non-modal (visible in the status bar), or invisible progress.
|
||||||
In all cases, the code is executed on a background thread, which is associated with a [`ProgressIndicator`](upsource:///platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java) object.
|
In all cases, the code is executed on a background thread, which is associated with a [`ProgressIndicator`](%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java) object.
|
||||||
The current thread's indicator can be retrieved any time via `ProgressIndicatorProvider.getGlobalProgressIndicator()`.
|
The current thread's indicator can be retrieved any time via `ProgressIndicatorProvider.getGlobalProgressIndicator()`.
|
||||||
|
|
||||||
For visible progresses, threads can use `ProgressIndicator` to notify the user about current status: e.g., set text or visual fraction of the work done.
|
For visible progresses, threads can use `ProgressIndicator` to notify the user about current status: e.g., set text or visual fraction of the work done.
|
||||||
@ -60,9 +60,9 @@ For visible progresses, threads can use `ProgressIndicator` to notify the user a
|
|||||||
Progress indicators also provide means to handle cancellation of background processes, either by the user (pressing the _Cancel_ button) or from code (e.g., when the current operation becomes obsolete due to some changes in the project).
|
Progress indicators also provide means to handle cancellation of background processes, either by the user (pressing the _Cancel_ button) or from code (e.g., when the current operation becomes obsolete due to some changes in the project).
|
||||||
The progress can be marked as canceled by calling `ProgressIndicator.cancel()`.
|
The progress can be marked as canceled by calling `ProgressIndicator.cancel()`.
|
||||||
The process reacts to this by calling `ProgressIndicator.checkCanceled()` (or `ProgressManager.checkCanceled()` if no indicator instance at hand).
|
The process reacts to this by calling `ProgressIndicator.checkCanceled()` (or `ProgressManager.checkCanceled()` if no indicator instance at hand).
|
||||||
This call throws a special unchecked [`ProcessCanceledException`](upsource:///platform/util/base/src/com/intellij/openapi/progress/ProcessCanceledException.java) if the background process has been canceled.
|
This call throws a special unchecked [`ProcessCanceledException`](%gh-ic%/platform/util/base/src/com/intellij/openapi/progress/ProcessCanceledException.java) if the background process has been canceled.
|
||||||
|
|
||||||
All code working with PSI, or in other kinds of background processes, must be prepared for [`ProcessCanceledException`](upsource:///platform/util/base/src/com/intellij/openapi/progress/ProcessCanceledException.java) being thrown from any point.
|
All code working with PSI, or in other kinds of background processes, must be prepared for [`ProcessCanceledException`](%gh-ic%/platform/util/base/src/com/intellij/openapi/progress/ProcessCanceledException.java) being thrown from any point.
|
||||||
This exception should never be logged but rethrown, and it'll be handled in the infrastructure that started the process.
|
This exception should never be logged but rethrown, and it'll be handled in the infrastructure that started the process.
|
||||||
|
|
||||||
The `checkCanceled()` should be called often enough to guarantee the process's smooth cancellation.
|
The `checkCanceled()` should be called often enough to guarantee the process's smooth cancellation.
|
||||||
@ -88,7 +88,7 @@ The next time the background thread calls `checkCanceled()`, a `ProcessCanceledE
|
|||||||
|
|
||||||
There are two recommended ways of doing this:
|
There are two recommended ways of doing this:
|
||||||
|
|
||||||
* If on UI thread, call `ReadAction.nonBlocking()` which returns [`NonBlockingReadAction`](upsource:///platform/core-api/src/com/intellij/openapi/application/NonBlockingReadAction.java)
|
* If on UI thread, call `ReadAction.nonBlocking()` which returns [`NonBlockingReadAction`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/NonBlockingReadAction.java)
|
||||||
* If already in a background thread, use `ProgressManager.getInstance().runInReadActionWithWriteActionPriority()` in a loop, until it passes or the whole activity becomes obsolete.
|
* If already in a background thread, use `ProgressManager.getInstance().runInReadActionWithWriteActionPriority()` in a loop, until it passes or the whole activity becomes obsolete.
|
||||||
|
|
||||||
In both approaches, always check at the start of each read action, if the objects are still valid, and if the whole operation still makes sense (i.e., not canceled by the user, the project isn't closed, etc.).
|
In both approaches, always check at the start of each read action, if the objects are still valid, and if the whole operation still makes sense (i.e., not canceled by the user, the project isn't closed, etc.).
|
||||||
@ -110,6 +110,6 @@ Meanwhile, please try to speed up what you can in your plugin, it'll be benefici
|
|||||||
Don't do anything expensive inside event listeners.
|
Don't do anything expensive inside event listeners.
|
||||||
Ideally, you should only clear some caches.
|
Ideally, you should only clear some caches.
|
||||||
You can also schedule background processing of events, but be prepared that some new events might be delivered before your background processing starts, and thus the world might have changed by that moment or even in the middle of background processing.
|
You can also schedule background processing of events, but be prepared that some new events might be delivered before your background processing starts, and thus the world might have changed by that moment or even in the middle of background processing.
|
||||||
Consider using [`MergingUpdateQueue`](upsource:///platform/ide-core/src/com/intellij/util/ui/update/MergingUpdateQueue.java) and `ReadAction.nonBlocking()` to mitigate these issues.
|
Consider using [`MergingUpdateQueue`](%gh-ic%/platform/ide-core/src/com/intellij/util/ui/update/MergingUpdateQueue.java) and `ReadAction.nonBlocking()` to mitigate these issues.
|
||||||
|
|
||||||
Massive batches of VFS events can be pre-processed in background, see [`AsyncFileListener`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/AsyncFileListener.java) (2019.2 or later).
|
Massive batches of VFS events can be pre-processed in background, see [`AsyncFileListener`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/AsyncFileListener.java) (2019.2 or later).
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
The PSI is a read/write representation of the source code as a tree of elements corresponding to a source file's structure.
|
The PSI is a read/write representation of the source code as a tree of elements corresponding to a source file's structure.
|
||||||
You can modify the PSI by *adding*, *replacing*, and *deleting* PSI elements.
|
You can modify the PSI by *adding*, *replacing*, and *deleting* PSI elements.
|
||||||
|
|
||||||
To perform these operations, you use methods such as `PsiElement.add()`, `PsiElement.delete()`, and `PsiElement.replace()`, as well as other methods defined in the [`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) interface that let you process multiple elements in a single operation, or to specify the exact location in the tree where an element needs to be added.
|
To perform these operations, you use methods such as `PsiElement.add()`, `PsiElement.delete()`, and `PsiElement.replace()`, as well as other methods defined in the [`PsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) interface that let you process multiple elements in a single operation, or to specify the exact location in the tree where an element needs to be added.
|
||||||
|
|
||||||
Like document operations, PSI modifications need to be wrapped in a write action and in command (and can only be performed in the event dispatch thread).
|
Like document operations, PSI modifications need to be wrapped in a write action and in command (and can only be performed in the event dispatch thread).
|
||||||
See [the Documents article](documents.md#what-are-the-rules-of-working-with-documents) for more information on commands and write actions.
|
See [the Documents article](documents.md#what-are-the-rules-of-working-with-documents) for more information on commands and write actions.
|
||||||
@ -13,11 +13,11 @@ See [the Documents article](documents.md#what-are-the-rules-of-working-with-docu
|
|||||||
## Creating the New PSI
|
## Creating the New PSI
|
||||||
|
|
||||||
The PSI elements to add to the tree or replace existing PSI elements are usually *created from text*.
|
The PSI elements to add to the tree or replace existing PSI elements are usually *created from text*.
|
||||||
In the most general case, you use the `createFileFromText()` method of [`PsiFileFactory`](upsource:///platform/core-api/src/com/intellij/psi/PsiFileFactory.java) to create a new file that contains the code construct which you need to add to the tree or to use as a replacement for an existing element, traverse the resulting tree to locate the specific part that you need, and then pass that element to `add()` or `replace()`.
|
In the most general case, you use the `createFileFromText()` method of [`PsiFileFactory`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiFileFactory.java) to create a new file that contains the code construct which you need to add to the tree or to use as a replacement for an existing element, traverse the resulting tree to locate the specific part that you need, and then pass that element to `add()` or `replace()`.
|
||||||
See also [](psi_files.md#how-do-i-create-a-psi-file).
|
See also [](psi_files.md#how-do-i-create-a-psi-file).
|
||||||
|
|
||||||
Most languages provide factory methods that let you create specific code constructs more easily.
|
Most languages provide factory methods that let you create specific code constructs more easily.
|
||||||
For example, the [`PsiJavaParserFacade`](upsource:///java/java-psi-api/src/com/intellij/psi/PsiJavaParserFacade.java) class contains methods such as `createMethodFromText()`, which creates a Java method from the given text.
|
For example, the [`PsiJavaParserFacade`](%gh-ic%/java/java-psi-api/src/com/intellij/psi/PsiJavaParserFacade.java) class contains methods such as `createMethodFromText()`, which creates a Java method from the given text.
|
||||||
|
|
||||||
When you're implementing refactorings, [intentions](code_intentions.md), or inspection [quickfixes](code_inspections_and_intentions.md) that work with existing code, the text that you pass to the various `createFromText()` methods will combine hard-coded fragments and fragments of code taken from the existing file.
|
When you're implementing refactorings, [intentions](code_intentions.md), or inspection [quickfixes](code_inspections_and_intentions.md) that work with existing code, the text that you pass to the various `createFromText()` methods will combine hard-coded fragments and fragments of code taken from the existing file.
|
||||||
For small code fragments (individual identifiers), you can simply append the text from the existing code to the text of the code fragment you are building.
|
For small code fragments (individual identifiers), you can simply append the text from the existing code to the text of the code fragment you are building.
|
||||||
@ -69,13 +69,13 @@ This method ensures that the structure you've built is the same as what the pars
|
|||||||
|
|
||||||
When working with PSI modification functions, you should never create individual whitespace nodes (spaces or line breaks) from the text.
|
When working with PSI modification functions, you should never create individual whitespace nodes (spaces or line breaks) from the text.
|
||||||
Instead, all whitespace modifications are performed by the formatter, which follows the code style settings selected by the user.
|
Instead, all whitespace modifications are performed by the formatter, which follows the code style settings selected by the user.
|
||||||
Formatting is automatically performed at the end of every command, and if you need, you can also perform it manually using the `reformat(PsiElement)` method in the [`CodeStyleManager`](upsource:///platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java) class.
|
Formatting is automatically performed at the end of every command, and if you need, you can also perform it manually using the `reformat(PsiElement)` method in the [`CodeStyleManager`](%gh-ic%/platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java) class.
|
||||||
|
|
||||||
Also, when working with Java code (or with code in other languages with a similar import mechanism such as Groovy or Python), you should never create imports manually.
|
Also, when working with Java code (or with code in other languages with a similar import mechanism such as Groovy or Python), you should never create imports manually.
|
||||||
Instead, you should insert fully-qualified names into the code you're generating, and then call the `shortenClassReferences()` method in the [`JavaCodeStyleManager`](upsource:///java/java-psi-api/src/com/intellij/psi/codeStyle/JavaCodeStyleManager.java) (or the equivalent API for the language you're working with).
|
Instead, you should insert fully-qualified names into the code you're generating, and then call the `shortenClassReferences()` method in the [`JavaCodeStyleManager`](%gh-ic%/java/java-psi-api/src/com/intellij/psi/codeStyle/JavaCodeStyleManager.java) (or the equivalent API for the language you're working with).
|
||||||
This ensures that the imports are created according to the user's code style settings and inserted into the file's correct place.
|
This ensures that the imports are created according to the user's code style settings and inserted into the file's correct place.
|
||||||
|
|
||||||
## Combining PSI and Document Modifications
|
## Combining PSI and Document Modifications
|
||||||
|
|
||||||
In some cases, you need to perform a PSI modification and then to perform an operation on the document you've just modified through the PSI (for example, start a [live template](live_templates.md)).
|
In some cases, you need to perform a PSI modification and then to perform an operation on the document you've just modified through the PSI (for example, start a [live template](live_templates.md)).
|
||||||
To complete the PSI-based post-processing (such as formatting) and commit the changes to the document, call `doPostponedOperationsAndUnblockDocument()` on [`PsiDocumentManager`](upsource:///platform/core-api/src/com/intellij/psi/PsiDocumentManager.java) instance.
|
To complete the PSI-based post-processing (such as formatting) and commit the changes to the document, call `doPostponedOperationsAndUnblockDocument()` on [`PsiDocumentManager`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java) instance.
|
||||||
|
@ -31,7 +31,7 @@ file.accept(new JavaRecursiveElementVisitor() {
|
|||||||
In many cases, you can also use more specific APIs for top-down navigation.
|
In many cases, you can also use more specific APIs for top-down navigation.
|
||||||
For example, if you need to get a list of all methods in a Java class, you can use a visitor, but a much easier way to do that is calling `PsiClass.getMethods()`.
|
For example, if you need to get a list of all methods in a Java class, you can use a visitor, but a much easier way to do that is calling `PsiClass.getMethods()`.
|
||||||
|
|
||||||
[`PsiTreeUtil`](upsource:///platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java) contains a number of general-purpose, language-independent functions for PSI tree navigation, some of which (for example, `findChildrenOfType()`) perform top-down navigation.
|
[`PsiTreeUtil`](%gh-ic%/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java) contains a number of general-purpose, language-independent functions for PSI tree navigation, some of which (for example, `findChildrenOfType()`) perform top-down navigation.
|
||||||
|
|
||||||
## Bottom-Up Navigation
|
## Bottom-Up Navigation
|
||||||
|
|
||||||
@ -55,4 +55,4 @@ PsiMethod containingMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.clas
|
|||||||
PsiClass containingClass = containingMethod.getContainingClass();
|
PsiClass containingClass = containingMethod.getContainingClass();
|
||||||
```
|
```
|
||||||
|
|
||||||
To see how the navigation works in practice, please refer to the [code sample](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/psi_demo/src/main/java/org/intellij/sdk/psi/PsiNavigationDemoAction.java).
|
To see how the navigation works in practice, please refer to the [code sample](%gh-sdk-samples%/psi_demo/src/main/java/org/intellij/sdk/psi/PsiNavigationDemoAction.java).
|
||||||
|
@ -9,15 +9,15 @@ A PSI element, in its turn, can have child PSI elements.
|
|||||||
PSI elements and operations at the level of individual PSI elements are used to explore the source code's internal structure as it is interpreted by the IntelliJ Platform.
|
PSI elements and operations at the level of individual PSI elements are used to explore the source code's internal structure as it is interpreted by the IntelliJ Platform.
|
||||||
For example, you can use PSI elements to perform code analysis, such as [code inspections](https://www.jetbrains.com/help/idea/code-inspection.html) or [intention actions](https://www.jetbrains.com/idea/help/intention-actions.html).
|
For example, you can use PSI elements to perform code analysis, such as [code inspections](https://www.jetbrains.com/help/idea/code-inspection.html) or [intention actions](https://www.jetbrains.com/idea/help/intention-actions.html).
|
||||||
|
|
||||||
The [`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) class is the common base class for PSI elements.
|
The [`PsiElement`](%gh-ic%/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?
|
## How do I get a PSI element?
|
||||||
|
|
||||||
| Context | API |
|
| Context | API |
|
||||||
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [Action](basic_action_system.md) | [`AnActionEvent.getData(CommonDataKeys.PSI_ELEMENT)`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java)<br/>Note: If an editor is currently open and the element under caret is a [reference](psi_references.md), this will return the result of resolving the reference. |
|
| [Action](basic_action_system.md) | [`AnActionEvent.getData(CommonDataKeys.PSI_ELEMENT)`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java)<br/>Note: If an editor is currently open and the element under caret is a [reference](psi_references.md), this will return the result of resolving the reference. |
|
||||||
| [PSI File](psi_files.md) | [`PsiFile.findElementAt(offset)`](upsource:///platform/core-api/src/com/intellij/psi/PsiFile.java) - This returns a leaf element at the specified offset, normally a lexer token. Use `PsiTreeUtil.getParentOfType()` to find the element of the exact type.<br/>[`PsiRecursiveElementWalkingVisitor`](upsource:///platform/core-api/src/com/intellij/psi/PsiRecursiveElementWalkingVisitor.java) |
|
| [PSI File](psi_files.md) | [`PsiFile.findElementAt(offset)`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiFile.java) - This returns a leaf element at the specified offset, normally a lexer token. Use `PsiTreeUtil.getParentOfType()` to find the element of the exact type.<br/>[`PsiRecursiveElementWalkingVisitor`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiRecursiveElementWalkingVisitor.java) |
|
||||||
| [Reference](psi_references.md) | [`PsiReference.resolve()`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) |
|
| [Reference](psi_references.md) | [`PsiReference.resolve()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) |
|
||||||
|
|
||||||
## What can I do with PSI elements?
|
## What can I do with PSI elements?
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
A PSI (Program Structure Interface) file is the root of a structure representing a file's contents as a hierarchy of elements in a particular programming language.
|
A PSI (Program Structure Interface) file is the root of a structure representing a file's contents as a hierarchy of elements in a particular programming language.
|
||||||
|
|
||||||
The [`PsiFile`](upsource:///platform/core-api/src/com/intellij/psi/PsiFile.java) class is the common base class for all PSI files, while files in a specific language are usually represented by its subclasses. For example, the [`PsiJavaFile`](upsource:///java/java-psi-api/src/com/intellij/psi/PsiJavaFile.java) class represents a Java file, and the [`XmlFile`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlFile.java) class represents an XML file.
|
The [`PsiFile`](%gh-ic%/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`](%gh-ic%/java/java-psi-api/src/com/intellij/psi/PsiJavaFile.java) class represents a Java file, and the [`XmlFile`](%gh-ic%/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.
|
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.
|
||||||
|
|
||||||
@ -12,11 +12,11 @@ Unlike `VirtualFile` and `Document`, which have application scope (even if multi
|
|||||||
|
|
||||||
| Context | API |
|
| Context | API |
|
||||||
|----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [Action](basic_action_system.md) | [`AnActionEvent.getData(CommonDataKeys.PSI_FILE)`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) |
|
| [Action](basic_action_system.md) | [`AnActionEvent.getData(CommonDataKeys.PSI_FILE)`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) |
|
||||||
| [Document](documents.md) | [`PsiDocumentManager.getInstance(project).getPsiFile()`](upsource:///platform/core-api/src/com/intellij/psi/PsiDocumentManager.java) |
|
| [Document](documents.md) | [`PsiDocumentManager.getInstance(project).getPsiFile()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java) |
|
||||||
| [PSI Element](psi_elements.md) | [`PsiElement.getContainingFile()`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) (may return `null` if the PSI element is not contained in a file) |
|
| [PSI Element](psi_elements.md) | [`PsiElement.getContainingFile()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) (may return `null` if the PSI element is not contained in a file) |
|
||||||
| [Virtual File](virtual_file.md) | [`PsiManager.getInstance(project).findFile()`](upsource:///platform/core-api/src/com/intellij/psi/PsiManager.java) |
|
| [Virtual File](virtual_file.md) | [`PsiManager.getInstance(project).findFile()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiManager.java) |
|
||||||
| File Name | [`FilenameIndex.getFilesByName(project, name, scope)`](upsource:///platform/indexing-api/src/com/intellij/psi/search/FilenameIndex.java) |
|
| File Name | [`FilenameIndex.getFilesByName(project, name, scope)`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/search/FilenameIndex.java) |
|
||||||
|
|
||||||
## What can I do with a PSI file?
|
## What can I do with a PSI file?
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ See also [Navigating the PSI](navigating_psi.md).
|
|||||||
|
|
||||||
## Where does a PSI file come from?
|
## Where does a PSI file come from?
|
||||||
|
|
||||||
As PSI is language-dependent, PSI files are created using the [`Language`](upsource:///platform/core-api/src/com/intellij/lang/Language.java) instance:
|
As PSI is language-dependent, PSI files are created using the [`Language`](%gh-ic%/platform/core-api/src/com/intellij/lang/Language.java) instance:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
LanguageParserDefinitions.INSTANCE
|
LanguageParserDefinitions.INSTANCE
|
||||||
@ -50,16 +50,16 @@ Like documents, PSI files are weakly referenced from the corresponding `VirtualF
|
|||||||
|
|
||||||
## How do I create a PSI file?
|
## How do I create a PSI file?
|
||||||
|
|
||||||
The [`PsiFileFactory`](upsource:///platform/core-api/src/com/intellij/psi/PsiFileFactory.java) `createFileFromText()` method creates an in-memory PSI file with the specified contents.
|
The [`PsiFileFactory`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiFileFactory.java) `createFileFromText()` method creates an in-memory PSI file with the specified contents.
|
||||||
|
|
||||||
To save the PSI file to disk, use the [`PsiDirectory`](upsource:///platform/core-api/src/com/intellij/psi/PsiDirectory.java) `add()` method.
|
To save the PSI file to disk, use the [`PsiDirectory`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiDirectory.java) `add()` method.
|
||||||
|
|
||||||
## How do I get notified when PSI files change?
|
## 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.
|
`PsiManager.getInstance(project).addPsiTreeChangeListener()` allows you to receive notifications about all changes to the PSI tree of a project.
|
||||||
Alternatively, register [`PsiTreeChangeListener`](upsource:///platform/core-api/src/com/intellij/psi/PsiTreeChangeListener.java) in `com.intellij.psi.treeChangeListener` extension point.
|
Alternatively, register [`PsiTreeChangeListener`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiTreeChangeListener.java) in `com.intellij.psi.treeChangeListener` extension point.
|
||||||
|
|
||||||
> Please see [`PsiTreeChangeEvent`](upsource:///platform/core-api/src/com/intellij/psi/PsiTreeChangeEvent.java) Javadoc for common problems when dealing with PSI events.
|
> Please see [`PsiTreeChangeEvent`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiTreeChangeEvent.java) Javadoc for common problems when dealing with PSI events.
|
||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ Everything else, even if it's needed for resolve/highlighting purposes, can be a
|
|||||||
|
|
||||||
If stubs don't suit your case well (e.g., the information you need is large and/or very rarely needed, or you're developing a plugin for a language whose PSI you don't control), you can create a [custom index or gist](indexing_and_psi_stubs.md).
|
If stubs don't suit your case well (e.g., the information you need is large and/or very rarely needed, or you're developing a plugin for a language whose PSI you don't control), you can create a [custom index or gist](indexing_and_psi_stubs.md).
|
||||||
|
|
||||||
To ensure you're not loading AST accidentally, you can use [`AstLoadingFilter`](upsource:///platform/core-api/src/com/intellij/util/AstLoadingFilter.java) in production and `PsiManagerEx.setAssertOnFileLoadingFilter()` in tests.
|
To ensure you're not loading AST accidentally, you can use [`AstLoadingFilter`](%gh-ic%/platform/core-api/src/com/intellij/util/AstLoadingFilter.java) in production and `PsiManagerEx.setAssertOnFileLoadingFilter()` in tests.
|
||||||
|
|
||||||
The same applies to documents: only the ones opened in editors should be loaded.
|
The same applies to documents: only the ones opened in editors should be loaded.
|
||||||
Usually, you shouldn't need document contents (as most information can be retrieved from PSI).
|
Usually, you shouldn't need document contents (as most information can be retrieved from PSI).
|
||||||
@ -40,6 +40,6 @@ If you still need documents, then at least ensure you load them one by one and d
|
|||||||
|
|
||||||
Method calls such as `PsiElement.getReference(s)`, `PsiReference.resolve()` (and `multiResolve()` and other equivalents) or computation of expression types, type inference results, control flow graphs, etc. can be expensive.
|
Method calls such as `PsiElement.getReference(s)`, `PsiReference.resolve()` (and `multiResolve()` and other equivalents) or computation of expression types, type inference results, control flow graphs, etc. can be expensive.
|
||||||
To avoid paying this cost several times, the result of such computation can be cached and reused.
|
To avoid paying this cost several times, the result of such computation can be cached and reused.
|
||||||
Usually, [`CachedValue`](upsource:///platform/core-api/src/com/intellij/psi/util/CachedValue.java) works well for this purpose.
|
Usually, [`CachedValue`](%gh-ic%/platform/core-api/src/com/intellij/psi/util/CachedValue.java) works well for this purpose.
|
||||||
|
|
||||||
If the information you cache depends only on a subtree of the current PSI element (and nothing else: no resolve results or other files), you can cache it in a field in your `PsiElement` implementation and drop the cache in an override of `ASTDelegatePsiElement.subtreeChanged()`.
|
If the information you cache depends only on a subtree of the current PSI element (and nothing else: no resolve results or other files), you can cache it in a field in your `PsiElement` implementation and drop the cache in an override of `ASTDelegatePsiElement.subtreeChanged()`.
|
||||||
|
@ -21,7 +21,7 @@ Note that `String message` is not a reference and cannot be resolved.
|
|||||||
Instead, it's a _declaration_.
|
Instead, it's a _declaration_.
|
||||||
It does not refer to any name defined elsewhere; instead, it defines a name by itself.
|
It does not refer to any name defined elsewhere; instead, it defines a name by itself.
|
||||||
|
|
||||||
A reference is an instance of a class implementing the [`PsiReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) interface.
|
A reference is an instance of a class implementing the [`PsiReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) interface.
|
||||||
Note that references are distinct from PSI elements.
|
Note that references are distinct from PSI elements.
|
||||||
References created by a PSI element are returned from `PsiElement.getReferences()`, the underlying PSI element of a reference can be obtained from `PsiReference.getElement()`.
|
References created by a PSI element are returned from `PsiElement.getReferences()`, the underlying PSI element of a reference can be obtained from `PsiReference.getElement()`.
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ References are also often contributed to non-code files, such as XML or JSON.
|
|||||||
Contributing references is one of the most common ways to extend an existing language.
|
Contributing references is one of the most common ways to extend an existing language.
|
||||||
For example, your plugin can contribute references to Java code, even though the Java PSI is part of the platform and not defined in your plugin.
|
For example, your plugin can contribute references to Java code, even though the Java PSI is part of the platform and not defined in your plugin.
|
||||||
|
|
||||||
Implement [`PsiReferenceContributor`](upsource:///platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java) registered in `com.intellij.psi.referenceContributor` extension point.
|
Implement [`PsiReferenceContributor`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java) registered in `com.intellij.psi.referenceContributor` extension point.
|
||||||
|
|
||||||
Attribute `language` should be set to the Language ID where this contributor applies to.
|
Attribute `language` should be set to the Language ID where this contributor applies to.
|
||||||
The exact places to contribute references to are then specified using [Element Patterns](element_patterns.md) in calls to `PsiReferenceRegistrar.registerReferenceProvider()`.
|
The exact places to contribute references to are then specified using [Element Patterns](element_patterns.md) in calls to `PsiReferenceRegistrar.registerReferenceProvider()`.
|
||||||
@ -78,10 +78,10 @@ The second case is *polyvariant references*.
|
|||||||
Consider the case of a JavaScript program.
|
Consider the case of a JavaScript program.
|
||||||
JavaScript is a dynamically typed language, so the IDE cannot always precisely determine which method is being called at a particular location.
|
JavaScript is a dynamically typed language, so the IDE cannot always precisely determine which method is being called at a particular location.
|
||||||
To handle this, it provides a reference that can be resolved to multiple possible elements.
|
To handle this, it provides a reference that can be resolved to multiple possible elements.
|
||||||
Such references implement the [`PsiPolyVariantReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiPolyVariantReference.java) interface.
|
Such references implement the [`PsiPolyVariantReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiPolyVariantReference.java) interface.
|
||||||
|
|
||||||
For resolving a `PsiPolyVariantReference`, you call its `multiResolve()` method.
|
For resolving a `PsiPolyVariantReference`, you call its `multiResolve()` method.
|
||||||
The call returns an array of [`ResolveResult`](upsource:///platform/core-api/src/com/intellij/psi/ResolveResult.java) objects.
|
The call returns an array of [`ResolveResult`](%gh-ic%/platform/core-api/src/com/intellij/psi/ResolveResult.java) objects.
|
||||||
Each of the objects identifies a PSI element and also specifies whether the result is valid.
|
Each of the objects identifies a PSI element and also specifies whether the result is valid.
|
||||||
For example, suppose you have multiple Java method overloads and a call with arguments not matching any of the overloads.
|
For example, suppose you have multiple Java method overloads and a call with arguments not matching any of the overloads.
|
||||||
In that case, you will get back `ResolveResult` objects for all of the overloads, and `isValidResult()` returns `false` for all of them.
|
In that case, you will get back `ResolveResult` objects for all of the overloads, and `isValidResult()` returns `false` for all of them.
|
||||||
@ -91,8 +91,8 @@ In that case, you will get back `ResolveResult` objects for all of the overloads
|
|||||||
As you already know, resolving a reference means going from usage to the corresponding declaration.
|
As you already know, resolving a reference means going from usage to the corresponding declaration.
|
||||||
To perform the navigation in the opposite direction - from a declaration to its usages - perform a **references search**.
|
To perform the navigation in the opposite direction - from a declaration to its usages - perform a **references search**.
|
||||||
|
|
||||||
To perform a search using [`ReferencesSearch`](upsource:///platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java), specify the *element* to search for, and optionally other parameters such as the scope in which the reference needs to be searched.
|
To perform a search using [`ReferencesSearch`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java), specify the *element* to search for, and optionally other parameters such as the scope in which the reference needs to be searched.
|
||||||
The created [`Query`](upsource:///platform/core-api/src/com/intellij/util/Query.java) allows obtaining all results at once or iterating over the results one by one.
|
The created [`Query`](%gh-ic%/platform/core-api/src/com/intellij/util/Query.java) allows obtaining all results at once or iterating over the results one by one.
|
||||||
The latter allows stopping processing as soon as the first (matching) result has been found.
|
The latter allows stopping processing as soon as the first (matching) result has been found.
|
||||||
|
|
||||||
## Implementing References
|
## Implementing References
|
||||||
|
@ -21,7 +21,7 @@ For plugins, that should work for all JVM languages in the same way.
|
|||||||
Some known examples are:
|
Some known examples are:
|
||||||
* [Spring Framework](spring_api.md)
|
* [Spring Framework](spring_api.md)
|
||||||
* [Android Studio](android_studio.md)
|
* [Android Studio](android_studio.md)
|
||||||
* [Plugin DevKit](upsource:///plugins/devkit/devkit-core)
|
* [Plugin DevKit](%gh-ic%/plugins/devkit/devkit-core)
|
||||||
|
|
||||||
### Which languages are supported?
|
### Which languages are supported?
|
||||||
|
|
||||||
@ -33,19 +33,19 @@ Some known examples are:
|
|||||||
### What about modifying PSI?
|
### What about modifying PSI?
|
||||||
|
|
||||||
UAST is a read-only API.
|
UAST is a read-only API.
|
||||||
There are experimental [`UastCodeGenerationPlugin`](upsource:///uast/uast-common/src/org/jetbrains/uast/generate/UastCodeGenerationPlugin.kt) and [`JvmElementActionsFactory`](upsource:///java/java-analysis-api/src/com/intellij/lang/jvm/actions/JvmElementActionsFactory.kt) classes, but they are currently not recommended for external usage.
|
There are experimental [`UastCodeGenerationPlugin`](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/generate/UastCodeGenerationPlugin.kt) and [`JvmElementActionsFactory`](%gh-ic%/java/java-analysis-api/src/com/intellij/lang/jvm/actions/JvmElementActionsFactory.kt) classes, but they are currently not recommended for external usage.
|
||||||
|
|
||||||
## Working with UAST
|
## Working with UAST
|
||||||
|
|
||||||
The base element of UAST is [`UElement`](upsource:///uast/uast-common/src/org/jetbrains/uast/baseElements/UElement.kt).
|
The base element of UAST is [`UElement`](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/baseElements/UElement.kt).
|
||||||
All common base sub-interfaces are located in the [declarations](upsource:///uast/uast-common/src/org/jetbrains/uast/declarations) and [expressions](upsource:///uast/uast-common/src/org/jetbrains/uast/expressions) directories of the **uast** module.
|
All common base sub-interfaces are located in the [declarations](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/declarations) and [expressions](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/expressions) directories of the **uast** module.
|
||||||
|
|
||||||
All these sub-interfaces provide methods to get the information about common syntax elements:
|
All these sub-interfaces provide methods to get the information about common syntax elements:
|
||||||
[`UClass`](upsource:///uast/uast-common/src/org/jetbrains/uast/declarations/UClass.kt) about class declarations, [`UIfExpression`](upsource:///uast/uast-common/src/org/jetbrains/uast/controlStructures/UIfExpression.kt) about conditional expressions, and so on.
|
[`UClass`](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/declarations/UClass.kt) about class declarations, [`UIfExpression`](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/controlStructures/UIfExpression.kt) about conditional expressions, and so on.
|
||||||
|
|
||||||
### PSI to UAST Conversion
|
### PSI to UAST Conversion
|
||||||
|
|
||||||
To obtain UAST for given `PsiElement` of one of supported languages, use [`UastFacade`](upsource:///uast/uast-common/src/org/jetbrains/uast/UastContext.kt) class or [`UastContextKt.toUElement()`](upsource:///uast/uast-common/src/org/jetbrains/uast/UastContext.kt) method (`org.jetbrains.uast.toUElement` for Kotlin).
|
To obtain UAST for given `PsiElement` of one of supported languages, use [`UastFacade`](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/UastContext.kt) class or [`UastContextKt.toUElement()`](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/UastContext.kt) method (`org.jetbrains.uast.toUElement` for Kotlin).
|
||||||
|
|
||||||
To convert `PsiElement` to the specific `UElement`, use one of the following approaches:
|
To convert `PsiElement` to the specific `UElement`, use one of the following approaches:
|
||||||
|
|
||||||
@ -116,13 +116,13 @@ Note: both `sourcePsi` and `javaPsi` can be [converted](#psi-to-uast-conversion)
|
|||||||
|
|
||||||
In UAST there is no unified way to get _children_ of the `UElement` (though it is possible to get its parent via `UElement#uastParent`).
|
In UAST there is no unified way to get _children_ of the `UElement` (though it is possible to get its parent via `UElement#uastParent`).
|
||||||
Thus, the only way to walk the UAST as a tree is passing the
|
Thus, the only way to walk the UAST as a tree is passing the
|
||||||
[`UastVisitor`](upsource:///uast/uast-common/src/org/jetbrains/uast/visitor/UastVisitor.kt) to `UElement.accept()` method.
|
[`UastVisitor`](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/visitor/UastVisitor.kt) to `UElement.accept()` method.
|
||||||
|
|
||||||
Note: there is a convention in UAST-visitors that a visitor will not be passed to children if `visit*()` returns `true`.
|
Note: there is a convention in UAST-visitors that a visitor will not be passed to children if `visit*()` returns `true`.
|
||||||
Otherwise, `UastVisitor` will continue the walk into depth.
|
Otherwise, `UastVisitor` will continue the walk into depth.
|
||||||
|
|
||||||
`UastVisitor` can be converted to [`PsiElementVisitor`](upsource:///platform/core-api/src/com/intellij/psi/PsiElementVisitor.java) using [`UastVisitorAdapter`](upsource:///java/java-analysis-api/src/com/intellij/uast/UastVisitorAdapter.java)
|
`UastVisitor` can be converted to [`PsiElementVisitor`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElementVisitor.java) using [`UastVisitorAdapter`](%gh-ic%/java/java-analysis-api/src/com/intellij/uast/UastVisitorAdapter.java)
|
||||||
or [`UastHintedVisitorAdapter`](upsource:///java/java-analysis-api/src/com/intellij/uast/UastHintedVisitorAdapter.kt).
|
or [`UastHintedVisitorAdapter`](%gh-ic%/java/java-analysis-api/src/com/intellij/uast/UastHintedVisitorAdapter.kt).
|
||||||
The latter is preferable as it offers better performance and more predictable results.
|
The latter is preferable as it offers better performance and more predictable results.
|
||||||
|
|
||||||
As a general rule, it's recommended to abstain from using `UastVisitor`: if you don't need to process many `UElement`s of different types and if the structure of elements is not very important, then it is better to walk the PSI-tree using `PsiElementVisitor` and [convert](#psi-to-uast-conversion) each `PsiElement` to its corresponding UAST explicitly via `UastContext.toUElement()`.
|
As a general rule, it's recommended to abstain from using `UastVisitor`: if you don't need to process many `UElement`s of different types and if the structure of elements is not very important, then it is better to walk the PSI-tree using `PsiElementVisitor` and [convert](#psi-to-uast-conversion) each `PsiElement` to its corresponding UAST explicitly via `UastContext.toUElement()`.
|
||||||
@ -145,11 +145,11 @@ For really hard performance optimisation consider using `UastLanguagePlugin.getP
|
|||||||
|
|
||||||
### `ULiteralExpression` should not be used for strings
|
### `ULiteralExpression` should not be used for strings
|
||||||
|
|
||||||
[`ULiteralExpression`](upsource:///uast/uast-common/src/org/jetbrains/uast/expressions/ULiteralExpression.kt) represents
|
[`ULiteralExpression`](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/expressions/ULiteralExpression.kt) represents
|
||||||
literal values like numbers, booleans, and string.
|
literal values like numbers, booleans, and string.
|
||||||
Although string values are also literals, `ULiteralExpression` is not very handy to work with them.
|
Although string values are also literals, `ULiteralExpression` is not very handy to work with them.
|
||||||
For instance, it doesn't handle Kotlin's string interpolations.
|
For instance, it doesn't handle Kotlin's string interpolations.
|
||||||
To process string literals when evaluating their value or to perform language injection, use [`UInjectionHost`](upsource:///uast/uast-common/src/org/jetbrains/uast/expressions/UInjectionHost.kt) instead.
|
To process string literals when evaluating their value or to perform language injection, use [`UInjectionHost`](%gh-ic%/uast/uast-common/src/org/jetbrains/uast/expressions/UInjectionHost.kt) instead.
|
||||||
|
|
||||||
### `sourcePsi` and `javaPsi`, `psi` and `UElement` as PSI
|
### `sourcePsi` and `javaPsi`, `psi` and `UElement` as PSI
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ To inspect UAST Tree, invoke [internal action](enabling_internal.md) <menupath>T
|
|||||||
|
|
||||||
### Inspections
|
### Inspections
|
||||||
|
|
||||||
Use [`AbstractBaseUastLocalInspectionTool`](upsource:///java/java-analysis-api/src/com/intellij/codeInspection/AbstractBaseUastLocalInspectionTool.java) as base class and specify `language="UAST"` in registration.
|
Use [`AbstractBaseUastLocalInspectionTool`](%gh-ic%/java/java-analysis-api/src/com/intellij/codeInspection/AbstractBaseUastLocalInspectionTool.java) as base class and specify `language="UAST"` in registration.
|
||||||
If inspection targets only a subset of default types (`UFile`, `UClass`, `UField`, and `UMethod`), specify `UElement`s as hints in overloaded constructor to improve performance.
|
If inspection targets only a subset of default types (`UFile`, `UClass`, `UField`, and `UMethod`), specify `UElement`s as hints in overloaded constructor to improve performance.
|
||||||
|
|
||||||
### Line Marker
|
### Line Marker
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||||
|
|
||||||
A [`VirtualFile`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java) (VF) is the IntelliJ Platform's representation of a file in a [Virtual File System (VFS)](virtual_file_system.md).
|
A [`VirtualFile`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java) (VF) is the IntelliJ Platform's representation of a file in a [Virtual File System (VFS)](virtual_file_system.md).
|
||||||
|
|
||||||
Most commonly, a virtual file is a file in a local file system.
|
Most commonly, a virtual file is a file in a local file system.
|
||||||
However, the IntelliJ Platform 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.
|
However, the IntelliJ Platform 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.
|
||||||
@ -14,10 +14,10 @@ Contents of a `VirtualFile` are treated as a stream of bytes, but concepts like
|
|||||||
|
|
||||||
| Context | API |
|
| Context | API |
|
||||||
|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [Action](basic_action_system.md) | [`AnActionEvent.getData(PlatformDataKeys.VIRTUAL_FILE)`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java)<br/>[`AnActionEvent.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY)`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) for multiple selection |
|
| [Action](basic_action_system.md) | [`AnActionEvent.getData(PlatformDataKeys.VIRTUAL_FILE)`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java)<br/>[`AnActionEvent.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY)`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) for multiple selection |
|
||||||
| [Document](documents.md) | [`FileDocumentManager.getFile()`](upsource:///platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java) |
|
| [Document](documents.md) | [`FileDocumentManager.getFile()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java) |
|
||||||
| [PSI File](psi_files.md) | [`PsiFile.getVirtualFile()`](upsource:///platform/core-api/src/com/intellij/psi/PsiFile.java) (may return `null` if the PSI file exists only in memory) |
|
| [PSI File](psi_files.md) | [`PsiFile.getVirtualFile()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiFile.java) (may return `null` if the PSI file exists only in memory) |
|
||||||
| Local File System Path | [`LocalFileSystem.findFileByIoFile()`](upsource:///platform/analysis-api/src/com/intellij/openapi/vfs/LocalFileSystem.java)<br/>[`VirtualFileManager.findFileByNioPath()`/`refreshAndFindFileByNioPath()`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java) (2020.2+) |
|
| Local File System Path | [`LocalFileSystem.findFileByIoFile()`](%gh-ic%/platform/analysis-api/src/com/intellij/openapi/vfs/LocalFileSystem.java)<br/>[`VirtualFileManager.findFileByNioPath()`/`refreshAndFindFileByNioPath()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java) (2020.2+) |
|
||||||
|
|
||||||
## What can I do with it?
|
## What can I do with it?
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ If one needs to create a file through VFS, use `VirtualFile.createChildData()` t
|
|||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
Implement [`BulkFileListener`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/newvfs/BulkFileListener.java) and subscribe to the [message bus](messaging_infrastructure.md) topic `VirtualFileManager.VFS_CHANGES`.
|
Implement [`BulkFileListener`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/newvfs/BulkFileListener.java) and subscribe to the [message bus](messaging_infrastructure.md) topic `VirtualFileManager.VFS_CHANGES`.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@ -68,21 +68,21 @@ project.getMessageBus().connect().subscribe(VirtualFileManager.VFS_CHANGES,
|
|||||||
|
|
||||||
See [Message Infrastructure](messaging_infrastructure.md) and [Plugin Listeners](plugin_listeners.md) for more details.
|
See [Message Infrastructure](messaging_infrastructure.md) and [Plugin Listeners](plugin_listeners.md) for more details.
|
||||||
|
|
||||||
For a non-blocking alternative, starting with version 2019.2 of the platform, see [`AsyncFileListener`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/AsyncFileListener.java).
|
For a non-blocking alternative, starting with version 2019.2 of the platform, see [`AsyncFileListener`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/AsyncFileListener.java).
|
||||||
|
|
||||||
## Are there any utilities for analyzing and manipulating virtual files?
|
## Are there any utilities for analyzing and manipulating virtual files?
|
||||||
|
|
||||||
[`VfsUtil`](upsource:///platform/analysis-api/src/com/intellij/openapi/vfs/VfsUtil.java) and [`VfsUtilCore`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java) provide utility methods for analyzing files in the Virtual File System.
|
[`VfsUtil`](%gh-ic%/platform/analysis-api/src/com/intellij/openapi/vfs/VfsUtil.java) and [`VfsUtilCore`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java) provide utility methods for analyzing files in the Virtual File System.
|
||||||
|
|
||||||
For storing a large set of Virtual Files, use dedicated `VfsUtilCore.createCompactVirtualFileSet()`.
|
For storing a large set of Virtual Files, use dedicated `VfsUtilCore.createCompactVirtualFileSet()`.
|
||||||
|
|
||||||
Use [`ProjectLocator`](upsource:///platform/projectModel-api/src/com/intellij/openapi/project/ProjectLocator.java) to find the projects that contain a given virtual file.
|
Use [`ProjectLocator`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/project/ProjectLocator.java) to find the projects that contain a given virtual file.
|
||||||
|
|
||||||
## 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`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java) class (most likely you'll also need to implement `VirtualFile`), and register your implementation via `com.intellij.virtualFileSystem` extension point (2019.2 and later) or [application component](plugin_components.md) for earlier versions.
|
To provide an alternative file system implementation (for example, an FTP file system), implement the [`VirtualFileSystem`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java) class (most likely you'll also need to implement `VirtualFile`), and register your implementation via `com.intellij.virtualFileSystem` extension point (2019.2 and later) or [application component](plugin_components.md) for earlier versions.
|
||||||
|
|
||||||
To hook into operations performed in the local file system (for example, when developing a version control system integration that needs custom rename/move handling), implement [`LocalFileOperationsHandler`](upsource:///platform/analysis-api/src/com/intellij/openapi/vfs/LocalFileOperationsHandler.java) and register it via `LocalFileSystem.registerAuxiliaryFileOperationsHandler()`.
|
To hook into operations performed in the local file system (for example, when developing a version control system integration that needs custom rename/move handling), implement [`LocalFileOperationsHandler`](%gh-ic%/platform/analysis-api/src/com/intellij/openapi/vfs/LocalFileOperationsHandler.java) and register it via `LocalFileSystem.registerAuxiliaryFileOperationsHandler()`.
|
||||||
|
|
||||||
## What are the rules for working with VFS?
|
## What are the rules for working with VFS?
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ The [](grouping_action.md) tutorial demonstrates three types of groups that can
|
|||||||
|
|
||||||
## Action Implementation
|
## Action Implementation
|
||||||
|
|
||||||
An action is a class derived from the abstract class [`AnAction`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java).
|
An action is a class derived from the abstract class [`AnAction`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java).
|
||||||
The IntelliJ Platform calls methods of actions when a user interacts with a menu item or toolbar button.
|
The IntelliJ Platform calls methods of actions when a user interacts with a menu item or toolbar button.
|
||||||
|
|
||||||
> Classes based on `AnAction` must not have class fields of any kind.
|
> Classes based on `AnAction` must not have class fields of any kind.
|
||||||
@ -32,8 +32,8 @@ The IntelliJ Platform calls methods of actions when a user interacts with a menu
|
|||||||
Every IntelliJ Platform action should override `AnAction.update()` and must override `AnAction.actionPerformed()`.
|
Every IntelliJ Platform action should override `AnAction.update()` and must override `AnAction.actionPerformed()`.
|
||||||
* An action's method `AnAction.update()` is called by the IntelliJ Platform framework to update an action state.
|
* An action's method `AnAction.update()` is called by the IntelliJ Platform framework to update an action state.
|
||||||
The state (enabled, visible) of an action determines whether the action is available in the UI.
|
The state (enabled, visible) of an action determines whether the action is available in the UI.
|
||||||
An object of the [`AnActionEvent`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) type is passed to this method and contains information about the current context for the action.
|
An object of the [`AnActionEvent`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) type is passed to this method and contains information about the current context for the action.
|
||||||
Actions are made available by changing state in the [`Presentation`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java) object associated with the event context.
|
Actions are made available by changing state in the [`Presentation`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java) object associated with the event context.
|
||||||
As explained in [Overriding the `AnAction.update()` Method](#overriding-the-anactionupdate-method), it is vital `update()` methods _execute quickly_ and return execution to platform.
|
As explained in [Overriding the `AnAction.update()` Method](#overriding-the-anactionupdate-method), it is vital `update()` methods _execute quickly_ and return execution to platform.
|
||||||
* An action's method `AnAction.actionPerformed()` is called by the IntelliJ Platform if available and selected by the user.
|
* An action's method `AnAction.actionPerformed()` is called by the IntelliJ Platform if available and selected by the user.
|
||||||
This method does the heavy lifting for the action: it contains the code executed when the action gets invoked.
|
This method does the heavy lifting for the action: it contains the code executed when the action gets invoked.
|
||||||
@ -64,7 +64,7 @@ Implementors must ensure that changing presentation and availability status hand
|
|||||||
The `AnActionEvent` object passed to `update()` carries information about the current context for the action.
|
The `AnActionEvent` object passed to `update()` carries information about the current context for the action.
|
||||||
Context information is available from the methods of `AnActionEvent`, providing information such as the Presentation and whether the action is triggered by a Toolbar.
|
Context information is available from the methods of `AnActionEvent`, providing information such as the Presentation and whether the action is triggered by a Toolbar.
|
||||||
Additional context information is available using the method `AnActionEvent.getData()`.
|
Additional context information is available using the method `AnActionEvent.getData()`.
|
||||||
Keys defined e.g. in [`CommonDataKeys`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CommonDataKeys.java) are passed to the `getData()` method to retrieve objects such as `Project`, `Editor`, `PsiFile`, and other information.
|
Keys defined e.g. in [`CommonDataKeys`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CommonDataKeys.java) are passed to the `getData()` method to retrieve objects such as `Project`, `Editor`, `PsiFile`, and other information.
|
||||||
Accessing this information is relatively light-weight and is suited for `AnAction.update()`.
|
Accessing this information is relatively light-weight and is suited for `AnAction.update()`.
|
||||||
|
|
||||||
#### Enabling and Setting Visibility for an Action
|
#### Enabling and Setting Visibility for an Action
|
||||||
@ -90,11 +90,11 @@ The visibility of a disabled action in a menu depends on whether the host menu (
|
|||||||
See [Grouping Actions](#grouping-actions) for more information about the `compact` attribute and menu actions' visibility.
|
See [Grouping Actions](#grouping-actions) for more information about the `compact` attribute and menu actions' visibility.
|
||||||
|
|
||||||
> If an action is added to a toolbar, its `update()` can be called if there was any user activity or focus transfer.
|
> If an action is added to a toolbar, its `update()` can be called if there was any user activity or focus transfer.
|
||||||
> If the action's availability changes in the absence of these events, then call [`ActivityTracker.getInstance().inc()`](upsource:///platform/platform-api/src/com/intellij/ide/ActivityTracker.java) to notify the action subsystem to update all toolbar actions.
|
> If the action's availability changes in the absence of these events, then call [`ActivityTracker.getInstance().inc()`](%gh-ic%/platform/platform-api/src/com/intellij/ide/ActivityTracker.java) to notify the action subsystem to update all toolbar actions.
|
||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
An example of enabling a menu action based on whether a project is open is demonstrated in [`PopupDialogAction.update()`](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java) method.
|
An example of enabling a menu action based on whether a project is open is demonstrated in [`PopupDialogAction.update()`](%gh-sdk-samples%/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java) method.
|
||||||
|
|
||||||
### Overriding the AnAction.actionPerformed Method
|
### Overriding the AnAction.actionPerformed Method
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ For example, the `actionPerformed()` method can modify, remove, or add PSI eleme
|
|||||||
|
|
||||||
The code that executes in the `AnAction.actionPerformed()` method should execute efficiently, but it does not have to meet the same stringent requirements as the `update()` method.
|
The code that executes in the `AnAction.actionPerformed()` method should execute efficiently, but it does not have to meet the same stringent requirements as the `update()` method.
|
||||||
|
|
||||||
An example of inspecting PSI elements is demonstrated in the SDK code sample `action_basics` [`PopupDialogAction.actionPerformed()`](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java) method.
|
An example of inspecting PSI elements is demonstrated in the SDK code sample `action_basics` [`PopupDialogAction.actionPerformed()`](%gh-sdk-samples%/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java) method.
|
||||||
|
|
||||||
### Action IDs
|
### Action IDs
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ Basing the identifier for a custom action on the fully qualified name of the imp
|
|||||||
Including the plugin identifier in the action identifier should prevent it from clashing with other plugins' actions.
|
Including the plugin identifier in the action identifier should prevent it from clashing with other plugins' actions.
|
||||||
An action must have a unique identifier for each place.
|
An action must have a unique identifier for each place.
|
||||||
It is used in the IDE UI, even though the FQN of the implementation is the same.
|
It is used in the IDE UI, even though the FQN of the implementation is the same.
|
||||||
Definitions of identifiers for the standard IntelliJ Platform actions are in [`IdeActions`](upsource:///platform/ide-core/src/com/intellij/openapi/actionSystem/IdeActions.java).
|
Definitions of identifiers for the standard IntelliJ Platform actions are in [`IdeActions`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/actionSystem/IdeActions.java).
|
||||||
|
|
||||||
### Grouping Actions
|
### Grouping Actions
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ See the [Action Declaration Reference](#action-declaration-reference) section fo
|
|||||||
|
|
||||||
#### Presentation
|
#### Presentation
|
||||||
|
|
||||||
A new [`Presentation`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java) gets created for every place where the action appears.
|
A new [`Presentation`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java) gets created for every place where the action appears.
|
||||||
Therefore, the same action can have a different text or icon when it appears in different places of the user interface.
|
Therefore, the same action can have a different text or icon 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.
|
Different presentations for the action are created by copying the Presentation returned by the `AnAction.getTemplatePresentation()` method.
|
||||||
|
|
||||||
@ -256,8 +256,8 @@ If `<override-text>` is used for a group `id`, the key includes the `<place>` at
|
|||||||
|
|
||||||
#### Action Declaration Reference
|
#### Action Declaration Reference
|
||||||
|
|
||||||
The places where actions can appear are defined by constants in [`ActionPlaces`](upsource:///platform/ide-core/src/com/intellij/openapi/actionSystem/ActionPlaces.java).
|
The places where actions can appear are defined by constants in [`ActionPlaces`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/actionSystem/ActionPlaces.java).
|
||||||
Group IDs for the IntelliJ Platform are defined in [`PlatformActions.xml`](upsource:///platform/platform-resources/src/idea/PlatformActions.xml).
|
Group IDs for the IntelliJ Platform are defined in [`PlatformActions.xml`](%gh-ic%/platform/platform-resources/src/idea/PlatformActions.xml).
|
||||||
|
|
||||||
This, and additional information can also be found by using the [Code Completion](https://www.jetbrains.com/help/idea/auto-completing-code.html#invoke-basic-completion), [Quick Definition](https://www.jetbrains.com/help/idea/viewing-reference-information.html#view-definition-symbols) and [Quick Documentation](https://www.jetbrains.com/help/idea/viewing-reference-information.html#inline-quick-documentation) features.
|
This, and additional information can also be found by using the [Code Completion](https://www.jetbrains.com/help/idea/auto-completing-code.html#invoke-basic-completion), [Quick Definition](https://www.jetbrains.com/help/idea/viewing-reference-information.html#view-definition-symbols) and [Quick Documentation](https://www.jetbrains.com/help/idea/viewing-reference-information.html#inline-quick-documentation) features.
|
||||||
|
|
||||||
@ -455,13 +455,13 @@ This, and additional information can also be found by using the [Code Completion
|
|||||||
### Registering Actions from Code
|
### Registering Actions from Code
|
||||||
|
|
||||||
Two steps are required to register an action from code:
|
Two steps are required to register an action from code:
|
||||||
* First, an instance of the class derived from `AnAction` must be passed to the `registerAction()` method of [`ActionManager`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java), to associate the action with an ID.
|
* First, an instance of the class derived from `AnAction` must be passed to the `registerAction()` method of [`ActionManager`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java), to associate the action with an ID.
|
||||||
* Second, the action needs to be added to one or more groups.
|
* 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 [`DefaultActionGroup`](upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java).
|
To get an instance of an action group by ID, it is necessary to call `ActionManager.getAction()` and cast the returned value to [`DefaultActionGroup`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java).
|
||||||
|
|
||||||
## Building UI from Actions
|
## Building UI from Actions
|
||||||
|
|
||||||
If a plugin needs to include a toolbar or popup menu built from a group of actions in its user interface, that is accomplished through [`ActionPopupMenu`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionPopupMenu.java) and [`ActionToolbar`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionToolbar.java).
|
If a plugin needs to include a toolbar or popup menu built from a group of actions in its user interface, that is accomplished through [`ActionPopupMenu`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionPopupMenu.java) and [`ActionToolbar`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionToolbar.java).
|
||||||
These objects can be created through calls to the `ActionManager.createActionPopupMenu()` and `createActionToolbar()` methods.
|
These objects can be created through calls to the `ActionManager.createActionPopupMenu()` and `createActionToolbar()` methods.
|
||||||
To get a Swing component from such an object, call the respective `getComponent()` method.
|
To get a Swing component from such an object, call the respective `getComponent()` method.
|
||||||
|
|
||||||
@ -474,18 +474,18 @@ See [Toolbar](https://jetbrains.design/intellij/controls/toolbar/) in IntelliJ P
|
|||||||
|
|
||||||
### Toggle/Selection
|
### Toggle/Selection
|
||||||
|
|
||||||
Use [`ToggleAction`](upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/ToggleAction.java)
|
Use [`ToggleAction`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/actionSystem/ToggleAction.java)
|
||||||
for actions with "selected"/"pressed" state (e.g., menu item with checkbox, toolbar action button).
|
for actions with "selected"/"pressed" state (e.g., menu item with checkbox, toolbar action button).
|
||||||
See also [`ToggleOptionAction`](upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/ToggleOptionAction.java).
|
See also [`ToggleOptionAction`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/actionSystem/ToggleOptionAction.java).
|
||||||
|
|
||||||
### Back/Forward Navigation
|
### Back/Forward Navigation
|
||||||
|
|
||||||
Use [`BackAction`](upsource:///platform/platform-api/src/com/intellij/ui/navigation/BackAction.java) and
|
Use [`BackAction`](%gh-ic%/platform/platform-api/src/com/intellij/ui/navigation/BackAction.java) and
|
||||||
[`ForwardAction`](upsource:///platform/platform-api/src/com/intellij/ui/navigation/ForwardAction.java) to provide navigation trail taken from
|
[`ForwardAction`](%gh-ic%/platform/platform-api/src/com/intellij/ui/navigation/ForwardAction.java) to provide navigation trail taken from
|
||||||
[`History`](upsource:///platform/platform-api/src/com/intellij/ui/navigation/History.java) provided by `History.KEY`.
|
[`History`](%gh-ic%/platform/platform-api/src/com/intellij/ui/navigation/History.java) provided by `History.KEY`.
|
||||||
|
|
||||||
### Runtime Placeholder Action
|
### Runtime Placeholder Action
|
||||||
|
|
||||||
For actions registered at runtime (e.g., in a tool window toolbar), add an `<action>` entry with
|
For actions registered at runtime (e.g., in a tool window toolbar), add an `<action>` entry with
|
||||||
[`EmptyAction`](upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java)
|
[`EmptyAction`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java)
|
||||||
to "reserve" Action ID so they become visible in <menupath>Settings/Preferences | Keymap</menupath>.
|
to "reserve" Action ID so they become visible in <menupath>Settings/Preferences | Keymap</menupath>.
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||||
|
|
||||||
The IntelliJ Platform's [`Disposer`](upsource:///platform/util/src/com/intellij/openapi/util/Disposer.java) facilitates resource cleanup.
|
The IntelliJ Platform's [`Disposer`](%gh-ic%/platform/util/src/com/intellij/openapi/util/Disposer.java) facilitates resource cleanup.
|
||||||
If a subsystem keeps a set of resources alive coincident with a parent object's lifetime, the subsystem's resources should be registered with the `Disposer` to be released before or at the same time as the parent object.
|
If a subsystem keeps a set of resources alive coincident with a parent object's lifetime, the subsystem's resources should be registered with the `Disposer` to be released before or at the same time as the parent object.
|
||||||
|
|
||||||
The most common resource type managed by `Disposer` is listeners, but there are other possible types:
|
The most common resource type managed by `Disposer` is listeners, but there are other possible types:
|
||||||
* File handles, and database connections,
|
* File handles, and database connections,
|
||||||
* Caches and other significant data structures.
|
* Caches and other significant data structures.
|
||||||
|
|
||||||
The `Disposer` is a singleton that manages a tree of [`Disposable`](upsource:///platform/util/src/com/intellij/openapi/Disposable.java) instances.
|
The `Disposer` is a singleton that manages a tree of [`Disposable`](%gh-ic%/platform/util/src/com/intellij/openapi/Disposable.java) instances.
|
||||||
A `Disposable` is an interface for any object providing a `Disposable.dispose()` method to release heavyweight resources after a specific lifetime.
|
A `Disposable` is an interface for any object providing a `Disposable.dispose()` method to release heavyweight resources after a specific lifetime.
|
||||||
|
|
||||||
The `Disposer` supports chaining `Disposables` in parent-child relationships.
|
The `Disposer` supports chaining `Disposables` in parent-child relationships.
|
||||||
@ -25,7 +25,7 @@ Note that extensions registered in <path>plugin.xml</path> are *not* automatical
|
|||||||
If an extension requires executing some code to dispose it, you need to define a service and to put the code in its `dispose()` method or use it as a parent disposable.
|
If an extension requires executing some code to dispose it, you need to define a service and to put the code in its `dispose()` method or use it as a parent disposable.
|
||||||
|
|
||||||
## The Disposer Singleton
|
## The Disposer Singleton
|
||||||
The primary purpose of the [`Disposer`](upsource:///platform/util/src/com/intellij/openapi/util/Disposer.java) singleton is to enforce the rule that _a child `Disposable` never outlives its parent_.
|
The primary purpose of the [`Disposer`](%gh-ic%/platform/util/src/com/intellij/openapi/util/Disposer.java) singleton is to enforce the rule that _a child `Disposable` never outlives its parent_.
|
||||||
|
|
||||||
The `Disposer` organizes `Disposable` objects in a tree of parent-child relationships.
|
The `Disposer` organizes `Disposable` objects in a tree of parent-child relationships.
|
||||||
The tree of `Disposable` objects ensures the `Disposer` releases children of a parent first.
|
The tree of `Disposable` objects ensures the `Disposer` releases children of a parent first.
|
||||||
@ -178,7 +178,7 @@ The following snippet represents the sort of "memory leak detected" error encoun
|
|||||||
>
|
>
|
||||||
{type="tip"}
|
{type="tip"}
|
||||||
|
|
||||||
In this specific case, the IntelliJ Platform ([`CoreProgressManager`](upsource:///platform/core-impl/src/com/intellij/openapi/progress/impl/CoreProgressManager.java)) started a task that contained the `DynamicWizard` code.
|
In this specific case, the IntelliJ Platform ([`CoreProgressManager`](%gh-ic%/platform/core-impl/src/com/intellij/openapi/progress/impl/CoreProgressManager.java)) started a task that contained the `DynamicWizard` code.
|
||||||
In turn, that code allocated a `Project` that was never disposed by the time the application exited.
|
In turn, that code allocated a `Project` that was never disposed by the time the application exited.
|
||||||
That is a promising place to start digging.
|
That is a promising place to start digging.
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ Use the following checklist to ensure that you are ready to develop your custom
|
|||||||
For more information, see below.
|
For more information, see below.
|
||||||
- (_Optional_) **Get IntelliJ IDEA CE source code** on your local computer.
|
- (_Optional_) **Get IntelliJ IDEA CE source code** on your local computer.
|
||||||
Getting IntelliJ IDEA CE source code is not a requirement for plugin development, but having it makes debugging your plugins much more straightforward.
|
Getting IntelliJ IDEA CE source code is not a requirement for plugin development, but having it makes debugging your plugins much more straightforward.
|
||||||
For detailed instructions, refer to the _Getting IntelliJ IDEA Community Edition Source Code_ section of [Check Out And Build Community Edition](upsource:///README.md).
|
For detailed instructions, refer to the _Getting IntelliJ IDEA Community Edition Source Code_ section of [Check Out And Build Community Edition](%gh-ic%/README.md).
|
||||||
Note that building IntelliJ IDEA CE from source code is not required for plugin development.
|
Note that building IntelliJ IDEA CE from source code is not required for plugin development.
|
||||||
|
|
||||||
### Configuring IntelliJ Platform SDK
|
### Configuring IntelliJ Platform SDK
|
||||||
@ -24,7 +24,7 @@ Use the following checklist to ensure that you are ready to develop your custom
|
|||||||
To set up your plugin development environment:
|
To set up your plugin development environment:
|
||||||
|
|
||||||
* Set up a required Java SDK.
|
* Set up a required Java SDK.
|
||||||
See the _IntelliJ Build Configuration_ section of [Check Out And Build Community Edition](upsource:///README.md) for instructions about creating **1.8** (**11** when targeting 2020.3 or later) Java SDK.
|
See the _IntelliJ Build Configuration_ section of [Check Out And Build Community Edition](%gh-ic%/README.md) for instructions about creating **1.8** (**11** when targeting 2020.3 or later) Java SDK.
|
||||||
|
|
||||||
> Do not use a more recent Java version than the one specified.
|
> Do not use a more recent Java version than the one specified.
|
||||||
>
|
>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
The IntelliJ platform uses [`Logger`](upsource:///platform/util/src/com/intellij/openapi/diagnostic/Logger.java) abstraction class to shield from underlying logging implementation and configuration.
|
The IntelliJ platform uses [`Logger`](%gh-ic%/platform/util/src/com/intellij/openapi/diagnostic/Logger.java) abstraction class to shield from underlying logging implementation and configuration.
|
||||||
|
|
||||||
Plugins should obtain a dedicated instance:
|
Plugins should obtain a dedicated instance:
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ See [Development Instance Sandbox Directory](ide_development_instance.md#the-dev
|
|||||||
|
|
||||||
See [Testing FAQ](testing_faq.md) on how to enable `DEBUG`/`TRACE` level logging during tests, and obtain separate logs for failing tests.
|
See [Testing FAQ](testing_faq.md) on how to enable `DEBUG`/`TRACE` level logging during tests, and obtain separate logs for failing tests.
|
||||||
|
|
||||||
To provide additional context for [reporting fatal errors](#error-reporting), use `Logger.error()` methods taking additional `Attachment` (see [`AttachmentFactory`](upsource:///platform/core-impl/src/com/intellij/diagnostic/AttachmentFactory.java)).
|
To provide additional context for [reporting fatal errors](#error-reporting), use `Logger.error()` methods taking additional `Attachment` (see [`AttachmentFactory`](%gh-ic%/platform/core-impl/src/com/intellij/diagnostic/AttachmentFactory.java)).
|
||||||
|
|
||||||
## Error Reporting
|
## Error Reporting
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ The IDE will show fatal errors caught by itself as well as logging messages with
|
|||||||
|
|
||||||
For the latter, reporting is disabled by default — instead, there's an option to disable the plugin causing the exception.
|
For the latter, reporting is disabled by default — instead, there's an option to disable the plugin causing the exception.
|
||||||
|
|
||||||
To let users report such errors to the vendor, plugins can implement custom [`ErrorReportSubmitter`](upsource:///platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java) registered in `com.intellij.errorHandler` extension point.
|
To let users report such errors to the vendor, plugins can implement custom [`ErrorReportSubmitter`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java) registered in `com.intellij.errorHandler` extension point.
|
||||||
See [IntelliJ Platform Explorer](https://jb.gg/ipe?extensions=com.intellij.errorHandler) for existing implementations — ranging from pre-filling web-based issue tracker forms to fully automated submission to log monitoring systems.
|
See [IntelliJ Platform Explorer](https://jb.gg/ipe?extensions=com.intellij.errorHandler) for existing implementations — ranging from pre-filling web-based issue tracker forms to fully automated submission to log monitoring systems.
|
||||||
This [tutorial](https://www.plugin-dev.com/intellij/general/error-reporting/) also offers a working solution for using _Sentry_.
|
This [tutorial](https://www.plugin-dev.com/intellij/general/error-reporting/) also offers a working solution for using _Sentry_.
|
||||||
|
|
||||||
@ -87,41 +87,41 @@ To disable red exclamation notification icon in status bar, invoke <menupath>Hel
|
|||||||
|
|
||||||
## Runtime Information
|
## Runtime Information
|
||||||
|
|
||||||
[`ApplicationInfo`](upsource:///platform/core-api/src/com/intellij/openapi/application/ApplicationInfo.java) provides information on the IDE version and vendor.
|
[`ApplicationInfo`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/ApplicationInfo.java) provides information on the IDE version and vendor.
|
||||||
NOTE: to restrict compatibility, declare [IDEs](plugin_compatibility.md) and [versions](build_number_ranges.md) via <path>plugin.xml</path>.
|
NOTE: to restrict compatibility, declare [IDEs](plugin_compatibility.md) and [versions](build_number_ranges.md) via <path>plugin.xml</path>.
|
||||||
|
|
||||||
To obtain information about OS and Java VM, use [`SystemInfo`](upsource:///platform/util/src/com/intellij/openapi/util/SystemInfo.java).
|
To obtain information about OS and Java VM, use [`SystemInfo`](%gh-ic%/platform/util/src/com/intellij/openapi/util/SystemInfo.java).
|
||||||
|
|
||||||
To access relevant configuration directories, see [`PathManager`](upsource:///platform/util/src/com/intellij/openapi/application/PathManager.java).
|
To access relevant configuration directories, see [`PathManager`](%gh-ic%/platform/util/src/com/intellij/openapi/application/PathManager.java).
|
||||||
|
|
||||||
To obtain unique installation UUID, use [`PermanentInstallationID`](upsource:///platform/platform-impl/src/com/intellij/openapi/application/PermanentInstallationID.java).
|
To obtain unique installation UUID, use [`PermanentInstallationID`](%gh-ic%/platform/platform-impl/src/com/intellij/openapi/application/PermanentInstallationID.java).
|
||||||
|
|
||||||
## Context Help
|
## Context Help
|
||||||
|
|
||||||
To show custom context web-based help for your plugin's functionality (e.g., for [dialogs](dialog_wrapper.md)), provide [`WebHelpProvider`](upsource:///platform/platform-api/src/com/intellij/openapi/help/WebHelpProvider.java) registered in `com.intellij.webHelpProvider` extension point.
|
To show custom context web-based help for your plugin's functionality (e.g., for [dialogs](dialog_wrapper.md)), provide [`WebHelpProvider`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/help/WebHelpProvider.java) registered in `com.intellij.webHelpProvider` extension point.
|
||||||
|
|
||||||
## Running Tasks Once
|
## Running Tasks Once
|
||||||
|
|
||||||
Use [`RunOnceUtil`](upsource:///platform/ide-core/src/com/intellij/ide/util/RunOnceUtil.java) to run a task exactly once per project/application.
|
Use [`RunOnceUtil`](%gh-ic%/platform/ide-core/src/com/intellij/ide/util/RunOnceUtil.java) to run a task exactly once per project/application.
|
||||||
|
|
||||||
## Application Events
|
## Application Events
|
||||||
|
|
||||||
Application lifecycle events can be tracked via [`AppLifecycleListener`](upsource:///platform/platform-impl/src/com/intellij/ide/AppLifecycleListener.java) [listener](plugin_listeners.md).
|
Application lifecycle events can be tracked via [`AppLifecycleListener`](%gh-ic%/platform/platform-impl/src/com/intellij/ide/AppLifecycleListener.java) [listener](plugin_listeners.md).
|
||||||
See also [](plugin_components.md#application-startup) and [](plugin_components.md#project-and-application-close).
|
See also [](plugin_components.md#application-startup) and [](plugin_components.md#project-and-application-close).
|
||||||
|
|
||||||
Register [`ApplicationActivationListener`](upsource:///platform/ide-core/src/com/intellij/openapi/application/ApplicationActivationListener.java) [listener](plugin_listeners.md) to be notified of "application focused/unfocused" events.
|
Register [`ApplicationActivationListener`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/application/ApplicationActivationListener.java) [listener](plugin_listeners.md) to be notified of "application focused/unfocused" events.
|
||||||
|
|
||||||
## Plugin Management
|
## Plugin Management
|
||||||
|
|
||||||
Currently, installed plugins can be checked via [`PluginManagerCore.isPluginInstalled()`](upsource:///platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java).
|
Currently, installed plugins can be checked via [`PluginManagerCore.isPluginInstalled()`](%gh-ic%/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java).
|
||||||
|
|
||||||
### Plugin Suggestions
|
### Plugin Suggestions
|
||||||
|
|
||||||
For specific features (e.g., [File Type](registering_file_type.md), [Facet](facet.md), ...), the IDE will suggest installing matching plugins automatically.
|
For specific features (e.g., [File Type](registering_file_type.md), [Facet](facet.md), ...), the IDE will suggest installing matching plugins automatically.
|
||||||
See [Plugin Recommendations](https://plugins.jetbrains.com/docs/marketplace/intellij-plugin-recommendations.html) in Marketplace documentation for details.
|
See [Plugin Recommendations](https://plugins.jetbrains.com/docs/marketplace/intellij-plugin-recommendations.html) in Marketplace documentation for details.
|
||||||
|
|
||||||
To suggest other relevant plugins, use [`PluginsAdvertiser.installAndEnable()`](upsource:///platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.kt).
|
To suggest other relevant plugins, use [`PluginsAdvertiser.installAndEnable()`](%gh-ic%/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.kt).
|
||||||
|
|
||||||
### Deprecating a Plugin
|
### Deprecating a Plugin
|
||||||
|
|
||||||
To suggest replacing the currently installed deprecated plugin with the new one, implement [`PluginReplacement`](upsource:///platform/platform-api/src/com/intellij/ide/plugins/PluginReplacement.java) registered in `com.intellij.pluginReplacement` extension point.
|
To suggest replacing the currently installed deprecated plugin with the new one, implement [`PluginReplacement`](%gh-ic%/platform/platform-api/src/com/intellij/ide/plugins/PluginReplacement.java) registered in `com.intellij.pluginReplacement` extension point.
|
||||||
|
@ -28,8 +28,8 @@ Therefore, custom language plugin developers typically use stub indexes in their
|
|||||||
|
|
||||||
Indexing is a potentially lengthy process.
|
Indexing is a potentially lengthy process.
|
||||||
It's performed in the background, and during this time, IDE features are restricted to the ones that don't require index: basic text editing, version control, etc.
|
It's performed in the background, and during this time, IDE features are restricted to the ones that don't require index: basic text editing, version control, etc.
|
||||||
This restriction is managed by [`DumbService`](upsource:///platform/core-api/src/com/intellij/openapi/project/DumbService.java).
|
This restriction is managed by [`DumbService`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/DumbService.java).
|
||||||
Violations are reported via [`IndexNotReadyException`](upsource:///platform/core-api/src/com/intellij/openapi/project/IndexNotReadyException.java), please see its javadoc on how to adapt callers.
|
Violations are reported via [`IndexNotReadyException`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/IndexNotReadyException.java), please see its javadoc on how to adapt callers.
|
||||||
|
|
||||||
`DumbService` provides API to query whether the IDE is currently in "dumb" mode (where index access is not allowed) or "smart" mode (with all index built and ready to use).
|
`DumbService` provides API to query whether the IDE is currently in "dumb" mode (where index access is not allowed) or "smart" mode (with all index built and ready to use).
|
||||||
It also provides ways of delaying code execution until indexes are ready.
|
It also provides ways of delaying code execution until indexes are ready.
|
||||||
@ -45,12 +45,12 @@ Sometimes, the following conditions hold:
|
|||||||
* The data can be recalculated lazily on request without significant performance penalties.
|
* The data can be recalculated lazily on request without significant performance penalties.
|
||||||
|
|
||||||
A [file-based index](file_based_indexes.md) can be used in such cases, but file gists provide a way to perform data calculation lazily, caching on disk, and a more lightweight API.
|
A [file-based index](file_based_indexes.md) can be used in such cases, but file gists provide a way to perform data calculation lazily, caching on disk, and a more lightweight API.
|
||||||
Please see [`VirtualFileGist`](upsource:///platform/indexing-api/src/com/intellij/util/gist/VirtualFileGist.java) and [`PsiFileGist`](upsource:///platform/indexing-api/src/com/intellij/util/gist/PsiFileGist.java) documentation.
|
Please see [`VirtualFileGist`](%gh-ic%/platform/indexing-api/src/com/intellij/util/gist/VirtualFileGist.java) and [`PsiFileGist`](%gh-ic%/platform/indexing-api/src/com/intellij/util/gist/PsiFileGist.java) documentation.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
- `VirtualFileGist`: [`ImageInfoIndex`](upsource:///images/src/org/intellij/images/index/ImageInfoIndex.java) calculating image dimensions/bit depth needed to be displayed in specific parts of UI.
|
- `VirtualFileGist`: [`ImageInfoIndex`](%gh-ic%/images/src/org/intellij/images/index/ImageInfoIndex.java) calculating image dimensions/bit depth needed to be displayed in specific parts of UI.
|
||||||
- `PsiFileGist`: [`JavaSimplePropertyGist`](upsource:///java/java-indexing-impl/src/com/intellij/psi/impl/JavaSimplePropertyGist.kt) providing simple properties in Java
|
- `PsiFileGist`: [`JavaSimplePropertyGist`](%gh-ic%/java/java-indexing-impl/src/com/intellij/psi/impl/JavaSimplePropertyGist.kt) providing simple properties in Java
|
||||||
|
|
||||||
## Improving Indexing Performance
|
## Improving Indexing Performance
|
||||||
|
|
||||||
@ -64,17 +64,17 @@ These are additionally available in HTML format starting with 2021.1.
|
|||||||
Use [lexer](implementing_lexer.md) information instead of parsed trees if possible.
|
Use [lexer](implementing_lexer.md) information instead of parsed trees if possible.
|
||||||
|
|
||||||
If impossible, use light AST which doesn't create memory-hungry AST nodes inside, so traversing it might be faster.
|
If impossible, use light AST which doesn't create memory-hungry AST nodes inside, so traversing it might be faster.
|
||||||
Obtain [`LighterAST`](upsource:///platform/core-api/src/com/intellij/lang/LighterAST.java) by casting `FileContent` input parameter to [`PsiDependentFileContent`](upsource:///platform/core-api/src/com/intellij/util/indexing/PsiDependentFileContent.java) and calling `getLighterAST()`.
|
Obtain [`LighterAST`](%gh-ic%/platform/core-api/src/com/intellij/lang/LighterAST.java) by casting `FileContent` input parameter to [`PsiDependentFileContent`](%gh-ic%/platform/core-api/src/com/intellij/util/indexing/PsiDependentFileContent.java) and calling `getLighterAST()`.
|
||||||
Make sure to traverse only the nodes you need to.
|
Make sure to traverse only the nodes you need to.
|
||||||
See also [`LighterASTNodeVisitor`](upsource:///platform/core-impl/src/com/intellij/psi/impl/source/tree/LighterASTNodeVisitor.java) and [`LightTreeUtil`](upsource:///platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java) for useful utility methods.
|
See also [`LighterASTNodeVisitor`](%gh-ic%/platform/core-impl/src/com/intellij/psi/impl/source/tree/LighterASTNodeVisitor.java) and [`LightTreeUtil`](%gh-ic%/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java) for useful utility methods.
|
||||||
|
|
||||||
For [stub index](stub_indexes.md), implement [`LightStubBuilder`](upsource:///platform/core-impl/src/com/intellij/psi/stubs/LightStubBuilder.java).
|
For [stub index](stub_indexes.md), implement [`LightStubBuilder`](%gh-ic%/platform/core-impl/src/com/intellij/psi/stubs/LightStubBuilder.java).
|
||||||
|
|
||||||
If a custom language contains lazy-parseable elements that never or rarely contain any stubs, consider implementing [`StubBuilder.skipChildProcessingWhenBuildingStubs()`](upsource:///platform/core-api/src/com/intellij/psi/StubBuilder.java) (preferably using Lexer/node text).
|
If a custom language contains lazy-parseable elements that never or rarely contain any stubs, consider implementing [`StubBuilder.skipChildProcessingWhenBuildingStubs()`](%gh-ic%/platform/core-api/src/com/intellij/psi/StubBuilder.java) (preferably using Lexer/node text).
|
||||||
|
|
||||||
For indexing XML, also consider using [`NanoXmlUtil`](upsource:///platform/indexing-impl/src/com/intellij/util/xml/NanoXmlUtil.java).
|
For indexing XML, also consider using [`NanoXmlUtil`](%gh-ic%/platform/indexing-impl/src/com/intellij/util/xml/NanoXmlUtil.java).
|
||||||
|
|
||||||
### Consider Prebuilt Stubs
|
### Consider Prebuilt Stubs
|
||||||
|
|
||||||
If your language has a massive standard library, which is mostly the same for all users, you can avoid stub-indexing it in each installation by providing prebuilt stubs with your distribution.
|
If your language has a massive standard library, which is mostly the same for all users, you can avoid stub-indexing it in each installation by providing prebuilt stubs with your distribution.
|
||||||
See [`PrebuiltStubsProvider`](upsource:///platform/indexing-impl/src/com/intellij/psi/stubs/PrebuiltStubs.kt) extension.
|
See [`PrebuiltStubsProvider`](%gh-ic%/platform/indexing-impl/src/com/intellij/psi/stubs/PrebuiltStubs.kt) extension.
|
||||||
|
@ -25,27 +25,27 @@ When accessing an index, specify the key you're interested in and get back the l
|
|||||||
|
|
||||||
## Implementing a File-Based Index
|
## Implementing a File-Based Index
|
||||||
|
|
||||||
> A relatively simple file-based index implementation is the [UI Designer bound forms index](upsource:///plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java), storing FQN of bound implementation class for [GUI Designer](https://www.jetbrains.com/help/idea/gui-designer-basics.html) <path>.form</path> files.
|
> A relatively simple file-based index implementation is the [UI Designer bound forms index](%gh-ic%/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java), storing FQN of bound implementation class for [GUI Designer](https://www.jetbrains.com/help/idea/gui-designer-basics.html) <path>.form</path> files.
|
||||||
>
|
>
|
||||||
{type="tip"}
|
{type="tip"}
|
||||||
|
|
||||||
Each specific index implementation is a class extending [`FileBasedIndexExtension`](upsource:///platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java) registered via `com.intellij.fileBasedIndex` extension point.
|
Each specific index implementation is a class extending [`FileBasedIndexExtension`](%gh-ic%/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java) registered via `com.intellij.fileBasedIndex` extension point.
|
||||||
|
|
||||||
An implementation of a file-based index consists of the following main parts:
|
An implementation of a file-based index consists of the following main parts:
|
||||||
|
|
||||||
* `getIndexer()` returns the [`DataIndexer`](upsource:///platform/util/src/com/intellij/util/indexing/DataIndexer.java) implementation actually responsible for building a set of key/value pairs based on file content.
|
* `getIndexer()` returns the [`DataIndexer`](%gh-ic%/platform/util/src/com/intellij/util/indexing/DataIndexer.java) implementation actually responsible for building a set of key/value pairs based on file content.
|
||||||
* `getKeyDescriptor()` returns the [`KeyDescriptor`](upsource:///platform/util/src/com/intellij/util/io/KeyDescriptor.java) responsible for comparing keys and storing them in a serialized binary format.
|
* `getKeyDescriptor()` returns the [`KeyDescriptor`](%gh-ic%/platform/util/src/com/intellij/util/io/KeyDescriptor.java) responsible for comparing keys and storing them in a serialized binary format.
|
||||||
Probably the most commonly used implementation is [`EnumeratorStringDescriptor`](upsource:///platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java), which is designed for storing identifiers efficiently.
|
Probably the most commonly used implementation is [`EnumeratorStringDescriptor`](%gh-ic%/platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java), which is designed for storing identifiers efficiently.
|
||||||
* `getValueExternalizer()` returns the [`DataExternalizer`](upsource:///platform/util/src/com/intellij/util/io/DataExternalizer.java) responsible for storing values in a serialized binary format.
|
* `getValueExternalizer()` returns the [`DataExternalizer`](%gh-ic%/platform/util/src/com/intellij/util/io/DataExternalizer.java) responsible for storing values in a serialized binary format.
|
||||||
* `getInputFilter()` allows restricting the indexing only to a certain set of files.
|
* `getInputFilter()` allows restricting the indexing only to a certain set of files.
|
||||||
Consider using [`DefaultFileTypeSpecificInputFilter`](upsource:///platform/indexing-api/src/com/intellij/util/indexing/DefaultFileTypeSpecificInputFilter.java).
|
Consider using [`DefaultFileTypeSpecificInputFilter`](%gh-ic%/platform/indexing-api/src/com/intellij/util/indexing/DefaultFileTypeSpecificInputFilter.java).
|
||||||
* `getName()` returns a unique index ID.
|
* `getName()` returns a unique index ID.
|
||||||
Consider using fully qualified index class name to not clash with other plugins defining index with the same ID, e.g., `com.example.myplugin.indexing.MyIndex`.
|
Consider using fully qualified index class name to not clash with other plugins defining index with the same ID, e.g., `com.example.myplugin.indexing.MyIndex`.
|
||||||
* `getVersion()` returns the version of the index implementation.
|
* `getVersion()` returns the version of the index implementation.
|
||||||
The index is automatically rebuilt if the current version differs from the version of the index implementation used to build it.
|
The index is automatically rebuilt if the current version differs from the version of the index implementation used to build it.
|
||||||
|
|
||||||
If there's no value to associate with the files (i.e., value type is `Void`), simplify the implementation by extending [`ScalarIndexExtension`](upsource:///platform/indexing-api/src/com/intellij/util/indexing/ScalarIndexExtension.java).
|
If there's no value to associate with the files (i.e., value type is `Void`), simplify the implementation by extending [`ScalarIndexExtension`](%gh-ic%/platform/indexing-api/src/com/intellij/util/indexing/ScalarIndexExtension.java).
|
||||||
In case of single value per file, extend from [`SingleEntryFileBasedIndexExtension`](upsource:///platform/indexing-api/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.java).
|
In case of single value per file, extend from [`SingleEntryFileBasedIndexExtension`](%gh-ic%/platform/indexing-api/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.java).
|
||||||
|
|
||||||
Please see also [Improving indexing performance](indexing_and_psi_stubs.md#improving-indexing-performance).
|
Please see also [Improving indexing performance](indexing_and_psi_stubs.md#improving-indexing-performance).
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ Please see also [Improving indexing performance](indexing_and_psi_stubs.md#impro
|
|||||||
|
|
||||||
## Accessing a File-Based Index
|
## Accessing a File-Based Index
|
||||||
|
|
||||||
Access to file-based indexes is performed through the [`FileBasedIndex`](upsource:///platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java) class.
|
Access to file-based indexes is performed through the [`FileBasedIndex`](%gh-ic%/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java) class.
|
||||||
|
|
||||||
> Please note index access is restricted during [Dumb Mode](indexing_and_psi_stubs.md#dumb-mode).
|
> Please note index access is restricted during [Dumb Mode](indexing_and_psi_stubs.md#dumb-mode).
|
||||||
>
|
>
|
||||||
@ -92,14 +92,14 @@ The IntelliJ Platform contains several standard file-based indexes.
|
|||||||
The most useful indexes for plugin developers are:
|
The most useful indexes for plugin developers are:
|
||||||
|
|
||||||
### Word Index
|
### Word Index
|
||||||
Generally, the word index should be accessed indirectly by using helper methods of the [`PsiSearchHelper`](upsource:///platform/indexing-api/src/com/intellij/psi/search/PsiSearchHelper.java) class.
|
Generally, the word index should be accessed indirectly by using helper methods of the [`PsiSearchHelper`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/search/PsiSearchHelper.java) class.
|
||||||
|
|
||||||
### File Name Index
|
### File Name Index
|
||||||
[`FilenameIndex`](upsource:///platform/indexing-api/src/com/intellij/psi/search/FilenameIndex.java) provides a quick way to find all files matching a specific file name.
|
[`FilenameIndex`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/search/FilenameIndex.java) provides a quick way to find all files matching a specific file name.
|
||||||
|
|
||||||
### File Type Index
|
### File Type Index
|
||||||
[`FileTypeIndex`](upsource:///platform/indexing-api/src/com/intellij/psi/search/FileTypeIndex.java) serves a similar goal: it allows to find all files of a particular [`FileType`](upsource:///platform/core-api/src/com/intellij/openapi/fileTypes/FileType.java) quickly.
|
[`FileTypeIndex`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/search/FileTypeIndex.java) serves a similar goal: it allows to find all files of a particular [`FileType`](%gh-ic%/platform/core-api/src/com/intellij/openapi/fileTypes/FileType.java) quickly.
|
||||||
|
|
||||||
## Additional Index Roots
|
## Additional Index Roots
|
||||||
|
|
||||||
To add additional files/directories to be indexed, implement [`IndexableSetContributor`](upsource:///platform/indexing-api/src/com/intellij/util/indexing/IndexableSetContributor.java) and register in [`com.intellij.indexedRootsProvider`](https://jb.gg/ipe?extensions=com.intellij.indexedRootsProvider) extension point.
|
To add additional files/directories to be indexed, implement [`IndexableSetContributor`](%gh-ic%/platform/indexing-api/src/com/intellij/util/indexing/IndexableSetContributor.java) and register in [`com.intellij.indexedRootsProvider`](https://jb.gg/ipe?extensions=com.intellij.indexedRootsProvider) extension point.
|
||||||
|
@ -24,21 +24,21 @@ You usually don't need to have stubs for things like statements or local variabl
|
|||||||
|
|
||||||
The following steps need to be performed only once for each language that supports stubs:
|
The following steps need to be performed only once for each language that supports stubs:
|
||||||
|
|
||||||
* Change the file element type for your language (the element type that you return from `ParserDefinition.getFileNodeType()`) to a class that extends [`IStubFileElementType`](upsource:///platform/core-impl/src/com/intellij/psi/tree/IStubFileElementType.java).
|
* Change the file element type for your language (the element type that you return from `ParserDefinition.getFileNodeType()`) to a class that extends [`IStubFileElementType`](%gh-ic%/platform/core-impl/src/com/intellij/psi/tree/IStubFileElementType.java).
|
||||||
* In your <path>plugin.xml</path>, define the `com.intellij.stubElementTypeHolder` extension and specify the interface which contains the `IElementType` constants used by your language's parser as well as `externalIdPrefix` if possible ([example](upsource:///plugins/properties/src/META-INF/plugin.xml)).
|
* In your <path>plugin.xml</path>, define the `com.intellij.stubElementTypeHolder` extension and specify the interface which contains the `IElementType` constants used by your language's parser as well as `externalIdPrefix` if possible ([example](%gh-ic%/plugins/properties/src/META-INF/plugin.xml)).
|
||||||
|
|
||||||
For each element type that you want to store in the stub tree, you need to perform the following steps:
|
For each element type that you want to store in the stub tree, you need to perform the following steps:
|
||||||
|
|
||||||
* Define an interface for the stub, derived from the [`StubElement`](upsource:///platform/core-api/src/com/intellij/psi/stubs/StubElement.java) interface ([example](upsource:///plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertyStub.java)).
|
* Define an interface for the stub, derived from the [`StubElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/stubs/StubElement.java) interface ([example](%gh-ic%/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertyStub.java)).
|
||||||
* Provide an implementation for the interface ([example](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyStubImpl.java)).
|
* Provide an implementation for the interface ([example](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyStubImpl.java)).
|
||||||
* Make sure the interface for the PSI element extends [`StubBasedPsiElement`](upsource:///platform/core-api/src/com/intellij/psi/StubBasedPsiElement.java) parameterized by the type of the stub interface ([example](upsource:///plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/Property.java)).
|
* Make sure the interface for the PSI element extends [`StubBasedPsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/StubBasedPsiElement.java) parameterized by the type of the stub interface ([example](%gh-ic%/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/Property.java)).
|
||||||
* Make sure the implementation class for the PSI element extends [`StubBasedPsiElementBase`](upsource:///platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java) parameterized by the type of the stub interface ([example](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)).
|
* Make sure the implementation class for the PSI element extends [`StubBasedPsiElementBase`](%gh-ic%/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java) parameterized by the type of the stub interface ([example](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)).
|
||||||
Provide both a constructor that accepts an `ASTNode` and a constructor that accepts a stub.
|
Provide both a constructor that accepts an `ASTNode` and a constructor that accepts a stub.
|
||||||
* Create a class that implements `IStubElementType` and is parameterized with the stub interface and the actual PSI element interface ([example](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertyStubElementType.java)).
|
* Create a class that implements `IStubElementType` and is parameterized with the stub interface and the actual PSI element interface ([example](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertyStubElementType.java)).
|
||||||
Implement the `createPsi()` and `createStub()` methods for creating PSI from a stub and vice versa.
|
Implement the `createPsi()` and `createStub()` methods for creating PSI from a stub and vice versa.
|
||||||
Implement the `serialize()` and `deserialize()` methods for storing the data in a binary stream.
|
Implement the `serialize()` and `deserialize()` methods for storing the data in a binary stream.
|
||||||
* Use the class implementing `IStubElementType` as the element type constant when parsing ([example](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertiesElementTypes.java)).
|
* Use the class implementing `IStubElementType` as the element type constant when parsing ([example](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertiesElementTypes.java)).
|
||||||
* Make sure all methods in the PSI element interface access the stub data rather than the PSI tree when appropriate ([example: `Property.getKey()` implementation](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)).
|
* Make sure all methods in the PSI element interface access the stub data rather than the PSI tree when appropriate ([example: `Property.getKey()` implementation](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)).
|
||||||
|
|
||||||
> If you use [Grammar-Kit](https://github.com/JetBrains/Grammar-Kit) to generate your language PSI, see the [Stub indices support](https://github.com/JetBrains/Grammar-Kit/blob/master/HOWTO.md#35-stub-indices-support) section for instructions on integrating your grammar with stubs.
|
> If you use [Grammar-Kit](https://github.com/JetBrains/Grammar-Kit) to generate your language PSI, see the [Stub indices support](https://github.com/JetBrains/Grammar-Kit/blob/master/HOWTO.md#35-stub-indices-support) section for instructions on integrating your grammar with stubs.
|
||||||
>
|
>
|
||||||
@ -54,7 +54,7 @@ The exclusion is not recursive: if some elements of the element for which you re
|
|||||||
For serializing string data, e.g. element names, in stubs, we recommend to use `StubOutputStream.writeName()` and `StubInputStream.readName()` methods.
|
For serializing string data, e.g. element names, in stubs, we recommend to use `StubOutputStream.writeName()` and `StubInputStream.readName()` methods.
|
||||||
These methods ensure that each unique identifier is stored only once in the data stream.
|
These methods ensure that each unique identifier is stored only once in the data stream.
|
||||||
This reduces the size of the serialized stub tree data.
|
This reduces the size of the serialized stub tree data.
|
||||||
See also [`DataInputOutputUtil`](upsource:///platform/util/src/com/intellij/util/io/DataInputOutputUtil.java).
|
See also [`DataInputOutputUtil`](%gh-ic%/platform/util/src/com/intellij/util/io/DataInputOutputUtil.java).
|
||||||
|
|
||||||
If you need to change the stored binary format for the stubs (for example, if you want to store some additional data or some new elements), make sure you advance the stub version returned from `IStubFileElementType.getStubVersion()` for your language.
|
If you need to change the stored binary format for the stubs (for example, if you want to store some additional data or some new elements), make sure you advance the stub version returned from `IStubFileElementType.getStubVersion()` for your language.
|
||||||
This will cause the stubs and [stub indices](#stub-indexes) to be rebuilt, and will avoid mismatches between the stored data format, and the code trying to load it.
|
This will cause the stubs and [stub indices](#stub-indexes) to be rebuilt, and will avoid mismatches between the stored data format, and the code trying to load it.
|
||||||
@ -72,11 +72,11 @@ When building the stub tree, you can, at the same time, put some data about the
|
|||||||
Unlike file-based indexes, stub indexes do not support storing custom data as values; the value is always a PSI element.
|
Unlike file-based indexes, stub indexes do not support storing custom data as values; the value is always a PSI element.
|
||||||
Keys in stub indexes are typically strings (such as class names); other data types are also supported if desired.
|
Keys in stub indexes are typically strings (such as class names); other data types are also supported if desired.
|
||||||
|
|
||||||
A stub index is a class which extends [`AbstractStubIndex`](upsource:///platform/indexing-api/src/com/intellij/psi/stubs/AbstractStubIndex.java).
|
A stub index is a class which extends [`AbstractStubIndex`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/stubs/AbstractStubIndex.java).
|
||||||
In the most common case, when the key type is `String`, you use a more specific base class, namely [`StringStubIndexExtension`](upsource:///platform/indexing-api/src/com/intellij/psi/stubs/StringStubIndexExtension.java).
|
In the most common case, when the key type is `String`, you use a more specific base class, namely [`StringStubIndexExtension`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/stubs/StringStubIndexExtension.java).
|
||||||
Stub index implementation classes are registered in the `com.intellij.stubIndex` extension point.
|
Stub index implementation classes are registered in the `com.intellij.stubIndex` extension point.
|
||||||
|
|
||||||
To put data into an index, you implement the method `IStubElementType.indexStub()` ([example: `JavaClassElementType.indexStub()`](upsource:///java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java)).
|
To put data into an index, you implement the method `IStubElementType.indexStub()` ([example: `JavaClassElementType.indexStub()`](%gh-ic%/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java)).
|
||||||
This method accepts an `IndexSink` as a parameter and puts in the index ID and the key for each index in which the element should be stored.
|
This method accepts an `IndexSink` as a parameter and puts in the index ID and the key for each index in which the element should be stored.
|
||||||
|
|
||||||
To access the data from an index, the following two methods are used:
|
To access the data from an index, the following two methods are used:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
The Credentials Store API allows you to store sensitive user data securely, like passwords, server URLs, etc.
|
The Credentials Store API allows you to store sensitive user data securely, like passwords, server URLs, etc.
|
||||||
|
|
||||||
## How to Use
|
## How to Use
|
||||||
Use [`PasswordSafe`](upsource:///platform/remote-core/src/ide/passwordSafe/PasswordSafe.kt) to work with credentials.
|
Use [`PasswordSafe`](%gh-ic%/platform/remote-core/src/ide/passwordSafe/PasswordSafe.kt) to work with credentials.
|
||||||
|
|
||||||
_Common Utility Method:_
|
_Common Utility Method:_
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||||
|
|
||||||
The IntelliJ Platform provides an API that allows components or services to persist their state between restarts of the IDE.
|
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`](upsource:///platform/projectModel-api/src/com/intellij/openapi/components/PersistentStateComponent.java) interface.
|
You can use either a simple API to persist a few values or persist the state of more complicated components using the [`PersistentStateComponent`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/components/PersistentStateComponent.java) interface.
|
||||||
|
|
||||||
> If you need to persist sensitive data like passwords, please see [Persisting Sensitive Data](persisting_sensitive_data.md).
|
> If you need to persist sensitive data like passwords, please see [Persisting Sensitive Data](persisting_sensitive_data.md).
|
||||||
>
|
>
|
||||||
@ -11,7 +11,7 @@ You can use either a simple API to persist a few values or persist the state of
|
|||||||
|
|
||||||
## Using PersistentStateComponent
|
## Using PersistentStateComponent
|
||||||
|
|
||||||
The [`com.intellij.openapi.components.PersistentStateComponent`](upsource:///platform/projectModel-api/src/com/intellij/openapi/components/PersistentStateComponent.java) interface gives you the most flexibility for defining the values to be persisted, their format, and storage location.
|
The [`com.intellij.openapi.components.PersistentStateComponent`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/components/PersistentStateComponent.java) interface gives you the most flexibility for defining the values to be persisted, their format, and storage location.
|
||||||
|
|
||||||
To use it:
|
To use it:
|
||||||
- mark a [service](plugin_services.md) as implementing the `PersistentStateComponent` interface
|
- mark a [service](plugin_services.md) as implementing the `PersistentStateComponent` interface
|
||||||
@ -76,7 +76,7 @@ class MyService implements PersistentStateComponent<MyService> {
|
|||||||
|
|
||||||
### Implementing the State Class
|
### Implementing the State Class
|
||||||
|
|
||||||
The implementation of `PersistentStateComponent` works by serializing public fields, [annotated](upsource:///platform/util/src/com/intellij/util/xmlb/annotations) private fields (see also [Customizing the XML format of persisted values](#customizing-the-xml-format-of-persisted-values)), and bean properties into an XML format.
|
The implementation of `PersistentStateComponent` works by serializing public fields, [annotated](%gh-ic%/platform/util/src/com/intellij/util/xmlb/annotations) private fields (see also [Customizing the XML format of persisted values](#customizing-the-xml-format-of-persisted-values)), and bean properties into an XML format.
|
||||||
|
|
||||||
To exclude a public field or bean property from serialization, annotate the field or getter with `@com.intellij.util.xmlb.annotations.Transient`.
|
To exclude a public field or bean property from serialization, annotate the field or getter with `@com.intellij.util.xmlb.annotations.Transient`.
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ The following types of values can be persisted:
|
|||||||
* maps
|
* maps
|
||||||
* enums
|
* enums
|
||||||
|
|
||||||
For other types, extend [`com.intellij.util.xmlb.Converter`](upsource:///platform/util/src/com/intellij/util/xmlb/Converter.java):
|
For other types, extend [`com.intellij.util.xmlb.Converter`](%gh-ic%/platform/util/src/com/intellij/util/xmlb/Converter.java):
|
||||||
|
|
||||||
```java
|
```java
|
||||||
class LocalDateTimeConverter extends Converter<LocalDateTime> {
|
class LocalDateTimeConverter extends Converter<LocalDateTime> {
|
||||||
@ -140,7 +140,7 @@ The simplest ways of specifying the `@Storage` annotation are as follows:
|
|||||||
|
|
||||||
The state is persisted in a separate file by specifying a different setting for the `value` parameter, which was the `file` parameter before 2016.x.
|
The state is persisted in a separate file by specifying a different setting for the `value` parameter, which was the `file` parameter before 2016.x.
|
||||||
|
|
||||||
See [`StoragePathMacros`](upsource:///platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java) for commonly used values.
|
See [`StoragePathMacros`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java) for commonly used values.
|
||||||
|
|
||||||
> For application-level storage, it is strongly recommended to use a custom file, using of <path>other.xml</path> is deprecated.
|
> For application-level storage, it is strongly recommended to use a custom file, using of <path>other.xml</path> is deprecated.
|
||||||
>
|
>
|
||||||
@ -157,7 +157,7 @@ The `roamingType` parameter of the `@Storage` annotation specifies the roaming t
|
|||||||
|
|
||||||
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`, `@XCollection` annotations.
|
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`, `@XCollection` annotations.
|
||||||
|
|
||||||
Please see `com.intellij.util.xmlb.annotations`'s [`package.html`](upsource:///platform/util/src/com/intellij/util/xmlb/annotations/package.html) for more information.
|
Please see `com.intellij.util.xmlb.annotations`'s [`package.html`](%gh-ic%/platform/util/src/com/intellij/util/xmlb/annotations/package.html) for more information.
|
||||||
|
|
||||||
If the state you need to serialize doesn't map cleanly to a JavaBean, you can use `org.jdom.Element` as the state class.
|
If the state 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 then is saved directly in the state XML file.
|
In that case, you can use the `getState()` method to build an XML element with an arbitrary structure, which then is saved directly in the state XML file.
|
||||||
@ -166,7 +166,7 @@ Please note this is not recommended and should be avoided whenever possible.
|
|||||||
|
|
||||||
### Migrating Persisted Values
|
### Migrating Persisted Values
|
||||||
|
|
||||||
If the underlying persistence model or storage format has changed, a [`ConverterProvider`](upsource:///platform/lang-impl/src/com/intellij/conversion/ConverterProvider.java) can provide [`ProjectConverter`](upsource:///platform/lang-impl/src/com/intellij/conversion/ProjectConverter.java) whose `getAdditionalAffectedFiles()` method returns affected files to migrate and performs programmatic migration of stored values.
|
If the underlying persistence model or storage format has changed, a [`ConverterProvider`](%gh-ic%/platform/lang-impl/src/com/intellij/conversion/ConverterProvider.java) can provide [`ProjectConverter`](%gh-ic%/platform/lang-impl/src/com/intellij/conversion/ProjectConverter.java) whose `getAdditionalAffectedFiles()` method returns affected files to migrate and performs programmatic migration of stored values.
|
||||||
|
|
||||||
### Persistent Component Lifecycle
|
### Persistent Component Lifecycle
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ Otherwise, the returned state is serialized in XML and stored.
|
|||||||
|
|
||||||
## Using PropertiesComponent for Simple Non-Roamable Persistence
|
## Using PropertiesComponent for Simple Non-Roamable Persistence
|
||||||
|
|
||||||
If the plugin needs to persist just a few simple values, the easiest way to do so is to use the [`com.intellij.ide.util.PropertiesComponent`](upsource:///platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java) service.
|
If the plugin needs to persist just a few simple values, the easiest way to do so is to use the [`com.intellij.ide.util.PropertiesComponent`](%gh-ic%/platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java) service.
|
||||||
It can save both application-level values and project-level values in the workspace file.
|
It can save both application-level values and project-level values in the workspace file.
|
||||||
Roaming is disabled for `PropertiesComponent`, so use it only for temporary, non-roamable properties.
|
Roaming is disabled for `PropertiesComponent`, so use it only for temporary, non-roamable properties.
|
||||||
|
|
||||||
@ -189,10 +189,10 @@ Since all plugins share the same namespace, it is highly recommended prefixing k
|
|||||||
|
|
||||||
## Legacy API (JDOMExternalizable)
|
## Legacy API (JDOMExternalizable)
|
||||||
|
|
||||||
Older components use the [`JDOMExternalizable`](upsource:///platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) interface for persisting state.
|
Older components use the [`JDOMExternalizable`](%gh-ic%/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) interface for persisting state.
|
||||||
It uses the `readExternal()` method for reading the state from a JDOM element, and `writeExternal()` to write the state.
|
It uses the `readExternal()` method for reading the state from a JDOM element, and `writeExternal()` to write the state.
|
||||||
|
|
||||||
Implementations can manually store the state in attributes and sub-elements or use the [`DefaultJDOMExternalizer`](upsource:///platform/util/src/com/intellij/openapi/util/DefaultJDOMExternalizer.java) class to store the values of all public fields automatically.
|
Implementations can manually store the state in attributes and sub-elements or use the [`DefaultJDOMExternalizer`](%gh-ic%/platform/util/src/com/intellij/openapi/util/DefaultJDOMExternalizer.java) class to store the values of all public fields automatically.
|
||||||
|
|
||||||
Components save their state in the following files:
|
Components save their state in the following files:
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ Do not store references to PSI elements in objects which can survive plugin load
|
|||||||
Replace with `String` from `Language.getID()`/`FileType.getName()` (use inspection <control>Plugin DevKit | Code | Map key may leak</control>).
|
Replace with `String` from `Language.getID()`/`FileType.getName()` (use inspection <control>Plugin DevKit | Code | Map key may leak</control>).
|
||||||
|
|
||||||
### Plugin Load/Unload Events
|
### Plugin Load/Unload Events
|
||||||
Register [`DynamicPluginListener`](upsource:///platform/core-api/src/com/intellij/ide/plugins/DynamicPluginListener.kt) [application listener](plugin_listeners.md) to receive updates on plugin load/unload events.
|
Register [`DynamicPluginListener`](%gh-ic%/platform/core-api/src/com/intellij/ide/plugins/DynamicPluginListener.kt) [application listener](plugin_listeners.md) to receive updates on plugin load/unload events.
|
||||||
|
|
||||||
This can be used to e.g., cancel long-running activities or disallow unload due to ongoing processes.
|
This can be used to e.g., cancel long-running activities or disallow unload due to ongoing processes.
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||||
|
|
||||||
The IntelliJ Platform provides the concept of _actions_.
|
The IntelliJ Platform provides the concept of _actions_.
|
||||||
An action is a class derived from [`AnAction`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java), whose `actionPerformed()` method is called when its menu item or toolbar button is selected.
|
An action is a class derived from [`AnAction`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java), whose `actionPerformed()` method is called when its menu item or toolbar button is selected.
|
||||||
|
|
||||||
Actions are the most common way for a user to invoke the functionality of your plugin.
|
Actions are the most common way for a user to invoke the functionality of your plugin.
|
||||||
An action can be invoked from a menu or a toolbar, using a keyboard shortcut or the <menupath>Help | Find Action...</menupath> lookup.
|
An action can be invoked from a menu or a toolbar, using a keyboard shortcut or the <menupath>Help | Find Action...</menupath> lookup.
|
||||||
|
@ -36,21 +36,21 @@ To subscribe to events, use a [listener](plugin_listeners.md) or create an [exte
|
|||||||
{type="warning"}
|
{type="warning"}
|
||||||
|
|
||||||
Plugin code should only be executed when projects are opened (see [Project Open](#project-open)) or when the user invokes an action of a plugin.
|
Plugin code should only be executed when projects are opened (see [Project Open](#project-open)) or when the user invokes an action of a plugin.
|
||||||
If this cannot be avoided, add a [listener](plugin_listeners.md) subscribing to the [`AppLifecycleListener`](upsource:///platform/platform-impl/src/com/intellij/ide/AppLifecycleListener.java) topic.
|
If this cannot be avoided, add a [listener](plugin_listeners.md) subscribing to the [`AppLifecycleListener`](%gh-ic%/platform/platform-impl/src/com/intellij/ide/AppLifecycleListener.java) topic.
|
||||||
See also [Running Tasks Once](ide_infrastructure.md).
|
See also [Running Tasks Once](ide_infrastructure.md).
|
||||||
|
|
||||||
To execute an activity in background on IDE startup (e.g., to warm up caches), use [`PreloadingActivity`](upsource:///platform/ide-core/src/com/intellij/openapi/application/PreloadingActivity.java).
|
To execute an activity in background on IDE startup (e.g., to warm up caches), use [`PreloadingActivity`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/application/PreloadingActivity.java).
|
||||||
|
|
||||||
### Project Open
|
### Project Open
|
||||||
|
|
||||||
To execute code when a project is being opened, use one of these two [extensions](plugin_extensions.md):
|
To execute code when a project is being opened, use one of these two [extensions](plugin_extensions.md):
|
||||||
|
|
||||||
#### `com.intellij.postStartupActivity`
|
#### `com.intellij.postStartupActivity`
|
||||||
[`StartupActivity`](upsource:///platform/core-api/src/com/intellij/openapi/startup/StartupActivity.java) for immediate execution on EDT.
|
[`StartupActivity`](%gh-ic%/platform/core-api/src/com/intellij/openapi/startup/StartupActivity.java) for immediate execution on EDT.
|
||||||
Implement `DumbAware` to indicate activity can run in background thread (in parallel with other such tasks).
|
Implement `DumbAware` to indicate activity can run in background thread (in parallel with other such tasks).
|
||||||
|
|
||||||
#### `com.intellij.backgroundPostStartupActivity`
|
#### `com.intellij.backgroundPostStartupActivity`
|
||||||
[`StartupActivity.Background`](upsource:///platform/core-api/src/com/intellij/openapi/startup/StartupActivity.java) for execution with 5 seconds delay in background thread (2019.3 or later).
|
[`StartupActivity.Background`](%gh-ic%/platform/core-api/src/com/intellij/openapi/startup/StartupActivity.java) for execution with 5 seconds delay in background thread (2019.3 or later).
|
||||||
|
|
||||||
Any long-running or CPU intensive tasks should be made visible to users by using `ProgressManager.run(Task.Backgroundable)`.
|
Any long-running or CPU intensive tasks should be made visible to users by using `ProgressManager.run(Task.Backgroundable)`.
|
||||||
Access to indices must be wrapped with `DumbService`, see also [General Threading Rules](general_threading_rules.md).
|
Access to indices must be wrapped with `DumbService`, see also [General Threading Rules](general_threading_rules.md).
|
||||||
|
@ -44,7 +44,7 @@ Then insert a child element `<extensionPoint>` that defines the extension point
|
|||||||
The `name` attribute assigns a unique name for this extension point.
|
The `name` attribute assigns a unique name for this extension point.
|
||||||
Its fully qualified name required in [Using Extension Points](#using-extension-points) is built by prefixing `<id>` + `.`: `my.plugin.myExtensionPoint1` and `my.plugin.myExtensionPoint2`.
|
Its fully qualified name required in [Using Extension Points](#using-extension-points) is built by prefixing `<id>` + `.`: `my.plugin.myExtensionPoint1` and `my.plugin.myExtensionPoint2`.
|
||||||
|
|
||||||
The `beanClass` attribute sets a bean class that specifies one or several properties annotated with the [`@Attribute`](upsource:///platform/util/src/com/intellij/util/xmlb/annotations/Attribute.java) annotation.
|
The `beanClass` attribute sets a bean class that specifies one or several properties annotated with the [`@Attribute`](%gh-ic%/platform/util/src/com/intellij/util/xmlb/annotations/Attribute.java) annotation.
|
||||||
Note that bean classes do not follow the JavaBean standard.
|
Note that bean classes do not follow the JavaBean standard.
|
||||||
|
|
||||||
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.
|
||||||
@ -113,7 +113,7 @@ For above extension points usage in _anotherPlugin_ would look like this (see al
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Using Extension Points
|
## Using Extension Points
|
||||||
To refer to all registered extension instances at runtime, declare an [`ExtensionPointName`](upsource:///platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java) passing in the fully-qualified name matching its [declaration in plugin.xml](#declaring-extension-points).
|
To refer to all registered extension instances at runtime, declare an [`ExtensionPointName`](%gh-ic%/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java) passing in the fully-qualified name matching its [declaration in plugin.xml](#declaring-extension-points).
|
||||||
|
|
||||||
<path>myPlugin/src/com/myplugin/MyExtensionUsingService.java</path>
|
<path>myPlugin/src/com/myplugin/MyExtensionUsingService.java</path>
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ A gutter icon for the `ExtensionPointName` declaration allows navigating to the
|
|||||||
To support [Dynamic Plugins](dynamic_plugins.md) (2020.1 and later), an extension point must adhere to specific usage rules:
|
To support [Dynamic Plugins](dynamic_plugins.md) (2020.1 and later), an extension point must adhere to specific usage rules:
|
||||||
|
|
||||||
- extensions are enumerated on every use and extensions instances are not stored anywhere
|
- extensions are enumerated on every use and extensions instances are not stored anywhere
|
||||||
- alternatively, an [`ExtensionPointListener`](upsource:///platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointListener.java) can perform necessary updates of data structures (register via `ExtensionPointName.addExtensionPointListener()`)
|
- alternatively, an [`ExtensionPointListener`](%gh-ic%/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointListener.java) can perform necessary updates of data structures (register via `ExtensionPointName.addExtensionPointListener()`)
|
||||||
|
|
||||||
Extension points matching these conditions can then be marked as _dynamic_ by adding `dynamic="true"` in their declaration:
|
Extension points matching these conditions can then be marked as _dynamic_ by adding `dynamic="true"` in their declaration:
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ See [](explore_api.md) for more information and strategies.
|
|||||||
The child element's name must match the name of the extension point you want the extension to access.
|
The child element's 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:
|
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 `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`](upsource:///platform/util/src/com/intellij/util/xmlb/annotations/Attribute.java) annotations in the specified bean class.
|
* If the extension point was declared using the `beanClass` attribute, for newly added child element, set all attributes annotated with the [`@Attribute`](%gh-ic%/platform/util/src/com/intellij/util/xmlb/annotations/Attribute.java) annotations in the specified bean class.
|
||||||
|
|
||||||
See the [](plugin_extension_points.md#declaring-extension-points) section for details.
|
See the [](plugin_extension_points.md#declaring-extension-points) section for details.
|
||||||
|
|
||||||
@ -77,13 +77,13 @@ The following properties are available always:
|
|||||||
* `order` - allows ordering all defined extensions using `first`, `last` or `before|after [id]` respectively
|
* `order` - allows ordering all defined extensions using `first`, `last` or `before|after [id]` respectively
|
||||||
* `os` - allows restricting an extension to given OS, e.g., `os="windows"` registers the extension on Windows only
|
* `os` - allows restricting an extension to given OS, e.g., `os="windows"` registers the extension on Windows only
|
||||||
|
|
||||||
If an extension instance needs to "opt out" in certain scenarios, it can throw [`ExtensionNotApplicableException`](upsource:///platform/extensions/src/com/intellij/openapi/extensions/ExtensionNotApplicableException.java) in its constructor.
|
If an extension instance needs to "opt out" in certain scenarios, it can throw [`ExtensionNotApplicableException`](%gh-ic%/platform/extensions/src/com/intellij/openapi/extensions/ExtensionNotApplicableException.java) in its constructor.
|
||||||
|
|
||||||
### Extension Properties Code Insight
|
### Extension Properties Code Insight
|
||||||
|
|
||||||
Several tooling features are available to help configure bean class extension points in <path>plugin.xml</path>.
|
Several tooling features are available to help configure bean class extension points in <path>plugin.xml</path>.
|
||||||
|
|
||||||
Properties annotated with [`@RequiredElement`](upsource:///platform/extensions/src/com/intellij/openapi/extensions/RequiredElement.java) are inserted automatically and validated (2019.3 and later).
|
Properties annotated with [`@RequiredElement`](%gh-ic%/platform/extensions/src/com/intellij/openapi/extensions/RequiredElement.java) are inserted automatically and validated (2019.3 and later).
|
||||||
If the given property is allowed to have an explicit empty value, set `allowEmpty` to `true` (2020.3 and later).
|
If the given property is allowed to have an explicit empty value, set `allowEmpty` to `true` (2020.3 and later).
|
||||||
|
|
||||||
Property names matching the following list will resolve to fully qualified class name:
|
Property names matching the following list will resolve to fully qualified class name:
|
||||||
|
@ -36,7 +36,7 @@ To define an application-level listener, add the following section to your <path
|
|||||||
```
|
```
|
||||||
|
|
||||||
The `topic` attribute specifies the listener interface corresponding to the type of events you want to receive.
|
The `topic` attribute specifies the listener interface corresponding to the type of events you want to receive.
|
||||||
Usually, this is the interface used as the type parameter of the [`Topic`](upsource:///platform/extensions/src/com/intellij/util/messages/Topic.java) instance for the type of events.
|
Usually, this is the interface used as the type parameter of the [`Topic`](%gh-ic%/platform/extensions/src/com/intellij/util/messages/Topic.java) instance for the type of events.
|
||||||
The `class` attribute specifies the class in your plugin that implements the listener interface and receives the events.
|
The `class` attribute specifies the class in your plugin that implements the listener interface and receives the events.
|
||||||
|
|
||||||
As a specific example, if you want to receive events about all [Virtual File System](virtual_file_system.md) changes, you need to implement the `BulkFileListener` interface, corresponding to the topic `VirtualFileManager.VFS_CHANGES`.
|
As a specific example, if you want to receive events about all [Virtual File System](virtual_file_system.md) changes, you need to implement the `BulkFileListener` interface, corresponding to the topic `VirtualFileManager.VFS_CHANGES`.
|
||||||
@ -91,7 +91,7 @@ They can be used to listen to project-level events, for example, [tool window](t
|
|||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
```
|
```
|
||||||
|
|
||||||
The class implementing the listener interface can define a one-argument constructor accepting a [`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java), and it will receive the instance of the project for which the listener is created:
|
The class implementing the listener interface can define a one-argument constructor accepting a [`Project`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/Project.java), and it will receive the instance of the project for which the listener is created:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
package myPlugin;
|
package myPlugin;
|
||||||
@ -115,8 +115,8 @@ public class MyToolWindowListener implements ToolWindowManagerListener {
|
|||||||
Registration of listeners can be restricted using the following attributes:
|
Registration of listeners can be restricted using the following attributes:
|
||||||
|
|
||||||
- `os` - allows restricting listener to given OS, e.g., `os="windows"` for Windows only (2020.1 and later)
|
- `os` - allows restricting listener to given OS, e.g., `os="windows"` for Windows only (2020.1 and later)
|
||||||
- `activeInTestMode` - set to `false` to disable listener if [`Application.isUnitTestMode()`](upsource:///platform/core-api/src/com/intellij/openapi/application/Application.java) returns `true`
|
- `activeInTestMode` - set to `false` to disable listener if [`Application.isUnitTestMode()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/Application.java) returns `true`
|
||||||
- `activeInHeadlessMode` - set to `false` to disable listener if [`Application.isHeadlessEnvironment()`](upsource:///platform/core-api/src/com/intellij/openapi/application/Application.java) returns `true`.
|
- `activeInHeadlessMode` - set to `false` to disable listener if [`Application.isHeadlessEnvironment()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/Application.java) returns `true`.
|
||||||
Also, covers `activeInTestMode` as test mode implies headless mode.
|
Also, covers `activeInTestMode` as test mode implies headless mode.
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||||
|
|
||||||
A _service_ is a plugin component loaded on demand when your plugin calls the `getService()` method of corresponding [`ComponentManager`](upsource:///platform/extensions/src/com/intellij/openapi/components/ComponentManager.java) instance (see [Types](#types)).
|
A _service_ is a plugin component loaded on demand when your plugin calls the `getService()` method of corresponding [`ComponentManager`](%gh-ic%/platform/extensions/src/com/intellij/openapi/components/ComponentManager.java) instance (see [Types](#types)).
|
||||||
The IntelliJ Platform ensures that only one instance of a service is loaded even though it is called several times.
|
The IntelliJ Platform ensures that only one instance of a service is loaded even though it is called several times.
|
||||||
|
|
||||||
A service must have an implementation class that is used for service instantiation.
|
A service must have an implementation class that is used for service instantiation.
|
||||||
A service may also have an interface class used to obtain the service instance and provide the service's API.
|
A service may also have an interface class used to obtain the service instance and provide the service's API.
|
||||||
|
|
||||||
A service needing a shutdown hook/cleanup routine can implement [`Disposable`](upsource:///platform/util/src/com/intellij/openapi/Disposable.java) and perform necessary work in `dispose()` (see [Automatically Disposed Objects](disposers.md#automatically-disposed-objects)).
|
A service needing a shutdown hook/cleanup routine can implement [`Disposable`](%gh-ic%/platform/util/src/com/intellij/openapi/Disposable.java) and perform necessary work in `dispose()` (see [Automatically Disposed Objects](disposers.md#automatically-disposed-objects)).
|
||||||
|
|
||||||
Services are used to encapsulate logic operating on a set of related classes or to provide some reusable functionality that can be used across the plugin project, and conceptually don't differ from the service classes in other languages or frameworks.
|
Services are used to encapsulate logic operating on a set of related classes or to provide some reusable functionality that can be used across the plugin project, and conceptually don't differ from the service classes in other languages or frameworks.
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ To improve startup performance, avoid any heavy initializations in the construct
|
|||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
A service not going to be overridden does not need to be registered in <path>plugin.xml</path> (see [Declaring a Service](#declaring-a-service)).
|
A service not going to be overridden does not need to be registered in <path>plugin.xml</path> (see [Declaring a Service](#declaring-a-service)).
|
||||||
Instead, annotate service class with [`@Service`](upsource:///platform/core-api/src/com/intellij/openapi/components/Service.java).
|
Instead, annotate service class with [`@Service`](%gh-ic%/platform/core-api/src/com/intellij/openapi/components/Service.java).
|
||||||
The service instance will be created in scope according to the caller (see [Retrieving a Service](#retrieving-a-service)).
|
The service instance will be created in scope according to the caller (see [Retrieving a Service](#retrieving-a-service)).
|
||||||
|
|
||||||
Restrictions:
|
Restrictions:
|
||||||
|
@ -16,7 +16,7 @@ The project structure and Java classes available to manage projects and modules
|
|||||||
This section briefly discusses the IDEA project structure, project components, and related terms.
|
This section briefly discusses the IDEA project structure, project components, and related terms.
|
||||||
For more information about projects and their components, refer to [Project](https://www.jetbrains.com/help/idea/about-projects.html), [Module](https://www.jetbrains.com/help/idea/creating-and-managing-modules.html), [Library](https://www.jetbrains.com/help/idea/working-with-libraries.html), [Facet](https://www.jetbrains.com/help/idea/adding-support-for-frameworks-and-technologies.html#facets) in the IntelliJ IDEA Web Help.
|
For more information about projects and their components, refer to [Project](https://www.jetbrains.com/help/idea/about-projects.html), [Module](https://www.jetbrains.com/help/idea/creating-and-managing-modules.html), [Library](https://www.jetbrains.com/help/idea/working-with-libraries.html), [Facet](https://www.jetbrains.com/help/idea/adding-support-for-frameworks-and-technologies.html#facets) in the IntelliJ IDEA Web Help.
|
||||||
|
|
||||||
Use [`ProjectSettingsService`](upsource:///platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java) to open related entries in <control>Project Structure</control> dialog.
|
Use [`ProjectSettingsService`](%gh-ic%/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java) to open related entries in <control>Project Structure</control> dialog.
|
||||||
|
|
||||||
### Project
|
### Project
|
||||||
In the IntelliJ Platform, a _project_ encapsulates all of a project's source code, libraries, and build instructions into a single organizational unit.
|
In the IntelliJ Platform, a _project_ encapsulates all of a project's source code, libraries, and build instructions into a single organizational unit.
|
||||||
|
@ -13,8 +13,8 @@ This is used to, e.g., change the icon of module nodes to reflect the module typ
|
|||||||
to Python Jupyter directories as location strings.
|
to Python Jupyter directories as location strings.
|
||||||
|
|
||||||
To modify project view node representations, implement
|
To modify project view node representations, implement
|
||||||
[`ProjectViewNodeDecorator`](upsource:///platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewNodeDecorator.java)
|
[`ProjectViewNodeDecorator`](%gh-ic%/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewNodeDecorator.java)
|
||||||
and register it as `com.intellij.projectViewNodeDecorator` extension.
|
and register it as `com.intellij.projectViewNodeDecorator` extension.
|
||||||
From the interface only the `decorate()` method that modifies `ProjectViewNode`s needs to be implemented.
|
From the interface only the `decorate()` method that modifies `ProjectViewNode`s needs to be implemented.
|
||||||
If you need to update your node representation on certain events, please use
|
If you need to update your node representation on certain events, please use
|
||||||
[`ProjectView.update()`](upsource:///platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java).
|
[`ProjectView.update()`](%gh-ic%/platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java).
|
||||||
|
@ -17,19 +17,19 @@ Unlike [Developing Custom Language Plugins](custom_language_support.md), it is a
|
|||||||
|
|
||||||
### 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()`](upsource:///platform/indexing-api/src/com/intellij/psi/search/FilenameIndex.java)
|
[`FilenameIndex.getFilesByName()`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/search/FilenameIndex.java)
|
||||||
|
|
||||||
### How do I find where a particular PSI element is used?
|
### How do I find where a particular PSI element is used?
|
||||||
|
|
||||||
[`ReferencesSearch.search()`](upsource:///platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java)
|
[`ReferencesSearch.search()`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java)
|
||||||
|
|
||||||
### How do I rename a PSI element?
|
### How do I rename a PSI element?
|
||||||
|
|
||||||
[`RefactoringFactory.createRename()`](upsource:///platform/lang-api/src/com/intellij/refactoring/RefactoringFactory.java)
|
[`RefactoringFactory.createRename()`](%gh-ic%/platform/lang-api/src/com/intellij/refactoring/RefactoringFactory.java)
|
||||||
|
|
||||||
### 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()`](upsource:///platform/analysis-api/src/com/intellij/util/FileContentUtil.java)
|
[`FileContentUtil.reparseFiles()`](%gh-ic%/platform/analysis-api/src/com/intellij/util/FileContentUtil.java)
|
||||||
|
|
||||||
## Java Specific
|
## Java Specific
|
||||||
|
|
||||||
@ -40,19 +40,19 @@ Unlike [Developing Custom Language Plugins](custom_language_support.md), it is a
|
|||||||
|
|
||||||
### How do I find all inheritors of a class?
|
### How do I find all inheritors of a class?
|
||||||
|
|
||||||
[`ClassInheritorsSearch.search()`](upsource:///java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java)
|
[`ClassInheritorsSearch.search()`](%gh-ic%/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java)
|
||||||
|
|
||||||
### How do I find a class by qualified name?
|
### How do I find a class by qualified name?
|
||||||
|
|
||||||
[`JavaPsiFacade.findClass()`](upsource:///java/java-psi-api/src/com/intellij/psi/JavaPsiFacade.java)
|
[`JavaPsiFacade.findClass()`](%gh-ic%/java/java-psi-api/src/com/intellij/psi/JavaPsiFacade.java)
|
||||||
|
|
||||||
### How do I find a class by short name?
|
### How do I find a class by short name?
|
||||||
|
|
||||||
[`PsiShortNamesCache.getClassesByName()`](upsource:///java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java)
|
[`PsiShortNamesCache.getClassesByName()`](%gh-ic%/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java)
|
||||||
|
|
||||||
### How do I find a superclass of a Java class?
|
### How do I find a superclass of a Java class?
|
||||||
|
|
||||||
[`PsiClass.getSuperClass()`](upsource:///java/java-psi-api/src/com/intellij/psi/PsiClass.java)
|
[`PsiClass.getSuperClass()`](%gh-ic%/java/java-psi-api/src/com/intellij/psi/PsiClass.java)
|
||||||
|
|
||||||
### How do I get a reference to the containing package of a Java class?
|
### How do I get a reference to the containing package of a Java class?
|
||||||
|
|
||||||
@ -64,8 +64,8 @@ PsiPackage psiPackage = JavaPsiFacade.getInstance(project)
|
|||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
[`PsiUtil.getPackageName()`](upsource:///java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java)
|
[`PsiUtil.getPackageName()`](%gh-ic%/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java)
|
||||||
|
|
||||||
### How do I find the methods overriding a specific method?
|
### How do I find the methods overriding a specific method?
|
||||||
|
|
||||||
[`OverridingMethodsSearch.search()`](upsource:///java/java-indexing-api/src/com/intellij/psi/search/searches/OverridingMethodsSearch.java)
|
[`OverridingMethodsSearch.search()`](%gh-ic%/java/java-indexing-api/src/com/intellij/psi/search/searches/OverridingMethodsSearch.java)
|
||||||
|
@ -6,21 +6,21 @@ The standard execution of a run action goes through the following steps:
|
|||||||
|
|
||||||
* The user selects a *run configuration* (for example, by choosing one from the run configurations combo box) and an *executor* (for example, by pressing a toolbar button created by the executor).
|
* The user selects a *run configuration* (for example, by choosing one from the run configurations combo box) and an *executor* (for example, by pressing a toolbar button created by the executor).
|
||||||
* The *program runner* that will actually execute the process is selected by polling all registered program runners and asking whether they can run the specified run profile with the specified executor ID.
|
* The *program runner* that will actually execute the process is selected by polling all registered program runners and asking whether they can run the specified run profile with the specified executor ID.
|
||||||
* The [`ExecutionEnvironment`](upsource:///platform/execution/src/com/intellij/execution/runners/ExecutionEnvironment.java) object is created.
|
* The [`ExecutionEnvironment`](%gh-ic%/platform/execution/src/com/intellij/execution/runners/ExecutionEnvironment.java) object is created.
|
||||||
This object aggregates all the settings required to execute the process and the selected [`ProgramRunner`](upsource:///platform/execution/src/com/intellij/execution/runners/ProgramRunner.java).
|
This object aggregates all the settings required to execute the process and the selected [`ProgramRunner`](%gh-ic%/platform/execution/src/com/intellij/execution/runners/ProgramRunner.java).
|
||||||
* `ProgramRunner.execute()` is called, receiving the executor and the execution environment.
|
* `ProgramRunner.execute()` is called, receiving the executor and the execution environment.
|
||||||
|
|
||||||
Implementations of `ProgramRunner.execute()` go through the following steps to execute the process:
|
Implementations of `ProgramRunner.execute()` go through the following steps to execute the process:
|
||||||
|
|
||||||
* `RunProfile.getState()` method is called to create a [`RunProfileState`](upsource:///platform/execution/src/com/intellij/execution/configurations/RunProfileState.java) object, describing a process about to be started.
|
* `RunProfile.getState()` method is called to create a [`RunProfileState`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunProfileState.java) object, describing a process about to be started.
|
||||||
At this stage, the command line parameters, environment variables, and other information required to start the process are initialized.
|
At this stage, the command line parameters, environment variables, and other information required to start the process are initialized.
|
||||||
* `RunProfileState.execute()` is called.
|
* `RunProfileState.execute()` is called.
|
||||||
It starts the process, attaches a `ProcessHandler` to its input and output streams, creates a console to display the process output, and returns an [`ExecutionResult`](upsource:///platform/execution/src/com/intellij/execution/ExecutionResult.java) object aggregating the console and the process handler.
|
It starts the process, attaches a `ProcessHandler` to its input and output streams, creates a console to display the process output, and returns an [`ExecutionResult`](%gh-ic%/platform/execution/src/com/intellij/execution/ExecutionResult.java) object aggregating the console and the process handler.
|
||||||
* The `RunContentBuilder` object is created and invoked to display the execution console in a tab of the Run or Debug tool window.
|
* The `RunContentBuilder` object is created and invoked to display the execution console in a tab of the Run or Debug tool window.
|
||||||
|
|
||||||
## Executor
|
## Executor
|
||||||
|
|
||||||
The [`Executor`](upsource:///platform/execution/src/com/intellij/execution/Executor.java) interface describes a specific way of executing any possible run configuration.
|
The [`Executor`](%gh-ic%/platform/execution/src/com/intellij/execution/Executor.java) interface describes a specific way of executing any possible run configuration.
|
||||||
|
|
||||||
The three default executors provided by the IntelliJ Platform by default are _Run_, _Debug_, and _Run with Coverage_. Each executor gets its own toolbar button, which starts the selected run configuration using this executor, and its own context menu item for starting a configuration using this executor.
|
The three default executors provided by the IntelliJ Platform by default are _Run_, _Debug_, and _Run with Coverage_. Each executor gets its own toolbar button, which starts the selected run configuration using this executor, and its own context menu item for starting a configuration using this executor.
|
||||||
|
|
||||||
@ -32,35 +32,35 @@ However, it can be useful, for example, if you're implementing a profiler integr
|
|||||||
The `RunProfileState` interface comes up in every run configuration implementation as the return value `RunProfile.getState()`.
|
The `RunProfileState` interface comes up in every run configuration implementation as the return value `RunProfile.getState()`.
|
||||||
It describes a process that is ready to be started and holds information like the command line, current working directory, and environment variables for the process to be started. (The existence of `RunProfileState` as a separate step in the execution flow allows run configuration extensions and other components to patch the configuration and modify the parameters before it gets executed.)
|
It describes a process that is ready to be started and holds information like the command line, current working directory, and environment variables for the process to be started. (The existence of `RunProfileState` as a separate step in the execution flow allows run configuration extensions and other components to patch the configuration and modify the parameters before it gets executed.)
|
||||||
|
|
||||||
The standard base class used as implementation of `RunProfileState` is [`CommandLineState`](upsource:///platform/execution/src/com/intellij/execution/configurations/CommandLineState.java).
|
The standard base class used as implementation of `RunProfileState` is [`CommandLineState`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/CommandLineState.java).
|
||||||
It contains the logic for putting together a running process and a console into an [`ExecutionResult`](upsource:///platform/execution/src/com/intellij/execution/ExecutionResult.java), but doesn't know anything how the process is actually started.
|
It contains the logic for putting together a running process and a console into an [`ExecutionResult`](%gh-ic%/platform/execution/src/com/intellij/execution/ExecutionResult.java), but doesn't know anything how the process is actually started.
|
||||||
For starting the process, it's best to use the [`GeneralCommandLine`](upsource:///platform/platform-util-io/src/com/intellij/execution/configurations/GeneralCommandLine.java) class, which takes care of setting up the command line parameters and executing the process.
|
For starting the process, it's best to use the [`GeneralCommandLine`](%gh-ic%/platform/platform-util-io/src/com/intellij/execution/configurations/GeneralCommandLine.java) class, which takes care of setting up the command line parameters and executing the process.
|
||||||
|
|
||||||
Alternatively, if the process you need to run is a JVM-based one, you can use the [`JavaCommandLineState`](upsource:///java/execution/impl/src/com/intellij/execution/configurations/JavaCommandLineState.java) base class.
|
Alternatively, if the process you need to run is a JVM-based one, you can use the [`JavaCommandLineState`](%gh-ic%/java/execution/impl/src/com/intellij/execution/configurations/JavaCommandLineState.java) base class.
|
||||||
It knows about the JVM command line parameters and can take care of details like calculating the classpath for the JVM.
|
It knows about the JVM command line parameters and can take care of details like calculating the classpath for the JVM.
|
||||||
|
|
||||||
To monitor the execution of a process and capture its output, the [`OSProcessHandler`](upsource:///platform/platform-util-io/src/com/intellij/execution/process/OSProcessHandler.java) class is usually used.
|
To monitor the execution of a process and capture its output, the [`OSProcessHandler`](%gh-ic%/platform/platform-util-io/src/com/intellij/execution/process/OSProcessHandler.java) class is usually used.
|
||||||
Once you've created an instance of `OSProcessHandler` from either a command line or a Process object, you need to call the `startNotify()` method to capture its output.
|
Once you've created an instance of `OSProcessHandler` from either a command line or a Process object, you need to call the `startNotify()` method to capture its output.
|
||||||
You may also want to attach a [`ProcessTerminatedListener`](upsource:///platform/ide-core/src/com/intellij/execution/process/ProcessTerminatedListener.java) to the `OSProcessHandler` so that the exit status of the process will be displayed in the console.
|
You may also want to attach a [`ProcessTerminatedListener`](%gh-ic%/platform/ide-core/src/com/intellij/execution/process/ProcessTerminatedListener.java) to the `OSProcessHandler` so that the exit status of the process will be displayed in the console.
|
||||||
|
|
||||||
## Displaying Process Output
|
## Displaying Process Output
|
||||||
|
|
||||||
If you're using `CommandLineState`, a console view will be automatically created and attached to the process's output.
|
If you're using `CommandLineState`, a console view will be automatically created and attached to the process's output.
|
||||||
Alternatively, you can arrange this yourself:
|
Alternatively, you can arrange this yourself:
|
||||||
|
|
||||||
* `TextConsoleBuilderFactory.createBuilder(project).getConsole()` creates a [`ConsoleView`](upsource:///platform/execution/src/com/intellij/execution/ui/ConsoleView.java) instance
|
* `TextConsoleBuilderFactory.createBuilder(project).getConsole()` creates a [`ConsoleView`](%gh-ic%/platform/execution/src/com/intellij/execution/ui/ConsoleView.java) instance
|
||||||
* `ConsoleView.attachToProcess()` attaches it to the output of a process.
|
* `ConsoleView.attachToProcess()` attaches it to the output of a process.
|
||||||
|
|
||||||
If the running process uses ANSI escape codes to color its output, the [`ColoredProcessHandler`](upsource:///platform/platform-util-io/src/com/intellij/execution/process/ColoredProcessHandler.java) class will parse it and display the colors in the IntelliJ console.
|
If the running process uses ANSI escape codes to color its output, the [`ColoredProcessHandler`](%gh-ic%/platform/platform-util-io/src/com/intellij/execution/process/ColoredProcessHandler.java) class will parse it and display the colors in the IntelliJ console.
|
||||||
|
|
||||||
Console [`Filter`](upsource:///platform/execution/src/com/intellij/execution/filters/Filter.java) allows you to convert certain strings found in the process output to clickable hyperlinks.
|
Console [`Filter`](%gh-ic%/platform/execution/src/com/intellij/execution/filters/Filter.java) allows you to convert certain strings found in the process output to clickable hyperlinks.
|
||||||
To attach a filter to the console, use `CommandLineState.addConsoleFilters()` or, if you're creating a console manually, `TextConsoleBuilder.addFilter()`.
|
To attach a filter to the console, use `CommandLineState.addConsoleFilters()` or, if you're creating a console manually, `TextConsoleBuilder.addFilter()`.
|
||||||
|
|
||||||
Two common filter implementations you may want to reuse are [`RegexpFilter`](upsource:///platform/lang-api/src/com/intellij/execution/filters/RegexpFilter.java) and [`UrlFilter`](upsource:///platform/execution-impl/src/com/intellij/execution/filters/UrlFilter.java).
|
Two common filter implementations you may want to reuse are [`RegexpFilter`](%gh-ic%/platform/lang-api/src/com/intellij/execution/filters/RegexpFilter.java) and [`UrlFilter`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/filters/UrlFilter.java).
|
||||||
|
|
||||||
## Starting a Run Configuration from Code
|
## Starting a Run Configuration from Code
|
||||||
|
|
||||||
If you have an existing run configuration that you need to execute, the easiest way to do so is to use [`ProgramRunnerUtil.executeConfiguration()`](upsource:///platform/execution-impl/src/com/intellij/execution/ProgramRunnerUtil.java).
|
If you have an existing run configuration that you need to execute, the easiest way to do so is to use [`ProgramRunnerUtil.executeConfiguration()`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/ProgramRunnerUtil.java).
|
||||||
The method takes a [`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java), a [`RunnerAndConfigurationSettings`](upsource:///platform/execution/src/com/intellij/execution/RunnerAndConfigurationSettings.java), as well as an [`Executor`](upsource:///platform/execution/src/com/intellij/execution/Executor.java).
|
The method takes a [`Project`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/Project.java), a [`RunnerAndConfigurationSettings`](%gh-ic%/platform/execution/src/com/intellij/execution/RunnerAndConfigurationSettings.java), as well as an [`Executor`](%gh-ic%/platform/execution/src/com/intellij/execution/Executor.java).
|
||||||
To get the `RunnerAndConfigurationSettings` for an existing configuration, you can use, for example, `RunManager.getConfigurationSettings(ConfigurationType)`.
|
To get the `RunnerAndConfigurationSettings` for an existing configuration, you can use, for example, `RunManager.getConfigurationSettings(ConfigurationType)`.
|
||||||
As the last parameter, you normally pass either `DefaultRunExecutor.getRunExecutorInstance()` or `DefaultDebugExecutor.getDebugExecutorInstance()`.
|
As the last parameter, you normally pass either `DefaultRunExecutor.getRunExecutorInstance()` or `DefaultDebugExecutor.getDebugExecutorInstance()`.
|
||||||
|
@ -6,40 +6,40 @@ This document describes the primary classes to work with run configurations and
|
|||||||
|
|
||||||
## Configuration Type
|
## Configuration Type
|
||||||
|
|
||||||
The starting point for implementing any run configuration type is the [`ConfigurationType`](upsource:///platform/execution/src/com/intellij/execution/configurations/ConfigurationType.java) interface.
|
The starting point for implementing any run configuration type is the [`ConfigurationType`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationType.java) interface.
|
||||||
The list of available configuration types is shown when a user opens the _'Edit run configurations'_ dialog and executes _'Add'_ action:
|
The list of available configuration types is shown when a user opens the _'Edit run configurations'_ dialog and executes _'Add'_ action:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Every type there is represented as an instance of [`ConfigurationType`](upsource:///platform/execution/src/com/intellij/execution/configurations/ConfigurationType.java) and registered like below:
|
Every type there is represented as an instance of [`ConfigurationType`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationType.java) and registered like below:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<configurationType
|
<configurationType
|
||||||
implementation="org.jetbrains.plugins.gradle.service.execution.GradleExternalTaskConfigurationType"/>
|
implementation="org.jetbrains.plugins.gradle.service.execution.GradleExternalTaskConfigurationType"/>
|
||||||
```
|
```
|
||||||
|
|
||||||
The easiest way to implement this interface is to use the [`ConfigurationTypeBase`](upsource:///platform/execution/src/com/intellij/execution/configurations/runConfigurationType.kt) base class.
|
The easiest way to implement this interface is to use the [`ConfigurationTypeBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/runConfigurationType.kt) base class.
|
||||||
To use it, you need to inherit from it and to provide the configuration type parameters (ID, name, description, and icon) as constructor parameters.
|
To use it, you need to inherit from it and to provide the configuration type parameters (ID, name, description, and icon) as constructor parameters.
|
||||||
In addition to that, you need to call the [`addFactory()`](upsource:///platform/execution/src/com/intellij/execution/configurations/runConfigurationType.kt) method to add a configuration factory.
|
In addition to that, you need to call the [`addFactory()`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/runConfigurationType.kt) method to add a configuration factory.
|
||||||
|
|
||||||
## Configuration Factory
|
## Configuration Factory
|
||||||
|
|
||||||
All run configurations are created by the [`ConfigurationFactory`](upsource:///platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) registered for a particular `ConfigurationType`.
|
All run configurations are created by the [`ConfigurationFactory`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) registered for a particular `ConfigurationType`.
|
||||||
It's possible that one `ConfigurationType` has more than one `ConfigurationFactory`:
|
It's possible that one `ConfigurationType` has more than one `ConfigurationFactory`:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
The key API of `ConfigurationFactory`, and the only method that you're required to implement, is the [`createTemplateConfiguration`](upsource:///platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) method.
|
The key API of `ConfigurationFactory`, and the only method that you're required to implement, is the [`createTemplateConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) method.
|
||||||
This method is called once per project to create the template run configuration.
|
This method is called once per project to create the template run configuration.
|
||||||
|
|
||||||
All real run configurations (loaded from the workspace or created by the user) are called by cloning the template through the [`createConfiguration`](upsource:///platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) method.
|
All real run configurations (loaded from the workspace or created by the user) are called by cloning the template through the [`createConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) method.
|
||||||
|
|
||||||
You can customize additional aspects of your configuration factory by overriding the [`getIcon`](upsource:///platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java), [`getAddIcon`](upsource:///platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java), [`getName`](upsource:///platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) and the default settings methods.
|
You can customize additional aspects of your configuration factory by overriding the [`getIcon`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java), [`getAddIcon`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java), [`getName`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) and the default settings methods.
|
||||||
These additional overrides are optional.
|
These additional overrides are optional.
|
||||||
|
|
||||||
## Run Configuration
|
## Run Configuration
|
||||||
|
|
||||||
The run configuration itself is represented by the [`RunConfiguration`](upsource:///platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) interface.
|
The run configuration itself is represented by the [`RunConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) interface.
|
||||||
A _'run configuration'_ here is some named profile which can be executed, e.g., the application started via `main()` class, test, remote debug to particular machine/port, etc.
|
A _'run configuration'_ here is some named profile which can be executed, e.g., the application started via `main()` class, test, remote debug to particular machine/port, etc.
|
||||||
|
|
||||||
Here is an example of a Java run configuration defined for a particular project:
|
Here is an example of a Java run configuration defined for a particular project:
|
||||||
@ -48,17 +48,17 @@ Here is an example of a Java run configuration defined for a particular project:
|
|||||||
|
|
||||||
When implementing a run configuration, you may want to use one of the common base classes:
|
When implementing a run configuration, you may want to use one of the common base classes:
|
||||||
|
|
||||||
* [`RunConfigurationBase`](upsource:///platform/execution/src/com/intellij/execution/configurations/RunConfigurationBase.java) is a general-purpose superclass that contains the most basic implementation of a run configuration.
|
* [`RunConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfigurationBase.java) is a general-purpose superclass that contains the most basic implementation of a run configuration.
|
||||||
* [`LocatableConfigurationBase`](upsource:///platform/execution/src/com/intellij/execution/configurations/LocatableConfigurationBase.java) is a common base class that should be used for configurations that can be created from context by a `RunConfigurationProducer`.
|
* [`LocatableConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/LocatableConfigurationBase.java) is a common base class that should be used for configurations that can be created from context by a `RunConfigurationProducer`.
|
||||||
It supports automatically generating a name for a configuration from its settings and keeping track of whether the name was changed by the user.
|
It supports automatically generating a name for a configuration from its settings and keeping track of whether the name was changed by the user.
|
||||||
* [`ModuleBasedConfiguration`](upsource:///platform/execution/src/com/intellij/execution/configurations/ModuleBasedConfiguration.java) is a base class for a configuration that is associated with a specific module (for example, Java run configurations use the selected module to determine the run classpath).
|
* [`ModuleBasedConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ModuleBasedConfiguration.java) is a base class for a configuration that is associated with a specific module (for example, Java run configurations use the selected module to determine the run classpath).
|
||||||
|
|
||||||
## Settings Editor
|
## Settings Editor
|
||||||
|
|
||||||
That common run configuration settings might be modified via:
|
That common run configuration settings might be modified via:
|
||||||
|
|
||||||
[`RunConfiguration`-specific UI](upsource:///platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java)
|
[`RunConfiguration`-specific UI](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java)
|
||||||
That is handled by [`SettingsEditor`](upsource:///platform/ide-core/src/com/intellij/openapi/options/SettingsEditor.java):
|
That is handled by [`SettingsEditor`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/SettingsEditor.java):
|
||||||
|
|
||||||
* `getComponent()` method is called by the IDE and shows run configuration specific UI.
|
* `getComponent()` method is called by the IDE and shows run configuration specific UI.
|
||||||
* `resetFrom()` is called to discard all non-confirmed user changes made via that UI.
|
* `resetFrom()` is called to discard all non-confirmed user changes made via that UI.
|
||||||
@ -67,9 +67,9 @@ That is handled by [`SettingsEditor`](upsource:///platform/ide-core/src/com/inte
|
|||||||
## Persistence
|
## Persistence
|
||||||
|
|
||||||
That run configuration settings are persistent, i.e., they are stored at the file system and loaded back on the IDE startup.
|
That run configuration settings are persistent, i.e., they are stored at the file system and loaded back on the IDE startup.
|
||||||
That is performed via [`writeExternal()`](upsource:///platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) and [`readExternal()`](upsource:///platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) methods of [`RunConfiguration`](upsource:///platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) class correspondingly.
|
That is performed via [`writeExternal()`](%gh-ic%/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) and [`readExternal()`](%gh-ic%/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) methods of [`RunConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) class correspondingly.
|
||||||
|
|
||||||
The actual configurations stored by the IntelliJ Platform are represented by instances of the [`RunnerAndConfigurationSettings`](upsource:///platform/execution/src/com/intellij/execution/RunnerAndConfigurationSettings.java) class, which combines a run configuration with runner-specific settings, as well as keeping track of certain run configuration flags such as "temporary" or "singleton".
|
The actual configurations stored by the IntelliJ Platform are represented by instances of the [`RunnerAndConfigurationSettings`](%gh-ic%/platform/execution/src/com/intellij/execution/RunnerAndConfigurationSettings.java) class, which combines a run configuration with runner-specific settings, as well as keeping track of certain run configuration flags such as "temporary" or "singleton".
|
||||||
|
|
||||||
Dealing with instances of this class becomes necessary when you need to create run configurations from code.
|
Dealing with instances of this class becomes necessary when you need to create run configurations from code.
|
||||||
This is accomplished with the following two steps:
|
This is accomplished with the following two steps:
|
||||||
@ -81,16 +81,16 @@ This is accomplished with the following two steps:
|
|||||||
|
|
||||||
Most run configurations contain references to classes, files, or directories in their settings, and these settings usually need to be updated when the corresponding element is renamed or moved.
|
Most run configurations contain references to classes, files, or directories in their settings, and these settings usually need to be updated when the corresponding element is renamed or moved.
|
||||||
|
|
||||||
To support that, your run configuration needs to implement the [`RefactoringListenerProvider`](upsource:///platform/execution/src/com/intellij/execution/configurations/RefactoringListenerProvider.java) interface.
|
To support that, your run configuration needs to implement the [`RefactoringListenerProvider`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RefactoringListenerProvider.java) interface.
|
||||||
|
|
||||||
In your implementation of `getRefactoringElementListener()`, you need to check whether the refactored element is the one that your run configuration refers to.
|
In your implementation of `getRefactoringElementListener()`, you need to check whether the refactored element is the one that your run configuration refers to.
|
||||||
If it is, you return a [`RefactoringElementListener`](upsource:///platform/analysis-api/src/com/intellij/refactoring/listeners/RefactoringElementListener.java) that updates your configuration according to the new name and location of the element.
|
If it is, you return a [`RefactoringElementListener`](%gh-ic%/platform/analysis-api/src/com/intellij/refactoring/listeners/RefactoringElementListener.java) that updates your configuration according to the new name and location of the element.
|
||||||
|
|
||||||
## Creating Configurations from Context
|
## Creating Configurations from Context
|
||||||
|
|
||||||
Many plugins support automatic creation of run configurations from context so that the user can click, for example, on an application or test class and automatically run it using the correct run configuration type.
|
Many plugins support automatic creation of run configurations from context so that the user can click, for example, on an application or test class and automatically run it using the correct run configuration type.
|
||||||
To support that, you need to provide an implementation of the [`RunConfigurationProducer`](upsource:///platform/lang-api/src/com/intellij/execution/actions/RunConfigurationProducer.java) interface and to register it as `<runConfigurationProducer>` in your <path>plugin.xml</path>.
|
To support that, you need to provide an implementation of the [`RunConfigurationProducer`](%gh-ic%/platform/lang-api/src/com/intellij/execution/actions/RunConfigurationProducer.java) interface and to register it as `<runConfigurationProducer>` in your <path>plugin.xml</path>.
|
||||||
This API was redesigned in IntelliJ IDEA 13; the previous [`RuntimeConfigurationProducer`](upsource:///platform/lang-api/src/com/intellij/execution/junit/RuntimeConfigurationProducer.java) is a much more confusing version of the same API.
|
This API was redesigned in IntelliJ IDEA 13; the previous [`RuntimeConfigurationProducer`](%gh-ic%/platform/lang-api/src/com/intellij/execution/junit/RuntimeConfigurationProducer.java) is a much more confusing version of the same API.
|
||||||
|
|
||||||
The two main methods that you need to implement are:
|
The two main methods that you need to implement are:
|
||||||
|
|
||||||
@ -100,8 +100,8 @@ The two main methods that you need to implement are:
|
|||||||
* `isConfigurationFromContext()` checks if your type's specified configuration was created from the specified context.
|
* `isConfigurationFromContext()` checks if your type's specified configuration was created from the specified context.
|
||||||
Implementing this method allows you to reuse an existing run configuration, which applies to the current context instead of creating a new one and possibly ignoring the user's customizations in the existing one.
|
Implementing this method allows you to reuse an existing run configuration, which applies to the current context instead of creating a new one and possibly ignoring the user's customizations in the existing one.
|
||||||
|
|
||||||
Note that, to support the automatic naming of configurations created from context, your configuration should use [`LocatableConfigurationBase`](upsource:///platform/execution/src/com/intellij/execution/configurations/LocatableConfigurationBase.java) as the base class.
|
Note that, to support the automatic naming of configurations created from context, your configuration should use [`LocatableConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/LocatableConfigurationBase.java) as the base class.
|
||||||
|
|
||||||
## Running from the Gutter
|
## Running from the Gutter
|
||||||
|
|
||||||
Take a look at [`RunLineMarkerContributor`](upsource:///platform/execution-impl/src/com/intellij/execution/lineMarker/RunLineMarkerContributor.java) and its implementations.
|
Take a look at [`RunLineMarkerContributor`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/lineMarker/RunLineMarkerContributor.java) and its implementations.
|
||||||
|
@ -20,13 +20,13 @@ Light and heavy tests use different base classes or fixture classes, as describe
|
|||||||
|
|
||||||
The standard way of writing a light test is to extend the following classes:
|
The standard way of writing a light test is to extend the following classes:
|
||||||
|
|
||||||
* [`BasePlatformTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/BasePlatformTestCase.java) (2019.2 and later) for tests that don't have any Java dependencies.
|
* [`BasePlatformTestCase`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/BasePlatformTestCase.java) (2019.2 and later) for tests that don't have any Java dependencies.
|
||||||
For plugins using pre-2019.2 versions use [`LightPlatformCodeInsightFixtureTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/LightPlatformCodeInsightFixtureTestCase.java).
|
For plugins using pre-2019.2 versions use [`LightPlatformCodeInsightFixtureTestCase`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/LightPlatformCodeInsightFixtureTestCase.java).
|
||||||
* [`LightJavaCodeInsightFixtureTestCase`](upsource:///java/testFramework/src/com/intellij/testFramework/fixtures/LightJavaCodeInsightFixtureTestCase.java) (2019.2 and later) for tests that require the Java PSI or any related functionality.
|
* [`LightJavaCodeInsightFixtureTestCase`](%gh-ic%/java/testFramework/src/com/intellij/testFramework/fixtures/LightJavaCodeInsightFixtureTestCase.java) (2019.2 and later) for tests that require the Java PSI or any related functionality.
|
||||||
For plugins using pre-2019.2 versions use [`LightCodeInsightFixtureTestCase`](upsource:///java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java).
|
For plugins using pre-2019.2 versions use [`LightCodeInsightFixtureTestCase`](%gh-ic%/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java).
|
||||||
|
|
||||||
When writing a light test, you can specify the project's requirements that you need to have in your test, such as the module type, the configured [SDK](sdk.md), [facets](facet.md), [libraries](library.md), etc.
|
When writing a light test, you can specify the project's requirements that you need to have in your test, such as the module type, the configured [SDK](sdk.md), [facets](facet.md), [libraries](library.md), etc.
|
||||||
You do so by extending the [`LightProjectDescriptor`](upsource:///platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java) class and returning your project descriptor (usually stored in `static final` field) from `getProjectDescriptor()`.
|
You do so by extending the [`LightProjectDescriptor`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java) class and returning your project descriptor (usually stored in `static final` field) from `getProjectDescriptor()`.
|
||||||
|
|
||||||
If your plugin builds on top of Java support, please see [](testing_faq.md#how-to-test-a-jvm-language) to set up your test environment to obtain the required _Mock JDK_ automatically.
|
If your plugin builds on top of Java support, please see [](testing_faq.md#how-to-test-a-jvm-language) to set up your test environment to obtain the required _Mock JDK_ automatically.
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ Before executing each test, the project instance will be reused if the test case
|
|||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
> In 2019.3, `PlatformTestCase` has been renamed to [`HeavyPlatformTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/HeavyPlatformTestCase.java) reflecting its "heavy test" characteristics.
|
> In 2019.3, `PlatformTestCase` has been renamed to [`HeavyPlatformTestCase`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/HeavyPlatformTestCase.java) reflecting its "heavy test" characteristics.
|
||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
The test fixture creates a *test project* environment.
|
The test fixture creates a *test project* environment.
|
||||||
Unless you customize the project creation, the test project will have one module with one source root called <path>src</path>.
|
Unless you customize the project creation, the test project will have one module with one source root called <path>src</path>.
|
||||||
The test project files exist either in a temporary directory or in an in-memory file system, depending on which implementation of [`TempDirTestFixture`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/TempDirTestFixture.java) is used.
|
The test project files exist either in a temporary directory or in an in-memory file system, depending on which implementation of [`TempDirTestFixture`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/TempDirTestFixture.java) is used.
|
||||||
|
|
||||||
[`BasePlatformTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/BasePlatformTestCase.java) (renamed from `LightPlatformCodeInsightFixtureTestCase` in 2019.2) uses an in-memory implementation; if you set up the test environment by calling `IdeaTestFixtureFactory.createCodeInsightFixture()`, you can specify the implementation to use.
|
[`BasePlatformTestCase`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/BasePlatformTestCase.java) (renamed from `LightPlatformCodeInsightFixtureTestCase` in 2019.2) uses an in-memory implementation; if you set up the test environment by calling `IdeaTestFixtureFactory.createCodeInsightFixture()`, you can specify the implementation to use.
|
||||||
|
|
||||||
> If your tests use the in-memory implementation, and you abort the execution of your tests, the persisted filesystem caches may get out of sync with the in-memory structures, and you may get spurious errors in your tests.
|
> If your tests use the in-memory implementation, and you abort the execution of your tests, the persisted filesystem caches may get out of sync with the in-memory structures, and you may get spurious errors in your tests.
|
||||||
> If you get an unexpected error after a series of successful runs, **try rerunning the test**, and if that doesn't help, **delete the "system" subdirectory** in your [sandbox directory](ide_development_instance.md#the-development-instance-sandbox-directory).
|
> If you get an unexpected error after a series of successful runs, **try rerunning the test**, and if that doesn't help, **delete the "system" subdirectory** in your [sandbox directory](ide_development_instance.md#the-development-instance-sandbox-directory).
|
||||||
@ -32,14 +32,14 @@ The default implementation assumes running as part of the IntelliJ Platform sour
|
|||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
To copy files or directories from your <path>testdata</path> directory to the test project directory, you can use the `copyFileToProject()` and `copyDirectoryToProject()` methods from [`CodeInsightTestFixture`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java).
|
To copy files or directories from your <path>testdata</path> directory to the test project directory, you can use the `copyFileToProject()` and `copyDirectoryToProject()` methods from [`CodeInsightTestFixture`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java).
|
||||||
|
|
||||||
Most operations in plugin tests require a file open in the in-memory editor, in which highlighting, completion, and other operations will be performed.
|
Most operations in plugin tests require a file open in the in-memory editor, in which highlighting, completion, and other operations will be performed.
|
||||||
The in-memory editor instance is returned by `CodeInsightTestFixture.getEditor()`.
|
The in-memory editor instance is returned by `CodeInsightTestFixture.getEditor()`.
|
||||||
To copy a file from the <path>testdata</path> directory to the test project directory and immediately open it in the editor, you can use the `CodeInsightTestFixture.configureByFile()` or `configureByFiles()` methods.
|
To copy a file from the <path>testdata</path> directory to the test project directory and immediately open it in the editor, you can use the `CodeInsightTestFixture.configureByFile()` or `configureByFiles()` methods.
|
||||||
The latter copies multiple files to the test project directory and opens the *first* of them in the in-memory editor.
|
The latter copies multiple files to the test project directory and opens the *first* of them in the in-memory editor.
|
||||||
|
|
||||||
Alternatively, you can use one of the other methods, which take parameters annotated with [`@TestDataFile`](upsource:///platform/testFramework/src/com/intellij/testFramework/TestDataFile.java).
|
Alternatively, you can use one of the other methods, which take parameters annotated with [`@TestDataFile`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/TestDataFile.java).
|
||||||
These methods copy the specified files from the <path>testdata</path> directory to the test project directory, open the first of the specified files in the in-memory editor, and then perform the requested operation such as highlighting or code completion.
|
These methods copy the specified files from the <path>testdata</path> directory to the test project directory, open the first of the specified files in the in-memory editor, and then perform the requested operation such as highlighting or code completion.
|
||||||
|
|
||||||
> The IDE supports smart navigation between test code and related test data file(s); see this [blog post](https://blog.jetbrains.com/platform/2017/10/improvements-in-testing-intellij-platform-plugins/) for more details.
|
> The IDE supports smart navigation between test code and related test data file(s); see this [blog post](https://blog.jetbrains.com/platform/2017/10/improvements-in-testing-intellij-platform-plugins/) for more details.
|
||||||
|
@ -6,20 +6,20 @@ This page lists a number of common questions/issues and techniques useful for te
|
|||||||
|
|
||||||
## Useful Classes
|
## Useful Classes
|
||||||
|
|
||||||
- [`UsefulTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java)
|
- [`UsefulTestCase`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java)
|
||||||
- [`PlatformTestUtil`](upsource:///platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java)
|
- [`PlatformTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java)
|
||||||
- [`CodeInsightTestUtil`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestUtil.java)
|
- [`CodeInsightTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestUtil.java)
|
||||||
- [`EditorTestUtil`](upsource:///platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java)
|
- [`EditorTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java)
|
||||||
- [`PsiTestUtil`](upsource:///platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java)
|
- [`PsiTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java)
|
||||||
- [`VfsTestUtil`](upsource:///platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java)
|
- [`VfsTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java)
|
||||||
- [`IoTestUtil`](upsource:///platform/testFramework/src/com/intellij/openapi/util/io/IoTestUtil.java)
|
- [`IoTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/openapi/util/io/IoTestUtil.java)
|
||||||
|
|
||||||
### UI
|
### UI
|
||||||
|
|
||||||
- [`ProjectViewTestUtil`](upsource:///platform/testFramework/src/com/intellij/testFramework/ProjectViewTestUtil.java)
|
- [`ProjectViewTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/ProjectViewTestUtil.java)
|
||||||
- [`TestLookupElementPresentation`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/TestLookupElementPresentation.java)
|
- [`TestLookupElementPresentation`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/TestLookupElementPresentation.java)
|
||||||
- [`IconTestUtil`](upsource:///platform/testFramework/src/com/intellij/ui/IconTestUtil.java)
|
- [`IconTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/ui/IconTestUtil.java)
|
||||||
- [`TreeTestUtil`](upsource:///platform/testFramework/src/com/intellij/ui/tree/TreeTestUtil.java)
|
- [`TreeTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/ui/tree/TreeTestUtil.java)
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ void tearDown() {
|
|||||||
|
|
||||||
Avoid OS-specific assumptions (e.g., filesystem case-sensitivity, hardcoded separator instead of `java.io.File.separator`, default encoding, line endings).
|
Avoid OS-specific assumptions (e.g., filesystem case-sensitivity, hardcoded separator instead of `java.io.File.separator`, default encoding, line endings).
|
||||||
|
|
||||||
Use _ordered_ collections or [`UsefulTestCase.assertUnorderedCollection()`](upsource:///platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java).
|
Use _ordered_ collections or [`UsefulTestCase.assertUnorderedCollection()`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java).
|
||||||
|
|
||||||
Code deferring execution (e.g., via `Application.invokeLater()`) might not run during test execution (and possibly fails in production, too).
|
Code deferring execution (e.g., via `Application.invokeLater()`) might not run during test execution (and possibly fails in production, too).
|
||||||
Use `Application.invokeLater(runnable, myProject.getDisposed())`.
|
Use `Application.invokeLater(runnable, myProject.getDisposed())`.
|
||||||
@ -74,7 +74,7 @@ Annotate with [`org.jetbrains.annotations.TestOnly`](https://github.com/JetBrain
|
|||||||
|
|
||||||
### How to run tests for all files in a directory?
|
### How to run tests for all files in a directory?
|
||||||
|
|
||||||
Use [`FileBasedTestCaseHelper`](upsource:///platform/testFramework/src/com/intellij/testFramework/FileBasedTestCaseHelper.java), please see its javadoc for instructions.
|
Use [`FileBasedTestCaseHelper`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/FileBasedTestCaseHelper.java), please see its javadoc for instructions.
|
||||||
|
|
||||||
### How to modify setup on a per-test basis?
|
### How to modify setup on a per-test basis?
|
||||||
|
|
||||||
@ -82,27 +82,27 @@ Use `UsefulTestCase.getTestName()` or create your own annotation(s) which can be
|
|||||||
|
|
||||||
### How to run a performance test?
|
### How to run a performance test?
|
||||||
|
|
||||||
Use [`PlatformTestUtil.startPerformanceTest()`](upsource:///platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java) to assert machine-adjusted metrics.
|
Use [`PlatformTestUtil.startPerformanceTest()`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java) to assert machine-adjusted metrics.
|
||||||
|
|
||||||
### How to dispatch pending UI events?
|
### How to dispatch pending UI events?
|
||||||
|
|
||||||
Use [`PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()`](upsource:///platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java).
|
Use [`PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java).
|
||||||
|
|
||||||
### How to disable stderr logging?
|
### How to disable stderr logging?
|
||||||
|
|
||||||
Use [`DefaultLogger.disableStderrDumping()`](upsource:///platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java) passing `getTestRootDisposable()`.
|
Use [`DefaultLogger.disableStderrDumping()`](%gh-ic%/platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java) passing `getTestRootDisposable()`.
|
||||||
|
|
||||||
### How to register a resource (DTD, XSD) temporarily?
|
### How to register a resource (DTD, XSD) temporarily?
|
||||||
|
|
||||||
Use [`ExternalResourceManagerExImpl.registerResourceTemporarily()`](upsource:///xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java) passing `getTestRootDisposable()`.
|
Use [`ExternalResourceManagerExImpl.registerResourceTemporarily()`](%gh-ic%/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java) passing `getTestRootDisposable()`.
|
||||||
|
|
||||||
### How to replace component/service in tests?
|
### How to replace component/service in tests?
|
||||||
|
|
||||||
Provide dedicated test implementation via `testServiceImplementation` in [service declaration](plugin_services.md#declaring-a-service), or use [`ServiceContainerUtil`](upsource:///platform/testFramework/src/com/intellij/testFramework/ServiceContainerUtil.kt).
|
Provide dedicated test implementation via `testServiceImplementation` in [service declaration](plugin_services.md#declaring-a-service), or use [`ServiceContainerUtil`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/ServiceContainerUtil.kt).
|
||||||
|
|
||||||
### How to replace extension points in tests?
|
### How to replace extension points in tests?
|
||||||
|
|
||||||
Use [`ExtensionTestUtil`](upsource:///platform/testFramework/src/com/intellij/testFramework/ExtensionTestUtil.kt).
|
Use [`ExtensionTestUtil`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/ExtensionTestUtil.kt).
|
||||||
|
|
||||||
### How to wait for a specified amount of time?
|
### How to wait for a specified amount of time?
|
||||||
|
|
||||||
@ -110,12 +110,12 @@ If possible, use [](#how-to-wait-for-condition-with-timeout) approach. Otherwise
|
|||||||
|
|
||||||
### How to wait for condition with timeout?
|
### How to wait for condition with timeout?
|
||||||
|
|
||||||
Use [`WaitFor`](upsource:///platform/util/src/com/intellij/util/WaitFor.java).
|
Use [`WaitFor`](%gh-ic%/platform/util/src/com/intellij/util/WaitFor.java).
|
||||||
|
|
||||||
### How to test a JVM language?
|
### How to test a JVM language?
|
||||||
|
|
||||||
Plugins supporting a JVM language may require JDK and language standard library to be set up in a test project, so that classes like `java.lang.String` can be correctly resolved during tests.
|
Plugins supporting a JVM language may require JDK and language standard library to be set up in a test project, so that classes like `java.lang.String` can be correctly resolved during tests.
|
||||||
Tests extending [`LightJavaCodeInsightFixtureTestCase`](upsource:///java/testFramework/src/com/intellij/testFramework/fixtures/LightJavaCodeInsightFixtureTestCase.java) use one of the mock JDKs distributed with the [IntelliJ Community project](https://github.com/JetBrains/intellij-community) sources (notice <path>java/mockJDK-$JAVA_VERSION$</path> directories).
|
Tests extending [`LightJavaCodeInsightFixtureTestCase`](%gh-ic%/java/testFramework/src/com/intellij/testFramework/fixtures/LightJavaCodeInsightFixtureTestCase.java) use one of the mock JDKs distributed with the [IntelliJ Community project](https://github.com/JetBrains/intellij-community) sources (notice <path>java/mockJDK-$JAVA_VERSION$</path> directories).
|
||||||
These JAR files are not available in plugin project dependencies, so the IntelliJ Community sources must be checked out to the machine running the tests, and sources' location must be provided to the test framework.
|
These JAR files are not available in plugin project dependencies, so the IntelliJ Community sources must be checked out to the machine running the tests, and sources' location must be provided to the test framework.
|
||||||
It's done by setting the `idea.home.path` system property to the absolute path of the checked-out sources in the `test` task configuration:
|
It's done by setting the `idea.home.path` system property to the absolute path of the checked-out sources in the `test` task configuration:
|
||||||
|
|
||||||
@ -144,20 +144,20 @@ test {
|
|||||||
|
|
||||||
The default JDK version used by the test framework depends on the target platform version and is the latest supported version.
|
The default JDK version used by the test framework depends on the target platform version and is the latest supported version.
|
||||||
The easiest way to change the JDK version to a custom one is by overriding `LightJavaCodeInsightFixtureTestCase.getProjectDescriptor()` and using one of the predefined project descriptors in `LightJavaCodeInsightFixtureTestCase`.
|
The easiest way to change the JDK version to a custom one is by overriding `LightJavaCodeInsightFixtureTestCase.getProjectDescriptor()` and using one of the predefined project descriptors in `LightJavaCodeInsightFixtureTestCase`.
|
||||||
If a project descriptor requires more customizations, its `getSdk()` method can use one of the [`IdeaTestUtil.getMockJdk*()`](upsource:///java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java) methods.
|
If a project descriptor requires more customizations, its `getSdk()` method can use one of the [`IdeaTestUtil.getMockJdk*()`](%gh-ic%/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java) methods.
|
||||||
|
|
||||||
Sometimes, testing a JVM language requires adding standard or other libraries to a test project.
|
Sometimes, testing a JVM language requires adding standard or other libraries to a test project.
|
||||||
If a required library is available in the Maven repository, use [`MavenDependencyUtil`](upsource:///java/testFramework/src/com/intellij/testFramework/fixtures/MavenDependencyUtil.java), e.g.:
|
If a required library is available in the Maven repository, use [`MavenDependencyUtil`](%gh-ic%/java/testFramework/src/com/intellij/testFramework/fixtures/MavenDependencyUtil.java), e.g.:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
MavenDependencyUtil.addFromMaven(model,
|
MavenDependencyUtil.addFromMaven(model,
|
||||||
"org.jetbrains.kotlin:kotlin-stdlib:1.6.10");
|
"org.jetbrains.kotlin:kotlin-stdlib:1.6.10");
|
||||||
```
|
```
|
||||||
|
|
||||||
For [light tests](light_and_heavy_tests.md), use convenience method [`DefaultLightProjectDescriptor.withRepositoryLibrary()`](upsource:///java/testFramework/src/com/intellij/testFramework/fixtures/DefaultLightProjectDescriptor.java)
|
For [light tests](light_and_heavy_tests.md), use convenience method [`DefaultLightProjectDescriptor.withRepositoryLibrary()`](%gh-ic%/java/testFramework/src/com/intellij/testFramework/fixtures/DefaultLightProjectDescriptor.java)
|
||||||
and [`JavaModuleFixtureBuilder.addMavenLibrary()`](upsource:///java/testFramework/src/com/intellij/testFramework/builders/JavaModuleFixtureBuilder.java) for [heavy tests](light_and_heavy_tests.md).
|
and [`JavaModuleFixtureBuilder.addMavenLibrary()`](%gh-ic%/java/testFramework/src/com/intellij/testFramework/builders/JavaModuleFixtureBuilder.java) for [heavy tests](light_and_heavy_tests.md).
|
||||||
|
|
||||||
If a required library is an unpublished JAR file, use [`PsiTestUtil.addLibrary()`](upsource:///platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java) or `addProjectLibrary()` method and the JAR file path, e.g.:
|
If a required library is an unpublished JAR file, use [`PsiTestUtil.addLibrary()`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java) or `addProjectLibrary()` method and the JAR file path, e.g.:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
PsiTestUtil.addLibrary(model,
|
PsiTestUtil.addLibrary(model,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
When writing plugin tests, a common task is testing various kinds of highlighting (inspections, annotators, parser error highlighting, etc.).
|
When writing plugin tests, a common task is testing various kinds of highlighting (inspections, annotators, parser error highlighting, etc.).
|
||||||
The IntelliJ Platform provides a dedicated utility and markup format for this task.
|
The IntelliJ Platform provides a dedicated utility and markup format for this task.
|
||||||
|
|
||||||
To test the highlighting for the file currently loaded into the in-memory editor, invoke [`CodeInsightTestFixture.checkHighlighting()`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java).
|
To test the highlighting for the file currently loaded into the in-memory editor, invoke [`CodeInsightTestFixture.checkHighlighting()`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java).
|
||||||
The parameters to the method specify which severities should be taken into account when comparing the results with the expected results: errors are always taken into account, whereas warnings, weak warnings, and infos are optional.
|
The parameters to the method specify which severities should be taken into account when comparing the results with the expected results: errors are always taken into account, whereas warnings, weak warnings, and infos are optional.
|
||||||
To ignore verifying additional highlighting, set parameter `ignoreExtraHighlighting` to `true`.
|
To ignore verifying additional highlighting, set parameter `ignoreExtraHighlighting` to `true`.
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ This is done by calling `CodeInsightTestFixture.enableInspections()` in the setu
|
|||||||
|
|
||||||
### Syntax Highlighting
|
### Syntax Highlighting
|
||||||
|
|
||||||
To test syntax highlighting provided by [Lexer](implementing_lexer.md), use [`EditorTestUtil.testFileSyntaxHighlighting()`](upsource:///platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java).
|
To test syntax highlighting provided by [Lexer](implementing_lexer.md), use [`EditorTestUtil.testFileSyntaxHighlighting()`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java).
|
||||||
|
|
||||||
## Expected Highlighting Results
|
## Expected Highlighting Results
|
||||||
|
|
||||||
@ -63,9 +63,9 @@ The tag can also have the following optional attributes.
|
|||||||
* `tooltip` expected tooltip message
|
* `tooltip` expected tooltip message
|
||||||
|
|
||||||
**Visual**
|
**Visual**
|
||||||
* `textAttributesKey` expected [`TextAttributesKey`](upsource:///platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java) referenced by its `externalName`
|
* `textAttributesKey` expected [`TextAttributesKey`](%gh-ic%/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java) referenced by its `externalName`
|
||||||
* `foregroundColor`, `backgroundColor`, `effectColor` expected colors for the highlighting
|
* `foregroundColor`, `backgroundColor`, `effectColor` expected colors for the highlighting
|
||||||
* `effectType` expected effect type for the highlighting (see [`EffectType`](upsource:///platform/core-api/src/com/intellij/openapi/editor/markup/EffectType.java))
|
* `effectType` expected effect type for the highlighting (see [`EffectType`](%gh-ic%/platform/core-api/src/com/intellij/openapi/editor/markup/EffectType.java))
|
||||||
* `fontType` expected font style for the highlighting (`0` - normal, `1` - bold, `2` - italic, `3` - bold italic)
|
* `fontType` expected font style for the highlighting (`0` - normal, `1` - bold, `2` - italic, `3` - bold italic)
|
||||||
|
|
||||||
### Special Cases
|
### Special Cases
|
||||||
|
@ -8,7 +8,7 @@ However, most of the tests are written using JUnit 3.
|
|||||||
|
|
||||||
When writing your tests, you have the choice between using a standard base class to perform the test set up for you and using a fixture class, which lets you perform the setup manually and does not tie you to a specific test framework.
|
When writing your tests, you have the choice between using a standard base class to perform the test set up for you and using a fixture class, which lets you perform the setup manually and does not tie you to a specific test framework.
|
||||||
|
|
||||||
With the former approach, you can use classes such as [`BasePlatformTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/BasePlatformTestCase.java) ([`LightPlatformCodeInsightFixtureTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/LightPlatformCodeInsightFixtureTestCase.java) before 2019.2).
|
With the former approach, you can use classes such as [`BasePlatformTestCase`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/BasePlatformTestCase.java) ([`LightPlatformCodeInsightFixtureTestCase`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/LightPlatformCodeInsightFixtureTestCase.java) before 2019.2).
|
||||||
|
|
||||||
With the latter approach, you use the [`IdeaTestFixtureFactory`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/IdeaTestFixtureFactory.java) class to create instances of fixtures for the test environment.
|
With the latter approach, you use the [`IdeaTestFixtureFactory`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/IdeaTestFixtureFactory.java) class to create instances of fixtures for the test environment.
|
||||||
You need to call the fixture creation and setup methods from the test setup method used by your test framework.
|
You need to call the fixture creation and setup methods from the test setup method used by your test framework.
|
||||||
|
@ -69,13 +69,13 @@ 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.
|
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](general_threading_rules.md) for more details on the threading model and read/write actions.
|
See [IntelliJ Platform Architectural Overview](general_threading_rules.md) for more details on the threading model and read/write actions.
|
||||||
|
|
||||||
The same threading requirements also apply to functions like [`LocalFileSystem.refreshAndFindFileByPath()`](upsource:///platform/analysis-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()`](%gh-ic%/platform/analysis-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.
|
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:
|
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()`](upsource:///platform/analysis-api/src/com/intellij/openapi/vfs/newvfs/RefreshQueue.java)
|
* [`RefreshQueue.createSession()`](%gh-ic%/platform/analysis-api/src/com/intellij/openapi/vfs/newvfs/RefreshQueue.java)
|
||||||
* [`VirtualFile.refresh()`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java)
|
* [`VirtualFile.refresh()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java)
|
||||||
|
|
||||||
In some cases, synchronous refreshes can cause deadlocks, depending on which locks are held by the thread invoking the refresh operation.
|
In some cases, synchronous refreshes can cause deadlocks, depending on which locks are held by the thread invoking the refresh operation.
|
||||||
|
|
||||||
@ -84,12 +84,12 @@ In some cases, synchronous refreshes can cause deadlocks, depending on which loc
|
|||||||
All changes happening in the virtual file system, either due to refresh operations or caused by user actions, are reported as _virtual file system events_.
|
All changes happening in the virtual file system, either due to refresh operations or caused by user actions, are reported as _virtual file system events_.
|
||||||
VFS events are always fired in the event dispatch thread and in a write action.
|
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 [`BulkFileListener`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/newvfs/BulkFileListener.java) and to subscribe with it to the [`VirtualFileManager.VFS_CHANGES`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java) topic.
|
The most efficient way to listen to VFS events is to implement [`BulkFileListener`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/newvfs/BulkFileListener.java) and to subscribe with it to the [`VirtualFileManager.VFS_CHANGES`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java) topic.
|
||||||
A non-blocking variant [`AsyncFileListener`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/AsyncFileListener.java) is also available in 2019.2 or later.
|
A non-blocking variant [`AsyncFileListener`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/AsyncFileListener.java) is also available in 2019.2 or later.
|
||||||
See [How do I get notified when VFS changes?](virtual_file.md#how-do-i-get-notified-when-vfs-changes) for implementation details.
|
See [How do I get notified when VFS changes?](virtual_file.md#how-do-i-get-notified-when-vfs-changes) for implementation details.
|
||||||
|
|
||||||
> VFS listeners are application level and will receive events for changes happening in *all* the projects opened by the user.
|
> 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 that aren't relevant to your task (e.g., via [`ProjectFileIndex.isInContent()`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java)).
|
> You may need to filter out events that aren't relevant to your task (e.g., via [`ProjectFileIndex.isInContent()`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java)).
|
||||||
>
|
>
|
||||||
{type="warning"}
|
{type="warning"}
|
||||||
|
|
||||||
@ -99,6 +99,6 @@ So when you process the `beforeFileDeletion` event, for example, the file has al
|
|||||||
However, it is still present in the VFS snapshot, and you can access its last contents using the VFS API.
|
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.
|
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()`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java), you may not get `fileCreated` notifications when files are created in that directory.
|
For example, if you accessed a `VirtualFile` for a directory but never loaded its contents using [`VirtualFile.getChildren()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java), 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.
|
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.
|
||||||
|
@ -138,7 +138,7 @@ Element Patterns
|
|||||||
: Add a new section about [Element Patterns](element_patterns.md) that are used when implementing [Completion Contributors](completion_contributor.md) or [PSI Reference Contributors](psi_references.md#contributed-references).
|
: Add a new section about [Element Patterns](element_patterns.md) that are used when implementing [Completion Contributors](completion_contributor.md) or [PSI Reference Contributors](psi_references.md#contributed-references).
|
||||||
|
|
||||||
Editor - Text Selection
|
Editor - Text Selection
|
||||||
: Add a new section about [Text Selection EPs](text_selection.md) and describe [`ExtendWordSelectionHandler`](upsource:///platform/lang-api/src/com/intellij/codeInsight/editorActions/ExtendWordSelectionHandler.java).
|
: Add a new section about [Text Selection EPs](text_selection.md) and describe [`ExtendWordSelectionHandler`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/editorActions/ExtendWordSelectionHandler.java).
|
||||||
|
|
||||||
SDK Setup Assistance
|
SDK Setup Assistance
|
||||||
: Added a code sample to the SDK tutorial that expands on [assisting in the setup of an SDK](sdk.md#assisting-in-setting-up-an-sdk).
|
: Added a code sample to the SDK tutorial that expands on [assisting in the setup of an SDK](sdk.md#assisting-in-setting-up-an-sdk).
|
||||||
|
@ -43,7 +43,7 @@ At this time, it's not possible to extend the IntelliJ Platform in non-JVM langu
|
|||||||
|
|
||||||
## Open Source
|
## Open Source
|
||||||
|
|
||||||
The IntelliJ Platform is Open Source, under the [Apache License](upsource:///LICENSE.txt), and [hosted on GitHub](https://github.com/JetBrains/intellij-community).
|
The IntelliJ Platform is Open Source, under the [Apache License](%gh-ic%/LICENSE.txt), and [hosted on GitHub](https://github.com/JetBrains/intellij-community).
|
||||||
|
|
||||||
While this guide refers to the IntelliJ Platform as a separate entity, there is no "IntelliJ Platform" GitHub repository.
|
While this guide refers to the IntelliJ Platform as a separate entity, there is no "IntelliJ Platform" GitHub repository.
|
||||||
Instead, the platform is considered to be an almost complete overlap with the IntelliJ IDEA Community Edition, which is a free and Open Source version of IntelliJ IDEA Ultimate (the GitHub repository linked above is the [JetBrains/intellij-community](https://github.com/JetBrains/intellij-community) repository).
|
Instead, the platform is considered to be an almost complete overlap with the IntelliJ IDEA Community Edition, which is a free and Open Source version of IntelliJ IDEA Ultimate (the GitHub repository linked above is the [JetBrains/intellij-community](https://github.com/JetBrains/intellij-community) repository).
|
||||||
|
@ -175,7 +175,7 @@ The sequence of elements in an SDK code sample <path>plugin.xml</path> file is:
|
|||||||
## README File
|
## README File
|
||||||
|
|
||||||
Each code sample provided within the IntelliJ Platform SDK should contain a README file describing the sample purpose and its content.
|
Each code sample provided within the IntelliJ Platform SDK should contain a README file describing the sample purpose and its content.
|
||||||
The [`SAMPLE_README.md`](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/SAMPLE_README.md) file contains a template that should be used as an initial draft for further writing.
|
The [`SAMPLE_README.md`](%gh-sdk-samples%/SAMPLE_README.md) file contains a template that should be used as an initial draft for further writing.
|
||||||
|
|
||||||
Each <path>README.md</path> file is supposed to have the same structure for better navigation and readability:
|
Each <path>README.md</path> file is supposed to have the same structure for better navigation and readability:
|
||||||
- A header with the link to the main IntelliJ SDK documentation and a page that the sample refers to.
|
- A header with the link to the main IntelliJ SDK documentation and a page that the sample refers to.
|
||||||
|
@ -118,20 +118,20 @@ General Markdown links have the default Markdown link style:
|
|||||||
|
|
||||||
#### Links to IntelliJ Platform Source
|
#### Links to IntelliJ Platform Source
|
||||||
|
|
||||||
Links to files in the IntelliJ Platform (`intellij-community`) repository use `upsource:///` instead of the full URL to the repository.
|
Links to files in the IntelliJ Platform (`intellij-community`) repository use `%gh-ic%` prefix instead of the full URL to the repository.
|
||||||
The `upsource:///` URI effectively points to the root of the `intellij-community` repository.
|
|
||||||
* `[README.md](upsource:///README.md)`{disable-links} links to general, non-code information files. ([README.md](upsource:///README.md))
|
* `[README.md](%gh-ic%/README.md)`{disable-links} links to general, non-code information files. ([README.md](%gh-ic%/README.md))
|
||||||
Examples of this file type include _LICENSE.txt_ and _README.md_.
|
Examples of this file type include _LICENSE.txt_ and _README.md_.
|
||||||
* `[`\`plugin.xml\``](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java)`{disable-links} links to declarative source code files, use `code` style. ([`plugin.xml`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java))
|
* `[`IdeaPlugin.xml`](%gh-ic%/community-resources/src/META-INF/IdeaPlugin.xml)`{disable-links} links to declarative source code files, use `code` style. ([`IdeaPlugin.xml`](%gh-ic%/community-resources/src/META-INF/IdeaPlugin.xml))
|
||||||
Examples of this file type include: `settings.gradle`, `plugin.xml` or `theme_basics.theme.json`.
|
Examples of this file type include: `settings.gradle`, `plugin.xml` or `theme_basics.theme.json`.
|
||||||
* `[`\`AnAction\``](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java)`{disable-links} links to source files for code objects like interfaces and classes, use `code` style but without the file extension. [`AnAction`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java)
|
* `[`\`AnAction\``](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java)`{disable-links} links to source files for code objects like interfaces and classes, use `code` style but without the file extension. ([`AnAction`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java))
|
||||||
Examples of this file type include Java and Kotlin.
|
Examples of this file type include Java and Kotlin.
|
||||||
* Note the use of \`\` characters surrounding the class name in the link.
|
* Note the use of \`\` characters surrounding the class name in the link.
|
||||||
* When linking to an API in this manner, the FQN isn't necessary in the link.
|
* When linking to an API in this manner, the FQN isn't necessary in the link.
|
||||||
* No file extension (*.java, *.kt, *.py, etc.) is used by convention.
|
* No file extension (*.java, *.kt, *.py, etc.) is used by convention.
|
||||||
* Be judicious when using such links.
|
* Be judicious when using such links.
|
||||||
Generally, only one link is needed for a given file on a documentation page.
|
Generally, only one link is needed for a given file on a documentation page.
|
||||||
* Links to files in source code packages in other repositories follow much the same rules, except the links use `https:` instead of `upsource:///`.
|
* Links to files in source code packages in other GitHub repositories follow much the same rules, except the links use a different custom `gh-...` prefix defined in <path>v.list</path>.
|
||||||
|
|
||||||
### Guidelines for Highlighting Syntax
|
### Guidelines for Highlighting Syntax
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ In-paragraph code fragments and IntelliJ Platform APIs are formatted according t
|
|||||||
* The FQN is used for the first reference to an interface, class, or package on a page.
|
* The FQN is used for the first reference to an interface, class, or package on a page.
|
||||||
Rather than `AnAction`, introduce it as `com.intellij.openapi.actionSystem.AnAction`.
|
Rather than `AnAction`, introduce it as `com.intellij.openapi.actionSystem.AnAction`.
|
||||||
Subsequent references on the page can be `AnAction`.
|
Subsequent references on the page can be `AnAction`.
|
||||||
Exception: the FQN is not used with an upsource [link](#links).
|
Exception: the FQN is not used with an GitHub [link](#links).
|
||||||
* Use the FQN when first introducing an [extension point](plugin_extension_points.md) (EP) on a page.
|
* Use the FQN when first introducing an [extension point](plugin_extension_points.md) (EP) on a page.
|
||||||
Rather than `stubIndex`, introduce `com.intellij.stubIndex`.
|
Rather than `stubIndex`, introduce `com.intellij.stubIndex`.
|
||||||
Subsequent mentions on the page can be `stubIndex`.
|
Subsequent mentions on the page can be `stubIndex`.
|
||||||
|
@ -63,7 +63,7 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
|-----------------|----------------|
|
|-----------------|----------------|
|
||||||
| [cidr.lang.swiftCustomIncludePathProvider](https://jb.gg/ipe?extensions=cidr.lang.swiftCustomIncludePathProvider) ![Non-Dynamic][non-dynamic] | `SwiftCustomIncludePathProvider` |
|
| [cidr.lang.swiftCustomIncludePathProvider](https://jb.gg/ipe?extensions=cidr.lang.swiftCustomIncludePathProvider) ![Non-Dynamic][non-dynamic] | `SwiftCustomIncludePathProvider` |
|
||||||
| [cidr.lang.swiftSourceModuleProvider](https://jb.gg/ipe?extensions=cidr.lang.swiftSourceModuleProvider) ![Non-Dynamic][non-dynamic] | `SwiftSourceModuleProvider` |
|
| [cidr.lang.swiftSourceModuleProvider](https://jb.gg/ipe?extensions=cidr.lang.swiftSourceModuleProvider) ![Non-Dynamic][non-dynamic] | `SwiftSourceModuleProvider` |
|
||||||
| [cidr.lang.swiftTypeInheritorsSearch](https://jb.gg/ipe?extensions=cidr.lang.swiftTypeInheritorsSearch) ![Non-Dynamic][non-dynamic] | [`QueryExecutor`](upsource:///platform/core-api/src/com/intellij/util/QueryExecutor.java) |
|
| [cidr.lang.swiftTypeInheritorsSearch](https://jb.gg/ipe?extensions=cidr.lang.swiftTypeInheritorsSearch) ![Non-Dynamic][non-dynamic] | [`QueryExecutor`](%gh-ic%/platform/core-api/src/com/intellij/util/QueryExecutor.java) |
|
||||||
| [swift.kotlinNative](https://jb.gg/ipe?extensions=swift.kotlinNative) ![Non-Dynamic][non-dynamic] | `KotlinNativeExtensionPoint` |
|
| [swift.kotlinNative](https://jb.gg/ipe?extensions=swift.kotlinNative) ![Non-Dynamic][non-dynamic] | `KotlinNativeExtensionPoint` |
|
||||||
| [swift.lang.sourceKit.compileArgumentsCollector](https://jb.gg/ipe?extensions=swift.lang.sourceKit.compileArgumentsCollector) | `SwiftSourceKitCompileArgumentsCollector` |
|
| [swift.lang.sourceKit.compileArgumentsCollector](https://jb.gg/ipe?extensions=swift.lang.sourceKit.compileArgumentsCollector) | `SwiftSourceKitCompileArgumentsCollector` |
|
||||||
| [swift.lang.sourceKit.dataGenerator](https://jb.gg/ipe?extensions=swift.lang.sourceKit.dataGenerator) ![Project-Level][project-level] | `SourceKitDataGenerator` |
|
| [swift.lang.sourceKit.dataGenerator](https://jb.gg/ipe?extensions=swift.lang.sourceKit.dataGenerator) ![Project-Level][project-level] | `SourceKitDataGenerator` |
|
||||||
|
@ -14,7 +14,7 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
|
|
||||||
| Topic | Listener |
|
| Topic | Listener |
|
||||||
|-------|----------|
|
|-------|----------|
|
||||||
| [FileSymbolTablesCache#OUT_OF_CODE_BLOCK_TOPIC](https://jb.gg/ipe/listeners?topics=com.intellij.psi.util.PsiModificationTracker.Listener) ![Project-Level][project-level] | [`Listener`](upsource:///platform/core-api/src/com/intellij/psi/util/PsiModificationTracker.java) |
|
| [FileSymbolTablesCache#OUT_OF_CODE_BLOCK_TOPIC](https://jb.gg/ipe/listeners?topics=com.intellij.psi.util.PsiModificationTracker.Listener) ![Project-Level][project-level] | [`Listener`](%gh-ic%/platform/core-api/src/com/intellij/psi/util/PsiModificationTracker.java) |
|
||||||
| [CMakeWorkspaceListener#TOPIC](https://jb.gg/ipe/listeners?topics=com.jetbrains.cidr.cpp.cmake.workspace.CMakeWorkspaceListener) | `CMakeWorkspaceListener` |
|
| [CMakeWorkspaceListener#TOPIC](https://jb.gg/ipe/listeners?topics=com.jetbrains.cidr.cpp.cmake.workspace.CMakeWorkspaceListener) | `CMakeWorkspaceListener` |
|
||||||
| [CubeMXManager#TOPIC](https://jb.gg/ipe/listeners?topics=com.jetbrains.cidr.cpp.embedded.stm32cubemx.CubeMXManager.CubeStatusListener) | `CubeStatusListener` |
|
| [CubeMXManager#TOPIC](https://jb.gg/ipe/listeners?topics=com.jetbrains.cidr.cpp.embedded.stm32cubemx.CubeMXManager.CubeStatusListener) | `CubeStatusListener` |
|
||||||
| [CLionExternalBuildManagerListener#TOPIC](https://jb.gg/ipe/listeners?topics=com.jetbrains.cidr.cpp.execution.external.build.CLionExternalBuildManagerListener) | `CLionExternalBuildManagerListener` |
|
| [CLionExternalBuildManagerListener#TOPIC](https://jb.gg/ipe/listeners?topics=com.jetbrains.cidr.cpp.execution.external.build.CLionExternalBuildManagerListener) | `CLionExternalBuildManagerListener` |
|
||||||
@ -91,7 +91,7 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
|
|
||||||
| Extension Point | Implementation |
|
| Extension Point | Implementation |
|
||||||
|-----------------|----------------|
|
|-----------------|----------------|
|
||||||
| [cidr.lang.annotatorInspectionToolProvider](https://jb.gg/ipe?extensions=cidr.lang.annotatorInspectionToolProvider) ![Non-Dynamic][non-dynamic] | [`NotNullProducer`](upsource:///platform/util/src/com/intellij/util/NotNullProducer.java) |
|
| [cidr.lang.annotatorInspectionToolProvider](https://jb.gg/ipe?extensions=cidr.lang.annotatorInspectionToolProvider) ![Non-Dynamic][non-dynamic] | [`NotNullProducer`](%gh-ic%/platform/util/src/com/intellij/util/NotNullProducer.java) |
|
||||||
| [cidr.lang.fileTypeHelper](https://jb.gg/ipe?extensions=cidr.lang.fileTypeHelper) ![Non-Dynamic][non-dynamic] | `OCFileTypeHelper` |
|
| [cidr.lang.fileTypeHelper](https://jb.gg/ipe?extensions=cidr.lang.fileTypeHelper) ![Non-Dynamic][non-dynamic] | `OCFileTypeHelper` |
|
||||||
| [cidr.lang.knownModuleDetector](https://jb.gg/ipe?extensions=cidr.lang.knownModuleDetector) ![Internal API][internal] | `CidrKnownModuleDetector` |
|
| [cidr.lang.knownModuleDetector](https://jb.gg/ipe?extensions=cidr.lang.knownModuleDetector) ![Internal API][internal] | `CidrKnownModuleDetector` |
|
||||||
| [cidr.lang.languageKindHelper](https://jb.gg/ipe?extensions=cidr.lang.languageKindHelper) ![Non-Dynamic][non-dynamic] | `OCLanguageKindCalculatorHelper` |
|
| [cidr.lang.languageKindHelper](https://jb.gg/ipe?extensions=cidr.lang.languageKindHelper) ![Non-Dynamic][non-dynamic] | `OCLanguageKindCalculatorHelper` |
|
||||||
@ -99,7 +99,7 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
| [cidr.lang.newFileLangBackendHandler](https://jb.gg/ipe?extensions=cidr.lang.newFileLangBackendHandler) ![Non-Dynamic][non-dynamic] | `OCNewFileLangBackendHandler` |
|
| [cidr.lang.newFileLangBackendHandler](https://jb.gg/ipe?extensions=cidr.lang.newFileLangBackendHandler) ![Non-Dynamic][non-dynamic] | `OCNewFileLangBackendHandler` |
|
||||||
| [cidr.lang.newFileModelHandlerProvider](https://jb.gg/ipe?extensions=cidr.lang.newFileModelHandlerProvider) ![Non-Dynamic][non-dynamic] | `OCNewFileProjectModelHandlerProvider` |
|
| [cidr.lang.newFileModelHandlerProvider](https://jb.gg/ipe?extensions=cidr.lang.newFileModelHandlerProvider) ![Non-Dynamic][non-dynamic] | `OCNewFileProjectModelHandlerProvider` |
|
||||||
| [cidr.lang.projectWizardFilesFormatter](https://jb.gg/ipe?extensions=cidr.lang.projectWizardFilesFormatter) ![Non-Dynamic][non-dynamic] | `CidrProjectWizardFilesFormatter` |
|
| [cidr.lang.projectWizardFilesFormatter](https://jb.gg/ipe?extensions=cidr.lang.projectWizardFilesFormatter) ![Non-Dynamic][non-dynamic] | `CidrProjectWizardFilesFormatter` |
|
||||||
| [cidr.lang.standaloneInspectionToolProvider](https://jb.gg/ipe?extensions=cidr.lang.standaloneInspectionToolProvider) ![Non-Dynamic][non-dynamic] | [`NotNullProducer`](upsource:///platform/util/src/com/intellij/util/NotNullProducer.java) |
|
| [cidr.lang.standaloneInspectionToolProvider](https://jb.gg/ipe?extensions=cidr.lang.standaloneInspectionToolProvider) ![Non-Dynamic][non-dynamic] | [`NotNullProducer`](%gh-ic%/platform/util/src/com/intellij/util/NotNullProducer.java) |
|
||||||
|
|
||||||
### CidrLangPlugin.xml
|
### CidrLangPlugin.xml
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
| [cidr.lang.foreignUsagesRenameProcessor](https://jb.gg/ipe?extensions=cidr.lang.foreignUsagesRenameProcessor) ![Non-Dynamic][non-dynamic] | `OCForeignUsagesRenameProcessor` |
|
| [cidr.lang.foreignUsagesRenameProcessor](https://jb.gg/ipe?extensions=cidr.lang.foreignUsagesRenameProcessor) ![Non-Dynamic][non-dynamic] | `OCForeignUsagesRenameProcessor` |
|
||||||
| [cidr.lang.groupedFileNaming](https://jb.gg/ipe?extensions=cidr.lang.groupedFileNaming) ![Non-Dynamic][non-dynamic] | `OCGroupedFileNaming` |
|
| [cidr.lang.groupedFileNaming](https://jb.gg/ipe?extensions=cidr.lang.groupedFileNaming) ![Non-Dynamic][non-dynamic] | `OCGroupedFileNaming` |
|
||||||
| [cidr.lang.includeHelper](https://jb.gg/ipe?extensions=cidr.lang.includeHelper) ![Non-Dynamic][non-dynamic] | `OCIncludeHelper` |
|
| [cidr.lang.includeHelper](https://jb.gg/ipe?extensions=cidr.lang.includeHelper) ![Non-Dynamic][non-dynamic] | `OCIncludeHelper` |
|
||||||
| [cidr.lang.includeHierarchyProvider](https://jb.gg/ipe?extensions=cidr.lang.includeHierarchyProvider) ![Non-Dynamic][non-dynamic] | [`HierarchyProvider`](upsource:///platform/lang-api/src/com/intellij/ide/hierarchy/HierarchyProvider.java) |
|
| [cidr.lang.includeHierarchyProvider](https://jb.gg/ipe?extensions=cidr.lang.includeHierarchyProvider) ![Non-Dynamic][non-dynamic] | [`HierarchyProvider`](%gh-ic%/platform/lang-api/src/com/intellij/ide/hierarchy/HierarchyProvider.java) |
|
||||||
| [cidr.lang.initialBuildingActivity](https://jb.gg/ipe?extensions=cidr.lang.initialBuildingActivity) ![Non-Dynamic][non-dynamic] | `OCInitialBuildingActivity` |
|
| [cidr.lang.initialBuildingActivity](https://jb.gg/ipe?extensions=cidr.lang.initialBuildingActivity) ![Non-Dynamic][non-dynamic] | `OCInitialBuildingActivity` |
|
||||||
| [cidr.lang.languageKindContributor](https://jb.gg/ipe?extensions=cidr.lang.languageKindContributor) ![Non-Dynamic][non-dynamic] | `OCLanguageKindContributor` |
|
| [cidr.lang.languageKindContributor](https://jb.gg/ipe?extensions=cidr.lang.languageKindContributor) ![Non-Dynamic][non-dynamic] | `OCLanguageKindContributor` |
|
||||||
| [cidr.lang.libraryFileConfigurationProvider](https://jb.gg/ipe?extensions=cidr.lang.libraryFileConfigurationProvider) ![Non-Dynamic][non-dynamic] | `OCLibraryFileResolveConfigurationProvider` |
|
| [cidr.lang.libraryFileConfigurationProvider](https://jb.gg/ipe?extensions=cidr.lang.libraryFileConfigurationProvider) ![Non-Dynamic][non-dynamic] | `OCLibraryFileResolveConfigurationProvider` |
|
||||||
@ -128,7 +128,7 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
| [cidr.lang.moduleMapSearchRootProvider](https://jb.gg/ipe?extensions=cidr.lang.moduleMapSearchRootProvider) ![Non-Dynamic][non-dynamic] | `ModuleMapSearchRootProvider` |
|
| [cidr.lang.moduleMapSearchRootProvider](https://jb.gg/ipe?extensions=cidr.lang.moduleMapSearchRootProvider) ![Non-Dynamic][non-dynamic] | `ModuleMapSearchRootProvider` |
|
||||||
| [cidr.lang.moduleResolver](https://jb.gg/ipe?extensions=cidr.lang.moduleResolver) ![Non-Dynamic][non-dynamic] | `OCModuleResolver` |
|
| [cidr.lang.moduleResolver](https://jb.gg/ipe?extensions=cidr.lang.moduleResolver) ![Non-Dynamic][non-dynamic] | `OCModuleResolver` |
|
||||||
| [cidr.lang.ocAdditionalFileSymbolTableBuilder](https://jb.gg/ipe?extensions=cidr.lang.ocAdditionalFileSymbolTableBuilder) ![Non-Dynamic][non-dynamic] | `OCAdditionalFileSymbolTableBuilder` |
|
| [cidr.lang.ocAdditionalFileSymbolTableBuilder](https://jb.gg/ipe?extensions=cidr.lang.ocAdditionalFileSymbolTableBuilder) ![Non-Dynamic][non-dynamic] | `OCAdditionalFileSymbolTableBuilder` |
|
||||||
| [cidr.lang.ocDirectInheritorsSearch](https://jb.gg/ipe?extensions=cidr.lang.ocDirectInheritorsSearch) ![Non-Dynamic][non-dynamic] | [`QueryExecutor`](upsource:///platform/core-api/src/com/intellij/util/QueryExecutor.java) |
|
| [cidr.lang.ocDirectInheritorsSearch](https://jb.gg/ipe?extensions=cidr.lang.ocDirectInheritorsSearch) ![Non-Dynamic][non-dynamic] | [`QueryExecutor`](%gh-ic%/platform/core-api/src/com/intellij/util/QueryExecutor.java) |
|
||||||
| [cidr.lang.ocResolveRootAndConfigurationProvider](https://jb.gg/ipe?extensions=cidr.lang.ocResolveRootAndConfigurationProvider) ![Non-Dynamic][non-dynamic] | `OCResolveRootAndConfigurationProvider` |
|
| [cidr.lang.ocResolveRootAndConfigurationProvider](https://jb.gg/ipe?extensions=cidr.lang.ocResolveRootAndConfigurationProvider) ![Non-Dynamic][non-dynamic] | `OCResolveRootAndConfigurationProvider` |
|
||||||
| [cidr.lang.renameHandlerExtension](https://jb.gg/ipe?extensions=cidr.lang.renameHandlerExtension) ![Non-Dynamic][non-dynamic] | `OCRenameHandlerExtension` |
|
| [cidr.lang.renameHandlerExtension](https://jb.gg/ipe?extensions=cidr.lang.renameHandlerExtension) ![Non-Dynamic][non-dynamic] | `OCRenameHandlerExtension` |
|
||||||
| [cidr.lang.renameProcessorExtension](https://jb.gg/ipe?extensions=cidr.lang.renameProcessorExtension) ![Non-Dynamic][non-dynamic] | `OCRenameProcessorExtension` |
|
| [cidr.lang.renameProcessorExtension](https://jb.gg/ipe?extensions=cidr.lang.renameProcessorExtension) ![Non-Dynamic][non-dynamic] | `OCRenameProcessorExtension` |
|
||||||
|
@ -50,7 +50,7 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
| [com.intellij.php.debug.template.configurable](https://jb.gg/ipe?extensions=com.intellij.php.debug.template.configurable) ![Internal API][internal] ![Project-Level][project-level] | `PhpTemplateDebugConfigurable` |
|
| [com.intellij.php.debug.template.configurable](https://jb.gg/ipe?extensions=com.intellij.php.debug.template.configurable) ![Internal API][internal] ![Project-Level][project-level] | `PhpTemplateDebugConfigurable` |
|
||||||
| [com.intellij.php.debug.templateLanguage](https://jb.gg/ipe?extensions=com.intellij.php.debug.templateLanguage) ![Internal API][internal] | `PhpTemplateLanguagePathMapper` |
|
| [com.intellij.php.debug.templateLanguage](https://jb.gg/ipe?extensions=com.intellij.php.debug.templateLanguage) ![Internal API][internal] | `PhpTemplateLanguagePathMapper` |
|
||||||
| [com.intellij.php.typeProvider2](https://jb.gg/ipe?extensions=com.intellij.php.typeProvider2) ![Deprecated][deprecated] | `PhpTypeProvider2` |
|
| [com.intellij.php.typeProvider2](https://jb.gg/ipe?extensions=com.intellij.php.typeProvider2) ![Deprecated][deprecated] | `PhpTypeProvider2` |
|
||||||
| [com.intellij.phpDeadCode](https://jb.gg/ipe?extensions=com.intellij.phpDeadCode) | [`EntryPoint`](upsource:///platform/analysis-api/src/com/intellij/codeInspection/reference/EntryPoint.java) |
|
| [com.intellij.phpDeadCode](https://jb.gg/ipe?extensions=com.intellij.phpDeadCode) | [`EntryPoint`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInspection/reference/EntryPoint.java) |
|
||||||
| [com.jetbrains.php.arrayShapesProvider](https://jb.gg/ipe?extensions=com.jetbrains.php.arrayShapesProvider) | `PhpArrayShapesProvider` |
|
| [com.jetbrains.php.arrayShapesProvider](https://jb.gg/ipe?extensions=com.jetbrains.php.arrayShapesProvider) | `PhpArrayShapesProvider` |
|
||||||
| [com.jetbrains.php.classAliasProvider](https://jb.gg/ipe?extensions=com.jetbrains.php.classAliasProvider) | `PhpClassAliasProvider` |
|
| [com.jetbrains.php.classAliasProvider](https://jb.gg/ipe?extensions=com.jetbrains.php.classAliasProvider) | `PhpClassAliasProvider` |
|
||||||
| [com.jetbrains.php.composer.execProvider](https://jb.gg/ipe?extensions=com.jetbrains.php.composer.execProvider) | `ComposerExecutionProvider` |
|
| [com.jetbrains.php.composer.execProvider](https://jb.gg/ipe?extensions=com.jetbrains.php.composer.execProvider) | `ComposerExecutionProvider` |
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
- `getReferences()` returns all path references from the PSI element.
|
- `getReferences()` returns all path references from the PSI element.
|
||||||
|
|
||||||
Using this method in conjunction with
|
Using this method in conjunction with
|
||||||
[PsiReferenceContributor](upsource:///platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java)
|
[PsiReferenceContributor](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java)
|
||||||
you can add autocompletion for string literals in the specific contexts.
|
you can add autocompletion for string literals in the specific contexts.
|
||||||
For example, if certain PHP functions in your code accept paths, you can autocomplete them when writing arguments.
|
For example, if certain PHP functions in your code accept paths, you can autocomplete them when writing arguments.
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
|
|
||||||
| Topic | Listener |
|
| Topic | Listener |
|
||||||
|------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
|
|------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [RiderStyleCopConfigurable#STYLE_COP_CONFIGURABLE_TOPIC](https://jb.gg/ipe/listeners?topics=com.intellij.application.options.editor.EditorOptionsListener) | [`EditorOptionsListener`](upsource:///platform/platform-impl/src/com/intellij/application/options/editor/EditorOptionsListener.java) |
|
| [RiderStyleCopConfigurable#STYLE_COP_CONFIGURABLE_TOPIC](https://jb.gg/ipe/listeners?topics=com.intellij.application.options.editor.EditorOptionsListener) | [`EditorOptionsListener`](%gh-ic%/platform/platform-impl/src/com/intellij/application/options/editor/EditorOptionsListener.java) |
|
||||||
| [RiderClangFormatConfigurable#CLANG_FORMAT_CONFIGURABLE_TOPIC](https://jb.gg/ipe/listeners?topics=com.intellij.application.options.editor.EditorOptionsListener) | [`EditorOptionsListener`](upsource:///platform/platform-impl/src/com/intellij/application/options/editor/EditorOptionsListener.java) |
|
| [RiderClangFormatConfigurable#CLANG_FORMAT_CONFIGURABLE_TOPIC](https://jb.gg/ipe/listeners?topics=com.intellij.application.options.editor.EditorOptionsListener) | [`EditorOptionsListener`](%gh-ic%/platform/platform-impl/src/com/intellij/application/options/editor/EditorOptionsListener.java) |
|
||||||
|
|
||||||
### com.jetbrains.dotTrace
|
### com.jetbrains.dotTrace
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
| [org.jetbrains.plugins.ruby.rubyRenameProcessor](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubyRenameProcessor) | `RenameProcessor` |
|
| [org.jetbrains.plugins.ruby.rubyRenameProcessor](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubyRenameProcessor) | `RenameProcessor` |
|
||||||
| [org.jetbrains.plugins.ruby.rubySdkConfigurator](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubySdkConfigurator) | `RubySdkConfigurator` |
|
| [org.jetbrains.plugins.ruby.rubySdkConfigurator](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubySdkConfigurator) | `RubySdkConfigurator` |
|
||||||
| [org.jetbrains.plugins.ruby.rubySdkRefresher](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubySdkRefresher) | `SdkRefresher` |
|
| [org.jetbrains.plugins.ruby.rubySdkRefresher](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubySdkRefresher) | `SdkRefresher` |
|
||||||
| [org.jetbrains.plugins.ruby.rubySuperMethodsSearch](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubySuperMethodsSearch) | [`QueryExecutor`](upsource:///platform/core-api/src/com/intellij/util/QueryExecutor.java) |
|
| [org.jetbrains.plugins.ruby.rubySuperMethodsSearch](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubySuperMethodsSearch) | [`QueryExecutor`](%gh-ic%/platform/core-api/src/com/intellij/util/QueryExecutor.java) |
|
||||||
| [org.jetbrains.plugins.ruby.rubySupportProvider](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubySupportProvider) | `RubySupportProvider` |
|
| [org.jetbrains.plugins.ruby.rubySupportProvider](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubySupportProvider) | `RubySupportProvider` |
|
||||||
| [org.jetbrains.plugins.ruby.rubyTypeProvider](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubyTypeProvider) | `RubyTypeProvider` |
|
| [org.jetbrains.plugins.ruby.rubyTypeProvider](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.rubyTypeProvider) | `RubyTypeProvider` |
|
||||||
| [org.jetbrains.plugins.ruby.run.console.filter](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.run.console.filter) | `RubyConsoleFilterProvider` |
|
| [org.jetbrains.plugins.ruby.run.console.filter](https://jb.gg/ipe?extensions=org.jetbrains.plugins.ruby.run.console.filter) | `RubyConsoleFilterProvider` |
|
||||||
|
@ -78,7 +78,7 @@ See [](extension_point_list.md) for IntelliJ Platform.
|
|||||||
| [JavaScript.inheritedLanguagesConfigurableProvider](https://jb.gg/ipe?extensions=JavaScript.inheritedLanguagesConfigurableProvider) | `JSInheritedLanguagesConfigurableProvider` |
|
| [JavaScript.inheritedLanguagesConfigurableProvider](https://jb.gg/ipe?extensions=JavaScript.inheritedLanguagesConfigurableProvider) | `JSInheritedLanguagesConfigurableProvider` |
|
||||||
| [JavaScript.intentionAndInspectionFilter](https://jb.gg/ipe?extensions=JavaScript.intentionAndInspectionFilter) | `IntentionAndInspectionFilter` |
|
| [JavaScript.intentionAndInspectionFilter](https://jb.gg/ipe?extensions=JavaScript.intentionAndInspectionFilter) | `IntentionAndInspectionFilter` |
|
||||||
| [JavaScript.jestPackageProvider](https://jb.gg/ipe?extensions=JavaScript.jestPackageProvider) | `JestPackageProvider` |
|
| [JavaScript.jestPackageProvider](https://jb.gg/ipe?extensions=JavaScript.jestPackageProvider) | `JestPackageProvider` |
|
||||||
| [JavaScript.lang.templates](https://jb.gg/ipe?extensions=JavaScript.lang.templates) ![Project-Level][project-level] | [`Configurable`](upsource:///platform/ide-core/src/com/intellij/openapi/options/Configurable.java) |
|
| [JavaScript.lang.templates](https://jb.gg/ipe?extensions=JavaScript.lang.templates) ![Project-Level][project-level] | [`Configurable`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/Configurable.java) |
|
||||||
| [JavaScript.languageServiceProvider](https://jb.gg/ipe?extensions=JavaScript.languageServiceProvider) ![Project-Level][project-level] | `JSLanguageServiceProvider` |
|
| [JavaScript.languageServiceProvider](https://jb.gg/ipe?extensions=JavaScript.languageServiceProvider) ![Project-Level][project-level] | `JSLanguageServiceProvider` |
|
||||||
| [JavaScript.languageServiceRemoteHelperFactory](https://jb.gg/ipe?extensions=JavaScript.languageServiceRemoteHelperFactory) | `Factory` |
|
| [JavaScript.languageServiceRemoteHelperFactory](https://jb.gg/ipe?extensions=JavaScript.languageServiceRemoteHelperFactory) | `Factory` |
|
||||||
| [JavaScript.moduleReferenceContributor](https://jb.gg/ipe?extensions=JavaScript.moduleReferenceContributor) | `JSModuleReferenceContributor` |
|
| [JavaScript.moduleReferenceContributor](https://jb.gg/ipe?extensions=JavaScript.moduleReferenceContributor) | `JSModuleReferenceContributor` |
|
||||||
|
@ -16,7 +16,7 @@ if only standard attributes are set, they will not be used by the version before
|
|||||||
|
|
||||||
### Text Attribute Key Dependency
|
### Text Attribute Key Dependency
|
||||||
|
|
||||||
The easiest and the best way to specify highlighting text attributes is to specify a dependency on one of standard keys defined in [`DefaultLanguageHighlighterColors`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/DefaultLanguageHighlighterColors.java):
|
The easiest and the best way to specify highlighting text attributes is to specify a dependency on one of standard keys defined in [`DefaultLanguageHighlighterColors`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/editor/DefaultLanguageHighlighterColors.java):
|
||||||
|
|
||||||
```java
|
```java
|
||||||
static final TextAttributesKey MY_KEYWORD =
|
static final TextAttributesKey MY_KEYWORD =
|
||||||
|
@ -20,8 +20,8 @@ _- Sample 1_ - Sample implementation
|
|||||||
|
|
||||||
EP: `com.intellij.lang.braceMatcher`
|
EP: `com.intellij.lang.braceMatcher`
|
||||||
|
|
||||||
[`PairedBraceMatcher`](upsource:///platform/analysis-api/src/com/intellij/lang/PairedBraceMatcher.java)
|
[`PairedBraceMatcher`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/PairedBraceMatcher.java)
|
||||||
Returns an array of brace pairs ([`BracePair`](upsource:///platform/analysis-api/src/com/intellij/lang/BracePair.java)) specifying the characters for the opening and closing braces and the lexer token types for these characters.
|
Returns an array of brace pairs ([`BracePair`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/BracePair.java)) specifying the characters for the opening and closing braces and the lexer token types for these characters.
|
||||||
(In principle, it is possible to return multi-character tokens, like "begin" and "end", as the start and end tokens of a brace pair.
|
(In principle, it is possible to return multi-character tokens, like "begin" and "end", as the start and end tokens of a brace pair.
|
||||||
The IDE will match such braces, but the highlighting for such braces will not be entirely correct.)
|
The IDE will match such braces, but the highlighting for such braces will not be entirely correct.)
|
||||||
|
|
||||||
@ -34,23 +34,23 @@ See also [](#recognizing-complex-multi-block-expressions).
|
|||||||
|
|
||||||
EP: `com.intellij.lang.quoteHandler`
|
EP: `com.intellij.lang.quoteHandler`
|
||||||
|
|
||||||
To support _Insert pair quote_ feature, provide [`QuoteHandler`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/editorActions/QuoteHandler.java).
|
To support _Insert pair quote_ feature, provide [`QuoteHandler`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/editorActions/QuoteHandler.java).
|
||||||
In most cases, [`SimpleTokenSetQuoteHandler`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/editorActions/SimpleTokenSetQuoteHandler.java) base implementation will be suitable.
|
In most cases, [`SimpleTokenSetQuoteHandler`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SimpleTokenSetQuoteHandler.java) base implementation will be suitable.
|
||||||
|
|
||||||
### Comment Code
|
### Comment Code
|
||||||
|
|
||||||
EP: `com.intellij.lang.commenter`
|
EP: `com.intellij.lang.commenter`
|
||||||
|
|
||||||
[`Commenter`](upsource:///platform/core-api/src/com/intellij/lang/Commenter.java) returns the prefix for the line comment, and the prefix and suffix for the block comment if supported by the language.
|
[`Commenter`](%gh-ic%/platform/core-api/src/com/intellij/lang/Commenter.java) returns the prefix for the line comment, and the prefix and suffix for the block comment if supported by the language.
|
||||||
|
|
||||||
- [`Commenter`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesCommenter.java) for [Properties language plugin](upsource:///plugins/properties)
|
- [`Commenter`](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesCommenter.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
- [Custom Language Support Tutorial: Commenter](commenter.md)
|
- [Custom Language Support Tutorial: Commenter](commenter.md)
|
||||||
|
|
||||||
### Code Folding
|
### Code Folding
|
||||||
|
|
||||||
EP: `com.intellij.lang.foldingBuilder`
|
EP: `com.intellij.lang.foldingBuilder`
|
||||||
|
|
||||||
[`FoldingBuilder`](upsource:///platform/core-api/src/com/intellij/lang/folding/FoldingBuilder.java) returns the list of foldable text ranges (as an array of [`FoldingDescriptor`](upsource:///platform/core-api/src/com/intellij/lang/folding/FoldingDescriptor.java) objects), the replacement text which is shown for each range when it is folded, and the default state of each folding region (folded or unfolded).
|
[`FoldingBuilder`](%gh-ic%/platform/core-api/src/com/intellij/lang/folding/FoldingBuilder.java) returns the list of foldable text ranges (as an array of [`FoldingDescriptor`](%gh-ic%/platform/core-api/src/com/intellij/lang/folding/FoldingDescriptor.java) objects), the replacement text which is shown for each range when it is folded, and the default state of each folding region (folded or unfolded).
|
||||||
|
|
||||||
- [Custom Language Support Tutorial: Folding Builder](folding_builder.md)
|
- [Custom Language Support Tutorial: Folding Builder](folding_builder.md)
|
||||||
|
|
||||||
@ -58,75 +58,75 @@ EP: `com.intellij.lang.foldingBuilder`
|
|||||||
|
|
||||||
EP: `com.intellij.joinLinesHandler`
|
EP: `com.intellij.joinLinesHandler`
|
||||||
|
|
||||||
[`JoinLinesHandlerDelegate`](upsource:///platform/lang-api/src/com/intellij/codeInsight/editorActions/JoinLinesHandlerDelegate.java) allows extending support smart/semantic <menupath>Edit | Join Lines</menupath> (e.g., String literal split on multiple lines).
|
[`JoinLinesHandlerDelegate`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/editorActions/JoinLinesHandlerDelegate.java) allows extending support smart/semantic <menupath>Edit | Join Lines</menupath> (e.g., String literal split on multiple lines).
|
||||||
|
|
||||||
### Smart Enter
|
### Smart Enter
|
||||||
|
|
||||||
EP: `com.intellij.lang.smartEnterProcessor`
|
EP: `com.intellij.lang.smartEnterProcessor`
|
||||||
|
|
||||||
[`SmartEnterProcessor`](upsource:///platform/lang-api/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterProcessor.java) handles <menupath>Edit | Complete Statement</menupath> (e.g., autocomplete missing semicolon/parentheses).
|
[`SmartEnterProcessor`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterProcessor.java) handles <menupath>Edit | Complete Statement</menupath> (e.g., autocomplete missing semicolon/parentheses).
|
||||||
|
|
||||||
### Move Element Left/Right
|
### Move Element Left/Right
|
||||||
|
|
||||||
EP: `com.intellij.moveLeftRightHandler`
|
EP: `com.intellij.moveLeftRightHandler`
|
||||||
|
|
||||||
Return children of given element from [`MoveElementLeftRightHandler`](upsource:///platform/lang-api/src/com/intellij/codeInsight/editorActions/moveLeftRight/MoveElementLeftRightHandler.java) for <menupath>Code | Move Element Left|Right</menupath>, e.g., method call parameters.
|
Return children of given element from [`MoveElementLeftRightHandler`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/editorActions/moveLeftRight/MoveElementLeftRightHandler.java) for <menupath>Code | Move Element Left|Right</menupath>, e.g., method call parameters.
|
||||||
Alternatively, implement [`PsiListLikeElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiListLikeElement.java) in PSI element.
|
Alternatively, implement [`PsiListLikeElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiListLikeElement.java) in PSI element.
|
||||||
|
|
||||||
### Naming Suggestions
|
### Naming Suggestions
|
||||||
|
|
||||||
EP: `com.intellij.nameSuggestionProvider`
|
EP: `com.intellij.nameSuggestionProvider`
|
||||||
|
|
||||||
[`NameSuggestionProvider`](upsource:///platform/refactoring/src/com/intellij/refactoring/rename/NameSuggestionProvider.java) provides name suggestions for the given element, e.g., for Rename refactoring.
|
[`NameSuggestionProvider`](%gh-ic%/platform/refactoring/src/com/intellij/refactoring/rename/NameSuggestionProvider.java) provides name suggestions for the given element, e.g., for Rename refactoring.
|
||||||
|
|
||||||
### Semantic Highlight Usages
|
### Semantic Highlight Usages
|
||||||
|
|
||||||
EP: `com.intellij.highlightUsagesHandlerFactory`
|
EP: `com.intellij.highlightUsagesHandlerFactory`
|
||||||
|
|
||||||
[`HighlightUsagesHandlerFactory`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java) allows highlighting e.g., Exit Points or Exceptions.
|
[`HighlightUsagesHandlerFactory`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java) allows highlighting e.g., Exit Points or Exceptions.
|
||||||
|
|
||||||
### TODO View
|
### TODO View
|
||||||
|
|
||||||
EP: n/a
|
EP: n/a
|
||||||
|
|
||||||
[`ParserDefinition.getCommentTokens()`](upsource:///platform/core-api/src/com/intellij/lang/ParserDefinition.java) must return the set of tokens treated as comments to populate the *TODO* window.
|
[`ParserDefinition.getCommentTokens()`](%gh-ic%/platform/core-api/src/com/intellij/lang/ParserDefinition.java) must return the set of tokens treated as comments to populate the *TODO* window.
|
||||||
|
|
||||||
### Context Info
|
### Context Info
|
||||||
|
|
||||||
EP: `com.intellij.declarationRangeHandler`
|
EP: `com.intellij.declarationRangeHandler`
|
||||||
|
|
||||||
[`DeclarationRangeHandler`](upsource:///platform/lang-api/src/com/intellij/codeInsight/hint/DeclarationRangeHandler.java) provides <menupath>View | Context Info</menupath> for custom languages with structure view implementation based on a [`TreeBasedStructureViewBuilder`](upsource:///platform/editor-ui-api/src/com/intellij/ide/structureView/TreeBasedStructureViewBuilder.java).
|
[`DeclarationRangeHandler`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/hint/DeclarationRangeHandler.java) provides <menupath>View | Context Info</menupath> for custom languages with structure view implementation based on a [`TreeBasedStructureViewBuilder`](%gh-ic%/platform/editor-ui-api/src/com/intellij/ide/structureView/TreeBasedStructureViewBuilder.java).
|
||||||
|
|
||||||
### Spellchecking
|
### Spellchecking
|
||||||
|
|
||||||
EP: `com.intellij.spellchecker.support`
|
EP: `com.intellij.spellchecker.support`
|
||||||
|
|
||||||
[`SpellcheckingStrategy`](upsource:///spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java) provides [`Tokenizer`](upsource:///spellchecker/src/com/intellij/spellchecker/tokenizer/Tokenizer.java) to use for given `PsiElement` (return `EMPTY_TOKENIZER` for no spellchecking).
|
[`SpellcheckingStrategy`](%gh-ic%/spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java) provides [`Tokenizer`](%gh-ic%/spellchecker/src/com/intellij/spellchecker/tokenizer/Tokenizer.java) to use for given `PsiElement` (return `EMPTY_TOKENIZER` for no spellchecking).
|
||||||
|
|
||||||
### Reference Injection
|
### Reference Injection
|
||||||
|
|
||||||
EP: `com.intellij.referenceInjector`
|
EP: `com.intellij.referenceInjector`
|
||||||
|
|
||||||
[`ReferenceInjector`](upsource:///platform/analysis-api/src/com/intellij/psi/injection/ReferenceInjector.java) allows users to inject pre-defined references (e.g., "Encoding", "File Reference") into `PsiLanguageInjectionHost` elements (IntelliLang plugin required).
|
[`ReferenceInjector`](%gh-ic%/platform/analysis-api/src/com/intellij/psi/injection/ReferenceInjector.java) allows users to inject pre-defined references (e.g., "Encoding", "File Reference") into `PsiLanguageInjectionHost` elements (IntelliLang plugin required).
|
||||||
|
|
||||||
### Color Preview/Chooser
|
### Color Preview/Chooser
|
||||||
|
|
||||||
EP: `com.intellij.colorProvider`
|
EP: `com.intellij.colorProvider`
|
||||||
|
|
||||||
[`ElementColorProvider`](upsource:///platform/lang-api/src/com/intellij/openapi/editor/ElementColorProvider.java) renders gutter icon for an element containing color information.
|
[`ElementColorProvider`](%gh-ic%/platform/lang-api/src/com/intellij/openapi/editor/ElementColorProvider.java) renders gutter icon for an element containing color information.
|
||||||
|
|
||||||
### File Includes
|
### File Includes
|
||||||
|
|
||||||
EP: `com.intellij.include.provider`
|
EP: `com.intellij.include.provider`
|
||||||
|
|
||||||
[`FileIncludeProvider`](upsource:///platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeProvider.java) provides information about _include_ statements resolving to files (e.g., `<xi:include>` in XML).
|
[`FileIncludeProvider`](%gh-ic%/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeProvider.java) provides information about _include_ statements resolving to files (e.g., `<xi:include>` in XML).
|
||||||
Including/included files can then be obtained via [`FileIncludeManager`](upsource:///platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeManager.java).
|
Including/included files can then be obtained via [`FileIncludeManager`](%gh-ic%/platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeManager.java).
|
||||||
|
|
||||||
### Recognizing Complex Multi-Block Expressions
|
### Recognizing Complex Multi-Block Expressions
|
||||||
|
|
||||||
EP: `com.intellij.codeBlockSupportHandler`
|
EP: `com.intellij.codeBlockSupportHandler`
|
||||||
|
|
||||||
[`CodeBlockSupportHandler`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/highlighting/CodeBlockSupportHandler.java)
|
[`CodeBlockSupportHandler`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/highlighting/CodeBlockSupportHandler.java)
|
||||||
allows providing text ranges for more complex code blocks like, e.g., in `if`/`elsif`/`else` blocks.
|
allows providing text ranges for more complex code blocks like, e.g., in `if`/`elsif`/`else` blocks.
|
||||||
It is used to highlight markers and keywords if one is under the cursor, and for navigation to the beginning/end of blocks.
|
It is used to highlight markers and keywords if one is under the cursor, and for navigation to the beginning/end of blocks.
|
||||||
See also [](#brace-matching).
|
See also [](#brace-matching).
|
||||||
@ -135,17 +135,17 @@ See also [](#brace-matching).
|
|||||||
|
|
||||||
EP: `com.intellij.breadcrumbsInfoProvider`
|
EP: `com.intellij.breadcrumbsInfoProvider`
|
||||||
|
|
||||||
[`BreadcrumbsProvider`](upsource:///platform/editor-ui-api/src/com/intellij/ui/breadcrumbs/BreadcrumbsProvider.java)
|
[`BreadcrumbsProvider`](%gh-ic%/platform/editor-ui-api/src/com/intellij/ui/breadcrumbs/BreadcrumbsProvider.java)
|
||||||
allows for language-specific breadcrumbs.
|
allows for language-specific breadcrumbs.
|
||||||
Please refer to
|
Please refer to
|
||||||
[`GroovyBreadcrumbsInfoProvider`](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/editor/GroovyBreadcrumbsInfoProvider.kt)
|
[`GroovyBreadcrumbsInfoProvider`](%gh-ic%/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/GroovyBreadcrumbsInfoProvider.kt)
|
||||||
as implementation example.
|
as implementation example.
|
||||||
|
|
||||||
### Plain Text Completion
|
### Plain Text Completion
|
||||||
|
|
||||||
EP: `completion.plainTextSymbol`
|
EP: `completion.plainTextSymbol`
|
||||||
|
|
||||||
[`PlainTextSymbolCompletionContributor`](upsource:///platform/lang-api/src/com/intellij/codeInsight/completion/PlainTextSymbolCompletionContributor.java)
|
[`PlainTextSymbolCompletionContributor`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/completion/PlainTextSymbolCompletionContributor.java)
|
||||||
provides a simple way to extract lookup elements from a file so that users have completion available
|
provides a simple way to extract lookup elements from a file so that users have completion available
|
||||||
in, e.g., plain text editors like VCS commit messages.
|
in, e.g., plain text editors like VCS commit messages.
|
||||||
|
|
||||||
@ -153,33 +153,33 @@ in, e.g., plain text editors like VCS commit messages.
|
|||||||
|
|
||||||
EP: `com.intellij.listSplitJoinContext`
|
EP: `com.intellij.listSplitJoinContext`
|
||||||
|
|
||||||
[`ListSplitJoinContext`](upsource:///platform/lang-impl/src/com/intellij/openapi/editor/actions/lists/ListSplitJoinContext.kt)
|
[`ListSplitJoinContext`](%gh-ic%/platform/lang-impl/src/com/intellij/openapi/editor/actions/lists/ListSplitJoinContext.kt)
|
||||||
needs to be implemented to define the exact behavior of splitting and joining list-like constructs
|
needs to be implemented to define the exact behavior of splitting and joining list-like constructs
|
||||||
in a language.
|
in a language.
|
||||||
The UI will show implementations of this EP as an
|
The UI will show implementations of this EP as an
|
||||||
[intention action](https://www.jetbrains.com/help/idea/intention-actions.html)
|
[intention action](https://www.jetbrains.com/help/idea/intention-actions.html)
|
||||||
at appropriate locations.
|
at appropriate locations.
|
||||||
Developers can use the abstract classes in
|
Developers can use the abstract classes in
|
||||||
[`DefaultListSplitJoinContext`](upsource:///platform/lang-impl/src/com/intellij/openapi/editor/actions/lists/DefaultListSplitJoinContext.kt)
|
[`DefaultListSplitJoinContext`](%gh-ic%/platform/lang-impl/src/com/intellij/openapi/editor/actions/lists/DefaultListSplitJoinContext.kt)
|
||||||
for their implementation and
|
for their implementation and
|
||||||
[`XmlAttributesSplitJoinContext`](upsource:///xml/impl/src/com/intellij/codeInsight/intentions/XmlAttributesSplitJoinContext.kt)
|
[`XmlAttributesSplitJoinContext`](%gh-ic%/xml/impl/src/com/intellij/codeInsight/intentions/XmlAttributesSplitJoinContext.kt)
|
||||||
serves as a good example.
|
serves as a good example.
|
||||||
|
|
||||||
### Suggesting Rename and Change Signature Refactorings
|
### Suggesting Rename and Change Signature Refactorings
|
||||||
|
|
||||||
EP: `com.intellij.suggestedRefactoringSupport`
|
EP: `com.intellij.suggestedRefactoringSupport`
|
||||||
|
|
||||||
[`SuggestedRefactoringSupport`](upsource:///platform/lang-api/src/com/intellij/refactoring/suggested/SuggestedRefactoringSupport.kt)
|
[`SuggestedRefactoringSupport`](%gh-ic%/platform/lang-api/src/com/intellij/refactoring/suggested/SuggestedRefactoringSupport.kt)
|
||||||
provides functionality for suggesting rename and change signature refactorings for custom languages.
|
provides functionality for suggesting rename and change signature refactorings for custom languages.
|
||||||
Please see
|
Please see
|
||||||
[`KotlinSuggestedRefactoringSupport`](upsource:///plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringSupport.kt)
|
[`KotlinSuggestedRefactoringSupport`](%gh-ic%/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringSupport.kt)
|
||||||
for an implementation example.
|
for an implementation example.
|
||||||
|
|
||||||
### Reader Mode
|
### Reader Mode
|
||||||
|
|
||||||
EP: `readerModeMatcher`
|
EP: `readerModeMatcher`
|
||||||
|
|
||||||
[`ReaderModeMatcher`](upsource:///platform/editor-ui-api/src/com/intellij/codeInsight/actions/ReaderModeMatcher.kt)
|
[`ReaderModeMatcher`](%gh-ic%/platform/editor-ui-api/src/com/intellij/codeInsight/actions/ReaderModeMatcher.kt)
|
||||||
provides a way to decide if files are shown in the correct mode: reader mode vs. normal editor mode.
|
provides a way to decide if files are shown in the correct mode: reader mode vs. normal editor mode.
|
||||||
Please see
|
Please see
|
||||||
[the documentation](https://www.jetbrains.com/help/idea/reader-mode.html)
|
[the documentation](https://www.jetbrains.com/help/idea/reader-mode.html)
|
||||||
@ -189,17 +189,17 @@ to get familiar with reader mode.
|
|||||||
|
|
||||||
EP: `com.intellij.editorTabColorProvider`
|
EP: `com.intellij.editorTabColorProvider`
|
||||||
|
|
||||||
[`EditorTabColorProvider`](upsource:///platform/ide-core-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabColorProvider.java)
|
[`EditorTabColorProvider`](%gh-ic%/platform/ide-core-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabColorProvider.java)
|
||||||
allows for the modification of the background colors for specific files.
|
allows for the modification of the background colors for specific files.
|
||||||
|
|
||||||
### Custom Names and Tooltips for Editor Tabs
|
### Custom Names and Tooltips for Editor Tabs
|
||||||
|
|
||||||
EP: `com.intellij.editorTabTitleProvider`
|
EP: `com.intellij.editorTabTitleProvider`
|
||||||
|
|
||||||
[`EditorTabTitleProvider`](upsource:///platform/ide-core-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabTitleProvider.java)
|
[`EditorTabTitleProvider`](%gh-ic%/platform/ide-core-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabTitleProvider.java)
|
||||||
allows for specifying custom names and tooltips displayed in the title of editor tabs.
|
allows for specifying custom names and tooltips displayed in the title of editor tabs.
|
||||||
Please see, e.g.,
|
Please see, e.g.,
|
||||||
[`GradleEditorTabTitleProvider`](upsource:///plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEditorTabTitleProvider.kt)
|
[`GradleEditorTabTitleProvider`](%gh-ic%/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEditorTabTitleProvider.kt)
|
||||||
which shows how the project name is added to the editor tab for Gradle files.
|
which shows how the project name is added to the editor tab for Gradle files.
|
||||||
|
|
||||||
> If a topic you are interested in is not covered in the above sections, let us know via the "**Was this page helpful?**" feedback form below or [other channels](getting_help.md#problems-with-the-guide).
|
> If a topic you are interested in is not covered in the above sections, let us know via the "**Was this page helpful?**" feedback form below or [other channels](getting_help.md#problems-with-the-guide).
|
||||||
|
@ -9,11 +9,11 @@ Contributor-based completion provides more features, supports all three completi
|
|||||||
|
|
||||||
### Reference Completion
|
### Reference Completion
|
||||||
|
|
||||||
To fill the completion list, the IDE calls [`PsiReference.getVariants()`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) either on the reference at the caret location or on a dummy reference that would be placed at the caret.
|
To fill the completion list, the IDE calls [`PsiReference.getVariants()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) either on the reference at the caret location or on a dummy reference that would be placed at the caret.
|
||||||
This method needs to return an array of objects containing either strings, [`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) instances or instances of the [`LookupElement`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/lookup/LookupElement.java) class (see [Lookup Items](#lookup-items) below).
|
This method needs to return an array of objects containing either strings, [`PsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) instances or instances of the [`LookupElement`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInsight/lookup/LookupElement.java) class (see [Lookup Items](#lookup-items) below).
|
||||||
If a [`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) instance is returned in the array, the completion list shows the icon for the element.
|
If a [`PsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) instance is returned in the array, the completion list shows the icon for the element.
|
||||||
|
|
||||||
The most common way to implement `getVariants()` is to use the same function for walking up the tree as in [`PsiReference.resolve()`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java), and a different implementation of [`PsiScopeProcessor`](upsource:///platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java) which collects all declarations passed to its `execute()` method and returns them as an array for filling the completion list.
|
The most common way to implement `getVariants()` is to use the same function for walking up the tree as in [`PsiReference.resolve()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java), and a different implementation of [`PsiScopeProcessor`](%gh-ic%/platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java) which collects all declarations passed to its `execute()` method and returns them as an array for filling the completion list.
|
||||||
|
|
||||||
#### Symbol Reference Completion
|
#### Symbol Reference Completion
|
||||||
|
|
||||||
@ -22,18 +22,18 @@ The most common way to implement `getVariants()` is to use the same function for
|
|||||||
{type="warning"}
|
{type="warning"}
|
||||||
|
|
||||||
To provide completion variants by a `PsiSymbolReference` implement
|
To provide completion variants by a `PsiSymbolReference` implement
|
||||||
[`PsiCompletableReference`](upsource:///platform/analysis-api/src/com/intellij/model/psi/PsiCompletableReference.java).
|
[`PsiCompletableReference`](%gh-ic%/platform/analysis-api/src/com/intellij/model/psi/PsiCompletableReference.java).
|
||||||
|
|
||||||
### Contributor-Based Completion
|
### Contributor-Based Completion
|
||||||
|
|
||||||
Implementing the [`CompletionContributor`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/completion/CompletionContributor.java) interface gives you the greatest control over the operation of code completion for your language.
|
Implementing the [`CompletionContributor`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInsight/completion/CompletionContributor.java) interface gives you the greatest control over the operation of code completion for your language.
|
||||||
Register in `com.intellij.completion.contributor` extension point and specify `language` attribute (unless it works on any supported language).
|
Register in `com.intellij.completion.contributor` extension point and specify `language` attribute (unless it works on any supported language).
|
||||||
|
|
||||||
> Note that the JavaDoc of that class contains a detailed FAQ for implementing code completion.
|
> Note that the JavaDoc of that class contains a detailed FAQ for implementing code completion.
|
||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
The core scenario of using [`CompletionContributor`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/completion/CompletionContributor.java) consists of calling the `extend()` method and passing in the [Element Pattern](element_patterns.md) specifying the context in which this completion variant is applicable, as well as a *completion provider* which generates the items to show in the completion list.
|
The core scenario of using [`CompletionContributor`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInsight/completion/CompletionContributor.java) consists of calling the `extend()` method and passing in the [Element Pattern](element_patterns.md) specifying the context in which this completion variant is applicable, as well as a *completion provider* which generates the items to show in the completion list.
|
||||||
|
|
||||||
Keep in mind that the pattern is checked against the leaf PSI element.
|
Keep in mind that the pattern is checked against the leaf PSI element.
|
||||||
If you want to match a composite element, use `withParent()` or `withSuperParent()` methods.
|
If you want to match a composite element, use `withParent()` or `withSuperParent()` methods.
|
||||||
@ -43,8 +43,8 @@ If you want to match a composite element, use `withParent()` or `withSuperParent
|
|||||||
- [Custom Language Support Tutorial: Completion Contributor](completion_contributor.md)
|
- [Custom Language Support Tutorial: Completion Contributor](completion_contributor.md)
|
||||||
|
|
||||||
### Lookup Items
|
### Lookup Items
|
||||||
Items shown in the completion list are represented by instances of the [`LookupElement`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/lookup/LookupElement.java) interface.
|
Items shown in the completion list are represented by instances of the [`LookupElement`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInsight/lookup/LookupElement.java) interface.
|
||||||
These instances are typically created through the [`LookupElementBuilder`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java) class.
|
These instances are typically created through the [`LookupElementBuilder`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java) class.
|
||||||
|
|
||||||
For every lookup element, you can specify the following attributes:
|
For every lookup element, you can specify the following attributes:
|
||||||
|
|
||||||
@ -57,4 +57,4 @@ For every lookup element, you can specify the following attributes:
|
|||||||
|
|
||||||
### How to show a completion popup programmatically
|
### How to show a completion popup programmatically
|
||||||
|
|
||||||
Use [`AutoPopupController.scheduleAutoPopup()`](upsource:///platform/analysis-impl/src/com/intellij/codeInsight/AutoPopupController.java).
|
Use [`AutoPopupController.scheduleAutoPopup()`](%gh-ic%/platform/analysis-impl/src/com/intellij/codeInsight/AutoPopupController.java).
|
||||||
|
@ -9,13 +9,13 @@ The formatting engine, provided by the IDE, calculates the smallest number of wh
|
|||||||
The process of formatting a file or a file fragment consists of the following main steps:
|
The process of formatting a file or a file fragment consists of the following main steps:
|
||||||
|
|
||||||
* The _formatting model builder_ (
|
* The _formatting model builder_ (
|
||||||
[`FormattingModelBuilder`](upsource:///platform/code-style-api/src/com/intellij/formatting/FormattingModelBuilder.java)
|
[`FormattingModelBuilder`](%gh-ic%/platform/code-style-api/src/com/intellij/formatting/FormattingModelBuilder.java)
|
||||||
), implemented by the plugin, provides a formatting model (
|
), implemented by the plugin, provides a formatting model (
|
||||||
[`FormattingModel`](upsource:///platform/code-style-api/src/com/intellij/formatting/FormattingModel.java)
|
[`FormattingModel`](%gh-ic%/platform/code-style-api/src/com/intellij/formatting/FormattingModel.java)
|
||||||
) for the document to be formatted.
|
) for the document to be formatted.
|
||||||
|
|
||||||
* The formatting model is requested to build the structure of the file as applies to formatting, as a tree of _blocks_ (
|
* The formatting model is requested to build the structure of the file as applies to formatting, as a tree of _blocks_ (
|
||||||
[`Block`](upsource:///platform/code-style-api/src/com/intellij/formatting/Block.java)
|
[`Block`](%gh-ic%/platform/code-style-api/src/com/intellij/formatting/Block.java)
|
||||||
) with an associated indent, wrap, alignment, and spacing settings.
|
) with an associated indent, wrap, alignment, and spacing settings.
|
||||||
|
|
||||||
* The formatting engine calculates the sequence of whitespace characters (spaces, tabs, and/or line breaks) that needs to be placed at every block boundary, based on the plugin's formatting model.
|
* The formatting engine calculates the sequence of whitespace characters (spaces, tabs, and/or line breaks) that needs to be placed at every block boundary, based on the plugin's formatting model.
|
||||||
@ -39,11 +39,11 @@ Rather, only blocks for the text range covered by the formatting operation and t
|
|||||||
|
|
||||||
For every block, the plugin specifies the following properties:
|
For every block, the plugin specifies the following properties:
|
||||||
|
|
||||||
* The _spacing_ ([`Spacing`](upsource:///platform/code-style-api/src/com/intellij/formatting/Spacing.java)) specifies what spaces or line breaks are inserted between the specified children of the block.
|
* The _spacing_ ([`Spacing`](%gh-ic%/platform/code-style-api/src/com/intellij/formatting/Spacing.java)) specifies what spaces or line breaks are inserted between the specified children of the block.
|
||||||
The spacing object specifies the minimum and maximum number of spaces that must be placed between the specified child blocks, the minimum number of line breaks to put there, and whether the existing line breaks and blank lines should be preserved.
|
The spacing object specifies the minimum and maximum number of spaces that must be placed between the specified child blocks, the minimum number of line breaks to put there, and whether the existing line breaks and blank lines should be preserved.
|
||||||
The formatting model can also specify that the formatter may not modify the spacing between the specified blocks.
|
The formatting model can also specify that the formatter may not modify the spacing between the specified blocks.
|
||||||
|
|
||||||
* The _indent_ ([`Indent`](upsource:///platform/code-style-api/src/com/intellij/formatting/Indent.java)) specifies how the block is indented relative to its parent block.
|
* The _indent_ ([`Indent`](%gh-ic%/platform/code-style-api/src/com/intellij/formatting/Indent.java)) specifies how the block is indented relative to its parent block.
|
||||||
There are different modes of indenting defined by factory methods in the `Indent` class.
|
There are different modes of indenting defined by factory methods in the `Indent` class.
|
||||||
The most commonly used are:
|
The most commonly used are:
|
||||||
* the none indent (which means the child block is not indented)
|
* the none indent (which means the child block is not indented)
|
||||||
@ -53,15 +53,15 @@ For every block, the plugin specifies the following properties:
|
|||||||
If the formatting model does not specify an indent, the "continuation without first" mode is used.
|
If the formatting model does not specify an indent, the "continuation without first" mode is used.
|
||||||
This default means that the first block in a sequence of blocks with that type is not indented, and the following blocks are indented with a continuation indent.
|
This default means that the first block in a sequence of blocks with that type is not indented, and the following blocks are indented with a continuation indent.
|
||||||
|
|
||||||
* The _wrap_ ([`Wrap`](upsource:///platform/code-style-api/src/com/intellij/formatting/Wrap.java)) specifies whether the content of the block is wrapped to the next line.
|
* The _wrap_ ([`Wrap`](%gh-ic%/platform/code-style-api/src/com/intellij/formatting/Wrap.java)) specifies whether the content of the block is wrapped to the next line.
|
||||||
Wrapping is performed by inserting a line break before the block content.
|
Wrapping is performed by inserting a line break before the block content.
|
||||||
The plugin can specify that a particular block is never wrapped, always wrapped, or wrapped only if it exceeds the right margin.
|
The plugin can specify that a particular block is never wrapped, always wrapped, or wrapped only if it exceeds the right margin.
|
||||||
|
|
||||||
* The _alignment_ ([`Alignment`](upsource:///platform/code-style-api/src/com/intellij/formatting/Alignment.java)) specifies which blocks should be aligned with each other.
|
* The _alignment_ ([`Alignment`](%gh-ic%/platform/code-style-api/src/com/intellij/formatting/Alignment.java)) specifies which blocks should be aligned with each other.
|
||||||
If two blocks with the alignment property set to the same object instance are placed in different lines, and if the second block is the first non-whitespace block in its line, the formatter inserts white spaces before the second block, so that it starts from the same column as the first one.
|
If two blocks with the alignment property set to the same object instance are placed in different lines, and if the second block is the first non-whitespace block in its line, the formatter inserts white spaces before the second block, so that it starts from the same column as the first one.
|
||||||
|
|
||||||
For each of these properties, several particular use settings exist, described in the JavaDoc comments for the respective classes.
|
For each of these properties, several particular use settings exist, described in the JavaDoc comments for the respective classes.
|
||||||
See also [`SpacingBuilder`](upsource:///platform/code-style-api/src/com/intellij/formatting/SpacingBuilder.java), which aids in building rule-based configuration.
|
See also [`SpacingBuilder`](%gh-ic%/platform/code-style-api/src/com/intellij/formatting/SpacingBuilder.java), which aids in building rule-based configuration.
|
||||||
|
|
||||||
An important special case in using the formatter is the smart indent performed when the user presses the `Enter` key in a source code file.
|
An important special case in using the formatter is the smart indent performed when the user presses the `Enter` key in a source code file.
|
||||||
To determine the indent for the new line, the formatter engine calls the method `getChildAttributes()` on either the block immediately before the caret or the parent of that block, depending on the return value of the `isIncomplete()` method for the block before the caret.
|
To determine the indent for the new line, the formatter engine calls the method `getChildAttributes()` on either the block immediately before the caret or the parent of that block, depending on the return value of the `isIncomplete()` method for the block before the caret.
|
||||||
@ -83,30 +83,30 @@ Allows executing additional processing before the actual formatting is performed
|
|||||||
For example, it can be used to adjust the formatting range or modify the code by adding, removing, or converting elements like braces, semicolons, quotes, etc.
|
For example, it can be used to adjust the formatting range or modify the code by adding, removing, or converting elements like braces, semicolons, quotes, etc.
|
||||||
All the introduced changes will be handled by the main formatting step.
|
All the introduced changes will be handled by the main formatting step.
|
||||||
|
|
||||||
To register a formatting pre-processor, a plugin has to provide an implementation of [`PreFormatProcessor`](upsource:///platform/code-style-api/src/com/intellij/psi/impl/source/codeStyle/PreFormatProcessor.java) and register it in the `com.intellij.preFormatProcessor` extension point.
|
To register a formatting pre-processor, a plugin has to provide an implementation of [`PreFormatProcessor`](%gh-ic%/platform/code-style-api/src/com/intellij/psi/impl/source/codeStyle/PreFormatProcessor.java) and register it in the `com.intellij.preFormatProcessor` extension point.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
[`JsonTrailingCommaRemover`](upsource:///json/src/com/intellij/json/formatter/JsonTrailingCommaRemover.java) removing trailing commas in JSON files
|
[`JsonTrailingCommaRemover`](%gh-ic%/json/src/com/intellij/json/formatter/JsonTrailingCommaRemover.java) removing trailing commas in JSON files
|
||||||
|
|
||||||
### Post-Processor
|
### Post-Processor
|
||||||
|
|
||||||
It's similar to the pre-processor but is run after the actual formatting is performed.
|
It's similar to the pre-processor but is run after the actual formatting is performed.
|
||||||
It can be used for adding, removing, or converting elements like braces, semicolons, quotes, changing letter-cases, etc.
|
It can be used for adding, removing, or converting elements like braces, semicolons, quotes, changing letter-cases, etc.
|
||||||
|
|
||||||
To register a formatting post-processor, a plugin has to provide an implementation of [`PostFormatProcessor`](upsource:///platform/code-style-api/src/com/intellij/psi/impl/source/codeStyle/PostFormatProcessor.java) and register it in the `com.intellij.postFormatProcessor` extension point.
|
To register a formatting post-processor, a plugin has to provide an implementation of [`PostFormatProcessor`](%gh-ic%/platform/code-style-api/src/com/intellij/psi/impl/source/codeStyle/PostFormatProcessor.java) and register it in the `com.intellij.postFormatProcessor` extension point.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
[`TrailingCommaPostFormatProcessor`](upsource:///plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt) inserting trailing commas in Kotlin files
|
[`TrailingCommaPostFormatProcessor`](%gh-ic%/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt) inserting trailing commas in Kotlin files
|
||||||
|
|
||||||
### Rearranger
|
### Rearranger
|
||||||
|
|
||||||
Allows custom languages to provide user-configurable arrangement/grouping rules for element types supported by language plugin.
|
Allows custom languages to provide user-configurable arrangement/grouping rules for element types supported by language plugin.
|
||||||
Rules can be refined via modifiers and name; ordering can be applied additionally.
|
Rules can be refined via modifiers and name; ordering can be applied additionally.
|
||||||
Please see [`Rearranger`](upsource:///platform/code-style-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java) and related for JavaDoc.
|
Please see [`Rearranger`](%gh-ic%/platform/code-style-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java) and related for JavaDoc.
|
||||||
|
|
||||||
## Code Style Settings
|
## Code Style Settings
|
||||||
|
|
||||||
To specify the default indent size for the language provided by your plugin, and to allow the user to configure the tab size and indent size, you need to implement the [`FileTypeIndentOptionsProvider`](upsource:///platform/lang-api/src/com/intellij/psi/codeStyle/FileTypeIndentOptionsProvider.java) interface and to register the implementation in the `com.intellij.fileTypeIndentOptionsProvider` extension point.
|
To specify the default indent size for the language provided by your plugin, and to allow the user to configure the tab size and indent size, you need to implement the [`FileTypeIndentOptionsProvider`](%gh-ic%/platform/lang-api/src/com/intellij/psi/codeStyle/FileTypeIndentOptionsProvider.java) interface and to register the implementation in the `com.intellij.fileTypeIndentOptionsProvider` extension point.
|
||||||
The return value of `createIndentOptions()` determines the default indent size.
|
The return value of `createIndentOptions()` determines the default indent size.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
@ -116,7 +116,7 @@ The return value of `createIndentOptions()` determines the default indent size.
|
|||||||
|
|
||||||
_2021.3_
|
_2021.3_
|
||||||
|
|
||||||
Register [`AsyncDocumentFormattingService`](upsource:///platform/code-style-api/src/com/intellij/formatting/service/AsyncDocumentFormattingService.java) implementation in extension point [`com.intellij.formattingService`](https://jb.gg/ipe?extensions=com.intellij.formattingService) to invoke external formatter instead of IDE's builtin formatter.
|
Register [`AsyncDocumentFormattingService`](%gh-ic%/platform/code-style-api/src/com/intellij/formatting/service/AsyncDocumentFormattingService.java) implementation in extension point [`com.intellij.formattingService`](https://jb.gg/ipe?extensions=com.intellij.formattingService) to invoke external formatter instead of IDE's builtin formatter.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
[`ShExternalFormatter`](upsource:///plugins/sh/src/com/intellij/sh/formatter/ShExternalFormatter.java) from _Shell Script_ plugin
|
[`ShExternalFormatter`](%gh-ic%/plugins/sh/src/com/intellij/sh/formatter/ShExternalFormatter.java) from _Shell Script_ plugin
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
### Inspections
|
### Inspections
|
||||||
|
|
||||||
The code inspections for custom languages use the same API as all other code inspections, based on the [`LocalInspectionTool`](upsource:///platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java) class.
|
The code inspections for custom languages use the same API as all other code inspections, based on the [`LocalInspectionTool`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java) class.
|
||||||
|
|
||||||
The functionality of [`LocalInspectionTool`](upsource:///platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java) partially duplicates that of [Annotator](syntax_highlighting_and_error_highlighting.md#annotator).
|
The functionality of [`LocalInspectionTool`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java) partially duplicates that of [Annotator](syntax_highlighting_and_error_highlighting.md#annotator).
|
||||||
|
|
||||||
The main differences are:
|
The main differences are:
|
||||||
- supports batch analysis of code (through the <menupath>Code | Inspect Code...</menupath> action)
|
- supports batch analysis of code (through the <menupath>Code | Inspect Code...</menupath> action)
|
||||||
@ -19,14 +19,14 @@ See [Inspections](https://jetbrains.design/intellij/text/inspections/) topic in
|
|||||||
|
|
||||||
**Examples**:
|
**Examples**:
|
||||||
- [Code Inspections Tutorial](code_inspections.md)
|
- [Code Inspections Tutorial](code_inspections.md)
|
||||||
- A [simple inspection](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/codeInspection/TrailingSpacesInPropertyInspection.java) for [Properties language plugin](upsource:///plugins/properties)
|
- A [simple inspection](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/codeInspection/TrailingSpacesInPropertyInspection.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
|
||||||
### Intentions
|
### Intentions
|
||||||
|
|
||||||
The code intentions for custom languages also use the standard API for intentions.
|
The code intentions for custom languages also use the standard API for intentions.
|
||||||
The intention classes need to implement the [`IntentionAction`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java) interface and are registered using the `com.intellij.intentionAction` extension point.
|
The intention classes need to implement the [`IntentionAction`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java) interface and are registered using the `com.intellij.intentionAction` extension point.
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
- [Code Intentions Tutorial](code_intentions.md)
|
- [Code Intentions Tutorial](code_intentions.md)
|
||||||
- A [simple intention action](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitIfIntention.java) for Groovy
|
- A [simple intention action](%gh-ic%/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitIfIntention.java) for Groovy
|
||||||
- [Custom Language Support Tutorial: Quick Fix](quick_fix.md)
|
- [Custom Language Support Tutorial: Quick Fix](quick_fix.md)
|
||||||
|
@ -16,18 +16,18 @@ Each [symbol](symbols.md) may be declared in zero or more places, for example:
|
|||||||
- and a file is a symbol without declarations; it has only references.
|
- and a file is a symbol without declarations; it has only references.
|
||||||
|
|
||||||
Declarations in PSI elements are implementations of
|
Declarations in PSI elements are implementations of
|
||||||
[`PsiSymbolDeclaration`](upsource:///platform/core-api/src/com/intellij/model/psi/PsiSymbolDeclaration.java).
|
[`PsiSymbolDeclaration`](%gh-ic%/platform/core-api/src/com/intellij/model/psi/PsiSymbolDeclaration.java).
|
||||||
|
|
||||||
To report a declaration in a PSI element, either:
|
To report a declaration in a PSI element, either:
|
||||||
|
|
||||||
- implement and register
|
- implement and register
|
||||||
[`PsiSymbolDeclarationProvider`](upsource:///platform/core-api/src/com/intellij/model/psi/PsiSymbolDeclarationProvider.java);
|
[`PsiSymbolDeclarationProvider`](%gh-ic%/platform/core-api/src/com/intellij/model/psi/PsiSymbolDeclarationProvider.java);
|
||||||
- or implement `PsiSymbolDeclaration` directly in the `PsiElement`.
|
- or implement `PsiSymbolDeclaration` directly in the `PsiElement`.
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
References from PSI elements are implementations of
|
References from PSI elements are implementations of
|
||||||
[`PsiSymbolReference`](upsource:///platform/core-api/src/com/intellij/model/psi/PsiSymbolReference.java) interface.
|
[`PsiSymbolReference`](%gh-ic%/platform/core-api/src/com/intellij/model/psi/PsiSymbolReference.java) interface.
|
||||||
|
|
||||||
The main method of `PsiSymbolReference` is `resolveReference()`, which returns the collection of symbols to which the reference points,
|
The main method of `PsiSymbolReference` is `resolveReference()`, which returns the collection of symbols to which the reference points,
|
||||||
plus additional data.
|
plus additional data.
|
||||||
@ -37,7 +37,7 @@ which checks if the reference resolves to the specified symbol.
|
|||||||
This method can be implemented to walk the tree only if the element's text is equal to the reference's text.
|
This method can be implemented to walk the tree only if the element's text is equal to the reference's text.
|
||||||
|
|
||||||
For convenience, if the reference can possibly be resolved to a single symbol without additional data, then it might be extended from
|
For convenience, if the reference can possibly be resolved to a single symbol without additional data, then it might be extended from
|
||||||
[`SingleTargetReference`](upsource:///platform/core-api/src/com/intellij/model/SingleTargetReference.java).
|
[`SingleTargetReference`](%gh-ic%/platform/core-api/src/com/intellij/model/SingleTargetReference.java).
|
||||||
|
|
||||||
### Own References
|
### Own References
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ PSI element representing `x` in `x * 2` Java expression has an Own reference to
|
|||||||
because this is a reference from Java language point of view, and Java language support uses it, e.g., for code analysis.
|
because this is a reference from Java language point of view, and Java language support uses it, e.g., for code analysis.
|
||||||
|
|
||||||
To provide Own references by the `PsiElement`, implement
|
To provide Own references by the `PsiElement`, implement
|
||||||
[`PsiElement.getOwnReferences()`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) in the `PsiElement`.
|
[`PsiElement.getOwnReferences()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) in the `PsiElement`.
|
||||||
If the element contains a single reference, `Collections.singletonList()` can be used
|
If the element contains a single reference, `Collections.singletonList()` can be used
|
||||||
|
|
||||||
### External References
|
### External References
|
||||||
@ -61,10 +61,10 @@ PSI element representing `"users.txt"` in `new File("users.txt")` Java expressio
|
|||||||
but there is a plugin which _knows_ that this literal references a file name, and provides such reference.
|
but there is a plugin which _knows_ that this literal references a file name, and provides such reference.
|
||||||
|
|
||||||
External references might be contributed to PSI elements
|
External references might be contributed to PSI elements
|
||||||
that implement [`PsiExternalReferenceHost`](upsource:///platform/core-api/src/com/intellij/model/psi/PsiExternalReferenceHost.java).
|
that implement [`PsiExternalReferenceHost`](%gh-ic%/platform/core-api/src/com/intellij/model/psi/PsiExternalReferenceHost.java).
|
||||||
To allow other plugins to contribute references of `PsiElement`, implement `PsiExternalReferenceHost` in the `PsiElement`.
|
To allow other plugins to contribute references of `PsiElement`, implement `PsiExternalReferenceHost` in the `PsiElement`.
|
||||||
To contribute an External reference to the existing `PsiExternalReferenceHost`, implement and register
|
To contribute an External reference to the existing `PsiExternalReferenceHost`, implement and register
|
||||||
[`PsiSymbolReferenceProvider`](upsource:///platform/core-api/src/com/intellij/model/psi/PsiSymbolReferenceProvider.java).
|
[`PsiSymbolReferenceProvider`](%gh-ic%/platform/core-api/src/com/intellij/model/psi/PsiSymbolReferenceProvider.java).
|
||||||
|
|
||||||
### Implicit References
|
### Implicit References
|
||||||
|
|
||||||
@ -81,5 +81,5 @@ At the same time, it's possible:
|
|||||||
- to view documentation of the class targeted by this reference.
|
- to view documentation of the class targeted by this reference.
|
||||||
|
|
||||||
To provide an Implicit reference, implement and register
|
To provide an Implicit reference, implement and register
|
||||||
[`ImplicitReferenceProvider`](upsource:///platform/core-api/src/com/intellij/model/psi/ImplicitReferenceProvider.java)
|
[`ImplicitReferenceProvider`](%gh-ic%/platform/core-api/src/com/intellij/model/psi/ImplicitReferenceProvider.java)
|
||||||
in `com.intellij.psi.implicitReferenceProvider` extension point.
|
in `com.intellij.psi.implicitReferenceProvider` extension point.
|
||||||
|
@ -15,16 +15,16 @@ In addition to showing the documentation, the `getQuickNavigateInfo()` method re
|
|||||||
when the user hovers over an element with <shortcut>Ctrl</shortcut>/<shortcut>Cmd</shortcut> pressed.
|
when the user hovers over an element with <shortcut>Ctrl</shortcut>/<shortcut>Cmd</shortcut> pressed.
|
||||||
|
|
||||||
Custom actions can also be added to documentation inlays and documentation popups via
|
Custom actions can also be added to documentation inlays and documentation popups via
|
||||||
[`DocumentationActionProvider`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationActionProvider.java) registered in the
|
[`DocumentationActionProvider`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationActionProvider.java) registered in the
|
||||||
`com.intellij.documentationActionProvider` extension point.
|
`com.intellij.documentationActionProvider` extension point.
|
||||||
|
|
||||||
|
|
||||||
# Implementation
|
# Implementation
|
||||||
|
|
||||||
Custom language developers usually extend from
|
Custom language developers usually extend from
|
||||||
[`AbstractDocumentationProvider`](upsource:///platform/analysis-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java)
|
[`AbstractDocumentationProvider`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java)
|
||||||
instead of implementing the
|
instead of implementing the
|
||||||
[`DocumentationProvider`](upsource:///platform/analysis-api/src/com/intellij/lang/documentation/DocumentationProvider.java) interface.
|
[`DocumentationProvider`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/documentation/DocumentationProvider.java) interface.
|
||||||
This implementation needs to be registered as `com.intellij.lang.documentationProvider` in the <path>plugin.xml</path>.
|
This implementation needs to be registered as `com.intellij.lang.documentationProvider` in the <path>plugin.xml</path>.
|
||||||
|
|
||||||
The main work is done in `generateDoc()`, which has two PSI element arguments:
|
The main work is done in `generateDoc()`, which has two PSI element arguments:
|
||||||
@ -35,10 +35,10 @@ and provide the correct element.
|
|||||||
How the documentation for the target element is created is up to the custom language developer.
|
How the documentation for the target element is created is up to the custom language developer.
|
||||||
A common choice is to extract and format documentation comments.
|
A common choice is to extract and format documentation comments.
|
||||||
To format the documentation contents, you should use
|
To format the documentation contents, you should use
|
||||||
[`DocumentationMarkup`](upsource:///platform/analysis-api/src/com/intellij/lang/documentation/DocumentationMarkup.java)
|
[`DocumentationMarkup`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/documentation/DocumentationMarkup.java)
|
||||||
to achieve a consistent output.
|
to achieve a consistent output.
|
||||||
|
|
||||||
> Use [`HtmlSyntaxInfoUtil`](upsource:///platform/lang-impl/src/com/intellij/openapi/editor/richcopy/HtmlSyntaxInfoUtil.java) to create Lexer-based highlighted code samples.
|
> Use [`HtmlSyntaxInfoUtil`](%gh-ic%/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/HtmlSyntaxInfoUtil.java) to create Lexer-based highlighted code samples.
|
||||||
>
|
>
|
||||||
{type="tip"}
|
{type="tip"}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ Once these steps are completed, the following additional features can be impleme
|
|||||||
* Implement `generateHoverDoc()` to show different contents on mouse hover.
|
* Implement `generateHoverDoc()` to show different contents on mouse hover.
|
||||||
* Implement `getDocumentationElementForLookupItem()` to return a suitable PSI element for the given lookup element when
|
* Implement `getDocumentationElementForLookupItem()` to return a suitable PSI element for the given lookup element when
|
||||||
<menupath>View | Quick Documentation</menupath> is called on an element of the autocompletion popup.
|
<menupath>View | Quick Documentation</menupath> is called on an element of the autocompletion popup.
|
||||||
* Implement `getUrlFor()` and [`ExternalDocumentationProvider`](upsource:///platform/analysis-api/src/com/intellij/lang/documentation/ExternalDocumentationProvider.java) to fetch documentation for elements from online resources.
|
* Implement `getUrlFor()` and [`ExternalDocumentationProvider`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/documentation/ExternalDocumentationProvider.java) to fetch documentation for elements from online resources.
|
||||||
|
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
@ -56,5 +56,5 @@ Once these steps are completed, the following additional features can be impleme
|
|||||||
The [custom language tutorial](documentation_provider.md) contains a step-by-step guide for the `DocumentationProvider` of the Simple language.
|
The [custom language tutorial](documentation_provider.md) contains a step-by-step guide for the `DocumentationProvider` of the Simple language.
|
||||||
In addition, several implementations of other languages exist in the IntelliJ Platform code, for instance:
|
In addition, several implementations of other languages exist in the IntelliJ Platform code, for instance:
|
||||||
|
|
||||||
* The [Properties Language plugin](upsource:///plugins/properties) has a small and easy-to-understand [`DocumentationProvider`](upsource:///plugins/properties/src/com/intellij/lang/properties/PropertiesDocumentationProvider.java) similar to the one shown in the custom language tutorial.
|
* The [Properties Language plugin](%gh-ic%/plugins/properties) has a small and easy-to-understand [`DocumentationProvider`](%gh-ic%/plugins/properties/src/com/intellij/lang/properties/PropertiesDocumentationProvider.java) similar to the one shown in the custom language tutorial.
|
||||||
* Usage examples for `DocumentationMarkup` can be found in [`ThemeJsonDocumentationProvider`](upsource:///plugins/devkit/intellij.devkit.themes/src/ThemeJsonDocumentationProvider.java).
|
* Usage examples for `DocumentationMarkup` can be found in [`ThemeJsonDocumentationProvider`](%gh-ic%/plugins/devkit/intellij.devkit.themes/src/ThemeJsonDocumentationProvider.java).
|
||||||
|
@ -4,38 +4,38 @@
|
|||||||
|
|
||||||
The _Find Usages_ action is a multi-step process, and each step of the process requires involvement from the custom language plugin.
|
The _Find Usages_ action is a multi-step process, and each step of the process requires involvement from the custom language plugin.
|
||||||
|
|
||||||
The language plugin participates in the Find Usages process by registering an implementation of [`FindUsagesProvider`](upsource:///platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) in the `com.intellij.lang.findUsagesProvider` extension point, and through the PSI implementation using [`PsiNamedElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java) and [`PsiReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) interfaces.
|
The language plugin participates in the Find Usages process by registering an implementation of [`FindUsagesProvider`](%gh-ic%/platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) in the `com.intellij.lang.findUsagesProvider` extension point, and through the PSI implementation using [`PsiNamedElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java) and [`PsiReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) interfaces.
|
||||||
|
|
||||||
**Examples**:
|
**Examples**:
|
||||||
- Implementation of [`FindUsagesProvider`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/findUsages/PropertiesFindUsagesProvider.java) in [Properties language plugin](upsource:///plugins/properties)
|
- Implementation of [`FindUsagesProvider`](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/findUsages/PropertiesFindUsagesProvider.java) in [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
- [Custom Language Support Tutorial: Find Usages](find_usages_provider.md)
|
- [Custom Language Support Tutorial: Find Usages](find_usages_provider.md)
|
||||||
|
|
||||||
The steps of the _Find Usages_ action are the following:
|
The steps of the _Find Usages_ action are the following:
|
||||||
* Before the _Find Usages_ action can be invoked, the IDE builds an index of words present in every file in the custom language.
|
* Before the _Find Usages_ action can be invoked, the IDE builds an index of words present in every file in the custom language.
|
||||||
Using the [`WordsScanner`](upsource:///platform/indexing-api/src/com/intellij/lang/cacheBuilder/WordsScanner.java) implementation returned from [`FindUsagesProvider.getWordsScanner()`](upsource:///platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java), the contents of every file are loaded and passes it to the words scanner, along with the words consumer.
|
Using the [`WordsScanner`](%gh-ic%/platform/indexing-api/src/com/intellij/lang/cacheBuilder/WordsScanner.java) implementation returned from [`FindUsagesProvider.getWordsScanner()`](%gh-ic%/platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java), the contents of every file are loaded and passes it to the words scanner, along with the words consumer.
|
||||||
The words scanner breaks the text into words, defines the context for each word (code, comments, or literals), and passes the word to the consumer.
|
The words scanner breaks the text into words, defines the context for each word (code, comments, or literals), and passes the word to the consumer.
|
||||||
The simplest way to implement the words scanner is to use the [`DefaultWordsScanner`](upsource:///platform/indexing-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java) implementation, passing to it the sets of lexer token types which are treated as identifiers, literals, and comments.
|
The simplest way to implement the words scanner is to use the [`DefaultWordsScanner`](%gh-ic%/platform/indexing-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java) implementation, passing to it the sets of lexer token types which are treated as identifiers, literals, and comments.
|
||||||
The default words scanner will use the lexer to break the text into tokens and handle breaking the text of the comment and literal tokens into individual words.
|
The default words scanner will use the lexer to break the text into tokens and handle breaking the text of the comment and literal tokens into individual words.
|
||||||
* When the user invokes the _Find Usages_ action, the IDE locates the PSI element the references to be searched.
|
* When the user invokes the _Find Usages_ action, the IDE locates the PSI element the references to be searched.
|
||||||
The PSI element at the cursor (the direct tree parent of the token at the cursor position) must be either a [`PsiNamedElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java) or a [`PsiReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) which resolves to a [`PsiNamedElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java).
|
The PSI element at the cursor (the direct tree parent of the token at the cursor position) must be either a [`PsiNamedElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java) or a [`PsiReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) which resolves to a [`PsiNamedElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java).
|
||||||
The word cache will be used to search for the text returned from the [`PsiNamedElement.getName()`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java) method.
|
The word cache will be used to search for the text returned from the [`PsiNamedElement.getName()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java) method.
|
||||||
Also, if the text range of the [`PsiNamedElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java) includes some other text besides the identifier returned from `getName()` (for example, if the [`PsiNamedElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java) represents a JavaScript function and its text range includes the "`function`" keyword in addition to the name of the function), the method `getTextOffset()` must be overridden for the [`PsiNamedElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java), and must return the start offset of the name identifier within the text range of the element.
|
Also, if the text range of the [`PsiNamedElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java) includes some other text besides the identifier returned from `getName()` (for example, if the [`PsiNamedElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java) represents a JavaScript function and its text range includes the "`function`" keyword in addition to the name of the function), the method `getTextOffset()` must be overridden for the [`PsiNamedElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java), and must return the start offset of the name identifier within the text range of the element.
|
||||||
* Once the element is located, the IDE calls [`FindUsagesProvider.canFindUsagesFor()`](upsource:///platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) to ask the plugin if the _Find Usages_ action applies to the specific element.
|
* Once the element is located, the IDE calls [`FindUsagesProvider.canFindUsagesFor()`](%gh-ic%/platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) to ask the plugin if the _Find Usages_ action applies to the specific element.
|
||||||
* When showing the _Find Usages_ dialog to the user, [`FindUsagesProvider.getType()`](upsource:///platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) and [`FindUsagesProvider.getDescriptiveName()`](upsource:///platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) are called to determine how the element should be presented to the user.
|
* When showing the _Find Usages_ dialog to the user, [`FindUsagesProvider.getType()`](%gh-ic%/platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) and [`FindUsagesProvider.getDescriptiveName()`](%gh-ic%/platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) are called to determine how the element should be presented to the user.
|
||||||
* For every file containing the searched words, the IDE builds the PSI tree and recursively descends it.
|
* For every file containing the searched words, the IDE builds the PSI tree and recursively descends it.
|
||||||
The text of each element is broken into words and then scanned.
|
The text of each element is broken into words and then scanned.
|
||||||
If the element was indexed as an identifier, every word is checked to be a [`PsiReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) resolving to the element the usages of which are searched.
|
If the element was indexed as an identifier, every word is checked to be a [`PsiReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) resolving to the element the usages of which are searched.
|
||||||
If the element was indexed as a comment or literal and the search in comments or literals is enabled, it checks if the word is equal to the searched element's name.
|
If the element was indexed as a comment or literal and the search in comments or literals is enabled, it checks if the word is equal to the searched element's name.
|
||||||
* After the usages are collected, results are shown in the usages pane.
|
* After the usages are collected, results are shown in the usages pane.
|
||||||
The text shown for each found element is taken from the [`FindUsagesProvider.getNodeText()`](upsource:///platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) method.
|
The text shown for each found element is taken from the [`FindUsagesProvider.getNodeText()`](%gh-ic%/platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java) method.
|
||||||
To group results by type, implement [`UsageTypeProvider`](upsource:///platform/usageView-impl/src/com/intellij/usages/impl/rules/UsageTypeProvider.java) and register in `com.intellij.usageTypeProvider` extension point to provide custom or predefined [`UsageType`](upsource:///platform/usageView/src/com/intellij/usages/impl/rules/UsageType.java).
|
To group results by type, implement [`UsageTypeProvider`](%gh-ic%/platform/usageView-impl/src/com/intellij/usages/impl/rules/UsageTypeProvider.java) and register in `com.intellij.usageTypeProvider` extension point to provide custom or predefined [`UsageType`](%gh-ic%/platform/usageView/src/com/intellij/usages/impl/rules/UsageType.java).
|
||||||
|
|
||||||
To have the title of the found element be correctly displayed in the title of the Find Usages tool window, you need to provide an implementation of the [`ElementDescriptionProvider`](upsource:///platform/core-api/src/com/intellij/psi/ElementDescriptionProvider.java) interface.
|
To have the title of the found element be correctly displayed in the title of the Find Usages tool window, you need to provide an implementation of the [`ElementDescriptionProvider`](%gh-ic%/platform/core-api/src/com/intellij/psi/ElementDescriptionProvider.java) interface.
|
||||||
The [`ElementDescriptionLocation`](upsource:///platform/core-api/src/com/intellij/psi/ElementDescriptionLocation.java) passed to the provider in this case will be an instance of [`UsageViewLongNameLocation`](upsource:///platform/usageView/src/com/intellij/usageView/UsageViewLongNameLocation.java).
|
The [`ElementDescriptionLocation`](%gh-ic%/platform/core-api/src/com/intellij/psi/ElementDescriptionLocation.java) passed to the provider in this case will be an instance of [`UsageViewLongNameLocation`](%gh-ic%/platform/usageView/src/com/intellij/usageView/UsageViewLongNameLocation.java).
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
[`ElementDescriptionProvider`](upsource:///plugins/properties/src/com/intellij/lang/properties/PropertiesDescriptionProvider.java) for [Properties language plugin](upsource:///plugins/properties)
|
[`ElementDescriptionProvider`](%gh-ic%/plugins/properties/src/com/intellij/lang/properties/PropertiesDescriptionProvider.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
|
||||||
> In cases like function parameters and local variables, consider overriding [`PsiElement.getUseScope()`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) to return a narrower scope.
|
> In cases like function parameters and local variables, consider overriding [`PsiElement.getUseScope()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) to return a narrower scope.
|
||||||
> For instance, you might return just the scope of the nearest function definition.
|
> For instance, you might return just the scope of the nearest function definition.
|
||||||
> This optimization can significantly reduce the number of files that need to be parsed--and references that need to be resolved--when renaming a function parameter or local variable.
|
> This optimization can significantly reduce the number of files that need to be parsed--and references that need to be resolved--when renaming a function parameter or local variable.
|
||||||
|
@ -4,16 +4,16 @@
|
|||||||
|
|
||||||
A custom language plugin can provide its items to be included in the lists shown when the user chooses the <menupath>Navigate | Class</menupath> or <menupath>Navigate | Symbol</menupath> action.
|
A custom language plugin can provide its items to be included in the lists shown when the user chooses the <menupath>Navigate | Class</menupath> or <menupath>Navigate | Symbol</menupath> action.
|
||||||
|
|
||||||
Provide implementations of [`ChooseByNameContributor`](upsource:///platform/lang-api/src/com/intellij/navigation/ChooseByNameContributor.java) interface (separate implementations need to be provided for <control>Class</control> and <control>Symbol</control>, respectively), and register them in the `com.intellij.gotoClassContributor` and `com.intellij.gotoSymbolContributor` extension points.
|
Provide implementations of [`ChooseByNameContributor`](%gh-ic%/platform/lang-api/src/com/intellij/navigation/ChooseByNameContributor.java) interface (separate implementations need to be provided for <control>Class</control> and <control>Symbol</control>, respectively), and register them in the `com.intellij.gotoClassContributor` and `com.intellij.gotoSymbolContributor` extension points.
|
||||||
|
|
||||||
> Please consider implementing [`ChooseByNameContributorEx`](upsource:///platform/lang-impl/src/com/intellij/navigation/ChooseByNameContributorEx.java) for better performance.
|
> Please consider implementing [`ChooseByNameContributorEx`](%gh-ic%/platform/lang-impl/src/com/intellij/navigation/ChooseByNameContributorEx.java) for better performance.
|
||||||
>
|
>
|
||||||
{type="tip"}
|
{type="tip"}
|
||||||
|
|
||||||
Each contributor must return a complete list of names to show in the list for a specified project, which the IDE will then filter according to the text typed by the user in the dialog.
|
Each contributor must return a complete list of names to show in the list for a specified project, which the IDE will then filter according to the text typed by the user in the dialog.
|
||||||
Using [File-based or Stub indices](indexing_and_psi_stubs.md) to obtain matching candidates is highly recommended to improve performance.
|
Using [File-based or Stub indices](indexing_and_psi_stubs.md) to obtain matching candidates is highly recommended to improve performance.
|
||||||
|
|
||||||
For each name in that list, the contributor needs to provide a list of [`NavigationItem`](upsource:///platform/core-api/src/com/intellij/navigation/NavigationItem.java) instances (typically [`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java)), which specify the destinations to jump to when a specific item is selected from the list.
|
For each name in that list, the contributor needs to provide a list of [`NavigationItem`](%gh-ic%/platform/core-api/src/com/intellij/navigation/NavigationItem.java) instances (typically [`PsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java)), which specify the destinations to jump to when a specific item is selected from the list.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
- [Custom Language Support Tutorial: Go To Symbol Contributor](go_to_symbol_contributor.md)
|
- [Custom Language Support Tutorial: Go To Symbol Contributor](go_to_symbol_contributor.md)
|
||||||
|
@ -9,21 +9,21 @@ A Lexer defines how a file's contents are broken into tokens.
|
|||||||
The lexer, or [lexical analyzer](https://en.wikipedia.org/wiki/Lexical_analysis), defines how a file's contents are broken into tokens.
|
The lexer, or [lexical analyzer](https://en.wikipedia.org/wiki/Lexical_analysis), defines how a file's contents are broken into tokens.
|
||||||
The lexer serves as a foundation for nearly all features of custom language plugins, from basic syntax highlighting to advanced code analysis features.
|
The lexer serves as a foundation for nearly all features of custom language plugins, from basic syntax highlighting to advanced code analysis features.
|
||||||
|
|
||||||
The API for the lexer is defined by the [`Lexer`](upsource:///platform/core-api/src/com/intellij/lexer/Lexer.java) interface.
|
The API for the lexer is defined by the [`Lexer`](%gh-ic%/platform/core-api/src/com/intellij/lexer/Lexer.java) interface.
|
||||||
|
|
||||||
The IDE invokes the lexer in three main contexts, and the plugin can provide different lexer implementations if needed:
|
The IDE invokes the lexer in three main contexts, and the plugin can provide different lexer implementations if needed:
|
||||||
|
|
||||||
* [Syntax highlighting](syntax_highlighting_and_error_highlighting.md#lexer): The lexer is returned from the implementation of the
|
* [Syntax highlighting](syntax_highlighting_and_error_highlighting.md#lexer): The lexer is returned from the implementation of the
|
||||||
[`SyntaxHighlighterFactory`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java)
|
[`SyntaxHighlighterFactory`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java)
|
||||||
interface which is registered in the `com.intellij.lang.syntaxHighlighterFactory` extension point.
|
interface which is registered in the `com.intellij.lang.syntaxHighlighterFactory` extension point.
|
||||||
|
|
||||||
* [Building the syntax tree of a file](grammar_and_parser.md): the lexer is expected to be returned from
|
* [Building the syntax tree of a file](grammar_and_parser.md): the lexer is expected to be returned from
|
||||||
[`ParserDefinition.createLexer()`](upsource:///platform/core-api/src/com/intellij/lang/ParserDefinition.java)
|
[`ParserDefinition.createLexer()`](%gh-ic%/platform/core-api/src/com/intellij/lang/ParserDefinition.java)
|
||||||
implementation registered in the `com.intellij.lang.parserDefinition` extension point.
|
implementation registered in the `com.intellij.lang.parserDefinition` extension point.
|
||||||
|
|
||||||
* Building the index of the words contained in the file:
|
* Building the index of the words contained in the file:
|
||||||
if the lexer-based words scanner implementation is used, the lexer is passed to the
|
if the lexer-based words scanner implementation is used, the lexer is passed to the
|
||||||
[`DefaultWordsScanner`](upsource:///platform/indexing-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java)
|
[`DefaultWordsScanner`](%gh-ic%/platform/indexing-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java)
|
||||||
constructor. See also [](find_usages.md).
|
constructor. See also [](find_usages.md).
|
||||||
|
|
||||||
The lexer used for syntax highlighting can be invoked incrementally to process only the file's changed part.
|
The lexer used for syntax highlighting can be invoked incrementally to process only the file's changed part.
|
||||||
@ -32,7 +32,7 @@ In contrast, lexers used in other contexts are always called to process an entir
|
|||||||
### Lexer State
|
### Lexer State
|
||||||
|
|
||||||
A lexer that can be used incrementally may need to return its *state*, which means the context corresponding to each position in a file.
|
A lexer that can be used incrementally may need to return its *state*, which means the context corresponding to each position in a file.
|
||||||
For example, a [Java lexer](upsource:///java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java) could have separate states for top-level context, comment context, and string literal context.
|
For example, a [Java lexer](%gh-ic%/java/java-psi-impl/src/com/intellij/lang/java/lexer/JavaLexer.java) could have separate states for top-level context, comment context, and string literal context.
|
||||||
|
|
||||||
An essential requirement for a syntax highlighting lexer is that its state must be represented by a single integer number returned from `Lexer.getState()`.
|
An essential requirement for a syntax highlighting lexer is that its state must be represented by a single integer number returned from `Lexer.getState()`.
|
||||||
That state will be passed to the `Lexer.start()` method, along with the start offset of the fragment to process, when lexing is resumed from the middle of a file.
|
That state will be passed to the `Lexer.start()` method, along with the start offset of the fragment to process, when lexing is resumed from the middle of a file.
|
||||||
@ -42,8 +42,8 @@ Lexers used in other contexts can always return `0` from `getState()`.
|
|||||||
|
|
||||||
The easiest way to create a lexer for a custom language plugin is to use [JFlex](https://jflex.de).
|
The easiest way to create a lexer for a custom language plugin is to use [JFlex](https://jflex.de).
|
||||||
|
|
||||||
Classes [`FlexLexer`](upsource:///platform/core-api/src/com/intellij/lexer/FlexLexer.java) and [`FlexAdapter`](upsource:///platform/core-api/src/com/intellij/lexer/FlexAdapter.java) adapt JFlex lexers to the IntelliJ Platform Lexer API.
|
Classes [`FlexLexer`](%gh-ic%/platform/core-api/src/com/intellij/lexer/FlexLexer.java) and [`FlexAdapter`](%gh-ic%/platform/core-api/src/com/intellij/lexer/FlexAdapter.java) adapt JFlex lexers to the IntelliJ Platform Lexer API.
|
||||||
A [patched version of JFlex](https://github.com/JetBrains/intellij-deps-jflex) can be used with the lexer skeleton file [`idea-flex.skeleton`](upsource:///tools/lexer/idea-flex.skeleton) located in the [IntelliJ IDEA Community Edition](https://github.com/JetBrains/intellij-community) source to create lexers compatible with `FlexAdapter`.
|
A [patched version of JFlex](https://github.com/JetBrains/intellij-deps-jflex) can be used with the lexer skeleton file [`idea-flex.skeleton`](%gh-ic%/tools/lexer/idea-flex.skeleton) located in the [IntelliJ IDEA Community Edition](https://github.com/JetBrains/intellij-community) source to create lexers compatible with `FlexAdapter`.
|
||||||
The patched version of JFlex provides a new command-line option `--charat` that changes the JFlex generated code to work with the IntelliJ Platform skeleton.
|
The patched version of JFlex provides a new command-line option `--charat` that changes the JFlex generated code to work with the IntelliJ Platform skeleton.
|
||||||
Enabling `--charat` option passes the source data for lexing as a `java.lang.CharSequence` and not as an array of characters.
|
Enabling `--charat` option passes the source data for lexing as a `java.lang.CharSequence` and not as an array of characters.
|
||||||
|
|
||||||
@ -56,24 +56,24 @@ It provides syntax highlighting and other useful features for editing JFlex file
|
|||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
**Examples**:
|
**Examples**:
|
||||||
- [JFlex](upsource:///plugins/properties/src/com/intellij/lang/properties/parsing/Properties.flex) definition file for [Properties language plugin](upsource:///plugins/properties)
|
- [JFlex](%gh-ic%/plugins/properties/src/com/intellij/lang/properties/parsing/Properties.flex) definition file for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
- [Custom Language Support Tutorial: Lexer](lexer_and_parser_definition.md)
|
- [Custom Language Support Tutorial: Lexer](lexer_and_parser_definition.md)
|
||||||
|
|
||||||
### Token Types
|
### Token Types
|
||||||
|
|
||||||
Types of tokens for lexers are defined by instances of [`IElementType`](upsource:///platform/core-api/src/com/intellij/psi/tree/IElementType.java).
|
Types of tokens for lexers are defined by instances of [`IElementType`](%gh-ic%/platform/core-api/src/com/intellij/psi/tree/IElementType.java).
|
||||||
Many token types common for all languages are defined in the [`TokenType`](upsource:///platform/core-api/src/com/intellij/psi/TokenType.java) interface.
|
Many token types common for all languages are defined in the [`TokenType`](%gh-ic%/platform/core-api/src/com/intellij/psi/TokenType.java) interface.
|
||||||
Custom language plugins should reuse these token types wherever applicable.
|
Custom language plugins should reuse these token types wherever applicable.
|
||||||
For all other token types, the plugin needs to create new [`IElementType`](upsource:///platform/core-api/src/com/intellij/psi/tree/IElementType.java) instances and associate with the language in which the token type is used.
|
For all other token types, the plugin needs to create new [`IElementType`](%gh-ic%/platform/core-api/src/com/intellij/psi/tree/IElementType.java) instances and associate with the language in which the token type is used.
|
||||||
The same [`IElementType`](upsource:///platform/core-api/src/com/intellij/psi/tree/IElementType.java) instance should be returned every time a particular token type is encountered by the lexer.
|
The same [`IElementType`](%gh-ic%/platform/core-api/src/com/intellij/psi/tree/IElementType.java) instance should be returned every time a particular token type is encountered by the lexer.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
[Token types](upsource:///plugins/properties/properties-psi-api/src/com/intellij/lang/properties/parsing/PropertiesTokenTypes.java) for [Properties language plugin](upsource:///plugins/properties)
|
[Token types](%gh-ic%/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/parsing/PropertiesTokenTypes.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
|
||||||
### Embedded Language
|
### Embedded Language
|
||||||
|
|
||||||
An important feature that can be implemented at the lexer level is mixing languages within a file, such as embedding fragments of Java code in some template language.
|
An important feature that can be implemented at the lexer level is mixing languages within a file, such as embedding fragments of Java code in some template language.
|
||||||
Suppose a language supports embedding its fragments in another language.
|
Suppose a language supports embedding its fragments in another language.
|
||||||
In that case, it needs to define the chameleon token types for different types of fragments that can be embedded, and these token types need to implement the [`ILazyParseableElementType`](upsource:///platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java) interface.
|
In that case, it needs to define the chameleon token types for different types of fragments that can be embedded, and these token types need to implement the [`ILazyParseableElementType`](%gh-ic%/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java) interface.
|
||||||
The enclosing language's lexer needs to return the entire fragment of the embedded language as a single chameleon token, of the type defined by the embedded language.
|
The enclosing language's lexer needs to return the entire fragment of the embedded language as a single chameleon token, of the type defined by the embedded language.
|
||||||
To parse the contents of the chameleon token, the IDE will call the parser of the embedded language through a call to [`ILazyParseableElementType.parseContents()`](upsource:///platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java).
|
To parse the contents of the chameleon token, the IDE will call the parser of the embedded language through a call to [`ILazyParseableElementType.parseContents()`](%gh-ic%/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java).
|
||||||
|
@ -5,24 +5,24 @@
|
|||||||
Parsing files in IntelliJ Platform is a two-step process.
|
Parsing files in IntelliJ Platform is a two-step process.
|
||||||
|
|
||||||
First, an abstract syntax tree (AST) is built, defining the structure of the program.
|
First, an abstract syntax tree (AST) is built, defining the structure of the program.
|
||||||
AST nodes are created internally by the IDE and are represented by instances of the [`ASTNode`](upsource:///platform/core-api/src/com/intellij/lang/ASTNode.java) class.
|
AST nodes are created internally by the IDE and are represented by instances of the [`ASTNode`](%gh-ic%/platform/core-api/src/com/intellij/lang/ASTNode.java) class.
|
||||||
Each AST node has an associated element type [`IElementType`](upsource:///platform/core-api/src/com/intellij/psi/tree/IElementType.java) instance, and the element types are defined by the language plugin.
|
Each AST node has an associated element type [`IElementType`](%gh-ic%/platform/core-api/src/com/intellij/psi/tree/IElementType.java) instance, and the element types are defined by the language plugin.
|
||||||
The AST tree's top-level node for a file needs to have a special element type, which extends the [`IFileElementType`](upsource:///platform/core-api/src/com/intellij/psi/tree/IFileElementType.java) class.
|
The AST tree's top-level node for a file needs to have a special element type, which extends the [`IFileElementType`](%gh-ic%/platform/core-api/src/com/intellij/psi/tree/IFileElementType.java) class.
|
||||||
|
|
||||||
The AST nodes have a direct mapping to text ranges in the underlying document.
|
The AST nodes have a direct mapping to text ranges in the underlying document.
|
||||||
The bottom-most nodes of the AST match individual tokens returned by the [lexer](implementing_lexer.md), and higher-level nodes match multiple-token fragments.
|
The bottom-most nodes of the AST match individual tokens returned by the [lexer](implementing_lexer.md), and higher-level nodes match multiple-token fragments.
|
||||||
Operations performed on nodes of the AST tree, such as inserting, removing, reordering nodes, and so on, are immediately reflected as changes to the underlying document's text.
|
Operations performed on nodes of the AST tree, such as inserting, removing, reordering nodes, and so on, are immediately reflected as changes to the underlying document's text.
|
||||||
|
|
||||||
Second, a PSI, or Program Structure Interface, tree is built on top of the AST, adding semantics and methods for manipulating specific language constructs.
|
Second, a PSI, or Program Structure Interface, tree is built on top of the AST, adding semantics and methods for manipulating specific language constructs.
|
||||||
Nodes of the PSI tree are represented by classes implementing the [`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) interface and are created by the language plugin in the [`ParserDefinition.createElement()`](upsource:///platform/core-api/src/com/intellij/lang/ParserDefinition.java) method.
|
Nodes of the PSI tree are represented by classes implementing the [`PsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) interface and are created by the language plugin in the [`ParserDefinition.createElement()`](%gh-ic%/platform/core-api/src/com/intellij/lang/ParserDefinition.java) method.
|
||||||
The top-level node of the PSI tree for a file needs to implement the [`PsiFile`](upsource:///platform/core-api/src/com/intellij/psi/PsiFile.java) interface and is created in the [`ParserDefinition.createFile()`](upsource:///platform/core-api/src/com/intellij/lang/ParserDefinition.java) method.
|
The top-level node of the PSI tree for a file needs to implement the [`PsiFile`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiFile.java) interface and is created in the [`ParserDefinition.createFile()`](%gh-ic%/platform/core-api/src/com/intellij/lang/ParserDefinition.java) method.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
[`ParserDefinition`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertiesParserDefinition.java) for [Properties language plugin](upsource:///plugins/properties)
|
[`ParserDefinition`](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertiesParserDefinition.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
|
||||||
The PSI's lifecycle is described in more detail in [Fundamentals](fundamentals.md).
|
The PSI's lifecycle is described in more detail in [Fundamentals](fundamentals.md).
|
||||||
|
|
||||||
The base classes for the PSI implementation, including [`PsiFileBase`](upsource:///platform/core-impl/src/com/intellij/extapi/psi/PsiFileBase.java), the base implementation of [`PsiFile`](upsource:///platform/core-api/src/com/intellij/psi/PsiFile.java), and [`ASTWrapperPsiElement`](upsource:///platform/core-impl/src/com/intellij/extapi/psi/ASTWrapperPsiElement.java), the base implementation of [`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java), are provided by IntelliJ Platform.
|
The base classes for the PSI implementation, including [`PsiFileBase`](%gh-ic%/platform/core-impl/src/com/intellij/extapi/psi/PsiFileBase.java), the base implementation of [`PsiFile`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiFile.java), and [`ASTWrapperPsiElement`](%gh-ic%/platform/core-impl/src/com/intellij/extapi/psi/ASTWrapperPsiElement.java), the base implementation of [`PsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java), are provided by IntelliJ Platform.
|
||||||
|
|
||||||
### Parser Implementation
|
### Parser Implementation
|
||||||
|
|
||||||
@ -32,15 +32,15 @@ The Grammar-Kit plugin is built using its own engine; its source code and docume
|
|||||||
|
|
||||||
For re-using existing ANTLRv4 grammars, see [antlr4-intellij-adaptor](https://github.com/antlr/antlr4-intellij-adaptor) library.
|
For re-using existing ANTLRv4 grammars, see [antlr4-intellij-adaptor](https://github.com/antlr/antlr4-intellij-adaptor) library.
|
||||||
|
|
||||||
The language plugin provides the parser implementation as an implementation of the [`PsiParser`](upsource:///platform/core-api/src/com/intellij/lang/PsiParser.java) interface, returned from [`ParserDefinition.createParser()`](upsource:///platform/core-api/src/com/intellij/lang/ParserDefinition.java).
|
The language plugin provides the parser implementation as an implementation of the [`PsiParser`](%gh-ic%/platform/core-api/src/com/intellij/lang/PsiParser.java) interface, returned from [`ParserDefinition.createParser()`](%gh-ic%/platform/core-api/src/com/intellij/lang/ParserDefinition.java).
|
||||||
The parser receives an instance of the [`PsiBuilder`](upsource:///platform/core-api/src/com/intellij/lang/PsiBuilder.java) class, which is used to get the stream of tokens from the lexer and to hold the intermediate state of the AST being built.
|
The parser receives an instance of the [`PsiBuilder`](%gh-ic%/platform/core-api/src/com/intellij/lang/PsiBuilder.java) class, which is used to get the stream of tokens from the lexer and to hold the intermediate state of the AST being built.
|
||||||
The parser must process all tokens returned by the lexer up to the end of the stream, in other words, until [`PsiBuilder.getTokenType()`](upsource:///platform/core-api/src/com/intellij/lang/PsiBuilder.java) returns `null`, even if the tokens are not valid according to the language syntax.
|
The parser must process all tokens returned by the lexer up to the end of the stream, in other words, until [`PsiBuilder.getTokenType()`](%gh-ic%/platform/core-api/src/com/intellij/lang/PsiBuilder.java) returns `null`, even if the tokens are not valid according to the language syntax.
|
||||||
|
|
||||||
**Examples**:
|
**Examples**:
|
||||||
- [Custom Language Support Tutorial: Grammar and Parser](grammar_and_parser.md)
|
- [Custom Language Support Tutorial: Grammar and Parser](grammar_and_parser.md)
|
||||||
- [`PsiParser`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertiesParser.java) implementation for [Properties language plugin](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties).
|
- [`PsiParser`](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertiesParser.java) implementation for [Properties language plugin](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties).
|
||||||
|
|
||||||
The parser works by setting pairs of markers ([`PsiBuilder.Marker`](upsource:///platform/core-api/src/com/intellij/lang/PsiBuilder.java) instances) within the stream of tokens received from the lexer.
|
The parser works by setting pairs of markers ([`PsiBuilder.Marker`](%gh-ic%/platform/core-api/src/com/intellij/lang/PsiBuilder.java) instances) within the stream of tokens received from the lexer.
|
||||||
Each pair of markers defines the range of lexer tokens for a single node in the AST tree.
|
Each pair of markers defines the range of lexer tokens for a single node in the AST tree.
|
||||||
If a pair of markers is nested in another pair (starts after its start and ends before its end), it becomes the outer pair's child node.
|
If a pair of markers is nested in another pair (starts after its start and ends before its end), it becomes the outer pair's child node.
|
||||||
|
|
||||||
@ -57,10 +57,10 @@ When the parser reaches the '+' token following 'b', it can call `precede()` to
|
|||||||
#### Whitespace and Comments
|
#### Whitespace and Comments
|
||||||
|
|
||||||
An essential feature of `PsiBuilder` is its handling of whitespace and comments.
|
An essential feature of `PsiBuilder` is its handling of whitespace and comments.
|
||||||
The types of tokens which are treated as whitespace or comments are defined by `getWhitespaceTokens()` and `getCommentTokens()` in [`ParserDefinition`](upsource:///platform/core-api/src/com/intellij/lang/ParserDefinition.java).
|
The types of tokens which are treated as whitespace or comments are defined by `getWhitespaceTokens()` and `getCommentTokens()` in [`ParserDefinition`](%gh-ic%/platform/core-api/src/com/intellij/lang/ParserDefinition.java).
|
||||||
`PsiBuilder` automatically omits whitespace and comment tokens from the stream of tokens it passes to `PsiParser` and adjusts the token ranges of AST nodes so that leading and trailing whitespace tokens are not included in the node.
|
`PsiBuilder` automatically omits whitespace and comment tokens from the stream of tokens it passes to `PsiParser` and adjusts the token ranges of AST nodes so that leading and trailing whitespace tokens are not included in the node.
|
||||||
|
|
||||||
The token set returned from [`ParserDefinition.getCommentTokens()`](upsource:///platform/core-api/src/com/intellij/lang/ParserDefinition.java) is also used to search for [TODO items](https://www.jetbrains.com/help/idea/using-todo.html).
|
The token set returned from [`ParserDefinition.getCommentTokens()`](%gh-ic%/platform/core-api/src/com/intellij/lang/ParserDefinition.java) is also used to search for [TODO items](https://www.jetbrains.com/help/idea/using-todo.html).
|
||||||
|
|
||||||
To better understand the process of building a PSI tree for a simple expression, you can refer to the following diagram:
|
To better understand the process of building a PSI tree for a simple expression, you can refer to the following diagram:
|
||||||
|
|
||||||
@ -70,9 +70,9 @@ To better understand the process of building a PSI tree for a simple expression,
|
|||||||
|
|
||||||
In general, there is no single right way to implement a PSI for a custom language, and the plugin author can choose the PSI structure and set of methods that are the most convenient for the code which uses the PSI (error analysis, refactorings, and so on).
|
In general, there is no single right way to implement a PSI for a custom language, and the plugin author can choose the PSI structure and set of methods that are the most convenient for the code which uses the PSI (error analysis, refactorings, and so on).
|
||||||
However, one base interface needs to be used by a custom language PSI implementation to support features like [](rename_refactoring.md) and [](find_usages.md).
|
However, one base interface needs to be used by a custom language PSI implementation to support features like [](rename_refactoring.md) and [](find_usages.md).
|
||||||
Every element which can be renamed or referenced (a class definition, a method definition and so on) needs to implement the [`PsiNamedElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java) interface, with methods `getName()` and `setName()`.
|
Every element which can be renamed or referenced (a class definition, a method definition and so on) needs to implement the [`PsiNamedElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java) interface, with methods `getName()` and `setName()`.
|
||||||
|
|
||||||
Several functions which can be used for implementing and using the PSI can be found in the `com.intellij.psi.util` package, and in particular in the [`PsiUtilCore`](upsource:///platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java) and [`PsiTreeUtil`](upsource:///platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java) classes.
|
Several functions which can be used for implementing and using the PSI can be found in the `com.intellij.psi.util` package, and in particular in the [`PsiUtilCore`](%gh-ic%/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java) and [`PsiTreeUtil`](%gh-ic%/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java) classes.
|
||||||
|
|
||||||
> Use [builtin tools and PsiViewer plugin](explore_api.md#31-use-internal-mode-and-psiviewer) to explore and inspect PSI.
|
> Use [builtin tools and PsiViewer plugin](explore_api.md#31-use-internal-mode-and-psiviewer) to explore and inspect PSI.
|
||||||
>
|
>
|
||||||
|
@ -31,34 +31,34 @@ while the second one allows for the placement of inline and block inlays with cu
|
|||||||
### Simple Text Inlay Hints
|
### Simple Text Inlay Hints
|
||||||
|
|
||||||
Implement
|
Implement
|
||||||
[`InlayParameterHintsProvider`](upsource:///platform/lang-api/src/com/intellij/codeInsight/hints/InlayParameterHintsProvider.java)
|
[`InlayParameterHintsProvider`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/hints/InlayParameterHintsProvider.java)
|
||||||
and register it as `com.intellij.codeInsight.parameterNameHints` EP.
|
and register it as `com.intellij.codeInsight.parameterNameHints` EP.
|
||||||
The API documentation of `InlayParameterHintsProvider` explains in detail the rationale behind all methods.
|
The API documentation of `InlayParameterHintsProvider` explains in detail the rationale behind all methods.
|
||||||
|
|
||||||
Examples can be found in the following IntelliJ Platform plugins:
|
Examples can be found in the following IntelliJ Platform plugins:
|
||||||
|
|
||||||
- [`GroovyInlayParameterHintsProvider`](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyInlayParameterHintsProvider.kt)
|
- [`GroovyInlayParameterHintsProvider`](%gh-ic%/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyInlayParameterHintsProvider.kt)
|
||||||
implements inline hints for Groovy methods.
|
implements inline hints for Groovy methods.
|
||||||
- [`KotlinInlayParameterHintsProvider`](upsource:///plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInsight/hints/KotlinInlayParameterHintsProvider.kt)
|
- [`KotlinInlayParameterHintsProvider`](%gh-ic%/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInsight/hints/KotlinInlayParameterHintsProvider.kt)
|
||||||
implements parameter hints for Kotlin language.
|
implements parameter hints for Kotlin language.
|
||||||
|
|
||||||
### Advanced Inlay Hints
|
### Advanced Inlay Hints
|
||||||
|
|
||||||
Implement
|
Implement
|
||||||
[`InlayHintsProvider`](upsource:///platform/lang-api/src/com/intellij/codeInsight/hints/InlayHintsProvider.kt)
|
[`InlayHintsProvider`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/hints/InlayHintsProvider.kt)
|
||||||
and register it as `com.intellij.codeInsight.inlayProvider` EP.
|
and register it as `com.intellij.codeInsight.inlayProvider` EP.
|
||||||
The API documentation of `InlayHintsProvider` explains in detail the rationale behind all methods.
|
The API documentation of `InlayHintsProvider` explains in detail the rationale behind all methods.
|
||||||
|
|
||||||
Examples can be found in the following IntelliJ Platform plugins:
|
Examples can be found in the following IntelliJ Platform plugins:
|
||||||
|
|
||||||
- Groovy provides several implementations of this EP that can serve as a reference:
|
- Groovy provides several implementations of this EP that can serve as a reference:
|
||||||
[`GroovyParameterTypeHintsInlayProvider`](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/types/GroovyParameterTypeHintsInlayProvider.kt),
|
[`GroovyParameterTypeHintsInlayProvider`](%gh-ic%/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/types/GroovyParameterTypeHintsInlayProvider.kt),
|
||||||
[`GroovyLocalVariableTypeHintsInlayProvider`](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/types/GroovyLocalVariableTypeHintsInlayProvider.kt),
|
[`GroovyLocalVariableTypeHintsInlayProvider`](%gh-ic%/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/types/GroovyLocalVariableTypeHintsInlayProvider.kt),
|
||||||
and [`GroovyImplicitNullArgumentHintProvider`](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentHintProvider.kt).
|
and [`GroovyImplicitNullArgumentHintProvider`](%gh-ic%/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/hint/GroovyImplicitNullArgumentHintProvider.kt).
|
||||||
- Markdown uses this EP for _decorating_ tables in
|
- Markdown uses this EP for _decorating_ tables in
|
||||||
[`MarkdownTableInlayProvider`](upsource:///plugins/markdown/core/src/org/intellij/plugins/markdown/editor/tables/ui/MarkdownTableInlayProvider.kt).
|
[`MarkdownTableInlayProvider`](%gh-ic%/plugins/markdown/core/src/org/intellij/plugins/markdown/editor/tables/ui/MarkdownTableInlayProvider.kt).
|
||||||
- For a more complex example, see
|
- For a more complex example, see
|
||||||
[`KotlinLambdasHintsProvider`](upsource:///plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInsight/hints/KotlinLambdasHintsProvider.kt),
|
[`KotlinLambdasHintsProvider`](%gh-ic%/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInsight/hints/KotlinLambdasHintsProvider.kt),
|
||||||
its parent class and all implementations.
|
its parent class and all implementations.
|
||||||
|
|
||||||
### Further Tips
|
### Further Tips
|
||||||
@ -67,16 +67,16 @@ Examples can be found in the following IntelliJ Platform plugins:
|
|||||||
[Settings | Editor | Inlay Hints](https://www.jetbrains.com/help/idea/inlay-hints.html) and check out inlays that have already been implemented.
|
[Settings | Editor | Inlay Hints](https://www.jetbrains.com/help/idea/inlay-hints.html) and check out inlays that have already been implemented.
|
||||||
It gives insight into what’s possible.
|
It gives insight into what’s possible.
|
||||||
2. If you want to support multiple languages with a single type of inlay hints, please see
|
2. If you want to support multiple languages with a single type of inlay hints, please see
|
||||||
[`InlayHintsProviderFactory`](upsource:///platform/lang-api/src/com/intellij/codeInsight/hints/InlayHintsProviderFactory.kt)
|
[`InlayHintsProviderFactory`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/hints/InlayHintsProviderFactory.kt)
|
||||||
3. If you want to suppress inlay hints in specific places, please implement
|
3. If you want to suppress inlay hints in specific places, please implement
|
||||||
[`ParameterNameHintsSuppressor`](upsource:///platform/lang-api/src/com/intellij/codeInsight/hints/ParameterNameHintsSuppressor.kt)
|
[`ParameterNameHintsSuppressor`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/hints/ParameterNameHintsSuppressor.kt)
|
||||||
and register it as `com.intellij.codeInsight.parameterNameHintsSuppressor` EP.
|
and register it as `com.intellij.codeInsight.parameterNameHintsSuppressor` EP.
|
||||||
4. For testing inlay hints, see
|
4. For testing inlay hints, see
|
||||||
[`InlayHintsProviderTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/utils/inlays/InlayHintsProviderTestCase.kt)
|
[`InlayHintsProviderTestCase`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/utils/inlays/InlayHintsProviderTestCase.kt)
|
||||||
and [`InlayParameterHintsTest`](upsource:///platform/testFramework/src/com/intellij/testFramework/utils/inlays/InlayParameterHintsTest.kt).
|
and [`InlayParameterHintsTest`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/utils/inlays/InlayParameterHintsTest.kt).
|
||||||
5. If you need to force inlay hints to update when using
|
5. If you need to force inlay hints to update when using
|
||||||
[`DaemonCodeAnalyzer#restart()`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java),
|
[`DaemonCodeAnalyzer#restart()`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java),
|
||||||
please use
|
please use
|
||||||
[`ParameterHintsPassFactory#forceHintsUpdateOnNextPass()`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/hints/ParameterHintsPassFactory.java)
|
[`ParameterHintsPassFactory#forceHintsUpdateOnNextPass()`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/hints/ParameterHintsPassFactory.java)
|
||||||
before you call `restart()`.
|
before you call `restart()`.
|
||||||
If you want to force an update on a specific editor, note that the method also has an overload that takes an editor instance.
|
If you want to force an update on a specific editor, note that the method also has an overload that takes an editor instance.
|
||||||
|
@ -60,7 +60,7 @@ In the IntelliLang settings, it is defined as one possible injection in Java cod
|
|||||||
{border-effect="line"}
|
{border-effect="line"}
|
||||||
|
|
||||||
Double-clicking on this entry shows the exact context where a RegExp can be injected, and `String.matches()` is one of several possibilities.
|
Double-clicking on this entry shows the exact context where a RegExp can be injected, and `String.matches()` is one of several possibilities.
|
||||||
On the plugin side, these entries are defined in the file [`javaInjections.xml`](upsource:///plugins/IntelliLang/java-support/resources/javaInjections.xml):
|
On the plugin side, these entries are defined in the file [`javaInjections.xml`](%gh-ic%/plugins/IntelliLang/java-support/resources/javaInjections.xml):
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<injection language="RegExp" injector-id="java">
|
<injection language="RegExp" injector-id="java">
|
||||||
@ -76,7 +76,7 @@ On the plugin side, these entries are defined in the file [`javaInjections.xml`]
|
|||||||
```
|
```
|
||||||
|
|
||||||
The XML file with the injection configurations is loaded through the `org.intellij.intelliLang.injectionConfig` EP in the file
|
The XML file with the injection configurations is loaded through the `org.intellij.intelliLang.injectionConfig` EP in the file
|
||||||
[`intellilang-java-support.xml`](upsource:///plugins/IntelliLang/src/META-INF/intellilang-java-support.xml).
|
[`intellilang-java-support.xml`](%gh-ic%/plugins/IntelliLang/src/META-INF/intellilang-java-support.xml).
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<extensions defaultExtensionNs="org.intellij.intelliLang">
|
<extensions defaultExtensionNs="org.intellij.intelliLang">
|
||||||
@ -96,11 +96,11 @@ Therefore, plugin authors who want to provide injections for known languages can
|
|||||||
#### Implement org.intellij.intelliLang.languageSupport EP
|
#### Implement org.intellij.intelliLang.languageSupport EP
|
||||||
|
|
||||||
Implement the `org.intellij.intelliLang.languageSupport` EP and use
|
Implement the `org.intellij.intelliLang.languageSupport` EP and use
|
||||||
[`AbstractLanguageInjectionSupport`](upsource:///plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java) as a base class.
|
[`AbstractLanguageInjectionSupport`](%gh-ic%/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java) as a base class.
|
||||||
Please refer to the API docs of
|
Please refer to the API docs of
|
||||||
[`LanguageInjectionSupport`](upsource:///plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java)
|
[`LanguageInjectionSupport`](%gh-ic%/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java)
|
||||||
for information on methods to override and use
|
for information on methods to override and use
|
||||||
[`JavaLanguageInjectionSupport`](upsource:///plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java)
|
[`JavaLanguageInjectionSupport`](%gh-ic%/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java)
|
||||||
as an example implementation.
|
as an example implementation.
|
||||||
|
|
||||||
#### Create Injection Configuration
|
#### Create Injection Configuration
|
||||||
@ -109,13 +109,13 @@ Create an XML file with the injection configuration.
|
|||||||
You can export existing injections from the IntelliLang settings to create a template and then edit it.
|
You can export existing injections from the IntelliLang settings to create a template and then edit it.
|
||||||
[Element patterns](https://plugins.jetbrains.com/docs/intellij/element-patterns.html) are used to specify the context where injections will take place.
|
[Element patterns](https://plugins.jetbrains.com/docs/intellij/element-patterns.html) are used to specify the context where injections will take place.
|
||||||
Custom language authors can use the specific patterns returned from their implementation of
|
Custom language authors can use the specific patterns returned from their implementation of
|
||||||
[`JavaLanguageInjectionSupport.getPatternClasses`](upsource:///plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java).
|
[`JavaLanguageInjectionSupport.getPatternClasses`](%gh-ic%/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java).
|
||||||
|
|
||||||
The `injection` tag requires the attributes `language` and `injector-id`.
|
The `injection` tag requires the attributes `language` and `injector-id`.
|
||||||
The first one specifies the `language-id`
|
The first one specifies the `language-id`
|
||||||
(see [`Language.getID()`](upsource:///platform/core-api/src/com/intellij/lang/Language.java)) of the language that is injected.
|
(see [`Language.getID()`](%gh-ic%/platform/core-api/src/com/intellij/lang/Language.java)) of the language that is injected.
|
||||||
The second one is the id of the host language
|
The second one is the id of the host language
|
||||||
(see [`JavaLanguageInjectionSupport.getId()`](upsource:///plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java)).
|
(see [`JavaLanguageInjectionSupport.getId()`](%gh-ic%/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java)).
|
||||||
For instance, injecting SQLite into Python code is specified by the following opening tag:
|
For instance, injecting SQLite into Python code is specified by the following opening tag:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
@ -131,7 +131,7 @@ Inside an injection, the following tags can be used:
|
|||||||
| `<display-name>` | A short name for the injection. |
|
| `<display-name>` | A short name for the injection. |
|
||||||
| `<place>` | The element pattern that defines where an injection will take place. The content is wrapped in `![CDATA[...]]`. |
|
| `<place>` | The element pattern that defines where an injection will take place. The content is wrapped in `![CDATA[...]]`. |
|
||||||
| `<prefix>` and `<suffix>` | Static content that is wrapped around the injected code, e.g., to make it a valid expression. For example, to a CSS color specification inside a string, it can be wrapped with the prefix `div { color:` and the suffix `;}` to make it a valid CSS expression. |
|
| `<prefix>` and `<suffix>` | Static content that is wrapped around the injected code, e.g., to make it a valid expression. For example, to a CSS color specification inside a string, it can be wrapped with the prefix `div { color:` and the suffix `;}` to make it a valid CSS expression. |
|
||||||
| `<value-pattern>` | A regex for the content that specifies when this injection should be applied. Regex groups can specify the text range of the injection (e.g. `^javascript:(.+)`, see [`xmlInjections-html.xml`](upsource:///plugins/IntelliLang/xml-support/resources/xmlInjections-html.xml)). |
|
| `<value-pattern>` | A regex for the content that specifies when this injection should be applied. Regex groups can specify the text range of the injection (e.g. `^javascript:(.+)`, see [`xmlInjections-html.xml`](%gh-ic%/plugins/IntelliLang/xml-support/resources/xmlInjections-html.xml)). |
|
||||||
| `<ignore-pattern>` | A regex for the content that specifies when this injection should not be applied. |
|
| `<ignore-pattern>` | A regex for the content that specifies when this injection should not be applied. |
|
||||||
|
|
||||||
#### Create an XML File to Load the Configuration
|
#### Create an XML File to Load the Configuration
|
||||||
@ -161,7 +161,7 @@ Therefore, you load the configuration optionally in your main <path>plugin.xml</
|
|||||||
## LanguageInjectionContributor and LanguageInjectionPerformer
|
## LanguageInjectionContributor and LanguageInjectionPerformer
|
||||||
|
|
||||||
The `com.intellij.languageInjectionContributor` EP provides injection information for the given context in terms of _what_ to inject.
|
The `com.intellij.languageInjectionContributor` EP provides injection information for the given context in terms of _what_ to inject.
|
||||||
As a plugin author, implement [`LanguageInjectionContributor`](upsource:///platform/core-api/src/com/intellij/lang/injection/general/LanguageInjectionContributor.java) to provide context-specific injections.
|
As a plugin author, implement [`LanguageInjectionContributor`](%gh-ic%/platform/core-api/src/com/intellij/lang/injection/general/LanguageInjectionContributor.java) to provide context-specific injections.
|
||||||
|
|
||||||
For instance, if you want to inject a YAML or JSON to a literal language depending on some conditions, you could implement this interface like this:
|
For instance, if you want to inject a YAML or JSON to a literal language depending on some conditions, you could implement this interface like this:
|
||||||
|
|
||||||
@ -195,10 +195,10 @@ Register the implementation in your <path>plugin.xml</path>:
|
|||||||
|
|
||||||
If you want more control over how the injection should be done then implement the `com.intellij.languageInjectionPerformer` EP which allows for complex language injections, e.g. for concatenation or interpolation of strings.
|
If you want more control over how the injection should be done then implement the `com.intellij.languageInjectionPerformer` EP which allows for complex language injections, e.g. for concatenation or interpolation of strings.
|
||||||
If it is not implemented, then the
|
If it is not implemented, then the
|
||||||
[`DefaultLanguageInjectionPerformer`](upsource:///plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjectionPerformer.java)
|
[`DefaultLanguageInjectionPerformer`](%gh-ic%/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjectionPerformer.java)
|
||||||
will be used.
|
will be used.
|
||||||
|
|
||||||
For the `com.intellij.languageInjectionPerformer` EP, two methods need to be implemented in [`LanguageInjectionPerformer`](upsource:///platform/core-api/src/com/intellij/lang/injection/general/LanguageInjectionPerformer.java).
|
For the `com.intellij.languageInjectionPerformer` EP, two methods need to be implemented in [`LanguageInjectionPerformer`](%gh-ic%/platform/core-api/src/com/intellij/lang/injection/general/LanguageInjectionPerformer.java).
|
||||||
First, `isPrimary()` determines if this is the default `LanguageInjectionPerformer` for the language and if it handles most of the injections.
|
First, `isPrimary()` determines if this is the default `LanguageInjectionPerformer` for the language and if it handles most of the injections.
|
||||||
If there is no primary `LanguageInjectionPerformer` found, then a fallback injection will be performed.
|
If there is no primary `LanguageInjectionPerformer` found, then a fallback injection will be performed.
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ The method `performInjection()` does the actual injection into the context PSI e
|
|||||||
|
|
||||||
## MultiHostInjector
|
## MultiHostInjector
|
||||||
|
|
||||||
[`MultiHostInjector`](upsource:///platform/core-api/src/com/intellij/lang/injection/MultiHostInjector.java) registered in `com.intellij.multiHostInjector` EP is a very low-level API, but it gives plugin authors the most freedom.
|
[`MultiHostInjector`](%gh-ic%/platform/core-api/src/com/intellij/lang/injection/MultiHostInjector.java) registered in `com.intellij.multiHostInjector` EP is a very low-level API, but it gives plugin authors the most freedom.
|
||||||
It performs language injection inside other PSI elements, e.g. inject SQL inside an XML tag text or inject regular expressions into Java string literals.
|
It performs language injection inside other PSI elements, e.g. inject SQL inside an XML tag text or inject regular expressions into Java string literals.
|
||||||
|
|
||||||
Plugin authors need to implement `getLanguagesToInject()` to provide a list of places to inject a language, and `elementsToInjectIn()` to return a list of elements to inject.
|
Plugin authors need to implement `getLanguagesToInject()` to provide a list of places to inject a language, and `elementsToInjectIn()` to return a list of elements to inject.
|
||||||
|
@ -7,13 +7,13 @@ The navigation bar implementation is used to customize and extend the
|
|||||||
structure.
|
structure.
|
||||||
|
|
||||||
The starting point for the navigation bar extension is the
|
The starting point for the navigation bar extension is the
|
||||||
[`NavBarModelExtension`](upsource:///platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModelExtension.java)
|
[`NavBarModelExtension`](%gh-ic%/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModelExtension.java)
|
||||||
interface, which is registered in the `com.intellij.navbar` extension point.
|
interface, which is registered in the `com.intellij.navbar` extension point.
|
||||||
|
|
||||||
To reuse the IntelliJ Platform implementation, you can extend one of two classes:
|
To reuse the IntelliJ Platform implementation, you can extend one of two classes:
|
||||||
|
|
||||||
- [`DefaultNavBarExtension`](upsource:///platform/lang-impl/src/com/intellij/ide/navigationToolbar/DefaultNavBarExtension.java)
|
- [`DefaultNavBarExtension`](%gh-ic%/platform/lang-impl/src/com/intellij/ide/navigationToolbar/DefaultNavBarExtension.java)
|
||||||
- [`StructureAwareNavBarModelExtension`](upsource:///platform/lang-impl/src/com/intellij/ide/navigationToolbar/StructureAwareNavBarModelExtension.kt)
|
- [`StructureAwareNavBarModelExtension`](%gh-ic%/platform/lang-impl/src/com/intellij/ide/navigationToolbar/StructureAwareNavBarModelExtension.kt)
|
||||||
|
|
||||||
## Default Navigation Bar
|
## Default Navigation Bar
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ Direct navigation is the navigation from `PsiElement` to another `PsiElement`,
|
|||||||
such as navigation from `break` keyword to the end of a loop in Java, without showing any popups.
|
such as navigation from `break` keyword to the end of a loop in Java, without showing any popups.
|
||||||
|
|
||||||
To provide `PsiElement` for direct navigation, implement and register
|
To provide `PsiElement` for direct navigation, implement and register
|
||||||
[`DirectNavigationProvider`](upsource:///platform/core-api/src/com/intellij/navigation/DirectNavigationProvider.java).
|
[`DirectNavigationProvider`](%gh-ic%/platform/core-api/src/com/intellij/navigation/DirectNavigationProvider.java).
|
||||||
|
|
||||||
## Symbol Navigation
|
## Symbol Navigation
|
||||||
|
|
||||||
@ -24,16 +24,16 @@ which it obtains by resolving a [reference](declarations_and_references.md#refer
|
|||||||
If there are several target symbols or several navigation targets defined for a symbol,
|
If there are several target symbols or several navigation targets defined for a symbol,
|
||||||
then the IDE shows the navigation popup to ask the user to choose where to go.
|
then the IDE shows the navigation popup to ask the user to choose where to go.
|
||||||
|
|
||||||
The [`NavigationTarget`](upsource:///platform/core-api/src/com/intellij/navigation/NavigationTarget.java)
|
The [`NavigationTarget`](%gh-ic%/platform/core-api/src/com/intellij/navigation/NavigationTarget.java)
|
||||||
is essentially a pair of a `Navigatable` and
|
is essentially a pair of a `Navigatable` and
|
||||||
a [`TargetPresentation`](upsource:///platform/core-api/src/com/intellij/navigation/TargetPresentation.kt)
|
a [`TargetPresentation`](%gh-ic%/platform/core-api/src/com/intellij/navigation/TargetPresentation.kt)
|
||||||
instances (where to go and what to show in the popup).
|
instances (where to go and what to show in the popup).
|
||||||
|
|
||||||
To provide navigation targets by a `Symbol`, either:
|
To provide navigation targets by a `Symbol`, either:
|
||||||
- implement and register
|
- implement and register
|
||||||
[`SymbolNavigationProvider`](upsource:///platform/core-api/src/com/intellij/navigation/SymbolNavigationProvider.java);
|
[`SymbolNavigationProvider`](%gh-ic%/platform/core-api/src/com/intellij/navigation/SymbolNavigationProvider.java);
|
||||||
- or implement
|
- or implement
|
||||||
[`NavigatableSymbol`](upsource:///platform/core-api/src/com/intellij/navigation/NavigatableSymbol.java)
|
[`NavigatableSymbol`](%gh-ic%/platform/core-api/src/com/intellij/navigation/NavigatableSymbol.java)
|
||||||
in the `Symbol`.
|
in the `Symbol`.
|
||||||
|
|
||||||
## Showing Usages
|
## Showing Usages
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||||
|
|
||||||
Custom languages can use
|
Custom languages can use
|
||||||
[`ParameterInfoHandler`](upsource:///platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java)
|
[`ParameterInfoHandler`](%gh-ic%/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java)
|
||||||
registered in `com.intellij.codeInsight.parameterInfo` extension point (EP) to show information about parameters in method and function calls.
|
registered in `com.intellij.codeInsight.parameterInfo` extension point (EP) to show information about parameters in method and function calls.
|
||||||
This is a convenient way to display type signatures directly as a popup in the editor without having to consult the documentation.
|
This is a convenient way to display type signatures directly as a popup in the editor without having to consult the documentation.
|
||||||
If it is available, the IDE can show this popup automatically after a short delay, or it can be invoked explicitly via
|
If it is available, the IDE can show this popup automatically after a short delay, or it can be invoked explicitly via
|
||||||
@ -12,26 +12,26 @@ If it is available, the IDE can show this popup automatically after a short dela
|
|||||||
Parameter info is dynamic and can update the displayed information when the caret is moved or additional code is typed.
|
Parameter info is dynamic and can update the displayed information when the caret is moved or additional code is typed.
|
||||||
This allows for highlighting entries or marking the current parameter at the caret position.
|
This allows for highlighting entries or marking the current parameter at the caret position.
|
||||||
Therefore, the interface of the
|
Therefore, the interface of the
|
||||||
[`ParameterInfoHandler`](upsource:///platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java)
|
[`ParameterInfoHandler`](%gh-ic%/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java)
|
||||||
EP consists of methods for initially collecting the required information
|
EP consists of methods for initially collecting the required information
|
||||||
to display parameter information at the caret position as well as methods to update what should be displayed during edits.
|
to display parameter information at the caret position as well as methods to update what should be displayed during edits.
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
Language authors implement
|
Language authors implement
|
||||||
[`ParameterInfoHandler`](upsource:///platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java)
|
[`ParameterInfoHandler`](%gh-ic%/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java)
|
||||||
which takes two type parameters: `ParameterOwner` and `ParameterType`.
|
which takes two type parameters: `ParameterOwner` and `ParameterType`.
|
||||||
For the explanations that follow, we assume that `ParameterOwner` is a PSI element that represents a function call in a language,
|
For the explanations that follow, we assume that `ParameterOwner` is a PSI element that represents a function call in a language,
|
||||||
and `ParameterType` represents (possibly several) function definitions.
|
and `ParameterType` represents (possibly several) function definitions.
|
||||||
|
|
||||||
Additionally, `ParameterInfoHandler` uses several context types that are mutable and used to adjust what and how parameter information is displayed.
|
Additionally, `ParameterInfoHandler` uses several context types that are mutable and used to adjust what and how parameter information is displayed.
|
||||||
These contexts are, e.g.,
|
These contexts are, e.g.,
|
||||||
[`CreateParameterInfoContext`](upsource:///platform/lang-api/src/com/intellij/lang/parameterInfo/CreateParameterInfoContext.java),
|
[`CreateParameterInfoContext`](%gh-ic%/platform/lang-api/src/com/intellij/lang/parameterInfo/CreateParameterInfoContext.java),
|
||||||
[`UpdateParameterInfoContext`](upsource:///platform/lang-api/src/com/intellij/lang/parameterInfo/UpdateParameterInfoContext.java)
|
[`UpdateParameterInfoContext`](%gh-ic%/platform/lang-api/src/com/intellij/lang/parameterInfo/UpdateParameterInfoContext.java)
|
||||||
and
|
and
|
||||||
[`ParameterInfoUIContext`](upsource:///platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoUIContext.java)
|
[`ParameterInfoUIContext`](%gh-ic%/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoUIContext.java)
|
||||||
and they all derive from
|
and they all derive from
|
||||||
[`ParameterInfoContext`](upsource:///platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoContext.java).
|
[`ParameterInfoContext`](%gh-ic%/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoContext.java).
|
||||||
|
|
||||||
### Initial Phase
|
### Initial Phase
|
||||||
|
|
||||||
@ -68,10 +68,10 @@ Therefore, when the user moves the caret or types something, the following happe
|
|||||||
## Further Tips
|
## Further Tips
|
||||||
|
|
||||||
Language authors can implement
|
Language authors can implement
|
||||||
[`ParameterInfoHandlerWithTabActionSupport`](upsource:///platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandlerWithTabActionSupport.java)
|
[`ParameterInfoHandlerWithTabActionSupport`](%gh-ic%/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandlerWithTabActionSupport.java)
|
||||||
to extend the parameter info functionality with the ability to jump between parameter positions by pressing the tab key.
|
to extend the parameter info functionality with the ability to jump between parameter positions by pressing the tab key.
|
||||||
For recurring tasks like finding the index of the current parameter in a function call,
|
For recurring tasks like finding the index of the current parameter in a function call,
|
||||||
[`ParameterInfoUtils`](upsource:///platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoUtils.java) provides a collection of useful functions.
|
[`ParameterInfoUtils`](%gh-ic%/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoUtils.java) provides a collection of useful functions.
|
||||||
|
|
||||||
It is further helpful to inspect all the context-interfaces that extend from `ParameterInfoContext` and can be found in the `com.intellij.lang.parameterInfo` package
|
It is further helpful to inspect all the context-interfaces that extend from `ParameterInfoContext` and can be found in the `com.intellij.lang.parameterInfo` package
|
||||||
as they provide insight into what data of the parameter info can be accessed and changed in the different stages.
|
as they provide insight into what data of the parameter info can be accessed and changed in the different stages.
|
||||||
@ -80,16 +80,16 @@ Methods of the `ParameterInfoHandler` that have a default implementation can usu
|
|||||||
`syncUpdateOnCaretMove()` and `supportsOverloadSwitching()` are used internally by the IntelliJ Platform and are not required to be implemented by plugins.
|
`syncUpdateOnCaretMove()` and `supportsOverloadSwitching()` are used internally by the IntelliJ Platform and are not required to be implemented by plugins.
|
||||||
The `dispose()` method is called when the currently displayed parameter info is invalidated and destroyed.
|
The `dispose()` method is called when the currently displayed parameter info is invalidated and destroyed.
|
||||||
Only `isWhitespaceSensitive()` which is used in the `getCurrentOffset()` method of
|
Only `isWhitespaceSensitive()` which is used in the `getCurrentOffset()` method of
|
||||||
[`ParameterInfoControllerBase`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoControllerBase.java)
|
[`ParameterInfoControllerBase`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoControllerBase.java)
|
||||||
should be implemented when whitespace matters in a language.
|
should be implemented when whitespace matters in a language.
|
||||||
|
|
||||||
Note that parameter info works during indexing (using incomplete indices) when the implementations also extend
|
Note that parameter info works during indexing (using incomplete indices) when the implementations also extend
|
||||||
[`DumbAware`](upsource:///platform/core-api/src/com/intellij/openapi/project/DumbAware.java).
|
[`DumbAware`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/DumbAware.java).
|
||||||
It is recommended to adapt tests for dumb-mode since the results might be surprising,
|
It is recommended to adapt tests for dumb-mode since the results might be surprising,
|
||||||
and more changes to the handler might be required for better results.
|
and more changes to the handler might be required for better results.
|
||||||
|
|
||||||
Finally, language authors should be aware of the global
|
Finally, language authors should be aware of the global
|
||||||
[`CodeInsightSettings#SHOW_FULL_SIGNATURES_IN_PARAMETER_INFO`](upsource:///platform/analysis-impl/src/com/intellij/codeInsight/CodeInsightSettings.java)
|
[`CodeInsightSettings#SHOW_FULL_SIGNATURES_IN_PARAMETER_INFO`](%gh-ic%/platform/analysis-impl/src/com/intellij/codeInsight/CodeInsightSettings.java)
|
||||||
setting that can be used to present results that are consistent with the default IDE behavior.
|
setting that can be used to present results that are consistent with the default IDE behavior.
|
||||||
For Java, for instance, the IDE shows the full signature of the method/function on parameter info if this setting is enabled.
|
For Java, for instance, the IDE shows the full signature of the method/function on parameter info if this setting is enabled.
|
||||||
|
|
||||||
@ -97,8 +97,8 @@ For Java, for instance, the IDE shows the full signature of the method/function
|
|||||||
|
|
||||||
Existing, moderately complex, implementations of `ParameterInfoHandler` in the IntelliJ Platform that can serve as a reference are:
|
Existing, moderately complex, implementations of `ParameterInfoHandler` in the IntelliJ Platform that can serve as a reference are:
|
||||||
|
|
||||||
* [`XPathParameterInfoHandler`](upsource:///plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/XPathParameterInfoHandler.java)
|
* [`XPathParameterInfoHandler`](%gh-ic%/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/XPathParameterInfoHandler.java)
|
||||||
* [`XmlParameterInfoHandler`](upsource:///xml/impl/src/com/intellij/codeInsight/hint/api/impls/XmlParameterInfoHandler.java)
|
* [`XmlParameterInfoHandler`](%gh-ic%/xml/impl/src/com/intellij/codeInsight/hint/api/impls/XmlParameterInfoHandler.java)
|
||||||
|
|
||||||
Implementations of 3rd party plugins can be discovered using the
|
Implementations of 3rd party plugins can be discovered using the
|
||||||
[IntelliJ Platform Explorer](https://plugins.jetbrains.com/intellij-platform-explorer?extensions=com.intellij.codeInsight.parameterInfo).
|
[IntelliJ Platform Explorer](https://plugins.jetbrains.com/intellij-platform-explorer?extensions=com.intellij.codeInsight.parameterInfo).
|
||||||
|
@ -8,19 +8,19 @@ Resolving references gives users the ability to navigate from a PSI element usag
|
|||||||
This feature is needed in order to support the <menupath>Navigate | Declaration or Usages</menupath> action invoked by <shortcut>Ctrl/Cmd+B</shortcut> or clicking the mouse button while holding <shortcut>Ctrl/Cmd</shortcut> key, and it is a prerequisite for implementing the [Find Usages](find_usages.md) action, the [Rename Refactoring](rename_refactoring.md) and [Code Completion](code_completion.md).
|
This feature is needed in order to support the <menupath>Navigate | Declaration or Usages</menupath> action invoked by <shortcut>Ctrl/Cmd+B</shortcut> or clicking the mouse button while holding <shortcut>Ctrl/Cmd</shortcut> key, and it is a prerequisite for implementing the [Find Usages](find_usages.md) action, the [Rename Refactoring](rename_refactoring.md) and [Code Completion](code_completion.md).
|
||||||
|
|
||||||
The <menupath>View | Quick Definition</menupath> action is based on the same mechanism, so it becomes automatically available for all references that can be resolved by the language plugin.
|
The <menupath>View | Quick Definition</menupath> action is based on the same mechanism, so it becomes automatically available for all references that can be resolved by the language plugin.
|
||||||
To customize the exact document range to show in the popup (e.g., include "surrounding" code or comments), provide [`ImplementationTextSelectioner`](upsource:///platform/lang-api/src/com/intellij/codeInsight/hint/ImplementationTextSelectioner.java) registered in `com.intellij.lang.implementationTextSelectioner` extension point.
|
To customize the exact document range to show in the popup (e.g., include "surrounding" code or comments), provide [`ImplementationTextSelectioner`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/hint/ImplementationTextSelectioner.java) registered in `com.intellij.lang.implementationTextSelectioner` extension point.
|
||||||
|
|
||||||
## PsiReference
|
## PsiReference
|
||||||
|
|
||||||
All PSI elements which work as references (for which the <menupath>Navigate | Declaration or Usages</menupath> action applies) need to implement the
|
All PSI elements which work as references (for which the <menupath>Navigate | Declaration or Usages</menupath> action applies) need to implement the
|
||||||
[`PsiElement.getReference()`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) method and to return a [`PsiReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) implementation from that method.
|
[`PsiElement.getReference()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) method and to return a [`PsiReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) implementation from that method.
|
||||||
The `PsiReference` can be implemented by the same class as `PsiElement`, or by a different class.
|
The `PsiReference` can be implemented by the same class as `PsiElement`, or by a different class.
|
||||||
An element can also contain multiple references (for example, a string literal can contain multiple substrings which are valid fully-qualified class names), in which case it can implement `PsiElement.getReferences()` and return the references as an array.
|
An element can also contain multiple references (for example, a string literal can contain multiple substrings which are valid fully-qualified class names), in which case it can implement `PsiElement.getReferences()` and return the references as an array.
|
||||||
To optimize `PsiElement.getReferences()` performance, consider implementing [`HintedReferenceHost`](upsource:///platform/core-api/src/com/intellij/psi/HintedReferenceHost.java) to provide additional hints.
|
To optimize `PsiElement.getReferences()` performance, consider implementing [`HintedReferenceHost`](%gh-ic%/platform/core-api/src/com/intellij/psi/HintedReferenceHost.java) to provide additional hints.
|
||||||
|
|
||||||
The primary method of the [`PsiReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) interface is `resolve()`, which returns the element to which the reference points, or `null` if it was not possible to resolve the reference to a valid element (for example, should it point to an undefined class).
|
The primary method of the [`PsiReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) interface is `resolve()`, which returns the element to which the reference points, or `null` if it was not possible to resolve the reference to a valid element (for example, should it point to an undefined class).
|
||||||
The resolved element should implement the [`PsiNamedElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java) interface.
|
The resolved element should implement the [`PsiNamedElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java) interface.
|
||||||
In order to enable more advanced functionality, prefer implementing [`PsiNameIdentifierOwner`](upsource:///platform/core-api/src/com/intellij/psi/PsiNameIdentifierOwner.java) over [`PsiNamedElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java) where possible.
|
In order to enable more advanced functionality, prefer implementing [`PsiNameIdentifierOwner`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNameIdentifierOwner.java) over [`PsiNamedElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java) where possible.
|
||||||
|
|
||||||
> While the referencing element and the referenced element both may have a name, only the element which **introduces** the name (e.g., the definition `int x = 42`) needs to implement `PsiNamedElement`.
|
> While the referencing element and the referenced element both may have a name, only the element which **introduces** the name (e.g., the definition `int x = 42`) needs to implement `PsiNamedElement`.
|
||||||
> The referencing element at the point of usage (e.g., the `x` in the expression `x + 1`) should not implement `PsiNamedElement` since it does not _have_ a name.
|
> The referencing element at the point of usage (e.g., the `x` in the expression `x + 1`) should not implement `PsiNamedElement` since it does not _have_ a name.
|
||||||
@ -33,12 +33,12 @@ Still, additional optimizations are possible (for example, performing the tree w
|
|||||||
|
|
||||||
**Examples**:
|
**Examples**:
|
||||||
|
|
||||||
- [Reference](upsource:///plugins/properties/src/com/intellij/lang/properties/ResourceBundleReference.java) to a ResourceBundle in the [Properties language plugin](upsource:///plugins/properties)
|
- [Reference](%gh-ic%/plugins/properties/src/com/intellij/lang/properties/ResourceBundleReference.java) to a ResourceBundle in the [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
- [Custom Language Support Tutorial: Reference Contributor](reference_contributor.md)
|
- [Custom Language Support Tutorial: Reference Contributor](reference_contributor.md)
|
||||||
|
|
||||||
## Implementing Resolve Logic
|
## Implementing Resolve Logic
|
||||||
|
|
||||||
There is a set of interfaces that can be used as a base for implementing resolve support, namely the [`PsiScopeProcessor`](upsource:///platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java) interface and the [`PsiElement.processDeclarations()`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) method.
|
There is a set of interfaces that can be used as a base for implementing resolve support, namely the [`PsiScopeProcessor`](%gh-ic%/platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java) interface and the [`PsiElement.processDeclarations()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) method.
|
||||||
These interfaces have several extra complexities that are unnecessary for most custom languages (like support for substituting Java generics types).
|
These interfaces have several extra complexities that are unnecessary for most custom languages (like support for substituting Java generics types).
|
||||||
Still, they are required if the custom language can have references to Java code.
|
Still, they are required if the custom language can have references to Java code.
|
||||||
If Java interoperability is not required, the plugin can forgo the standard interfaces and provide its own, different implementation of resolve.
|
If Java interoperability is not required, the plugin can forgo the standard interfaces and provide its own, different implementation of resolve.
|
||||||
@ -47,21 +47,21 @@ Please see also [](psi_performance.md#cache-results-of-heavy-computations).
|
|||||||
|
|
||||||
The implementation of resolve based on the standard helper classes contains the following components:
|
The implementation of resolve based on the standard helper classes contains the following components:
|
||||||
|
|
||||||
* A class implements the [`PsiScopeProcessor`](upsource:///platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java) interface, which gathers the possible declarations for the reference and stops the resolve process when it has successfully completed.
|
* A class implements the [`PsiScopeProcessor`](%gh-ic%/platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java) interface, which gathers the possible declarations for the reference and stops the resolve process when it has successfully completed.
|
||||||
The primary method which needs to be implemented is `execute()`, which is called to process every declaration encountered during the resolve, and returns `true` if the resolve needs to be continued or `false` if the declaration has been found.
|
The primary method which needs to be implemented is `execute()`, which is called to process every declaration encountered during the resolve, and returns `true` if the resolve needs to be continued or `false` if the declaration has been found.
|
||||||
The methods `getHint()` and `handleEvent()` are used for internal optimizations and can be left empty in the `PsiScopeProcessor` implementations for custom languages.
|
The methods `getHint()` and `handleEvent()` are used for internal optimizations and can be left empty in the `PsiScopeProcessor` implementations for custom languages.
|
||||||
* A function which walks the PSI tree up from the reference location until the resolve has successfully completed or until the end of the resolve scope has been reached.
|
* A function which walks the PSI tree up from the reference location until the resolve has successfully completed or until the end of the resolve scope has been reached.
|
||||||
If the target of the reference is located in a different file, the file can be located, for example, using [`FilenameIndex.getFilesByName()`](upsource:///platform/indexing-api/src/com/intellij/psi/search/FilenameIndex.java) (if the file name is known) or by iterating through all custom language files in the project (`iterateContent()` in the
|
If the target of the reference is located in a different file, the file can be located, for example, using [`FilenameIndex.getFilesByName()`](%gh-ic%/platform/indexing-api/src/com/intellij/psi/search/FilenameIndex.java) (if the file name is known) or by iterating through all custom language files in the project (`iterateContent()` in the
|
||||||
[`ProjectFileIndex`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) interface obtained
|
[`ProjectFileIndex`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) interface obtained
|
||||||
from
|
from
|
||||||
[`ProjectRootManager.getFileIndex()`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java)).
|
[`ProjectRootManager.getFileIndex()`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java)).
|
||||||
* The individual PSI elements, on which the `processDeclarations()` method is called during the PSI tree walk.
|
* The individual PSI elements, on which the `processDeclarations()` method is called during the PSI tree walk.
|
||||||
If a PSI element is a declaration, it passes itself to the `execute()` method of the `PsiScopeProcessor` passed to it.
|
If a PSI element is a declaration, it passes itself to the `execute()` method of the `PsiScopeProcessor` passed to it.
|
||||||
Also, if necessary, according to the language scoping rules, a PSI element can pass the `PsiScopeProcessor` to its child elements.
|
Also, if necessary, according to the language scoping rules, a PSI element can pass the `PsiScopeProcessor` to its child elements.
|
||||||
|
|
||||||
## Resolving to Multiple Targets
|
## Resolving to Multiple Targets
|
||||||
|
|
||||||
An extension of the [`PsiReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) interface, which allows a reference to resolve to multiple targets, is the [`PsiPolyVariantReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiPolyVariantReference.java) interface.
|
An extension of the [`PsiReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) interface, which allows a reference to resolve to multiple targets, is the [`PsiPolyVariantReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiPolyVariantReference.java) interface.
|
||||||
The targets to which the reference resolves are returned from the `multiResolve()` method.
|
The targets to which the reference resolves are returned from the `multiResolve()` method.
|
||||||
The <menupath>Navigate | Declaration or Usages</menupath> action for such references allows the user to choose a navigation target in a popup.
|
The <menupath>Navigate | Declaration or Usages</menupath> action for such references allows the user to choose a navigation target in a popup.
|
||||||
The implementation of `multiResolve()` can be also based on [`PsiScopeProcessor`](upsource:///platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java), and can collect all valid targets for the reference instead of stopping when the first valid target is found.
|
The implementation of `multiResolve()` can be also based on [`PsiScopeProcessor`](%gh-ic%/platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java), and can collect all valid targets for the reference instead of stopping when the first valid target is found.
|
||||||
|
@ -6,7 +6,7 @@ The first step in developing a custom language plugin is registering a file type
|
|||||||
|
|
||||||
The IDE typically determines the type of a file by looking at its filename or extension.
|
The IDE typically determines the type of a file by looking at its filename or extension.
|
||||||
|
|
||||||
A custom language file type is a class derived from [`LanguageFileType`](upsource:///platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java), which passes a [`Language`](upsource:///platform/core-api/src/com/intellij/lang/Language.java) subclass to its base class constructor.
|
A custom language file type is a class derived from [`LanguageFileType`](%gh-ic%/platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java), which passes a [`Language`](%gh-ic%/platform/core-api/src/com/intellij/lang/Language.java) subclass to its base class constructor.
|
||||||
|
|
||||||
### Registration
|
### Registration
|
||||||
<tabs>
|
<tabs>
|
||||||
@ -33,19 +33,19 @@ To associate the file type in the IDE, specify one or more associations as liste
|
|||||||
>
|
>
|
||||||
{type="warning"}
|
{type="warning"}
|
||||||
|
|
||||||
To register a file type, the plugin developer provides a subclass of [`FileTypeFactory`](upsource:///platform/ide-core/src/com/intellij/openapi/fileTypes/FileTypeFactory.java), which is registered via the `com.intellij.fileTypeFactory` extension point.
|
To register a file type, the plugin developer provides a subclass of [`FileTypeFactory`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/fileTypes/FileTypeFactory.java), which is registered via the `com.intellij.fileTypeFactory` extension point.
|
||||||
|
|
||||||
</tab>
|
</tab>
|
||||||
</tabs>
|
</tabs>
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
- [Custom Language Support Tutorial: Language and File Type](language_and_filetype.md)
|
- [Custom Language Support Tutorial: Language and File Type](language_and_filetype.md)
|
||||||
- [`LanguageFileType`](upsource:///platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java) subclass in [Properties language plugin](upsource:///plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesFileType.java)
|
- [`LanguageFileType`](%gh-ic%/platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java) subclass in [Properties language plugin](%gh-ic%/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesFileType.java)
|
||||||
|
|
||||||
To verify that the file type is registered correctly, you can implement the [`LanguageFileType.getIcon()`](upsource:///platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java) method and verify that the correct icon (see [Working with Icons and Images](work_with_icons_and_images.md)) is displayed for files associated with your file type.
|
To verify that the file type is registered correctly, you can implement the [`LanguageFileType.getIcon()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java) method and verify that the correct icon (see [Working with Icons and Images](work_with_icons_and_images.md)) is displayed for files associated with your file type.
|
||||||
|
|
||||||
### Additional Features
|
### Additional Features
|
||||||
|
|
||||||
If you want IDEs to show a hint prompting users that your plugin supports a specific file type, see [Plugin Recommendations](https://plugins.jetbrains.com/docs/marketplace/intellij-plugin-recommendations.html).
|
If you want IDEs to show a hint prompting users that your plugin supports a specific file type, see [Plugin Recommendations](https://plugins.jetbrains.com/docs/marketplace/intellij-plugin-recommendations.html).
|
||||||
|
|
||||||
To control file type association with the IDE in the operating system, implement [`OSFileIdeAssociation`](upsource:///platform/core-api/src/com/intellij/openapi/fileTypes/OSFileIdeAssociation.java) (2020.3).
|
To control file type association with the IDE in the operating system, implement [`OSFileIdeAssociation`](%gh-ic%/platform/core-api/src/com/intellij/openapi/fileTypes/OSFileIdeAssociation.java) (2020.3).
|
||||||
|
@ -5,56 +5,56 @@
|
|||||||
The Rename refactoring operation is quite similar to that of [Find Usages](find_usages.md).
|
The Rename refactoring operation is quite similar to that of [Find Usages](find_usages.md).
|
||||||
It uses the same rules for locating the element to be renamed and the same index of words for finding the files that may have references to the element being renamed.
|
It uses the same rules for locating the element to be renamed and the same index of words for finding the files that may have references to the element being renamed.
|
||||||
|
|
||||||
When the rename refactoring is performed, the method [`PsiNamedElement.setName()`](upsource:///platform/core-api/src/com/intellij/psi/PsiNamedElement.java) is called for the renamed element, and [`PsiReference.handleElementRename()`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) is called for all references to the renamed element.
|
When the rename refactoring is performed, the method [`PsiNamedElement.setName()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiNamedElement.java) is called for the renamed element, and [`PsiReference.handleElementRename()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) is called for all references to the renamed element.
|
||||||
These methods perform basically the same action: replace the underlying AST node of the PSI element with the node containing the new text entered by the user.
|
These methods perform basically the same action: replace the underlying AST node of the PSI element with the node containing the new text entered by the user.
|
||||||
Creating an entirely correct AST node from scratch is quite tricky.
|
Creating an entirely correct AST node from scratch is quite tricky.
|
||||||
Thus, surprisingly, the easiest way to get the replacement node is to create a dummy file in the custom language so that it would contain the necessary node in its parse tree, build the parse tree and extract the required node from it.
|
Thus, surprisingly, the easiest way to get the replacement node is to create a dummy file in the custom language so that it would contain the necessary node in its parse tree, build the parse tree and extract the required node from it.
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
- [`setName()`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java) implementation for a [Properties language plugin](upsource:///plugins/properties)
|
- [`setName()`](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java) implementation for a [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
- [Custom Language Support Tutorial: Reference Contributor](reference_contributor.md)
|
- [Custom Language Support Tutorial: Reference Contributor](reference_contributor.md)
|
||||||
|
|
||||||
If a renamed reference extends [`PsiReferenceBase`](upsource:///platform/core-api/src/com/intellij/psi/PsiReferenceBase.java), renaming is performed by invoking the [`ElementManipulator.handleContentChange()`](upsource:///platform/core-api/src/com/intellij/psi/ElementManipulator.java), responsible for handling the content change and calculating the text range of reference inside the element.
|
If a renamed reference extends [`PsiReferenceBase`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReferenceBase.java), renaming is performed by invoking the [`ElementManipulator.handleContentChange()`](%gh-ic%/platform/core-api/src/com/intellij/psi/ElementManipulator.java), responsible for handling the content change and calculating the text range of reference inside the element.
|
||||||
|
|
||||||
To disable renaming for specific elements, implement `com.intellij.openapi.util.Condition<T>` for PsiElement of type `T` and register it in `com.intellij.vetoRenameCondition` extension point.
|
To disable renaming for specific elements, implement `com.intellij.openapi.util.Condition<T>` for PsiElement of type `T` and register it in `com.intellij.vetoRenameCondition` extension point.
|
||||||
|
|
||||||
### Name Validation
|
### Name Validation
|
||||||
[`NamesValidator`](upsource:///platform/analysis-api/src/com/intellij/lang/refactoring/NamesValidator.java) allows a plugin to check if the name entered by the user in the `Rename` dialog is a valid identifier (and not a keyword) according to the custom language rules.
|
[`NamesValidator`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/refactoring/NamesValidator.java) allows a plugin to check if the name entered by the user in the `Rename` dialog is a valid identifier (and not a keyword) according to the custom language rules.
|
||||||
If an implementation of this interface is not provided by the plugin, Java rules for validating identifiers are used.
|
If an implementation of this interface is not provided by the plugin, Java rules for validating identifiers are used.
|
||||||
Implementations of `NamesValidator` are registered in the `com.intellij.lang.namesValidator` extension point.
|
Implementations of `NamesValidator` are registered in the `com.intellij.lang.namesValidator` extension point.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
[`PropertiesNamesValidator`](upsource:///plugins/properties/src/com/intellij/lang/properties/PropertiesNamesValidator.java) for [Properties language plugin](upsource:///plugins/properties)
|
[`PropertiesNamesValidator`](%gh-ic%/plugins/properties/src/com/intellij/lang/properties/PropertiesNamesValidator.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
|
||||||
Another way to check is
|
Another way to check is
|
||||||
[`RenameInputValidator`](upsource:///platform/refactoring/src/com/intellij/refactoring/rename/RenameInputValidator.java),
|
[`RenameInputValidator`](%gh-ic%/platform/refactoring/src/com/intellij/refactoring/rename/RenameInputValidator.java),
|
||||||
unlike `NamesValidator` it allows you to more flexibly check the entered name for correctness based on the rule defined in the `isInputValid()` method.
|
unlike `NamesValidator` it allows you to more flexibly check the entered name for correctness based on the rule defined in the `isInputValid()` method.
|
||||||
|
|
||||||
To determine which elements this validator will apply to, override the `getPattern()` method returning the pattern of the element to validate.
|
To determine which elements this validator will apply to, override the `getPattern()` method returning the pattern of the element to validate.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
[`YAMLAnchorRenameInputValidator`](upsource:///plugins/yaml/src/org/jetbrains/yaml/resolve/YAMLAnchorRenameInputValidator.java) validating YAML language anchor names
|
[`YAMLAnchorRenameInputValidator`](%gh-ic%/plugins/yaml/src/org/jetbrains/yaml/resolve/YAMLAnchorRenameInputValidator.java) validating YAML language anchor names
|
||||||
|
|
||||||
`RenameInputValidator` can be extended to
|
`RenameInputValidator` can be extended to
|
||||||
[`RenameInputValidatorEx`](upsource:///platform/refactoring/src/com/intellij/refactoring/rename/RenameInputValidatorEx.java)
|
[`RenameInputValidatorEx`](%gh-ic%/platform/refactoring/src/com/intellij/refactoring/rename/RenameInputValidatorEx.java)
|
||||||
to override the default error message.
|
to override the default error message.
|
||||||
The `getErrorMessage()` method should return a custom error message in case of an invalid name, or `null` otherwise.
|
The `getErrorMessage()` method should return a custom error message in case of an invalid name, or `null` otherwise.
|
||||||
|
|
||||||
Note that `getErrorMessage()` only works if all `RenameInputValidator` accept the new name in `isInputValid()` and the name is a valid identifier for the language of the element.
|
Note that `getErrorMessage()` only works if all `RenameInputValidator` accept the new name in `isInputValid()` and the name is a valid identifier for the language of the element.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
[`YamlKeyValueRenameInputValidator`](upsource:///plugins/yaml/src/org/jetbrains/yaml/refactoring/rename/YamlKeyValueRenameInputValidator.java) validating YAML language keys
|
[`YamlKeyValueRenameInputValidator`](%gh-ic%/plugins/yaml/src/org/jetbrains/yaml/refactoring/rename/YamlKeyValueRenameInputValidator.java) validating YAML language keys
|
||||||
|
|
||||||
Implementations of `RenameInputValidator` or `RenameInputValidatorEx` are registered in the `com.intellij.renameInputValidator` extension point.
|
Implementations of `RenameInputValidator` or `RenameInputValidatorEx` are registered in the `com.intellij.renameInputValidator` extension point.
|
||||||
|
|
||||||
### Custom Rename UI and Workflow
|
### Custom Rename UI and Workflow
|
||||||
Further customization of the Rename refactoring processing is possible on multiple levels.
|
Further customization of the Rename refactoring processing is possible on multiple levels.
|
||||||
Providing a custom implementation of the [`RenameHandler`](upsource:///platform/refactoring/src/com/intellij/refactoring/rename/RenameHandler.java) interface allows you to entirely replace the UI and workflow of the rename refactoring, and also to support renaming something which is not a [`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) at all.
|
Providing a custom implementation of the [`RenameHandler`](%gh-ic%/platform/refactoring/src/com/intellij/refactoring/rename/RenameHandler.java) interface allows you to entirely replace the UI and workflow of the rename refactoring, and also to support renaming something which is not a [`PsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) at all.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
[`RenameHandler`](upsource:///plugins/properties/properties-resource-bundle-editor/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromEditorRenameHandler.java) for renaming a resource bundle in the [Properties language plugin](upsource:///plugins/properties)
|
[`RenameHandler`](%gh-ic%/plugins/properties/properties-resource-bundle-editor/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromEditorRenameHandler.java) for renaming a resource bundle in the [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
|
||||||
If you're okay with the standard UI but need to extend the default logic of renaming, you can provide an implementation of the [`RenamePsiElementProcessor`](upsource:///platform/lang-impl/src/com/intellij/refactoring/rename/RenamePsiElementProcessor.java) interface.
|
If you're okay with the standard UI but need to extend the default logic of renaming, you can provide an implementation of the [`RenamePsiElementProcessor`](%gh-ic%/platform/lang-impl/src/com/intellij/refactoring/rename/RenamePsiElementProcessor.java) interface.
|
||||||
This allows you to:
|
This allows you to:
|
||||||
|
|
||||||
* Rename an element different from the one on which the action was invoked (a super method, for example)
|
* Rename an element different from the one on which the action was invoked (a super method, for example)
|
||||||
@ -64,4 +64,4 @@ This allows you to:
|
|||||||
* etc.
|
* etc.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
[`RenamePsiElementProcessor`](upsource:///plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java) for renaming a property in [Properties plugin language](upsource:///plugins/properties)
|
[`RenamePsiElementProcessor`](%gh-ic%/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java) for renaming a property in [Properties plugin language](%gh-ic%/plugins/properties)
|
||||||
|
@ -7,20 +7,20 @@ The _Safe Delete_ refactoring also builds on the same [Find Usages](find_usages.
|
|||||||
In addition to that, to support _Safe Delete_, a plugin needs to implement two things:
|
In addition to that, to support _Safe Delete_, a plugin needs to implement two things:
|
||||||
|
|
||||||
* The
|
* The
|
||||||
[`RefactoringSupportProvider`](upsource:///platform/refactoring/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java)
|
[`RefactoringSupportProvider`](%gh-ic%/platform/refactoring/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java)
|
||||||
interface, registered in the `com.intellij.lang.refactoringSupport` extension point, and the `isSafeDeleteAvailable()` method, which checks if the _Safe Delete_ refactoring is available for a specific PSI element
|
interface, registered in the `com.intellij.lang.refactoringSupport` extension point, and the `isSafeDeleteAvailable()` method, which checks if the _Safe Delete_ refactoring is available for a specific PSI element
|
||||||
|
|
||||||
* The
|
* The
|
||||||
[`PsiElement.delete()`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java)
|
[`PsiElement.delete()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java)
|
||||||
method for the
|
method for the
|
||||||
[`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java)
|
[`PsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java)
|
||||||
subclasses for which _Safe Delete_ is available.
|
subclasses for which _Safe Delete_ is available.
|
||||||
Deleting PSI elements is implemented by deleting the underlying AST nodes from the AST tree (which, in turn, causes the text ranges corresponding to the AST nodes to be deleted from the document).
|
Deleting PSI elements is implemented by deleting the underlying AST nodes from the AST tree (which, in turn, causes the text ranges corresponding to the AST nodes to be deleted from the document).
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
[`delete()`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java) implementation for a Property in [Properties language plugin](upsource:///plugins/properties)
|
[`delete()`](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java) implementation for a Property in [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
|
||||||
If needed, it's possible to further customize how _Safe Delete_ is performed for a particular type of element (e.g., how references are searched) via [`SafeDeleteProcessorDelegate`](upsource:///platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessorDelegate.java).
|
If needed, it's possible to further customize how _Safe Delete_ is performed for a particular type of element (e.g., how references are searched) via [`SafeDeleteProcessorDelegate`](%gh-ic%/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessorDelegate.java).
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
[`SafeDeleteProcessorDelegate`](upsource:///plugins/properties/src/com/intellij/lang/properties/refactoring/PropertiesFilesSafeDeleteProcessor.java) implementation for [Properties language plugin](upsource:///plugins/properties)
|
[`SafeDeleteProcessorDelegate`](%gh-ic%/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertiesFilesSafeDeleteProcessor.java) implementation for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
@ -3,26 +3,26 @@
|
|||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||||
|
|
||||||
The Structure View implementation used for a specific file type can be customized on many levels.
|
The Structure View implementation used for a specific file type can be customized on many levels.
|
||||||
If a custom language plugin provides an implementation of the [`StructureView`](upsource:///platform/editor-ui-api/src/com/intellij/ide/structureView/StructureView.java) interface, it can completely replace the standard structure view implementation with a custom user interface component.
|
If a custom language plugin provides an implementation of the [`StructureView`](%gh-ic%/platform/editor-ui-api/src/com/intellij/ide/structureView/StructureView.java) interface, it can completely replace the standard structure view implementation with a custom user interface component.
|
||||||
However, for most languages, this is not necessary, and the standard `StructureView` implementation provided by IntelliJ Platform can be reused.
|
However, for most languages, this is not necessary, and the standard `StructureView` implementation provided by IntelliJ Platform can be reused.
|
||||||
|
|
||||||
> To modify an existing Structure View (e.g., add/filter nodes of builtin language support), use [`StructureViewExtension`](upsource:///platform/structure-view-impl/src/com/intellij/ide/structureView/StructureViewExtension.java) registered in `com.intellij.lang.structureViewExtension` extension point.
|
> To modify an existing Structure View (e.g., add/filter nodes of builtin language support), use [`StructureViewExtension`](%gh-ic%/platform/structure-view-impl/src/com/intellij/ide/structureView/StructureViewExtension.java) registered in `com.intellij.lang.structureViewExtension` extension point.
|
||||||
>
|
>
|
||||||
{type="tip"}
|
{type="tip"}
|
||||||
|
|
||||||
The starting point for the structure view is the [`PsiStructureViewFactory`](upsource:///platform/editor-ui-api/src/com/intellij/lang/PsiStructureViewFactory.java) interface, which is registered in the `com.intellij.lang.psiStructureViewFactory` extension point.
|
The starting point for the structure view is the [`PsiStructureViewFactory`](%gh-ic%/platform/editor-ui-api/src/com/intellij/lang/PsiStructureViewFactory.java) interface, which is registered in the `com.intellij.lang.psiStructureViewFactory` extension point.
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
- [`PsiStructureViewFactory`](upsource:///plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesStructureViewBuilderFactory.java) for [Properties language plugin](upsource:///plugins/properties)
|
- [`PsiStructureViewFactory`](%gh-ic%/plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesStructureViewBuilderFactory.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
- [Custom Language Support Tutorial: Structure View](structure_view_factory.md)
|
- [Custom Language Support Tutorial: Structure View](structure_view_factory.md)
|
||||||
|
|
||||||
To reuse the IntelliJ Platform implementation of the `StructureView`, the plugin returns a [`TreeBasedStructureViewBuilder`](upsource:///platform/editor-ui-api/src/com/intellij/ide/structureView/TreeBasedStructureViewBuilder.java) from its [`PsiStructureViewFactory.getStructureViewBuilder()`](upsource:///platform/editor-ui-api/src/com/intellij/lang/PsiStructureViewFactory.java) method.
|
To reuse the IntelliJ Platform implementation of the `StructureView`, the plugin returns a [`TreeBasedStructureViewBuilder`](%gh-ic%/platform/editor-ui-api/src/com/intellij/ide/structureView/TreeBasedStructureViewBuilder.java) from its [`PsiStructureViewFactory.getStructureViewBuilder()`](%gh-ic%/platform/editor-ui-api/src/com/intellij/lang/PsiStructureViewFactory.java) method.
|
||||||
As the builder model, the plugin can specify a subclass of [`TextEditorBasedStructureViewModel`](upsource:///platform/editor-ui-api/src/com/intellij/ide/structureView/TextEditorBasedStructureViewModel.java), and by overriding methods of this subclass, it customizes the structure view for a specific language.
|
As the builder model, the plugin can specify a subclass of [`TextEditorBasedStructureViewModel`](%gh-ic%/platform/editor-ui-api/src/com/intellij/ide/structureView/TextEditorBasedStructureViewModel.java), and by overriding methods of this subclass, it customizes the structure view for a specific language.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
[`StructureViewModel`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewModel.java) for [Properties language plugin](upsource:///plugins/properties)
|
[`StructureViewModel`](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewModel.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
|
||||||
The main method to override is `getRoot()`, which returns the instance of a class implementing the [`StructureViewTreeElement`](upsource:///platform/editor-ui-api/src/com/intellij/ide/structureView/StructureViewTreeElement.java) interface.
|
The main method to override is `getRoot()`, which returns the instance of a class implementing the [`StructureViewTreeElement`](%gh-ic%/platform/editor-ui-api/src/com/intellij/ide/structureView/StructureViewTreeElement.java) interface.
|
||||||
There exists no standard implementation of this interface, so a plugin will need to implement it completely.
|
There exists no standard implementation of this interface, so a plugin will need to implement it completely.
|
||||||
|
|
||||||
The structure view tree is usually built as a partial mirror of the PSI tree.
|
The structure view tree is usually built as a partial mirror of the PSI tree.
|
||||||
@ -34,4 +34,4 @@ The latter method returns an array of `PsiElement`\-derived classes, which can b
|
|||||||
It is used to select the Structure View item matching the cursor position when the structure view is first opened or when the <control>Autoscroll from source</control> option is enabled.
|
It is used to select the Structure View item matching the cursor position when the structure view is first opened or when the <control>Autoscroll from source</control> option is enabled.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
[`StructureViewTreeElement`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/PropertyStructureViewElement.java) for [Properties language plugin](upsource:///plugins/properties)
|
[`StructureViewTreeElement`](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/PropertyStructureViewElement.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||||
|
|
||||||
To support the _Surround With_ action, the plugin needs to register one or more implementations of the [`SurroundDescriptor`](upsource:///platform/lang-api/src/com/intellij/lang/surroundWith/SurroundDescriptor.java) interface in the `com.intellij.lang.surroundDescriptor` extension point.
|
To support the _Surround With_ action, the plugin needs to register one or more implementations of the [`SurroundDescriptor`](%gh-ic%/platform/lang-api/src/com/intellij/lang/surroundWith/SurroundDescriptor.java) interface in the `com.intellij.lang.surroundDescriptor` extension point.
|
||||||
Each of the surround descriptors defines a possible type of code fragment that can be surrounded - for example, one surround descriptor can handle surrounding expressions, and another can handle statements.
|
Each of the surround descriptors defines a possible type of code fragment that can be surrounded - for example, one surround descriptor can handle surrounding expressions, and another can handle statements.
|
||||||
Each surround descriptor, in turn, contains an array of [`Surrounder`](upsource:///platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java) objects, defining specific templates which can be used for surrounding the selected code fragment (for example, _Surround With if_, _Surround With for_, and so on).
|
Each surround descriptor, in turn, contains an array of [`Surrounder`](%gh-ic%/platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java) objects, defining specific templates which can be used for surrounding the selected code fragment (for example, _Surround With if_, _Surround With for_, and so on).
|
||||||
|
|
||||||
When the <menupath>Code | Surround With...</menupath> action is invoked, the IDE queries all surround descriptors for the language until it finds one that returns a non-empty array from its `getElementsToSurround()` method.
|
When the <menupath>Code | Surround With...</menupath> action is invoked, the IDE queries all surround descriptors for the language until it finds one that returns a non-empty array from its `getElementsToSurround()` method.
|
||||||
Then it calls the [`Surrounder.isApplicable()`](upsource:///platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java) method for each surrounder in that descriptor to check if the specific template is applicable in the current context.
|
Then it calls the [`Surrounder.isApplicable()`](%gh-ic%/platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java) method for each surrounder in that descriptor to check if the specific template is applicable in the current context.
|
||||||
Once the user selects a specific surrounder from the popup menu, the [`Surrounder.surroundElements()`](upsource:///platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java) method is used to execute the surround action.
|
Once the user selects a specific surrounder from the popup menu, the [`Surrounder.surroundElements()`](%gh-ic%/platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java) method is used to execute the surround action.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
[`SurroundDescriptor`](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/lang/surroundWith/GroovySurroundDescriptor.java) for Groovy plugin
|
[`SurroundDescriptor`](%gh-ic%/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/surroundWith/GroovySurroundDescriptor.java) for Groovy plugin
|
||||||
|
|
||||||
> See the [](live_templates.md) and [](advanced_postfix_templates.md#surround-postfix-templates) sections for information on how to support code surrounding with other IDE features.
|
> See the [](live_templates.md) and [](advanced_postfix_templates.md#surround-postfix-templates) sections for information on how to support code surrounding with other IDE features.
|
||||||
>
|
>
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
A symbol is a semantic element in some model, e.g., language or framework model.
|
A symbol is a semantic element in some model, e.g., language or framework model.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
The IntelliJ Platform uses [`Symbol`](upsource:///platform/core-api/src/com/intellij/model/Symbol.java) to represent symbols, and `Symbol` serves as a link between Platform APIs, such as navigation, finding usages, or renaming.
|
The IntelliJ Platform uses [`Symbol`](%gh-ic%/platform/core-api/src/com/intellij/model/Symbol.java) to represent symbols, and `Symbol` serves as a link between Platform APIs, such as navigation, finding usages, or renaming.
|
||||||
This API allows implementing the same functionalities as in the [References and Resolve](references_and_resolve.md) mechanism, but it is a more abstract concept not limited to connecting only PSI elements.
|
This API allows implementing the same functionalities as in the [References and Resolve](references_and_resolve.md) mechanism, but it is a more abstract concept not limited to connecting only PSI elements.
|
||||||
The platform obtains the target symbol from a [declaration](declarations_and_references.md#declarations) or by resolving a [reference](declarations_and_references.md#references) and then uses it to perform an action.
|
The platform obtains the target symbol from a [declaration](declarations_and_references.md#declarations) or by resolving a [reference](declarations_and_references.md#references) and then uses it to perform an action.
|
||||||
The [`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) is considered as an element in the source tree (enhanced `ASTNode`).
|
The [`PsiElement`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) is considered as an element in the source tree (enhanced `ASTNode`).
|
||||||
`Symbol` decouples semantic actions from [PSI](psi.md).
|
`Symbol` decouples semantic actions from [PSI](psi.md).
|
||||||
|
|
||||||
A `Symbol` is not required to be backed by a `PsiElement`, and it is incorrect to try to obtain the `PsiElement` from a `Symbol`.
|
A `Symbol` is not required to be backed by a `PsiElement`, and it is incorrect to try to obtain the `PsiElement` from a `Symbol`.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||||
|
|
||||||
The class used to specify how a particular range of text should be highlighted is called [`TextAttributesKey`](upsource:///platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java).
|
The class used to specify how a particular range of text should be highlighted is called [`TextAttributesKey`](%gh-ic%/platform/core-api/src/com/intellij/openapi/editor/colors/TextAttributesKey.java).
|
||||||
An instance of this class is created for every distinct type of item that should be highlighted (keyword, number, string, etc.).
|
An instance of this class is created for every distinct type of item that should be highlighted (keyword, number, string, etc.).
|
||||||
The `TextAttributesKey` defines the default attributes applied to items of the corresponding type (for example, keywords are bold, numbers are blue, strings are bold and green).
|
The `TextAttributesKey` defines the default attributes applied to items of the corresponding type (for example, keywords are bold, numbers are blue, strings are bold and green).
|
||||||
Highlighting from multiple `TextAttributesKey` items can be layered - for example, one key may define an item's boldness and another color.
|
Highlighting from multiple `TextAttributesKey` items can be layered - for example, one key may define an item's boldness and another color.
|
||||||
@ -10,19 +10,19 @@ Highlighting from multiple `TextAttributesKey` items can be layered - for exampl
|
|||||||
Existing highlighting can be suppressed programmatically in certain contexts, see [](controlling_highlighting.md).
|
Existing highlighting can be suppressed programmatically in certain contexts, see [](controlling_highlighting.md).
|
||||||
|
|
||||||
> To force re-highlighting (e.g., after changing plugin specific settings), use
|
> To force re-highlighting (e.g., after changing plugin specific settings), use
|
||||||
> [`DaemonCodeAnalyzer.restart()`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java).
|
> [`DaemonCodeAnalyzer.restart()`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java).
|
||||||
>
|
>
|
||||||
{type="tip"}
|
{type="tip"}
|
||||||
|
|
||||||
## Color Settings
|
## Color Settings
|
||||||
The mapping of the `TextAttributesKey` to specific attributes used in an editor is defined by the [`EditorColorsScheme`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorsScheme.java) class.
|
The mapping of the `TextAttributesKey` to specific attributes used in an editor is defined by the [`EditorColorsScheme`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorsScheme.java) class.
|
||||||
It can be configured by the user by providing an implementation of [`ColorSettingPage`](upsource:///platform/platform-api/src/com/intellij/openapi/options/colors/ColorSettingsPage.java) registered in `com.intellij.colorSettingsPage` extension point.
|
It can be configured by the user by providing an implementation of [`ColorSettingPage`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/options/colors/ColorSettingsPage.java) registered in `com.intellij.colorSettingsPage` extension point.
|
||||||
|
|
||||||
The <menupath>File | Export | Files or Selection to HTML</menupath> feature uses the same syntax highlighting mechanism as the editor.
|
The <menupath>File | Export | Files or Selection to HTML</menupath> feature uses the same syntax highlighting mechanism as the editor.
|
||||||
Thus, it will work automatically for custom languages that provide a syntax highlighter.
|
Thus, it will work automatically for custom languages that provide a syntax highlighter.
|
||||||
|
|
||||||
**Examples**:
|
**Examples**:
|
||||||
- [`ColorSettingsPage`](upsource:///plugins/properties/src/com/intellij/lang/properties/PropertiesColorsPage.java) for [Properties language plugin](upsource:///plugins/properties)
|
- [`ColorSettingsPage`](%gh-ic%/plugins/properties/src/com/intellij/lang/properties/PropertiesColorsPage.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
- [Custom Language Support Tutorial: Color Settings Page](syntax_highlighter_and_color_settings_page.md)
|
- [Custom Language Support Tutorial: Color Settings Page](syntax_highlighter_and_color_settings_page.md)
|
||||||
|
|
||||||
> New functionality about Language Defaults and support for additional color schemes are detailed in [Color Scheme Management](color_scheme_management.md).
|
> New functionality about Language Defaults and support for additional color schemes are detailed in [Color Scheme Management](color_scheme_management.md).
|
||||||
@ -33,15 +33,15 @@ The syntax and error highlighting are performed on multiple levels: Lexer, Parse
|
|||||||
|
|
||||||
## Lexer
|
## Lexer
|
||||||
|
|
||||||
The first syntax highlighting level is based on the lexer output and is provided through the [`SyntaxHighlighter`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java) interface.
|
The first syntax highlighting level is based on the lexer output and is provided through the [`SyntaxHighlighter`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighter.java) interface.
|
||||||
The syntax highlighter returns the `TextAttributesKey` instances for each token type, which needs special highlighting.
|
The syntax highlighter returns the `TextAttributesKey` instances for each token type, which needs special highlighting.
|
||||||
For highlighting lexer errors, the standard `TextAttributesKey` for bad characters [`HighlighterColors.BAD_CHARACTER`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/HighlighterColors.java) can be used.
|
For highlighting lexer errors, the standard `TextAttributesKey` for bad characters [`HighlighterColors.BAD_CHARACTER`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/editor/HighlighterColors.java) can be used.
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
- [`SyntaxHighlighter`](upsource:///plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesHighlighter.java) implementation for [Properties language plugin](upsource:///plugins/properties)
|
- [`SyntaxHighlighter`](%gh-ic%/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesHighlighter.java) implementation for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
- [Custom Language Support Tutorial: Syntax Highlighter](syntax_highlighter_and_color_settings_page.md)
|
- [Custom Language Support Tutorial: Syntax Highlighter](syntax_highlighter_and_color_settings_page.md)
|
||||||
|
|
||||||
> Use [`HtmlSyntaxInfoUtil`](upsource:///platform/lang-impl/src/com/intellij/openapi/editor/richcopy/HtmlSyntaxInfoUtil.java) to create Lexer-based highlighted code samples, e.g. for usage in documentation.
|
> Use [`HtmlSyntaxInfoUtil`](%gh-ic%/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/HtmlSyntaxInfoUtil.java) to create Lexer-based highlighted code samples, e.g. for usage in documentation.
|
||||||
>
|
>
|
||||||
{type="tip"}
|
{type="tip"}
|
||||||
|
|
||||||
@ -49,19 +49,19 @@ For highlighting lexer errors, the standard `TextAttributesKey` for bad characte
|
|||||||
|
|
||||||
[Semantic highlighting](https://www.jetbrains.com/help/idea/configuring-colors-and-fonts.html#semantic-highlighting) provides an additional coloring layer to improve the visual distinction of several related items (e.g., method parameters, local variables).
|
[Semantic highlighting](https://www.jetbrains.com/help/idea/configuring-colors-and-fonts.html#semantic-highlighting) provides an additional coloring layer to improve the visual distinction of several related items (e.g., method parameters, local variables).
|
||||||
|
|
||||||
Register [`RainbowVisitor`](upsource:///platform/analysis-impl/src/com/intellij/codeInsight/daemon/RainbowVisitor.java) in `com.intellij.highlightVisitor` extension point.
|
Register [`RainbowVisitor`](%gh-ic%/platform/analysis-impl/src/com/intellij/codeInsight/daemon/RainbowVisitor.java) in `com.intellij.highlightVisitor` extension point.
|
||||||
[](#color-settings) must implement [`RainbowColorSettingsPage`](upsource:///platform/platform-api/src/com/intellij/openapi/options/colors/RainbowColorSettingsPage.java) in addition.
|
[](#color-settings) must implement [`RainbowColorSettingsPage`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/options/colors/RainbowColorSettingsPage.java) in addition.
|
||||||
|
|
||||||
## Parser
|
## Parser
|
||||||
|
|
||||||
The second level of error highlighting happens during parsing.
|
The second level of error highlighting happens during parsing.
|
||||||
If a particular sequence of tokens is invalid according to the grammar of the language, the [`PsiBuilder.error()`](upsource:///platform/core-api/src/com/intellij/lang/PsiBuilder.java) method can highlight the invalid tokens and display an error message showing why they are not valid.
|
If a particular sequence of tokens is invalid according to the grammar of the language, the [`PsiBuilder.error()`](%gh-ic%/platform/core-api/src/com/intellij/lang/PsiBuilder.java) method can highlight the invalid tokens and display an error message showing why they are not valid.
|
||||||
|
|
||||||
See [](syntax_errors.md) on how to programmatically suppress these errors in certain contexts.
|
See [](syntax_errors.md) on how to programmatically suppress these errors in certain contexts.
|
||||||
|
|
||||||
## Annotator
|
## Annotator
|
||||||
|
|
||||||
The third level of highlighting is performed through the [`Annotator`](upsource:///platform/analysis-api/src/com/intellij/lang/annotation/Annotator.java) interface.
|
The third level of highlighting is performed through the [`Annotator`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/annotation/Annotator.java) interface.
|
||||||
A plugin can register one or more annotators in the `com.intellij.annotator` extension point, and these annotators are called during the background highlighting pass to process the elements in the custom language's PSI tree.
|
A plugin can register one or more annotators in the `com.intellij.annotator` extension point, and these annotators are called during the background highlighting pass to process the elements in the custom language's PSI tree.
|
||||||
Attribute `language` should be set to the Language ID where this annotator applies to.
|
Attribute `language` should be set to the Language ID where this annotator applies to.
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ To highlight a region of text as a warning or error:
|
|||||||
|
|
||||||
<tab title="Pre-2020.1">
|
<tab title="Pre-2020.1">
|
||||||
|
|
||||||
Call `createWarningAnnotation()`/`createErrorAnnotation()` on the [`AnnotationHolder`](upsource:///platform/analysis-api/src/com/intellij/lang/annotation/AnnotationHolder.java), and optionally calls `registerFix()` on the returned [`Annotation`](upsource:///platform/analysis-api/src/com/intellij/lang/annotation/Annotation.java) object to add a quick fix for the error or warning.
|
Call `createWarningAnnotation()`/`createErrorAnnotation()` on the [`AnnotationHolder`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/annotation/AnnotationHolder.java), and optionally calls `registerFix()` on the returned [`Annotation`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/annotation/Annotation.java) object to add a quick fix for the error or warning.
|
||||||
|
|
||||||
</tab>
|
</tab>
|
||||||
|
|
||||||
@ -116,21 +116,21 @@ To apply additional syntax highlighting (2020.1 and later):
|
|||||||
|
|
||||||
<tab title="Pre-2020.1">
|
<tab title="Pre-2020.1">
|
||||||
|
|
||||||
Call `AnnotationHolder.createInfoAnnotation()` with an empty message and then [`Annotation.setTextAttributes()`](upsource:///platform/analysis-api/src/com/intellij/lang/annotation/Annotation.java).
|
Call `AnnotationHolder.createInfoAnnotation()` with an empty message and then [`Annotation.setTextAttributes()`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/annotation/Annotation.java).
|
||||||
|
|
||||||
</tab>
|
</tab>
|
||||||
|
|
||||||
</tabs>
|
</tabs>
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
- [`Annotator`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesAnnotator.java) for [Properties language plugin](upsource:///plugins/properties)
|
- [`Annotator`](%gh-ic%/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesAnnotator.java) for [Properties language plugin](%gh-ic%/plugins/properties)
|
||||||
- [Custom Language Support Tutorial: Annotator](annotator.md)
|
- [Custom Language Support Tutorial: Annotator](annotator.md)
|
||||||
|
|
||||||
## External Tool
|
## External Tool
|
||||||
|
|
||||||
Finally, if the custom language employs external tools for validating files in the language (for example, uses the Xerces library for XML schema validation), it can provide an implementation of the [`ExternalAnnotator`](upsource:///platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java) interface and register it in `com.intellij.externalAnnotator` extension point (`language` attribute must be specified).
|
Finally, if the custom language employs external tools for validating files in the language (for example, uses the Xerces library for XML schema validation), it can provide an implementation of the [`ExternalAnnotator`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java) interface and register it in `com.intellij.externalAnnotator` extension point (`language` attribute must be specified).
|
||||||
|
|
||||||
The [`ExternalAnnotator`](upsource:///platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java) highlighting has the lowest priority and is invoked only after all other background processing has completed.
|
The [`ExternalAnnotator`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java) highlighting has the lowest priority and is invoked only after all other background processing has completed.
|
||||||
It uses the same [`AnnotationHolder`](upsource:///platform/analysis-api/src/com/intellij/lang/annotation/AnnotationHolder.java) interface for converting the output of the external tool into editor highlighting.
|
It uses the same [`AnnotationHolder`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/annotation/AnnotationHolder.java) interface for converting the output of the external tool into editor highlighting.
|
||||||
|
|
||||||
To skip running specific `ExternalAnnotator` for given file, register [`ExternalAnnotatorsFilter`](upsource:///platform/analysis-api/src/com/intellij/lang/ExternalAnnotatorsFilter.java) extension in `com.intellij.daemon.externalAnnotatorsFilter` extension point.
|
To skip running specific `ExternalAnnotator` for given file, register [`ExternalAnnotatorsFilter`](%gh-ic%/platform/analysis-api/src/com/intellij/lang/ExternalAnnotatorsFilter.java) extension in `com.intellij.daemon.externalAnnotatorsFilter` extension point.
|
||||||
|
@ -13,16 +13,16 @@ When the user invokes an action that involves executing an external build (Make,
|
|||||||
|
|
||||||
* Before-compile tasks are performed in the IDE process.
|
* Before-compile tasks are performed in the IDE process.
|
||||||
* Some source generation tasks that depend on the PSI (e.g., UI designer form to source compilation) are executed in the IDE process.
|
* Some source generation tasks that depend on the PSI (e.g., UI designer form to source compilation) are executed in the IDE process.
|
||||||
* [`BuildTargetScopeProvider`](upsource:///java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java) extensions are called to calculate the scope of the external build (the set of build targets to compile based on the target module to make and the known set of changes).
|
* [`BuildTargetScopeProvider`](%gh-ic%/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java) extensions are called to calculate the scope of the external build (the set of build targets to compile based on the target module to make and the known set of changes).
|
||||||
* The external build process is spawned (or an existing build process background process is reused).
|
* The external build process is spawned (or an existing build process background process is reused).
|
||||||
* The external build process loads the project model (<path>.idea</path>, <path>.iml</path> files, and so on), represented by a [`JpsModel`](upsource:///jps/model-api/src/org/jetbrains/jps/model/JpsModel.java) instance.
|
* The external build process loads the project model (<path>.idea</path>, <path>.iml</path> files, and so on), represented by a [`JpsModel`](%gh-ic%/jps/model-api/src/org/jetbrains/jps/model/JpsModel.java) instance.
|
||||||
* The full tree of targets to build is calculated based on each build target's dependencies to be compiled.
|
* The full tree of targets to build is calculated based on each build target's dependencies to be compiled.
|
||||||
* For each target, the set of builders capable of building this target is calculated.
|
* For each target, the set of builders capable of building this target is calculated.
|
||||||
* For every target and every builder, the `build()` method is called.
|
* For every target and every builder, the `build()` method is called.
|
||||||
This can happen in parallel if the "Compile independent modules in parallel" option is enabled in the settings.
|
This can happen in parallel if the "Compile independent modules in parallel" option is enabled in the settings.
|
||||||
For module-level builders, the order of invoking builders for a single target is determined by their category; for other builders, the order is undefined.
|
For module-level builders, the order of invoking builders for a single target is determined by their category; for other builders, the order is undefined.
|
||||||
* Caches to record the state of the compilation are saved.
|
* Caches to record the state of the compilation are saved.
|
||||||
* Compilation messages reported through the [`CompileContext`](upsource:///jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java) API are transmitted to the IDE process and displayed in the UI (in the *Messages* view).
|
* Compilation messages reported through the [`CompileContext`](%gh-ic%/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java) API are transmitted to the IDE process and displayed in the UI (in the *Messages* view).
|
||||||
* Post-compile tasks are executed in the IDE process.
|
* Post-compile tasks are executed in the IDE process.
|
||||||
|
|
||||||
### Incremental Build
|
### Incremental Build
|
||||||
@ -30,7 +30,7 @@ When the user invokes an action that involves executing an external build (Make,
|
|||||||
To support incremental build, the build process uses several caches which are persisted between build invocations.
|
To support incremental build, the build process uses several caches which are persisted between build invocations.
|
||||||
Even if your compiler doesn't support incremental build, you still need to report correct information so that incremental build works correctly for other compilers.
|
Even if your compiler doesn't support incremental build, you still need to report correct information so that incremental build works correctly for other compilers.
|
||||||
|
|
||||||
* [`SourceToOutputMapping`](upsource:///jps/jps-builders/src/org/jetbrains/jps/builders/storage/SourceToOutputMapping.java) is a many-to-many relationship between source files and output files ("which source files were used to produce the specified output file").
|
* [`SourceToOutputMapping`](%gh-ic%/jps/jps-builders/src/org/jetbrains/jps/builders/storage/SourceToOutputMapping.java) is a many-to-many relationship between source files and output files ("which source files were used to produce the specified output file").
|
||||||
It's filled by calls to `BuildOutputConsumer.registerOutputFile()` and `ModuleLevelBuilder.OutputConsumer.registerOutputFile()`.
|
It's filled by calls to `BuildOutputConsumer.registerOutputFile()` and `ModuleLevelBuilder.OutputConsumer.registerOutputFile()`.
|
||||||
|
|
||||||
The IDE monitors the project content changes and uses the information from those caches to generate the set of dirty and deleted files for every compilation. (Dirty files need to be recompiled, and deleted files need to have their output deleted).
|
The IDE monitors the project content changes and uses the information from those caches to generate the set of dirty and deleted files for every compilation. (Dirty files need to be recompiled, and deleted files need to have their output deleted).
|
||||||
@ -44,7 +44,7 @@ To pass custom data between the invocation of the same builder between multiple
|
|||||||
### Services and Extensions in External Builder
|
### Services and Extensions in External Builder
|
||||||
|
|
||||||
The external builder process uses the standard Java [services](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html) mechanism to support plugins.
|
The external builder process uses the standard Java [services](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html) mechanism to support plugins.
|
||||||
There are several service interfaces (e.g. [`BuilderService`](upsource:///jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderService.java) which can be implemented in plugins to extend the builder functionality.
|
There are several service interfaces (e.g. [`BuilderService`](%gh-ic%/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderService.java) which can be implemented in plugins to extend the builder functionality.
|
||||||
An implementation of a service needs to be registered by creating the <path>META-INF/services/$service-interface-fqn$</path> file containing the implementation class's qualified name.
|
An implementation of a service needs to be registered by creating the <path>META-INF/services/$service-interface-fqn$</path> file containing the implementation class's qualified name.
|
||||||
E.g. `BuilderService` implementations are registered in <path>META-INF/services/org.jetbrains.jps.incremental.BuilderService</path> file.
|
E.g. `BuilderService` implementations are registered in <path>META-INF/services/org.jetbrains.jps.incremental.BuilderService</path> file.
|
||||||
These files don't have extensions, so you need to map corresponding patterns to text files in IDE settings.
|
These files don't have extensions, so you need to map corresponding patterns to text files in IDE settings.
|
||||||
@ -117,12 +117,12 @@ In IntelliJ Platform versions before version 14.1, log4j configuration was store
|
|||||||
### Accessing Project Model and Configuration from External Build
|
### Accessing Project Model and Configuration from External Build
|
||||||
|
|
||||||
The project model in the External Build process is provided by JPS (*JetBrains Project System*).
|
The project model in the External Build process is provided by JPS (*JetBrains Project System*).
|
||||||
A project is represented by [`JpsProject`](upsource:///jps/model-api/src/org/jetbrains/jps/model/JpsProject.java), a module by [`JpsModule`](upsource:///jps/model-api/src/org/jetbrains/jps/model/JpsProject.java), and so on.
|
A project is represented by [`JpsProject`](%gh-ic%/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java), a module by [`JpsModule`](%gh-ic%/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java), and so on.
|
||||||
Suppose your compiler depends on something that isn't added to the model yet (e.g., some facet settings).
|
Suppose your compiler depends on something that isn't added to the model yet (e.g., some facet settings).
|
||||||
In that case, you need to extend the JPS model (use `JpsOsmorcModuleExtension` as a reference implementation) and provide an implementation of [`JpsModelSerializerExtension`](upsource:///jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java) to load the configuration from project files.
|
In that case, you need to extend the JPS model (use `JpsOsmorcModuleExtension` as a reference implementation) and provide an implementation of [`JpsModelSerializerExtension`](%gh-ic%/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java) to load the configuration from project files.
|
||||||
|
|
||||||
#### Implementing Builder
|
#### Implementing Builder
|
||||||
|
|
||||||
If your compiler isn't involved in the compilation of an existing [`BuildTarget`](upsource:///jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java), you need to create a new implementation of `BuildTarget` and `BuildTargetType`.
|
If your compiler isn't involved in the compilation of an existing [`BuildTarget`](%gh-ic%/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java), you need to create a new implementation of `BuildTarget` and `BuildTargetType`.
|
||||||
Also, register an implementation of [`BuildTargetScopeProvider`](upsource:///java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java) extension on the IDE side to add required targets to the build scope.
|
Also, register an implementation of [`BuildTargetScopeProvider`](%gh-ic%/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java) extension on the IDE side to add required targets to the build scope.
|
||||||
The builder implementation should extend either [`TargetBuilder`](upsource:///jps/jps-builders/src/org/jetbrains/jps/incremental/TargetBuilder.java) or [`ModuleLevelBuilder`](upsource:///jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleLevelBuilder.java) class and should be created using [`BuilderService`](upsource:///jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderService.java) extension.
|
The builder implementation should extend either [`TargetBuilder`](%gh-ic%/jps/jps-builders/src/org/jetbrains/jps/incremental/TargetBuilder.java) or [`ModuleLevelBuilder`](%gh-ic%/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleLevelBuilder.java) class and should be created using [`BuilderService`](%gh-ic%/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderService.java) extension.
|
||||||
|
@ -20,9 +20,9 @@ The *External System* sub-system provides a simple API for wrapping external sys
|
|||||||
|
|
||||||
The external system wrapper is required to be able to build project info on the basis of the given external system config.
|
The external system wrapper is required to be able to build project info on the basis of the given external system config.
|
||||||
That information is built with the following base classes:
|
That information is built with the following base classes:
|
||||||
* [`DataNode`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java)
|
* [`DataNode`](%gh-ic%/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java)
|
||||||
* [`Key`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/model/Key.java)
|
* [`Key`](%gh-ic%/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/Key.java)
|
||||||
* [`ExternalEntityData`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalEntityData.java)
|
* [`ExternalEntityData`](%gh-ic%/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalEntityData.java)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -37,7 +37,7 @@ The IDE provides a set of built-in `Key` and `ExternalEntityData` classes but an
|
|||||||
|
|
||||||
### Managing Project Data
|
### Managing Project Data
|
||||||
|
|
||||||
Processing project data built on an external system config basis can be performed with [`ProjectDataService`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataService.java).
|
Processing project data built on an external system config basis can be performed with [`ProjectDataService`](%gh-ic%/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataService.java).
|
||||||
It is a strategy which knows how to manage particular `ExternalEntityData`.
|
It is a strategy which knows how to manage particular `ExternalEntityData`.
|
||||||
For example, when we want to import a project from an external model, we can start with the top level `DataNode` which references project info and then import its data using corresponding service.
|
For example, when we want to import a project from an external model, we can start with the top level `DataNode` which references project info and then import its data using corresponding service.
|
||||||
|
|
||||||
@ -49,21 +49,21 @@ That means that a set of `DataNode`, `Key` and `ProjectDataServices` can be intr
|
|||||||
### Importing from External Model
|
### Importing from External Model
|
||||||
|
|
||||||
The IntelliJ Platform provides an API for importing projects from external models:
|
The IntelliJ Platform provides an API for importing projects from external models:
|
||||||
* [`ProjectImportBuilder`](upsource:///java/idea-ui/src/com/intellij/projectImport/ProjectImportBuilder.java)
|
* [`ProjectImportBuilder`](%gh-ic%/java/idea-ui/src/com/intellij/projectImport/ProjectImportBuilder.java)
|
||||||
* [`ProjectImportProvider`](upsource:///java/idea-ui/src/com/intellij/projectImport/ProjectImportProvider.java)
|
* [`ProjectImportProvider`](%gh-ic%/java/idea-ui/src/com/intellij/projectImport/ProjectImportProvider.java)
|
||||||
|
|
||||||
There are two classes built on the *template method* pattern which simplify implementation:
|
There are two classes built on the *template method* pattern which simplify implementation:
|
||||||
* [`AbstractExternalProjectImportBuilder`](upsource:///java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java)
|
* [`AbstractExternalProjectImportBuilder`](%gh-ic%/java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java)
|
||||||
* [`AbstractExternalProjectImportProvider`](upsource:///java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportProvider.java)
|
* [`AbstractExternalProjectImportProvider`](%gh-ic%/java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportProvider.java)
|
||||||
|
|
||||||
Note that [`AbstractExternalProjectImportBuilder`](upsource:///java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java) is built on top of the 'external system settings' controls.
|
Note that [`AbstractExternalProjectImportBuilder`](%gh-ic%/java/idea-ui/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalProjectImportBuilder.java) is built on top of the 'external system settings' controls.
|
||||||
|
|
||||||
Concrete implementations should be registered in [`com.intellij.projectImportBuilder`](https://jb.gg/ipe?extensions=com.intellij.projectImportBuilder) and [`com.intellij.projectImportProvider`](https://jb.gg/ipe?extensions=com.intellij.projectImportProvider) extension points accordingly.
|
Concrete implementations should be registered in [`com.intellij.projectImportBuilder`](https://jb.gg/ipe?extensions=com.intellij.projectImportBuilder) and [`com.intellij.projectImportProvider`](https://jb.gg/ipe?extensions=com.intellij.projectImportProvider) extension points accordingly.
|
||||||
|
|
||||||
Example of the project import provider and builder for Gradle:
|
Example of the project import provider and builder for Gradle:
|
||||||
|
|
||||||
* [`JavaGradleProjectImportProvider`](upsource:///plugins/gradle/java/src/service/project/wizard/JavaGradleProjectImportProvider.kt)
|
* [`JavaGradleProjectImportProvider`](%gh-ic%/plugins/gradle/java/src/service/project/wizard/JavaGradleProjectImportProvider.kt)
|
||||||
* [`JavaGradleProjectImportBuilder`](upsource:///plugins/gradle/java/src/service/project/wizard/JavaGradleProjectImportBuilder.kt)
|
* [`JavaGradleProjectImportBuilder`](%gh-ic%/plugins/gradle/java/src/service/project/wizard/JavaGradleProjectImportBuilder.kt)
|
||||||
|
|
||||||
## Auto-Import
|
## Auto-Import
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ It's possible to configure external system integration to automatically refresh
|
|||||||
|
|
||||||
### Auto-Import for ExternalSystemManager Implementation
|
### Auto-Import for ExternalSystemManager Implementation
|
||||||
|
|
||||||
Describe project's settings files to track by having external system [`ExternalSystemManager`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemManager.java) implement [`ExternalSystemAutoImportAware`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemAutoImportAware.java).
|
Describe project's settings files to track by having external system [`ExternalSystemManager`](%gh-ic%/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemManager.java) implement [`ExternalSystemAutoImportAware`](%gh-ic%/platform/external-system-api/src/com/intellij/openapi/externalSystem/ExternalSystemAutoImportAware.java).
|
||||||
|
|
||||||
> The `ExternalSystemAutoImportAware.getAffectedExternalProjectPath()` method is called quite often, that's why it's expected to return control as soon as possible.
|
> The `ExternalSystemAutoImportAware.getAffectedExternalProjectPath()` method is called quite often, that's why it's expected to return control as soon as possible.
|
||||||
> Helper `CachingExternalSystemAutoImportAware` class might be used for caching, i.e. `ExternalSystemManager` which implements `ExternalSystemAutoImportAware` can have a field like `new CachingExternalSystemAutoImportAware(new MyExternalSystemAutoImportAware())` and delegate `ExternalSystemAutoImportAware.getAffectedExternalProjectPath()` calls to it.
|
> Helper `CachingExternalSystemAutoImportAware` class might be used for caching, i.e. `ExternalSystemManager` which implements `ExternalSystemAutoImportAware` can have a field like `new CachingExternalSystemAutoImportAware(new MyExternalSystemAutoImportAware())` and delegate `ExternalSystemAutoImportAware.getAffectedExternalProjectPath()` calls to it.
|
||||||
@ -96,12 +96,12 @@ Then register the instance with `ExternalSystemProjectTracker` to start tracking
|
|||||||
### Icon for Reload Notification
|
### Icon for Reload Notification
|
||||||
|
|
||||||
From 2020.1, the icon for reload notification can be specified per external system.
|
From 2020.1, the icon for reload notification can be specified per external system.
|
||||||
Implement [`ExternalSystemIconProvider`](upsource:///platform/external-system-api/src/com/intellij/openapi/externalSystem/ui/ExternalSystemIconProvider.kt) and register via [com.intellij.externalIconProvider](https://jb.gg/ipe?extensions=com.intellij.externalIconProvider) extension point in <path>plugin.xml</path>.
|
Implement [`ExternalSystemIconProvider`](%gh-ic%/platform/external-system-api/src/com/intellij/openapi/externalSystem/ui/ExternalSystemIconProvider.kt) and register via [com.intellij.externalIconProvider](https://jb.gg/ipe?extensions=com.intellij.externalIconProvider) extension point in <path>plugin.xml</path>.
|
||||||
Alternatively, set `reloadIcon` field external system implements `ExternalSystemIconProvider` directly.
|
Alternatively, set `reloadIcon` field external system implements `ExternalSystemIconProvider` directly.
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
|
|
||||||
All external system settings controls are represented by implementations of [`ExternalSystemSettingsControl`](upsource:///platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemSettingsControl.java).
|
All external system settings controls are represented by implementations of [`ExternalSystemSettingsControl`](%gh-ic%/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemSettingsControl.java).
|
||||||
There are general and linked project-level external system settings.
|
There are general and linked project-level external system settings.
|
||||||
A particular external system settings UI contains the following items:
|
A particular external system settings UI contains the following items:
|
||||||
|
|
||||||
@ -109,14 +109,14 @@ A particular external system settings UI contains the following items:
|
|||||||
* Linked external projects list
|
* Linked external projects list
|
||||||
* Project-level settings for the selected project
|
* Project-level settings for the selected project
|
||||||
|
|
||||||
It's recommended to extend from [`AbstractExternalProjectSettingsControl`](upsource:///platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java) for implementing project-level settings control as it already handles some of them.
|
It's recommended to extend from [`AbstractExternalProjectSettingsControl`](%gh-ic%/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java) for implementing project-level settings control as it already handles some of them.
|
||||||
|
|
||||||
**Examples**:
|
**Examples**:
|
||||||
* [`GradleSystemSettingsControl`](upsource:///plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java) handling the <control>General settings</control> in <menupath>Settings/Preferences | Build, Execution, Deployment | Build Tools | Gradle</menupath>
|
* [`GradleSystemSettingsControl`](%gh-ic%/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java) handling the <control>General settings</control> in <menupath>Settings/Preferences | Build, Execution, Deployment | Build Tools | Gradle</menupath>
|
||||||
* [`GradleProjectSettingsControl`](upsource:///plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java) handling the selected Gradle project settings in <menupath>Settings/Preferences | Build, Execution, Deployment | Build Tools | Gradle</menupath>
|
* [`GradleProjectSettingsControl`](%gh-ic%/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java) handling the selected Gradle project settings in <menupath>Settings/Preferences | Build, Execution, Deployment | Build Tools | Gradle</menupath>
|
||||||
|
|
||||||
A similar approach is used for providing settings in importing external project UI.
|
A similar approach is used for providing settings in importing external project UI.
|
||||||
Implementation is expected to extend [`AbstractImportFromExternalSystemControl`](upsource:///java/idea-ui/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java) and instead of linked external projects list it contains target external project path control.
|
Implementation is expected to extend [`AbstractImportFromExternalSystemControl`](%gh-ic%/java/idea-ui/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java) and instead of linked external projects list it contains target external project path control.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
@ -126,5 +126,5 @@ Use `com.jetbrains.intellij.platform:external-system-test-framework` from [](int
|
|||||||
|
|
||||||
Relevant base classes:
|
Relevant base classes:
|
||||||
|
|
||||||
* [`ExternalSystemImportingTestCase`](upsource:///platform/external-system-api/testFramework/src/com/intellij/platform/externalSystem/testFramework/ExternalSystemImportingTestCase.java)
|
* [`ExternalSystemImportingTestCase`](%gh-ic%/platform/external-system-api/testFramework/src/com/intellij/platform/externalSystem/testFramework/ExternalSystemImportingTestCase.java)
|
||||||
* [`ExternalSystemTestCase`](upsource:///platform/external-system-api/testFramework/src/com/intellij/platform/externalSystem/testFramework/ExternalSystemTestCase.java)
|
* [`ExternalSystemTestCase`](%gh-ic%/platform/external-system-api/testFramework/src/com/intellij/platform/externalSystem/testFramework/ExternalSystemTestCase.java)
|
||||||
|
@ -10,7 +10,7 @@ This article is intended for plugin writers who create custom web server integra
|
|||||||
It describes the *Document Object Model* (DOM) in IntelliJ Platform - an easy way to work with DTD or Schema-based XML models.
|
It describes the *Document Object Model* (DOM) in IntelliJ Platform - an easy way to work with DTD or Schema-based XML models.
|
||||||
The following topics will be covered: working with DOM itself (reading/writing tags content, attributes, and subtags) and easy XML editing in the UI by connecting UI to DOM.
|
The following topics will be covered: working with DOM itself (reading/writing tags content, attributes, and subtags) and easy XML editing in the UI by connecting UI to DOM.
|
||||||
|
|
||||||
It's assumed that the reader is familiar with Java, Swing, IntelliJ Platform XML PSI (classes [`XmlTag`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlTag.java), [`XmlFile`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlFile.java), [`XmlTagValue`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlTagValue.java), etc.), IntelliJ Platform plugin development basics (application and project components, file editors).
|
It's assumed that the reader is familiar with Java, Swing, IntelliJ Platform XML PSI (classes [`XmlTag`](%gh-ic%/xml/xml-psi-api/src/com/intellij/psi/xml/XmlTag.java), [`XmlFile`](%gh-ic%/xml/xml-psi-api/src/com/intellij/psi/xml/XmlFile.java), [`XmlTagValue`](%gh-ic%/xml/xml-psi-api/src/com/intellij/psi/xml/XmlTagValue.java), etc.), IntelliJ Platform plugin development basics (application and project components, file editors).
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ if (document != null) {
|
|||||||
|
|
||||||
Looks awful, doesn't it?
|
Looks awful, doesn't it?
|
||||||
But there's a better way to do the same thing.
|
But there's a better way to do the same thing.
|
||||||
You just need to extend a special interface - [`DomElement`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/DomElement.java).
|
You just need to extend a special interface - [`DomElement`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/DomElement.java).
|
||||||
|
|
||||||
For example, let's create several interfaces:
|
For example, let's create several interfaces:
|
||||||
|
|
||||||
@ -84,14 +84,14 @@ interface Bar extends com.intellij.util.xml.DomElement {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Next, you should create a [`DomFileDescription`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/DomFileDescription.java) class, pass to its constructor the root tag name and root element interface.
|
Next, you should create a [`DomFileDescription`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/DomFileDescription.java) class, pass to its constructor the root tag name and root element interface.
|
||||||
Register it in <path>plugin.xml</path> using `com.intellij.dom.fileMetaData` extension point and specify `rootTagName` and `domVersion`/`stubVersion` attributes.
|
Register it in <path>plugin.xml</path> using `com.intellij.dom.fileMetaData` extension point and specify `rootTagName` and `domVersion`/`stubVersion` attributes.
|
||||||
|
|
||||||
> When targeting 2019.1 or earlier, use `com.intellij.dom.fileDescription` extension point instead.
|
> When targeting 2019.1 or earlier, use `com.intellij.dom.fileDescription` extension point instead.
|
||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
You can now get the file element from [`DomManager`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/DomManager.java).
|
You can now get the file element from [`DomManager`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/DomManager.java).
|
||||||
To get the "239" value, you only have to write the following code:
|
To get the "239" value, you only have to write the following code:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@ -202,7 +202,7 @@ interface GenericDomValue<T> {
|
|||||||
|
|
||||||
So, you can just specify a particular `T` when using this interface - and everything will work.
|
So, you can just specify a particular `T` when using this interface - and everything will work.
|
||||||
Methods that work with `String` are provided for many reasons.
|
Methods that work with `String` are provided for many reasons.
|
||||||
For example, your `T` is [`PsiClass`](upsource:///java/java-psi-api/src/com/intellij/psi/PsiClass.java).
|
For example, your `T` is [`PsiClass`](%gh-ic%/java/java-psi-api/src/com/intellij/psi/PsiClass.java).
|
||||||
It would be useful to highlight invalid values in the UI.
|
It would be useful to highlight invalid values in the UI.
|
||||||
To get the value to highlight (the string from the XML file), we have the `getStringValue()` method.
|
To get the value to highlight (the string from the XML file), we have the `getStringValue()` method.
|
||||||
The error message will be taken from the converter via `getErrorMessage()`.
|
The error message will be taken from the converter via `getErrorMessage()`.
|
||||||
@ -237,19 +237,19 @@ For example:
|
|||||||
GenericAttributeValue<PsiClass> getSomeClass();
|
GenericAttributeValue<PsiClass> getSomeClass();
|
||||||
```
|
```
|
||||||
|
|
||||||
The [`DomNameStrategy`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/DomNameStrategy.java) interface specifies how to convert accessor names to XML element names.
|
The [`DomNameStrategy`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/DomNameStrategy.java) interface specifies how to convert accessor names to XML element names.
|
||||||
Or more precisely, not the full accessor names, but rather the names minus any "get", "set" or "is" prefixes.
|
Or more precisely, not the full accessor names, but rather the names minus any "get", "set" or "is" prefixes.
|
||||||
The strategy class is specified in the `@NameStrategy` annotation in any DOM element interface.
|
The strategy class is specified in the `@NameStrategy` annotation in any DOM element interface.
|
||||||
Then any descendants and children of this interface will use this strategy.
|
Then any descendants and children of this interface will use this strategy.
|
||||||
The default strategy is [`HyphenNameStrategy`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/HyphenNameStrategy.java), where words are delimited by hyphens (see sample above).
|
The default strategy is [`HyphenNameStrategy`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/HyphenNameStrategy.java), where words are delimited by hyphens (see sample above).
|
||||||
Another common variant is [`JavaNameStrategy`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/JavaNameStrategy.java) that capitalizes the first letter of each word, as in Java's naming convention.
|
Another common variant is [`JavaNameStrategy`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/JavaNameStrategy.java) that capitalizes the first letter of each word, as in Java's naming convention.
|
||||||
In our example, the attribute name would be "someClass".
|
In our example, the attribute name would be "someClass".
|
||||||
|
|
||||||
If attribute doesn't define a `PsiClass`, but some other custom `T` that needs a converter, you just need to specify the `@Convert` annotation to the getter.
|
If attribute doesn't define a `PsiClass`, but some other custom `T` that needs a converter, you just need to specify the `@Convert` annotation to the getter.
|
||||||
|
|
||||||
Please note that the attributes' getter method will never return `null`, even if the attribute isn't specified in XML.
|
Please note that the attributes' getter method will never return `null`, even if the attribute isn't specified in XML.
|
||||||
Its `getValue()`, `getStringValue()` and `getXmlAttribute()` methods will return `null`, but the DOM interface instance will exist and be valid.
|
Its `getValue()`, `getStringValue()` and `getXmlAttribute()` methods will return `null`, but the DOM interface instance will exist and be valid.
|
||||||
If the element has an underlying attribute, this can be easily fixed (surely, only if you need that): just call the `undefine()` method (defined in `DomElement`), and the XML attribute disappears, while [`GenericAttributeValue`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/GenericAttributeValue.java) remains valid.
|
If the element has an underlying attribute, this can be easily fixed (surely, only if you need that): just call the `undefine()` method (defined in `DomElement`), and the XML attribute disappears, while [`GenericAttributeValue`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/GenericAttributeValue.java) remains valid.
|
||||||
|
|
||||||
### Children: Fixed Number
|
### Children: Fixed Number
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ Most often this fixed number is 1; in our case with the relations it is 2.
|
|||||||
Just like attributes, fixed-number children exist regardless of underlying tag existence.
|
Just like attributes, fixed-number children exist regardless of underlying tag existence.
|
||||||
If you need to delete tags, it can be done with the help of the same `undefine()` method.
|
If you need to delete tags, it can be done with the help of the same `undefine()` method.
|
||||||
|
|
||||||
For children of [`GenericDomValue`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/GenericDomValue.java) type, you can also specify a converter, just as you can for attributes.
|
For children of [`GenericDomValue`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/GenericDomValue.java) type, you can also specify a converter, just as you can for attributes.
|
||||||
|
|
||||||
### Children: Collections
|
### Children: Collections
|
||||||
|
|
||||||
@ -370,13 +370,13 @@ The index parameter in the last example means the index in the merged collection
|
|||||||
|
|
||||||
You can extend existing DOM model at runtime by implementing `com.intellij.util.xml.reflect.DomExtender<T>`.
|
You can extend existing DOM model at runtime by implementing `com.intellij.util.xml.reflect.DomExtender<T>`.
|
||||||
Register it in "extenderClass" attribute of EP `com.intellij.dom.extender`, where "domClass" specifies DOM class `<T>` to be extended.
|
Register it in "extenderClass" attribute of EP `com.intellij.dom.extender`, where "domClass" specifies DOM class `<T>` to be extended.
|
||||||
[`DomExtensionsRegistrar`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/reflect/DomExtensionsRegistrar.java) provides various methods to register dynamic attributes and children.
|
[`DomExtensionsRegistrar`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/reflect/DomExtensionsRegistrar.java) provides various methods to register dynamic attributes and children.
|
||||||
|
|
||||||
If the contributed elements depend on anything other than plain XML file content (used framework version, libraries in classpath, ...), make sure to return `false` from `DomExtender.supportsStubs()`.
|
If the contributed elements depend on anything other than plain XML file content (used framework version, libraries in classpath, ...), make sure to return `false` from `DomExtender.supportsStubs()`.
|
||||||
|
|
||||||
### Namespace Support
|
### Namespace Support
|
||||||
|
|
||||||
Annotate DOM model with [`Namespace`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/Namespace.java) and register namespace key mapping via `DomFileDescription.registerNamespacePolicy()` from `DomFileDescription.initializeFileDescription()`.
|
Annotate DOM model with [`Namespace`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/Namespace.java) and register namespace key mapping via `DomFileDescription.registerNamespacePolicy()` from `DomFileDescription.initializeFileDescription()`.
|
||||||
|
|
||||||
### Generating DOM from Existing XSD
|
### Generating DOM from Existing XSD
|
||||||
|
|
||||||
@ -394,8 +394,8 @@ Follow these steps:
|
|||||||
|
|
||||||
_Plugin DevKit_ supports the following features for working with DOM related code:
|
_Plugin DevKit_ supports the following features for working with DOM related code:
|
||||||
|
|
||||||
* [`DomElement`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/DomElement.java) - provide implicit usages for all DOM-related methods defined in inheriting classes (to suppress "unused method" warning)
|
* [`DomElement`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/DomElement.java) - provide implicit usages for all DOM-related methods defined in inheriting classes (to suppress "unused method" warning)
|
||||||
* [`DomElementVisitor`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/DomElementVisitor.java) - provide implicit usages for all DOM-related visitor methods defined in inheriting classes (to suppress "unused method" warning)
|
* [`DomElementVisitor`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/DomElementVisitor.java) - provide implicit usages for all DOM-related visitor methods defined in inheriting classes (to suppress "unused method" warning)
|
||||||
|
|
||||||
## Working with the DOM
|
## Working with the DOM
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ Otherwise, it's a `PropertyBean` (all three interfaces extend `ManagedBean`).
|
|||||||
And when we write `List<ManagedBean> getManagedBeans()`, we expect to get not only a list where all elements are instances of the `ManagedBean` interface, but a list where each element is of a certain type, i.e. `MapEntriesBean`, `ListEntriesBean`, or `PropertyBean`.
|
And when we write `List<ManagedBean> getManagedBeans()`, we expect to get not only a list where all elements are instances of the `ManagedBean` interface, but a list where each element is of a certain type, i.e. `MapEntriesBean`, `ListEntriesBean`, or `PropertyBean`.
|
||||||
|
|
||||||
In such cases, one should decide which interface the DOM element should actually implement (according to the given tag).
|
In such cases, one should decide which interface the DOM element should actually implement (according to the given tag).
|
||||||
This is achieved by extending the [`TypeChooser`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/TypeChooser.java) abstract class:
|
This is achieved by extending the [`TypeChooser`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/TypeChooser.java) abstract class:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public abstract class TypeChooser {
|
public abstract class TypeChooser {
|
||||||
@ -466,15 +466,15 @@ Element validity is very important, since you cannot invoke any methods on inval
|
|||||||
|
|
||||||
DOM also has a kind of reflection, called "Generic Info".
|
DOM also has a kind of reflection, called "Generic Info".
|
||||||
One would use it to be able to access children by tag names directly, instead of calling getter methods.
|
One would use it to be able to access children by tag names directly, instead of calling getter methods.
|
||||||
See [`DomGenericInfo`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/reflect/DomGenericInfo.java) interface and `getGenericInfo()` methods in `DomElement` and `DomManager` for more information.
|
See [`DomGenericInfo`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/reflect/DomGenericInfo.java) interface and `getGenericInfo()` methods in `DomElement` and `DomManager` for more information.
|
||||||
There's also `DomElement.getXmlElementName()` method that returns the name of a corresponding tag or attribute.
|
There's also `DomElement.getXmlElementName()` method that returns the name of a corresponding tag or attribute.
|
||||||
|
|
||||||
#### Presentation
|
#### Presentation
|
||||||
|
|
||||||
<!-- TODO: using @Presentation -->
|
<!-- TODO: using @Presentation -->
|
||||||
|
|
||||||
`DomElement.getPresentation()` returns an instance of [`ElementPresentation`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ElementPresentation.java), an interface that knows presentable element type, name, and sometimes even its icon.
|
`DomElement.getPresentation()` returns an instance of [`ElementPresentation`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ElementPresentation.java), an interface that knows presentable element type, name, and sometimes even its icon.
|
||||||
Presentations are actually obtained from presentation factory objects that, like `ClassChooser`s, should be registered in [`ElementPresentationManager`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ElementPresentationManager.java) as early as possible.
|
Presentations are actually obtained from presentation factory objects that, like `ClassChooser`s, should be registered in [`ElementPresentationManager`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ElementPresentationManager.java) as early as possible.
|
||||||
You can specify type name and icon for all elements of some class, ways of getting type name, icon and presentable name for particular objects.
|
You can specify type name and icon for all elements of some class, ways of getting type name, icon and presentable name for particular objects.
|
||||||
When not specified, presentable name is taken from the object itself, if it contains a method annotated with `@NameValue` annotation, that returns `String` or `GenericValue`.
|
When not specified, presentable name is taken from the object itself, if it contains a method annotated with `@NameValue` annotation, that returns `String` or `GenericValue`.
|
||||||
If there's no such method, it will return `null`.
|
If there's no such method, it will return `null`.
|
||||||
@ -490,7 +490,7 @@ DOM supports the following events: tag value changed, element defined/undefined/
|
|||||||
|
|
||||||
The DOM supports error checking and highlighting.
|
The DOM supports error checking and highlighting.
|
||||||
It's based on annotations which you add to the DOM element in a special place (don't confuse these annotations with the ones of Java 5 - they are very different).
|
It's based on annotations which you add to the DOM element in a special place (don't confuse these annotations with the ones of Java 5 - they are very different).
|
||||||
You need to implement the [`DomElementAnnotator`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/highlighting/DomElementsAnnotator.java) interface, and override `DomFileDescription.createAnnotator()` method, and create this annotator there.
|
You need to implement the [`DomElementAnnotator`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/highlighting/DomElementsAnnotator.java) interface, and override `DomFileDescription.createAnnotator()` method, and create this annotator there.
|
||||||
In `DomElementsAnnotator.annotate(DomElement element, DomElementsProblemsHolder annotator)` you should report about all errors and warnings in the element's subtree to the annotator (`DomElementsProblemsHolder.createProblem()`).
|
In `DomElementsAnnotator.annotate(DomElement element, DomElementsProblemsHolder annotator)` you should report about all errors and warnings in the element's subtree to the annotator (`DomElementsProblemsHolder.createProblem()`).
|
||||||
You should return this annotator in the corresponding virtual method of the `DomFileDescription`.
|
You should return this annotator in the corresponding virtual method of the `DomFileDescription`.
|
||||||
|
|
||||||
@ -527,16 +527,16 @@ That's the core idea.
|
|||||||
Since creating such converters is quite boring, we've done it for you.
|
Since creating such converters is quite boring, we've done it for you.
|
||||||
You don't have to annotate reference getters at all, as the name resolution will be made automatically.
|
You don't have to annotate reference getters at all, as the name resolution will be made automatically.
|
||||||
Elements will be searched by name, and the name will be taken from the method annotated with `@NameValue`.
|
Elements will be searched by name, and the name will be taken from the method annotated with `@NameValue`.
|
||||||
The converter used is [`DomResolveConverter`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/DomResolveConverter.java).
|
The converter used is [`DomResolveConverter`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/DomResolveConverter.java).
|
||||||
Its constructor takes a parameter, so it can't be referenced in `@Convert` annotation, but its subclasses (if you create them) - can.
|
Its constructor takes a parameter, so it can't be referenced in `@Convert` annotation, but its subclasses (if you create them) - can.
|
||||||
If you still want to specify explicitly that your reference to `DomElement` should be resolved "model-wide", use the `@Resolve` annotation parameterized with the desired class.
|
If you still want to specify explicitly that your reference to `DomElement` should be resolved "model-wide", use the `@Resolve` annotation parameterized with the desired class.
|
||||||
The resolution scope will be taken from the `DomFileDescription.getResolveScope()`.
|
The resolution scope will be taken from the `DomFileDescription.getResolveScope()`.
|
||||||
|
|
||||||
In addition to the above, auto-resolving in DOM also provides some features in your XML text editor: error highlighting, completion, Find Usages, Rename Refactoring...
|
In addition to the above, auto-resolving in DOM also provides some features in your XML text editor: error highlighting, completion, Find Usages, Rename Refactoring...
|
||||||
Unresolved references will be highlighted, and even completed.
|
Unresolved references will be highlighted, and even completed.
|
||||||
If you want to create a custom converter and want to have this code insight with it, you should extend not only the [`Converter`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/Converter.java) but [`ResolvingConverter`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ResolvingConverter.java).
|
If you want to create a custom converter and want to have this code insight with it, you should extend not only the [`Converter`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/Converter.java) but [`ResolvingConverter`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ResolvingConverter.java).
|
||||||
It has one more method `getVariants()`, where you'll have to provide the collection consisting of all targets your reference may resolve to.
|
It has one more method `getVariants()`, where you'll have to provide the collection consisting of all targets your reference may resolve to.
|
||||||
Those familiar with [`PsiReference`](upsource:///platform/core-api/src/com/intellij/psi/PsiReference.java) will recognize the similarities here.
|
Those familiar with [`PsiReference`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiReference.java) will recognize the similarities here.
|
||||||
|
|
||||||
If you need to choose a `Converter` depending on other values (e.g. in a sibling/parent element) or any runtime condition (e.g. presence or version of a library), you can use `WrappingConverter`.
|
If you need to choose a `Converter` depending on other values (e.g. in a sibling/parent element) or any runtime condition (e.g. presence or version of a library), you can use `WrappingConverter`.
|
||||||
See also `GenericDomValueConvertersRegistry` for managing an extensible registry of available Converters to choose from.
|
See also `GenericDomValueConvertersRegistry` for managing an extensible registry of available Converters to choose from.
|
||||||
@ -635,7 +635,7 @@ Simply register it using `com.intellij.dom.implementation` extension point and D
|
|||||||
Many frameworks require a set of XML configuration files ("fileset") to work as one model, so resolving/navigation works across all related DOM files.
|
Many frameworks require a set of XML configuration files ("fileset") to work as one model, so resolving/navigation works across all related DOM files.
|
||||||
Depending on implementation/plugin, providing filesets implicitly (using existing framework's setup in a project) or via user configuration (usually via dedicated `Facet`) can be achieved.
|
Depending on implementation/plugin, providing filesets implicitly (using existing framework's setup in a project) or via user configuration (usually via dedicated `Facet`) can be achieved.
|
||||||
|
|
||||||
Extend [`DomModelFactory`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/model/impl/DomModelFactory.java) (or [`BaseDomModelFactory`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/model/impl/BaseDomModelFactory.java) for non-`Module` scope) and provide implementation of your `DomModel`.
|
Extend [`DomModelFactory`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/model/impl/DomModelFactory.java) (or [`BaseDomModelFactory`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/model/impl/BaseDomModelFactory.java) for non-`Module` scope) and provide implementation of your `DomModel`.
|
||||||
Usually you will want to add searcher/utility methods to work with your `DomModel` implementation.
|
Usually you will want to add searcher/utility methods to work with your `DomModel` implementation.
|
||||||
Example can be found in Struts 2 plugin (package `com.intellij.struts2.dom.struts.model`).
|
Example can be found in Struts 2 plugin (package `com.intellij.struts2.dom.struts.model`).
|
||||||
|
|
||||||
@ -660,8 +660,8 @@ Set and increase `stubVersion` of `com.intellij.dom.fileMetaData` extension when
|
|||||||
All forms that deal with DOM are organized in a special way.
|
All forms that deal with DOM are organized in a special way.
|
||||||
They support two main things: getting data from XML into the UI, and saving UI data to XML.
|
They support two main things: getting data from XML into the UI, and saving UI data to XML.
|
||||||
The former is called resetting, the latter - committing.
|
The former is called resetting, the latter - committing.
|
||||||
There's [`Committable`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/Committable.java) interface that has corresponding methods: `commit()` and `reset()`.
|
There's [`Committable`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/Committable.java) interface that has corresponding methods: `commit()` and `reset()`.
|
||||||
There's also a way of structuring your forms into smaller parts, namely the Composite pattern: [`CompositeCommittable`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/CompositeCommittable.java).
|
There's also a way of structuring your forms into smaller parts, namely the Composite pattern: [`CompositeCommittable`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/CompositeCommittable.java).
|
||||||
Methods `commit()` and `reset()` are invoked automatically on editor tab switch or undo.
|
Methods `commit()` and `reset()` are invoked automatically on editor tab switch or undo.
|
||||||
So you only need to ensure that all your Swing structure is organized in a tree of `CompositeCommittable`, and all the hard work will be done by the IDE.
|
So you only need to ensure that all your Swing structure is organized in a tree of `CompositeCommittable`, and all the hard work will be done by the IDE.
|
||||||
|
|
||||||
@ -686,13 +686,13 @@ With simple controls, you can edit `GenericDomValue`: simple text, class names,
|
|||||||
These controls take a special object as a constructor parameter.
|
These controls take a special object as a constructor parameter.
|
||||||
This object should implement the `DomWrapper` interface that knows how to set/get values to/from a DOM model.
|
This object should implement the `DomWrapper` interface that knows how to set/get values to/from a DOM model.
|
||||||
|
|
||||||
We have three major DomWrapper's: [`DomFixedWrapper<T>`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/DomFixedWrapper.java) redirecting calls to
|
We have three major DomWrapper's: [`DomFixedWrapper<T>`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/DomFixedWrapper.java) redirecting calls to
|
||||||
[`GenericDomValue<T>`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/GenericDomValue.java),
|
[`GenericDomValue<T>`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/GenericDomValue.java),
|
||||||
[`DomStringWrapper`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/DomStringWrapper.java)
|
[`DomStringWrapper`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/DomStringWrapper.java)
|
||||||
redirecting calls to string accessors of
|
redirecting calls to string accessors of
|
||||||
[`GenericDomValue`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/GenericDomValue.java),
|
[`GenericDomValue`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/GenericDomValue.java),
|
||||||
and [`DomCollectionWrapper`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/DomCollectionWrapper.java)
|
and [`DomCollectionWrapper`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/DomCollectionWrapper.java)
|
||||||
that gets/sets values of the first element of the given [`GenericDomValue`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/GenericDomValue.java) collection.
|
that gets/sets values of the first element of the given [`GenericDomValue`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/GenericDomValue.java) collection.
|
||||||
Some controls (those having a text field as part of itself) take an additional boolean constructor parameter - _commitOnEveryChange_, whose meaning is evident from the name.
|
Some controls (those having a text field as part of itself) take an additional boolean constructor parameter - _commitOnEveryChange_, whose meaning is evident from the name.
|
||||||
We don't recommend using it anywhere except small dialogs, because committing on every change slows down the system significantly.
|
We don't recommend using it anywhere except small dialogs, because committing on every change slows down the system significantly.
|
||||||
|
|
||||||
@ -788,7 +788,7 @@ Editors are more complicated, but they closely resemble simple DOM controls.
|
|||||||
`DomUIFactory.createCellEditor()` will create any of them automatically (including the editor for `PsiClass`), so that you won't need to think about which one to select every time.
|
`DomUIFactory.createCellEditor()` will create any of them automatically (including the editor for `PsiClass`), so that you won't need to think about which one to select every time.
|
||||||
|
|
||||||
Collection control is a complex control, so it's bound to a complex Swing component.
|
Collection control is a complex control, so it's bound to a complex Swing component.
|
||||||
It's called [`DomTableView`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/DomTableView.java).
|
It's called [`DomTableView`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/DomTableView.java).
|
||||||
It has a toolbar (you can override `DomTableView.getToolbarPosition()` to customize its location), with Add and Delete buttons.
|
It has a toolbar (you can override `DomTableView.getToolbarPosition()` to customize its location), with Add and Delete buttons.
|
||||||
If you want, you may specify custom addition actions in `DomCollectionControl.createAdditionActions()` (it's recommended to extend `ControlAddAction`).
|
If you want, you may specify custom addition actions in `DomCollectionControl.createAdditionActions()` (it's recommended to extend `ControlAddAction`).
|
||||||
If there is only one addition action, it will be invoked after pressing the Add button; if there are many, then a popup menu will be displayed.
|
If there is only one addition action, it will be invoked after pressing the Add button; if there are many, then a popup menu will be displayed.
|
||||||
@ -811,7 +811,7 @@ If you want to change this behavior, override `DomTableView.allowMultipleRowsSel
|
|||||||
### UI Organization
|
### UI Organization
|
||||||
|
|
||||||
The easiest way to create a DOM-based UI form is to extend the
|
The easiest way to create a DOM-based UI form is to extend the
|
||||||
[`BasicDomElementComponent`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/BasicDomElementComponent.java) class.
|
[`BasicDomElementComponent`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/BasicDomElementComponent.java) class.
|
||||||
This will require you to pass some DOM element to the constructor.
|
This will require you to pass some DOM element to the constructor.
|
||||||
Then you bind an IntelliJ IDEA GUI Designer form to your subclass and design a beautiful form there.
|
Then you bind an IntelliJ IDEA GUI Designer form to your subclass and design a beautiful form there.
|
||||||
You will surely want to bind some controls to DOM UI, in which case you should of course ensure that they have the right types.
|
You will surely want to bind some controls to DOM UI, in which case you should of course ensure that they have the right types.
|
||||||
@ -849,12 +849,12 @@ All the fields here are now bound to the controls in the GUI form.
|
|||||||
|
|
||||||
Very often, you'll have to create your own file editor.
|
Very often, you'll have to create your own file editor.
|
||||||
Then, to use all the binding and undo functionality, it's suggested to inherit your
|
Then, to use all the binding and undo functionality, it's suggested to inherit your
|
||||||
[`FileEditorProvider`](upsource:///platform/analysis-api/src/com/intellij/openapi/fileEditor/FileEditorProvider.java)
|
[`FileEditorProvider`](%gh-ic%/platform/analysis-api/src/com/intellij/openapi/fileEditor/FileEditorProvider.java)
|
||||||
from
|
from
|
||||||
[`PerspectiveFileEditorProvider`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/PerspectiveFileEditorProvider.java), create an instance of
|
[`PerspectiveFileEditorProvider`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/PerspectiveFileEditorProvider.java), create an instance of
|
||||||
[`DomFileEditor`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/DomFileEditor.java)
|
[`DomFileEditor`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/DomFileEditor.java)
|
||||||
there, and pass a
|
there, and pass a
|
||||||
[`BasicDomElementComponent`](upsource:///xml/dom-openapi/src/com/intellij/util/xml/ui/BasicDomElementComponent.java).
|
[`BasicDomElementComponent`](%gh-ic%/xml/dom-openapi/src/com/intellij/util/xml/ui/BasicDomElementComponent.java).
|
||||||
To easily create an editor with a caption at the top, like in our EJB and JSF, you may use the static method `DomFileEditor.createDomFileEditor()`.
|
To easily create an editor with a caption at the top, like in our EJB and JSF, you may use the static method `DomFileEditor.createDomFileEditor()`.
|
||||||
`DomFileEditor` automatically listens to all changes in the document corresponding to the given DOM element, and therefore refreshes your component on undo.
|
`DomFileEditor` automatically listens to all changes in the document corresponding to the given DOM element, and therefore refreshes your component on undo.
|
||||||
If you want to listen to changes in additional documents, use the methods `addWatchedDocument()`, `removeWatchedDocument()`, `addWatchedElement()`, `removeWatchedElement()` in `DomFileEditor`.
|
If you want to listen to changes in additional documents, use the methods `addWatchedDocument()`, `removeWatchedDocument()`, `addWatchedElement()`, `removeWatchedElement()` in `DomFileEditor`.
|
||||||
@ -870,8 +870,8 @@ You are welcome to post your questions and comments to our [Open API and Plugin
|
|||||||
The following bundled open-source plugins make (heavy) use of DOM:
|
The following bundled open-source plugins make (heavy) use of DOM:
|
||||||
|
|
||||||
- [Android](https://github.com/JetBrains/android)
|
- [Android](https://github.com/JetBrains/android)
|
||||||
- [Ant](upsource:///plugins/ant)
|
- [Ant](%gh-ic%/plugins/ant)
|
||||||
- [Plugin DevKit](upsource:///plugins/devkit/devkit-core)
|
- [Plugin DevKit](%gh-ic%/plugins/devkit/devkit-core)
|
||||||
- [Maven](upsource:///plugins/maven)
|
- [Maven](%gh-ic%/plugins/maven)
|
||||||
- [Struts 2](https://github.com/JetBrains/intellij-plugins/tree/master/struts2) (Ultimate Edition)
|
- [Struts 2](https://github.com/JetBrains/intellij-plugins/tree/master/struts2) (Ultimate Edition)
|
||||||
- [IntelliJ Platform Explorer - OSS plugins using DOM](https://jb.gg/ipe?extensions=com.intellij.dom.fileMetaData)
|
- [IntelliJ Platform Explorer - OSS plugins using DOM](https://jb.gg/ipe?extensions=com.intellij.dom.fileMetaData)
|
||||||
|
@ -29,11 +29,11 @@ These can be useful to locate the underlying implementation, related Action, etc
|
|||||||
|
|
||||||
| Type | Place | Properties |
|
| Type | Place | Properties |
|
||||||
|--------------------------------------------------------------------------------------------------------|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|--------------------------------------------------------------------------------------------------------|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [`AnAction`](basic_action_system.md) | Action Button<br/>Menu Item | `Action` - [`AnAction`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java) implementation<br/>`Action ID` - Action `id`<br/>`Action Plugin ID` - contributing plugin |
|
| [`AnAction`](basic_action_system.md) | Action Button<br/>Menu Item | `Action` - [`AnAction`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java) implementation<br/>`Action ID` - Action `id`<br/>`Action Plugin ID` - contributing plugin |
|
||||||
| [`ActionToolbar`](basic_action_system.md) | Action Toolbar | `Toolbar Group` - Action Group ID<br/>`All Groups` - contained Action Group IDs |
|
| [`ActionToolbar`](basic_action_system.md) | Action Toolbar | `Toolbar Group` - Action Group ID<br/>`All Groups` - contained Action Group IDs |
|
||||||
| [`DialogWrapper`](dialog_wrapper.md) | Modal Dialog | `dialogWrapperClass` - [`DialogWrapper`](upsource:///platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java) implementation |
|
| [`DialogWrapper`](dialog_wrapper.md) | Modal Dialog | `dialogWrapperClass` - [`DialogWrapper`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java) implementation |
|
||||||
| [`GutterMark`](upsource:///platform/editor-ui-api/src/com/intellij/codeInsight/daemon/GutterMark.java) | Editor Gutter Icon | `gutter renderer` - [`GutterMark`](upsource:///platform/editor-ui-api/src/com/intellij/codeInsight/daemon/GutterMark.java) implementation |
|
| [`GutterMark`](%gh-ic%/platform/editor-ui-api/src/com/intellij/codeInsight/daemon/GutterMark.java) | Editor Gutter Icon | `gutter renderer` - [`GutterMark`](%gh-ic%/platform/editor-ui-api/src/com/intellij/codeInsight/daemon/GutterMark.java) implementation |
|
||||||
| [`IntentionAction`/`QuickFix`](code_inspections_and_intentions.md) | Popup Menu in Editor | `intention action`/`quick fix` - [`IntentionAction`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java) / [`QuickFix`](upsource:///platform/analysis-api/src/com/intellij/codeInspection/QuickFix.java) implementation |
|
| [`IntentionAction`/`QuickFix`](code_inspections_and_intentions.md) | Popup Menu in Editor | `intention action`/`quick fix` - [`IntentionAction`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java) / [`QuickFix`](%gh-ic%/platform/analysis-api/src/com/intellij/codeInspection/QuickFix.java) implementation |
|
||||||
| [`Tree`](lists_and_trees.md) | Tree | `treeModelClass` - `javax.swing.tree.TreeModel` implementation |
|
| [`Tree`](lists_and_trees.md) | Tree | `treeModelClass` - `javax.swing.tree.TreeModel` implementation |
|
||||||
|
|
||||||
Custom Swing components can also provide additional properties via [`UiInspectorContextProvider`](upsource:///platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorContextProvider.java) (2020.1 and later).
|
Custom Swing components can also provide additional properties via [`UiInspectorContextProvider`](%gh-ic%/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorContextProvider.java) (2020.1 and later).
|
||||||
|
@ -70,7 +70,7 @@ myBrowser.openDevTools();
|
|||||||
|
|
||||||
### JBCefApp
|
### JBCefApp
|
||||||
|
|
||||||
[`JBCefApp`](upsource:///platform/platform-api/src/com/intellij/ui/jcef/JBCefApp.java)
|
[`JBCefApp`](%gh-ic%/platform/platform-api/src/com/intellij/ui/jcef/JBCefApp.java)
|
||||||
|
|
||||||
Performs JCEF auto-initialization, manages its lifecycle, and provides `JBCefClient` instances.
|
Performs JCEF auto-initialization, manages its lifecycle, and provides `JBCefClient` instances.
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ To avoid the above problems, the IDE should be run with the bundled JetBrains Ru
|
|||||||
|
|
||||||
### JBCefClient
|
### JBCefClient
|
||||||
|
|
||||||
[`JBCefClient`](upsource:///platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java)
|
[`JBCefClient`](%gh-ic%/platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java)
|
||||||
|
|
||||||
Is tied to every browser component explicitly or implicitly.
|
Is tied to every browser component explicitly or implicitly.
|
||||||
Used for adding handlers to the associated browser.
|
Used for adding handlers to the associated browser.
|
||||||
@ -103,7 +103,7 @@ If a client was created explicitly, it should be [disposed](disposers.md) by the
|
|||||||
|
|
||||||
### JBCefBrowser
|
### JBCefBrowser
|
||||||
|
|
||||||
[`JBCefBrowser`](upsource:///platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowser.java)
|
[`JBCefBrowser`](%gh-ic%/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowser.java)
|
||||||
|
|
||||||
Provides the browser UI component:
|
Provides the browser UI component:
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ myPanel.add(new JBCefBrowser("https://www.jetbrains.com").getComponent());
|
|||||||
|
|
||||||
### JBCefJSQuery
|
### JBCefJSQuery
|
||||||
|
|
||||||
[`JBCefJSQuery`](upsource:///platform/platform-api/src/com/intellij/ui/jcef/JBCefJSQuery.java)
|
[`JBCefJSQuery`](%gh-ic%/platform/platform-api/src/com/intellij/ui/jcef/JBCefJSQuery.java)
|
||||||
|
|
||||||
Provides JS query callback mechanism.
|
Provides JS query callback mechanism.
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ Manages all subscriptions for particular client within particular bus.
|
|||||||
* it's possible to specify *default handler* and subscribe to the target topic without explicitly provided callback.
|
* it's possible to specify *default handler* and subscribe to the target topic without explicitly provided callback.
|
||||||
Connection will use that *default handler* when storing *(topic-handler)* mapping;
|
Connection will use that *default handler* when storing *(topic-handler)* mapping;
|
||||||
* it's possible to explicitly release acquired resources (*disconnect()* method).
|
* it's possible to explicitly release acquired resources (*disconnect()* method).
|
||||||
Also it can be plugged to standard semi-automatic disposing ([`Disposable`](upsource:///platform/util/src/com/intellij/openapi/Disposable.java));
|
Also it can be plugged to standard semi-automatic disposing ([`Disposable`](%gh-ic%/platform/util/src/com/intellij/openapi/Disposable.java));
|
||||||
|
|
||||||
### Putting Altogether
|
### Putting Altogether
|
||||||
|
|
||||||
@ -111,9 +111,9 @@ public void doChange(Context context) {
|
|||||||
|
|
||||||
*Existing resources*
|
*Existing resources*
|
||||||
|
|
||||||
* *MessageBus* instances are available via [`ComponentManager.getMessageBus()`](upsource:///platform/extensions/src/com/intellij/openapi/components/ComponentManager.java)
|
* *MessageBus* instances are available via [`ComponentManager.getMessageBus()`](%gh-ic%/platform/extensions/src/com/intellij/openapi/components/ComponentManager.java)
|
||||||
Many standard interfaces implement a message bus, e.g., [`Application`](upsource:///platform/core-api/src/com/intellij/openapi/application/Application.java) and [`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java).
|
Many standard interfaces implement a message bus, e.g., [`Application`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/Application.java) and [`Project`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/Project.java).
|
||||||
* A number of public topics are used by the IntelliJ Platform, e.g., [`AppTopics`](upsource:///platform/platform-api/src/com/intellij/AppTopics.java), [`ProjectTopics`](upsource:///platform/projectModel-api/src/com/intellij/ProjectTopics.java), etc.
|
* A number of public topics are used by the IntelliJ Platform, e.g., [`AppTopics`](%gh-ic%/platform/platform-api/src/com/intellij/AppTopics.java), [`ProjectTopics`](%gh-ic%/platform/projectModel-api/src/com/intellij/ProjectTopics.java), etc.
|
||||||
So, it's possible to subscribe to them in order to receive information about the processing.
|
So, it's possible to subscribe to them in order to receive information about the processing.
|
||||||
|
|
||||||
## Broadcasting
|
## Broadcasting
|
||||||
|
@ -14,7 +14,7 @@ Currently, the most recent caret is considered the primary one.
|
|||||||
|
|
||||||
## Core Functionality
|
## Core Functionality
|
||||||
|
|
||||||
Core logic related to multi-caret implementation such as accessing currently existing carets, adding and removing carets, is available via [`CaretModel`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java) interface, some changes also have been made in [`SelectionModel`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/SelectionModel.java) interface.
|
Core logic related to multi-caret implementation such as accessing currently existing carets, adding and removing carets, is available via [`CaretModel`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java) interface, some changes also have been made in [`SelectionModel`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/editor/SelectionModel.java) interface.
|
||||||
Check Javadoc of those interfaces for details.
|
Check Javadoc of those interfaces for details.
|
||||||
|
|
||||||
Notable changes from old behaviour:
|
Notable changes from old behaviour:
|
||||||
@ -31,7 +31,7 @@ Notable changes from old behaviour:
|
|||||||
|
|
||||||
### EditorAction and EditorActionHandler
|
### EditorAction and EditorActionHandler
|
||||||
|
|
||||||
When [`EditorActionHandler`](upsource:///platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java) is invoked, an additional parameter will be passed to it — a caret instance on which it should operate, or `null` if it's invoked without any caret context.
|
When [`EditorActionHandler`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java) is invoked, an additional parameter will be passed to it — a caret instance on which it should operate, or `null` if it's invoked without any caret context.
|
||||||
If the handler invokes another handler (delegate handler for the same `actionId` or a completely unrelated handler), that parameter should normally be passed to the delegate unchanged (unless no context caret has been provided to the handler, but it needs to invoke another handler on a specific caret).
|
If the handler invokes another handler (delegate handler for the same `actionId` or a completely unrelated handler), that parameter should normally be passed to the delegate unchanged (unless no context caret has been provided to the handler, but it needs to invoke another handler on a specific caret).
|
||||||
Of course, the handler can just ignore the caret parameter if its functionality is not related to caret/selection position.
|
Of course, the handler can just ignore the caret parameter if its functionality is not related to caret/selection position.
|
||||||
|
|
||||||
@ -56,23 +56,23 @@ At the moment there's no need to make any changes in the handlers to support mul
|
|||||||
|
|
||||||
### TypedActionHandler, TypedHandlerDelegate
|
### TypedActionHandler, TypedHandlerDelegate
|
||||||
|
|
||||||
[`TypedActionHandler`](upsource:///platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedActionHandler.java) and [`TypedHandlerDelegate`](upsource:///platform/lang-api/src/com/intellij/codeInsight/editorActions/TypedHandlerDelegate.java) implementations are invoked only once for each typed character.
|
[`TypedActionHandler`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedActionHandler.java) and [`TypedHandlerDelegate`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/editorActions/TypedHandlerDelegate.java) implementations are invoked only once for each typed character.
|
||||||
If those handlers need to support multiple carets, they will need to implement that explicitly.
|
If those handlers need to support multiple carets, they will need to implement that explicitly.
|
||||||
|
|
||||||
[`EditorModificationUtil`](upsource:///platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java).
|
[`EditorModificationUtil`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java).
|
||||||
`typeInStringAtCaretHonorMultipleCarets()` method is available to do the most common task in this case — inserting the same text into all caret positions and/or moving all carets relatively to their current position.
|
`typeInStringAtCaretHonorMultipleCarets()` method is available to do the most common task in this case — inserting the same text into all caret positions and/or moving all carets relatively to their current position.
|
||||||
Examples of its usage:
|
Examples of its usage:
|
||||||
|
|
||||||
* [`TypedAction`](upsource:///platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedAction.java).
|
* [`TypedAction`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedAction.java).
|
||||||
* [`XmlGtTypedHandler`](upsource:///xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.java).
|
* [`XmlGtTypedHandler`](%gh-ic%/xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.java).
|
||||||
|
|
||||||
> Starting from version 14, [`TypedHandlerDelegate`](upsource:///platform/lang-api/src/com/intellij/codeInsight/editorActions/TypedHandlerDelegate.java) implementations are invoked automatically for each caret.
|
> Starting from version 14, [`TypedHandlerDelegate`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/editorActions/TypedHandlerDelegate.java) implementations are invoked automatically for each caret.
|
||||||
> If one wants to implement custom multicaret behaviour on typing, [`TypedActionHandler`](upsource:///platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedActionHandler.java) needs to be provided instead.
|
> If one wants to implement custom multicaret behaviour on typing, [`TypedActionHandler`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedActionHandler.java) needs to be provided instead.
|
||||||
>
|
>
|
||||||
{type="note"}
|
{type="note"}
|
||||||
|
|
||||||
## Code Insight Actions
|
## Code Insight Actions
|
||||||
|
|
||||||
Existing actions inheriting from [`CodeInsightAction`](upsource:///platform/lang-api/src/com/intellij/codeInsight/actions/CodeInsightAction.java) will work for primary caret only.
|
Existing actions inheriting from [`CodeInsightAction`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/actions/CodeInsightAction.java) will work for primary caret only.
|
||||||
To support multiple carets, one should subclass [`MultiCaretCodeInsightAction`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightAction.java) instead.
|
To support multiple carets, one should subclass [`MultiCaretCodeInsightAction`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightAction.java) instead.
|
||||||
Each caret might have a different editor and PSI instance, so using the old API is not possible.
|
Each caret might have a different editor and PSI instance, so using the old API is not possible.
|
||||||
|
@ -14,7 +14,7 @@ Please see [Facet Basics](https://github.com/JetBrains/intellij-sdk-code-samples
|
|||||||
## Working with Facets
|
## Working with Facets
|
||||||
|
|
||||||
### Managing Facets
|
### Managing Facets
|
||||||
To create, search and access the list of facets for a module use [`FacetManager`](upsource:///platform/lang-core/src/com/intellij/facet/FacetManager.java).
|
To create, search and access the list of facets for a module use [`FacetManager`](%gh-ic%/platform/lang-core/src/com/intellij/facet/FacetManager.java).
|
||||||
|
|
||||||
### Facet-Based Tool Window
|
### Facet-Based Tool Window
|
||||||
A [tool window](tool_windows.md) dependent on the existence of given facet(s) can be registered via `com.intellij.facet.toolWindow` extension point.
|
A [tool window](tool_windows.md) dependent on the existence of given facet(s) can be registered via `com.intellij.facet.toolWindow` extension point.
|
||||||
|
@ -14,7 +14,7 @@ For more information about libraries, refer to [Libraries](https://www.jetbrains
|
|||||||
A particular type of programmatically defined libraries is [Predefined Libraries](#predefined-libraries).
|
A particular type of programmatically defined libraries is [Predefined Libraries](#predefined-libraries).
|
||||||
|
|
||||||
## Accessing Libraries and Jars
|
## Accessing Libraries and Jars
|
||||||
Package [`com.intellij.openapi.roots.libraries`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/libraries) provides functionality for working with project libraries and JAR files.
|
Package [`com.intellij.openapi.roots.libraries`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/libraries) provides functionality for working with project libraries and JAR files.
|
||||||
|
|
||||||
### Getting a List of Libraries a Module Depends On
|
### Getting a List of Libraries a Module Depends On
|
||||||
To get the list of libraries that a module depends on, use `OrderEnumerator.forEachLibrary` as follows.
|
To get the list of libraries that a module depends on, use `OrderEnumerator.forEachLibrary` as follows.
|
||||||
@ -31,18 +31,18 @@ Messages.showInfoMessage(StringUtil.join(libraryNames, "\n"), "Libraries in Modu
|
|||||||
This sample code outputs a list of libraries that the given module depends on.
|
This sample code outputs a list of libraries that the given module depends on.
|
||||||
|
|
||||||
### Getting a List of All Libraries
|
### Getting a List of All Libraries
|
||||||
To manage the lists of application and project libraries, use [`LibraryTable`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/libraries/LibraryTable.java).
|
To manage the lists of application and project libraries, use [`LibraryTable`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/LibraryTable.java).
|
||||||
The list of application-level library tables is accessed by calling [`LibraryTablesRegistrar.getLibraryTable()`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/libraries/LibraryTablesRegistrar.java), whereas the list of project-level library tables is accessed via `LibraryTablesRegistrar.getLibraryTable(Project)`.
|
The list of application-level library tables is accessed by calling [`LibraryTablesRegistrar.getLibraryTable()`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/LibraryTablesRegistrar.java), whereas the list of project-level library tables is accessed via `LibraryTablesRegistrar.getLibraryTable(Project)`.
|
||||||
Once you have a `LibraryTable`, you can get the libraries in it by calling `LibraryTable.getLibraries()`.
|
Once you have a `LibraryTable`, you can get the libraries in it by calling `LibraryTable.getLibraries()`.
|
||||||
|
|
||||||
To get the list of all module libraries defined in a given module, use API from [`OrderEntryUtil`](upsource:///platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java):
|
To get the list of all module libraries defined in a given module, use API from [`OrderEntryUtil`](%gh-ic%/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java):
|
||||||
|
|
||||||
```java
|
```java
|
||||||
OrderEntryUtil.getModuleLibraries(ModuleRootManager.getInstance(module));
|
OrderEntryUtil.getModuleLibraries(ModuleRootManager.getInstance(module));
|
||||||
```
|
```
|
||||||
|
|
||||||
### Getting the Library Content
|
### Getting the Library Content
|
||||||
[`Library`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/libraries/Library.java) provides the `getUrls()` method you can use to get a list of source roots and classes the library includes.
|
[`Library`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/Library.java) 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:
|
To clarify, consider the following code snippet:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@ -69,8 +69,8 @@ To create a library, perform the following steps:
|
|||||||
* Add contents to the library (see below)
|
* Add contents to the library (see below)
|
||||||
* For a module-level library, commit the modifiable model returned by `ModuleRootManager.getInstance(module).getModifiableModel()`.
|
* For a module-level library, commit the modifiable model returned by `ModuleRootManager.getInstance(module).getModifiableModel()`.
|
||||||
|
|
||||||
For module-level libraries, you can also use simplified APIs in the [`ModuleRootModificationUtil`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java) class to add a library with a single API call.
|
For module-level libraries, you can also use simplified APIs in the [`ModuleRootModificationUtil`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java) class to add a library with a single API call.
|
||||||
You can find an example of using these APIs in the [project_model](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/project_model/src/main/java/org/intellij/sdk/project/model/ModificationAction.java) code sample.
|
You can find an example of using these APIs in the [project_model](%gh-sdk-samples%/project_model/src/main/java/org/intellij/sdk/project/model/ModificationAction.java) code sample.
|
||||||
|
|
||||||
### Adding Contents or Modifying a Library
|
### Adding Contents or Modifying a Library
|
||||||
To add or change the roots of a library, you need to perform the following steps:
|
To add or change the roots of a library, you need to perform the following steps:
|
||||||
@ -83,7 +83,7 @@ To add or change the roots of a library, you need to perform the following steps
|
|||||||
Use `ModuleRootModificationUtil.addDependency(Module, Library)` from under a [write action](general_threading_rules.md#read-write-lock).
|
Use `ModuleRootModificationUtil.addDependency(Module, Library)` from under a [write action](general_threading_rules.md#read-write-lock).
|
||||||
|
|
||||||
### Checking Belonging to a Library
|
### Checking Belonging to a Library
|
||||||
The [`ProjectFileIndex`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) interface implements a number of methods you can use to check whether the specified file belongs to the project library classes or library sources.
|
The [`ProjectFileIndex`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) 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:
|
You can use the following methods:
|
||||||
|
|
||||||
* To check if a specified virtual file is a compiled class file use
|
* To check if a specified virtual file is a compiled class file use
|
||||||
@ -99,13 +99,13 @@ You can use the following methods:
|
|||||||
ProjectFileIndex.isInLibrarySource(virtualFileorDirectory)
|
ProjectFileIndex.isInLibrarySource(virtualFileorDirectory)
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [project_model](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/project_model/src/main/java/org/intellij/sdk/project/model/ProjectFileIndexSampleAction.java) to see how the method mentioned above can be applied.
|
See the [project_model](%gh-sdk-samples%/project_model/src/main/java/org/intellij/sdk/project/model/ProjectFileIndexSampleAction.java) to see how the method mentioned above can be applied.
|
||||||
|
|
||||||
More details on libraries can be found in the [plugin_model](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/project_model/src/main/java/org/intellij/sdk/project/model/LibrariesAction.java) code sample.
|
More details on libraries can be found in the [plugin_model](%gh-sdk-samples%/project_model/src/main/java/org/intellij/sdk/project/model/LibrariesAction.java) code sample.
|
||||||
|
|
||||||
## Predefined Libraries
|
## Predefined Libraries
|
||||||
EP: `com.intellij.additionalLibraryRootsProvider`
|
EP: `com.intellij.additionalLibraryRootsProvider`
|
||||||
|
|
||||||
[`AdditionalLibraryRootsProvider`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/AdditionalLibraryRootsProvider.java)
|
[`AdditionalLibraryRootsProvider`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/AdditionalLibraryRootsProvider.java)
|
||||||
Allows providing synthetic/predefined libraries ([`SyntheticLibrary`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/SyntheticLibrary.java)) in a project without exposing them in the model.
|
Allows providing synthetic/predefined libraries ([`SyntheticLibrary`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/SyntheticLibrary.java)) in a project without exposing them in the model.
|
||||||
By default, they're also hidden from UI.
|
By default, they're also hidden from UI.
|
||||||
|
@ -24,13 +24,13 @@ Plugins can store additional data associated with a module by creating facets or
|
|||||||
|
|
||||||
The IntelliJ Platform provides a number of classes and interfaces you can use to work with modules:
|
The IntelliJ Platform provides a number of classes and interfaces you can use to work with modules:
|
||||||
|
|
||||||
* [`Module`](upsource:///platform/core-api/src/com/intellij/openapi/module/Module.java)
|
* [`Module`](%gh-ic%/platform/core-api/src/com/intellij/openapi/module/Module.java)
|
||||||
* [`ModuleUtil`](upsource:///platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java)
|
* [`ModuleUtil`](%gh-ic%/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java)
|
||||||
* [`ModuleManager`](upsource:///platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java)
|
* [`ModuleManager`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java)
|
||||||
* [`ModuleRootManager`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java)
|
* [`ModuleRootManager`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java)
|
||||||
* [`ModuleRootModel`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModel.java)
|
* [`ModuleRootModel`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModel.java)
|
||||||
* [`ModifiableModuleModel`](upsource:///platform/projectModel-api/src/com/intellij/openapi/module/ModifiableModuleModel.java)
|
* [`ModifiableModuleModel`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/module/ModifiableModuleModel.java)
|
||||||
* [`ModifiableRootModel`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java)
|
* [`ModifiableRootModel`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java)
|
||||||
|
|
||||||
This section discusses how to complete some common tasks related to management of modules.
|
This section discusses how to complete some common tasks related to management of modules.
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ Use the `ModuleManager.getModules()` method.
|
|||||||
_Order entries_ include SDK, libraries and other modules the module uses.
|
_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](https://www.jetbrains.com/help/idea/dependencies-tab.html) tab of the *Project Structure* dialog box.
|
With the IntelliJ IDEA UI, you can view order entries for a module on the [Dependencies](https://www.jetbrains.com/help/idea/dependencies-tab.html) tab of the *Project Structure* dialog box.
|
||||||
|
|
||||||
To explore the [module dependencies](https://www.jetbrains.com/help/idea/dependencies-tab.html), use the [`OrderEnumerator`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/OrderEnumerator.java) class.
|
To explore the [module dependencies](https://www.jetbrains.com/help/idea/dependencies-tab.html), use the [`OrderEnumerator`](%gh-ic%/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:
|
The following code snippet illustrates how you can get classpath (classes root of all dependencies) for a module:
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ VirtualFile[] roots = ModuleRootManager.getInstance(module).orderEntries().class
|
|||||||
### How do I get the SDK the module uses?
|
### How do I get the SDK the module uses?
|
||||||
|
|
||||||
Use the `ModuleRootManager.getSdk()` method.
|
Use the `ModuleRootManager.getSdk()` method.
|
||||||
This method returns a value of the [`Sdk`](upsource:///platform/projectModel-api/src/com/intellij/openapi/projectRoots/Sdk.java) type.
|
This method returns a value of the [`Sdk`](%gh-ic%/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:
|
The following code snippet illustrates how you can get detailed information on SDK the specified module uses:
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ String moduleName = module == null ? "Module not found" : module.getName();
|
|||||||
|
|
||||||
### Accessing Module Roots
|
### Accessing Module Roots
|
||||||
|
|
||||||
Information about module roots can be accessed via [`ModuleRootManager`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java).
|
Information about module roots can be accessed via [`ModuleRootManager`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java).
|
||||||
For example, the following snippet shows how to access the content roots of a module:
|
For example, the following snippet shows how to access the content roots of a module:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@ -123,7 +123,7 @@ VirtualFile moduleSourceRoot = ProjectRootManager.getInstance(project).getFileIn
|
|||||||
|
|
||||||
### Java: Compiler Output Properties
|
### Java: Compiler Output Properties
|
||||||
|
|
||||||
Obtain [`CompilerModuleExtension`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/CompilerModuleExtension.java) for given `Module` instance to access <control>Compiler Output</control> path related properties.
|
Obtain [`CompilerModuleExtension`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/CompilerModuleExtension.java) for given `Module` instance to access <control>Compiler Output</control> path related properties.
|
||||||
|
|
||||||
## Receiving Notifications About Module Changes
|
## Receiving Notifications About Module Changes
|
||||||
|
|
||||||
|
@ -19,13 +19,13 @@ Note that direct access to project files isn't required to load or save settings
|
|||||||
See [Persisting State of Components](persisting_state_of_components.md) for more information.
|
See [Persisting State of Components](persisting_state_of_components.md) for more information.
|
||||||
|
|
||||||
To work with projects and project files, use the following classes and interfaces:
|
To work with projects and project files, use the following classes and interfaces:
|
||||||
* [`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java)
|
* [`Project`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/Project.java)
|
||||||
* [`ProjectRootManager`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java)
|
* [`ProjectRootManager`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java)
|
||||||
* [`ProjectManager`](upsource:///platform/projectModel-api/src/com/intellij/openapi/project/ProjectManager.java)
|
* [`ProjectManager`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/project/ProjectManager.java)
|
||||||
* [`ProjectFileIndex`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java)
|
* [`ProjectFileIndex`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java)
|
||||||
|
|
||||||
Other classes for working with the project model are located in the [`projectModel-api.openapi`](upsource:///platform/projectModel-api/src/com/intellij/openapi) package.
|
Other classes for working with the project model are located in the [`projectModel-api.openapi`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi) package.
|
||||||
Basic API classes and interfaces for the concepts of [`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java), [`Module`](upsource:///platform/core-api/src/com/intellij/openapi/module/Module.java) and [`Application`](upsource:///platform/core-api/src/com/intellij/openapi/application/Application.java) are placed in the [`core-api.openapi`](upsource:///platform/core-api/src/com/intellij/openapi) package.
|
Basic API classes and interfaces for the concepts of [`Project`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/Project.java), [`Module`](%gh-ic%/platform/core-api/src/com/intellij/openapi/module/Module.java) and [`Application`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/Application.java) are placed in the [`core-api.openapi`](%gh-ic%/platform/core-api/src/com/intellij/openapi) package.
|
||||||
|
|
||||||
### How to get a Project instance?
|
### How to get a Project instance?
|
||||||
|
|
||||||
@ -33,17 +33,17 @@ A Project instance is available in multiple contexts:
|
|||||||
|
|
||||||
| Context | API |
|
| Context | API |
|
||||||
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [Action](basic_action_system.md) | [`AnActionEvent.getProject()`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java)<br/>[`DataContext.getData(CommonDataKeys.PROJECT)`](upsource:///platform/core-ui/src/openapi/actionSystem/DataContext.java) |
|
| [Action](basic_action_system.md) | [`AnActionEvent.getProject()`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java)<br/>[`DataContext.getData(CommonDataKeys.PROJECT)`](%gh-ic%/platform/core-ui/src/openapi/actionSystem/DataContext.java) |
|
||||||
| [Editor](editor_basics.md) | [`Editor.getProject()`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/Editor.java) |
|
| [Editor](editor_basics.md) | [`Editor.getProject()`](%gh-ic%/platform/editor-ui-api/src/com/intellij/openapi/editor/Editor.java) |
|
||||||
| [Module](module.md) | [`Module.getProject()`](upsource:///platform/core-api/src/com/intellij/openapi/module/Module.java) |
|
| [Module](module.md) | [`Module.getProject()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/module/Module.java) |
|
||||||
| [PSI](psi.md) | [`PsiElement.getProject()`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) |
|
| [PSI](psi.md) | [`PsiElement.getProject()`](%gh-ic%/platform/core-api/src/com/intellij/psi/PsiElement.java) |
|
||||||
| [Tests](testing_plugins.md) | [`IdeaProjectTestFixture.getProject()`](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/IdeaProjectTestFixture.java) |
|
| [Tests](testing_plugins.md) | [`IdeaProjectTestFixture.getProject()`](%gh-ic%/platform/testFramework/src/com/intellij/testFramework/fixtures/IdeaProjectTestFixture.java) |
|
||||||
|
|
||||||
It is also possible to retrieve projects in generic contexts:
|
It is also possible to retrieve projects in generic contexts:
|
||||||
* Project from [`VirtualFile`](virtual_file.md):
|
* Project from [`VirtualFile`](virtual_file.md):
|
||||||
* [`ProjectLocator.guessProjectForFile(VirtualFile)`](upsource:///platform/projectModel-api/src/com/intellij/openapi/project/ProjectLocator.java) - returns any project containing a given file.
|
* [`ProjectLocator.guessProjectForFile(VirtualFile)`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/project/ProjectLocator.java) - returns any project containing a given file.
|
||||||
* [`ProjectLocator.getProjectsForFile(VirtualFile)`](upsource:///platform/projectModel-api/src/com/intellij/openapi/project/ProjectLocator.java) - returns the list of projects that a given file is a part of.
|
* [`ProjectLocator.getProjectsForFile(VirtualFile)`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/project/ProjectLocator.java) - returns the list of projects that a given file is a part of.
|
||||||
* List of currently opened projects: [`ProjectManager.getOpenProjects()`](upsource:///platform/projectModel-api/src/com/intellij/openapi/project/ProjectManager.java)
|
* List of currently opened projects: [`ProjectManager.getOpenProjects()`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/project/ProjectManager.java)
|
||||||
|
|
||||||
### Getting a List of Source Roots for All Modules in a Project
|
### Getting a List of Source Roots for All Modules in a Project
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ Messages.showInfoMessage("Source roots for the " + projectName +
|
|||||||
|
|
||||||
### Checking if a File Belongs to a Project
|
### Checking if a File Belongs to a Project
|
||||||
|
|
||||||
Use [`ProjectFileIndex`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) to get this information:
|
Use [`ProjectFileIndex`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) to get this information:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
ProjectFileIndex projectFileIndex =
|
ProjectFileIndex projectFileIndex =
|
||||||
@ -86,7 +86,7 @@ Note that this method returns `null` if the file or directory does not belong to
|
|||||||
|
|
||||||
### Checking Whether a File or Directory Is Related to the Project Libraries
|
### Checking Whether a File or Directory Is Related to the Project Libraries
|
||||||
|
|
||||||
The [`ProjectFileIndex`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) interface implements a number of methods you can use to check whether the specified file belongs to the project library classes or library sources:
|
The [`ProjectFileIndex`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java) interface implements a number of methods you can use to check whether the specified file belongs to the project library classes or library sources:
|
||||||
* `isLibraryClassFile()`: Returns `true` if the specified `virtualFile` is a compiled class file.
|
* `isLibraryClassFile()`: Returns `true` if the specified `virtualFile` is a compiled class file.
|
||||||
* `isInLibraryClasses()`: Returns `true` if the specified `virtualFileOrDirectory` belongs to library classes.
|
* `isInLibraryClasses()`: Returns `true` if the specified `virtualFileOrDirectory` belongs to library classes.
|
||||||
* `isInLibrarySource()`: Returns `true` if the specified `virtualFileOrDirectory` belongs to library sources.
|
* `isInLibrarySource()`: Returns `true` if the specified `virtualFileOrDirectory` belongs to library sources.
|
||||||
@ -99,11 +99,11 @@ See [SDK](sdk.md) for more details.
|
|||||||
|
|
||||||
## Changing the Project Structure
|
## Changing the Project Structure
|
||||||
|
|
||||||
Utility classes used for modifying the project structure can be found in the package [`projectModel-impl.openapi`](upsource:///platform/projectModel-impl/src/com/intellij/openapi).
|
Utility classes used for modifying the project structure can be found in the package [`projectModel-impl.openapi`](%gh-ic%/platform/projectModel-impl/src/com/intellij/openapi).
|
||||||
Its [`roots`](upsource:///platform/projectModel-impl/src/com/intellij/openapi/roots) subpackage contains instances and utilities intended for work with project and module source roots, including [`ModuleRootModificationUtil`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java) and [`ProjectRootUtil`](upsource:///platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootUtil.java).
|
Its [`roots`](%gh-ic%/platform/projectModel-impl/src/com/intellij/openapi/roots) subpackage contains instances and utilities intended for work with project and module source roots, including [`ModuleRootModificationUtil`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java) and [`ProjectRootUtil`](%gh-ic%/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootUtil.java).
|
||||||
Project structure changes need to be performed in [write action](general_threading_rules.md#read-write-lock).
|
Project structure changes need to be performed in [write action](general_threading_rules.md#read-write-lock).
|
||||||
|
|
||||||
Refer to the [project_model](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/project_model/src/main/java/org/intellij/sdk/project/model/ModificationAction.java) code sample to learn how project structure modification can be implemented.
|
Refer to the [project_model](%gh-sdk-samples%/project_model/src/main/java/org/intellij/sdk/project/model/ModificationAction.java) code sample to learn how project structure modification can be implemented.
|
||||||
|
|
||||||
## Receiving Notifications About Project Structure Changes
|
## Receiving Notifications About Project Structure Changes
|
||||||
|
|
||||||
@ -124,4 +124,4 @@ The event only notifies that something has changed; if more details are needed a
|
|||||||
|
|
||||||
## Receiving Notification About Project Close/Open Events
|
## Receiving Notification About Project Close/Open Events
|
||||||
|
|
||||||
Use [`ProjectManagerListener`](upsource:///platform/projectModel-api/src/com/intellij/openapi/project/ProjectManagerListener.java) [listener](plugin_listeners.md)
|
Use [`ProjectManagerListener`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/project/ProjectManagerListener.java) [listener](plugin_listeners.md)
|
||||||
|
@ -10,7 +10,7 @@ Optionally, individual SDKs for each module can be configured.
|
|||||||
For more information about SDKs, see [SDK](https://www.jetbrains.com/help/idea/working-with-sdks.html) in the IntelliJ IDEA Web Help.
|
For more information about SDKs, see [SDK](https://www.jetbrains.com/help/idea/working-with-sdks.html) in the IntelliJ IDEA Web Help.
|
||||||
|
|
||||||
## Getting Project SDK Information
|
## Getting Project SDK Information
|
||||||
The information about the project SDK is accessed via [`ProjectRootManager`](upsource:///platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java) like the following example shows
|
The information about the project SDK is accessed via [`ProjectRootManager`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java) like the following example shows
|
||||||
|
|
||||||
```java
|
```java
|
||||||
Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();
|
Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();
|
||||||
@ -46,11 +46,11 @@ See the [project_model](https://github.com/JetBrains/intellij-sdk-code-samples/t
|
|||||||
|
|
||||||
## Available SDKs
|
## Available SDKs
|
||||||
|
|
||||||
[`ProjectJdkTable`](upsource:///platform/projectModel-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java) can be used to query and modify configured SDKs.
|
[`ProjectJdkTable`](%gh-ic%/platform/projectModel-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java) can be used to query and modify configured SDKs.
|
||||||
|
|
||||||
## Working with a Custom SDK
|
## Working with a Custom SDK
|
||||||
|
|
||||||
To create a custom SDK, provide a class extending [`SdkType`](upsource:///platform/lang-core/src/com/intellij/openapi/projectRoots/SdkType.java), leave `saveAdditionalData()` blank, and register it in the `com.intellij.sdkType` extension point.
|
To create a custom SDK, provide a class extending [`SdkType`](%gh-ic%/platform/lang-core/src/com/intellij/openapi/projectRoots/SdkType.java), leave `saveAdditionalData()` blank, and register it in the `com.intellij.sdkType` extension point.
|
||||||
|
|
||||||
To make SDK settings persistent, override `setupSdkPaths()` and save settings by `modificator.commitChanges()`:
|
To make SDK settings persistent, override `setupSdkPaths()` and save settings by `modificator.commitChanges()`:
|
||||||
|
|
||||||
@ -64,16 +64,16 @@ public boolean setupSdkPaths(@NotNull Sdk sdk, @NotNull SdkModel sdkModel) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
To let a user select an SDK, see [`ProjectJdksEditor`](upsource:///java/idea-ui/src/com/intellij/openapi/projectRoots/ui/ProjectJdksEditor.java).
|
To let a user select an SDK, see [`ProjectJdksEditor`](%gh-ic%/java/idea-ui/src/com/intellij/openapi/projectRoots/ui/ProjectJdksEditor.java).
|
||||||
|
|
||||||
However, it is not recommended to use "SDK" in non-IntelliJ IDEA IDEs.
|
However, it is not recommended to use "SDK" in non-IntelliJ IDEA IDEs.
|
||||||
Although "SDK" is available in most JetBrains products, `ProjectJdksEditor` is specific to Java, making the operation around "SDK" difficult.
|
Although "SDK" is available in most JetBrains products, `ProjectJdksEditor` is specific to Java, making the operation around "SDK" difficult.
|
||||||
The recommended way of managing "SDK" settings is to create a [`CustomStepProjectGenerator`](upsource:///platform/lang-impl/src/com/intellij/ide/util/projectWizard/CustomStepProjectGenerator.java) implementation and save settings in a [`PersistentStateComponent`](persisting_state_of_components.md).
|
The recommended way of managing "SDK" settings is to create a [`CustomStepProjectGenerator`](%gh-ic%/platform/lang-impl/src/com/intellij/ide/util/projectWizard/CustomStepProjectGenerator.java) implementation and save settings in a [`PersistentStateComponent`](persisting_state_of_components.md).
|
||||||
|
|
||||||
## Assisting in Setting Up an SDK
|
## Assisting in Setting Up an SDK
|
||||||
|
|
||||||
Prompting the user with a notification to set up an SDK can help them get up-and-running with a plugin faster.
|
Prompting the user with a notification to set up an SDK can help them get up-and-running with a plugin faster.
|
||||||
Use `com.intellij.projectSdkSetupValidator` extension point to register an implementation of [`ProjectSdkSetupValidator`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/daemon/ProjectSdkSetupValidator.java) to notify the user if they are missing an SDK.
|
Use `com.intellij.projectSdkSetupValidator` extension point to register an implementation of [`ProjectSdkSetupValidator`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/daemon/ProjectSdkSetupValidator.java) to notify the user if they are missing an SDK.
|
||||||
|
|
||||||
The following is a simplified example that checks whether an instance of "DemoSdk" has been configured in the project when the user opens a "DemoFileType":
|
The following is a simplified example that checks whether an instance of "DemoSdk" has been configured in the project when the user opens a "DemoFileType":
|
||||||
|
|
||||||
@ -110,6 +110,6 @@ Within `DemoProjectSdkSetupValidator`:
|
|||||||
|
|
||||||
|
|
||||||
> `ProjectSdkSetupValidator` will not work in IntelliJ Platform-based IDEs such as PyCharm.
|
> `ProjectSdkSetupValidator` will not work in IntelliJ Platform-based IDEs such as PyCharm.
|
||||||
> In such cases, you should register an implementation of [`EditorNotifications.Provider`](upsource:///platform/platform-api/src/com/intellij/ui/EditorNotifications.java) at the `com.intellij.editorNotificationProvider` extension point and override the `createNotificationPanel()` method with the conditionality and panel setup you want.
|
> In such cases, you should register an implementation of [`EditorNotifications.Provider`](%gh-ic%/platform/platform-api/src/com/intellij/ui/EditorNotifications.java) at the `com.intellij.editorNotificationProvider` extension point and override the `createNotificationPanel()` method with the conditionality and panel setup you want.
|
||||||
>
|
>
|
||||||
{type="warning"}
|
{type="warning"}
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
When a project is opened in the IDE for the first time, the user will be asked whether they trust the project or not.
|
When a project is opened in the IDE for the first time, the user will be asked whether they trust the project or not.
|
||||||
If the user chooses to preview the project in the safe mode, no potentially dangerous feature can be executed automatically or unexpectedly.
|
If the user chooses to preview the project in the safe mode, no potentially dangerous feature can be executed automatically or unexpectedly.
|
||||||
|
|
||||||
A plugin can check whether the project is trusted via the Kotlin extension method `Project.isTrusted()` or from Java via static method [`TrustedProjects.isTrusted(Project)`](upsource:///platform/platform-impl/src/com/intellij/ide/impl/TrustedProjects.kt).
|
A plugin can check whether the project is trusted via the Kotlin extension method `Project.isTrusted()` or from Java via static method [`TrustedProjects.isTrusted(Project)`](%gh-ic%/platform/platform-impl/src/com/intellij/ide/impl/TrustedProjects.kt).
|
||||||
|
|
||||||
A project opened in the safe mode can become trusted afterward: either the user can click on the <control>Trust Project</control> link in the notification panel shown on top of the editor,
|
A project opened in the safe mode can become trusted afterward: either the user can click on the <control>Trust Project</control> link in the notification panel shown on top of the editor,
|
||||||
or the state can be changed programmatically, for instance, if the user invokes a dangerous action, and that action proposes to switch to the Trusted mode.
|
or the state can be changed programmatically, for instance, if the user invokes a dangerous action, and that action proposes to switch to the Trusted mode.
|
||||||
|
|
||||||
Therefore, a plugin can subscribe to changes of the trusted state via [application-level listener](plugin_listeners.md#defining-application-level-listeners) [`TrustStateListener`](upsource:///platform/platform-impl/src/com/intellij/ide/impl/TrustedProjects.kt) to switch on a feature that was disabled in the safe mode.
|
Therefore, a plugin can subscribe to changes of the trusted state via [application-level listener](plugin_listeners.md#defining-application-level-listeners) [`TrustStateListener`](%gh-ic%/platform/platform-impl/src/com/intellij/ide/impl/TrustedProjects.kt) to switch on a feature that was disabled in the safe mode.
|
||||||
To do it the plugin should implement `TrustStateListener.onProjectTrusted()`.
|
To do it the plugin should implement `TrustStateListener.onProjectTrusted()`.
|
||||||
Or better, use one of [`TrustedProjects.whenProjectTrusted()`](upsource:///platform/platform-impl/src/com/intellij/ide/impl/TrustedProjects.kt) helper methods accepting a lambda, one for Kotlin and another for Java.
|
Or better, use one of [`TrustedProjects.whenProjectTrusted()`](%gh-ic%/platform/platform-impl/src/com/intellij/ide/impl/TrustedProjects.kt) helper methods accepting a lambda, one for Kotlin and another for Java.
|
||||||
|
|
||||||
## Is the feature dangerous?
|
## Is the feature dangerous?
|
||||||
|
|
||||||
|
@ -9,11 +9,11 @@ Working with the project wizard can be illustrated with the [RedLine SmallTalk p
|
|||||||
## Implementing a New Module Type
|
## Implementing a New Module Type
|
||||||
|
|
||||||
Additional support for specific tools and technologies is usually done via implementing some certain module type which is attached to the project.
|
Additional support for specific tools and technologies is usually done via implementing some certain module type which is attached to the project.
|
||||||
New module type should be derived from the class [`ModuleType`](upsource:///platform/lang-core/src/com/intellij/openapi/module/ModuleType.java).
|
New module type should be derived from the class [`ModuleType`](%gh-ic%/platform/lang-core/src/com/intellij/openapi/module/ModuleType.java).
|
||||||
|
|
||||||
## Custom Project Wizard
|
## Custom Project Wizard
|
||||||
|
|
||||||
Main utilities to configure a custom project wizard can be found in the package [`lang-api.ide.util.projectWizard`](upsource:///platform/lang-api/src/com/intellij/ide/util/projectWizard).
|
Main utilities to configure a custom project wizard can be found in the package [`lang-api.ide.util.projectWizard`](%gh-ic%/platform/lang-api/src/com/intellij/ide/util/projectWizard).
|
||||||
These classes and interfaces serve the following purposes:
|
These classes and interfaces serve the following purposes:
|
||||||
|
|
||||||
* Modification of the configuration wizard view
|
* Modification of the configuration wizard view
|
||||||
@ -33,12 +33,12 @@ To create a new module type add an extension
|
|||||||
```
|
```
|
||||||
|
|
||||||
to the [`plugin.xml`](https://github.com/bulenkov/RedlineSmalltalk/blob/master/resources/META-INF/plugin.xml).
|
to the [`plugin.xml`](https://github.com/bulenkov/RedlineSmalltalk/blob/master/resources/META-INF/plugin.xml).
|
||||||
A custom module type should extend the [`ModuleType`](upsource:///platform/lang-core/src/com/intellij/openapi/module/ModuleType.java) generic from [`ModuleBuilder`](upsource:///platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java).
|
A custom module type should extend the [`ModuleType`](%gh-ic%/platform/lang-core/src/com/intellij/openapi/module/ModuleType.java) generic from [`ModuleBuilder`](%gh-ic%/platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java).
|
||||||
The following [module type implementation](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleType.java) of a custom module type shows how this instance can be registered and implemented.
|
The following [module type implementation](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleType.java) of a custom module type shows how this instance can be registered and implemented.
|
||||||
|
|
||||||
### Implementing Module Builder
|
### Implementing Module Builder
|
||||||
|
|
||||||
To set up a new module environment [`ModuleBuilder`](upsource:///platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java) class should be extended and registered as an extension point like the following snippet shows:
|
To set up a new module environment [`ModuleBuilder`](%gh-ic%/platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java) class should be extended and registered as an extension point like the following snippet shows:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
@ -59,11 +59,11 @@ Functionality which is mandatory to implement consists of:
|
|||||||
public abstract ModuleType getModuleType();
|
public abstract ModuleType getModuleType();
|
||||||
```
|
```
|
||||||
|
|
||||||
See [`JavaModuleBuilder`](upsource:///java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java) to understand better how to implement a module builder.
|
See [`JavaModuleBuilder`](%gh-ic%/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java) to understand better how to implement a module builder.
|
||||||
|
|
||||||
If your module type is based on the Java module and meant to support Java as well, extending [`JavaModuleBuilder`](upsource:///java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java) is enough.
|
If your module type is based on the Java module and meant to support Java as well, extending [`JavaModuleBuilder`](%gh-ic%/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java) is enough.
|
||||||
No extension point needs to be registered.
|
No extension point needs to be registered.
|
||||||
Refer to [SmallTalk module type](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleType.java) to see how [`JavaModuleBuilder`](upsource:///java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java) can be derived.
|
Refer to [SmallTalk module type](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleType.java) to see how [`JavaModuleBuilder`](%gh-ic%/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java) can be derived.
|
||||||
|
|
||||||
> Starting with the 2022.1 release, IntelliJ-based IDEs use the refreshed project wizard and some module builder base classes return `false` from `isAvailable()` when the new wizard is enabled.
|
> Starting with the 2022.1 release, IntelliJ-based IDEs use the refreshed project wizard and some module builder base classes return `false` from `isAvailable()` when the new wizard is enabled.
|
||||||
> If your module builder is not visible in 2022.1, make sure that your `ModuleBuilder.isAvailable()` returns `true`.
|
> If your module builder is not visible in 2022.1, make sure that your `ModuleBuilder.isAvailable()` returns `true`.
|
||||||
@ -73,16 +73,16 @@ Refer to [SmallTalk module type](https://github.com/bulenkov/RedlineSmalltalk/bl
|
|||||||
### Implementing Module Builder Listener
|
### Implementing Module Builder Listener
|
||||||
|
|
||||||
Module builder listener reacts on a new module creation, which could be done either as a part of the project creation process, or as adding a new module to the already existing project.
|
Module builder listener reacts on a new module creation, which could be done either as a part of the project creation process, or as adding a new module to the already existing project.
|
||||||
To provide a certain behavior right after a module has been created, module builder should implement [`ModuleBuilderListener.moduleCreated(Module)`](upsource:///platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleBuilderListener.java).
|
To provide a certain behavior right after a module has been created, module builder should implement [`ModuleBuilderListener.moduleCreated(Module)`](%gh-ic%/platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleBuilderListener.java).
|
||||||
|
|
||||||
Examples of the tasks executed right after a module has been created may include configuring module roots, looking up for an SDK and setting it up, adding a specific facet if required, etc.
|
Examples of the tasks executed right after a module has been created may include configuring module roots, looking up for an SDK and setting it up, adding a specific facet if required, etc.
|
||||||
For more details, please see the following [SmallTalk custom module type](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleType.java) implementation.
|
For more details, please see the following [SmallTalk custom module type](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleType.java) implementation.
|
||||||
|
|
||||||
### Adding New Wizard Steps
|
### Adding New Wizard Steps
|
||||||
|
|
||||||
Adding new steps to the module wizard can be done by overriding [`AbstractModuleBuilder.createWizardSteps(WizardContext, ModulesProvider)`](upsource:///platform/lang-core/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java).
|
Adding new steps to the module wizard can be done by overriding [`AbstractModuleBuilder.createWizardSteps(WizardContext, ModulesProvider)`](%gh-ic%/platform/lang-core/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java).
|
||||||
See an example [module builder](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleBuilder.java).
|
See an example [module builder](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleBuilder.java).
|
||||||
If this method returns a non-empty array of [`ModuleWizardStep`](upsource:///platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java) objects, new steps will be shown in their indexing order while creating a new module.
|
If this method returns a non-empty array of [`ModuleWizardStep`](%gh-ic%/platform/lang-core/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java) objects, new steps will be shown in their indexing order while creating a new module.
|
||||||
The following [implementation](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleWizardStep.java) for the SmallTalk project type illustrates how a custom wizard step can be created.
|
The following [implementation](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleWizardStep.java) for the SmallTalk project type illustrates how a custom wizard step can be created.
|
||||||
The [`RsModuleWizardStep`](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleWizardStep.java) class is derived from `ModuleWizardStep`, which has two methods to be overridden:
|
The [`RsModuleWizardStep`](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleWizardStep.java) class is derived from `ModuleWizardStep`, which has two methods to be overridden:
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ To understand facets better from the end-user's point of view, see the [Facet](f
|
|||||||
|
|
||||||
## Implementing Project Structure Detector
|
## Implementing Project Structure Detector
|
||||||
|
|
||||||
To support the creation of your module when a project is imported from existing sources, extend [`ProjectStructureDetector`](upsource:///java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectStructureDetector.java).
|
To support the creation of your module when a project is imported from existing sources, extend [`ProjectStructureDetector`](%gh-ic%/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectStructureDetector.java).
|
||||||
To detect the files your module supports, implement `ProjectStructureDetector.detectRoots()`.
|
To detect the files your module supports, implement `ProjectStructureDetector.detectRoots()`.
|
||||||
|
|
||||||
Refer to the [Smalltalk project structure detector](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsProjectStructureDetector.java) to see example implementation.
|
Refer to the [Smalltalk project structure detector](https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsProjectStructureDetector.java) to see example implementation.
|
||||||
|
@ -101,7 +101,7 @@ For the child of a parent, the `id` attribute becomes compound:
|
|||||||
|
|
||||||
## Implementations for Parent-Child Settings
|
## Implementations for Parent-Child Settings
|
||||||
|
|
||||||
Implementations can be based on [`Configurable`](upsource:///platform/ide-core/src/com/intellij/openapi/options/Configurable.java), [`ConfigurableProvider`](upsource:///platform/ide-core/src/com/intellij/openapi/options/ConfigurableProvider.java) or one of their subtypes.
|
Implementations can be based on [`Configurable`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/Configurable.java), [`ConfigurableProvider`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/ConfigurableProvider.java) or one of their subtypes.
|
||||||
For more information about creating Settings implementations, see [Implementations for Settings Extension Points](settings_guide.md#implementations-for-settings-extension-points).
|
For more information about creating Settings implementations, see [Implementations for Settings Extension Points](settings_guide.md#implementations-for-settings-extension-points).
|
||||||
|
|
||||||
### Configurable Marker Interfaces
|
### Configurable Marker Interfaces
|
||||||
|
@ -18,7 +18,7 @@ This document describes adding custom Settings at the Project and Application (o
|
|||||||
Custom Settings implementations are declared in a plugin's configuration (<path>plugin.xml</path>) file using one of two extension points (EP), depending on the level of the Settings.
|
Custom Settings implementations are declared in a plugin's configuration (<path>plugin.xml</path>) file using one of two extension points (EP), depending on the level of the Settings.
|
||||||
Many [attributes](#settings-declaration-attributes) are shared between the EP declarations.
|
Many [attributes](#settings-declaration-attributes) are shared between the EP declarations.
|
||||||
|
|
||||||
Application and Project Settings typically provide an implementation based on the [`Configurable`](upsource:///platform/ide-core/src/com/intellij/openapi/options/Configurable.java) interface because they do not have runtime dependencies.
|
Application and Project Settings typically provide an implementation based on the [`Configurable`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/Configurable.java) interface because they do not have runtime dependencies.
|
||||||
See [Implementations for Settings Extension Points](#implementations-for-settings-extension-points) for more information.
|
See [Implementations for Settings Extension Points](#implementations-for-settings-extension-points) for more information.
|
||||||
|
|
||||||
> For performance reasons, it is recommended to declare as much information as possible about a 'Settings' implementation using attributes in the EP element in the <path>plugin.xml</path> descriptor.
|
> For performance reasons, it is recommended to declare as much information as possible about a 'Settings' implementation using attributes in the EP element in the <path>plugin.xml</path> descriptor.
|
||||||
@ -65,7 +65,7 @@ See [](#settings-declaration-attributes) for details.
|
|||||||
|
|
||||||
### Settings Declaration Attributes
|
### Settings Declaration Attributes
|
||||||
|
|
||||||
Readers are encouraged to review the Javadoc comments for [`Configurable`](upsource:///platform/ide-core/src/com/intellij/openapi/options/Configurable.java) because the attribute information applies to `ConfigurableProvider` as well as `Configurable`, as noted.
|
Readers are encouraged to review the Javadoc comments for [`Configurable`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/Configurable.java) because the attribute information applies to `ConfigurableProvider` as well as `Configurable`, as noted.
|
||||||
This section provides some additional clarification of those comments.
|
This section provides some additional clarification of those comments.
|
||||||
|
|
||||||
#### Table of Attributes
|
#### Table of Attributes
|
||||||
@ -111,20 +111,20 @@ See the [previous section](#table-of-attributes) for all supported attributes.
|
|||||||
## Implementations for Settings Extension Points
|
## Implementations for Settings Extension Points
|
||||||
|
|
||||||
Implementations for `com.intellij.projectConfigurable` and `com.intellij.applicationConfigurable` EPs can have one of two bases:
|
Implementations for `com.intellij.projectConfigurable` and `com.intellij.applicationConfigurable` EPs can have one of two bases:
|
||||||
* The [`Configurable`](upsource:///platform/ide-core/src/com/intellij/openapi/options/Configurable.java) interface, which provides a named configurable component with a Swing form.
|
* The [`Configurable`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/Configurable.java) interface, which provides a named configurable component with a Swing form.
|
||||||
Most Settings providers are based on the `Configurable` interface or one of its sub- or supertypes.
|
Most Settings providers are based on the `Configurable` interface or one of its sub- or supertypes.
|
||||||
* The [`ConfigurableProvider`](upsource:///platform/ide-core/src/com/intellij/openapi/options/ConfigurableProvider.java) class, which can hide a configurable component from the Settings dialog based on runtime conditions.
|
* The [`ConfigurableProvider`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/ConfigurableProvider.java) class, which can hide a configurable component from the Settings dialog based on runtime conditions.
|
||||||
|
|
||||||
### The Configurable Interface
|
### The Configurable Interface
|
||||||
|
|
||||||
Many Settings in the `intellij-community` code base implement `Configurable` or one of its subtypes, such as [`SearchableConfigurable`](upsource:///platform/ide-core/src/com/intellij/openapi/options/SearchableConfigurable.java).
|
Many Settings in the `intellij-community` code base implement `Configurable` or one of its subtypes, such as [`SearchableConfigurable`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/SearchableConfigurable.java).
|
||||||
Readers are encouraged to review the Javadoc comments for `Configurable`.
|
Readers are encouraged to review the Javadoc comments for `Configurable`.
|
||||||
|
|
||||||
#### Constructors
|
#### Constructors
|
||||||
|
|
||||||
Implementations must meet several requirements for constructors.
|
Implementations must meet several requirements for constructors.
|
||||||
* Application Settings implementations, declared using the [`applicationConfigurable` EP](#declaring-application-settings), must have a default constructor with no arguments.
|
* Application Settings implementations, declared using the [`applicationConfigurable` EP](#declaring-application-settings), must have a default constructor with no arguments.
|
||||||
* Project Settings implementations, declared using the [`projectConfigurable` EP](#declaring-project-settings), must declare a constructor with a single argument of type [`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java).
|
* Project Settings implementations, declared using the [`projectConfigurable` EP](#declaring-project-settings), must declare a constructor with a single argument of type [`Project`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/Project.java).
|
||||||
* Beginning in 2020.2, constructor injection (other than for `Project`) is not allowed.
|
* Beginning in 2020.2, constructor injection (other than for `Project`) is not allowed.
|
||||||
|
|
||||||
For a `Configurable` implementation correctly declared using an EP, the implementation's constructor is not invoked by the IntelliJ Platform until a user chooses the corresponding Settings `displayName` in the Settings Dialog menu.
|
For a `Configurable` implementation correctly declared using an EP, the implementation's constructor is not invoked by the IntelliJ Platform until a user chooses the corresponding Settings `displayName` in the Settings Dialog menu.
|
||||||
@ -144,7 +144,7 @@ A few high-level points are reviewed here:
|
|||||||
* A `Configurable` instance's lifetime ends when <control>OK</control> or <control>Cancel</control> is selected in the Settings Dialog.
|
* A `Configurable` instance's lifetime ends when <control>OK</control> or <control>Cancel</control> is selected in the Settings Dialog.
|
||||||
An instance's `Configurable.disposeUIResources()` is called when the Settings Dialog is closing.
|
An instance's `Configurable.disposeUIResources()` is called when the Settings Dialog is closing.
|
||||||
|
|
||||||
To open Settings dialog or show specific `Configurable`, see [`ShowSettingsUtil`](upsource:///platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java).
|
To open Settings dialog or show specific `Configurable`, see [`ShowSettingsUtil`](%gh-ic%/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java).
|
||||||
|
|
||||||
#### Configurable Marker Interfaces
|
#### Configurable Marker Interfaces
|
||||||
|
|
||||||
@ -162,17 +162,17 @@ The following nested interfaces are markers, which convey information about the
|
|||||||
|
|
||||||
There are classes in the IntelliJ Platform specialized in particular types of Settings.
|
There are classes in the IntelliJ Platform specialized in particular types of Settings.
|
||||||
These subtypes are based on `com.intellij.openapi.options.ConfigurableEP`.
|
These subtypes are based on `com.intellij.openapi.options.ConfigurableEP`.
|
||||||
For example, <menupath>Settings/Preferences | Editor | General | Appearance</menupath> allows adding Settings via [`EditorSmartKeysConfigurableEP`](upsource:///platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurableEP.java) and `com.intellij.editorSmartKeysConfigurable` EP.
|
For example, <menupath>Settings/Preferences | Editor | General | Appearance</menupath> allows adding Settings via [`EditorSmartKeysConfigurableEP`](%gh-ic%/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurableEP.java) and `com.intellij.editorSmartKeysConfigurable` EP.
|
||||||
|
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
Existing implementations of `Configurable` in the IntelliJ Platform that can serve as a reference are:
|
Existing implementations of `Configurable` in the IntelliJ Platform that can serve as a reference are:
|
||||||
* [`ConsoleConfigurable`](upsource:///platform/lang-impl/src/com/intellij/execution/console/ConsoleConfigurable.java) (application configurable)
|
* [`ConsoleConfigurable`](%gh-ic%/platform/lang-impl/src/com/intellij/execution/console/ConsoleConfigurable.java) (application configurable)
|
||||||
* [`AutoImportOptionsConfigurable`](upsource:///platform/lang-impl/src/com/intellij/application/options/editor/AutoImportOptionsConfigurable.kt) (project configurable)
|
* [`AutoImportOptionsConfigurable`](%gh-ic%/platform/lang-impl/src/com/intellij/application/options/editor/AutoImportOptionsConfigurable.kt) (project configurable)
|
||||||
|
|
||||||
### The ConfigurableProvider Class
|
### The ConfigurableProvider Class
|
||||||
|
|
||||||
The [`ConfigurableProvider`](upsource:///platform/ide-core/src/com/intellij/openapi/options/ConfigurableProvider.java) class only provides a `Configurable` implementation if its runtime conditions are met.
|
The [`ConfigurableProvider`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/ConfigurableProvider.java) class only provides a `Configurable` implementation if its runtime conditions are met.
|
||||||
The IntelliJ Platform first calls the `ConfigurableProvider.canCreateConfigurable()`, which evaluates runtime conditions to determine if Settings changes make sense in the current context.
|
The IntelliJ Platform first calls the `ConfigurableProvider.canCreateConfigurable()`, which evaluates runtime conditions to determine if Settings changes make sense in the current context.
|
||||||
If the Settings make sense to display, `canCreateConfigurable()` returns `true`.
|
If the Settings make sense to display, `canCreateConfigurable()` returns `true`.
|
||||||
In that case the IntelliJ Platform calls `ConfigurableProvider.createConfigurable()`, which returns the `Configurable` object for its Settings implementation.
|
In that case the IntelliJ Platform calls `ConfigurableProvider.createConfigurable()`, which returns the `Configurable` object for its Settings implementation.
|
||||||
@ -180,4 +180,4 @@ In that case the IntelliJ Platform calls `ConfigurableProvider.createConfigurabl
|
|||||||
By choosing not to provide a `Configuration` implementation in some circumstances, the `ConfigurableProvider` opts out of the Settings display and modification process.
|
By choosing not to provide a `Configuration` implementation in some circumstances, the `ConfigurableProvider` opts out of the Settings display and modification process.
|
||||||
The use of `ConfigurableProvider` as a basis for a Settings implementation is declared using [attributes](#table-of-attributes) in the EP declaration.
|
The use of `ConfigurableProvider` as a basis for a Settings implementation is declared using [attributes](#table-of-attributes) in the EP declaration.
|
||||||
|
|
||||||
**Example**: [`RunToolbarSettingsConfigurableProvider`](upsource:///platform/execution-impl/src/com/intellij/execution/runToolbar/RunToolbarSettingsConfigurableProvider.kt)
|
**Example**: [`RunToolbarSettingsConfigurableProvider`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/runToolbar/RunToolbarSettingsConfigurableProvider.kt)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
EP: `com.intellij.extendWordSelectionHandler`
|
EP: `com.intellij.extendWordSelectionHandler`
|
||||||
|
|
||||||
Implementing [`ExtendWordSelectionHandler`](upsource:///platform/lang-api/src/com/intellij/codeInsight/editorActions/ExtendWordSelectionHandler.java) and registering it as `com.intellij.extendWordSelectionHandler` EP in your <path>plugin.xml</path> allows you to provide additional text ranges to be used when extending or shrinking a selection.
|
Implementing [`ExtendWordSelectionHandler`](%gh-ic%/platform/lang-api/src/com/intellij/codeInsight/editorActions/ExtendWordSelectionHandler.java) and registering it as `com.intellij.extendWordSelectionHandler` EP in your <path>plugin.xml</path> allows you to provide additional text ranges to be used when extending or shrinking a selection.
|
||||||
Return `true` from `canSelect(PsiElement)` for the PSI elements that you want to provide additional text-ranges for.
|
Return `true` from `canSelect(PsiElement)` for the PSI elements that you want to provide additional text-ranges for.
|
||||||
The IntelliJ Platform will call `select(PsiElement, CharSequence, int, Editor)` for these elements where you can compute additional text ranges and return them as `List<TextRange>`.
|
The IntelliJ Platform will call `select(PsiElement, CharSequence, int, Editor)` for these elements where you can compute additional text ranges and return them as `List<TextRange>`.
|
||||||
|
|
||||||
@ -45,12 +45,12 @@ This can be achieved by implementing this EP in the following way:
|
|||||||
### Further Insight and Debugging
|
### Further Insight and Debugging
|
||||||
|
|
||||||
Looking at other implementations can be an effective way to get a better understanding of how this EP works.
|
Looking at other implementations can be an effective way to get a better understanding of how this EP works.
|
||||||
To get further insight into this EP, you may want to take a look at [`DocTagSelectioner`](upsource:///java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java).
|
To get further insight into this EP, you may want to take a look at [`DocTagSelectioner`](%gh-ic%/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java).
|
||||||
It provides the ability to select tag names like `@param` in JavaDoc comments.
|
It provides the ability to select tag names like `@param` in JavaDoc comments.
|
||||||
Additionally, the [IntelliJ Platform Explorer](https://plugins.jetbrains.com/intellij-platform-explorer/?extensions=com.intellij.extendWordSelectionHandler) provides a list of open-source plugins with implementations of the `extendWordSelectionHandler` EP.
|
Additionally, the [IntelliJ Platform Explorer](https://plugins.jetbrains.com/intellij-platform-explorer/?extensions=com.intellij.extendWordSelectionHandler) provides a list of open-source plugins with implementations of the `extendWordSelectionHandler` EP.
|
||||||
|
|
||||||
There are also some important places in the IntelliJ Platform to add breakpoints during debugging.
|
There are also some important places in the IntelliJ Platform to add breakpoints during debugging.
|
||||||
When _Extend Selection_ is called by the user, it is handled by [`SelectWordHandler`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordHandler.java).
|
When _Extend Selection_ is called by the user, it is handled by [`SelectWordHandler`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordHandler.java).
|
||||||
The majority of the work, however, is then done inside [`SelectWordUtil`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java), where `processElement()` checks which implementations of this EP apply for the current PSI element.
|
The majority of the work, however, is then done inside [`SelectWordUtil`](%gh-ic%/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java), where `processElement()` checks which implementations of this EP apply for the current PSI element.
|
||||||
If one of them returns `true` from its `canSelect()` method, the additional text ranges are extracted in the `askSelectioner()` function.
|
If one of them returns `true` from its `canSelect()` method, the additional text ranges are extracted in the `askSelectioner()` function.
|
||||||
These places are good candidates to set breakpoints and investigate during debugging.
|
These places are good candidates to set breakpoints and investigate during debugging.
|
||||||
|
@ -18,7 +18,7 @@ Colors are defined by six-digit RGB or eight-digit RGBA hexadecimal notation.
|
|||||||
|
|
||||||
### UI Theme Reference Implementations
|
### UI Theme Reference Implementations
|
||||||
When learning new syntax, it is often useful to have some existing implementations for reference.
|
When learning new syntax, it is often useful to have some existing implementations for reference.
|
||||||
For example, refer to the [Theme description file](upsource:///platform/platform-resources/src/themes/HighContrast.theme.json) for the IntelliJ IDEA _High Contrast_ Theme.
|
For example, refer to the [Theme description file](%gh-ic%/platform/platform-resources/src/themes/HighContrast.theme.json) for the IntelliJ IDEA _High Contrast_ Theme.
|
||||||
It may also help to review some of the [UI Themes available](https://plugins.jetbrains.com/search?headline=164-theme&tags=Theme) at the JetBrains Marketplace.
|
It may also help to review some of the [UI Themes available](https://plugins.jetbrains.com/search?headline=164-theme&tags=Theme) at the JetBrains Marketplace.
|
||||||
|
|
||||||
## Defining Named Colors
|
## Defining Named Colors
|
||||||
@ -209,7 +209,7 @@ The 2019.1 release control keys are compatible with release 2019.2 and later ver
|
|||||||
|
|
||||||
Methods for identifying UI control keys are in the [Finding Attribute Keys for UI Controls](#finding-attribute-keys-for-ui-controls) section.
|
Methods for identifying UI control keys are in the [Finding Attribute Keys for UI Controls](#finding-attribute-keys-for-ui-controls) section.
|
||||||
|
|
||||||
For example, here is an excerpt from the IntelliJ Platform [High Contrast Theme](upsource:///platform/platform-resources/src/themes/HighContrast.theme.json):
|
For example, here is an excerpt from the IntelliJ Platform [High Contrast Theme](%gh-ic%/platform/platform-resources/src/themes/HighContrast.theme.json):
|
||||||
Note that a Theme file can mix versions of `property` identifiers:
|
Note that a Theme file can mix versions of `property` identifiers:
|
||||||
* The first three `property` entries are recognized by release 2019.1 and ignored by subsequent releases because they are defined by new `property` identifiers.
|
* The first three `property` entries are recognized by release 2019.1 and ignored by subsequent releases because they are defined by new `property` identifiers.
|
||||||
* The `underlineColor` `property` is recognized by release 2019.1 and subsequent releases.
|
* The `underlineColor` `property` is recognized by release 2019.1 and subsequent releases.
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user