mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-29 09:47:50 +08:00
Clean up inconsistent markdown code style
Search: ```([^`\n]+)``` Replace: `$1`
This commit is contained in:
parent
23305e4b52
commit
d5952b46f7
@ -21,17 +21,17 @@ class.
|
||||
Every action can be included in multiple groups, and thus appear in multiple places within the IDEA user interface.
|
||||
Different places where actions can appear are defined by constants in the
|
||||
[ActionPlaces](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java)
|
||||
interface. For every place where the action appears, a new ```Presentation``` is created.
|
||||
interface. For every place where the action appears, a new `Presentation` is created.
|
||||
Thus, the same action can have different text or icons when it appears in different places of the user interface.
|
||||
Different presentations for the action are created by copying the presentation returned by the ```AnAction.getTemplatePresentation()``` method.
|
||||
Different presentations for the action are created by copying the presentation returned by the `AnAction.getTemplatePresentation()` method.
|
||||
|
||||
To update the state of the action, the method ```AnAction.update()``` is periodically called by IDEA.
|
||||
The object of type ```AnActionEvent``` passed to this method carries the information about the current context for the action, and in particular, the specific presentation which needs to be updated.
|
||||
To update the state of the action, the method `AnAction.update()` is periodically called by IDEA.
|
||||
The object of type `AnActionEvent` passed to this method carries the information about the current context for the action, and in particular, the specific presentation which needs to be updated.
|
||||
|
||||
To retrieve the information about the current state of the IDE, including the active project, the selected file, the selection in the editor and so on, the method ```AnActionEvent.getData()``` can be used.
|
||||
Different data keys that can be passed to that method are defined in the ```DataKeys``` class.
|
||||
To retrieve the information about the current state of the IDE, including the active project, the selected file, the selection in the editor and so on, the method `AnActionEvent.getData()` can be used.
|
||||
Different data keys that can be passed to that method are defined in the `DataKeys` class.
|
||||
|
||||
The ```AnActionEvent``` instance is also passed to the ```actionPerformed``` method.
|
||||
The `AnActionEvent` instance is also passed to the `actionPerformed` method.
|
||||
|
||||
## Registering Actions
|
||||
|
||||
@ -100,23 +100,23 @@ Registering actions in plugin.xml is demonstrated in the following example. The
|
||||
### Registering Actions from Code
|
||||
|
||||
To register an action from code, two steps are required.
|
||||
First, an instance of the class derived from ```AnAction``` must be passed to the ```registerAction``` method of the
|
||||
First, an instance of the class derived from `AnAction` must be passed to the `registerAction` method of the
|
||||
[ActionManager](https://github.com/JetBrains/intellij-community/blob/master/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java)
|
||||
class, to associate the action with an ID.
|
||||
Second, the action needs to be added to one or more groups.
|
||||
To get an instance of an action group by ID, it is necessary to call ```ActionManager.getAction()``` and cast the returned value to the
|
||||
To get an instance of an action group by ID, it is necessary to call `ActionManager.getAction()` and cast the returned value to the
|
||||
[DefaultActionGroup](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java)
|
||||
class.
|
||||
|
||||
You can create a plugin that registers actions on IDEA startup using the following procedure.
|
||||
|
||||
*To register an action on IDEA startup*
|
||||
# Create a new class that implements the ```ApplicationComponent``` interface.
|
||||
# In this class, override the ```getComponentName```, ```initComponent```, and ```disposeComponent``` methods.
|
||||
# Create a new class that implements the `ApplicationComponent` interface.
|
||||
# In this class, override the `getComponentName`, `initComponent`, and `disposeComponent` methods.
|
||||
# Register this class in the `<application-components>` section of the plugin.xml file.
|
||||
|
||||
|
||||
To clarify the above procedure, consider the following sample Java class ```MyPluginRegistration``` that registers an action defined in a custom ```TextBoxes``` class and adds a new menu command to the *Window* menu group on the main menu:
|
||||
To clarify the above procedure, consider the following sample Java class `MyPluginRegistration` that registers an action defined in a custom `TextBoxes` class and adds a new menu command to the *Window* menu group on the main menu:
|
||||
|
||||
```java
|
||||
public class MyPluginRegistration implements ApplicationComponent {
|
||||
@ -146,7 +146,7 @@ public class MyPluginRegistration implements ApplicationComponent {
|
||||
}
|
||||
```
|
||||
|
||||
Note, that the sample ```TextBoxes``` class is described in
|
||||
Note, that the sample `TextBoxes` class is described in
|
||||
[Getting Started with Plugin Development](/basics/getting_started.md).
|
||||
|
||||
To ensure that your plugin is initialized on IDEA start-up, make the following changes to the `<application-components>` section of the plugin.xml file:
|
||||
@ -162,8 +162,8 @@ To ensure that your plugin is initialized on IDEA start-up, make the following c
|
||||
|
||||
## Building UI from Actions
|
||||
|
||||
If a plugin needs to include a toolbar or popup menu built from a group of actions in its own user interface, that can be accomplished through the ```ActionPopupMenu``` and ```ActionToolbar``` classes. These objects can be created through calls to ```ActionManager.createActionPopupMenu``` and ```ActionManager.createActionToolbar```.
|
||||
If a plugin needs to include a toolbar or popup menu built from a group of actions in its own user interface, that can be accomplished through the `ActionPopupMenu` and `ActionToolbar` classes. These objects can be created through calls to `ActionManager.createActionPopupMenu` and `ActionManager.createActionToolbar`.
|
||||
To get a Swing component from such an object, simply call the getComponent() method.
|
||||
|
||||
If your action toolbar is attached to a specific component (for example, a panel in a toolwindow), you usually need to call ```ActionToolbar.setTargetComponent()``` and pass the instance of the related component as a parameter.
|
||||
If your action toolbar is attached to a specific component (for example, a panel in a toolwindow), you usually need to call `ActionToolbar.setTargetComponent()` and pass the instance of the related component as a parameter.
|
||||
This ensures that the state of the toolbar buttons depends on the state of the related component, and not on the current focus location within the IDE frame.
|
||||
|
@ -6,9 +6,9 @@ A document is an editable sequence of Unicode characters, which typically corres
|
||||
|
||||
## How do I get a document?
|
||||
|
||||
* From an action: ```e.getData(PlatformDataKeys.EDITOR).getDocument()```
|
||||
* From a virtual file: ```FileDocumentManager.getDocument()```. This call forces the document content to be loaded from disk if it wasn't loaded previously; if you're only interested in open documents or documents which may have been modified, use ```FileDocumentManager.getCachedDocument()``` instead.
|
||||
* From a PSI file: ```PsiDocumentManager.getInstance().getDocument()``` or ```PsiDocumentManager.getInstance().getCachedDocument()```
|
||||
* From an action: `e.getData(PlatformDataKeys.EDITOR).getDocument()`
|
||||
* From a virtual file: `FileDocumentManager.getDocument()`. This call forces the document content to be loaded from disk if it wasn't loaded previously; if you're only interested in open documents or documents which may have been modified, use `FileDocumentManager.getCachedDocument()` instead.
|
||||
* From a PSI file: `PsiDocumentManager.getInstance().getDocument()` or `PsiDocumentManager.getInstance().getCachedDocument()`
|
||||
|
||||
## What can I do with a Document?
|
||||
|
||||
@ -24,18 +24,18 @@ Document instances are weakly referenced from VirtualFile instances. Thus, an un
|
||||
|
||||
## How do I create a Document?
|
||||
|
||||
If you need to create a new file on disk, you don't create a document: you create a PSI file and then get its document. If you need to create a document instance which isn't bound to anything, you can use ```EditorFactory.createDocument```.
|
||||
If you need to create a new file on disk, you don't create a document: you create a PSI file and then get its document. If you need to create a document instance which isn't bound to anything, you can use `EditorFactory.createDocument`.
|
||||
|
||||
## How do I get notified when Documents change?
|
||||
|
||||
* ```Document.addDocumentListener``` allows you to receive notifications about changes in a particular Document instance.
|
||||
* ```EditorFactory.getEventMulticaster().addDocumentListener``` allows you to receive notifications about changes in all open documents.
|
||||
* ```FileDocumentManager.addFileDocumentManagerListener``` allows you to receive notifications when any document is saved or reloaded from disk.
|
||||
* `Document.addDocumentListener` allows you to receive notifications about changes in a particular Document instance.
|
||||
* `EditorFactory.getEventMulticaster().addDocumentListener` allows you to receive notifications about changes in all open documents.
|
||||
* `FileDocumentManager.addFileDocumentManagerListener` allows you to receive notifications when any document is saved or reloaded from disk.
|
||||
|
||||
## What are the rules of working with Documents?
|
||||
|
||||
The general read/write action rules are in effect. In addition to that, any operations which modify the contents of the document must be wrapped in a command (```CommandProcessor.getInstance().executeCommand()```). ```executeCommand()``` calls can be nested, and the outermost ```executeCommand``` call is added to the undo stack. If multiple documents are modified within a command, undoing this command will by default show a confirmation dialog to the user.
|
||||
The general read/write action rules are in effect. In addition to that, any operations which modify the contents of the document must be wrapped in a command (`CommandProcessor.getInstance().executeCommand()`). `executeCommand()` calls can be nested, and the outermost `executeCommand` call is added to the undo stack. If multiple documents are modified within a command, undoing this command will by default show a confirmation dialog to the user.
|
||||
|
||||
If the file corresponding to a document is read-only (for example, not checked out from the version control system), document modifications will fail. Thus, before modifying the document, it is necessary to call ```ReadonlyStatusHandler.getInstance(project).ensureFilesWritable()``` to check out the file if necessary.
|
||||
If the file corresponding to a document is read-only (for example, not checked out from the version control system), document modifications will fail. Thus, before modifying the document, it is necessary to call `ReadonlyStatusHandler.getInstance(project).ensureFilesWritable()` to check out the file if necessary.
|
||||
|
||||
All text strings passed to document modification methods (```setText```, ```insertString```, ```replaceString```) must use only \n as line separators.
|
||||
All text strings passed to document modification methods (`setText`, `insertString`, `replaceString`) must use only \n as line separators.
|
||||
|
@ -3,26 +3,26 @@ title: File View Providers
|
||||
---
|
||||
|
||||
A file view provider (see the [FileViewProvider](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/FileViewProvider.java) class) was introduced in IntelliJ IDEA 6.0. Its main purpose is to manage access to multiple PSI trees within a single file.
|
||||
For example, a JSPX page has a separate PSI tree for the Java code in it (```PsiJavaFile```), a separate tree for the XML code (```XmlFile```), and a separate tree for JSP as a whole
|
||||
For example, a JSPX page has a separate PSI tree for the Java code in it (`PsiJavaFile`), a separate tree for the XML code (`XmlFile`), and a separate tree for JSP as a whole
|
||||
[JspFile](https://github.com/JetBrains/intellij-community/blob/master/java/jsp-openapi/src/com/intellij/psi/jsp/JspFile.java)).
|
||||
Each of the PSI trees covers the entire contents of the file, and contains special "outer language elements" in the places where contents in a different language can be found.
|
||||
|
||||
A ```FileViewProvider``` instance corresponds to a single ```VirtualFile```, a single ```Document```, and can be used to retrieve multiple ```PsiFile``` instances.
|
||||
A `FileViewProvider` instance corresponds to a single `VirtualFile`, a single `Document`, and can be used to retrieve multiple `PsiFile` instances.
|
||||
|
||||
## How do I get an FVP?
|
||||
|
||||
* From a VirtualFile: ```PsiManager.getInstance(project).findViewProvider()```
|
||||
* From a PSI file: ```psiFile.getViewProvider()```
|
||||
* From a VirtualFile: `PsiManager.getInstance(project).findViewProvider()`
|
||||
* From a PSI file: `psiFile.getViewProvider()`
|
||||
|
||||
## What can I do with an FVP?
|
||||
|
||||
* To get the list of all languages for which PSI trees exist in a file: ```fileViewProvider.getLanguages()```
|
||||
* To get the PSI tree for a particular language: ```fileViewProvider.getPsi(language)```, where the ```language``` parameter can take values of the
|
||||
* To get the list of all languages for which PSI trees exist in a file: `fileViewProvider.getLanguages()`
|
||||
* To get the PSI tree for a particular language: `fileViewProvider.getPsi(language)`, where the `language` parameter can take values of the
|
||||
[Language](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lang/Language.java)
|
||||
type defined in
|
||||
[StdLanguages](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/lang/StdLanguages.java)
|
||||
class. For example, to get the PSI tree for XML, use ```fileViewProvider.getPsi(StdLanguages.XML)```.
|
||||
* To find an element of a particular language at the specified offset in the file: ```fileViewProvider.findElementAt(offset,language)```
|
||||
class. For example, to get the PSI tree for XML, use `fileViewProvider.getPsi(StdLanguages.XML)`.
|
||||
* To find an element of a particular language at the specified offset in the file: `fileViewProvider.findElementAt(offset,language)`
|
||||
|
||||
## How do I extend FVP?
|
||||
|
||||
@ -34,7 +34,7 @@ This extension point is declared using the
|
||||
bean class.
|
||||
To access this extension point, create a Java class that implements the
|
||||
[FileViewProviderFactory](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java)
|
||||
interface, and in this class, override the ```createFileViewProvider``` method.
|
||||
interface, and in this class, override the `createFileViewProvider` method.
|
||||
To declare the extension to the _fileType.fileViewProviderFactory_ extension point, to the `<extensions>` section of the plugin.xml file, add the following syntax:
|
||||
|
||||
```
|
||||
@ -42,4 +42,4 @@ To declare the extension to the _fileType.fileViewProviderFactory_ extension poi
|
||||
</fileType.fileViewProviderFactory>
|
||||
```
|
||||
|
||||
where the _%file type%_ refers to the type of the file being created (for example, to "JFS"), and the _%class name%_ refers to the name of your Java class that implements the ```FileViewProviderFactory``` interface.
|
||||
where the _%file type%_ refers to the type of the file being created (for example, to "JFS"), and the _%class name%_ refers to the name of your Java class that implements the `FileViewProviderFactory` interface.
|
||||
|
@ -4,9 +4,9 @@ title: General Threading Rules
|
||||
|
||||
In general, data structures in IntelliJ Platform are covered by a single "multiple readers / single writer" lock.
|
||||
Reading data is allowed from any thread.
|
||||
Reading data from the UI thread does not require any special effort. However, read operations performed from any other thread need to be wrapped in a read action by using ```ApplicationManager.getApplication().runReadAction()```.
|
||||
Writing the data is only allowed from the UI thread, and write operations always need to be wrapped in a write action with ```ApplicationManager.getApplication().runWriteAction()```.
|
||||
Reading data from the UI thread does not require any special effort. However, read operations performed from any other thread need to be wrapped in a read action by using `ApplicationManager.getApplication().runReadAction()`.
|
||||
Writing the data is only allowed from the UI thread, and write operations always need to be wrapped in a write action with `ApplicationManager.getApplication().runWriteAction()`.
|
||||
|
||||
To pass control from a background thread to the event dispatch thread, instead of the standard ```SwingUtilities.invokeLater()```, plugins should use ```ApplicationManager.getApplication().invokeLater()```.
|
||||
To pass control from a background thread to the event dispatch thread, instead of the standard `SwingUtilities.invokeLater()`, plugins should use `ApplicationManager.getApplication().invokeLater()`.
|
||||
The latter API allows specifying the _modality state_ for the call, i.e. the stack of modal dialogs under which the call is allowed to execute.
|
||||
Passing ```ModalityState.NON_MODAL``` means that the operation will be executed after all modal dialogs are closed. Passing ```ModalityState.stateForComponent()``` means that the operation may be executed while the specified component (part of a dialog) is still visible.
|
||||
Passing `ModalityState.NON_MODAL` means that the operation will be executed after all modal dialogs are closed. Passing `ModalityState.stateForComponent()` means that the operation may be executed while the specified component (part of a dialog) is still visible.
|
||||
|
@ -13,11 +13,11 @@ class is the common base class for PSI elements.
|
||||
|
||||
## How do I get a PSI element?
|
||||
|
||||
* From an action: ```e.getData(LangDataKeys.PSI_ELEMENT)```. Note: if an editor is currently open and the element under caret is a reference, this will return the result of resolving the reference. This may or may not be what you need.
|
||||
* From a file by offset: ```PsiFile.findElementAt()```. Note: this returns the lowest level element at the specified offset, which is normally a lexer token.
|
||||
* From an action: `e.getData(LangDataKeys.PSI_ELEMENT)`. Note: if an editor is currently open and the element under caret is a reference, this will return the result of resolving the reference. This may or may not be what you need.
|
||||
* From a file by offset: `PsiFile.findElementAt()`. Note: this returns the lowest level element at the specified offset, which is normally a lexer token.
|
||||
Most likely you should use PsiTreeUtil.getParentOfType() to find the element you really need.
|
||||
* By iterating through a PSI file: using a ```PsiRecursiveElementWalkingVisitor```.
|
||||
* By resolving a reference: ```PsiReference.resolve()```
|
||||
* By iterating through a PSI file: using a `PsiRecursiveElementWalkingVisitor`.
|
||||
* By resolving a reference: `PsiReference.resolve()`
|
||||
|
||||
## What can I do with PSI elements?
|
||||
|
||||
|
@ -12,46 +12,46 @@ class represents a Java file, and the
|
||||
[XmlFile](https://github.com/JetBrains/intellij-community/blob/master/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).
|
||||
|
||||
## How do I get a PSI file?
|
||||
|
||||
* From an action: ```e.getData(LangDataKeys.PSI_FILE)```.
|
||||
* From a VirtualFile: ```PsiManager.getInstance(project).findFile()```
|
||||
* From a Document: ```PsiDocumentManager.getInstance(project).getPsiFile()```
|
||||
* From an element inside the file: ```psiElement.getContainingFile()```
|
||||
* To find files with a specific name anywhere in the project, use ```FilenameIndex.getFilesByName(project, name, scope)```
|
||||
* From an action: `e.getData(LangDataKeys.PSI_FILE)`.
|
||||
* From a VirtualFile: `PsiManager.getInstance(project).findFile()`
|
||||
* From a Document: `PsiDocumentManager.getInstance(project).getPsiFile()`
|
||||
* From an element inside the file: `psiElement.getContainingFile()`
|
||||
* To find files with a specific name anywhere in the project, use `FilenameIndex.getFilesByName(project, name, scope)`
|
||||
|
||||
## What can I do with a PSI file?
|
||||
|
||||
Most interesting modification operations are performed on the level of individual PSI elements, not files as a whole.
|
||||
|
||||
To iterate over the elements in a file, use ```psiFile.accept(new PsiRecursiveElementWalkingVisitor()...);```
|
||||
To iterate over the elements in a file, use `psiFile.accept(new PsiRecursiveElementWalkingVisitor()...);`
|
||||
|
||||
## Where does it a PSI file come from?
|
||||
|
||||
As PSI is language-dependent, PSI files are created through the
|
||||
[Language](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lang/Language.java)
|
||||
object, by using the ```LanguageParserDefinitions.INSTANCE.forLanguage(language).createFile(fileViewProvider)``` method.
|
||||
object, by using the `LanguageParserDefinitions.INSTANCE.forLanguage(language).createFile(fileViewProvider)` method.
|
||||
|
||||
Like documents, PSI files are created on demand when the PSI is accessed for a particular file.
|
||||
|
||||
## How long do PSI files persist?
|
||||
|
||||
Like documents, PSI files are weakly referenced from the corresponding ```VirtualFile``` instances and can be garbage-collected if not referenced by anyone.
|
||||
Like documents, PSI files are weakly referenced from the corresponding `VirtualFile` instances and can be garbage-collected if not referenced by anyone.
|
||||
|
||||
## How do I create a PSI file?
|
||||
|
||||
The
|
||||
[PsiFileFactory](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/PsiFileFactory.java).
|
||||
```getInstance(project).createFileFromText()``` method creates an in-memory PSI file with the specified contents.
|
||||
`getInstance(project).createFileFromText()` method creates an in-memory PSI file with the specified contents.
|
||||
To save the PSI file to disk, use the
|
||||
[PsiDirectory](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/PsiDirectory.java).
|
||||
```add()``` method.
|
||||
`add()` method.
|
||||
|
||||
## How do I get notified when PSI files change?
|
||||
|
||||
```PsiManager.getInstance(project).addPsiTreeChangeListener()``` allows you to receive notifications about all changes to the PSI tree of a project.
|
||||
`PsiManager.getInstance(project).addPsiTreeChangeListener()` allows you to receive notifications about all changes to the PSI tree of a project.
|
||||
|
||||
|
||||
## How do I extend PSI?
|
||||
|
@ -9,50 +9,50 @@ The VFS level deals only with binary content. You can get or set the contents of
|
||||
|
||||
#### How do I get a virtual file?
|
||||
|
||||
* From an action: ```e.getData(PlatformDataKeys.VIRTUAL_FILE)```. If you are interested in multiple selection, you can also use ```e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY)```.
|
||||
* From an action: `e.getData(PlatformDataKeys.VIRTUAL_FILE)`. If you are interested in multiple selection, you can also use `e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY)`.
|
||||
|
||||
* From a path in the local file system: ```LocalFileSystem.getInstance().findFileByIoFile()```
|
||||
* From a path in the local file system: `LocalFileSystem.getInstance().findFileByIoFile()`
|
||||
|
||||
* From a PSI file: ```psiFile.getVirtualFile()``` (may return null if the PSI file exists only in memory)
|
||||
* From a PSI file: `psiFile.getVirtualFile()` (may return null if the PSI file exists only in memory)
|
||||
|
||||
* From a document: ```FileDocumentManager.getInstance().getFile()```
|
||||
* From a document: `FileDocumentManager.getInstance().getFile()`
|
||||
|
||||
#### What can I do with it?
|
||||
|
||||
Typical file operations are available, such as traverse the file system, get file contents, rename, move, or delete.
|
||||
|
||||
Recursive iteration should be performed using ```VfsUtilCore.iterateChildrenRecursively``` to prevent endless loops caused by recursive symlinks.
|
||||
Recursive iteration should be performed using `VfsUtilCore.iterateChildrenRecursively` to prevent endless loops caused by recursive symlinks.
|
||||
|
||||
#### Where does it come from?
|
||||
|
||||
The VFS is built incrementally, by scanning the file system up and down starting from the project root.
|
||||
New files appearing in the file system are detected by VFS _refreshes_. A refresh operation can be initiated programmatically using (```VirtualFileManager.getInstance().refresh()``` or ```VirtualFile.refresh()```).
|
||||
New files appearing in the file system are detected by VFS _refreshes_. A refresh operation can be initiated programmatically using (`VirtualFileManager.getInstance().refresh()` or `VirtualFile.refresh()`).
|
||||
VFS refreshes are also triggered whenever file system watchers receive file system change notifications (available on the Windows and Mac operating systems).
|
||||
As a plugin developer, you may want to invoke a VFS refresh if you need to access a file that has just been created by an external tool through IntelliJ IDEA APIs.
|
||||
|
||||
#### How long does a virtual file persist?
|
||||
|
||||
A particular file on disk is represented by equal ```VirtualFile``` instances for the entire lifetime of the IDEA process. There may be several instances corresponding to the same file, and they can be garbage-collected.
|
||||
The file is a ```UserDataHolder```, and the user data is shared between those equal instances. If a file is deleted, its corresponding VirtualFile instance becomes invalid ( the ```isValid()``` method returns _false_ and operations cause exceptions).
|
||||
A particular file on disk is represented by equal `VirtualFile` instances for the entire lifetime of the IDEA process. There may be several instances corresponding to the same file, and they can be garbage-collected.
|
||||
The file is a `UserDataHolder`, and the user data is shared between those equal instances. If a file is deleted, its corresponding VirtualFile instance becomes invalid ( the `isValid()` method returns _false_ and operations cause exceptions).
|
||||
|
||||
#### How do I create a virtual file?
|
||||
|
||||
Usually you don't. As a rule, files are created either through the PSI API or through the regular java.io.File API.
|
||||
If you do need to create a file through VFS, you can use the ```VirtualFile.createChildData()``` method to create a ```VirtualFile``` instance and the ```VirtualFile.setBinaryContent()``` method to write some data to the file.
|
||||
If you do need to create a file through VFS, you can use the `VirtualFile.createChildData()` method to create a `VirtualFile` instance and the `VirtualFile.setBinaryContent()` method to write some data to the file.
|
||||
|
||||
#### How do I get notified when VFS changes?
|
||||
|
||||
The ```VirtualFileManager.addVirtualFileListener()``` method allows you to receive notifications about all changes in the VFS.
|
||||
The `VirtualFileManager.addVirtualFileListener()` method allows you to receive notifications about all changes in the VFS.
|
||||
|
||||
#### How do I extend VFS?
|
||||
|
||||
To provide an alternative file system implementation (for example, an FTP file system), implement the
|
||||
[VirtualFileSystem](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java)
|
||||
class (most likely you'll also need to implement ```VirtualFile```), and register your implementation as an
|
||||
class (most likely you'll also need to implement `VirtualFile`), and register your implementation as an
|
||||
[application component](http://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_components.html).
|
||||
To hook into operations performed in the local file system (for example, if you are developing a version control system integration that needs custom rename/move handling), implement the
|
||||
[LocalFileOperationsHandler](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/vfs/LocalFileOperationsHandler.java)
|
||||
interface and register it through the```LocalFileSystem.registerAuxiliaryFileOperationsHandler``` method.
|
||||
interface and register it through the`LocalFileSystem.registerAuxiliaryFileOperationsHandler` method.
|
||||
|
||||
#### What are the rules for working with VFS?
|
||||
|
||||
|
@ -20,7 +20,7 @@ You can check out the code either by using IntelliJ IDEA or from the command lin
|
||||
|
||||
* Select **VCS \| Checkout from Version Control \| Git** from the main menu
|
||||
|
||||
* In the **Git Repository URL** field, enter ```git://git.jetbrains.org/idea/community.git```
|
||||
* In the **Git Repository URL** field, enter `git://git.jetbrains.org/idea/community.git`
|
||||
|
||||

