This post explains IntelliJ IDEA Plugin development.
The source code explained here is uploaded in official repository as a CLion plugin, please check Single File Execution Plugin on github.
Contents
Save value for IntelliJ Plugin
If your plugin want to keep some configuration value and you want to save the values in storage, PersistentStateComponent
can be used in IntelliJ IDEA plugin development.
Ref
Make a class implments PersistentStateComponent
Create new Java class, and add implements PersistentStateComponent<T>
.
Following hands on example, I will introduce easy quick implementation for this class. I made SingleFileExecutionConfig
class which implements PersistentStateComponent<SingleFileExecutionConfig>
. So the State type T
is same with created class.
To implement this interface PersistentStateComponent<T>
, we need to override
getState()
called every time the settings are saved. If the state returned fromgetState()
is different from the default state obtained by default constructor, the returned state is serialized in XML and stored.loadState(T)
called when the component has been created, and after the XML file with the persisted state is changed externally.
and it is nice to implement getInstance
method.
For the implementation of these 3 methods, you don’t need to remember about above behavior. Just implement as following template.
/** * PersistentStateComponent keeps project config values. */ @State( name="SingleFileExecutionConfig", storages = { @Storage("SingleFileExecutionConfig.xml")} ) public class SingleFileExecutionConfig implements PersistentStateComponent<SingleFileExecutionConfig> { @Nullable @Override public SingleFileExecutionConfig getState() { return this; } @Override public void loadState(SingleFileExecutionConfig singleFileExecutionConfig) { XmlSerializerUtil.copyBean(singleFileExecutionConfig, this); } @Nullable public static SingleFileExecutionConfig getInstance(Project project) { return ServiceManager.getService(project, SingleFileExecutionConfig.class); } }
Note that for the getService
method in getInstance
, project
variable is necessary when your PersistentStateComponent
is project level. If your service is application level, project
instance is not necessary.
See
@State annotation – specify the storage location to be saved
As you may notice, @State
annotation is written at the top. This is to specify where the persisted values will be stored. For the fields,
name
(required) – specifies the name of the state.storages
– specify the storage locations
Example,@Storage("yourName.xml")
If component is project-level@Storage(StoragePathMacros.WORKSPACE_FILE)
for values stored in the workspace file.
See official doc’s “Defining the storage location” for more details.
After that, you can just declare variables which will be saved, and the Getter and Setter of these variables. For example, to declare one String variable executableName
, add below code to this class.
String executableName; public String getExecutableName() { return executableName; } public void setExecutableName(String executableName) { this.executableName = executableName; }
Declaring PersistentStateComponent in plugin.xml
To use this PersistentStateComponent
, declaration in plugin.xml
is necessary.
<extensions defaultExtensionNs="com.intellij"> ... <projectService serviceInterface="SingleFileExecutionConfig" serviceImplementation="SingleFileExecutionConfig"/> </extensions>
Using PersistentStateComponent from the other module
Let’s consider a case that you want to use created SingleFileExecutionConfig
class from Configurable
class (see IntelliJ Plugin Development introduction: ApplicationConfigurable, ProjectConfigurable for explanation of Configurable
).
The instance can be obtained by calling getInstance
method. For example,
private final SingleFileExecutionConfig mConfig; @SuppressWarnings("FieldCanBeLocal") private final Project mProject; public SingleFileExecutionConfigurable(@NotNull Project project) { mProject = project; mConfig = SingleFileExecutionConfig.getInstance(project); }
To update the value, you can just directly update the field variable of this instance (mConfig
). No explicit “save” method call is needed! The value is automatically saved when you get the value in next time.
Below code is an example for the variable updating part. this apply()
method is called when user change the configuration in Settings dialog.
public void apply() { mConfig.setExecutableName(exeNameTextField.getText()); mConfig.notShowOverwriteConfirmDialog = notShowDialogCheckBox.isSelected(); }
Check the source code for more detail.