Introduction
IntelliJ Plugin Development docs: https://www.jetbrains.org/intellij/sdk/docs/welcome.html https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started.htmlIt is really important to understand the different ways you can interact with files:
- As VirtualFiles, which confusingly, are the files on the filesystem.
- As structured, understood files, called PSI files. e.g. a Java file is a PSI file
- As files open in the Editor.
- XML files
https://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/virtual_file.html
https://www.jetbrains.org/intellij/sdk/docs/reference_guide/editors.html
Structured files like Java or XML are called PSI:
https://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/psi.html
https://www.jetbrains.org/intellij/sdk/docs/basics/psi_cookbook.html
How to add an action to a menu
In your plugin.xml:<actions> <action id="com.ice.refactor.RemoveFacadeUsageAction" class="com.ice.refactor.RemoveFacadeUsageAction" text="Remove Facade Usage" description="Remove facade usage"> <add-to-group group-id="RefactoringMenu4" anchor="last"/> </action>However by far the easiest way to do this is to use the custom inspection / quick fix – if you have an action not yet added to the plugin config, right click on the class name and IntelliJ will open a dialog box to help you add the config. Really cool!
How to add settings to your plugin
See this useful post: Adding plugin settingsEssentially:
- Create a Configuration class
- Create a Form class that it will bind to
- Use the Visual Editor to design the form
- Use the PropertiesComponent.getInstance() to save simple properties like booleans and strings
Find the PSI element under the carat
final Editor editor = event.getData(CommonDataKeys.EDITOR); int findElementFlags = TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED + TargetElementUtil.ELEMENT_NAME_ACCEPTED + TargetElementUtil.LOOKUP_ITEM_ACCEPTED; TargetElementUtil targetElementUtil = new TargetElementUtil(); PsiElement psiElement = targetElementUtil.findTargetElement(editor, findElementFlags, offset);
Getting the text under the carat
final Editor editor = event.getData(CommonDataKeys.EDITOR); int offset = editor.getCaretModel().getOffset(); Document document = editor.getDocument(); String textUnderCarat = document.getText(TextRange.from(offset - 10, offset + 30));
Getting the VirtualFile from the Document in the editor
VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
See: Virtual file
Find classes implementing an interface
PsiClass interfaceClass = (PsiClass)psiElement; PsiElement psiImplClass = DefinitionsScopedSearch.search(interfaceClass).findFirst(); PsiClass facadeImplementationClass = (PsiClass)psiImplClass;
Find usages of a method
CollectionFind children of a PSI element
PsiTreeUtil.findChildOfTypeAdd an annotation to a Java class
javaPsiFacade = JavaPsiFacade.getInstance(event.getProject()); PsiElementFactory elementFactory = javaPsiFacade.getElementFactory(); PsiAnnotation inputAnnotation = elementFactory.createAnnotationFromText(annotationText, psiClass); // Note that we pass in the desired annotation, but another java object is actually created and added to the target. // This is what we must pass back to our caller. PsiAnnotation actualAnnotation = (PsiAnnotation)targetLocation.addAfter(inputAnnotation, targetLocation);