|
||||
|
||||
|
@ -7,7 +7,7 @@ All products based on IntelliJ Platform (IntelliJ IDEA, RubyMine, WebStorm, PhpS
|
||||
Thus, a plugin that does not use any Java-specific functionality may be marked as compatible with these other products in addition to IntelliJ IDEA.
|
||||
This is done by specifying *module dependencies* in the `plugin.xml` file.
|
||||
|
||||
A module dependency is a ```<depends>``` tag where the contents of the tag starts with *com.intellij.modules*.
|
||||
A module dependency is a `<depends>` tag where the contents of the tag starts with *com.intellij.modules*.
|
||||
|
||||
For example:
|
||||
|
||||
|
@ -23,7 +23,7 @@ To set up your plugin development environment:
|
||||
**Note:**
|
||||
You may use IntelliJ IDEA Ultimate as an alternative, but the debugging of core code will only work with the *Community Edition*.
|
||||
|
||||
* In the Sourcepath tab of the SDK settings, click the ```Add``` button:
|
||||
* In the Sourcepath tab of the SDK settings, click the `Add` button:
|
||||
|
||||

|
||||
|
||||
|
@ -47,7 +47,7 @@ If you don't need to associate any value with the files (i.e. your value type is
|
||||
[ScalarIndexExtension](https://github.com/JetBrains/intellij-community/blob/master/platform/indexing-impl/src/com/intellij/util/indexing/ScalarIndexExtension.java)
|
||||
as the base class.
|
||||
|
||||
**Note:** The data returned by ```DataIndexer.map()``` must depend only on input data passed to the method, and must not depend on any external files.
|
||||
**Note:** The data returned by `DataIndexer.map()` must depend only on input data passed to the method, and must not depend on any external files.
|
||||
Otherwise your index will not be correctly updated when the external data changes, and you will have stale data in your index.
|
||||
|
||||
## Accessing a File-based Index
|
||||
|
@ -38,11 +38,11 @@ For each element type that you want to store in the stub tree, you need to perfo
|
||||
|
||||
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.
|
||||
* Change the file element type for your language (the element type that you return from `ParserDefinition.getFileNodeType()`) to a class that extends IStubFileElementType.
|
||||
|
||||
* In your plugin.xml, define the ```<stubElementTypeHolder>``` extension and specify the interface which contains the `IElementType` constants used by your language's parser ([example](https://github.com/JetBrains/intellij-community/blob/master/plugins/properties/src/META-INF/plugin.xml#L55)).
|
||||
* In your plugin.xml, define the `<stubElementTypeHolder>` extension and specify the interface which contains the `IElementType` constants used by your language's parser ([example](https://github.com/JetBrains/intellij-community/blob/master/plugins/properties/src/META-INF/plugin.xml#L55)).
|
||||
|
||||
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.
|
||||
This reduces the size of the serialized stub tree data.
|
||||
|
||||
@ -63,9 +63,9 @@ Otherwise the stub tree will not be rebuilt when an external dependency changes,
|
||||
When building the stub tree, you can at the same time put some data about the stub elements into a number of indexes, which then can be used to find the PSI elements by the corresponding key. 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 normally strings (such as class names); other data types are also supported if desired.
|
||||
|
||||
A stub index is a class which extends [AbstractStubIndex](https://github.com/JetBrains/intellij-community/blob/master/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](https://github.com/JetBrains/intellij-community/blob/master/platform/indexing-api/src/com/intellij/psi/stubs/StringStubIndexExtension.java).
|
||||
Stub index implementation classes are registered in the ```<stubIndex>``` extension point.
|
||||
Stub index implementation classes are registered in the `<stubIndex>` extension point.
|
||||
|
||||
To put data into an index, you implement the method ```IStubElementType.indexStub()``` ([example: JavaClassElementType.indexStub()](https://github.com/JetBrains/intellij-community/blob/master/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java#L189)). 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 put data into an index, you implement the method `IStubElementType.indexStub()` ([example: JavaClassElementType.indexStub()](https://github.com/JetBrains/intellij-community/blob/master/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java#L189)). 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:
|
||||
|
||||
|
@ -10,22 +10,22 @@ interface.
|
||||
|
||||
## Using PropertiesComponent for Simple non-roamable Persistence
|
||||
|
||||
If the only thing that your plugin needs to persist is a few simple values, the easiest way to do so is to use the ```com.intellij.ide.util.PropertiesComponent``` service. It can be used for saving both application-level values and project-level values (stored in the workspace file). Roaming is disabled for PropertiesComponent, so, use it only for temporary non-roamable properties.
|
||||
If the only thing that your plugin needs to persist is a few simple values, the easiest way to do so is to use the `com.intellij.ide.util.PropertiesComponent` service. It can be used for saving both application-level values and project-level values (stored in the workspace file). Roaming is disabled for PropertiesComponent, so, use it only for temporary non-roamable properties.
|
||||
|
||||
Use the ```PropertiesComponent.getInstance()``` method for storing application-level values, and the ```PropertiesComponent.getInstance(Project)``` method for storing project-level values.
|
||||
Use the `PropertiesComponent.getInstance()` method for storing application-level values, and the `PropertiesComponent.getInstance(Project)` method for storing project-level values.
|
||||
Since all plugins share the same namespace, it is highly recommended to prefix key names (e.g. using your plugin ID).
|
||||
|
||||
## Using PersistentStateComponent
|
||||
|
||||
The ```com.intellij.openapi.components.PersistentStateComponent``` interface gives you the most flexibility for defining the values to be persisted, their format and storage location. In order to use it, you should mark a service or a component as implementing the ```PersistentStateComponent``` interface, define the state class, and specify the storage location using the ```@com.intellij.openapi.components.State``` annotation.
|
||||
The `com.intellij.openapi.components.PersistentStateComponent` interface gives you the most flexibility for defining the values to be persisted, their format and storage location. In order to use it, you should mark a service or a component as implementing the `PersistentStateComponent` interface, define the state class, and specify the storage location using the `@com.intellij.openapi.components.State` annotation.
|
||||
|
||||
Note that instances of extensions cannot persist their state by implementing ```PersistentStateComponent```. If your extension needs to have persistent state, you need to define a separate service responsible for managing that state.
|
||||
Note that instances of extensions cannot persist their state by implementing `PersistentStateComponent`. If your extension needs to have persistent state, you need to define a separate service responsible for managing that state.
|
||||
|
||||
### Implementing the PersistentStateComponent Interface
|
||||
|
||||
The implementation of ```PersistentStateComponent``` needs to be parameterized with the type of the state class. The state class can either be a separate JavaBean class, or the class implementing ```PersistentStateComponent``` itself.
|
||||
The implementation of `PersistentStateComponent` needs to be parameterized with the type of the state class. The state class can either be a separate JavaBean class, or the class implementing `PersistentStateComponent` itself.
|
||||
|
||||
In the former case, the instance of the state class is typically stored as a field in the ```PersistentStateComponent``` class:
|
||||
In the former case, the instance of the state class is typically stored as a field in the `PersistentStateComponent` class:
|
||||
|
||||
```java
|
||||
class MyService implements PersistentStateComponent<MyService.State> {
|
||||
@ -42,7 +42,7 @@ class MyService implements PersistentStateComponent<MyService.State> {
|
||||
}
|
||||
```
|
||||
|
||||
In the latter case, you can use the following pattern to implement ```getState()``` and ```loadState()``` methods:
|
||||
In the latter case, you can use the following pattern to implement `getState()` and `loadState()` methods:
|
||||
|
||||
```java
|
||||
class MyService implements PersistentStateComponent<MyService> {
|
||||
@ -60,7 +60,7 @@ class MyService implements PersistentStateComponent<MyService> {
|
||||
|
||||
### Implementing the State Class
|
||||
|
||||
The implementation of ```PersistentStateComponent``` works by serializing public fields,
|
||||
The implementation of `PersistentStateComponent` works by serializing public fields,
|
||||
[annotated](https://github.com/JetBrains/intellij-community/tree/master/platform/util/src/com/intellij/util/xmlb/annotations)
|
||||
private fields and bean properties into an XML format. The following types of values can be persisted:
|
||||
|
||||
@ -71,38 +71,38 @@ private fields and bean properties into an XML format. The following types of va
|
||||
* maps;
|
||||
* enums.
|
||||
|
||||
In order to exclude a public field or bean property from serialization, you can annotate the field or getter with the ```@com.intellij.util.xmlb.annotations.Transient``` annotation.
|
||||
In order to exclude a public field or bean property from serialization, you can annotate the field or getter with the `@com.intellij.util.xmlb.annotations.Transient` annotation.
|
||||
|
||||
Note that the state class must have a default constructor.
|
||||
It should return the default state of the component (one used if there is nothing persisted in the XML files yet).
|
||||
|
||||
State class should have a ```equals``` method, but if it is not implemented, state objects will be compared by fields.
|
||||
State class should have a `equals` method, but if it is not implemented, state objects will be compared by fields.
|
||||
If you write in Kotlin, use [Data](http://kotlinlang.org/docs/reference/data-classes.html).
|
||||
|
||||
### Defining the Storage Location
|
||||
|
||||
In order to specify where exactly the persisted values wiil be stored, you need to add a ```@State``` annotation to the ```PersistentStateComponent``` class.
|
||||
In order to specify where exactly the persisted values wiil be stored, you need to add a `@State` annotation to the `PersistentStateComponent` class.
|
||||
It has the following fields:
|
||||
|
||||
* ```name``` (required) - specifies the name of the state (name of the root tag in XML)
|
||||
* One or more of ```@com.intellij.openapi.components.Storage``` annotations (required) - specify the storage locations for .ipr and directory-based projects
|
||||
* ```reloadable``` (optional) - if set to false, complete project reload is required when the XML file is changed externally and the state has changed.
|
||||
* `name` (required) - specifies the name of the state (name of the root tag in XML)
|
||||
* One or more of `@com.intellij.openapi.components.Storage` annotations (required) - specify the storage locations for .ipr and directory-based projects
|
||||
* `reloadable` (optional) - if set to false, complete project reload is required when the XML file is changed externally and the state has changed.
|
||||
|
||||
The simplest ways of specifying the ```@Storage``` annotation are as follows:
|
||||
The simplest ways of specifying the `@Storage` annotation are as follows:
|
||||
|
||||
* ```@Storage(id="other", file = StoragePathMacros.APP_CONFIG + "/yourName.xml")``` for application-level values
|
||||
* ```@Storage(id="other", file = StoragePathMacros.PROJECT_FILE)``` for values stored in the project file (for .ipr based projects)
|
||||
* ```@Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/other.xml", scheme = StorageScheme.DIRECTORY_BASED)})``` for values stored in the project directory (for directory-based projects)
|
||||
* ```@Storage(id="other", file = StoragePathMacros.WORKSPACE_FILE)``` for values stored in the workspace file
|
||||
* `@Storage(id="other", file = StoragePathMacros.APP_CONFIG + "/yourName.xml")` for application-level values
|
||||
* `@Storage(id="other", file = StoragePathMacros.PROJECT_FILE)` for values stored in the project file (for .ipr based projects)
|
||||
* `@Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/other.xml", scheme = StorageScheme.DIRECTORY_BASED)})` for values stored in the project directory (for directory-based projects)
|
||||
* `@Storage(id="other", file = StoragePathMacros.WORKSPACE_FILE)` for values stored in the workspace file
|
||||
|
||||
By specifying a different value for the ```file``` parameter, you can cause the state to be persisted in a different file. For application-level components strongly recommended to use custom file, using of ```other.xml``` is deprecated.
|
||||
By specifying a different value for the `file` parameter, you can cause the state to be persisted in a different file. For application-level components strongly recommended to use custom file, using of `other.xml` is deprecated.
|
||||
|
||||
The ```roamingType``` parameter of the ```@Storage``` annotation specifies the roaming type when the Settings Repository plugin is used.
|
||||
The `roamingType` parameter of the `@Storage` annotation specifies the roaming type when the Settings Repository plugin is used.
|
||||
|
||||
The ```id``` parameter of the ```@Storage``` annotation can be used to exclude specific fields from serialization in specific formats.
|
||||
If you do not need to exclude anything, you can set the ```id``` to an arbitrary string value.
|
||||
The `id` parameter of the `@Storage` annotation can be used to exclude specific fields from serialization in specific formats.
|
||||
If you do not need to exclude anything, you can set the `id` to an arbitrary string value.
|
||||
|
||||
If you need to specify where the values are stored when the directory-based project format is used, you need to add the second ```@Storage``` annotation with the scheme parameter set to StorageScheme.DIRECTORY_BASED, for example:
|
||||
If you need to specify where the values are stored when the directory-based project format is used, you need to add the second `@Storage` annotation with the scheme parameter set to StorageScheme.DIRECTORY_BASED, for example:
|
||||
|
||||
|
||||
```java
|
||||
@ -120,27 +120,27 @@ If you need to specify where the values are stored when the directory-based proj
|
||||
Please consider to use annotation parameters only to achieve backward compatibility.
|
||||
Otherwise feel free to file issues about serialization cosmetics.
|
||||
|
||||
If you want to use the default bean serialization but need to customize the storage format in XML (for example, for compatibility with previous versions of your plugin or externally defined XML formats), you can use the ```@Tag```, ```@Attribute```, ```@Property```, ```@MapAnnotation```, ```@AbstractCollection``` annotations.
|
||||
You can look at the source code (```com.intellij.util.xmlb``` package) to get more information about the meaning of these annotations.
|
||||
If you want to use the default bean serialization but need to customize the storage format in XML (for example, for compatibility with previous versions of your plugin or externally defined XML formats), you can use the `@Tag`, `@Attribute`, `@Property`, `@MapAnnotation`, `@AbstractCollection` annotations.
|
||||
You can look at the source code (`com.intellij.util.xmlb` package) to get more information about the meaning of these annotations.
|
||||
|
||||
If the state that you need to serialize doesn't map cleanly to a JavaBean, you can use ```org.jdom.Element``` as the state class.
|
||||
In that case, you can use the ```getState()``` method to build an XML element with an arbitrary structure, which will then be saved directly in the state XML file.
|
||||
In the ```loadState()``` method, you can deserialize the JDOM element tree using any custom logic.
|
||||
If the state that you need to serialize doesn't map cleanly to a JavaBean, you can use `org.jdom.Element` as the state class.
|
||||
In that case, you can use the `getState()` method to build an XML element with an arbitrary structure, which will then be saved directly in the state XML file.
|
||||
In the `loadState()` method, you can deserialize the JDOM element tree using any custom logic.
|
||||
But this way is not recommended and should be avoided.
|
||||
|
||||
## Persistent Component Lifecycle
|
||||
|
||||
The ```loadState()``` method is called after the component has been created (only if there is some non-default state persisted for the component), and after the XML file with the persisted state is changed externally (for example, if the project file was updated from the version control system). In the latter case, the component is responsible for updating the UI and other related components according to the changed state.
|
||||
The `loadState()` method is called after the component has been created (only if there is some non-default state persisted for the component), and after the XML file with the persisted state is changed externally (for example, if the project file was updated from the version control system). In the latter case, the component is responsible for updating the UI and other related components according to the changed state.
|
||||
|
||||
The ```getState()``` method is called every time the settings are saved (for example, on frame deactivation or when closing the IDE). If the state returned from ```getState()``` is equal to the default state (obtained by creating the state class with a default constructor), nothing is persisted in the XML. Otherwise, the returned state is serialized in XML and stored.
|
||||
The `getState()` method is called every time the settings are saved (for example, on frame deactivation or when closing the IDE). If the state returned from `getState()` is equal to the default state (obtained by creating the state class with a default constructor), nothing is persisted in the XML. Otherwise, the returned state is serialized in XML and stored.
|
||||
|
||||
## Legacy API (JDOMExternalizable)
|
||||
|
||||
Older IDEA components use the ```JDOMExternalizable``` interface for persisting state.
|
||||
It uses the ```readExternal()``` method for reading the state from a JDOM element, and ```writeExternal()``` to write the state to it.
|
||||
```JDOMExternalizable``` implementations can store the state in attributes and sub-elements manually, and/or use the ```DefaultJDOMExternalizer``` class to store the values of all public fields automatically.
|
||||
Older IDEA components use the `JDOMExternalizable` interface for persisting state.
|
||||
It uses the `readExternal()` method for reading the state from a JDOM element, and `writeExternal()` to write the state to it.
|
||||
`JDOMExternalizable` implementations can store the state in attributes and sub-elements manually, and/or use the `DefaultJDOMExternalizer` class to store the values of all public fields automatically.
|
||||
|
||||
When the component's class implements the ```JDOMExternalizable``` interface, the components save their state in the following files:
|
||||
When the component's class implements the `JDOMExternalizable` interface, the components save their state in the following files:
|
||||
|
||||
* Project-level components save their state to the project (.ipr) file. However, if the workspace option in the plugin.xml file is set to _true_, the component saves its configuration to the workspace (.iws) file instead.
|
||||
* Module-level components save their state to the module (.iml) file.
|
||||
|
@ -6,6 +6,6 @@ To load the classes of each plugin, IntelliJ IDEA uses a separate class loader.
|
||||
This allows each plugin to use a different version of a library, even if the same library is used by IntelliJ IDEA itself or by another plugin.
|
||||
|
||||
By default, the main IntelliJ IDEA class loader loads classes that were not found in the plugin class loader.
|
||||
However, in the plugin.xml file, you may use the ```<depends>``` element to specify that a plugin depends on one or more other plugins.
|
||||
However, in the plugin.xml file, you may use the `<depends>` element to specify that a plugin depends on one or more other plugins.
|
||||
In this case the class loaders of those plugins will be used for classes not found in the current plugin.
|
||||
This allows a plugin to reference classes from other plugins.
|
||||
|
@ -21,7 +21,7 @@ instance by using the `getComponent(Class)` method.
|
||||
Project-level components are created for each
|
||||
[Project](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/project/Project.java)
|
||||
instance in IntelliJ IDEA. (Please note that components may be created even for unopened projects.)
|
||||
They can be acquired from the Project instance by using the ```getComponent(Class)``` method.
|
||||
They can be acquired from the Project instance by using the `getComponent(Class)` method.
|
||||
|
||||
Module-level components are created for each
|
||||
[Module](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/module/Module.java)
|
||||
@ -39,7 +39,7 @@ or
|
||||
Interface and implementation classes may be the same.
|
||||
|
||||
Each component has a unique name which is used for its externalization and other internal needs.
|
||||
The name of a component is returned by its ```getComponentName()``` method.
|
||||
The name of a component is returned by its `getComponentName()` method.
|
||||
|
||||
### Components Naming Notation
|
||||
|
||||
@ -52,12 +52,12 @@ Optionally, application-level component's implementation class may implement the
|
||||
interface.
|
||||
An application component that has no dependencies should have a constructor with no parameters which will be used for its instantiation.
|
||||
If an application component depends on other application components, it can specify these components as constructor parameters. IntelliJ IDEA will ensure that the components are instantiated in the correct order to satisfy the dependencies.
|
||||
Note that application-level components must be registered in the ```<application-components>``` section of the plugin.xml file (see Plugin Configuration File below).
|
||||
Note that application-level components must be registered in the `<application-components>` section of the plugin.xml file (see Plugin Configuration File below).
|
||||
|
||||
#### Quick creation of application components
|
||||
|
||||
*IntelliJ IDEA* suggests a simplified way to create application components, with all the required infrastructure.
|
||||
The IntelliJ interface will help you declare the application component's implementation class, and will automatically make appropriate changes to the ```<application-components>``` section of the *plugin.xml* file.
|
||||
The IntelliJ interface will help you declare the application component's implementation class, and will automatically make appropriate changes to the `<application-components>` section of the *plugin.xml* file.
|
||||
|
||||
**To create and register an application component:**
|
||||
|
||||
@ -81,13 +81,13 @@ The constructor of a project-level component can have a parameter of the
|
||||
type, if it needs the project instance.
|
||||
It can also specify other application-level or project-level components as parameters, if it depends on those components.
|
||||
|
||||
Note that project-level components must be registered in the ```<project-components>``` section of the *plugin.xml* file (see Plugin Configuration File below).
|
||||
Note that project-level components must be registered in the `<project-components>` section of the *plugin.xml* file (see Plugin Configuration File below).
|
||||
|
||||
#### Quick creation of project components
|
||||
|
||||
<!--TODO Link to demo source code -->
|
||||
*IntelliJ IDEA* suggests a simplified way to create project components, with all the required infrastructure.
|
||||
The IDEA interface will help you declare the project component's implementation class, and will automatically make appropriate changes to the ```<project-components>``` section of the `plugin.xml` file.
|
||||
The IDEA interface will help you declare the project component's implementation class, and will automatically make appropriate changes to the `<project-components>` section of the `plugin.xml` file.
|
||||
|
||||
**To create and register a project component**
|
||||
|
||||
@ -110,7 +110,7 @@ interface.
|
||||
The constructor of a module-level component can have a parameter of the Module type, if it needs the module instance.
|
||||
It can also specify other application-level, project-level or module-level components as parameters, if it depends on those components.
|
||||
|
||||
Note that module-level components must be registered in the ```<module-components>``` section of the `plugin.xml` file (see Plugin Configuration File below).
|
||||
Note that module-level components must be registered in the `<module-components>` section of the `plugin.xml` file (see Plugin Configuration File below).
|
||||
|
||||
#### Quick creation of module components
|
||||
|
||||
@ -160,9 +160,9 @@ For more information and samples, refer to
|
||||
|
||||
The defaults (components' predefined settings) should be placed in the `<component_name>.xml` file.
|
||||
Place this file in the plugin's classpath in the folder corresponding to the default package.
|
||||
The ```readExternal()``` method will be called on the `<component>` root tag.
|
||||
The `readExternal()` method will be called on the `<component>` root tag.
|
||||
|
||||
If a component has defaults, the ```readExternal()``` method is called twice:
|
||||
If a component has defaults, the `readExternal()` method is called twice:
|
||||
|
||||
* the first time for defaults
|
||||
|
||||
@ -174,31 +174,31 @@ The components are loaded in the following order:
|
||||
|
||||
* Creation - constructor is invoked.
|
||||
|
||||
* Initialization - the ```initComponent``` method is invoked (if the component implements the
|
||||
* Initialization - the `initComponent` method is invoked (if the component implements the
|
||||
[ApplicationComponent](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/components/ApplicationComponent.java)
|
||||
interface).
|
||||
|
||||
* Configuration - the ```readExternal``` method is invoked (if the component implements
|
||||
* Configuration - the `readExternal` method is invoked (if the component implements
|
||||
[JDOMExternalizable](https://github.com/JetBrains/intellij-community/blob/master/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java)
|
||||
interface), or the ```loadState``` method is invoked (if the component implements
|
||||
interface), or the `loadState` method is invoked (if the component implements
|
||||
[PersistentStateComponent](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/components/PersistentStateComponent.java)
|
||||
and has non-default persisted state).
|
||||
|
||||
* For module components, the ```moduleAdded``` method of the
|
||||
* For module components, the `moduleAdded` method of the
|
||||
[ModuleComponent](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/module/ModuleComponent.java)
|
||||
interface is invoked to notify that a module has been added to the project.
|
||||
|
||||
* For project components, the ```projectOpened``` method of the
|
||||
* For project components, the `projectOpened` method of the
|
||||
[ProjectComponent](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/components/ProjectComponent.java)
|
||||
interface is invoked to notify that a project has been loaded.
|
||||
|
||||
The components are unloaded in the following order:
|
||||
|
||||
* Saving configuration - the ```writeExternal``` method is invoked (if the component implements the
|
||||
* Saving configuration - the `writeExternal` method is invoked (if the component implements the
|
||||
[JDOMExternalizable](https://github.com/JetBrains/intellij-community/blob/master/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java)
|
||||
interface), or the ```getState``` method is invoked (if the component implements PersistentStateComponent).
|
||||
interface), or the `getState` method is invoked (if the component implements PersistentStateComponent).
|
||||
|
||||
* Disposal - the ```disposeComponent``` method is invoked.
|
||||
* Disposal - the `disposeComponent` method is invoked.
|
||||
|
||||
Note that you should not request any other components using the ```getComponent()``` method in the constructor of your component, otherwise you'll get an assertion.
|
||||
If you need access to other components when initializing your component, you can specify them as constructor parameters or access them in the ```initComponent``` method.
|
||||
Note that you should not request any other components using the `getComponent()` method in the constructor of your component, otherwise you'll get an assertion.
|
||||
If you need access to other components when initializing your component, you can specify them as constructor parameters or access them in the `initComponent` method.
|
||||
|
@ -15,11 +15,11 @@ If you want your plugin to extend the functionality of other plugins or the IDEA
|
||||
|
||||
## How to Declare Extensions and Extension Points?
|
||||
|
||||
You can declare extensions and extension points in the plugin configuration file plugin.xml, within the ```<extensions>``` and ```<extensionPoints>``` sections, respectively.
|
||||
You can declare extensions and extension points in the plugin configuration file plugin.xml, within the `<extensions>` and `<extensionPoints>` sections, respectively.
|
||||
|
||||
*To declare an extension point*
|
||||
|
||||
* In the ```<extensionPoints>``` section, insert a child element ```<extensionPoint>``` that defines the extension point name and the name of a bean class or an interface that is allowed to extend the plugin functionality in the *'name'*, *'beanClass'* and *'interface'* attributes, respectively.
|
||||
* In the `<extensionPoints>` section, insert a child element `<extensionPoint>` that defines the extension point name and the name of a bean class or an interface that is allowed to extend the plugin functionality in the *'name'*, *'beanClass'* and *'interface'* attributes, respectively.
|
||||
|
||||
To clarify this procedure, consider the following sample section of the plugin.xml file:
|
||||
|
||||
@ -36,7 +36,7 @@ The *beanClass* attribute sets a bean class that specifies one or several proper
|
||||
[@Attribute](https://github.com/JetBrains/intellij-community/blob/master/xml/dom-openapi/src/com/intellij/util/xml/Attribute.java)
|
||||
annotation.
|
||||
The plugin that contributes to the extension point will read those properties from the plugin.xml file.
|
||||
To clarify this, consider the following sample ```MyBeanClass1``` bean class used in the above plugin.xml file:
|
||||
To clarify this, consider the following sample `MyBeanClass1` bean class used in the above plugin.xml file:
|
||||
|
||||
```java
|
||||
public class MyBeanClass1 extends AbstractExtensionPointBean {
|
||||
|
@ -3,7 +3,7 @@ title: Plugin Services
|
||||
---
|
||||
|
||||
*IntelliJ Platform* provides the concept of _services_.
|
||||
A _service_ is a plugin component loaded on demand, when your plugin calls the ```getService``` method of the
|
||||
A _service_ is a plugin component loaded on demand, when your plugin calls the `getService` method of the
|
||||
[ServiceManager](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/components/ServiceManager.java)
|
||||
class.
|
||||
*IntelliJ Platform* ensures that only one instance of a service is loaded even though the service is called several times.
|
||||
|
@ -105,12 +105,12 @@ See
|
||||
[Persisting State of Components](http://www.jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html)
|
||||
for more information.
|
||||
|
||||
Note that hereafter, the ```project``` variable is of the ```Project``` type.
|
||||
For example, for the opened project, you can get it from an action: ```Project project = e.getProject();```
|
||||
Note that hereafter, the `project` variable is of the `Project` type.
|
||||
For example, for the opened project, you can get it from an action: `Project project = e.getProject();`
|
||||
|
||||
#### How do I get a list of source roots for all modules in my project?
|
||||
|
||||
Use the ```ProjectRootManager.getContentSourceRoots()``` method.
|
||||
Use the `ProjectRootManager.getContentSourceRoots()` method.
|
||||
To clarify this, consider the following code snippet:
|
||||
|
||||
|
||||
@ -128,65 +128,65 @@ Messages.showInfoMessage("Source roots for the " + projectName + " plugin:\n" +
|
||||
|
||||
#### How do I check whether a file is related to a project?
|
||||
|
||||
**IntelliJ Platform** provides the ```ProjectFileIndex``` interface you can use to verify whether a file or directory is related to the specified IDEA project.
|
||||
**IntelliJ Platform** provides the `ProjectFileIndex` interface you can use to verify whether a file or directory is related to the specified IDEA project.
|
||||
This section explains how you can use this interface.
|
||||
|
||||
##### How do I get an instance of the ProjectFileIndex interface?
|
||||
|
||||
Use the ```ProjectRootManager.getFileIndex()``` method. For example:
|
||||
```ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();```
|
||||
Use the `ProjectRootManager.getFileIndex()` method. For example:
|
||||
`ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();`
|
||||
|
||||
##### How do I get a module to which a file belongs?
|
||||
|
||||
To determine a module in the project in question to which the specified
|
||||
[virtual file](http://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/virtual_file.html)
|
||||
belongs, use the ```ProjectFileIndex.getModuleForFile(virtualFile)``` method:
|
||||
belongs, use the `ProjectFileIndex.getModuleForFile(virtualFile)` method:
|
||||
|
||||
```
|
||||
Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);
|
||||
```
|
||||
|
||||
Note that this method returns ```null``` if the file does not belong to any module.
|
||||
Note that this method returns `null` if the file does not belong to any module.
|
||||
|
||||
You can also use the ```ProjectFileIndex.getContentRootForFile``` method to get the module content root to which the specified file or directory belongs:
|
||||
You can also use the `ProjectFileIndex.getContentRootForFile` method to get the module content root to which the specified file or directory belongs:
|
||||
|
||||
```VirtualFile moduleContentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFileorDirectory);```
|
||||
`VirtualFile moduleContentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFileorDirectory);`
|
||||
|
||||
|
||||
##### How do I get the module source root or library source root to which the specified file or directory belongs?
|
||||
|
||||
Use the ```ProjectFileIndex.getSourceRootForFile``` method. For example:
|
||||
Use the `ProjectFileIndex.getSourceRootForFile` method. For example:
|
||||
|
||||
```VirtualFile moduleSourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(virtualFileorDirectory);
|
||||
```
|
||||
Note that this method returns ```null``` if the file or directory does not belong to any source root of modules in the project.
|
||||
Note that this method returns `null` if the file or directory does not belong to any source root of modules in the project.
|
||||
|
||||
##### How do I check whether a file or directory is related to the project libraries?
|
||||
|
||||
The ```ProjectFileIndex``` interface implements a number of methods you can use to check whether the specified file belongs to the project library classes or library sources.
|
||||
The `ProjectFileIndex` interface implements a number of methods you can use to check whether the specified file belongs to the project library classes or library sources.
|
||||
You can use the following methods:
|
||||
|
||||
* ```ProjectFileIndex.isLibraryClassFile(virtualFile)```: Returns ```true``` if the specified ```virtualFile``` is a compiled class file.
|
||||
* `ProjectFileIndex.isLibraryClassFile(virtualFile)`: Returns `true` if the specified `virtualFile` is a compiled class file.
|
||||
|
||||
* ```ProjectFileIndex.isInLibraryClasses(virtualFileorDirectory)```: Returns ```true``` if the specified ```virtualFileorDirectory``` belongs to library classes.
|
||||
* `ProjectFileIndex.isInLibraryClasses(virtualFileorDirectory)`: Returns `true` if the specified `virtualFileorDirectory` belongs to library classes.
|
||||
|
||||
* ```ProjectFileIndex.isInLibrarySource(virtualFileorDirectory)```: Returns ```true``` if the specified ```virtualFileorDirectory``` belongs to library sources.
|
||||
* `ProjectFileIndex.isInLibrarySource(virtualFileorDirectory)`: Returns `true` if the specified `virtualFileorDirectory` belongs to library sources.
|
||||
|
||||
##### How do I get the project SDK?
|
||||
|
||||
* To get the project-level SDK: ```Sdk projectSDK = ProjectRootManager.getInstance(project).getProjectSdk();```
|
||||
* To get the project-level SDK: `Sdk projectSDK = ProjectRootManager.getInstance(project).getProjectSdk();`
|
||||
|
||||
* To get the project-level SDK name: ```String projectSDKName = ProjectRootManager.getInstance(project).getProjectSdkName();```
|
||||
* To get the project-level SDK name: `String projectSDKName = ProjectRootManager.getInstance(project).getProjectSdkName();`
|
||||
|
||||
##### How do I set the project SDK?
|
||||
|
||||
##### To set the project-level SDK:
|
||||
|
||||
```ProjectRootManager.getInstance(project).setProjectSdk(Sdk jdk);```
|
||||
`ProjectRootManager.getInstance(project).setProjectSdk(Sdk jdk);`
|
||||
|
||||
##### To set the project-level SDK name:
|
||||
|
||||
```ProjectRootManager.getInstance(project).setProjectSdkName(String name);```
|
||||
`ProjectRootManager.getInstance(project).setProjectSdkName(String name);`
|
||||
|
||||
Note that by default, the project modules use the project SDK. Optionally, you can configure individual SDK for each module.
|
||||
|
||||
@ -206,7 +206,7 @@ This section discusses how to complete some common tasks related to management o
|
||||
|
||||
#### How do I get a list of modules the project includes?
|
||||
|
||||
Use the ```ModuleManager.getModules()``` method.
|
||||
Use the `ModuleManager.getModules()` method.
|
||||
|
||||
#### How do I get dependencies and classpath of a module?
|
||||
|
||||
@ -228,7 +228,7 @@ VirtualFile[] roots = ModuleRootManager.getInstance(module).orderEntries().class
|
||||
|
||||
#### 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](https://github.com/JetBrains/intellij-community/blob/master/platform/projectModel-api/src/com/intellij/openapi/projectRoots/Sdk.java)
|
||||
type.
|
||||
@ -243,7 +243,7 @@ String jdkInfo = "Module: " + module.getName() + " SDK: " + SDK.getName() + " SD
|
||||
|
||||
#### How do I get a list of modules on which this module directly depends?
|
||||
|
||||
Use the ```ModuleRootManager.getDependencies()``` method to get an array of the ```Module``` type values or the ```ModuleRootManager.getDependencyModuleNames()``` to get an array of module names. To clarify, consider the following code snippet:
|
||||
Use the `ModuleRootManager.getDependencies()` method to get an array of the `Module` type values or the `ModuleRootManager.getDependencyModuleNames()` to get an array of module names. To clarify, consider the following code snippet:
|
||||
|
||||
```java
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
@ -253,14 +253,14 @@ String[] dependentModulesNames = moduleRootManager.getDependencyModuleNames();
|
||||
|
||||
#### How do I get a list of modules that depend on this module?
|
||||
|
||||
Use the ```ModuleManager.getModuleDependentModules(module)``` method.
|
||||
Use the `ModuleManager.getModuleDependentModules(module)` method.
|
||||
|
||||
Note that you can also check whether a module (*module1*) depends on another specified module (*module2*) using the ```ModuleManager.isModuleDependent``` method in the following way:
|
||||
```boolean isDependent = ModuleManager.getInstance(project).isModuleDependent(module1,module2);```
|
||||
Note that you can also check whether a module (*module1*) depends on another specified module (*module2*) using the `ModuleManager.isModuleDependent` method in the following way:
|
||||
`boolean isDependent = ModuleManager.getInstance(project).isModuleDependent(module1,module2);`
|
||||
|
||||
#### How do I get a module to which the specified file or PSI element belongs?
|
||||
|
||||
* To get the project module to which the specified file belongs, use the ```ModuleUtil.findModuleForFile()``` static method.
|
||||
* To get the project module to which the specified file belongs, use the `ModuleUtil.findModuleForFile()` static method.
|
||||
To clarify, consider the following code snippet:
|
||||
|
||||
```java
|
||||
@ -272,13 +272,13 @@ String moduleName = module == null ? "Module not found" : module.getName();
|
||||
|
||||
* To get the project module to which the specified
|
||||
[PSI element](http://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/psi_elements.html)
|
||||
belongs, use the ```ModuleUtil.findModuleForPsiElement(psiElement)``` method.
|
||||
belongs, use the `ModuleUtil.findModuleForPsiElement(psiElement)` method.
|
||||
|
||||
#### How do I work with libraries available within a module?
|
||||
|
||||
##### How do I get a list of libraries available within a module?
|
||||
|
||||
To get the list of libraries, use ```OrderEnumerator#forEachLibrary``` method.
|
||||
To get the list of libraries, use `OrderEnumerator#forEachLibrary` method.
|
||||
To clarify this, consider the following code snippet that illustrates how to output the list of libraries for the specified module:
|
||||
|
||||
```java
|
||||
@ -292,11 +292,11 @@ ModuleRootManager.getInstance(module).orderEntries().forEachLibrary(new Processo
|
||||
});
|
||||
Messages.showInfoMessage(StringUtil.join(libraryNames, "\n"), "Libraries in Module");
|
||||
```
|
||||
This sample code outputs a list of libraries for the ```module``` module.
|
||||
This sample code outputs a list of libraries for the `module` module.
|
||||
|
||||
##### How do I get the library content?
|
||||
|
||||
The ```Library``` class provides the ```getUrls``` method you can use to get a list of source roots and classes the library includes.
|
||||
The `Library` class provides the `getUrls` method you can use to get a list of source roots and classes the library includes.
|
||||
To clarify, consider the following code snippet:
|
||||
|
||||
```java
|
||||
@ -312,7 +312,7 @@ for (String each : lib.getUrls(OrderRootType.CLASSES)) {
|
||||
Messages.showInfoMessage(roots.toString(), "Library Info");
|
||||
```
|
||||
|
||||
In this sample code, ```lib``` is of the
|
||||
In this sample code, `lib` is of the
|
||||
[Library](https://github.com/JetBrains/intellij-community/blob/master/platform/projectModel-api/src/com/intellij/openapi/roots/libraries/Library.java)
|
||||
type.
|
||||
|
||||
|
@ -9,37 +9,37 @@ it talks about working with the PSI of existing languages (such as Java).
|
||||
|
||||
### How do I find a file if I know its name but don't know the path?
|
||||
|
||||
```FilenameIndex.getFilesByName()```
|
||||
`FilenameIndex.getFilesByName()`
|
||||
|
||||
### How do I find where a particular PSI element is used?
|
||||
|
||||
```ReferencesSearch.search()```
|
||||
`ReferencesSearch.search()`
|
||||
|
||||
### How do I rename a PSI element?
|
||||
|
||||
```RefactoringFactory.createRename()```
|
||||
`RefactoringFactory.createRename()`
|
||||
|
||||
### How can I cause the PSI for a virtual file to be rebuilt?
|
||||
|
||||
```FileContentUtil.reparseFiles()```
|
||||
`FileContentUtil.reparseFiles()`
|
||||
|
||||
## Java Specific
|
||||
|
||||
### How do I find all inheritors of a class?
|
||||
|
||||
```ClassInheritorsSearch.search()```
|
||||
`ClassInheritorsSearch.search()`
|
||||
|
||||
### How do I find a class by qualified name?
|
||||
|
||||
```JavaPsiFacade.findClass()```
|
||||
`JavaPsiFacade.findClass()`
|
||||
|
||||
### How do I find a class by short name?
|
||||
|
||||
```PsiShortNamesCache.getInstance().getClassesByName()```
|
||||
`PsiShortNamesCache.getInstance().getClassesByName()`
|
||||
|
||||
### How do I find a superclass of a Java class?
|
||||
|
||||
```PsiClass.getSuperClass()```
|
||||
`PsiClass.getSuperClass()`
|
||||
|
||||
### How do I get a reference to the containing package of a Java class?
|
||||
|
||||
@ -50,4 +50,4 @@ PsiPackage pkg = JavaPsiFacade.getInstance(project).findPackage(javaFile.getPack
|
||||
|
||||
### How do I find the methods overriding a specific method?
|
||||
|
||||
```OverridingMethodsSearch.search()```
|
||||
`OverridingMethodsSearch.search()`
|
||||
|
@ -10,15 +10,15 @@ The standard execution of a run action goes through the following steps:
|
||||
|
||||
* The *ExecutionEnvironment* object is created. The object aggregates all the settings required to execute the process, as well as the selected ProgramRunner.
|
||||
|
||||
* ```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``` 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 is initialized.
|
||||
* `RunProfile.getState()` method is called to create a `RunProfileState` 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 is initialized.
|
||||
|
||||
* ```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``` object aggregating the console and the process handler.
|
||||
* `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` 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 toolwindow.
|
||||
* The `RunContentBuilder` object is created and invoked to display the execution console in a tab of the Run or Debug toolwindow.
|
||||
|
||||
## Executor
|
||||
|
||||
@ -33,7 +33,7 @@ However, it can be useful, for example, if you're implementing a profiler integr
|
||||
|
||||
## Running a Process
|
||||
|
||||
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 which is ready to be started and holds the 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 to modify the parameters before it gets executed.)
|
||||
|
||||
@ -52,20 +52,20 @@ base class. It knows about the command line parameters of the JVM and can take c
|
||||
To monitor the execution of a process and capture its output, the
|
||||
[OSProcessHandler](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java)
|
||||
class is normally 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 start capturing 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 start capturing its output.
|
||||
You may also want to attach a [ProcessTerminatedListener](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/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 the Process Output
|
||||
|
||||
If you're using ```CommandLineState```, a console view will be automatically created and attached to the output of the process.
|
||||
If you're using `CommandLineState`, a console view will be automatically created and attached to the output of the process.
|
||||
Alternatively, you can arrange this yourself:
|
||||
|
||||
* ```TextConsoleBuilderFactory.createBuilder(project).getConsole()``` creates a
|
||||
* `TextConsoleBuilderFactory.createBuilder(project).getConsole()` creates a
|
||||
[ConsoleView](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/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 process you're running uses ANSI escape codes to color its output, the
|
||||
[ColoredProcessHandler](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/execution/process/ColoredProcessHandler.java)
|
||||
@ -73,7 +73,7 @@ class will parse it and display the colors in the IntelliJ console.
|
||||
|
||||
Console
|
||||
[filters](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/execution/filters/Filter.java)
|
||||
allow 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()```.
|
||||
allow 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()`.
|
||||
Two common filter implementations you may want to reuse are
|
||||
[RegexpFilter](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/execution/filters/RegexpFilter.java)
|
||||
and
|
||||
@ -84,5 +84,5 @@ and
|
||||
If you have an existing run configuration that you need to execute, the easiest way to do so is to use
|
||||
[ProgramRunnerUtil.executeConfiguration](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java#L110).
|
||||
The method takes a Project, a RunnerAndConfigurationSettings, as well as an Executor.
|
||||
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()```.
|
||||
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()`.
|
||||
|
@ -73,7 +73,7 @@ When implementing a run configuration, you may want to use one of the common bas
|
||||
is a general-purpose superclass that contains the most basic implementation of a run configuration.
|
||||
|
||||
* [LocatableConfigurationBase](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/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```.
|
||||
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.
|
||||
|
||||
* [ModuleBasedConfiguration](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/execution/configurations/ModuleBasedConfiguration.java)
|
||||
@ -109,9 +109,9 @@ class, which combines a run configuration with runner-specific settings, as well
|
||||
|
||||
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:
|
||||
|
||||
* ```RunManager.createConfiguration()``` creates an instance of ```RunnerAndConfigurationSettings```;
|
||||
* `RunManager.createConfiguration()` creates an instance of `RunnerAndConfigurationSettings`;
|
||||
|
||||
* ```RunManager.addConfiguration()``` makes it persistent by adding it to either the list of shared configurations stored in a project, or to the list of local configurations stored in the workspace file.
|
||||
* `RunManager.addConfiguration()` makes it persistent by adding it to either the list of shared configurations stored in a project, or to the list of local configurations stored in the workspace file.
|
||||
|
||||
<div id="refactoring-support"/>
|
||||
|
||||
@ -121,22 +121,22 @@ Most run configurations contain references to classes, files or directories in t
|
||||
In order to support that, your run configuration needs to implement the
|
||||
[RefactoringListenerProvider](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/execution/configurations/RefactoringListenerProvider.java)
|
||||
interface.
|
||||
In your implementation of ```getRefactoringElementListener()```, you need to check whether the element being refactored is the one that your run configuration refers to, and if it is, you return a ```RefactoringElementListener``` that updates your configuration according to the new name and location of the element.
|
||||
In your implementation of `getRefactoringElementListener()`, you need to check whether the element being refactored is the one that your run configuration refers to, and if it is, you return a `RefactoringElementListener` that updates your configuration according to the new name and location of the element.
|
||||
|
||||
## 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. In order to support that, you need to provide an implementation of the
|
||||
[RunConfigurationProducer](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/execution/actions/RunConfigurationProducer.java)
|
||||
interface and to register it as `<runConfigurationProducer>` in your plugin.xml.
|
||||
(Note that this API has been redesigned in IntelliJ IDEA 13; ```RuntimeConfigurationProducer``` is an older and much more confusing version of the same API).
|
||||
(Note that this API has been redesigned in IntelliJ IDEA 13; `RuntimeConfigurationProducer` is an older and much more confusing version of the same API).
|
||||
|
||||
The two main methods that you need to implement are:
|
||||
|
||||
* ```setupConfigurationFromContext``` receives a blank configuration of your type and a ```ConfigurationContext``` containing information about a source code location (accessible by calling ```getLocation()``` or ```getPsiLocation()```).
|
||||
* `setupConfigurationFromContext` receives a blank configuration of your type and a `ConfigurationContext` containing information about a source code location (accessible by calling `getLocation()` or `getPsiLocation()`).
|
||||
Your implementation needs to check whether the location is applicable for your configuration type (for example, if it's in a file of the language you're supporting).
|
||||
If not, you need to return false, and if it is, you need to put the correct context-specific settings into the run configuration and return true.
|
||||
|
||||
* ```isConfigurationFromContext``` checks if the specified configuration of your type was created from the specified context.
|
||||
* `isConfigurationFromContext` checks if the specified configuration of your type was created from the specified context.
|
||||
Implementing this method allows you to reuse an existing run configuration which is applicable to the current context instead of creating a new one and possibly ignoring the customisations the user has performed in the existing one.
|
||||
|
||||
Note that, in order to support automatic naming of configurations created from context, your configuration should use
|
||||
|
@ -5,7 +5,7 @@ title: Settings, Caches, Logs, and Plugins
|
||||
Every IntelliJ-based IDE stores it's local settings, caches, log and installed plugins on a hard drive.
|
||||
Location of the IDE files depends on the operating system, product and version.
|
||||
IDE settings directory name is made up of the product code name and product version.
|
||||
We will use ```<product_system_name><product_version>``` as an alias for the product internal settings home directory name.
|
||||
We will use `<product_system_name><product_version>` as an alias for the product internal settings home directory name.
|
||||
|
||||
## Directories Location
|
||||
|
||||
@ -14,11 +14,11 @@ We will use ```<product_system_name><product_version>``` as an alias for the pro
|
||||
|
||||
* **Windows:**
|
||||
You can find internal configuration data in:
|
||||
```<User home>\.<product_system_name><product_version>```
|
||||
`<User home>\.<product_system_name><product_version>`
|
||||
|
||||
* **Linux:**
|
||||
You can find internal configuration data in:
|
||||
```~/.<product_system_name><product_version>```
|
||||
`~/.<product_system_name><product_version>`
|
||||
|
||||
|
||||
In the folder you can find two subdirectories:
|
||||
@ -31,15 +31,15 @@ We will use ```<product_system_name><product_version>``` as an alias for the pro
|
||||
|
||||
You can find internal configuration data in:
|
||||
|
||||
```/Applications/<product_system_name><product_version>/Contents/plugins``` contains the catalog with plugins.
|
||||
`/Applications/<product_system_name><product_version>/Contents/plugins` contains the catalog with plugins.
|
||||
|
||||
```~/Library/Preferences/<product_system_name><product_version>``` contains the rest of the configuration settings.
|
||||
`~/Library/Preferences/<product_system_name><product_version>` contains the rest of the configuration settings.
|
||||
|
||||
```~/Library/Caches/<product_system_name><product_version>``` contains data caches, logs, local history, etc.
|
||||
`~/Library/Caches/<product_system_name><product_version>` contains data caches, logs, local history, etc.
|
||||
|
||||
These files can be quite significant in size.
|
||||
|
||||
```~/Library/Logs/<product_system_name><product_version>``` contains logs.
|
||||
`~/Library/Logs/<product_system_name><product_version>` contains logs.
|
||||
|
||||
## Product System Names
|
||||
|
||||
|
@ -16,12 +16,12 @@ Because of the performance difference, we recommend plugin developers to write l
|
||||
|
||||
The standard way of writing a light test is to extend the following classes:
|
||||
|
||||
* ```LightPlatformCodeInsightFixtureTestCase``` for tests that don't have any Java dependencies
|
||||
* `LightPlatformCodeInsightFixtureTestCase` for tests that don't have any Java dependencies
|
||||
|
||||
* ```LightCodeInsightFixtureTestCase``` for tests that require the Java PSI or any related functionality
|
||||
* `LightCodeInsightFixtureTestCase` for tests that require the Java PSI or any related functionality
|
||||
|
||||
When writing a light test, you can specify the requirements for the project that you need to have in your test, such as the module type, the configured SDK, facets, libraries etc.
|
||||
You do so by extending the ```LightProjectDescriptor``` class and returning your project descriptor from ```LightCodeInsightFixtureTestCase.getProjectDescriptor()```.
|
||||
You do so by extending the `LightProjectDescriptor` class and returning your project descriptor from `LightCodeInsightFixtureTestCase.getProjectDescriptor()`.
|
||||
Before executing each test, the project will be reused if the test case returns the same project descriptor as the previous one, or recreated if the descriptor is different.
|
||||
|
||||
**Note:**
|
||||
|
@ -3,9 +3,9 @@ title: Test Project and Testdata Directories
|
||||
---
|
||||
|
||||
The test fixture creates a *test project* environment.
|
||||
Unless you customize the project creation, the test project will have one module with one source root called "```src```".
|
||||
The files for the test project physically exist either in a temporary directory or in an in-memory file system, depending on which implementation of ```TempDirTestFixture``` is used.
|
||||
```LightPlatformCodeInsightFixtureTestCase``` uses an in-memory implementation; if you set up the test environment by calling ```IdeaTestFixtureFactory.createCodeInsightFixture```, you can specify the implementation to use.
|
||||
Unless you customize the project creation, the test project will have one module with one source root called "`src`".
|
||||
The files for the test project physically exist either in a temporary directory or in an in-memory file system, depending on which implementation of `TempDirTestFixture` is used.
|
||||
`LightPlatformCodeInsightFixtureTestCase` uses an in-memory implementation; if you set up the test environment by calling `IdeaTestFixtureFactory.createCodeInsightFixture`, you can specify the implementation to use.
|
||||
|
||||
**Note:**
|
||||
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.
|
||||
@ -13,29 +13,29 @@ If you get an unexpected error after a series of successful runs, **try running
|
||||
|
||||
In your plugin, you normally store the test data for your tests (such as files on which plugin features will be executed and expected output files) in the *testdata* directory.
|
||||
This is just a directory under the content root of your plugin, but not under a source root. Files in testdata are normally not valid source code and must not be compiled.
|
||||
To specify the location of testdata, you must override the ```LightPlatformCodeInsightFixtureTestCase.getTestDataPath()``` method.
|
||||
To specify the location of testdata, you must override the `LightPlatformCodeInsightFixtureTestCase.getTestDataPath()` method.
|
||||
The default implementation assumes running as part of the IntelliJ Platform source tree and is not appropriate for third-party plugins.
|
||||
|
||||
**Note:**
|
||||
A very common pattern in IntelliJ Platform tests is to use the name of the test method being executed as the base for building the testdata file paths.
|
||||
This allows to reuse most of the code between different test methods that test different aspects of the same feature, and this approach is also recommended for third-party plugin tests.
|
||||
The name of the test method can be retrieved using ```UsefulTestCase.getTestName()```.
|
||||
The name of the test method can be retrieved using `UsefulTestCase.getTestName()`.
|
||||
|
||||
To copy files or directories from your testdata directory to the test project directory, you can use the ```copyFileToProject()``` and ```copyDirectoryToProject()``` methods in the ```CodeInsightTestFixture``` class.
|
||||
To copy files or directories from your testdata directory to the test project directory, you can use the `copyFileToProject()` and `copyDirectoryToProject()` methods in the `CodeInsightTestFixture` class.
|
||||
|
||||
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()```.
|
||||
To copy a file from the testdata directory to the test project directory and immediately open it in the editor, you can use the ```CodeInsightTestFixture.configureByFile()``` or ```configureByFiles()``` methods.
|
||||
The in-memory editor instance is returned by `CodeInsightTestFixture.getEditor()`.
|
||||
To copy a file from the testdata 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.
|
||||
|
||||
Alternatively, you can use one of the other methods which take parameters annotated with ```@TestDataFile```.
|
||||
Alternatively, you can use one of the other methods which take parameters annotated with `@TestDataFile`.
|
||||
These methods copy the specified files from the testdata 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.
|
||||
|
||||
When a file is opened in the in-memory editor, special markup in the file content can be used to specify the caret position or selection.
|
||||
You can use one of the following markers:
|
||||
|
||||
* ```<caret>``` specifies the position where the caret should be placed;
|
||||
* `<caret>` specifies the position where the caret should be placed;
|
||||
|
||||
* ```<selection>``` and ```</selection>``` specify the start and end of the text range to be selected;
|
||||
* `<selection>` and `</selection>` specify the start and end of the text range to be selected;
|
||||
|
||||
* ```<block>``` and ```</block>``` specify the start and end points of the column selection.
|
||||
* `<block>` and `</block>` specify the start and end points of the column selection.
|
||||
|
@ -5,12 +5,12 @@ title: Testing Highlighting
|
||||
A common task when writing plugin tests 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.
|
||||
|
||||
To test the highlighting for the file currently loaded into the in-memory editor, you invoke the ```checkHighlighting()``` method.
|
||||
To test the highlighting for the file currently loaded into the in-memory editor, you invoke the `checkHighlighting()` method.
|
||||
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.
|
||||
Alternatively, you can use the ```testHighlighting()``` method, which loads a testdata file into the in-memory editor and highlights it as a single operation.
|
||||
Alternatively, you can use the `testHighlighting()` method, which loads a testdata file into the in-memory editor and highlights it as a single operation.
|
||||
|
||||
If you need to test inspections (rather than generic highlighting provided by a highlighting lexer or annotator), you need to enable inspections that you're testing.
|
||||
This is done by calling ```CodeInsightTestFixture.enableInspections()``` in the setup method of your test or directly in a test method, before the call to checkHighlighting().
|
||||
This is done by calling `CodeInsightTestFixture.enableInspections()` in the setup method of your test or directly in a test method, before the call to checkHighlighting().
|
||||
|
||||
The expected results of the highlighting are specified directly in the source file.
|
||||
The platform supports an extensive XML-like markup language for this. In its simplest form, the markup looks like this:
|
||||
@ -30,27 +30,27 @@ public int <warning descr="The compareTo() method does not reference 'foo' which
|
||||
The tag name specifies the severity of the expected highlighting.
|
||||
The following severities are supported:
|
||||
|
||||
* ```<error>```
|
||||
* `<error>`
|
||||
|
||||
* ```<warning>```
|
||||
* `<warning>`
|
||||
|
||||
* ```<weak_warning>```
|
||||
* `<weak_warning>`
|
||||
|
||||
* ```<info>```
|
||||
* `<info>`
|
||||
|
||||
* ```<inject>``` (for an injected fragment)
|
||||
* `<inject>` (for an injected fragment)
|
||||
|
||||
* ```<symbolName>``` (for a marker that highlights an identifier according to its type)
|
||||
* `<symbolName>` (for a marker that highlights an identifier according to its type)
|
||||
|
||||
* any custom severity can be referenced by its name
|
||||
|
||||
|
||||
The tag can also have the following optional attributes:
|
||||
|
||||
* ```descr``` expected message associated with the highlighter (if not specified, any text will match; if the message contains a quotation mark, it can be escaped by putting two backslash characters before it)
|
||||
* `descr` expected message associated with the highlighter (if not specified, any text will match; if the message contains a quotation mark, it can be escaped by putting two backslash characters before it)
|
||||
|
||||
* ```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``` enum for possible values)
|
||||
* `effectType` expected effect type for the highlighting (see `EffectType` enum for possible values)
|
||||
|
||||
* ```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)
|
||||
|
@ -8,5 +8,5 @@ In fact, the IntelliJ IDEA team uses both JUnit, TestNG and Cucumber for testing
|
||||
However, most of the tests are written using JUnit 3.
|
||||
|
||||
When writing your own 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 ```LightPlatformCodeInsightFixtureTestCase``` (despite being one of the longest and ugliest class names you'll run into in the IntelliJ Platform API, it's actually the recommended approach for writing tests).
|
||||
With the latter approach, you use the ```IdeaTestFixtureFactory``` class to create instances of fixtures for the test environment, and you need to call the fixture creation and setup methods from the test setup method used by your test framework.
|
||||
With the former approach, you can use classes such as `LightPlatformCodeInsightFixtureTestCase` (despite being one of the longest and ugliest class names you'll run into in the IntelliJ Platform API, it's actually the recommended approach for writing tests).
|
||||
With the latter approach, you use the `IdeaTestFixtureFactory` class to create instances of fixtures for the test environment, and you need to call the fixture creation and setup methods from the test setup method used by your test framework.
|
||||
|
@ -5,18 +5,18 @@ title: Writing Tests
|
||||
In most cases, once you have the necessary files copied to the test project and loaded into the in-memory editor, writing the test itself involves invoking your plugin code and has few dependencies on the test framework.
|
||||
However, for many common cases the framework provides helper methods that can make testing easier:
|
||||
|
||||
* ```type()``` simulates the typing of a character or string into the in-memory editor;
|
||||
* `type()` simulates the typing of a character or string into the in-memory editor;
|
||||
|
||||
* ```performEditorAction()``` simulates the execution of an action in the context of the in-memory editor;
|
||||
* `performEditorAction()` simulates the execution of an action in the context of the in-memory editor;
|
||||
|
||||
* ```complete()``` simulates the invocation of code completion and returns the list of lookup elements displayed in the completion list (or ```null``` if the completion had no suggestions or one suggestion which was auto-inserted);
|
||||
* `complete()` simulates the invocation of code completion and returns the list of lookup elements displayed in the completion list (or `null` if the completion had no suggestions or one suggestion which was auto-inserted);
|
||||
|
||||
* ```findUsages()``` simulates the invocation of 'Find Usages' and returns the found usages;
|
||||
* `findUsages()` simulates the invocation of 'Find Usages' and returns the found usages;
|
||||
|
||||
* ```findSingleIntention()``` in combination with ```launchAction()``` simulate the invocation of an intention action or inspection quickfix with the specified name;
|
||||
* `findSingleIntention()` in combination with `launchAction()` simulate the invocation of an intention action or inspection quickfix with the specified name;
|
||||
|
||||
* ```renameElementAtCaret()``` or ```rename()``` simulate the execution of a rename refactoring.
|
||||
* `renameElementAtCaret()` or `rename()` simulate the execution of a rename refactoring.
|
||||
|
||||
To compare the results of executing the action with the expected results, you can use the ```checkResultByFile()``` method.
|
||||
To compare the results of executing the action with the expected results, you can use the `checkResultByFile()` method.
|
||||
The file with the expected results can also contain markup to specify the expected caret position or selected text range.
|
||||
If you're testing an action which modifies multiple files (a project-wide refactoring, for example), you can compare an entire directory under the test project with the expected output using ```PlatformTestUtil.assertDirectoriesEqual()```.
|
||||
If you're testing an action which modifies multiple files (a project-wide refactoring, for example), you can compare an entire directory under the test project with the expected output using `PlatformTestUtil.assertDirectoriesEqual()`.
|
||||
|
@ -96,7 +96,7 @@ package.
|
||||
|
||||
##How do I get a list of source roots for all modules in my project?
|
||||
Use the
|
||||
```ProjectRootManager.getContentSourceRoots() method```.
|
||||
`ProjectRootManager.getContentSourceRoots() method`.
|
||||
To clarify this, see the following:
|
||||
|
||||
[code sample] (https://github.com/JetBrains/intellij-sdk/blob/master/code_samples/project_model/src/com/intellij/plugins/project/model/ShowSourceRootsActions.java).
|
||||
@ -107,18 +107,18 @@ to get this information.
|
||||
|
||||
###How do I get an instance of the ProjectFileIndex interface?
|
||||
Use the ProjectRootManager.getFileIndex() method. For example:
|
||||
```ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();```
|
||||
`ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();`
|
||||
|
||||
###How do I get a module to which a file belongs?
|
||||
To determine a module in the project in question to which the specified virtual file belongs, use the
|
||||
ProjectFileIndex.getModuleForFile(virtualFile) method:
|
||||
|
||||
```Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);```
|
||||
`Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);`
|
||||
|
||||
Note that this method returns null if the file does not belong to any module.
|
||||
You can also use the ProjectFileIndex.getContentRootForFile method to get the module content root to which the specified file or directory belongs:
|
||||
|
||||
```VirtualFile moduleContentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFileOrDirectory);```
|
||||
`VirtualFile moduleContentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFileOrDirectory);`
|
||||
|
||||
[Code sample] (https://github.com/JetBrains/intellij-sdk/blob/master/code_samples/project_model/src/com/intellij/plugins/project/model/ProjectFileIndexSampleAction.java)
|
||||
|
||||
@ -126,7 +126,7 @@ You can also use the ProjectFileIndex.getContentRootForFile method to get the mo
|
||||
|
||||
Use the ProjectFileIndex.getSourceRootForFile method. For example:
|
||||
|
||||
```VirtualFile moduleSourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(virtualFileOrDirectory);```
|
||||
`VirtualFile moduleSourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(virtualFileOrDirectory);`
|
||||
|
||||
Note that this method returns null if the file or directory does not belong to any source root of modules in the project.
|
||||
|
||||
@ -136,22 +136,22 @@ Note that this method returns null if the file or directory does not belong to a
|
||||
The ProjectFileIndex interface implements a number of methods you can use to check whether the specified file belongs to the project library classes or library sources.
|
||||
You can use the following methods:
|
||||
|
||||
* ```ProjectFileIndex.isLibraryClassFile(virtualFile)```: Returns true if the specified virtualFile is a compiled class file.
|
||||
* ```ProjectFileIndex.isInLibraryClasses(virtualFileorDirectory)```: Returns true if the specified virtualFileorDirectory belongs to library classes.
|
||||
* ```ProjectFileIndex.isInLibrarySource(virtualFileorDirectory)```: Returns true if the specified virtualFileorDirectory belongs to library sources.
|
||||
* `ProjectFileIndex.isLibraryClassFile(virtualFile)`: Returns true if the specified virtualFile is a compiled class file.
|
||||
* `ProjectFileIndex.isInLibraryClasses(virtualFileorDirectory)`: Returns true if the specified virtualFileorDirectory belongs to library classes.
|
||||
* `ProjectFileIndex.isInLibrarySource(virtualFileorDirectory)`: Returns true if the specified virtualFileorDirectory belongs to library sources.
|
||||
|
||||
[Code sample] (https://github.com/JetBrains/intellij-sdk/blob/master/code_samples/project_model/src/com/intellij/plugins/project/model/ProjectFileIndexSampleAction.java)
|
||||
|
||||
###How do I get and set the project SDK?
|
||||
* To get the project-level SDK: ```Sdk projectSDK = ProjectRootManager.getInstance(project).getProjectSdk();```
|
||||
* To get the project-level SDK name: ```String projectSDKName = ProjectRootManager.getInstance(project).getProjectSdkName();```
|
||||
* To set the project-level SDK: ```ProjectRootManager.getInstance(project).setProjectSdk(Sdk jdk);```
|
||||
* To set the project-level SDK name: ```ProjectRootManager.getInstance(project).setProjectSdkName(String name);```
|
||||
* To get the project-level SDK: `Sdk projectSDK = ProjectRootManager.getInstance(project).getProjectSdk();`
|
||||
* To get the project-level SDK name: `String projectSDKName = ProjectRootManager.getInstance(project).getProjectSdkName();`
|
||||
* To set the project-level SDK: `ProjectRootManager.getInstance(project).setProjectSdk(Sdk jdk);`
|
||||
* To set the project-level SDK name: `ProjectRootManager.getInstance(project).setProjectSdkName(String name);`
|
||||
|
||||
Note that by default, the project modules use the project SDK. Optionally, you can configure individual SDK for each module.
|
||||
|
||||
###How to get a file module?
|
||||
```final Module currentModule = fileIndex.getModuleForFile(virtualFile);```
|
||||
`final Module currentModule = fileIndex.getModuleForFile(virtualFile);`
|
||||
|
||||
###How to get a module file index?
|
||||
Information about model roots can be accessed via the class
|
||||
@ -162,7 +162,7 @@ can be obtained, which is analogical to the
|
||||
[ProjectFileIndex.java] (https://github.com/JetBrains/intellij-community/blob/master/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java)
|
||||
but in the scope of a module
|
||||
|
||||
```ModuleRootManager.getInstance(currentModule).getFileIndex()```
|
||||
`ModuleRootManager.getInstance(currentModule).getFileIndex()`
|
||||
|
||||
##Changing the project structure
|
||||
Utility classes which can be used for modifying a project structure can be found in the package
|
||||
@ -194,7 +194,7 @@ Main information about the project Sdk can be accessed via
|
||||
[ProjectRootManager.java] (https://github.com/JetBrains/intellij-community/blob/master/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java)
|
||||
like the following example shows
|
||||
|
||||
```String projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();```
|
||||
`String projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();`
|
||||
|
||||
[Code sample] (https://github.com/JetBrains/intellij-sdk/blob/master/code_samples/project_model/src/com/intellij/plugins/project/model/ProjectSdkAction.java)
|
||||
|
||||
|
@ -25,7 +25,7 @@ These classes and interfaces serve the following purposes:
|
||||
|
||||
###Module type
|
||||
To create a new module type and an extension
|
||||
```<moduleType id="MY_MODULE" implementationClass="st.redline.smalltalk.module.MyModuleType"/>```
|
||||
`<moduleType id="MY_MODULE" implementationClass="st.redline.smalltalk.module.MyModuleType"/>`
|
||||
to the [plugin.xml] (https://github.com/bulenkov/RedlineSmalltalk/blob/master/resources/META-INF/plugin.xml).
|
||||
A custom module type should extend the
|
||||
[ModuleType.java] (https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/openapi/module/ModuleType.java)
|
||||
@ -47,8 +47,8 @@ class should be extended and registered as an extension point like the following
|
||||
|
||||
Functionality which is mandatory to implement consists of:
|
||||
|
||||
* Setting up a root model for the new module by overriding ```public abstract void setupRootModel(ModifiableRootModel modifiableRootModel) throws ConfigurationException;```
|
||||
* Getting a module type ```public abstract ModuleType getModuleType();```
|
||||
* Setting up a root model for the new module by overriding `public abstract void setupRootModel(ModifiableRootModel modifiableRootModel) throws ConfigurationException;`
|
||||
* Getting a module type `public abstract ModuleType getModuleType();`
|
||||
|
||||
See
|
||||
[JavaModuleBuilder.java] (https://github.com/JetBrains/intellij-community/blob/master/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java)
|
||||
@ -67,14 +67,14 @@ Module builder listener reacts on a new module creation, which could be done eit
|
||||
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.java] (https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilderListener.java)
|
||||
Method ```public void moduleCreated(@NotNull final Module module);``` executed tasks right after a module has been created,
|
||||
Method `public void moduleCreated(@NotNull final Module module);` executed tasks right after a module has been created,
|
||||
these may include configuring roots looking up for an SDK and setting it up, adding a specific facet if required and others.
|
||||
For more details please see this
|
||||
[code sample] (https://github.com/bulenkov/RedlineSmalltalk/blob/master/src/st/redline/smalltalk/module/RsModuleType.java)
|
||||
|
||||
###Adding new wizard steps
|
||||
Adding new steps to the module wizard can be done by overriding the
|
||||
``` public ModuleWizardStep[] createWizardSteps(WizardContext wizardContext, ModulesProvider modulesProvider);```
|
||||
` public ModuleWizardStep[] createWizardSteps(WizardContext wizardContext, ModulesProvider modulesProvider);`
|
||||
method in a custom
|
||||
[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 objects, new steps will be shown in their indexing oder while creating a new module.
|
||||
@ -85,8 +85,8 @@ This class is derived from
|
||||
[ModuleWizardStep.java] (https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleWizardStep.java),
|
||||
which has two methods to be overridden:
|
||||
|
||||
* ```public JComponent getComponent();``` defines how the step will look like
|
||||
* ```public void updateDataModel();``` commits data from UI into ModuleBuilder and WizardContext
|
||||
* `public JComponent getComponent();` defines how the step will look like
|
||||
* `public void updateDataModel();` commits data from UI into ModuleBuilder and WizardContext
|
||||
|
||||
#Facet
|
||||
Facets in IntelliJ are the way to store multiple kinds of module-specific settings, for instance to make a language support or framework available in some given module.
|
||||
|
@ -54,7 +54,7 @@ See also
|
||||
[SpacingBuilder](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-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.
|
||||
If the block before the cursor is incomplete (contains elements that the user will probably type but has not yet typed, like a closing parenthesis of the parameter list or the trailing semicolon of a statement), `getChildAttributes()` is called on the block before the caret; otherwise, it's called on the parent block.
|
||||
|
||||
|
@ -14,4 +14,4 @@ for
|
||||
[Properties language plugin](https://github.com/JetBrains/intellij-community/tree/master/plugins/properties/)
|
||||
|
||||
|
||||
The `getQuickNavigateInfo()` method returns the text to be displayed when the user holds the mouse over an element with ```Ctrl``` pressed.
|
||||
The `getQuickNavigateInfo()` method returns the text to be displayed when the user holds the mouse over an element with `Ctrl` pressed.
|
||||
|
@ -2,7 +2,7 @@
|
||||
title: Find Usages
|
||||
---
|
||||
|
||||
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](https://github.com/JetBrains/intellij-community/blob/master/platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java)
|
||||
in the `com.intellij.lang.findUsagesProvider` extension point, and through the PSI implementation using
|
||||
@ -18,9 +18,9 @@ in
|
||||
[Properties language plugin](https://github.com/JetBrains/intellij-community/tree/master/plugins/properties/)
|
||||
|
||||
|
||||
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](https://github.com/JetBrains/intellij-community/blob/master/platform/indexing-api/src/com/intellij/lang/cacheBuilder/WordsScanner.java)
|
||||
implementation returned from
|
||||
|
@ -2,10 +2,10 @@
|
||||
title: Go to Class and Go to Symbol
|
||||
---
|
||||
|
||||
A custom language plugin can provide its own items to be included in the lists shown when the user chooses the ```Go to | Class...``` or ```Go to | Symbol...``` action.
|
||||
A custom language plugin can provide its own items to be included in the lists shown when the user chooses the `Go to | Class...` or `Go to | Symbol...` action.
|
||||
In order to do so, the plugin must provide implementations for the
|
||||
[ChooseByNameContributor](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/navigation/ChooseByNameContributor.java)
|
||||
interface (separate implementations need to be provided for ```Go to Class``` and ```Go to Symbol```), and register them in the `com.intellij.gotoClassContributor` and `com.intellij.gotoSymbolContributor` extension points.
|
||||
interface (separate implementations need to be provided for `Go to Class` and `Go to Symbol`), and register them in the `com.intellij.gotoClassContributor` and `com.intellij.gotoSymbolContributor` extension points.
|
||||
|
||||
Each contributor needs to be able to return a complete list of names to show in the list for a specified project, which will then be filtered by the IDE according to the text typed by the user in the dialog.
|
||||
For each name in that list, the contributor needs to provide a list of
|
||||
|
@ -13,13 +13,13 @@ The IDE invokes the lexer in three main contexts, and the plugin can provide dif
|
||||
|
||||
* Syntax highlighting: The lexer is returned from the implementation of the
|
||||
[SyntaxHighlighterFactory](https://github.com/JetBrains/intellij-community/blob/master/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: the lexer is expected to be returned from
|
||||
[ParserDefinition.createLexer()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lang/ParserDefinition.java),
|
||||
and the
|
||||
[ParserDefinition](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lang/ParserDefinition.java)
|
||||
interface is registered in the ```com.intellij.lang.parserDefinition``` extension point.
|
||||
interface is registered in the `com.intellij.lang.parserDefinition` extension point.
|
||||
|
||||
* 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
|
||||
@ -49,8 +49,8 @@ The source code of
|
||||
[IntelliJ IDEA Community Edition](https://github.com/JetBrains/intellij-community)
|
||||
includes a patched version of JFlex 1.4 located in *tools/lexer/jflex-1.4* and lexer skeleton file *tools/lexer/idea-flex.skeleton* which can be used for creating lexers compatible with
|
||||
[FlexAdapter](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lexer/FlexAdapter.java).
|
||||
The patched version of JFlex provides a new command line option ```--charat``` which changes the JFlex generated code so that it works with the IntelliJ Platform skeleton.
|
||||
Enabling ```--charat``` option passes the source data for lexing as a
|
||||
The patched version of JFlex provides a new command line option `--charat` which changes the JFlex generated code so that it works with the IntelliJ Platform skeleton.
|
||||
Enabling `--charat` option passes the source data for lexing as a
|
||||
[CharSequence](https://docs.oracle.com/javase/8/docs/api/java/lang/CharSequence.html)
|
||||
and not as an array of characters.
|
||||
|
||||
|
@ -83,20 +83,20 @@ If a pair of markers is nested in another pair (starts after its start and ends
|
||||
The element type for the marker pair and for the AST node created from it is specified when the end marker is set, which is done by making call to
|
||||
[PsiBuilder.Marker.done()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lang/PsiBuilder.java).
|
||||
Also, it is possible to drop a start marker before its end marker has been set.
|
||||
The ```drop()``` method drops only a single start marker without affecting any markers added after it, and the ```rollbackTo()``` method drops the start marker and all markers added after it and reverts the lexer position to the start marker.
|
||||
The `drop()` method drops only a single start marker without affecting any markers added after it, and the `rollbackTo()` method drops the start marker and all markers added after it and reverts the lexer position to the start marker.
|
||||
These methods can be used to implement lookahead when parsing.
|
||||
|
||||
The method
|
||||
[PsiBuilder.Marker.precede()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lang/PsiBuilder.java)
|
||||
is useful for right-to-left parsing when you don't know how many markers you need at a certain position until you read more input.
|
||||
For example, a binary expression ```a+b+c``` needs to be parsed as ```( (a+b) + c )```.
|
||||
For example, a binary expression `a+b+c` needs to be parsed as `( (a+b) + c )`.
|
||||
Thus, two start markers are needed at the position of the token 'a', but that is not known until the token 'c' is read.
|
||||
When the parser reaches the '+' token following 'b', it can call `precede()` to duplicate the start marker at 'a' position, and then put its matching end marker after 'c'.
|
||||
|
||||
An important feature of
|
||||
[PsiBuilder](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lang/PsiBuilder.java)
|
||||
is its handling of whitespace and comments.
|
||||
The types of tokens which are treated as whitespace or comments are defined by the methods ```getWhitespaceTokens()``` and ```getCommentTokens()``` in the
|
||||
The types of tokens which are treated as whitespace or comments are defined by the methods `getWhitespaceTokens()` and `getCommentTokens()` in the
|
||||
[ParserDefinition](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lang/ParserDefinition.java)
|
||||
class.
|
||||
[PsiBuilder](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lang/PsiBuilder.java)
|
||||
@ -116,9 +116,9 @@ In general, there is no single right way to implement a PSI for a custom languag
|
||||
However, there is one base interface which needs to be used by a custom language PSI implementation in order to support features like rename and find usages.
|
||||
Every element which can be renamed or referenced (a class definition, a method definition and so on) needs to implement the
|
||||
[PsiNamedElement](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/PsiNamedElement.java)
|
||||
interface, with methods ```getName()``` and ```setName()```.
|
||||
interface, with methods `getName()` and `setName()`.
|
||||
|
||||
A number of 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
|
||||
A number of 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
|
||||
[PsiUtil](https://github.com/JetBrains/intellij-community/blob/master/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java)
|
||||
and
|
||||
[PsiTreeUtil](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java)
|
||||
|
@ -4,9 +4,9 @@ title: References and Resolve
|
||||
|
||||
One of the most important and tricky parts in the implementation of a custom language PSI is resolving references.
|
||||
Resolving references means the ability to go from the usage of an element (access of a variable, call of a method and so on) to the declaration of the element (the variable definition, the method declaration and so on).
|
||||
This is obviously needed in order to support ```Go to Declaration``` action invoked by **Ctrl-B** and **Ctrl-Click**, and it is also a prerequisite for the ```Find Usages``` action, the ```Rename``` refactoring and the code completion.
|
||||
This is obviously needed in order to support `Go to Declaration` action invoked by **Ctrl-B** and **Ctrl-Click**, and it is also a prerequisite for the `Find Usages` action, the `Rename` refactoring and the code completion.
|
||||
|
||||
All PSI elements which work as references (for which the ```Go to Declaration``` action applies) need to implement the
|
||||
All PSI elements which work as references (for which the `Go to Declaration` action applies) need to implement the
|
||||
[PsiElement.getReference()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/PsiElement.java)
|
||||
method and to return a
|
||||
[PsiReference](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/PsiReference.java)
|
||||
@ -21,9 +21,9 @@ and return the references as an array.
|
||||
|
||||
The main method of the
|
||||
[PsiReference](https://github.com/JetBrains/intellij-community/blob/master/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, it points to an undefined class).
|
||||
A counterpart to this method is ```isReferenceTo()```, which checks if the reference resolves to the specified element.
|
||||
The latter method can be implemented by calling ```resolve()``` and comparing the result with the passed PSI element, but additional optimizations (for example, performing the tree walk only if the text of the element is equal to the text of the reference) are possible.
|
||||
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, it points to an undefined class).
|
||||
A counterpart to this method is `isReferenceTo()`, which checks if the reference resolves to the specified element.
|
||||
The latter method can be implemented by calling `resolve()` and comparing the result with the passed PSI element, but additional optimizations (for example, performing the tree walk only if the text of the element is equal to the text of the reference) are possible.
|
||||
|
||||
**Example**:
|
||||
[Reference](https://github.com/JetBrains/intellij-community/blob/master/plugins/properties/src/com/intellij/lang/properties/ResourceBundleReference.java)
|
||||
@ -71,9 +71,9 @@ interface, which allows a reference to resolve to multiple targets, is the
|
||||
[PsiPolyVariantReference](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/PsiPolyVariantReference.java)
|
||||
interface.
|
||||
The targets to which the reference resolves are returned from the `multiResolve()` method.
|
||||
The ```Go to Declaration``` action for such references allows the user to choose the target to navigate to.
|
||||
The `Go to Declaration` action for such references allows the user to choose the target to navigate to.
|
||||
The implementation of `multiResolve()` can be also based on
|
||||
[PsiScopeProcessor](https://github.com/JetBrains/intellij-community/blob/master/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 ```Quick Definition Lookup``` action is based on the same mechanism as ```Go to Declaration```, so it becomes automatically available for all references which can be resolved by the language plugin.
|
||||
The `Quick Definition Lookup` action is based on the same mechanism as `Go to Declaration`, so it becomes automatically available for all references which can be resolved by the language plugin.
|
||||
|
@ -12,7 +12,7 @@ which passes a
|
||||
implementation class to its base class constructor.
|
||||
To register a file type, the plugin developer provides an implementation of the
|
||||
[FileTypeFactory](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeFactory.java)
|
||||
interface, which is registered via the ```com.intellij.fileTypeFactory```
|
||||
interface, which is registered via the `com.intellij.fileTypeFactory`
|
||||
[platform extension point](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml).
|
||||
|
||||
**Example**:
|
||||
|
@ -23,7 +23,7 @@ implementation for a
|
||||
|
||||
Another interface related to the Rename refactoring is
|
||||
[NamesValidator](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/lang/refactoring/NamesValidator.java).
|
||||
This interface 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.
|
||||
This interface 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.
|
||||
Implementations of
|
||||
[NamesValidator](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/lang/refactoring/NamesValidator.java)
|
||||
|
@ -3,18 +3,18 @@ title: Safe Delete Refactoring
|
||||
---
|
||||
|
||||
|
||||
The ```Safe Delete``` refactoring also builds on the same ```Find Usages``` framework as ```Rename```.
|
||||
In addition to that, in order to support ```Safe Delete```, a plugin needs to implement two things:
|
||||
The `Safe Delete` refactoring also builds on the same `Find Usages` framework as `Rename`.
|
||||
In addition to that, in order to support `Safe Delete`, a plugin needs to implement two things:
|
||||
|
||||
* The
|
||||
[RefactoringSupportProvider](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/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
|
||||
[PsiElement.delete()](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/psi/PsiElement.java#L371)
|
||||
method for the
|
||||
[PsiElement](https://github.com/JetBrains/intellij-community/blob/master/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).
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ the plugin can specify which of the child elements of a specific PSI tree node n
|
||||
Another important method is `getPresentation()`, which can be used to customize the text, attributes and icon used to represent an element in the structure view.
|
||||
|
||||
The implementation of `StructureViewTreeElement.getChildren()` needs to be matched by `TextEditorBasedStructureViewModel.getSuitableClasses()`.
|
||||
The latter method returns an array of `PsiElement`\-derived classes which can be shown as structure view elements, and is used to select the Structure View item matching the cursor position when the structure view is first opened or when the ```Autoscroll from source``` option is used.
|
||||
The latter method returns an array of `PsiElement`\-derived classes which can be shown as structure view elements, and is used to select the Structure View item matching the cursor position when the structure view is first opened or when the `Autoscroll from source` option is used.
|
||||
|
||||
**Example:**
|
||||
[StructureViewElement](https://github.com/JetBrains/intellij-community/blob/master/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesStructureViewElement.java)
|
||||
|
@ -2,15 +2,15 @@
|
||||
title: Surround With
|
||||
---
|
||||
|
||||
In order to support the ```Code | Surround With...``` action, the plugin needs to register one or more implementations of the
|
||||
In order to support the `Code | Surround With...` action, the plugin needs to register one or more implementations of the
|
||||
[SurroundDescriptor](https://github.com/JetBrains/intellij-community/blob/master/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 which 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](https://github.com/JetBrains/intellij-community/blob/master/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).
|
||||
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 ```Surround With...``` 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 `Surround With...` 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()](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java#L46)
|
||||
method for each surrounder in that descriptor to check if the specific template is applicable in the current context.
|
||||
|
@ -55,15 +55,15 @@ method can be used to highlight the invalid tokens and display an error message
|
||||
The third level of highlighting is performed through the
|
||||
[Annotator](https://github.com/JetBrains/intellij-community/blob/master/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 PSI tree of the custom language.
|
||||
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 PSI tree of the custom language.
|
||||
Annotators can analyze not only the syntax, but also the semantics using PSI, and thus can provide much more complex syntax and error highlighting logic.
|
||||
The annotator can also provide quick fixes to problems it detects.
|
||||
|
||||
When the file is changed, the annotator is called incrementally to process only changed elements in the PSI tree.
|
||||
|
||||
To highlight a region of text as a warning or error, the annotator calls ```createErrorAnnotation()``` or ```createWarningAnnotation()``` on the
|
||||
To highlight a region of text as a warning or error, the annotator calls `createErrorAnnotation()` or `createWarningAnnotation()` on the
|
||||
[AnnotationHolder](https://github.com/JetBrains/intellij-community/blob/master/platform/analysis-api/src/com/intellij/lang/annotation/AnnotationHolder.java)
|
||||
object passed to it, and optionally calls ```registerFix()``` on the returned
|
||||
object passed to it, and optionally calls `registerFix()` on the returned
|
||||
[Annotation](https://github.com/JetBrains/intellij-community/blob/master/platform/analysis-api/src/com/intellij/lang/annotation/Annotation.java)
|
||||
object to add a quick fix for the error or warning.
|
||||
To apply additional syntax highlighting, the annotator can call
|
||||
@ -95,11 +95,11 @@ interface for converting the output of the external tool into editor highlightin
|
||||
The plugin can also provide a configuration interface to allow the user to configure the colors used for highlighting specific items.
|
||||
In order to do that, it should provide an implementation of
|
||||
[ColorSettingPage](https://github.com/JetBrains/intellij-community/blob/master/platform/lang-api/src/com/intellij/openapi/options/colors/ColorSettingsPage.java)
|
||||
and register it in the ```com.intellij.colorSettingsPage``` extension point.
|
||||
and register it in the `com.intellij.colorSettingsPage` extension point.
|
||||
|
||||
**Example**:
|
||||
[ColorSettingsPage](https://github.com/JetBrains/intellij-community/blob/master/plugins/properties/src/com/intellij/openapi/options/colors/pages/PropertiesColorsPage.java)
|
||||
for
|
||||
[Properties language plugin](https://github.com/JetBrains/intellij-community/tree/master/plugins/properties/)
|
||||
|
||||
The ```Export to HTML``` feature uses the same syntax highlighting mechanism as the editor, so it will work automatically for custom languages which provide a syntax highlighter.
|
||||
The `Export to HTML` feature uses the same syntax highlighting mechanism as the editor, so it will work automatically for custom languages which provide a syntax highlighter.
|
||||
|
@ -14,7 +14,7 @@ When the user invokes an action that involves executing an external build (Make,
|
||||
|
||||
* The external build process is spawned (or an existing build process background process is reused).
|
||||
|
||||
* The external build process loads the project model (.idea, .iml files and so on), represented by a ```JpsModel``` instance.
|
||||
* The external build process loads the project model (.idea, .iml files and so on), represented by a `JpsModel` instance.
|
||||
|
||||
* The full tree of targets to build is calculated, based on the dependencies of each build target to be compiled.
|
||||
|
||||
@ -32,15 +32,15 @@ When the user invokes an action that involves executing an external build (Make,
|
||||
|
||||
To support incremental build, the build process uses a number of 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.
|
||||
|
||||
* ```SourceToOutputMapping``` 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()`.
|
||||
* `SourceToOutputMapping` 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()`.
|
||||
|
||||
* ```Timestamps``` records the timestamp of each source file when it was compiled by each build target. (If the compilation was invoked multiple times with different scopes and the file was changed in the meantime, the last compiled timestamps for different build targets may vary.) It's updated automatically by JPS.
|
||||
* `Timestamps` records the timestamp of each source file when it was compiled by each build target. (If the compilation was invoked multiple times with different scopes and the file was changed in the meantime, the last compiled timestamps for different build targets may vary.) It's updated automatically by JPS.
|
||||
|
||||
The IDE monitors the changes of the project content 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). A builder can also report additional files as dirty (e.g. if a method is deleted, the builder can report the classes using this method as dirty.) A module-level builder can add some files to the dirty scope; if this happens, and if the builder returns ```ADDITIONAL_PASS_REQUIRED``` from its `build()` method, another round of builder execution for the same module chunk will be started with the new dirty scope.
|
||||
The IDE monitors the changes of the project content 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). A builder can also report additional files as dirty (e.g. if a method is deleted, the builder can report the classes using this method as dirty.) A module-level builder can add some files to the dirty scope; if this happens, and if the builder returns `ADDITIONAL_PASS_REQUIRED` from its `build()` method, another round of builder execution for the same module chunk will be started with the new dirty scope.
|
||||
|
||||
A builder may also want to have its custom caches to store additional information to support partial recompilation of a target (e.g. the dependencies between Java files in a module). To store this data, you can either store arbitrary files in the directory returned from ```BuildDataManager.getDataPaths().getTargetDataRoot()``` or use a higher-level API: ```BuildDataManager.getStorage()```
|
||||
A builder may also want to have its custom caches to store additional information to support partial recompilation of a target (e.g. the dependencies between Java files in a module). To store this data, you can either store arbitrary files in the directory returned from `BuildDataManager.getDataPaths().getTargetDataRoot()` or use a higher-level API: `BuildDataManager.getStorage()`
|
||||
|
||||
To pass custom data between the invocation of the same builder between multiple targets, you can use ```CompileContext.getUserData()``` and ```CompileContext.putUserData()```.
|
||||
To pass custom data between the invocation of the same builder between multiple targets, you can use `CompileContext.getUserData()` and `CompileContext.putUserData()`.
|
||||
|
||||
### Services and extensions in External Builder
|
||||
|
||||
|
@ -38,7 +38,7 @@ Spring facets usually contain one more user-configured/provided filesets, which
|
||||
|
||||
A fileset usually corresponds to an actual application context configuration at runtime. Hierarchies can be modeled by depending on another fileset (possibly from another module).
|
||||
|
||||
As an API-user, you will usually rather work with ```SpringModel``` (which is built on top of fileset(s)).
|
||||
As an API-user, you will usually rather work with `SpringModel` (which is built on top of fileset(s)).
|
||||
|
||||
## How do I...
|
||||
**Some core classes have been changed in 14(.1), please see "_Version 14(.1)_" notes for info on how to replace existing API-calls**
|
||||
@ -46,48 +46,48 @@ As an API-user, you will usually rather work with ```SpringModel``` (which is bu
|
||||
### Spring Model
|
||||
|
||||
##### Obtain Spring Model by file, PsiElement, ..
|
||||
See ```SpringManager#getSpringModel(s)...``` and ```com.intellij.spring.model.utils.SpringModelUtils```.
|
||||
See `SpringManager#getSpringModel(s)...` and `com.intellij.spring.model.utils.SpringModelUtils`.
|
||||
|
||||
##### Contribute implicit model(s)
|
||||
See ```com.intellij.spring.SpringModelProvider``` to provide implicit filesets (e.g. provided by another framework in specific configuration file).
|
||||
See `com.intellij.spring.SpringModelProvider` to provide implicit filesets (e.g. provided by another framework in specific configuration file).
|
||||
|
||||
##### Contribute implicit beans
|
||||
See ```com.intellij.spring.model.jam.CustomComponentsDiscoverer``` or ```com.intellij.spring.model.SpringImplicitBeansProviderBase``` to provide implicit (framework-specific) beans (e.g. "servletContext" by Spring MVC).
|
||||
See `com.intellij.spring.model.jam.CustomComponentsDiscoverer` or `com.intellij.spring.model.SpringImplicitBeansProviderBase` to provide implicit (framework-specific) beans (e.g. "servletContext" by Spring MVC).
|
||||
|
||||
##### Contribute custom bean scope
|
||||
_Version 14_
|
||||
See ```com.intellij.spring.model.scope.SpringCustomBeanScope``` to provide custom (e.g. framework specific) bean scopes.
|
||||
See `com.intellij.spring.model.scope.SpringCustomBeanScope` to provide custom (e.g. framework specific) bean scopes.
|
||||
|
||||
##### Obtain/Create Spring Profiles
|
||||
_Version 14.1_
|
||||
```com.intellij.spring.profiles.SpringProfilesFactory```
|
||||
`com.intellij.spring.profiles.SpringProfilesFactory`
|
||||
|
||||
### Beans
|
||||
|
||||
##### Search for bean by name
|
||||
```com.intellij.spring.CommonSpringModel#findBeanByName```
|
||||
`com.intellij.spring.CommonSpringModel#findBeanByName`
|
||||
|
||||
_Version 14_: ```com.intellij.spring.model.utils.SpringModelSearchers#findBean```
|
||||
_Version 14_: `com.intellij.spring.model.utils.SpringModelSearchers#findBean`
|
||||
|
||||
##### Search for beans by type
|
||||
Choose one of ```com.intellij.spring.CommonSpringModel#findBeansByPsiClassXXX``` variants (please note deprecated methods).
|
||||
Choose one of `com.intellij.spring.CommonSpringModel#findBeansByPsiClassXXX` variants (please note deprecated methods).
|
||||
|
||||
_Version 14_: ```com.intellij.spring.model.utils.SpringModelSearchers#findBeans```
|
||||
_Version 14_: `com.intellij.spring.model.utils.SpringModelSearchers#findBeans`
|
||||
|
||||
##### Find out if bean with given name/type exists
|
||||
_Version 14_: ```com.intellij.spring.model.utils.SpringModelSearchers#doesBeanExist``` (please note deprecated methods)
|
||||
_Version 14_: `com.intellij.spring.model.utils.SpringModelSearchers#doesBeanExist` (please note deprecated methods)
|
||||
|
||||
##### Mark bean as infrastructure bean
|
||||
_Version 14_: implement ```SpringInfrastructureBean```, such beans obtain special icon and can be filtered in various places in UI
|
||||
_Version 14_: implement `SpringInfrastructureBean`, such beans obtain special icon and can be filtered in various places in UI
|
||||
|
||||
### XML Configuration
|
||||
All support for XML-based Spring configuration files is provided via [DOM-API](xml_dom_api.md).
|
||||
|
||||
##### Add support for additional Spring namespace
|
||||
See EP ```com.intellij.spring.dom.SpringCustomNamespaces```, registered namespace-key must match the one registered with your DOM elements via ```@Namespace```.
|
||||
Register available elements via standard ```DomExtender<Beans>``` EP or ```com.intellij.spring.dom.SpringCustomNamespaces#registerExtensions``` (Version 14).
|
||||
See EP `com.intellij.spring.dom.SpringCustomNamespaces`, registered namespace-key must match the one registered with your DOM elements via `@Namespace`.
|
||||
Register available elements via standard `DomExtender<Beans>` EP or `com.intellij.spring.dom.SpringCustomNamespaces#registerExtensions` (Version 14).
|
||||
|
||||
Please pay attention to ```getModelVersion``` and ```getStubVersion``` (see javadoc).
|
||||
Please pay attention to `getModelVersion` and `getStubVersion` (see javadoc).
|
||||
|
||||
##### Add reference to Spring Bean in my DomElement
|
||||
Use the following template:
|
||||
@ -113,14 +113,14 @@ JamStringAttributeMeta.Single<SpringBeanPointer> ATTRIBUTE_META =
|
||||
### IDE features
|
||||
|
||||
##### Add inspections to Spring Validator
|
||||
Add additional inspections (e.g. for custom namespace) to Spring Validator (*Settings|Compiler|Validation*) via EP ```com.intellij.spring.SpringInspectionsRegistry$Contributor```.
|
||||
Add additional inspections (e.g. for custom namespace) to Spring Validator (*Settings|Compiler|Validation*) via EP `com.intellij.spring.SpringInspectionsRegistry$Contributor`.
|
||||
|
||||
##### Add additional files to Spring Validator
|
||||
_Version 14.1_
|
||||
Additional files to be processed by inspections registered with Spring Validator (e.g. specific ```.properties``` configuration files) can be registered via ```com.intellij.spring.SpringInspectionsRegistry$AdditionalFilesContributor```
|
||||
Additional files to be processed by inspections registered with Spring Validator (e.g. specific `.properties` configuration files) can be registered via `com.intellij.spring.SpringInspectionsRegistry$AdditionalFilesContributor`
|
||||
|
||||
##### Configure Spring support for other frameworks
|
||||
Use ```com.intellij.spring.facet.SpringConfigurator``` to provide "automatic" configuration when Spring facet is added via framework wizard.
|
||||
Use `com.intellij.spring.facet.SpringConfigurator` to provide "automatic" configuration when Spring facet is added via framework wizard.
|
||||
|
||||
##### UI/Presentation
|
||||
Please do not reference bean icons from ```SpringApiIcons``` directly, but use ```SpringPresentationProvider``` to re-use unified icon/bean name. See ```SpringBeansPsiElementCellRenderer``` for popup/list renderer.
|
||||
Please do not reference bean icons from `SpringApiIcons` directly, but use `SpringPresentationProvider` to re-use unified icon/bean name. See `SpringBeansPsiElementCellRenderer` for popup/list renderer.
|
||||
|
@ -104,7 +104,7 @@ String getValue();
|
||||
void setValue(String s);
|
||||
```
|
||||
|
||||
These method names (`getValue` and `setValue`) are standard, and they are used for accessing tag values by default. If you want to use custom method names for the same goal, you should annotate these methods with ```@TagValue```, for example:
|
||||
These method names (`getValue` and `setValue`) are standard, and they are used for accessing tag values by default. If you want to use custom method names for the same goal, you should annotate these methods with `@TagValue`, for example:
|
||||
|
||||
```java
|
||||
@TagValue
|
||||
|
@ -31,7 +31,7 @@ ModuleRootManager.getInstance(currentModule).getFileIndex()
|
||||
### Checking Belonging to a Module Source Root
|
||||
|
||||
To check if a virtual file or directory belongs to a module source root, use the
|
||||
```ProjectFileIndex.getSourceRootForFile```
|
||||
`ProjectFileIndex.getSourceRootForFile`
|
||||
method.
|
||||
This method returns null if the file or directory does not belong to any source root of modules in the project.
|
||||
|
||||
|
@ -37,7 +37,7 @@ package.
|
||||
### Finding Source Roots
|
||||
|
||||
To get an array of all the source roots for a project use
|
||||
```ProjectRootManager.getContentSourceRoots()```
|
||||
`ProjectRootManager.getContentSourceRoots()`
|
||||
method like this code snippet shows:
|
||||
|
||||
|
||||
|
@ -34,11 +34,11 @@ To create instances of
|
||||
the
|
||||
[VcsContextFactory](https://github.com/JetBrains/intellij-community/blob/master/platform/vcs-api/src/com/intellij/openapi/vcs/actions/VcsContextFactory.java)
|
||||
API is used.
|
||||
It can be accessed as```PeerFactory.getInstance().getVcsContextFactory()```
|
||||
It can be accessed as`PeerFactory.getInstance().getVcsContextFactory()`
|
||||
|
||||
[FilePath](https://github.com/JetBrains/intellij-community/blob/master/platform/vcs-api/vcs-api-core/src/com/intellij/openapi/vcs/FilePath.java)
|
||||
representing paths in a VCS repository, rather than local paths, are created using
|
||||
```VcsContextFactory.createFilePathOnNonLocal()```. ```FilePath.isNonLocal()``` returns true for such files.
|
||||
`VcsContextFactory.createFilePathOnNonLocal()`. `FilePath.isNonLocal()` returns true for such files.
|
||||
|
||||
### Revision Number
|
||||
|
||||
@ -57,14 +57,14 @@ A
|
||||
represents a particular revision of a file, which exists either locally or in a VCS repository.
|
||||
It has three main attributes:
|
||||
|
||||
* ```FilePath``` specifying the file of which this is a revision. If some version of the file exists locally, this should be a local path.
|
||||
* `FilePath` specifying the file of which this is a revision. If some version of the file exists locally, this should be a local path.
|
||||
|
||||
* ```VcsRevisionNumber``` specifying the revision number of the revision, or ```VcsRevisionNumber.NULL``` if the revision exists only locally.
|
||||
* `VcsRevisionNumber` specifying the revision number of the revision, or `VcsRevisionNumber.NULL` if the revision exists only locally.
|
||||
|
||||
* Content of the revision.
|
||||
|
||||
The content is returned as string, and the VCS plugin is responsible for converting the binary file content to correct encoding.
|
||||
To detect the encoding automatically based on the IDE settings and the byte order mark, the method ```CharsetToolkit.bytesToString()``` can be used (this API is new in IDEA 7.0.2).
|
||||
To detect the encoding automatically based on the IDE settings and the byte order mark, the method `CharsetToolkit.bytesToString()` can be used (this API is new in IDEA 7.0.2).
|
||||
Revisions of binary files can also be represented as BinaryContentRevision, which is a subclass of ContentRevision.
|
||||
For binary revisions, the result of getContent() is undefined, and getBinaryContent() can be used to retrieve the contents as a byte array.
|
||||
|
||||
@ -89,9 +89,9 @@ A
|
||||
[Change](https://github.com/JetBrains/intellij-community/blob/master/platform/vcs-api/vcs-api-core/src/com/intellij/openapi/vcs/changes/Change.java)
|
||||
essentially consists of two content revisions:
|
||||
|
||||
* before revision (```null``` if the *Change* represents file creation)
|
||||
* before revision (`null` if the *Change* represents file creation)
|
||||
|
||||
* after revision (```null``` if the *Change* represents file deletion)
|
||||
* after revision (`null` if the *Change* represents file deletion)
|
||||
|
||||
A move or rename is represented by a Change where the before revision and the after revision have different file paths.
|
||||
A custom file status can be specified for a
|
||||
@ -141,7 +141,7 @@ The recommended way to register an AbstractVcs implementation is to add an exten
|
||||
</idea-plugin>
|
||||
```
|
||||
|
||||
Here ```name``` is the unique name of the VCS (this must match the string returned by your implementation of ```AbstractVcs.getName()```), and *vcsClass* is your implementation class.
|
||||
Here `name` is the unique name of the VCS (this must match the string returned by your implementation of `AbstractVcs.getName()`), and *vcsClass* is your implementation class.
|
||||
|
||||
### ChangeProvider
|
||||
|
||||
@ -172,22 +172,22 @@ The
|
||||
[ChangeProvider](https://github.com/JetBrains/intellij-community/blob/master/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeProvider.java)
|
||||
can either iterate all files under the dirty scope using
|
||||
[VcsDirtyScope.iterate()](https://github.com/JetBrains/intellij-community/blob/master/platform/vcs-api/src/com/intellij/openapi/vcs/changes/VcsDirtyScope.java),
|
||||
or retrieve information about its contents using the ```getDirtyFiles()``` and ```getDirtyDirectoriesRecursively()``` methods.
|
||||
or retrieve information about its contents using the `getDirtyFiles()` and `getDirtyDirectoriesRecursively()` methods.
|
||||
If it is possible to retrieve the information about the local changes from the VCS in batch, it's strongly preferable to use the second method, as it scales much better for large working copies.
|
||||
|
||||
The
|
||||
[ChangeProvider](https://github.com/JetBrains/intellij-community/blob/master/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeProvider.java)
|
||||
reports data to ChangelistBuilder using the following methods:
|
||||
|
||||
* ```processChange()``` is called for files which have been checked out (or modified if the VCS doesn't use an explicit checkout model), scheduled for addition or deletion, moved or renamed.
|
||||
* `processChange()` is called for files which have been checked out (or modified if the VCS doesn't use an explicit checkout model), scheduled for addition or deletion, moved or renamed.
|
||||
|
||||
* ```processUnversionedFile()``` is called for files which exist on disk, but are not managed by the VCS, not scheduled for addition, and not ignored through *.cvsignore* or a similar mechanism.
|
||||
* `processUnversionedFile()` is called for files which exist on disk, but are not managed by the VCS, not scheduled for addition, and not ignored through *.cvsignore* or a similar mechanism.
|
||||
|
||||
* ```processLocallyDeletedFile()``` is called for files which exist in the VCS repository, but do not exist on disk and are not scheduled for deletion.
|
||||
* `processLocallyDeletedFile()` is called for files which exist in the VCS repository, but do not exist on disk and are not scheduled for deletion.
|
||||
|
||||
* ```processIgnoredFile()``` is called for files which are not managed by the VCS but are ignored through *.cvsignore* or a similar mechanism.
|
||||
* `processIgnoredFile()` is called for files which are not managed by the VCS but are ignored through *.cvsignore* or a similar mechanism.
|
||||
|
||||
* ```processSwitchedFile()``` is called for files or directories for which the working copy corresponds to a different branch compared to the working copy of their parent directory.
|
||||
* `processSwitchedFile()` is called for files or directories for which the working copy corresponds to a different branch compared to the working copy of their parent directory.
|
||||
This can be called for the same files for which processSwitchedFile() has already been called.
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ The best way to deal with icons and other image resources is to put them to a de
|
||||
|
||||

|
||||
|
||||
Then you should use ```getIcon()``` method of ```com.intellij.openapi.util.IconLoader``` class in your code to get access icons.
|
||||
Then you should use `getIcon()` method of `com.intellij.openapi.util.IconLoader` class in your code to get access icons.
|
||||
You can define a class or an interface with icon constants:
|
||||
|
||||
```java
|
||||
@ -60,7 +60,7 @@ So, every icon should have a copy for Retina devices and Darcula look and feel.
|
||||
|
||||
|
||||
IconLoader will load the icon that matches the best depending on the current environment.
|
||||
So, always use ```IconLoader.getIcon("/iconName.png")```.
|
||||
So, always use `IconLoader.getIcon("/iconName.png")`.
|
||||
Here are examples of *toolWindowStructure.png* icon representations:
|
||||
|
||||
|
||||
|
@ -146,7 +146,7 @@ Action's class should be registered in
|
||||
|
||||
#### 2.2.5. Providing specific behaviour for the group
|
||||
|
||||
In this case we override ```public void update(AnActionEvent event);``` method to make the group visible as a *Tools* menu item,
|
||||
In this case we override `public void update(AnActionEvent event);` method to make the group visible as a *Tools* menu item,
|
||||
however, it will be enabled only if there's an instance of the editor available. Also a custom icon is set up:
|
||||
|
||||
```java
|
||||
@ -203,7 +203,7 @@ For statically defined group of action use
|
||||
|
||||
#### 2.3.3. Accessing children actions
|
||||
|
||||
An array of children actions should be returned by the method ```public AnAction[] getChildren(AnActionEvent anActionEvent);``` of the a created group:
|
||||
An array of children actions should be returned by the method `public AnAction[] getChildren(AnActionEvent anActionEvent);` of the a created group:
|
||||
|
||||
```java
|
||||
public class BaseActionGroup extends ActionGroup {
|
||||
|
@ -28,7 +28,7 @@ public class SimpleAction extends AnAction {
|
||||
|
||||
The only method of an inheritor of
|
||||
[AnAction](https://github.com/JetBrains/intellij-community/blob/master/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java)
|
||||
which needs to be overridden is ```public void actionPerformed(AnActionEvent anActionEvent);```, and it should contain a part of code to be executed after the action has been invoked.
|
||||
which needs to be overridden is `public void actionPerformed(AnActionEvent anActionEvent);`, and it should contain a part of code to be executed after the action has been invoked.
|
||||
In this case the action does nothing.
|
||||
|
||||
```java
|
||||
@ -117,7 +117,7 @@ After performing the steps described above we need to compile and run the plugin
|
||||
|
||||
### 1.5. Performing an action
|
||||
|
||||
In order to make the action do something we need to implement it's ```public void actionPerformed(AnActionEvent anActionEvent);``` method.
|
||||
In order to make the action do something we need to implement it's `public void actionPerformed(AnActionEvent anActionEvent);` method.
|
||||
In the following example action invokes a dialog that shows information about a selected Project View Item and has no icon and any pre-selected default option:
|
||||
|
||||
```java
|
||||
@ -133,7 +133,7 @@ public void actionPerformed(AnActionEvent anActionEvent) {
|
||||
|
||||
### 1.6. Setting up action's visibility and availability
|
||||
|
||||
To manipulate with action's visibility and availability we need to override it's ```public void update(@NotNull AnActionEvent e);```
|
||||
To manipulate with action's visibility and availability we need to override it's `public void update(@NotNull AnActionEvent e);`
|
||||
|
||||
Default implementation of this method does nothing.
|
||||
Override this method to provide the ability to dynamically change action's state and(or) presentation depending on the context.
|
||||
|
@ -50,10 +50,10 @@ public class SimpleLineMarkerProvider extends RelatedItemLineMarkerProvider {
|
||||
## More technical details for implementers
|
||||
|
||||
* Please return line marker info for exact element you were asked for.
|
||||
For example, do not return class marker info if ```getLineMarkerInfo()``` was called for a method.
|
||||
For example, do not return class marker info if `getLineMarkerInfo()` was called for a method.
|
||||
|
||||
* Please return relevant line marker info for as small element as possible.
|
||||
For example, do not return method marker for ```PsiMethod```. Instead, return it for the ```PsiIdentifier``` which is a name of this method.
|
||||
For example, do not return method marker for `PsiMethod`. Instead, return it for the `PsiIdentifier` which is a name of this method.
|
||||
|
||||
### Even more technical details:
|
||||
|
||||
@ -68,7 +68,7 @@ public class MyLineMarkerProvider implements LineMarkerProvider {
|
||||
}
|
||||
```
|
||||
|
||||
Inspection (specifically, ```LineMarkersPass```) for performance reasons queries all ```LineMarkerProviders``` in two passes:
|
||||
Inspection (specifically, `LineMarkersPass`) for performance reasons queries all `LineMarkerProviders` in two passes:
|
||||
|
||||
* first pass for all elements in visible area
|
||||
|
||||
@ -76,14 +76,14 @@ Inspection (specifically, ```LineMarkersPass```) for performance reasons queries
|
||||
|
||||
If providers return nothing for either area, its line markers are cleared.
|
||||
So if e.g. a method is half-visible (its name is visible but part of its body isn't) and
|
||||
some poorly written ```LineMarkerProvider``` returned info for the ```PsiMethod``` instead of ```PsiIdentifier``` then:
|
||||
some poorly written `LineMarkerProvider` returned info for the `PsiMethod` instead of `PsiIdentifier` then:
|
||||
|
||||
* the first pass removes line marker info because whole ```PsiMethod``` is not visible.
|
||||
* the first pass removes line marker info because whole `PsiMethod` is not visible.
|
||||
|
||||
* the second pass tries to add line marker info back because ```LineMarkerProvider``` is called for the ```PsiMethod``` at last.
|
||||
* the second pass tries to add line marker info back because `LineMarkerProvider` is called for the `PsiMethod` at last.
|
||||
|
||||
As a result, line marker icon would blink annoyingly.
|
||||
To fix this, rewrite ```LineMarkerProvider``` to return info for ```PsiIdentifier``` instead of ```PsiMethod```:
|
||||
To fix this, rewrite `LineMarkerProvider` to return info for `PsiIdentifier` instead of `PsiMethod`:
|
||||
|
||||
```java
|
||||
public class MyLineMarkerProvider implements LineMarkerProvider {
|
||||
|
@ -102,7 +102,7 @@ public class EditorAreaIllustration extends AnAction {
|
||||
|
||||
## 2.6. Displaying position values
|
||||
To display the actual values of logical anf visual positions we add an
|
||||
```Messages.showInfoMessage()``` call that will show them in form of notification after the action is performed.
|
||||
`Messages.showInfoMessage()` call that will show them in form of notification after the action is performed.
|
||||
|
||||
```java
|
||||
public class EditorAreaIllustration extends AnAction {
|
||||
|
@ -30,7 +30,7 @@ public class MyTypedHandler implements TypedActionHandler {
|
||||
|
||||
### 3.1.3. Implementing logic for handling keystrokes
|
||||
|
||||
```public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext);```
|
||||
`public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext);`
|
||||
|
||||
method should contain the main logical part for handling keystrokes. It will be called every time a key is pressed.
|
||||
In the following example our typed handler is meant insert a string at the zero offset in the editor after a keystroke occurs:
|
||||
@ -55,7 +55,7 @@ public class MyTypedHandler implements TypedActionHandler {
|
||||
### 3.1.4. Setting up *TypedActionHandler*
|
||||
|
||||
To enable a custom implementation of *TypedActionHandler* in the plugin we need to create a new instance of it and pass to
|
||||
```public TypedActionHandler setupHandler(TypedActionHandler handler);``` method of the
|
||||
`public TypedActionHandler setupHandler(TypedActionHandler handler);` method of the
|
||||
[TypedAction](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedAction.java)
|
||||
class. By doing it we replace the typing handler with the specified handler.
|
||||
|
||||
@ -150,7 +150,7 @@ public class EditorHandlerIllustration extends AnAction {
|
||||
|
||||
### 3.2.4. Making *EditorActionHandler* execute actions
|
||||
|
||||
To execute an action we need to call the ```public final void execute(@NotNull Editor editor, @Nullable final Caret contextCaret, final DataContext dataContext);```
|
||||
To execute an action we need to call the `public final void execute(@NotNull Editor editor, @Nullable final Caret contextCaret, final DataContext dataContext);`
|
||||
method of a corresponding *EditorActionHandler*
|
||||
|
||||
```java
|
||||
|
@ -62,8 +62,8 @@ Further steps will show how to check these conditions through obtaining instance
|
||||
|
||||
## 1.2. Getting an instance of the Active Editor
|
||||
|
||||
A reference to an instance of the Editor can be obtained by calling ```CommonDataKeys.EDITOR```,
|
||||
obtaining a project reference is performed the same way ```CommonDataKeys.PROJECT```.
|
||||
A reference to an instance of the Editor can be obtained by calling `CommonDataKeys.EDITOR`,
|
||||
obtaining a project reference is performed the same way `CommonDataKeys.PROJECT`.
|
||||
|
||||
|
||||
```java
|
||||
@ -84,10 +84,10 @@ public class EditorIllustration extends AnAction {
|
||||
To access an Editor instance also can be used other ways:
|
||||
|
||||
* If [DataContext](https://github.com/JetBrains/intellij-community/blob/master/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/DataContext.java)
|
||||
object is available ```final Editor editor = CommonDataKeys.EDITOR.getData(context);```
|
||||
object is available `final Editor editor = CommonDataKeys.EDITOR.getData(context);`
|
||||
|
||||
* If [ActionEvent](https://github.com/JetBrains/intellij-community/blob/master/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java)
|
||||
object is available ```final Editor editor = actionEvent.getData(CommonDataKeys.EDITOR);```
|
||||
object is available `final Editor editor = actionEvent.getData(CommonDataKeys.EDITOR);`
|
||||
|
||||
|
||||
|
||||
@ -95,8 +95,8 @@ To access an Editor instance also can be used other ways:
|
||||
|
||||
After making sure we have a project open and an instance of the Editor we need to check if any selection is available and set action's visibility accordingly to these conditions.
|
||||
[SelectionModel](https://github.com/JetBrains/intellij-community/blob/master/platform/editor-ui-api/src/com/intellij/openapi/editor/SelectionModel.java)
|
||||
got from the Editor allows to do it by calling it's ```hasSelection()``` method.
|
||||
Here's how our ```update(final AnActionEvent e)``` method should look like at the end:
|
||||
got from the Editor allows to do it by calling it's `hasSelection()` method.
|
||||
Here's how our `update(final AnActionEvent e)` method should look like at the end:
|
||||
|
||||
|
||||
```java
|
||||
@ -133,7 +133,7 @@ package and include:
|
||||
|
||||
The action is visible and available now.
|
||||
In order to make it do something we need to override it's
|
||||
```public void actionPerformed(final AnActionEvent anActionEvent)``` method.
|
||||
`public void actionPerformed(final AnActionEvent anActionEvent)` method.
|
||||
|
||||
|
||||
```java
|
||||
@ -172,7 +172,7 @@ public void actionPerformed(final AnActionEvent anActionEvent) {
|
||||
## 1.5. Modifying text
|
||||
|
||||
Generally replacement can be done by calling
|
||||
```void replaceString(int startOffset, int endOffset, @NotNull CharSequence s);``` of the Document, however,
|
||||
`void replaceString(int startOffset, int endOffset, @NotNull CharSequence s);` of the Document, however,
|
||||
the operation of replacement must be executed safely, this means the Document must be locked and any changes should be performed under the
|
||||
[write action](https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/openapi/command/WriteCommandAction.java#L172).
|
||||
See
|
||||
|
@ -70,7 +70,7 @@ public class DemoFramework extends FrameworkTypeEx {
|
||||
## 4. Creating provider for enabling framework support
|
||||
|
||||
To make framework set up available while executing project creating steps
|
||||
```public FrameworkSupportInModuleProvider createProvider();```
|
||||
`public FrameworkSupportInModuleProvider createProvider();`
|
||||
of the
|
||||
[DemoFramework](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/framework/src/com/intellij/tutorials/framework/DemoFramework.java)
|
||||
must be implemented:
|
||||
|
@ -32,11 +32,11 @@ tab : \u0009
|
||||
### 2.2. Copy the expected PSI tree
|
||||
|
||||
The easiest way to get the expected PSI structure for any file is to use PSI Viewer.
|
||||
Run the project and call ```Tools``` → ```View PSI Structure```.
|
||||
Run the project and call `Tools` → `View PSI Structure`.
|
||||
|
||||

|
||||
|
||||
Use ```Copy PSI``` button to copy the expected PSI structure to the clipboard.
|
||||
Use `Copy PSI` button to copy the expected PSI structure to the clipboard.
|
||||
|
||||
### 2.3. Define an output test data
|
||||
|
||||
|
@ -6,7 +6,7 @@ title: 1. Tests Prerequisites
|
||||
### 1.1. Create a folder for tests
|
||||
|
||||
Open the project with the plugin and create a separate folder "tests".
|
||||
Mark the folder as a test source root via the context menu ```Mark Directory As``` → ```Test Source Root```.
|
||||
Mark the folder as a test source root via the context menu `Mark Directory As` → `Test Source Root`.
|
||||
|
||||
### 1.2. Create a folder for test data
|
||||
|
||||
|
@ -10,7 +10,7 @@ The
|
||||
is the base class which is supposed to be used for all modal dialogs (and some non-modal dialogs) shown in *IntelliJ IDEA* plugins.
|
||||
It provides the following features:
|
||||
|
||||
* Button layout (platform-specific order of ```OK/Cancel``` buttons, Mac OS-specific ```Help``` button)
|
||||
* Button layout (platform-specific order of `OK/Cancel` buttons, Mac OS-specific `Help` button)
|
||||
|
||||
* Context help
|
||||
|
||||
@ -20,13 +20,13 @@ It provides the following features:
|
||||
|
||||
* Keyboard shortcuts
|
||||
|
||||
* ```Esc``` for closing the dialog
|
||||
* `Esc` for closing the dialog
|
||||
|
||||
* ```Left/Right``` for switching between buttons
|
||||
* `Left/Right` for switching between buttons
|
||||
|
||||
* ```Y/N``` for ```Yes/No``` actions if they exist in the dialog
|
||||
* `Y/N` for `Yes/No` actions if they exist in the dialog
|
||||
|
||||
* Optional ```Do not ask again``` checkbox
|
||||
* Optional `Do not ask again` checkbox
|
||||
|
||||
|
||||
When using the
|
||||
@ -35,38 +35,38 @@ class for your own dialog, you need to follow these steps:
|
||||
|
||||
* Call the base class constructor and provide either a project in the frame of which the dialog will be displayed, or a parent component for the dialog.
|
||||
|
||||
* Call the ```init()``` method from the constructor of your dialog class
|
||||
* Call the `init()` method from the constructor of your dialog class
|
||||
|
||||
* Call the setTitle() method to set the title for the dialog box
|
||||
|
||||
* Implement the ```createCenterPanel()``` method to return the component comprising the main contents of the dialog.
|
||||
* Implement the `createCenterPanel()` method to return the component comprising the main contents of the dialog.
|
||||
|
||||
* *Optional*: Override the ```getPreferredFocusedComponent()``` method and return the component that should be focused when the dialog is first displayed.
|
||||
* *Optional*: Override the `getPreferredFocusedComponent()` method and return the component that should be focused when the dialog is first displayed.
|
||||
|
||||
* *Optional*: Override the ```getDimensionServiceKey()``` method to return the identifier which will be used for persisting the dialog dimensions.
|
||||
* *Optional*: Override the `getDimensionServiceKey()` method to return the identifier which will be used for persisting the dialog dimensions.
|
||||
|
||||
* *Optional*: Override the ```getHelpId()``` method to return the context help topic associated with the dialog.
|
||||
* *Optional*: Override the `getHelpId()` method to return the context help topic associated with the dialog.
|
||||
|
||||
The
|
||||
[DialogWrapper](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java)
|
||||
class is often used together with UI Designer forms.
|
||||
In this case, you bind a UI Designer form to your class extending
|
||||
[DialogWrapper](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java),
|
||||
bind the top-level panel of the form to a field and return that field from the ```createCenterPanel()``` method.
|
||||
bind the top-level panel of the form to a field and return that field from the `createCenterPanel()` method.
|
||||
|
||||
To display the dialog, you call the ```show()``` method and then use the ```getExitCode()``` method to check how the dialog was closed.
|
||||
To display the dialog, you call the `show()` method and then use the `getExitCode()` method to check how the dialog was closed.
|
||||
|
||||
To customize the buttons displayed in the dialog (replacing the standard ```OK/Cancel/Help``` set of buttons), you can override either the ```createActions()``` or ```createLeftActions()``` methods.
|
||||
To customize the buttons displayed in the dialog (replacing the standard `OK/Cancel/Help` set of buttons), you can override either the `createActions()` or `createLeftActions()` methods.
|
||||
Both of these methods return an array of Swing Action objects.
|
||||
If the button that you're adding closes the dialog, you can use
|
||||
[DialogWrapperExitAction](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java),
|
||||
as the base class for your action.
|
||||
|
||||
To validate the data entered into the dialog, you can override the ```doValidate()``` method.
|
||||
To validate the data entered into the dialog, you can override the `doValidate()` method.
|
||||
The method will be called automatically by timer.
|
||||
If the currently entered data is valid, you need to return null from your implementation.
|
||||
Otherwise, you need to return a
|
||||
[ValidationInfo](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/ValidationInfo.java)
|
||||
class, which encapsulates an error message and an optional component associated with the invalid data.
|
||||
If you specify a component, an error icon will be displayed next to it, and it will be focused when the user tries to invoke the ```OK``` action.
|
||||
If you specify a component, an error icon will be displayed next to it, and it will be focused when the user tries to invoke the `OK` action.
|
||||
|
||||
|
@ -37,5 +37,5 @@ This can be accomplished with the following steps:
|
||||
|
||||
* Pass the returned document to the
|
||||
[EditorTextField](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-impl/src/com/intellij/ui/EditorTextField.java)
|
||||
constructor or its ```setDocument()``` method.
|
||||
constructor or its `setDocument()` method.
|
||||
|
||||
|
@ -15,15 +15,15 @@ The
|
||||
[FileChooserDescriptor](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java)
|
||||
class allows you to control which files can be selected.
|
||||
The constructor parameters specify whether files and/or directories can be selected, and whether multiple selection is allowed.
|
||||
For more fine-grained control over the allowed selection, you can overload the ```isFileSelectable()``` method.
|
||||
You can also customize the presentation of files by overloading ```getIcon()```, ```getName()``` and ```getComment()``` methods on
|
||||
For more fine-grained control over the allowed selection, you can overload the `isFileSelectable()` method.
|
||||
You can also customize the presentation of files by overloading `getIcon()`, `getName()` and `getComment()` methods on
|
||||
[FileChooserDescriptor](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java).
|
||||
Note that the native Mac OS X file chooser does not support most of the customizations, so if you rely on them, you need to use an overload of ```chooseFiles()``` which displays the standard *IntelliJ IDEA* dialog.
|
||||
Note that the native Mac OS X file chooser does not support most of the customizations, so if you rely on them, you need to use an overload of `chooseFiles()` which displays the standard *IntelliJ IDEA* dialog.
|
||||
|
||||
A very common way of using file choosers is to use a text field for entering the path with an ellipsis button ("...") for showing the file chooser.
|
||||
To create such a control, use the
|
||||
[TextFieldWithBrowseButton](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/TextFieldWithBrowseButton.java)
|
||||
component and call the ```addBrowseFolderListener()``` method on it to set up the file chooser.
|
||||
component and call the `addBrowseFolderListener()` method on it to set up the file chooser.
|
||||
As an added bonus, this will enable filename completion when entering paths in the text box.
|
||||
|
||||
An alternative UI for selecting files, which works best when the most common way of selecting a file is by typing its name, is available through the
|
||||
@ -33,9 +33,9 @@ The dialog shown by this API has two tabs:
|
||||
|
||||
* One shows the project structure
|
||||
|
||||
* Another shows a list of files similar to the one used by the ```Goto File``` popup.
|
||||
* Another shows a list of files similar to the one used by the `Goto File` popup.
|
||||
|
||||
To show the dialog, call ```showDialog()``` on the chooser returned from ```createFileChooser()```, and then call ```getSelectedFile``` to retrieve the user's selection.
|
||||
To show the dialog, call `showDialog()` on the chooser returned from `createFileChooser()`, and then call `getSelectedFile` to retrieve the user's selection.
|
||||
|
||||
## Class and Package Choosers
|
||||
|
||||
|
@ -17,10 +17,10 @@ supports the following additional features on top of
|
||||
* Drawing a tooltip with complete text of an item if the item doesn't fit into the list box width.
|
||||
|
||||
* Drawing a gray text message in the middle of the list box when it contains no items.
|
||||
The text can be customized by calling ```getEmptyText().setText()```.
|
||||
The text can be customized by calling `getEmptyText().setText()`.
|
||||
|
||||
* Drawing a busy icon in the top right corner of the list box to indicate that a background operation is being performed.
|
||||
This can be enabled by calling ```setPaintBusy()```.
|
||||
This can be enabled by calling `setPaintBusy()`.
|
||||
|
||||
Similarly, the
|
||||
[Tree](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java)
|
||||
@ -38,7 +38,7 @@ When you need to customize the presentation of items in a list box or a tree, it
|
||||
or
|
||||
[ColoredTreeCellRenderer](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java)
|
||||
classes as the cell renderer.
|
||||
These classes allow you to compose the presentation out of multiple text fragments with different attributes by calling ```append()``` and to set an optional icon for the item by calling ```setIcon```.
|
||||
These classes allow you to compose the presentation out of multiple text fragments with different attributes by calling `append()` and to set an optional icon for the item by calling `setIcon`.
|
||||
The renderer automatically takes care of setting the correct text color for selected items and of many other platform-specific rendering details.
|
||||
|
||||
### ListSpeedSearch and TreeSpeedSearch
|
||||
@ -47,12 +47,12 @@ To facilitate keyboard-based selection of items in a list box or a tree, you can
|
||||
[ListSpeedSearch](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-impl/src/com/intellij/ui/ListSpeedSearch.java)
|
||||
and
|
||||
[TreeSpeedSearch](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java).
|
||||
This can be done simply by calling ```new ListSpeedSeach(list)``` or ```new TreeSpeedSearch(tree)```.
|
||||
If you need to customize the text which is used to locate the element, you can override the ```getElementText()``` method.
|
||||
This can be done simply by calling `new ListSpeedSeach(list)` or `new TreeSpeedSearch(tree)`.
|
||||
If you need to customize the text which is used to locate the element, you can override the `getElementText()` method.
|
||||
Alternatively, you can pass a function to convert items to strings.
|
||||
A function needs to be passed as ```elementTextDelegate``` to the
|
||||
A function needs to be passed as `elementTextDelegate` to the
|
||||
[ListSpeedSearch](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-impl/src/com/intellij/ui/ListSpeedSearch.java)
|
||||
constructor or as ```toString``` to the
|
||||
constructor or as `toString` to the
|
||||
[TreeSpeedSearch](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-impl/src/com/intellij/ui/TreeSpeedSearch.java)
|
||||
constructor.
|
||||
|
||||
@ -77,11 +77,11 @@ To use a toolbar decorator:
|
||||
[ToolbarDecorator.createDecorator](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java)
|
||||
to create a decorator instance.
|
||||
|
||||
* If you need to support adding and/or removing items, call ```setAddAction()``` and/or ```setRemoveAction()```.
|
||||
* If you need to support adding and/or removing items, call `setAddAction()` and/or `setRemoveAction()`.
|
||||
|
||||
* If you need other buttons in additional to the standard ones, call ```addExtraAction()``` or ```setActionGroup()```.
|
||||
* If you need other buttons in additional to the standard ones, call `addExtraAction()` or `setActionGroup()`.
|
||||
|
||||
* Call ```createPanel()``` and add the component it returns to your panel.
|
||||
* Call `createPanel()` and add the component it returns to your panel.
|
||||
|
||||
<!--
|
||||
### AbstractTreeBuilder and AbstractTreeStructure
|
||||
|
@ -13,7 +13,7 @@ When running on Mac OS X, the message boxes shown by the
|
||||
[Messages](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/Messages.java)
|
||||
class use native UI.
|
||||
|
||||
The ```showCheckboxMessageDialog()``` function provides an easy way to implement a ```Do not show this again``` checkbox on messages.
|
||||
The `showCheckboxMessageDialog()` function provides an easy way to implement a `Do not show this again` checkbox on messages.
|
||||
|
||||
Note that it is recommended to use non-modal notifications instead of modal message boxes whenever it's appropriate.
|
||||
Please refer to the [Notifications](notifications.md) topic for more information.
|
||||
@ -32,11 +32,11 @@ instead of the standard
|
||||
[JSplitPane](http://docs.oracle.com/javase/8/docs/api/javax/swing/JSplitPane.html)
|
||||
in your plugins.
|
||||
|
||||
To add your components to the splitter, call the ```setFirstComponent()``` and ```setSecondComponent()``` methods.
|
||||
To add your components to the splitter, call the `setFirstComponent()` and `setSecondComponent()` methods.
|
||||
|
||||
[JBSplitter](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/ui/JBSplitter.java)
|
||||
supports automatic remembering of the split proportion.
|
||||
In order to enable it, call the ```setSplitterProportionKey()``` method and pass the ID under which the proportion will be stored.
|
||||
In order to enable it, call the `setSplitterProportionKey()` method and pass the ID under which the proportion will be stored.
|
||||
|
||||
### JBTabs
|
||||
|
||||
|
@ -10,7 +10,7 @@ As a replacement, *IntelliJ IDEA* provides multiple non-modal notification UI op
|
||||
|
||||
### Dialogs
|
||||
|
||||
When working in a modal dialog, instead of checking the validity of the input when the ```OK``` button is pressed and notifying the user about invalid data with a modal dialog, the recommended approach is to use
|
||||
When working in a modal dialog, instead of checking the validity of the input when the `OK` button is pressed and notifying the user about invalid data with a modal dialog, the recommended approach is to use
|
||||
[DialogBuilder.doValidate()](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java),
|
||||
which was described previously.
|
||||
|
||||
@ -19,7 +19,7 @@ which was described previously.
|
||||
For actions invoked from the editor (such as refactorings, navigation actions and different code insight features), the best way to notify the user about the inability to perform an action is to use the
|
||||
[HintManager](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/codeInsight/hint/HintManager.java)
|
||||
class.
|
||||
Its method ```showErrorHint()``` displays a floating popup above the editor which is automatically hidden when the user starts performing another action in the editor.
|
||||
Its method `showErrorHint()` displays a floating popup above the editor which is automatically hidden when the user starts performing another action in the editor.
|
||||
Other
|
||||
[HintManager](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/codeInsight/hint/HintManager.java)
|
||||
methods can be used for displaying other kinds of non-modal notification hints over an editor.
|
||||
@ -32,7 +32,7 @@ class.
|
||||
|
||||
It has two main advantages:
|
||||
|
||||
* The user can control the way each notification type is displayed under ```Settings | Notifications```
|
||||
* The user can control the way each notification type is displayed under `Settings | Notifications`
|
||||
|
||||
* All displayed notifications are gathered in the Event Log toolwindow and can be reviewed later
|
||||
|
||||
@ -45,10 +45,10 @@ instance to the constructor of the
|
||||
[Notification](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/notification/Notification.java)
|
||||
class.
|
||||
|
||||
The ```groupDisplayId``` parameter of the
|
||||
The `groupDisplayId` parameter of the
|
||||
[Notification](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/notification/Notification.java)
|
||||
constructor specifies a notification type.
|
||||
The user can choose the display type corresponding to each notification type under ```Settings | Notifications```.
|
||||
The user can choose the display type corresponding to each notification type under `Settings | Notifications`.
|
||||
To specify the preferred display type, you need to call
|
||||
[Notifications.Bus.register()](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/notification/Notification.java)
|
||||
before displaying any notifications.
|
||||
|
@ -15,16 +15,16 @@ The
|
||||
interface allows you to create popups that display different kinds of components, depending on your specific needs.
|
||||
The most commonly used methods are:
|
||||
|
||||
* ```createComponentPopupBuilder()``` is the most generic one, allowing you to show any
|
||||
* `createComponentPopupBuilder()` is the most generic one, allowing you to show any
|
||||
[Swing](http://docs.oracle.com/javase/tutorial/uiswing/start/index.html)
|
||||
component in the popup.
|
||||
|
||||
* ```createListPopupBuilder()``` creates a popup for choosing one or more items from a
|
||||
* `createListPopupBuilder()` creates a popup for choosing one or more items from a
|
||||
[Swing JList](http://docs.oracle.com/javase/8/docs/api/javax/swing/JList.html).
|
||||
|
||||
* ```createConfirmation()``` creates a popup for choosing between two options, and performing different actions depending on which option is selected.
|
||||
* `createConfirmation()` creates a popup for choosing between two options, and performing different actions depending on which option is selected.
|
||||
|
||||
* ```createActionGroupPopup()``` creates a popup which shows the actions from an action group and executes the action selected by the user.
|
||||
* `createActionGroupPopup()` creates a popup which shows the actions from an action group and executes the action selected by the user.
|
||||
|
||||
Action group popups support different ways of choosing an action from the keyboard, in additional to the normal arrow keys.
|
||||
By passing one of the constants in the
|
||||
@ -43,18 +43,18 @@ method.
|
||||
Normally you don't need to implement the entire interface; instead, you can derive from the
|
||||
[BaseListPopupStep](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/popup/util/BaseListPopupStep.java)
|
||||
class.
|
||||
The key methods to override are ```getTextFor()``` (returning the text to display for an item) and ```onChosen()``` (called when an item is selected).
|
||||
By returning a new popup step from the ```onChosen()``` method, you can implement hierarchical (nested) popups.
|
||||
The key methods to override are `getTextFor()` (returning the text to display for an item) and `onChosen()` (called when an item is selected).
|
||||
By returning a new popup step from the `onChosen()` method, you can implement hierarchical (nested) popups.
|
||||
|
||||
Once you've created the popup, you need to display it by calling one of the ```show()``` methods.
|
||||
You can let *IntelliJ IDEA* automatically choose the position based on the context, by calling ```showInBestPositionFor()```, or specify the position explicitly through methods like ```showUnderneathOf()``` and ```showInCenterOf()```.
|
||||
Once you've created the popup, you need to display it by calling one of the `show()` methods.
|
||||
You can let *IntelliJ IDEA* automatically choose the position based on the context, by calling `showInBestPositionFor()`, or specify the position explicitly through methods like `showUnderneathOf()` and `showInCenterOf()`.
|
||||
|
||||
|
||||
**Note:**
|
||||
|
||||
> The ```show()``` methods return immediately and do not wait for the popup to be closed.
|
||||
> The `show()` methods return immediately and do not wait for the popup to be closed.
|
||||
|
||||
If you need to perform some action when the popup is closed, you can either attach a listener to it using the ```addListener()``` method, override a method of the popup contents such as
|
||||
If you need to perform some action when the popup is closed, you can either attach a listener to it using the `addListener()` method, override a method of the popup contents such as
|
||||
[PopupStep.onChosen()](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupStep.java),
|
||||
or attach an event handler to your own component within the popup.
|
||||
|
||||
|
@ -13,9 +13,9 @@ For example, the Run toolwindow displays a tab for each active run configuration
|
||||
|
||||
There are two main scenarios for the use of tool windows in a plugin.
|
||||
In the first scenario (used by the Ant and Commander plugins, for example), a toolwindow button is always visible, and the user can activate it and interact with the plugin functionality at any time.
|
||||
In the second scenario (used by the ```Analyze Dependencies``` action, for example), the toolwindow is created to show the results of a specific operation, and can be closed by the user after the operation is completed.
|
||||
In the second scenario (used by the `Analyze Dependencies` action, for example), the toolwindow is created to show the results of a specific operation, and can be closed by the user after the operation is completed.
|
||||
|
||||
In the first scenario, the toolwindow is registered in *plugin.xml* using the ```<toolWindow>``` extension point.
|
||||
In the first scenario, the toolwindow is registered in *plugin.xml* using the `<toolWindow>` extension point.
|
||||
The extension point attributes specify all the data which is necessary to display the toolwindow button:
|
||||
|
||||
* The ID of the toolwindow (corresponds to the text displayed on the toolwindow button)
|
||||
@ -29,7 +29,7 @@ The extension point attributes specify all the data which is necessary to displa
|
||||
In addition to that, you specify the *factory class* - the name of a class implementing the
|
||||
[ToolWindowFactory](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowFactory.java)
|
||||
interface.
|
||||
When the user clicks on the toolwindow button, the ```createToolWindowContent()``` method of the factory class is called, and initializes the UI of the toolwindow.
|
||||
When the user clicks on the toolwindow button, the `createToolWindowContent()` method of the factory class is called, and initializes the UI of the toolwindow.
|
||||
This procedure ensures that unused toolwindows don't cause any overhead in startup time or memory usage: if a user does not interact with the toolwindow of your plugin, no plugin code will be loaded or executed.
|
||||
|
||||
If the toolwindow of your plugin doesn't need to be displayed for all projects, you can also specify the *conditionClass* attribute - the qualified name of a class implementing the
|
||||
@ -46,7 +46,7 @@ The method has multiple overloads that can be used depending on your task.
|
||||
If you use an overload that takes a component, the component becomes the first content (tab) displayed in the toolwindow.
|
||||
|
||||
Displaying the contents of many toolwindows requires access to the indexes.
|
||||
Because of that, toolwindows are normally disabled while building indices, unless you pass true as the value of ```canWorkInDumbMode``` to the ```registerToolWindow()``` function.
|
||||
Because of that, toolwindows are normally disabled while building indices, unless you pass true as the value of `canWorkInDumbMode` to the `registerToolWindow()` function.
|
||||
|
||||
As mentioned previously, toolwindows can contain multiple tabs, or contents.
|
||||
To manage the contents of a toolwindow, you can call
|
||||
@ -57,8 +57,8 @@ and then to add it to the toolwindow using
|
||||
[ContentManager.addContent()](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/ui/content/ContentManager.java).
|
||||
|
||||
You can control whether the user is allowed to close tabs either globally or on a per-tab basis.
|
||||
The former is done by passing the ```canCloseContents``` parameter to the ```registerToolWindow()``` function, or by specifying
|
||||
```canCloseContents="true"``` in *plugin.xml*.
|
||||
The former is done by passing the `canCloseContents` parameter to the `registerToolWindow()` function, or by specifying
|
||||
`canCloseContents="true"` in *plugin.xml*.
|
||||
If closing tabs is enabled in general, you can disable closing of specific tabs by calling
|
||||
[Content.setCloseable(false)](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/ui/content/Content.java).
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user