From 857d94549489038aaf81c8029d89b8faac26fcad Mon Sep 17 00:00:00 2001 From: Jakub Chrzanowski Date: Wed, 12 Aug 2020 11:25:19 +0200 Subject: [PATCH] Code Samples READMEs --- README.md | 63 +++++++++++++ action_basics/README.md | 36 ++++++++ .../src/main/java/icons/SdkIcons.java | 3 + .../sdk/action/CustomDefaultActionGroup.java | 6 +- .../sdk/action/DynamicActionGroup.java | 4 +- .../sdk/action/PopupDialogAction.java | 22 +++-- .../src/main/resources/META-INF/plugin.xml | 57 +++++++----- comparing_references_inspection/README.md | 26 ++++++ .../ComparingReferencesInspection.java | 60 +++++++------ .../src/main/resources/META-INF/plugin.xml | 70 +++++++-------- .../ComparingReferencesInspectionTest.java | 4 +- conditional_operator_intention/README.md | 51 +++++++++++ .../ConditionalOperatorConverter.java | 88 +++++++++++-------- .../src/main/resources/META-INF/plugin.xml | 7 +- editor_basics/README.md | 43 +++++++++ .../src/main/java/icons/SdkIcons.java | 2 + .../sdk/editor/EditorAreaIllustration.java | 15 ++-- .../sdk/editor/EditorHandlerIllustration.java | 28 +++--- .../sdk/editor/EditorIllustrationAction.java | 23 +++-- .../intellij/sdk/editor/MyTypedHandler.java | 2 + .../src/main/resources/META-INF/plugin.xml | 12 +-- facet_basics/README.md | 27 ++++++ .../src/main/java/icons/SdkIcons.java | 2 + .../sdk/facet/DemoFacetConfiguration.java | 7 +- .../sdk/facet/DemoFacetEditorTab.java | 22 ++--- .../intellij/sdk/facet/DemoFacetState.java | 1 + .../org/intellij/sdk/facet/DemoFacetType.java | 9 +- .../src/main/resources/META-INF/plugin.xml | 7 +- framework_basics/README.md | 24 +++++ .../src/main/java/icons/SdkIcons.java | 2 + .../intellij/sdk/framework/DemoFramework.java | 1 + .../src/main/resources/META-INF/plugin.xml | 11 +-- inspection_basics/README.md | 25 ++++++ .../sdk/inspection/DemoCodeInspection.java | 3 +- .../sdk/inspection/DemoInspectionVisitor.java | 2 + .../src/main/resources/META-INF/plugin.xml | 51 ++++++----- kotlin_demo/README.md | 25 ++++++ .../org/intellij/sdk/kotlin/HelloAction.kt | 1 + .../src/main/resources/META-INF/plugin.xml | 6 +- live_templates/README.md | 31 +++++++ .../sdk/liveTemplates/MarkdownContext.java | 2 +- .../sdk/liveTemplates/TitleCaseMacro.java | 15 ++-- .../src/main/resources/META-INF/plugin.xml | 9 +- max_opened_projects/README.md | 35 ++++++++ .../ProjectCountingService.java | 1 + .../ProjectOpenCloseListener.java | 8 +- .../src/main/resources/META-INF/plugin.xml | 18 ++-- module/README.md | 24 +++++ module/src/main/java/icons/SdkIcons.java | 2 + .../sdk/module/DemoModuleBuilder.java | 6 +- .../intellij/sdk/module/DemoModuleType.java | 2 + .../sdk/module/DemoModuleWizardStep.java | 2 + module/src/main/resources/META-INF/plugin.xml | 8 +- product_specific/pycharm_basics/README.md | 23 +++++ .../src/main/java/icons/SdkIcons.java | 2 + .../sdk/pycharm/PopupDialogAction.java | 14 +-- .../src/main/resources/META-INF/plugin.xml | 12 +-- project_model/README.md | 36 ++++++++ .../src/main/java/icons/SdkIcons.java | 2 + .../sdk/project/model/LibrariesAction.java | 34 +++++-- .../sdk/project/model/ModificationAction.java | 18 +++- .../model/ProjectFileIndexSampleAction.java | 16 ++-- .../sdk/project/model/ProjectSdkAction.java | 2 + .../project/model/ShowSourceRootsActions.java | 12 ++- .../src/main/resources/META-INF/plugin.xml | 11 +-- project_view_pane/README.md | 24 +++++ .../sdk/view/pane/ImagesProjectNode.java | 15 +++- .../sdk/view/pane/ImagesProjectViewPane.java | 3 +- .../src/main/resources/META-INF/plugin.xml | 6 +- project_wizard/README.md | 24 +++++ .../project/wizard/DemoModuleWizardStep.java | 5 +- .../src/main/resources/META-INF/plugin.xml | 4 +- psi_demo/README.md | 27 ++++++ .../sdk/psi/PsiNavigationDemoAction.java | 80 +++++++++-------- .../src/main/resources/META-INF/plugin.xml | 6 +- run_configuration/README.md | 24 +++++ .../src/main/resources/META-INF/plugin.xml | 10 ++- settings/README.md | 29 ++++++ settings/build.gradle | 6 +- .../sdk/settings/AppSettingsComponent.java | 11 +-- .../sdk/settings/AppSettingsConfigurable.java | 6 +- .../sdk/settings/AppSettingsState.java | 2 +- .../src/main/resources/META-INF/plugin.xml | 11 +-- simple_language_plugin/README.md | 71 +++++++++++++++ .../intellij/sdk/language/SimpleLexer.java | 2 +- .../sdk/language/SimpleAnnotator.java | 15 +++- .../intellij/sdk/language/SimpleBlock.java | 14 +-- .../SimpleChooseByNameContributor.java | 12 ++- .../sdk/language/SimpleCodeStyleSettings.java | 7 +- .../SimpleCodeStyleSettingsProvider.java | 26 ++++-- .../sdk/language/SimpleColorSettingsPage.java | 55 ++++++------ .../sdk/language/SimpleCommenter.java | 12 +-- .../language/SimpleCompletionContributor.java | 1 + .../SimpleCreatePropertyQuickFix.java | 20 +++-- .../intellij/sdk/language/SimpleFileType.java | 2 + .../sdk/language/SimpleFileTypeFactory.java | 2 + .../language/SimpleFindUsagesProvider.java | 29 +++--- .../sdk/language/SimpleFoldingBuilder.java | 64 ++++++++------ .../SimpleFormattingModelBuilder.java | 38 ++++---- .../intellij/sdk/language/SimpleIcons.java | 4 +- .../intellij/sdk/language/SimpleLanguage.java | 2 + ...mpleLanguageCodeStyleSettingsProvider.java | 33 +++---- .../sdk/language/SimpleLexerAdapter.java | 4 +- .../language/SimpleLineMarkerProvider.java | 45 ++++++---- .../sdk/language/SimpleParserDefinition.java | 39 ++++---- .../SimpleRefactoringSupportProvider.java | 5 +- .../sdk/language/SimpleReference.java | 23 +++-- .../language/SimpleReferenceContributor.java | 5 +- .../language/SimpleStructureViewElement.java | 4 +- .../language/SimpleStructureViewFactory.java | 4 +- .../language/SimpleStructureViewModel.java | 18 ++-- .../sdk/language/SimpleSyntaxHighlighter.java | 25 +++--- .../SimpleSyntaxHighlighterFactory.java | 7 +- .../org/intellij/sdk/language/SimpleUtil.java | 21 +++-- .../language/psi/SimpleElementFactory.java | 8 +- .../sdk/language/psi/SimpleElementType.java | 6 +- .../intellij/sdk/language/psi/SimpleFile.java | 11 ++- .../sdk/language/psi/SimpleNamedElement.java | 3 +- .../sdk/language/psi/SimpleTokenType.java | 7 +- .../psi/impl/SimpleNamedElementImpl.java | 4 +- .../language/psi/impl/SimplePsiImplUtil.java | 3 +- .../src/main/resources/META-INF/plugin.xml | 43 +++++---- theme_basics/README.md | 39 ++++++++ theme_basics/resources/META-INF/plugin.xml | 2 +- tool_window/README.md | 27 ++++++ .../intellij/sdk/toolWindow/MyToolWindow.java | 2 + .../sdk/toolWindow/MyToolWindowFactory.java | 2 + .../src/main/resources/META-INF/plugin.xml | 14 +-- tree_structure_provider/README.md | 27 ++++++ .../TextOnlyTreeStructureProvider.java | 15 ++-- .../src/main/resources/META-INF/plugin.xml | 13 +-- 131 files changed, 1705 insertions(+), 616 deletions(-) create mode 100644 action_basics/README.md create mode 100644 comparing_references_inspection/README.md create mode 100644 conditional_operator_intention/README.md create mode 100644 editor_basics/README.md create mode 100644 facet_basics/README.md create mode 100644 framework_basics/README.md create mode 100644 inspection_basics/README.md create mode 100644 kotlin_demo/README.md create mode 100644 live_templates/README.md create mode 100644 max_opened_projects/README.md create mode 100644 module/README.md create mode 100644 product_specific/pycharm_basics/README.md create mode 100644 project_model/README.md create mode 100644 project_view_pane/README.md create mode 100644 project_wizard/README.md create mode 100644 psi_demo/README.md create mode 100644 run_configuration/README.md create mode 100644 settings/README.md create mode 100644 simple_language_plugin/README.md create mode 100644 theme_basics/README.md create mode 100644 tool_window/README.md create mode 100644 tree_structure_provider/README.md diff --git a/README.md b/README.md index e69de29bb..5aa4f7e66 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,63 @@ +# IntelliJ Platform SDK Code Samples + +[![official JetBrains project](https://jb.gg/badges/official.svg)][jb:confluence-on-gh] +[![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][jb:docs] +[![Twitter Follow](https://img.shields.io/twitter/follow/JBPlatform?style=flat)][jb:twitter] +[![Build](https://github.com/JetBrains/intellij-sdk-docs/workflows/Build/badge.svg)][gh:build] +[![Slack](https://img.shields.io/badge/Slack-%23intellij--platform-blue)][jb:slack] + +Learn how to build plugins using IntelliJ Platform SDK for the [JetBrains products][jb:products] by experimenting with +our code samples. These samples show you how features work and help you jumpstart your plugins. + +There is also [IntelliJ Platform Plugin Template][gh:template] project available. + +## Structure + +Code Samples depend on the [IntelliJ Platform SDK][docs] and [Gradle][docs:gradle] as a build system. + +The main plugin definition file is stored in the `plugin.xml` file, which is created according +to the [Plugin Configuration File documentation][docs:plugin.xml]. It describes definitions of the actions, extensions, +or listeners provided by the plugin. + +## Code Samples + +In the following table, you may find all available samples provided in the separated directories as stand-alone +projects available for running with the Gradle `:runIde` task. + +| Code Sample | Description | +| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [Action Basics](./action_basics) | Action and Action Group patterns implementation, adds entries to the Tools menu. | +| [Comparing References Inspection](./comparing_references_inspection) | Local Inspection Tool, adds entries to `Preferences \| Editor \| Inspections \| Java \| Probable Bugs`. | +| [Conditional Operator Intention](./conditional_operator_intention) | Intention action, suggests converting a ternary operator into an *if* block and adds entry to `Preferences \| Editor \| Intentions \| SDK Intentions`. | +| [Editor Basics](./editor_basics) | Basic Editor APIs example with editor popup menu with extra actions. | +| [Facet Basics](./facet_basics) | Custom Facet pattern, adds *SDK Facet* to the `Project Structure \| Project Settings \| Facets menu`. | +| [Framework Basics](./framework_basics) | Basic *SDK Demo Framework* support added to the `File \| New \| Project \| IntelliJ Platform Plugin` | +| [Inspection Basics](./inspection_basics) | Code Inspection entry added to the `Preferences \| Editor \| Inspections \| SDK \| Example Tools`. | +| [Kotlin Demo](./kotlin_demo) | Kotlin example extending the *Main Menu* with a `Greeting` menu group. | +| [Live Templates](./live_templates) | Live templates for Markdown language, adds an entry to the `Preferences \| Editor \| Live Templates` dialog. | +| [Max Opened Projects](./max_opened_projects) | Application services and listeners, shows warning dialog when more than 3 open projects are opened. | +| [Module](./module) | *SDK Demo Module* module type added to the `File \| New \| Project...`. | +| [Product Specific - PyCharm Sample](./product_specific/pycharm_basics) | Plugin project configuration for the PyCharm IDE. | +| [Project Model](./project_model) | Interacts with the project model, adds menu items to `Tools` and `Editor Context` menus. | +| [Project View Pane](./project_view_pane) | Project View Pane listing only image files. | +| [Project Wizard](./project_wizard) | Project Wizard example with demo steps. | +| [PSI Demo](./psi_demo) | PSI Navigation features presentation. | +| [Run Configuration](./run_configuration) | Run configuration implementation with factory, options and UI. | +| [Settings](./settings) | Custom settings panel, adds a settings panel to the `Settings \| Preferences` panel under `Tools`. | +| [Simple Language Plugin](./simple_language_plugin) | Custom language support, defines a new *Simple language* with syntax highlighting, annotations, code completion, and other features. | +| [Theme Basics](./theme_basics) | Sample *UI Theme* plugin with basic interface modifications. | +| [Tool Window](./tool_window) | Custom Tool Window example plugin. | +| [Tree Structure Provider](./tree_structure_provider) | Tree Structure Provider showing only plain text files. | + +[gh:build]: https://github.com/JetBrains/intellij-sdk-docs/actions?query=workflow%3ABuild +[gh:template]: https://github.com/JetBrains/intellij-platform-plugin-template + +[jb:confluence-on-gh]: https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub +[jb:docs]: https://www.jetbrains.org/intellij/sdk/docs +[jb:products]: https://www.jetbrains.com/products.html +[jb:slack]: https://plugins.jetbrains.com/slack +[jb:twitter]: https://twitter.com/JBPlatform + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:gradle]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/build_system.html +[docs:plugin.xml]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_configuration_file.html diff --git a/action_basics/README.md b/action_basics/README.md new file mode 100644 index 000000000..ca6057528 --- /dev/null +++ b/action_basics/README.md @@ -0,0 +1,36 @@ +# Action Sample Project [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Action System in IntelliJ SDK Docs][docs:actions]* + +## Quickstart + +Action Sample Project demonstrates registering actions process in various configurations. +Each action is an extension of the [`AnAction`][sdk:AnAction] abstract class and brings the possibility of extending IDE with an event performed with the user interaction - i.e., clicking the button, using the keyboard or mouse shortcuts. + +Plugin registers the [`PopupDialogAction`][file:PopupDialogAction] action, which provides a popup dialog as a feedback, in three different ways: + +- by assigning the keyboard (Ctrl/Cmd+Alt+A, C) and mouse shortcuts (Ctrl/Cmd + Mouse Button 3 + Double Click), +- by adding action item to the `ToolsMenu` group, available in Tools menu, +- by adding action item to the `EditorPopupMenu` group, available in Editor's context menu. + +### Actions + +| ID | Implementation | Extension Point Class | +| -------------------------------------------------- | --------------------------------------------------------- | ------------------------------ | +| `org.intellij.sdk.action.PopupDialogAction` | [PopupDialogAction][file:PopupDialogAction] | [AnAction][sdk:AnAction] | +| `org.intellij.sdk.action.GroupPopDialogAction` | [PopupDialogAction][file:PopupDialogAction] | [AnAction][sdk:AnAction] | +| `org.intellij.sdk.action.CustomGroupedAction` | [PopupDialogAction][file:PopupDialogAction] | [AnAction][sdk:AnAction] | +| `org.intellij.sdk.action.CustomDefaultActionGroup` | [CustomDefaultActionGroup][file:CustomDefaultActionGroup] | [ActionGroup][sdk:ActionGroup] | +| `org.intellij.sdk.action.DynamicActionGroup` | [DynamicActionGroup][file:DynamicActionGroup] | [ActionGroup][sdk:ActionGroup] | + +*Reference: [Action System in IntelliJ SDK Docs][docs:actions]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:actions]: https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html + +[file:PopupDialogAction]: ./src/main/java/org/intellij/sdk/action/PopupDialogAction.java +[file:CustomDefaultActionGroup]: ./src/main/java/org/intellij/sdk/action/CustomDefaultActionGroup.java +[file:DynamicActionGroup]: ./src/main/java/org/intellij/sdk/action/DynamicActionGroup.java + +[sdk:AnAction]: upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java +[sdk:ActionGroup]: upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/ActionInGroup.java diff --git a/action_basics/src/main/java/icons/SdkIcons.java b/action_basics/src/main/java/icons/SdkIcons.java index 68d9dcc2c..204f14ff6 100644 --- a/action_basics/src/main/java/icons/SdkIcons.java +++ b/action_basics/src/main/java/icons/SdkIcons.java @@ -3,8 +3,11 @@ package icons; import com.intellij.openapi.util.IconLoader; + import javax.swing.*; public class SdkIcons { + public static final Icon Sdk_default_icon = IconLoader.getIcon("/icons/sdk_16.svg"); + } diff --git a/action_basics/src/main/java/org/intellij/sdk/action/CustomDefaultActionGroup.java b/action_basics/src/main/java/org/intellij/sdk/action/CustomDefaultActionGroup.java index 3e06aec21..d9c058f62 100644 --- a/action_basics/src/main/java/org/intellij/sdk/action/CustomDefaultActionGroup.java +++ b/action_basics/src/main/java/org/intellij/sdk/action/CustomDefaultActionGroup.java @@ -12,13 +12,14 @@ import icons.SdkIcons; * Creates an action group to contain menu actions. See plugin.xml declarations. */ public class CustomDefaultActionGroup extends DefaultActionGroup { - + /** * Given CustomDefaultActionGroup is derived from ActionGroup, in this context * update() determines whether the action group itself should be enabled or disabled. * Requires an editor to be active in order to enable the group functionality. + * + * @param event Event received when the associated group-id menu is chosen. * @see com.intellij.openapi.actionSystem.AnAction#update(AnActionEvent) - * @param event Event received when the associated group-id menu is chosen. */ @Override public void update(AnActionEvent event) { @@ -28,4 +29,5 @@ public class CustomDefaultActionGroup extends DefaultActionGroup { // Take this opportunity to set an icon for the menu entry. event.getPresentation().setIcon(SdkIcons.Sdk_default_icon); } + } diff --git a/action_basics/src/main/java/org/intellij/sdk/action/DynamicActionGroup.java b/action_basics/src/main/java/org/intellij/sdk/action/DynamicActionGroup.java index fffbe3f32..3def613cb 100644 --- a/action_basics/src/main/java/org/intellij/sdk/action/DynamicActionGroup.java +++ b/action_basics/src/main/java/org/intellij/sdk/action/DynamicActionGroup.java @@ -30,9 +30,7 @@ public class DynamicActionGroup extends ActionGroup { @Override public AnAction[] getChildren(AnActionEvent e) { return new AnAction[]{ - new PopupDialogAction("Action Added at Runtime", - "Dynamic Action Demo", - SdkIcons.Sdk_default_icon) + new PopupDialogAction("Action Added at Runtime", "Dynamic Action Demo", SdkIcons.Sdk_default_icon) }; } diff --git a/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java b/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java index 69cb28870..edf7b1db5 100644 --- a/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java +++ b/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java @@ -20,40 +20,43 @@ import javax.swing.*; * in the plugin.xml file. But when added at runtime this class is instantiated by an action group. */ public class PopupDialogAction extends AnAction { - + /** * This default constructor is used by the IntelliJ Platform framework to * instantiate this class based on plugin.xml declarations. Only needed in PopupDialogAction * class because a second constructor is overridden. + * * @see AnAction#AnAction() */ public PopupDialogAction() { super(); } - + /** * This constructor is used to support dynamically added menu actions. * It sets the text, description to be displayed for the menu item. * Otherwise, the default AnAction constructor is used by the IntelliJ Platform. - * @param text The text to be displayed as a menu item. - * @param description The description of the menu item. - * @param icon The icon to be used with the menu item. + * + * @param text The text to be displayed as a menu item. + * @param description The description of the menu item. + * @param icon The icon to be used with the menu item. */ public PopupDialogAction(@Nullable String text, @Nullable String description, @Nullable Icon icon) { super(text, description, icon); } - + /** * Gives the user feedback when the dynamic action menu is chosen. * Pops a simple message dialog. See the psi_demo plugin for an * example of how to use AnActionEvent to access data. + * * @param event Event received when the associated menu item is chosen. */ @Override public void actionPerformed(@NotNull AnActionEvent event) { // Using the event, create and show a dialog Project currentProject = event.getProject(); - StringBuffer dlgMsg = new StringBuffer(event.getPresentation().getText() + " Selected!"); + StringBuilder dlgMsg = new StringBuilder(event.getPresentation().getText() + " Selected!"); String dlgTitle = event.getPresentation().getDescription(); // If an element is selected in the editor, add info about it. Navigatable nav = event.getData(CommonDataKeys.NAVIGATABLE); @@ -62,10 +65,11 @@ public class PopupDialogAction extends AnAction { } Messages.showMessageDialog(currentProject, dlgMsg.toString(), dlgTitle, Messages.getInformationIcon()); } - + /** * Determines whether this menu item is available for the current context. * Requires a project to be open. + * * @param e Event received when the associated group-id menu is chosen. */ @Override @@ -74,5 +78,5 @@ public class PopupDialogAction extends AnAction { Project project = e.getProject(); e.getPresentation().setEnabledAndVisible(project != null); } - + } diff --git a/action_basics/src/main/resources/META-INF/plugin.xml b/action_basics/src/main/resources/META-INF/plugin.xml index fc7477c5c..173770fc4 100644 --- a/action_basics/src/main/resources/META-INF/plugin.xml +++ b/action_basics/src/main/resources/META-INF/plugin.xml @@ -2,16 +2,16 @@ - + org.intellij.sdk.action - SDK: Action Sample Project + SDK: Action Sample com.intellij.modules.platform - + Adds entries to the Tools menu. @@ -31,40 +31,53 @@ IntelliJ Platform SDK - - + + text="Action Basics Plugin: Pop Dialog Action" description="SDK action example" + icon="SdkIcons.Sdk_default_icon"> - - - + + - - + + - - + + diff --git a/comparing_references_inspection/README.md b/comparing_references_inspection/README.md new file mode 100644 index 000000000..20d4548fa --- /dev/null +++ b/comparing_references_inspection/README.md @@ -0,0 +1,26 @@ +# Comparing References Inspection Sample [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Code Inspections in IntelliJ SDK Docs][docs:code_inspections]* + +## Quickstart + +Comparing References Inspection Sample demonstrates the implementation of the [Code Inspections][docs:code_inspections] feature for Java classes. + +The plugin inspects your Java code and highlights any fragments containing the comparison of two `String` or `Date` variables. +If such a check finds a comparison using the `==` or !`=` operators instead of the `.equals()` method, the plugin proposes a *quick-fix* action. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ------------------------------ | ------------------------------------------------------------------- | -------------------------------------------------------- | +| `com.intellij.localInspection` | [ComparingReferencesInspection][file:ComparingReferencesInspection] | [AbstractBaseJavaLocalInspectionTool][sdk:AbstractBJLIT] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:code_inspections]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/code_inspections.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:ComparingReferencesInspection]: ./src/main/java/org/intellij/sdk/codeInspection/ComparingReferencesInspection.java + +[sdk:AbstractBJLIT]: upsource:///java/java-analysis-api/src/com/intellij/codeInspection/AbstractBaseJavaLocalInspectionTool.java diff --git a/comparing_references_inspection/src/main/java/org/intellij/sdk/codeInspection/ComparingReferencesInspection.java b/comparing_references_inspection/src/main/java/org/intellij/sdk/codeInspection/ComparingReferencesInspection.java index 6b0763669..ea64e0a18 100644 --- a/comparing_references_inspection/src/main/java/org/intellij/sdk/codeInspection/ComparingReferencesInspection.java +++ b/comparing_references_inspection/src/main/java/org/intellij/sdk/codeInspection/ComparingReferencesInspection.java @@ -24,17 +24,17 @@ import static com.siyeh.ig.psiutils.ExpressionUtils.isNullLiteral; * The quick fix converts these comparisons to 'a.equals(b) or '!a.equals(b)' respectively. */ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspectionTool { + + // Defines the text of the quick fix intention + public static final String QUICK_FIX_NAME = "SDK: " + + InspectionsBundle.message("inspection.comparing.references.use.quickfix"); private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ComparingReferencesInspection"); private final CriQuickFix myQuickFix = new CriQuickFix(); - - // Defines the text of the quick fix intention - public static final String QUICK_FIX_NAME = "SDK: " + InspectionsBundle.message("inspection.comparing.references.use.quickfix"); - // This string holds a list of classes relevant to this inspection. @SuppressWarnings({"WeakerAccess"}) @NonNls public String CHECKED_CLASSES = "java.lang.String;java.util.Date"; - + /** * This method is called to get the panel describing the inspection. * It is called every time the user selects the inspection in preferences. @@ -55,7 +55,7 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti panel.add(checkedClasses); return panel; } - + /** * This method is overridden to provide a custom visitor * that inspects expressions with relational operators '==' and '!=' @@ -70,14 +70,15 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { - + /** * This string defines the short message shown to a user signaling the inspection * found a problem. It reuses a string from the inspections bundle. */ @NonNls - private final String DESCRIPTION_TEMPLATE = "SDK " + InspectionsBundle.message("inspection.comparing.references.problem.descriptor"); - + private final String DESCRIPTION_TEMPLATE = "SDK " + + InspectionsBundle.message("inspection.comparing.references.problem.descriptor"); + /** * Avoid defining visitors for both Reference and Binary expressions. * @@ -86,7 +87,7 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti @Override public void visitReferenceExpression(PsiReferenceExpression psiReferenceExpression) { } - + /** * Evaluate binary psi expressions to see if they contain * relational operators '==' and '!=', AND they contain @@ -105,19 +106,20 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti // The binary expression is the correct type for this inspection PsiExpression lOperand = expression.getLOperand(); PsiExpression rOperand = expression.getROperand(); - if (rOperand == null || isNullLiteral(lOperand) || isNullLiteral(rOperand)) + if (rOperand == null || isNullLiteral(lOperand) || isNullLiteral(rOperand)) { return; + } // Nothing is compared to null, now check the types being compared PsiType lType = lOperand.getType(); PsiType rType = rOperand.getType(); if (isCheckedType(lType) || isCheckedType(rType)) { // Identified an expression with potential problems, add to list with fix object. holder.registerProblem(expression, - DESCRIPTION_TEMPLATE, myQuickFix); + DESCRIPTION_TEMPLATE, myQuickFix); } } } - + /** * Verifies the input is the correct {@code PsiType} for this inspection. * @@ -126,26 +128,28 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti * one of the classes in the CHECKED_CLASSES list. */ private boolean isCheckedType(PsiType type) { - if (!(type instanceof PsiClassType)) + if (!(type instanceof PsiClassType)) { return false; + } StringTokenizer tokenizer = new StringTokenizer(CHECKED_CLASSES, ";"); while (tokenizer.hasMoreTokens()) { String className = tokenizer.nextToken(); - if (type.equalsToText(className)) + if (type.equalsToText(className)) { return true; + } } return false; } - + }; } - + /** * This class provides a solution to inspection problem expressions by manipulating * the PSI tree to use a.equals(b) instead of '==' or '!=' */ private static class CriQuickFix implements LocalQuickFix { - + /** * Returns a partially localized string for the quick fix intention. * Used by the test code for this plugin. @@ -157,7 +161,7 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti public String getName() { return QUICK_FIX_NAME; } - + /** * This method manipulates the PSI tree to replace 'a==b' with 'a.equals(b) * or 'a!=b' with '!a.equals(b)' @@ -171,18 +175,19 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti IElementType opSign = binaryExpression.getOperationTokenType(); PsiExpression lExpr = binaryExpression.getLOperand(); PsiExpression rExpr = binaryExpression.getROperand(); - if (rExpr == null) + if (rExpr == null) { return; - + } + PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); PsiMethodCallExpression equalsCall = - (PsiMethodCallExpression) factory.createExpressionFromText("a.equals(b)", null); - + (PsiMethodCallExpression) factory.createExpressionFromText("a.equals(b)", null); + equalsCall.getMethodExpression().getQualifierExpression().replace(lExpr); equalsCall.getArgumentList().getExpressions()[0].replace(rExpr); - + PsiExpression result = (PsiExpression) binaryExpression.replace(equalsCall); - + if (opSign == JavaTokenType.NE) { PsiPrefixExpression negation = (PsiPrefixExpression) factory.createExpressionFromText("!a", null); negation.getOperand().replace(result); @@ -192,11 +197,12 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti LOG.error(e); } } - + @NotNull public String getFamilyName() { return getName(); } + } - + } diff --git a/comparing_references_inspection/src/main/resources/META-INF/plugin.xml b/comparing_references_inspection/src/main/resources/META-INF/plugin.xml index 05ae6fa2b..4776e5e20 100644 --- a/comparing_references_inspection/src/main/resources/META-INF/plugin.xml +++ b/comparing_references_inspection/src/main/resources/META-INF/plugin.xml @@ -2,8 +2,8 @@ - - org.intelliJ.sdk.codeInspection + + org.intellij.sdk.codeInspection SDK: Comparing References Inspection Sample @@ -11,10 +11,11 @@ com.intellij.modules.java - + Adds entries to Preferences | Editor | Inspections | Java | Probable Bugs. + Demonstrates implementing a Local Inspection Tool.
Adds entries to + Preferences | Editor | Inspections | Java | Probable Bugs. ]]>
@@ -31,39 +32,38 @@ IntelliJ Platform SDK + + Attributes: + language= Language ID + shortName= Not specified, will be computed by the underlying implementation classes. + displayName= The string to be shown in the Preferences | Editor | Inspections panel + The displayName gets registered to identify this inspection. + Can be localized using key= and bundle= attributes instead. + groupPath= Defines the outermost grouping for this inspection in + the Preferences | Editor | Inspections panel. Not localized. + groupBundle= Name of *.bundle file to translate groupKey. + In this case reuse an IntelliJ Platform bundle file from intellij.platform.resources.en + groupKey= Key to use for translation subgroup name using groupBundle file. + In this case reuse the IntelliJ Platform subcategory "Probable bugs" + enabledByDefault= Inspection state when Inspections panel is created. + level= The default level of error found by this inspection, e.g. INFO, ERROR, etc. + @see com.intellij.codeHighlighting.HighlightDisplayLevel + implementationClass= FQN of inspection implementation + --> - + displayName="SDK: '==' or '!=' used instead of 'equals()'" + groupPath="Java" + groupBundle="messages.InspectionsBundle" + groupKey="group.names.probable.bugs" + enabledByDefault="true" + level="WARNING" + implementationClass="org.intellij.sdk.codeInspection.ComparingReferencesInspection"/>
diff --git a/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/ComparingReferencesInspectionTest.java b/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/ComparingReferencesInspectionTest.java index 7c3e55269..cae4f7c24 100644 --- a/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/ComparingReferencesInspectionTest.java +++ b/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/ComparingReferencesInspectionTest.java @@ -52,14 +52,14 @@ public class ComparingReferencesInspectionTest extends LightJavaCodeInsightFixtu /** * Test the "==" case */ - public void testRelationalEq() throws Throwable { + public void testRelationalEq() { doTest("Eq"); } /** * Test the "!=" case */ - public void testRelationalNeq() throws Throwable { + public void testRelationalNeq() { doTest("Neq"); } diff --git a/conditional_operator_intention/README.md b/conditional_operator_intention/README.md new file mode 100644 index 000000000..ee630d3f0 --- /dev/null +++ b/conditional_operator_intention/README.md @@ -0,0 +1,51 @@ +# Conditional Operator Converter [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Code Intentions in IntelliJ SDK Docs][docs:conditional_operator_intention]* + +## Quickstart + +Conditional Operator Converter provides an intention for converting the *ternary operator* into the *if* statement, i.e.: + +```java +public class X { + void f(boolean isMale) { + String title = isMale ? "Mr." : "Ms."; + System.out.println("title = " + title); + } +} +``` + +will become: + +```java +public class X { + void f(boolean isMale) { + String title; + if (isMale) { + title = "Mr."; + } else { + title = "Ms."; + } + System.out.println("title = " + title); + } +} +``` + +To invoke the intention action, it is necessary to place the caret on the `?` character of the ternary operator. +The converter in the `isAvailable` method, has defined the token check to match `JavaTokenType.QUEST`, which is `?` character. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ------------------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------ | +| `com.intellij.intentionAction` | [ConditionalOperatorConverter][file:ConditionalOperatorConverter] | [PsiElementBaseIntentionAction][sdk:PsiElementBaseIntentionAction] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:conditional_operator_intention]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/code_intentions.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:ConditionalOperatorConverter]: ./src/main/java/org/intellij/sdk/intention/ConditionalOperatorConverter.java + +[sdk:PsiElementBaseIntentionAction]: upsource:///platform/lang-api/src/com/intellij/codeInsight/intention/PsiElementBaseIntentionAction.java diff --git a/conditional_operator_intention/src/main/java/org/intellij/sdk/intention/ConditionalOperatorConverter.java b/conditional_operator_intention/src/main/java/org/intellij/sdk/intention/ConditionalOperatorConverter.java index 4f5df5745..d64e2e974 100644 --- a/conditional_operator_intention/src/main/java/org/intellij/sdk/intention/ConditionalOperatorConverter.java +++ b/conditional_operator_intention/src/main/java/org/intellij/sdk/intention/ConditionalOperatorConverter.java @@ -10,7 +10,9 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Implements an intention action to replace a ternary statement with if-then-else @@ -27,51 +29,51 @@ public class ConditionalOperatorConverter extends PsiElementBaseIntentionAction return "SDK Convert ternary operator to if statement"; } - /** * Returns text for name of this family of intentions. It is used to externalize * "auto-show" state of intentions. * It is also the directory name for the descriptions. * - * @return the intention family name. + * @return the intention family name. */ @NotNull public String getFamilyName() { return "ConditionalOperatorIntention"; } - /** * Checks whether this intention is available at the caret offset in file - the caret * must sit just before a "?" character in a ternary statement. If this condition is met, * this intention's entry is shown in the available intentions list. - * + *

* Note: this method must do its checks quickly and return. * * @param project a reference to the Project object being edited. * @param editor a reference to the object editing the project source * @param element a reference to the PSI element currently under the caret - * @return - *

    + * @return
      *
    • true if the caret is in a literal string element, so this functionality * should be added to the intention menu.
    • *
    • false for all other types of caret positions
    • *
    */ public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) { - // Quick sanity check - if (element == null) return false; + if (element == null) { + return false; + } // Is this a token of type representing a "?" character? if (element instanceof PsiJavaToken) { final PsiJavaToken token = (PsiJavaToken) element; - if (token.getTokenType() != JavaTokenType.QUEST) return false; + if (token.getTokenType() != JavaTokenType.QUEST) { + return false; + } // Is this token part of a fully formed conditional, i.e. a ternary? if (token.getParent() instanceof PsiConditionalExpression) { final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression) token.getParent(); - return conditionalExpression.getThenExpression() != null - && conditionalExpression.getElseExpression() != null;// Satisfies all criteria; call back invoke method + // Satisfies all criteria; call back invoke method + return conditionalExpression.getThenExpression() != null && conditionalExpression.getElseExpression() != null; } return false; } @@ -84,31 +86,38 @@ public class ConditionalOperatorConverter extends PsiElementBaseIntentionAction * moved above the if-then-else statement. Called when user selects this intention action * from the available intentions list. * - * @param project a reference to the Project object being edited. - * @param editor a reference to the object editing the project source - * @param element a reference to the PSI element currently under the caret - * @throws IncorrectOperationException Thrown by underlying (Psi model) write action context - * when manipulation of the psi tree fails. - * @see ConditionalOperatorConverter#startInWriteAction() + * @param project a reference to the Project object being edited. + * @param editor a reference to the object editing the project source + * @param element a reference to the PSI element currently under the caret + * @throws IncorrectOperationException Thrown by underlying (Psi model) write action context + * when manipulation of the psi tree fails. + * @see ConditionalOperatorConverter#startInWriteAction() */ - public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException { - + public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) + throws IncorrectOperationException { // Get the factory for making new PsiElements, and the code style manager to format new statements final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); final CodeStyleManager codeStylist = CodeStyleManager.getInstance(project); // Get the parent of the "?" element in the ternary statement to find the conditional expression that contains it - PsiConditionalExpression conditionalExpression = PsiTreeUtil.getParentOfType(element, PsiConditionalExpression.class, false); + PsiConditionalExpression conditionalExpression = + PsiTreeUtil.getParentOfType(element, PsiConditionalExpression.class, false); // Verify the conditional expression exists and has two outcomes in the ternary statement. - if (conditionalExpression == null) return; - if (conditionalExpression.getThenExpression() == null || conditionalExpression.getElseExpression() == null) return; + if (conditionalExpression == null) { + return; + } + if (conditionalExpression.getThenExpression() == null || conditionalExpression.getElseExpression() == null) { + return; + } // Keep searching up the Psi Tree in case the ternary is part of a FOR statement. PsiElement originalStatement = PsiTreeUtil.getParentOfType(conditionalExpression, PsiStatement.class, false); while (originalStatement instanceof PsiForStatement) { originalStatement = PsiTreeUtil.getParentOfType(originalStatement, PsiStatement.class, true); } - if (originalStatement == null) return; + if (originalStatement == null) { + return; + } // If the original statement is a declaration based on a ternary operator, // split the declaration and assignment @@ -120,12 +129,14 @@ public class ConditionalOperatorConverter extends PsiElementBaseIntentionAction PsiLocalVariable variable = null; for (PsiElement declaredElement : declaredElements) { if (declaredElement instanceof PsiLocalVariable && - PsiTreeUtil.isAncestor(declaredElement, conditionalExpression, true)) { + PsiTreeUtil.isAncestor(declaredElement, conditionalExpression, true)) { variable = (PsiLocalVariable) declaredElement; break; } } - if (variable == null) return; + if (variable == null) { + return; + } // Ensure that the variable declaration is not combined with other declarations, and add a mark variable.normalizeDeclaration(); @@ -134,7 +145,7 @@ public class ConditionalOperatorConverter extends PsiElementBaseIntentionAction // Create a new expression to declare the local variable PsiExpressionStatement statement = - (PsiExpressionStatement) factory.createStatementFromText(variable.getName() + " = 0;", null); + (PsiExpressionStatement) factory.createStatementFromText(variable.getName() + " = 0;", null); statement = (PsiExpressionStatement) codeStylist.reformat(statement); // Replace initializer with the ternary expression, making an assignment statement using the ternary @@ -152,7 +163,7 @@ public class ConditionalOperatorConverter extends PsiElementBaseIntentionAction // Create an IF statement from a string with placeholder elements. // This will replace the ternary statement - PsiIfStatement newIfStmt = (PsiIfStatement) factory.createStatementFromText("if (true) {a=b;} else {c=d;}",null); + PsiIfStatement newIfStmt = (PsiIfStatement) factory.createStatementFromText("if (true) {a=b;} else {c=d;}", null); newIfStmt = (PsiIfStatement) codeStylist.reformat(newIfStmt); // Replace the conditional expression with the one from the original ternary expression @@ -161,25 +172,26 @@ public class ConditionalOperatorConverter extends PsiElementBaseIntentionAction // Begin building the assignment string for the THEN and ELSE clauses using the // parent of the ternary conditional expression - PsiAssignmentExpression assignmentExpression = PsiTreeUtil.getParentOfType(conditionalExpression, PsiAssignmentExpression.class, false); + PsiAssignmentExpression assignmentExpression = + PsiTreeUtil.getParentOfType(conditionalExpression, PsiAssignmentExpression.class, false); // Get the contents of the assignment expression up to the start of the ternary expression - String exprFrag = assignmentExpression.getLExpression().getText() + assignmentExpression.getOperationSign().getText() ; + String exprFrag = assignmentExpression.getLExpression().getText() + + assignmentExpression.getOperationSign().getText(); // Build the THEN statement string for the new IF statement, // make a PsiExpressionStatement from the string, and switch the placeholder - String thenStr = exprFrag + conditionalExpression.getThenExpression().getText() + ";" ; + String thenStr = exprFrag + conditionalExpression.getThenExpression().getText() + ";"; PsiExpressionStatement thenStmt = (PsiExpressionStatement) factory.createStatementFromText(thenStr, null); - ( (PsiBlockStatement) newIfStmt.getThenBranch() ).getCodeBlock().getStatements()[0].replace(thenStmt); + ((PsiBlockStatement) newIfStmt.getThenBranch()).getCodeBlock().getStatements()[0].replace(thenStmt); // Build the ELSE statement string for the new IF statement, // make a PsiExpressionStatement from the string, and switch the placeholder - String elseStr = exprFrag + conditionalExpression.getElseExpression().getText() + ";" ; + String elseStr = exprFrag + conditionalExpression.getElseExpression().getText() + ";"; PsiExpressionStatement elseStmt = (PsiExpressionStatement) factory.createStatementFromText(elseStr, null); - ( (PsiBlockStatement) newIfStmt.getElseBranch() ).getCodeBlock().getStatements()[0].replace(elseStmt); + ((PsiBlockStatement) newIfStmt.getElseBranch()).getCodeBlock().getStatements()[0].replace(elseStmt); // Replace the entire original statement with the new IF newIfStmt = (PsiIfStatement) originalStatement.replace(newIfStmt); - } /** @@ -191,8 +203,8 @@ public class ConditionalOperatorConverter extends PsiElementBaseIntentionAction *
  • false if this intention action will start a write action
  • *
*/ - public boolean startInWriteAction() {return true;} - + public boolean startInWriteAction() { + return true; + } } - diff --git a/conditional_operator_intention/src/main/resources/META-INF/plugin.xml b/conditional_operator_intention/src/main/resources/META-INF/plugin.xml index 472f7eda5..516b989e4 100644 --- a/conditional_operator_intention/src/main/resources/META-INF/plugin.xml +++ b/conditional_operator_intention/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ - + org.intellij.sdk.intention @@ -12,10 +12,11 @@ com.intellij.modules.java com.intellij.modules.platform - + Adds entry to Preferences | Editor | Intentions | SDK Intentions. + Intention action that suggests converting a ternary operator into an 'if' block.
+ Adds entry to Preferences | Editor | Intentions | SDK Intentions. ]]>
diff --git a/editor_basics/README.md b/editor_basics/README.md new file mode 100644 index 000000000..83512544b --- /dev/null +++ b/editor_basics/README.md @@ -0,0 +1,43 @@ +# Editor Sample Project [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Basics of Working with the Editor in IntelliJ SDK Docs][docs:editor_basics]* + +## Quickstart + +Editor Sample Project provides a [TypedHandlerDelegate][sdk:TypedHandlerDelegate] implementation, which inserts `editor_basics` on the top of the edited document any time user types a character. +In addition, three actions are available in the Editor context menu: + +- Editor Replace Text - replaces the selected text with `editor_basics`, +- Editor Add Caret - adds extra caret below the current one, +- Caret Position - shows message dialog with information about the caret position. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| --------------------------- | ------------------------------------- | ------------------------------------------------ | +| `com.intellij.typedHandler` | [MyTypedHandler][file:MyTypedHandler] | [TypedHandlerDelegate][sdk:TypedHandlerDelegate] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + +### Actions + +| ID | Implementation | Extension Point Class | +| ------------------------------------------ | ----------------------------------------------------------- | ------------------------ | +| `EditorBasics.EditorIllustrationAction` | [EditorIllustrationAction][file:EditorIllustrationAction] | [AnAction][sdk:AnAction] | +| `EditorBasics.EditorHandlerIllustration` | [EditorHandlerIllustration][file:EditorHandlerIllustration] | [AnAction][sdk:AnAction] | +| `EditorBasics.LogicalPositionIllustration` | [EditorAreaIllustration][file:EditorAreaIllustration] | [AnAction][sdk:AnAction] | + +*Reference: [Action System in IntelliJ SDK Docs][docs:actions]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:actions]: https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html +[docs:editor_basics]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/editor_basics.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:MyTypedHandler]: ./src/main/java/org/intellij/sdk/editor/MyTypedHandler.java +[file:EditorIllustrationAction]: ./src/main/java/org/intellij/sdk/editor/EditorIllustrationAction.java +[file:EditorHandlerIllustration]: ./src/main/java/org/intellij/sdk/editor/EditorHandlerIllustration.java +[file:EditorAreaIllustration]: ./src/main/java/org/intellij/sdk/editor/EditorAreaIllustration.java + +[sdk:TypedHandlerDelegate]: upsource:///platform/lang-api/src/com/intellij/codeInsight/editorActions/TypedHandlerDelegate.java +[sdk:AnAction]: upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java diff --git a/editor_basics/src/main/java/icons/SdkIcons.java b/editor_basics/src/main/java/icons/SdkIcons.java index 8f85195c2..204f14ff6 100644 --- a/editor_basics/src/main/java/icons/SdkIcons.java +++ b/editor_basics/src/main/java/icons/SdkIcons.java @@ -7,5 +7,7 @@ import com.intellij.openapi.util.IconLoader; import javax.swing.*; public class SdkIcons { + public static final Icon Sdk_default_icon = IconLoader.getIcon("/icons/sdk_16.svg"); + } diff --git a/editor_basics/src/main/java/org/intellij/sdk/editor/EditorAreaIllustration.java b/editor_basics/src/main/java/org/intellij/sdk/editor/EditorAreaIllustration.java index 08ca7a226..9cbe8cc9b 100644 --- a/editor_basics/src/main/java/org/intellij/sdk/editor/EditorAreaIllustration.java +++ b/editor_basics/src/main/java/org/intellij/sdk/editor/EditorAreaIllustration.java @@ -17,10 +17,11 @@ import org.jetbrains.annotations.NotNull; * @see com.intellij.openapi.actionSystem.AnAction */ public class EditorAreaIllustration extends AnAction { - + /** * Displays a message with information about the current caret. - * @param e Event related to this action + * + * @param e Event related to this action */ @Override public void actionPerformed(@NotNull final AnActionEvent e) { @@ -38,12 +39,13 @@ public class EditorAreaIllustration extends AnAction { "Offset: " + caretOffset; Messages.showInfoMessage(report, "Caret Parameters Inside The Editor"); } - + /** * Sets visibility and enables this action menu item if: - * A project is open, - * An editor is active, - * @param e Event related to this action + * A project is open, + * An editor is active, + * + * @param e Event related to this action */ @Override public void update(@NotNull final AnActionEvent e) { @@ -53,4 +55,5 @@ public class EditorAreaIllustration extends AnAction { //Set visibility only in case of existing project and editor e.getPresentation().setEnabledAndVisible(project != null && editor != null); } + } diff --git a/editor_basics/src/main/java/org/intellij/sdk/editor/EditorHandlerIllustration.java b/editor_basics/src/main/java/org/intellij/sdk/editor/EditorHandlerIllustration.java index 7b10f6ed6..8972312d2 100644 --- a/editor_basics/src/main/java/org/intellij/sdk/editor/EditorHandlerIllustration.java +++ b/editor_basics/src/main/java/org/intellij/sdk/editor/EditorHandlerIllustration.java @@ -2,9 +2,13 @@ package org.intellij.sdk.editor; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.actionSystem.*; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -14,9 +18,11 @@ import org.jetbrains.annotations.NotNull; * @see com.intellij.openapi.actionSystem.AnAction */ public class EditorHandlerIllustration extends AnAction { + /** * Clones a new caret at a higher Logical Position line number. - * @param e Event related to this action + * + * @param e Event related to this action */ @Override public void actionPerformed(@NotNull final AnActionEvent e) { @@ -25,17 +31,19 @@ public class EditorHandlerIllustration extends AnAction { // Get the action manager in order to get the necessary action handler... final EditorActionManager actionManager = EditorActionManager.getInstance(); // Get the action handler registered to clone carets - final EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW); + final EditorActionHandler actionHandler = + actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW); // Clone one caret below the active caret actionHandler.execute(editor, editor.getCaretModel().getPrimaryCaret(), e.getDataContext()); } - + /** * Enables and sets visibility of this action menu item if: - * A project is open, - * An editor is active, - * At least one caret exists - * @param e Event related to this action + * A project is open, + * An editor is active, + * At least one caret exists + * + * @param e Event related to this action */ @Override public void update(@NotNull final AnActionEvent e) { @@ -49,5 +57,5 @@ public class EditorHandlerIllustration extends AnAction { } e.getPresentation().setEnabledAndVisible(menuAllowed); } - + } diff --git a/editor_basics/src/main/java/org/intellij/sdk/editor/EditorIllustrationAction.java b/editor_basics/src/main/java/org/intellij/sdk/editor/EditorIllustrationAction.java index d1b70038b..8361750e7 100644 --- a/editor_basics/src/main/java/org/intellij/sdk/editor/EditorIllustrationAction.java +++ b/editor_basics/src/main/java/org/intellij/sdk/editor/EditorIllustrationAction.java @@ -18,10 +18,11 @@ import org.jetbrains.annotations.NotNull; * @see com.intellij.openapi.actionSystem.AnAction */ public class EditorIllustrationAction extends AnAction { - + /** * Replaces the run of text selected by the primary caret with a fixed string. - * @param e Event related to this action + * + * @param e Event related to this action */ @Override public void actionPerformed(@NotNull final AnActionEvent e) { @@ -37,18 +38,19 @@ public class EditorIllustrationAction extends AnAction { // Replace the selection with a fixed string. // Must do this document change in a write action context. WriteCommandAction.runWriteCommandAction(project, () -> - document.replaceString(start, end, "editor_basics") + document.replaceString(start, end, "editor_basics") ); // De-select the text range that was just replaced primaryCaret.removeSelection(); } - + /** * Sets visibility and enables this action menu item if: - * A project is open, - * An editor is active, - * Some characters are selected - * @param e Event related to this action + * A project is open, + * An editor is active, + * Some characters are selected + * + * @param e Event related to this action */ @Override public void update(@NotNull final AnActionEvent e) { @@ -56,6 +58,9 @@ public class EditorIllustrationAction extends AnAction { final Project project = e.getProject(); final Editor editor = e.getData(CommonDataKeys.EDITOR); // Set visibility and enable only in case of existing project and editor and if a selection exists - e.getPresentation().setEnabledAndVisible( project != null && editor != null && editor.getSelectionModel().hasSelection() ); + e.getPresentation().setEnabledAndVisible( + project != null && editor != null && editor.getSelectionModel().hasSelection() + ); } + } diff --git a/editor_basics/src/main/java/org/intellij/sdk/editor/MyTypedHandler.java b/editor_basics/src/main/java/org/intellij/sdk/editor/MyTypedHandler.java index 84eda26a8..f872ab6ef 100644 --- a/editor_basics/src/main/java/org/intellij/sdk/editor/MyTypedHandler.java +++ b/editor_basics/src/main/java/org/intellij/sdk/editor/MyTypedHandler.java @@ -17,6 +17,7 @@ import org.jetbrains.annotations.NotNull; * Document changes are made in the context of a write action. */ class MyTypedHandler extends TypedHandlerDelegate { + @NotNull @Override public Result charTyped(char c, @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { @@ -28,4 +29,5 @@ class MyTypedHandler extends TypedHandlerDelegate { WriteCommandAction.runWriteCommandAction(project, runnable); return Result.STOP; } + } diff --git a/editor_basics/src/main/resources/META-INF/plugin.xml b/editor_basics/src/main/resources/META-INF/plugin.xml index 319781f97..4247060e0 100644 --- a/editor_basics/src/main/resources/META-INF/plugin.xml +++ b/editor_basics/src/main/resources/META-INF/plugin.xml @@ -2,20 +2,22 @@ - + org.intellij.sdk.editor - SDK: Editor Sample Project + SDK: Editor Sample com.intellij.modules.platform - + Mouse over each of this plugin's menu items to see hints in the lower left corner of the IDE. - ]]> + Illustrates various basic Editor APIs. Requires at least project to be open, and a file open in the editor + to see the menu items this plugin adds to the editor popup menu.
Mouse over each of this plugin's menu items + to see hints in the lower left corner of the IDE. + ]]>
Facets` section. +It allows us to specify any configuration specified by the `FacetConfiguration` implementation - path to the SDK in this case. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ------------------------ | ----------------------------------- | -------------------------- | +| `com.intellij.facetType` | [DemoFacetType][file:DemoFacetType] | [FacetType][sdk:FacetType] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:facet_basics]: https://www.jetbrains.org/intellij/sdk/docs/reference_guide/project_model/facet.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:DemoFacetType]: ./src/main/java/org/intellij/sdk/facet/DemoFacetType.java + +[sdk:FacetType]: upsource:///platform/lang-api/src/com/intellij/facet/FacetType.java diff --git a/facet_basics/src/main/java/icons/SdkIcons.java b/facet_basics/src/main/java/icons/SdkIcons.java index 8f85195c2..204f14ff6 100644 --- a/facet_basics/src/main/java/icons/SdkIcons.java +++ b/facet_basics/src/main/java/icons/SdkIcons.java @@ -7,5 +7,7 @@ import com.intellij.openapi.util.IconLoader; import javax.swing.*; public class SdkIcons { + public static final Icon Sdk_default_icon = IconLoader.getIcon("/icons/sdk_16.svg"); + } diff --git a/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetConfiguration.java b/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetConfiguration.java index 2a69e907b..3b1ce7a15 100644 --- a/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetConfiguration.java +++ b/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetConfiguration.java @@ -20,6 +20,7 @@ public class DemoFacetConfiguration implements FacetConfiguration, PersistentSta /** * Called by the IntelliJ Platform when saving this facet's state persistently. + * * @return a component state. All properties, public and annotated fields are serialized. * Only values which differ from default (i.e. the value of newly instantiated class) are serialized. * {@code null} value indicates that the returned state won't be stored, and @@ -30,7 +31,7 @@ public class DemoFacetConfiguration implements FacetConfiguration, PersistentSta public DemoFacetState getState() { return myFacetState; } - + /** * Called by the IntelliJ Platform when this facet's state is loaded. * The method can and will be called several times, if @@ -40,7 +41,7 @@ public class DemoFacetConfiguration implements FacetConfiguration, PersistentSta public void loadState(@NotNull DemoFacetState state) { myFacetState = state; } - + /** * Creates a set of editor tabs for this facet, potentially one per context. * @@ -51,7 +52,7 @@ public class DemoFacetConfiguration implements FacetConfiguration, PersistentSta @Override public FacetEditorTab[] createEditorTabs(FacetEditorContext context, FacetValidatorsManager manager) { return new FacetEditorTab[]{ - new DemoFacetEditorTab(myFacetState, context, manager) + new DemoFacetEditorTab(myFacetState, context, manager) }; } diff --git a/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetEditorTab.java b/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetEditorTab.java index c2b807f37..910b44763 100644 --- a/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetEditorTab.java +++ b/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetEditorTab.java @@ -6,7 +6,6 @@ import com.intellij.facet.ui.FacetEditorContext; import com.intellij.facet.ui.FacetEditorTab; import com.intellij.facet.ui.FacetValidatorsManager; import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -20,10 +19,10 @@ import java.awt.*; */ public class DemoFacetEditorTab extends FacetEditorTab { private static final String FACET_PANEL_PROMPT = "Path To SDK: "; - + private final DemoFacetState mySettings; private final JTextField myPath; - + /** * Only org.intellij.sdk.facet.DemoFacetState is captured so it can be updated per user changes * in the EditorTab. @@ -33,11 +32,12 @@ public class DemoFacetEditorTab extends FacetEditorTab { * @param validator Facet validator manager, can be used to get and apply a custom validator for * this facet. */ - public DemoFacetEditorTab(@NotNull DemoFacetState state, @NotNull FacetEditorContext context, @NotNull FacetValidatorsManager validator) { + public DemoFacetEditorTab(@NotNull DemoFacetState state, @NotNull FacetEditorContext context, + @NotNull FacetValidatorsManager validator) { mySettings = state; myPath = new JTextField(state.getDemoFacetState()); } - + /** * Provides the JPanel displayed in the Preferences | Facet UI * @@ -53,8 +53,8 @@ public class DemoFacetEditorTab extends FacetEditorTab { facetPanel.add(top, BorderLayout.NORTH); return facetPanel; } - - + + /** * @return the name of this facet for display in this editor tab. */ @@ -63,7 +63,7 @@ public class DemoFacetEditorTab extends FacetEditorTab { public String getDisplayName() { return DemoFacetType.FACET_NAME; } - + /** * Determines if the facet state entered in the UI differs * from the currently stored state. @@ -76,7 +76,7 @@ public class DemoFacetEditorTab extends FacetEditorTab { public boolean isModified() { return !StringUtil.equals(mySettings.getDemoFacetState(), myPath.getText().trim()); } - + /** * Stores new facet state (text) entered by the user. * Called when {@link #isModified()} returns true. @@ -92,7 +92,7 @@ public class DemoFacetEditorTab extends FacetEditorTab { throw new ConfigurationException(e.toString()); } } - + /** * Copies current org.intellij.sdk.facet.DemoFacetState into the myPath UI element. * This method is called each time this editor tab is needed for display. @@ -101,5 +101,5 @@ public class DemoFacetEditorTab extends FacetEditorTab { public void reset() { myPath.setText(mySettings.getDemoFacetState()); } - + } diff --git a/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetState.java b/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetState.java index 337e971fe..58b2bc275 100644 --- a/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetState.java +++ b/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetState.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull; * In this case it is just a string containing a path to an SDK. */ public class DemoFacetState { + static final String DEMO_FACET_INIT_PATH = ""; public String myPathToSdk; diff --git a/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetType.java b/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetType.java index 141f6d6d4..2ad43f971 100644 --- a/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetType.java +++ b/facet_basics/src/main/java/org/intellij/sdk/facet/DemoFacetType.java @@ -2,11 +2,14 @@ package org.intellij.sdk.facet; -import com.intellij.facet.*; +import com.intellij.facet.Facet; +import com.intellij.facet.FacetType; +import com.intellij.facet.FacetTypeId; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; import icons.SdkIcons; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -16,6 +19,7 @@ import javax.swing.*; * Allows application of this facet to all ModuleTypes. */ public class DemoFacetType extends FacetType { + public static final String FACET_ID = "DEMO_FACET_ID"; public static final String FACET_NAME = "SDK Facet"; public static final FacetTypeId DEMO_FACET_TYPE_ID = new FacetTypeId<>(FACET_ID); @@ -47,4 +51,5 @@ public class DemoFacetType extends FacetType public Icon getIcon() { return SdkIcons.Sdk_default_icon; } + } diff --git a/facet_basics/src/main/resources/META-INF/plugin.xml b/facet_basics/src/main/resources/META-INF/plugin.xml index c46b4f091..c26d0b04f 100644 --- a/facet_basics/src/main/resources/META-INF/plugin.xml +++ b/facet_basics/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ - + org.intellij.sdk.facet @@ -11,10 +11,11 @@ com.intellij.modules.lang - + Adds SDK Facet to the Project Structure | Project Settings | Facets menu. + Demonstrates implementing the custom Facet pattern.
Adds SDK Facet + to the Project Structure | Project Settings | Facets menu. ]]>
diff --git a/framework_basics/README.md b/framework_basics/README.md new file mode 100644 index 000000000..818bac6bb --- /dev/null +++ b/framework_basics/README.md @@ -0,0 +1,24 @@ +# Framework Sample Project [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Supporting Frameworks in IntelliJ SDK Docs][docs:supporting_frameworks]* + +## Quickstart + +Framework Sample Project provides a [DemoFramework][file:DemoFramework], which allows embedding framework support within the Project Wizard. +This sample implementation adds a new *SDK Demo Framework* support in the Java type project. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ----------------------------- | ----------------------------------- | -------------------------------------- | +| `com.intellij.framework.type` | [DemoFramework][file:DemoFramework] | [FrameworkTypeEx][sdk:FrameworkTypeEx] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:supporting_frameworks]: https://jetbrains.org/intellij/sdk/docs/tutorials/framework.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:DemoFramework]: ./src/main/java/org/intellij/sdk/framework/DemoFramework.java + +[sdk:FrameworkTypeEx]: upsource:///java/idea-ui/src/com/intellij/framework/FrameworkTypeEx.java diff --git a/framework_basics/src/main/java/icons/SdkIcons.java b/framework_basics/src/main/java/icons/SdkIcons.java index 8f85195c2..204f14ff6 100644 --- a/framework_basics/src/main/java/icons/SdkIcons.java +++ b/framework_basics/src/main/java/icons/SdkIcons.java @@ -7,5 +7,7 @@ import com.intellij.openapi.util.IconLoader; import javax.swing.*; public class SdkIcons { + public static final Icon Sdk_default_icon = IconLoader.getIcon("/icons/sdk_16.svg"); + } diff --git a/framework_basics/src/main/java/org/intellij/sdk/framework/DemoFramework.java b/framework_basics/src/main/java/org/intellij/sdk/framework/DemoFramework.java index 7db81b6c6..5fe691d49 100644 --- a/framework_basics/src/main/java/org/intellij/sdk/framework/DemoFramework.java +++ b/framework_basics/src/main/java/org/intellij/sdk/framework/DemoFramework.java @@ -71,4 +71,5 @@ public class DemoFramework extends FrameworkTypeEx { public Icon getIcon() { return SdkIcons.Sdk_default_icon; } + } diff --git a/framework_basics/src/main/resources/META-INF/plugin.xml b/framework_basics/src/main/resources/META-INF/plugin.xml index 430687083..9680c92ef 100644 --- a/framework_basics/src/main/resources/META-INF/plugin.xml +++ b/framework_basics/src/main/resources/META-INF/plugin.xml @@ -2,19 +2,20 @@ - + org.intellij.sdk.framework - - SDK: Framework Sample Project + + SDK: Framework Sample com.intellij.modules.java - + Adds SDK Demo Framework to File | New | Project | IntelliJ Platform Plugin + Demonstrates basic Framework support.
Adds SDK Demo Framework to + File | New | Project | IntelliJ Platform Plugin ]]>
diff --git a/inspection_basics/README.md b/inspection_basics/README.md new file mode 100644 index 000000000..dabfb0a65 --- /dev/null +++ b/inspection_basics/README.md @@ -0,0 +1,25 @@ +# Inspection Sample Project [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Code Inspections in IntelliJ SDK Docs][docs:code_inspections]* + +## Quickstart + +Inspection Sample Project implements a simple local inspection producing warnings for the regular plain text files. + +Inspection, enabled by default, uses a visitor passing all PSI elements with no error reporting. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ------------------------------ | --------------------------------------------- | ---------------------------------------------- | +| `com.intellij.localInspection` | [DemoCodeInspection][file:DemoCodeInspection] | [LocalInspectionTool][sdk:LocalInspectionTool] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:code_inspections]: https://jetbrains.org/intellij/sdk/docs/tutorials/code_inspections.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:DemoCodeInspection]: ./src/main/java/org/intellij/sdk/inspection/DemoCodeInspection.java + +[sdk:LocalInspectionTool]: upsource:///platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java diff --git a/inspection_basics/src/main/java/org/intellij/sdk/inspection/DemoCodeInspection.java b/inspection_basics/src/main/java/org/intellij/sdk/inspection/DemoCodeInspection.java index eb45d58b7..dff347146 100644 --- a/inspection_basics/src/main/java/org/intellij/sdk/inspection/DemoCodeInspection.java +++ b/inspection_basics/src/main/java/org/intellij/sdk/inspection/DemoCodeInspection.java @@ -7,7 +7,7 @@ import com.intellij.codeInspection.ProblemsHolder; import org.jetbrains.annotations.NotNull; public class DemoCodeInspection extends LocalInspectionTool { - + /** * This method is overridden to provide a custom visitor * The visitor must not be recursive and must be thread-safe. @@ -21,4 +21,5 @@ public class DemoCodeInspection extends LocalInspectionTool { public DemoInspectionVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { return new DemoInspectionVisitor(); } + } diff --git a/inspection_basics/src/main/java/org/intellij/sdk/inspection/DemoInspectionVisitor.java b/inspection_basics/src/main/java/org/intellij/sdk/inspection/DemoInspectionVisitor.java index 39a0c8f48..570e26c31 100644 --- a/inspection_basics/src/main/java/org/intellij/sdk/inspection/DemoInspectionVisitor.java +++ b/inspection_basics/src/main/java/org/intellij/sdk/inspection/DemoInspectionVisitor.java @@ -8,6 +8,7 @@ import com.intellij.psi.PsiPlainTextFile; import org.jetbrains.annotations.NotNull; public class DemoInspectionVisitor extends PsiElementVisitor { + @Override public void visitElement(@NotNull PsiElement element) { super.visitElement(element); @@ -17,4 +18,5 @@ public class DemoInspectionVisitor extends PsiElementVisitor { public void visitPlainTextFile(@NotNull PsiPlainTextFile file) { super.visitPlainTextFile(file); } + } diff --git a/inspection_basics/src/main/resources/META-INF/plugin.xml b/inspection_basics/src/main/resources/META-INF/plugin.xml index 11835f1d8..c048ed606 100644 --- a/inspection_basics/src/main/resources/META-INF/plugin.xml +++ b/inspection_basics/src/main/resources/META-INF/plugin.xml @@ -2,19 +2,20 @@ - + org.intellij.sdk.inspection - SDK: Inspection Sample Project + SDK: Inspection Sample com.intellij.modules.lang - + Preferences | Editor | Inspections | SDK | Example Tools
. + Basic example of working with code inspections. Adds entry to + Preferences | Editor | Inspections | SDK | Example Tools. ]]>
@@ -31,27 +32,28 @@ IntelliJ Platform SDK + + type element is applied within the scope of a file under edit. + It is preferred over + @see intellij.platform.resources.LangExtensionPoints + @see com.intellij.codeInspection.InspectionProfileEntry + + Attributes: + language= Language ID + shortName= Not specified, will be computed by the underlying implementation classes. + displayName= The string to be shown in the Preferences | Editor | Inspections panel + The displayName gets registered to identify this inspection. + Can be localized using key= and bundle= attributes instead. + groupPath= Defines the outermost grouping for this inspection in + the Preferences | Editor | Inspections panel. Not localized. + groupName= The subgroup containing this inspection. Not localized. + enabledByDefault= Inspection state when Inspections panel is created. + level= The default level of error found by this inspection, e.g. INFO, ERROR, etc. + @see com.intellij.codeHighlighting.HighlightDisplayLevel + implementationClass= FQN of inspection implementation + --> +
diff --git a/kotlin_demo/README.md b/kotlin_demo/README.md new file mode 100644 index 000000000..d28bce2f3 --- /dev/null +++ b/kotlin_demo/README.md @@ -0,0 +1,25 @@ +# Kotlin Demo [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Kotlin for Plugin Developers in IntelliJ SDK Docs][docs:kotlin]* + +## Quickstart + +Simple Kotlin Demo project is an example of the Kotlin-based plugin that provides the most straightforward action implemented by the [HelloAction.kt][file:HelloAction] Kotlin class. + +Action, added to the Main Menu, shows a message dialog when invoked. + +### Actions + +| ID | Implementation | Extension Point Class | +| ---------------- | ------------------------------- | ------------------------ | +| `MyPlugin.Hello` | [HelloAction][file:HelloAction] | [AnAction][sdk:AnAction] | + +*Reference: [Action System in IntelliJ SDK Docs][docs:actions]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:actions]: https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html +[docs:kotlin]: https://jetbrains.org/intellij/sdk/docs/tutorials/kotlin.html + +[file:HelloAction]: ./src/main/kotlin/org/intellij/sdk/kotlin/HelloAction.kt + +[sdk:AnAction]: upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java diff --git a/kotlin_demo/src/main/kotlin/org/intellij/sdk/kotlin/HelloAction.kt b/kotlin_demo/src/main/kotlin/org/intellij/sdk/kotlin/HelloAction.kt index f10a8f3b7..4c91da157 100644 --- a/kotlin_demo/src/main/kotlin/org/intellij/sdk/kotlin/HelloAction.kt +++ b/kotlin_demo/src/main/kotlin/org/intellij/sdk/kotlin/HelloAction.kt @@ -13,4 +13,5 @@ class HelloAction : DumbAwareAction() { val project = event.getData(PlatformDataKeys.PROJECT) Messages.showMessageDialog(project, "Hello from Kotlin!", "Greeting", Messages.getInformationIcon()) } + } diff --git a/kotlin_demo/src/main/resources/META-INF/plugin.xml b/kotlin_demo/src/main/resources/META-INF/plugin.xml index b2374671b..a92d0efca 100644 --- a/kotlin_demo/src/main/resources/META-INF/plugin.xml +++ b/kotlin_demo/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ - + org.intellij.sdk.kotlin @@ -11,10 +11,10 @@ com.intellij.modules.platform - + Greeting menu group anchored last in the Main Menu + Adds a Greeting menu group anchored last in the Main Menu ]]> diff --git a/live_templates/README.md b/live_templates/README.md new file mode 100644 index 000000000..979c973c6 --- /dev/null +++ b/live_templates/README.md @@ -0,0 +1,31 @@ +# Live Templates Sample [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Live Templates in IntelliJ SDK Docs][docs:live_templates]* + +## Quickstart + +Live Templates Sample Project implements two example live templates for the Markdown language: + +- New link reference - by typing the `{`, the following template will be inserted: `[$TEXT$]($LINK$)$END$` +- Convert to title case - retrieves the text from the macro or selection, if available. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ----------------------------------- | --------------------------------------- | ---------------------------------------------- | +| `com.intellij.defaultLiveTemplates` | [Markdown][file:Markdown] | | +| `com.intellij.liveTemplateContext` | [MarkdownContext][file:MarkdownContext] | [TemplateContextType][sdk:TemplateContextType] | +| `com.intellij.liveTemplateMacro` | [TitleCaseMacro][file:TitleCaseMacro] | [MacroBase][sdk:MacroBase] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:live_templates]: https://jetbrains.org/intellij/sdk/docs/tutorials/live_templates.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:Markdown]: ./src/main/resources/liveTemplates/Markdown.xml +[file:MarkdownContext]: ./src/main/java/org/intellij/sdk/liveTemplates/MarkdownContext.java +[file:TitleCaseMacro]: ./src/main/java/org/intellij/sdk/liveTemplates/TitleCaseMacro.java + +[sdk:TemplateContextType]: upsource:///platform/analysis-api/src/com/intellij/codeInsight/template/TemplateContextType.java +[sdk:MacroBase]: upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/macro/MacroBase.java diff --git a/live_templates/src/main/java/org/intellij/sdk/liveTemplates/MarkdownContext.java b/live_templates/src/main/java/org/intellij/sdk/liveTemplates/MarkdownContext.java index 266a71f71..c405794a6 100644 --- a/live_templates/src/main/java/org/intellij/sdk/liveTemplates/MarkdownContext.java +++ b/live_templates/src/main/java/org/intellij/sdk/liveTemplates/MarkdownContext.java @@ -4,10 +4,10 @@ package org.intellij.sdk.liveTemplates; import com.intellij.codeInsight.template.TemplateActionContext; import com.intellij.codeInsight.template.TemplateContextType; -import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; public class MarkdownContext extends TemplateContextType { + protected MarkdownContext() { super("MARKDOWN", "Markdown"); } diff --git a/live_templates/src/main/java/org/intellij/sdk/liveTemplates/TitleCaseMacro.java b/live_templates/src/main/java/org/intellij/sdk/liveTemplates/TitleCaseMacro.java index 0e384ca22..391accdd1 100644 --- a/live_templates/src/main/java/org/intellij/sdk/liveTemplates/TitleCaseMacro.java +++ b/live_templates/src/main/java/org/intellij/sdk/liveTemplates/TitleCaseMacro.java @@ -8,6 +8,7 @@ import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; public class TitleCaseMacro extends MacroBase { + public TitleCaseMacro() { super("titleCase", "titleCase(String)"); } @@ -23,14 +24,14 @@ public class TitleCaseMacro extends MacroBase { protected Result calculateResult(@NotNull Expression[] params, ExpressionContext context, boolean quick) { // Retrieve the text from the macro or selection, if any is available. String text = getTextResult(params, context, true); - if (text != null) { - if (text.length() > 0) { - // Capitalize the start of every word - text = StringUtil.toTitleCase(text); - } - return new TextResult(text); + if (text == null) { + return null; } - return null; + if (text.length() > 0) { + // Capitalize the start of every word + text = StringUtil.toTitleCase(text); + } + return new TextResult(text); } @Override diff --git a/live_templates/src/main/resources/META-INF/plugin.xml b/live_templates/src/main/resources/META-INF/plugin.xml index f601c73fe..9fbdd113a 100644 --- a/live_templates/src/main/resources/META-INF/plugin.xml +++ b/live_templates/src/main/resources/META-INF/plugin.xml @@ -2,19 +2,20 @@ - + org.intellij.sdk.liveTemplates - SDK: Live Templates Sample Project + SDK: Live Templates Sample com.intellij.modules.lang - + Adds an entry to the Preferences | Editor | Live Templates dialog. + Demonstrates implementing live templates for Markdown language.
Adds an entry to the + Preferences | Editor | Live Templates dialog. ]]>
diff --git a/max_opened_projects/README.md b/max_opened_projects/README.md new file mode 100644 index 000000000..36165e64a --- /dev/null +++ b/max_opened_projects/README.md @@ -0,0 +1,35 @@ +# Maximum Open Projects Sample [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Plugin Services in IntelliJ SDK Docs][docs:plugin_services]* + +## Quickstart + +Maximum Open Projects Sample implements a `ProjectManagerListener` with two methods applied to check if the current projects have been opened or closed. +Each method refers to the `ProjectCountingService` service registered as an `applicationService` extension point. +It provides methods to increase and decrease the global counter of the currently opened projects in the IDE. +After opening each one, a message dialog is presented to the user with the current number. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| --------------------------------- | ----------------------------------------------------- | --------------------- | +| `com.intellij.applicationService` | [ProjectCountingService][file:ProjectCountingService] | | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + +### Application Listeners + +| Name | Implementation | Extension Point Class | +| -------- | --------------------------------------------------------- | ---------------------------------------------------- | +| listener | [ProjectOpenCloseListener][file:ProjectOpenCloseListener] | [ProjectManagerListener][sdk:ProjectManagerListener] | + +*Reference: [Plugin Listeners in IntelliJ SDK Docs][docs:listeners]* + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:plugin_services]: https://jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_services.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html +[docs:listeners]: https://jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_listeners.html + +[file:ProjectCountingService]: ./src/main/java/org/intellij/sdk/maxOpenProjects/ProjectCountingService.java +[file:ProjectOpenCloseListener]: ./src/main/java/org/intellij/sdk/maxOpenProjects/ProjectOpenCloseListener.java + +[sdk:ProjectManagerListener]: upsource:///platform/projectModel-api/src/com/intellij/openapi/project/ProjectManagerListener.java diff --git a/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenProjects/ProjectCountingService.java b/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenProjects/ProjectCountingService.java index cd8b77f5a..886cfb062 100644 --- a/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenProjects/ProjectCountingService.java +++ b/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenProjects/ProjectCountingService.java @@ -7,6 +7,7 @@ package org.intellij.sdk.maxOpenProjects; * how many projects are open at a given time. */ public class ProjectCountingService { + // Sets the maximum allowed number of opened projects. private final static int MAX_OPEN_PRJ_LIMIT = 3; // The count of open projects must always be >= 0 diff --git a/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenProjects/ProjectOpenCloseListener.java b/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenProjects/ProjectOpenCloseListener.java index 62e1112bf..288a6f8c6 100644 --- a/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenProjects/ProjectOpenCloseListener.java +++ b/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenProjects/ProjectOpenCloseListener.java @@ -23,7 +23,9 @@ public class ProjectOpenCloseListener implements ProjectManagerListener { @Override public void projectOpened(@NotNull Project project) { // Ensure this isn't part of testing - if (ApplicationManager.getApplication().isUnitTestMode()) return; + if (ApplicationManager.getApplication().isUnitTestMode()) { + return; + } // Get the counting service ProjectCountingService projectCountingService = ServiceManager.getService(ProjectCountingService.class); // Increment the project count @@ -46,7 +48,9 @@ public class ProjectOpenCloseListener implements ProjectManagerListener { @Override public void projectClosed(@NotNull Project project) { // Ensure this isn't part of testing - if (ApplicationManager.getApplication().isUnitTestMode()) return; + if (ApplicationManager.getApplication().isUnitTestMode()) { + return; + } // Get the counting service ProjectCountingService projectCountingService = ServiceManager.getService(ProjectCountingService.class); // Decrement the count because a project just closed diff --git a/max_opened_projects/src/main/resources/META-INF/plugin.xml b/max_opened_projects/src/main/resources/META-INF/plugin.xml index 0cf2327af..6b7106567 100644 --- a/max_opened_projects/src/main/resources/META-INF/plugin.xml +++ b/max_opened_projects/src/main/resources/META-INF/plugin.xml @@ -2,25 +2,29 @@ - + org.intellij.sdk.maxOpenProjects - + SDK: Maximum Open Projects Sample com.intellij.modules.platform - + -
  • 2.1.0 Remove project component and use listener instead. No longer denies opening additional projects. Just notifies the user.
  • +
  • + 2.1.0 Remove project component and use listener instead. No longer denies opening additional + projects. Just notifies the user. +
  • 2.0.0 Convert to Gradle-based plugin.
  • 1.0.0 Release 2018.3 and earlier.
  • @@ -31,10 +35,12 @@ IntelliJ Platform SDK - + +
    diff --git a/module/README.md b/module/README.md new file mode 100644 index 000000000..c70f502ad --- /dev/null +++ b/module/README.md @@ -0,0 +1,24 @@ +# Module Type Sample [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Plugin Services in IntelliJ SDK Docs][docs:plugin_services]* + +## Quickstart + +The sample project that presents an implementation of the `moduleType` extension point, which adds a new module type to the *New Module* Project Wizard. +Module with a custom name, description, and icon set provides a `ModuleBuilder` with extra steps present for additional module configuration. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ------------------------- | ------------------------------------- | ---------------------------- | +| `com.intellij.moduleType` | [DemoModuleType][file:DemoModuleType] | [ModuleType][sdk:ModuleType] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:plugin_services]: https://jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_services.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:DemoModuleType]: ./src/main/java/org/intellij/sdk/module/DemoModuleType.java + +[sdk:ModuleType]: upsource:///platform/lang-api/src/com/intellij/openapi/module/ModuleType.java diff --git a/module/src/main/java/icons/SdkIcons.java b/module/src/main/java/icons/SdkIcons.java index 8f85195c2..204f14ff6 100644 --- a/module/src/main/java/icons/SdkIcons.java +++ b/module/src/main/java/icons/SdkIcons.java @@ -7,5 +7,7 @@ import com.intellij.openapi.util.IconLoader; import javax.swing.*; public class SdkIcons { + public static final Icon Sdk_default_icon = IconLoader.getIcon("/icons/sdk_16.svg"); + } diff --git a/module/src/main/java/org/intellij/sdk/module/DemoModuleBuilder.java b/module/src/main/java/org/intellij/sdk/module/DemoModuleBuilder.java index c03e13ff6..7d9e9fe8c 100644 --- a/module/src/main/java/org/intellij/sdk/module/DemoModuleBuilder.java +++ b/module/src/main/java/org/intellij/sdk/module/DemoModuleBuilder.java @@ -6,19 +6,18 @@ import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.ModuleWizardStep; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.Disposable; -import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.roots.ModifiableRootModel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class DemoModuleBuilder extends ModuleBuilder { + @Override public void setupRootModel(@NotNull ModifiableRootModel model) { - } @Override - public ModuleType getModuleType() { + public DemoModuleType getModuleType() { return DemoModuleType.getInstance(); } @@ -27,4 +26,5 @@ public class DemoModuleBuilder extends ModuleBuilder { public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) { return new DemoModuleWizardStep(); } + } diff --git a/module/src/main/java/org/intellij/sdk/module/DemoModuleType.java b/module/src/main/java/org/intellij/sdk/module/DemoModuleType.java index 961f4fd5b..b62807d91 100644 --- a/module/src/main/java/org/intellij/sdk/module/DemoModuleType.java +++ b/module/src/main/java/org/intellij/sdk/module/DemoModuleType.java @@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; public class DemoModuleType extends ModuleType { + private static final String ID = "DEMO_MODULE_TYPE"; public DemoModuleType() { @@ -54,4 +55,5 @@ public class DemoModuleType extends ModuleType { @NotNull ModulesProvider modulesProvider) { return super.createWizardSteps(wizardContext, moduleBuilder, modulesProvider); } + } diff --git a/module/src/main/java/org/intellij/sdk/module/DemoModuleWizardStep.java b/module/src/main/java/org/intellij/sdk/module/DemoModuleWizardStep.java index 3dc3707e6..158d33adf 100644 --- a/module/src/main/java/org/intellij/sdk/module/DemoModuleWizardStep.java +++ b/module/src/main/java/org/intellij/sdk/module/DemoModuleWizardStep.java @@ -7,6 +7,7 @@ import com.intellij.ide.util.projectWizard.ModuleWizardStep; import javax.swing.*; public class DemoModuleWizardStep extends ModuleWizardStep { + @Override public JComponent getComponent() { return new JLabel("Provide some setting here"); @@ -16,4 +17,5 @@ public class DemoModuleWizardStep extends ModuleWizardStep { public void updateDataModel() { //todo update model according to UI } + } diff --git a/module/src/main/resources/META-INF/plugin.xml b/module/src/main/resources/META-INF/plugin.xml index 0b5a1c5a5..3568b15b6 100644 --- a/module/src/main/resources/META-INF/plugin.xml +++ b/module/src/main/resources/META-INF/plugin.xml @@ -2,16 +2,16 @@ - + org.intellij.sdk.module - - SDK: Module Type Sample Project + + SDK: Module Type Sample com.intellij.modules.platform - + Adds SDK Demo Module to File | New | Project... diff --git a/product_specific/pycharm_basics/README.md b/product_specific/pycharm_basics/README.md new file mode 100644 index 000000000..15761cf3f --- /dev/null +++ b/product_specific/pycharm_basics/README.md @@ -0,0 +1,23 @@ +# PyCharm Sample [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [PyCharm Plugin Development in IntelliJ SDK Docs][docs:pycharm]* + +## Quickstart + +PyCharm Sample is a plugin that depends on the PyCharm IDE having the proper dependencies specified in the Gradle configuration file. +The implementation utilizes a simple action added to the *MainMenu* group displaying a message dialog after invoking. + +### Actions + +| ID | Implementation | Extension Point Class | +| -------------------------------------------- | ------------------------------------------- | ------------------------ | +| `org.intellij.sdk.pycharm.PopupDialogAction` | [PopupDialogAction][file:PopupDialogAction] | [AnAction][sdk:AnAction] | + +*Reference: [Action System in IntelliJ SDK Docs][docs:actions]* + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:actions]: https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html +[docs:pycharm]: https://jetbrains.org/intellij/sdk/docs/products/pycharm.html + +[file:PopupDialogAction]: ./src/main/java/org/intellij/sdk/pycharm/PopupDialogAction.java + +[sdk:AnAction]: upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java diff --git a/product_specific/pycharm_basics/src/main/java/icons/SdkIcons.java b/product_specific/pycharm_basics/src/main/java/icons/SdkIcons.java index 8f85195c2..204f14ff6 100644 --- a/product_specific/pycharm_basics/src/main/java/icons/SdkIcons.java +++ b/product_specific/pycharm_basics/src/main/java/icons/SdkIcons.java @@ -7,5 +7,7 @@ import com.intellij.openapi.util.IconLoader; import javax.swing.*; public class SdkIcons { + public static final Icon Sdk_default_icon = IconLoader.getIcon("/icons/sdk_16.svg"); + } diff --git a/product_specific/pycharm_basics/src/main/java/org/intellij/sdk/pycharm/PopupDialogAction.java b/product_specific/pycharm_basics/src/main/java/org/intellij/sdk/pycharm/PopupDialogAction.java index d8ee8f938..a85f8d51b 100644 --- a/product_specific/pycharm_basics/src/main/java/org/intellij/sdk/pycharm/PopupDialogAction.java +++ b/product_specific/pycharm_basics/src/main/java/org/intellij/sdk/pycharm/PopupDialogAction.java @@ -15,25 +15,27 @@ import org.jetbrains.annotations.NotNull; * in the plugin.xml file. But when added at runtime this class is instantiated by an action group. */ public class PopupDialogAction extends AnAction { - + /** * Gives the user feedback when the dynamic action menu is chosen. * Pops a simple message dialog. See the psi_demo plugin for an * example of how to use AnActionEvent to access data. + * * @param event Event received when the associated menu item is chosen. */ @Override public void actionPerformed(@NotNull AnActionEvent event) { Project project = event.getProject(); Messages.showMessageDialog(project, - "Popup dialog action", - "Greetings from PyCharm Basics Plugin", - Messages.getInformationIcon()); + "Popup dialog action", + "Greetings from PyCharm Basics Plugin", + Messages.getInformationIcon()); } - + /** * Determines whether this menu item is available for the current context. * Requires a project to be open. + * * @param e Event received when the associated group-id menu is chosen. */ @Override @@ -42,5 +44,5 @@ public class PopupDialogAction extends AnAction { Project project = e.getProject(); e.getPresentation().setEnabledAndVisible(project != null); } - + } diff --git a/product_specific/pycharm_basics/src/main/resources/META-INF/plugin.xml b/product_specific/pycharm_basics/src/main/resources/META-INF/plugin.xml index ff651aea0..177c55ba3 100644 --- a/product_specific/pycharm_basics/src/main/resources/META-INF/plugin.xml +++ b/product_specific/pycharm_basics/src/main/resources/META-INF/plugin.xml @@ -2,19 +2,19 @@ - + org.intellij.sdk.pycharm - SDK: PyCharm Sample Project + SDK: PyCharm Sample com.intellij.modules.python - + @@ -27,10 +27,10 @@ IntelliJ Platform SDK - + - + diff --git a/project_model/README.md b/project_model/README.md new file mode 100644 index 000000000..0cc868dcd --- /dev/null +++ b/project_model/README.md @@ -0,0 +1,36 @@ +# Project Model Sample [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [PyCharm Plugin Development in IntelliJ SDK Docs][docs:pycharm]* + +## Quickstart + +Project Model Sample project provides five actions that present data extracted using `ProjectRootManager` instance in the message dialogs. Within the implemented actions, you will be able to: +- fetch libraries used in the project, +- retrieve the information about the module details, +- rename the used SDK, +- get the content source roots, +- or extend the project dependencies with an additional library. + +### Actions + +| ID | Implementation | Extension Point Class | +| --------------------------------- | ----------------------------------------------------------------- | ------------------------ | +| `ProjectModel.SourceRoots` | [ShowSourceRootsActions][file:ShowSourceRootsActions] | [AnAction][sdk:AnAction] | +| `ProjectModel.ProjectSdk` | [ProjectSdkAction][file:ProjectSdkAction] | [AnAction][sdk:AnAction] | +| `ProjectModel.ProjectFileIndex` | [ProjectFileIndexSampleAction][file:ProjectFileIndexSampleAction] | [AnAction][sdk:AnAction] | +| `ProjectModel.ModificationAction` | [ModificationAction][file:ModificationAction] | [AnAction][sdk:AnAction] | +| `ProjectModel.LibrariesAction` | [LibrariesAction][file:LibrariesAction] | [AnAction][sdk:AnAction] | + +*Reference: [Action System in IntelliJ SDK Docs][docs:actions]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:actions]: https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html +[docs:pycharm]: https://jetbrains.org/intellij/sdk/docs/products/pycharm.html + +[file:ShowSourceRootsActions]: ./src/main/java/org/intellij/sdk/project/model/ShowSourceRootsActions.java +[file:ProjectSdkAction]: ./src/main/java/org/intellij/sdk/project/model/ProjectSdkAction.java +[file:ProjectFileIndexSampleAction]: ./src/main/java/org/intellij/sdk/project/model/ProjectFileIndexSampleAction.java +[file:ModificationAction]: ./src/main/java/org/intellij/sdk/project/model/ModificationAction.java +[file:LibrariesAction]: ./src/main/java/org/intellij/sdk/project/model/LibrariesAction.java + +[sdk:AnAction]: upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java diff --git a/project_model/src/main/java/icons/SdkIcons.java b/project_model/src/main/java/icons/SdkIcons.java index 8f85195c2..204f14ff6 100644 --- a/project_model/src/main/java/icons/SdkIcons.java +++ b/project_model/src/main/java/icons/SdkIcons.java @@ -7,5 +7,7 @@ import com.intellij.openapi.util.IconLoader; import javax.swing.*; public class SdkIcons { + public static final Icon Sdk_default_icon = IconLoader.getIcon("/icons/sdk_16.svg"); + } diff --git a/project_model/src/main/java/org/intellij/sdk/project/model/LibrariesAction.java b/project_model/src/main/java/org/intellij/sdk/project/model/LibrariesAction.java index 33b115ce2..abd488acf 100644 --- a/project_model/src/main/java/org/intellij/sdk/project/model/LibrariesAction.java +++ b/project_model/src/main/java/org/intellij/sdk/project/model/LibrariesAction.java @@ -16,16 +16,23 @@ import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; public class LibrariesAction extends AnAction { + @Override public void update(@NotNull final AnActionEvent event) { Project project = event.getProject(); - if (project == null) return; + if (project == null) { + return; + } Navigatable element = event.getData(CommonDataKeys.NAVIGATABLE); if (element instanceof PsiClass) { PsiFile psiFile = ((PsiClass) element).getContainingFile(); - if (psiFile == null) return; + if (psiFile == null) { + return; + } VirtualFile virtualFile = psiFile.getVirtualFile(); - if (virtualFile == null) return; + if (virtualFile == null) { + return; + } event.getPresentation().setEnabledAndVisible(true); } } @@ -33,22 +40,32 @@ public class LibrariesAction extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent event) { Project project = event.getProject(); - if (project == null) return; + if (project == null) { + return; + } Navigatable element = event.getData(CommonDataKeys.NAVIGATABLE); if (element instanceof PsiClass) { PsiFile psiFile = ((PsiClass) element).getContainingFile(); - if (psiFile == null) return; + if (psiFile == null) { + return; + } VirtualFile virtualFile = psiFile.getVirtualFile(); - if (virtualFile == null) return; + if (virtualFile == null) { + return; + } final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); StringBuilder jars = new StringBuilder(); for (OrderEntry orderEntry : fileIndex.getOrderEntriesForFile(virtualFile)) { if (orderEntry instanceof LibraryOrderEntry) { final LibraryOrderEntry libraryEntry = (LibraryOrderEntry) orderEntry; final Library library = libraryEntry.getLibrary(); - if (library == null) continue; + if (library == null) { + continue; + } VirtualFile[] files = library.getFiles(OrderRootType.CLASSES); - if (files.length == 0) continue; + if (files.length == 0) { + continue; + } for (VirtualFile jar : files) { jars.append(jar.getName()).append(", "); } @@ -64,4 +81,5 @@ public class LibrariesAction extends AnAction { "Libraries Info"); } } + } diff --git a/project_model/src/main/java/org/intellij/sdk/project/model/ModificationAction.java b/project_model/src/main/java/org/intellij/sdk/project/model/ModificationAction.java index d1fff3d81..5238dcb85 100644 --- a/project_model/src/main/java/org/intellij/sdk/project/model/ModificationAction.java +++ b/project_model/src/main/java/org/intellij/sdk/project/model/ModificationAction.java @@ -18,19 +18,28 @@ import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; public class ModificationAction extends AnAction { + @Override public void actionPerformed(@NotNull final AnActionEvent event) { Project project = event.getProject(); - if (project == null) return; + if (project == null) { + return; + } Navigatable element = event.getData(CommonDataKeys.NAVIGATABLE); if (element instanceof PsiClass) { PsiFile file = ((PsiClass) element).getContainingFile(); - if (file == null) return; + if (file == null) { + return; + } final VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile == null) return; + if (virtualFile == null) { + return; + } final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); final Module module = fileIndex.getModuleForFile(virtualFile); - if (module == null) return; + if (module == null) { + return; + } if (!ModuleRootManager.getInstance(module).getFileIndex().isInContent(virtualFile)) { ModuleRootModificationUtil.addModuleLibrary(module, virtualFile.getUrl()); } @@ -44,4 +53,5 @@ public class ModificationAction extends AnAction { Navigatable element = event.getData(CommonDataKeys.NAVIGATABLE); event.getPresentation().setEnabledAndVisible(project != null && element != null); } + } diff --git a/project_model/src/main/java/org/intellij/sdk/project/model/ProjectFileIndexSampleAction.java b/project_model/src/main/java/org/intellij/sdk/project/model/ProjectFileIndexSampleAction.java index feae0c4f9..44fd8b7fc 100644 --- a/project_model/src/main/java/org/intellij/sdk/project/model/ProjectFileIndexSampleAction.java +++ b/project_model/src/main/java/org/intellij/sdk/project/model/ProjectFileIndexSampleAction.java @@ -17,6 +17,7 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; public class ProjectFileIndexSampleAction extends AnAction { + @Override public void update(@NotNull final AnActionEvent event) { Project project = event.getProject(); @@ -29,7 +30,9 @@ public class ProjectFileIndexSampleAction extends AnAction { public void actionPerformed(@NotNull final AnActionEvent event) { Project project = event.getProject(); final Editor editor = event.getData(CommonDataKeys.EDITOR); - if (project == null || editor == null) return; + if (project == null || editor == null) { + return; + } Document document = editor.getDocument(); FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance(); VirtualFile virtualFile = fileDocumentManager.getFile(document); @@ -44,11 +47,12 @@ public class ProjectFileIndexSampleAction extends AnAction { boolean isInLibraryClasses = projectFileIndex.isInLibraryClasses(virtualFile); boolean isInLibrarySource = projectFileIndex.isInLibrarySource(virtualFile); Messages.showInfoMessage("Module: " + moduleName + "\n" + - "Module content root: " + moduleContentRoot + "\n" + - "Is library file: " + isLibraryFile + "\n" + - "Is in library classes: " + isInLibraryClasses + - ", Is in library source: " + isInLibrarySource, - "Main File Info for" + virtualFile.getName()); + "Module content root: " + moduleContentRoot + "\n" + + "Is library file: " + isLibraryFile + "\n" + + "Is in library classes: " + isInLibraryClasses + + ", Is in library source: " + isInLibrarySource, + "Main File Info for" + virtualFile.getName()); } } + } diff --git a/project_model/src/main/java/org/intellij/sdk/project/model/ProjectSdkAction.java b/project_model/src/main/java/org/intellij/sdk/project/model/ProjectSdkAction.java index 037bde3c7..872b2f9bc 100644 --- a/project_model/src/main/java/org/intellij/sdk/project/model/ProjectSdkAction.java +++ b/project_model/src/main/java/org/intellij/sdk/project/model/ProjectSdkAction.java @@ -11,6 +11,7 @@ import com.intellij.openapi.ui.Messages; import org.jetbrains.annotations.NotNull; public class ProjectSdkAction extends AnAction { + @Override public void actionPerformed(@NotNull final AnActionEvent event) { Project project = event.getProject(); @@ -33,4 +34,5 @@ public class ProjectSdkAction extends AnAction { event.getPresentation().setEnabledAndVisible(sdk != null); } } + } diff --git a/project_model/src/main/java/org/intellij/sdk/project/model/ShowSourceRootsActions.java b/project_model/src/main/java/org/intellij/sdk/project/model/ShowSourceRootsActions.java index 38452fc86..30c29639e 100644 --- a/project_model/src/main/java/org/intellij/sdk/project/model/ShowSourceRootsActions.java +++ b/project_model/src/main/java/org/intellij/sdk/project/model/ShowSourceRootsActions.java @@ -11,18 +11,23 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; public class ShowSourceRootsActions extends AnAction { + @Override public void actionPerformed(@NotNull final AnActionEvent event) { Project project = event.getProject(); - if (project == null) return; + if (project == null) { + return; + } String projectName = project.getName(); StringBuilder sourceRootsList = new StringBuilder(); VirtualFile[] vFiles = ProjectRootManager.getInstance(project).getContentSourceRoots(); for (VirtualFile file : vFiles) { sourceRootsList.append(file.getUrl()).append("\n"); } - Messages.showInfoMessage("Source roots for the " + projectName + " plugin:\n" + sourceRootsList.toString(), - "Project Properties"); + Messages.showInfoMessage( + "Source roots for the " + projectName + " plugin:\n" + sourceRootsList.toString(), + "Project Properties" + ); } @Override @@ -31,4 +36,5 @@ public class ShowSourceRootsActions extends AnAction { event.getPresentation().setEnabled(visibility); event.getPresentation().setVisible(visibility); } + } diff --git a/project_model/src/main/resources/META-INF/plugin.xml b/project_model/src/main/resources/META-INF/plugin.xml index e2f8df494..039c3d87e 100644 --- a/project_model/src/main/resources/META-INF/plugin.xml +++ b/project_model/src/main/resources/META-INF/plugin.xml @@ -2,19 +2,20 @@ - + org.intellij.sdk.project.model - - SDK: Project Model Sample Project + + SDK: Project Model Sample com.intellij.modules.java - + Adds menu items to Tools and Editor Context menus. + Demonstrates various aspects of interacting with project model.
    Adds menu items to + Tools and Editor Context menus. ]]>
    diff --git a/project_view_pane/README.md b/project_view_pane/README.md new file mode 100644 index 000000000..f68c7f567 --- /dev/null +++ b/project_view_pane/README.md @@ -0,0 +1,24 @@ +# Project View Pane Demo [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Plugin Services in IntelliJ SDK Docs][docs:project_view]* + +## Quickstart + +The current demo describes an implementation of the `projectViewPane` extension point, which allows creating an additional presentation type for the Project view pane. +`ImagesProjectViewPane` limits the project tree to the images only. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ | +| `com.intellij.projectViewPane` | [ImagesProjectViewPane][file:ImagesProjectViewPane] | [AbstractProjectViewPSIPane][sdk:AbstractProjectViewPSIPane] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:project_view]: https://jetbrains.org/intellij/sdk/docs/basics/project_view.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:ImagesProjectViewPane]: ./src/main/java/org/intellij/sdk/view/pane/ImagesProjectViewPane.java + +[sdk:AbstractProjectViewPSIPane]: upsource:///platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPSIPane.java diff --git a/project_view_pane/src/main/java/org/intellij/sdk/view/pane/ImagesProjectNode.java b/project_view_pane/src/main/java/org/intellij/sdk/view/pane/ImagesProjectNode.java index f8aa18036..d599fa1b0 100644 --- a/project_view_pane/src/main/java/org/intellij/sdk/view/pane/ImagesProjectNode.java +++ b/project_view_pane/src/main/java/org/intellij/sdk/view/pane/ImagesProjectNode.java @@ -25,6 +25,7 @@ import javax.swing.*; import java.util.*; public class ImagesProjectNode extends AbstractTreeNode { + private static final Key> IMAGES_PROJECT_DIRS = Key.create("images.files.or.directories"); public ImagesProjectNode(final Project project) { @@ -88,15 +89,21 @@ public class ImagesProjectNode extends AbstractTreeNode { files.add(file); } } - if (files.isEmpty()) return Collections.emptyList(); + if (files.isEmpty()) { + return Collections.emptyList(); + } final List> nodes = new ArrayList<>(files.size()); final boolean alwaysOnTop = ProjectView.getInstance(myProject).isFoldersAlwaysOnTop(""); files.sort((o1, o2) -> { if (alwaysOnTop) { final boolean d1 = o1.isDirectory(); final boolean d2 = o2.isDirectory(); - if (d1 && !d2) return -1; - if (!d1 && d2) return 1; + if (d1 && !d2) { + return -1; + } + if (!d1 && d2) { + return 1; + } } return StringUtil.naturalCompare(o1.getName(), o2.getName()); @@ -162,5 +169,5 @@ public class ImagesProjectNode extends AbstractTreeNode { } }); } -} +} diff --git a/project_view_pane/src/main/java/org/intellij/sdk/view/pane/ImagesProjectViewPane.java b/project_view_pane/src/main/java/org/intellij/sdk/view/pane/ImagesProjectViewPane.java index 2e7fb9f09..352130190 100644 --- a/project_view_pane/src/main/java/org/intellij/sdk/view/pane/ImagesProjectViewPane.java +++ b/project_view_pane/src/main/java/org/intellij/sdk/view/pane/ImagesProjectViewPane.java @@ -19,6 +19,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.tree.DefaultTreeModel; public class ImagesProjectViewPane extends AbstractProjectViewPSIPane { + public static final String ID = "IMAGES"; protected ImagesProjectViewPane(Project project) { @@ -110,5 +111,5 @@ public class ImagesProjectViewPane extends AbstractProjectViewPSIPane { protected AbstractTreeUpdater createTreeUpdater(@NotNull AbstractTreeBuilder builder) { throw new IllegalStateException("ImagesProjectViewPane tree is async now"); } -} +} diff --git a/project_view_pane/src/main/resources/META-INF/plugin.xml b/project_view_pane/src/main/resources/META-INF/plugin.xml index c095b9604..9c91ead3a 100644 --- a/project_view_pane/src/main/resources/META-INF/plugin.xml +++ b/project_view_pane/src/main/resources/META-INF/plugin.xml @@ -2,16 +2,16 @@ - + org.intellij.sdk.view.pane - + SDK: Project View Pane Demo com.intellij.modules.platform - + getModuleType() { return ModuleType.EMPTY; //or it could be other module type } @@ -36,4 +36,5 @@ public class DemoModuleWizardStep extends ModuleBuilder { } }}; } + } diff --git a/project_wizard/src/main/resources/META-INF/plugin.xml b/project_wizard/src/main/resources/META-INF/plugin.xml index 87cb47085..ee52f5a07 100644 --- a/project_wizard/src/main/resources/META-INF/plugin.xml +++ b/project_wizard/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ - + org.intellij.sdk.project.wizard @@ -11,7 +11,7 @@ com.intellij.modules.platform - + - + org.intellij.sdk.psi - + SDK: PSI Demo com.intellij.modules.java - + - + org.intellij.sdk.runConfiguration - + SDK: Run Configuration Demo com.intellij.modules.platform - + - See the Run Configurations for more information. + See the + Run Configurations + for more information. ]]> diff --git a/settings/README.md b/settings/README.md new file mode 100644 index 000000000..77a6ccd27 --- /dev/null +++ b/settings/README.md @@ -0,0 +1,29 @@ +# Settings Example [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Settings Tutorial in IntelliJ SDK Docs][docs:settings_tutorial]* + +## Quickstart + +This project illustrates a custom Application-level Settings through the implementation of: +- `AppSettingsConfigurable` is analogous to a Controller in the MVC model - it interacts with the other two Settings classes and the IntelliJ Platform, +- `AppSettingsState` is like a Model because it stores the Settings persistently, +- `AppSettingsComponent` is similar to a View because it displays and captures edits to the values of the Settings. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| -------------------------------------- | ------------------------------------------------------- | -------------------------------------------------------- | +| `com.intellij.applicationConfigurable` | [AppSettingsConfigurable][file:AppSettingsConfigurable] | [Configurable][sdk:Configurable] | +| `com.intellij.applicationService` | [AppSettingsState][file:AppSettingsState] | [PersistentStateComponent][sdk:PersistentStateComponent] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:settings_tutorial]: https://jetbrains.org/intellij/sdk/docs/tutorials/settings_tutorial.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:AppSettingsConfigurable]: ./src/main/java/org/intellij/sdk/settings/AppSettingsConfigurable.java +[file:AppSettingsState]: ./src/main/java/org/intellij/sdk/settings/AppSettingsState.java + +[sdk:Configurable]: upsource:///platform/platform-api/src/com/intellij/openapi/options/Configurable.java +[sdk:PersistentStateComponent]: upsource:///platform/projectModel-api/src/com/intellij/openapi/components/PersistentStateComponent.java diff --git a/settings/build.gradle b/settings/build.gradle index 6b93ca496..807c44b08 100644 --- a/settings/build.gradle +++ b/settings/build.gradle @@ -1,10 +1,14 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + plugins { id 'java' id 'org.jetbrains.intellij' version '0.4.21' } group 'org.intellij.sdk' -version '0.1' +version '1.0.0' + +sourceCompatibility = 1.8 repositories { mavenCentral() diff --git a/settings/src/main/java/org/intellij/sdk/settings/AppSettingsComponent.java b/settings/src/main/java/org/intellij/sdk/settings/AppSettingsComponent.java index 205f340ed..6f2b9c663 100644 --- a/settings/src/main/java/org/intellij/sdk/settings/AppSettingsComponent.java +++ b/settings/src/main/java/org/intellij/sdk/settings/AppSettingsComponent.java @@ -14,16 +14,17 @@ import javax.swing.*; * Supports creating and managing a JPanel for the Settings Dialog. */ public class AppSettingsComponent { + private final JPanel myMainPanel; private final JBTextField myUserNameText = new JBTextField(); - private final JBCheckBox myIdeaUserStatus = new JBCheckBox("Do You Use IntelliJ IDEA? "); + private final JBCheckBox myIdeaUserStatus = new JBCheckBox("Do you use IntelliJ IDEA? "); public AppSettingsComponent() { myMainPanel = FormBuilder.createFormBuilder() - .addLabeledComponent(new JBLabel("Enter User Name: "), myUserNameText, 1, false) - .addComponent(myIdeaUserStatus, 1) - .addComponentFillVertically(new JPanel(), 0) - .getPanel(); + .addLabeledComponent(new JBLabel("Enter user name: "), myUserNameText, 1, false) + .addComponent(myIdeaUserStatus, 1) + .addComponentFillVertically(new JPanel(), 0) + .getPanel(); } public JPanel getPanel() { diff --git a/settings/src/main/java/org/intellij/sdk/settings/AppSettingsConfigurable.java b/settings/src/main/java/org/intellij/sdk/settings/AppSettingsConfigurable.java index bf132d877..6475a1723 100644 --- a/settings/src/main/java/org/intellij/sdk/settings/AppSettingsConfigurable.java +++ b/settings/src/main/java/org/intellij/sdk/settings/AppSettingsConfigurable.java @@ -3,7 +3,6 @@ package org.intellij.sdk.settings; import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.options.ConfigurationException; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.Nullable; @@ -11,8 +10,9 @@ import javax.swing.*; /** * Provides controller functionality for application settings. -*/ + */ public class AppSettingsConfigurable implements Configurable { + private AppSettingsComponent mySettingsComponent; // A default constructor with no arguments is required because this implementation @@ -45,7 +45,7 @@ public class AppSettingsConfigurable implements Configurable { } @Override - public void apply() throws ConfigurationException { + public void apply() { AppSettingsState settings = AppSettingsState.getInstance(); settings.userId = mySettingsComponent.getUserNameText(); settings.ideaStatus = mySettingsComponent.getIdeaUserStatus(); diff --git a/settings/src/main/java/org/intellij/sdk/settings/AppSettingsState.java b/settings/src/main/java/org/intellij/sdk/settings/AppSettingsState.java index ae93e6e98..2578a8669 100644 --- a/settings/src/main/java/org/intellij/sdk/settings/AppSettingsState.java +++ b/settings/src/main/java/org/intellij/sdk/settings/AppSettingsState.java @@ -39,4 +39,4 @@ public class AppSettingsState implements PersistentStateComponent - + org.intellij.sdk.settings - SDK: Settings Example Project + SDK: Settings Example com.intellij.modules.platform - + Adds a settings panel to the Settings/Preferences panel under Tools. + Demonstrates implementing a custom settings panel.
    Adds a settings panel to the Settings/Preferences + panel under Tools. ]]>
    @@ -36,4 +37,4 @@ -
    \ No newline at end of file +
    diff --git a/simple_language_plugin/README.md b/simple_language_plugin/README.md new file mode 100644 index 000000000..3b33ba4bc --- /dev/null +++ b/simple_language_plugin/README.md @@ -0,0 +1,71 @@ +# Simple Language Sample [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Custom Language Support Tutorial in IntelliJ SDK Docs][docs:custom_language_support_tutorial]* + +## Quickstart + +Defines a new language, _Simple language_ with support for syntax highlighting, annotations, code completion, and other features. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| --------------------------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `com.intellij.fileType` | [SimpleFileType][file:SimpleFileType] | [LanguageFileType][sdk:LanguageFileType] | +| `com.intellij.lang.parserDefinition` | [SimpleParserDefinition][file:SimpleParserDefinition] | [ParserDefinition][sdk:ParserDefinition] | +| `com.intellij.lang.syntaxHighlighterFactory` | [SimpleSyntaxHighlighterFactory][file:SimpleSyntaxHighlighterFactory] | [SyntaxHighlighterFactory][sdk:SyntaxHighlighterFactory] | +| `com.intellij.colorSettingsPage` | [SimpleColorSettingsPage][file:SimpleColorSettingsPage] | [ColorSettingsPage][sdk:ColorSettingsPage] | +| `com.intellij.annotator` | [SimpleAnnotator][file:SimpleAnnotator] | [Annotator][sdk:Annotator] | +| `com.intellij.codeInsight.lineMarkerProvider` | [SimpleLineMarkerProvider][file:SimpleLineMarkerProvider] | [RelatedItemLineMarkerProvider][sdk:RelatedItemLineMarkerProvider] | +| `com.intellij.completion.contributor` | [SimpleCompletionContributor][file:SimpleCompletionContributor] | [CompletionContributor][sdk:CompletionContributor] | +| `com.intellij.psi.referenceContributor` | [SimpleReferenceContributor][file:SimpleReferenceContributor] | [PsiReferenceContributor][sdk:PsiReferenceContributor] | +| `com.intellij.lang.refactoringSupport` | [SimpleRefactoringSupportProvider][file:SimpleRefactoringSupportProvider] | [RefactoringSupportProvider][sdk:RefactoringSupportProvider] | +| `com.intellij.lang.findUsagesProvider` | [SimpleFindUsagesProvider][file:SimpleFindUsagesProvider] | [FindUsagesProvider][sdk:FindUsagesProvider] | +| `com.intellij.lang.foldingBuilder` | [SimpleFoldingBuilder][file:SimpleFoldingBuilder] | [FoldingBuilderEx][sdk:FoldingBuilderEx] | +| `com.intellij.gotoSymbolContributor` | [SimpleChooseByNameContributor][file:SimpleChooseByNameContributor] | [ChooseByNameContributor][sdk:ChooseByNameContributor] | +| `com.intellij.lang.psiStructureViewFactory` | [SimpleStructureViewFactory][file:SimpleStructureViewFactory] | [PsiStructureViewFactory][sdk:PsiStructureViewFactory] | +| `com.intellij.lang.formatter` | [SimpleFormattingModelBuilder][file:SimpleFormattingModelBuilder] | [FormattingModelBuilder][sdk:FormattingModelBuilder] | +| `com.intellij.codeStyleSettingsProvider` | [SimpleCodeStyleSettingsProvider][file:SimpleCodeStyleSettingsProvider] | [CodeStyleSettingsProvider][sdk:CodeStyleSettingsProvider] | +| `com.intellij.langCodeStyleSettingsProvider` | [SimpleLanguageCodeStyleSettingsProvider][file:SimpleLanguageCodeStyleSettingsProvider] | [LanguageCodeStyleSettingsProvider][sdk:LanguageCodeStyleSettingsProvider] | +| `com.intellij.lang.commenter` | [SimpleCommenter][file:SimpleCommenter] | [Commenter][sdk:Commenter] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:custom_language_support_tutorial]: https://jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support_tutorial.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:SimpleFileType]: ./src/main/java/org/intellij/sdk/language/SimpleFileType.java +[file:SimpleParserDefinition]: ./src/main/java/org/intellij/sdk/language/SimpleParserDefinition.java +[file:SimpleSyntaxHighlighterFactory]: ./src/main/java/org/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java +[file:SimpleColorSettingsPage]: ./src/main/java/org/intellij/sdk/language/SimpleColorSettingsPage.java +[file:SimpleAnnotator]: ./src/main/java/org/intellij/sdk/language/SimpleAnnotator.java +[file:SimpleLineMarkerProvider]: ./src/main/java/org/intellij/sdk/language/SimpleLineMarkerProvider.java +[file:SimpleCompletionContributor]: ./src/main/java/org/intellij/sdk/language/SimpleCompletionContributor.java +[file:SimpleReferenceContributor]: ./src/main/java/org/intellij/sdk/language/SimpleReferenceContributor.java +[file:SimpleRefactoringSupportProvider]: ./src/main/java/org/intellij/sdk/language/SimpleRefactoringSupportProvider.java +[file:SimpleFindUsagesProvider]: ./src/main/java/org/intellij/sdk/language/SimpleFindUsagesProvider.java +[file:SimpleFoldingBuilder]: ./src/main/java/org/intellij/sdk/language/SimpleFoldingBuilder.java +[file:SimpleChooseByNameContributor]: ./src/main/java/org/intellij/sdk/language/SimpleChooseByNameContributor.java +[file:SimpleStructureViewFactory]: ./src/main/java/org/intellij/sdk/language/SimpleStructureViewFactory.java +[file:SimpleFormattingModelBuilder]: ./src/main/java/org/intellij/sdk/language/SimpleFormattingModelBuilder.java +[file:SimpleCodeStyleSettingsProvider]: ./src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java +[file:SimpleLanguageCodeStyleSettingsProvider]: ./src/main/java/org/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java +[file:SimpleCommenter]: ./src/main/java/org/intellij/sdk/language/SimpleCommenter.java + +[sdk:LanguageFileType]: upsource:///platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java +[sdk:ParserDefinition]: upsource:///platform/core-api/src/com/intellij/lang/ParserDefinition.java +[sdk:SyntaxHighlighterFactory]: upsource:///platform/editor-ui-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java +[sdk:ColorSettingsPage]: upsource:///platform/platform-api/src/com/intellij/openapi/options/colors/ColorSettingsPage.java +[sdk:Annotator]: upsource:///platform/analysis-api/src/com/intellij/lang/annotation/Annotator.java +[sdk:RelatedItemLineMarkerProvider]: upsource:///platform/lang-api/src/com/intellij/codeInsight/daemon/RelatedItemLineMarkerProvider.java +[sdk:CompletionContributor]: upsource:///platform/analysis-api/src/com/intellij/codeInsight/completion/CompletionContributor.java +[sdk:PsiReferenceContributor]: upsource:///platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java +[sdk:RefactoringSupportProvider]: upsource:///platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java +[sdk:FindUsagesProvider]: upsource:///platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java +[sdk:FoldingBuilderEx]: upsource:///platform/core-api/src/com/intellij/lang/folding/FoldingBuilderEx.java +[sdk:ChooseByNameContributor]: upsource:///platform/lang-api/src/com/intellij/navigation/ChooseByNameContributor.java +[sdk:PsiStructureViewFactory]: upsource:///platform/editor-ui-api/src/com/intellij/lang/PsiStructureViewFactory.java +[sdk:FormattingModelBuilder]: upsource:///platform/lang-api/src/com/intellij/formatting/FormattingModelBuilder.java +[sdk:CodeStyleSettingsProvider]: upsource:///platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsProvider.java +[sdk:LanguageCodeStyleSettingsProvider]: upsource:///platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java +[sdk:Commenter]: upsource:///platform/core-api/src/com/intellij/lang/Commenter.java diff --git a/simple_language_plugin/src/main/gen/org/intellij/sdk/language/SimpleLexer.java b/simple_language_plugin/src/main/gen/org/intellij/sdk/language/SimpleLexer.java index 84e6d210f..711de9e1e 100644 --- a/simple_language_plugin/src/main/gen/org/intellij/sdk/language/SimpleLexer.java +++ b/simple_language_plugin/src/main/gen/org/intellij/sdk/language/SimpleLexer.java @@ -11,7 +11,7 @@ import com.intellij.psi.TokenType; /** * This class is a scanner generated by - * JFlex 1.7.0 + * JFlex 1.7.0 * from the specification file Simple.flex */ class SimpleLexer implements FlexLexer { diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleAnnotator.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleAnnotator.java index 39bb6cc04..d15987fea 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleAnnotator.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleAnnotator.java @@ -20,6 +20,7 @@ import static com.intellij.lang.annotation.HighlightSeverity.INFORMATION; public class SimpleAnnotator implements Annotator { + // Define strings for the Simple language prefix - used for annotations, line markers, etc. public static final String SIMPLE_PREFIX_STR = "simple"; public static final String SIMPLE_SEPARATOR_STR = ":"; @@ -27,12 +28,16 @@ public class SimpleAnnotator implements Annotator { @Override public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) { // Ensure the Psi Element is an expression - if (!(element instanceof PsiLiteralExpression)) return; + if (!(element instanceof PsiLiteralExpression)) { + return; + } // Ensure the Psi element contains a string that starts with the key and separator PsiLiteralExpression literalExpression = (PsiLiteralExpression) element; String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; - if ((value == null) || !value.startsWith(SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR)) return; + if ((value == null) || !value.startsWith(SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR)) { + return; + } // Define the text ranges (start is inclusive, end is exclusive) // "simple:key" @@ -47,8 +52,10 @@ public class SimpleAnnotator implements Annotator { List properties = SimpleUtil.findProperties(project, possibleProperties); // Set the annotations using the text ranges - Normally there would be one range, set by the element itself. - holder.newAnnotation(INFORMATION, "").range(prefixRange).textAttributes(DefaultLanguageHighlighterColors.KEYWORD).create(); - holder.newAnnotation(INFORMATION, "").range(separatorRange).textAttributes(SimpleSyntaxHighlighter.SEPARATOR).create(); + holder.newAnnotation(INFORMATION, "") + .range(prefixRange).textAttributes(DefaultLanguageHighlighterColors.KEYWORD).create(); + holder.newAnnotation(INFORMATION, "") + .range(separatorRange).textAttributes(SimpleSyntaxHighlighter.SEPARATOR).create(); if (properties.isEmpty()) { // No well-formed property found following the key-separator AnnotationBuilder builder = holder.newAnnotation(ERROR, "Unresolved property").range(keyRange); diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleBlock.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleBlock.java index 6d30b51d8..9d3436e0c 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleBlock.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleBlock.java @@ -13,14 +13,15 @@ import java.util.ArrayList; import java.util.List; public class SimpleBlock extends AbstractBlock { + private final SpacingBuilder spacingBuilder; - + protected SimpleBlock(@NotNull ASTNode node, @Nullable Wrap wrap, @Nullable Alignment alignment, SpacingBuilder spacingBuilder) { super(node, wrap, alignment); this.spacingBuilder = spacingBuilder; } - + @Override protected List buildChildren() { List blocks = new ArrayList<>(); @@ -28,27 +29,28 @@ public class SimpleBlock extends AbstractBlock { while (child != null) { if (child.getElementType() != TokenType.WHITE_SPACE) { Block block = new SimpleBlock(child, Wrap.createWrap(WrapType.NONE, false), Alignment.createAlignment(), - spacingBuilder); + spacingBuilder); blocks.add(block); } child = child.getTreeNext(); } return blocks; } - + @Override public Indent getIndent() { return Indent.getNoneIndent(); } - + @Nullable @Override public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) { return spacingBuilder.getSpacing(this, child1, child2); } - + @Override public boolean isLeaf() { return myNode.getFirstChildNode() == null; } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleChooseByNameContributor.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleChooseByNameContributor.java index eb3d1fa91..7e69044b0 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleChooseByNameContributor.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleChooseByNameContributor.java @@ -2,14 +2,17 @@ package org.intellij.sdk.language; -import com.intellij.navigation.*; +import com.intellij.navigation.ChooseByNameContributor; +import com.intellij.navigation.NavigationItem; import com.intellij.openapi.project.Project; import org.intellij.sdk.language.psi.SimpleProperty; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.List; public class SimpleChooseByNameContributor implements ChooseByNameContributor { + @NotNull @Override public String[] getNames(Project project, boolean includeNonProjectItems) { @@ -22,7 +25,7 @@ public class SimpleChooseByNameContributor implements ChooseByNameContributor { } return names.toArray(new String[names.size()]); } - + @NotNull @Override public NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) { @@ -30,4 +33,5 @@ public class SimpleChooseByNameContributor implements ChooseByNameContributor { List properties = SimpleUtil.findProperties(project, name); return properties.toArray(new NavigationItem[properties.size()]); } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettings.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettings.java index dd1e1580e..71f8bdcc1 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettings.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettings.java @@ -2,10 +2,13 @@ package org.intellij.sdk.language; -import com.intellij.psi.codeStyle.*; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; public class SimpleCodeStyleSettings extends CustomCodeStyleSettings { + public SimpleCodeStyleSettings(CodeStyleSettings settings) { super("SimpleCodeStyleSettings", settings); } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java index 04c17e1b7..f58602cd4 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java @@ -2,23 +2,30 @@ package org.intellij.sdk.language; -import com.intellij.application.options.*; -import com.intellij.psi.codeStyle.*; -import org.jetbrains.annotations.*; +import com.intellij.application.options.CodeStyleAbstractConfigurable; +import com.intellij.application.options.CodeStyleAbstractPanel; +import com.intellij.application.options.TabbedLanguageCodeStylePanel; +import com.intellij.psi.codeStyle.CodeStyleConfigurable; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsProvider; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class SimpleCodeStyleSettingsProvider extends CodeStyleSettingsProvider { + @Override public CustomCodeStyleSettings createCustomSettings(CodeStyleSettings settings) { return new SimpleCodeStyleSettings(settings); } - + @Nullable @Override public String getConfigurableDisplayName() { return "Simple"; } - - + + @NotNull public CodeStyleConfigurable createConfigurable(@NotNull CodeStyleSettings settings, @NotNull CodeStyleSettings modelSettings) { return new CodeStyleAbstractConfigurable(settings, modelSettings, this.getConfigurableDisplayName()) { @@ -28,10 +35,13 @@ public class SimpleCodeStyleSettingsProvider extends CodeStyleSettingsProvider { } }; } - + private static class SimpleCodeStyleMainPanel extends TabbedLanguageCodeStylePanel { + public SimpleCodeStyleMainPanel(CodeStyleSettings currentSettings, CodeStyleSettings settings) { super(SimpleLanguage.INSTANCE, currentSettings, settings); } + } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleColorSettingsPage.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleColorSettingsPage.java index cb9ff628e..be451f355 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleColorSettingsPage.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleColorSettingsPage.java @@ -4,70 +4,75 @@ package org.intellij.sdk.language; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.fileTypes.SyntaxHighlighter; -import com.intellij.openapi.options.colors.*; -import org.jetbrains.annotations.*; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Map; public class SimpleColorSettingsPage implements ColorSettingsPage { + private static final AttributesDescriptor[] DESCRIPTORS = new AttributesDescriptor[]{ - new AttributesDescriptor("Key", SimpleSyntaxHighlighter.KEY), - new AttributesDescriptor("Separator", SimpleSyntaxHighlighter.SEPARATOR), - new AttributesDescriptor("Value", SimpleSyntaxHighlighter.VALUE), - new AttributesDescriptor("Bad Value", SimpleSyntaxHighlighter.BAD_CHARACTER) - }; - + new AttributesDescriptor("Key", SimpleSyntaxHighlighter.KEY), + new AttributesDescriptor("Separator", SimpleSyntaxHighlighter.SEPARATOR), + new AttributesDescriptor("Value", SimpleSyntaxHighlighter.VALUE), + new AttributesDescriptor("Bad Value", SimpleSyntaxHighlighter.BAD_CHARACTER) + }; + @Nullable @Override public Icon getIcon() { return SimpleIcons.FILE; } - + @NotNull @Override public SyntaxHighlighter getHighlighter() { return new SimpleSyntaxHighlighter(); } - + @NotNull @Override public String getDemoText() { return "# You are reading the \".properties\" entry.\n" + - "! The exclamation mark can also mark text as comments.\n" + - "website = https://en.wikipedia.org/\n" + - "language = English\n" + - "# The backslash below tells the application to continue reading\n" + - "# the value onto the next line.\n" + - "message = Welcome to \\\n" + - " Wikipedia!\n" + - "# Add spaces to the key\n" + - "key\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n" + - "# Unicode\n" + - "tab : \\u0009"; + "! The exclamation mark can also mark text as comments.\n" + + "website = https://en.wikipedia.org/\n" + + "language = English\n" + + "# The backslash below tells the application to continue reading\n" + + "# the value onto the next line.\n" + + "message = Welcome to \\\n" + + " Wikipedia!\n" + + "# Add spaces to the key\n" + + "key\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n" + + "# Unicode\n" + + "tab : \\u0009"; } - + @Nullable @Override public Map getAdditionalHighlightingTagToDescriptorMap() { return null; } - + @NotNull @Override public AttributesDescriptor[] getAttributeDescriptors() { return DESCRIPTORS; } - + @NotNull @Override public ColorDescriptor[] getColorDescriptors() { return ColorDescriptor.EMPTY_ARRAY; } - + @NotNull @Override public String getDisplayName() { return "Simple"; } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCommenter.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCommenter.java index 97504756f..fac7f144a 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCommenter.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCommenter.java @@ -6,33 +6,35 @@ import com.intellij.lang.Commenter; import org.jetbrains.annotations.Nullable; public class SimpleCommenter implements Commenter { + @Nullable @Override public String getLineCommentPrefix() { return "#"; } - + @Nullable @Override public String getBlockCommentPrefix() { return ""; } - + @Nullable @Override public String getBlockCommentSuffix() { return null; } - + @Nullable @Override public String getCommentedBlockCommentPrefix() { return null; } - + @Nullable @Override public String getCommentedBlockCommentSuffix() { return null; } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCompletionContributor.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCompletionContributor.java index 86d4c32ec..8db5832bd 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCompletionContributor.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCompletionContributor.java @@ -22,4 +22,5 @@ public class SimpleCompletionContributor extends CompletionContributor { } ); } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCreatePropertyQuickFix.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCreatePropertyQuickFix.java index 3f4a5ba0a..f53e0f03d 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCreatePropertyQuickFix.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCreatePropertyQuickFix.java @@ -28,40 +28,41 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; class SimpleCreatePropertyQuickFix extends BaseIntentionAction { + private final String key; - + SimpleCreatePropertyQuickFix(String key) { this.key = key; } - + @NotNull @Override public String getText() { return "Create property"; } - + @NotNull @Override public String getFamilyName() { return "Simple properties"; } - + @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { return true; } - + @Override public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws - IncorrectOperationException { + IncorrectOperationException { ApplicationManager.getApplication().invokeLater(() -> { Collection virtualFiles = - FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project) ); + FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project)); if (virtualFiles.size() == 1) { createProperty(project, virtualFiles.iterator().next()); } else { final FileChooserDescriptor descriptor = - FileChooserDescriptorFactory.createSingleFileDescriptor(SimpleFileType.INSTANCE); + FileChooserDescriptorFactory.createSingleFileDescriptor(SimpleFileType.INSTANCE); descriptor.setRoots(ProjectUtil.guessProjectDir(project)); final VirtualFile file1 = FileChooser.chooseFile(descriptor, project, null); if (file1 != null) { @@ -70,7 +71,7 @@ class SimpleCreatePropertyQuickFix extends BaseIntentionAction { } }); } - + private void createProperty(final Project project, final VirtualFile file) { WriteCommandAction.writeCommandAction(project).run(() -> { SimpleFile simpleFile = (SimpleFile) PsiManager.getInstance(project).findFile(file); @@ -86,4 +87,5 @@ class SimpleCreatePropertyQuickFix extends BaseIntentionAction { FileEditorManager.getInstance(project).getSelectedTextEditor().getCaretModel().moveCaretRelatively(2, 0, false, false, false); }); } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileType.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileType.java index baca42491..3c4c6464a 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileType.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileType.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; public class SimpleFileType extends LanguageFileType { + public static final SimpleFileType INSTANCE = new SimpleFileType(); private SimpleFileType() { @@ -38,4 +39,5 @@ public class SimpleFileType extends LanguageFileType { public Icon getIcon() { return SimpleIcons.FILE; } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileTypeFactory.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileTypeFactory.java index f1f74cfd6..dfa15cdf6 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileTypeFactory.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileTypeFactory.java @@ -11,8 +11,10 @@ import org.jetbrains.annotations.NotNull; * for versions of the IntelliJ Platform prior to v2019.2 */ public class SimpleFileTypeFactory extends FileTypeFactory { + @Override public void createFileTypes(@NotNull FileTypeConsumer fileTypeConsumer) { fileTypeConsumer.consume(SimpleFileType.INSTANCE); } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFindUsagesProvider.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFindUsagesProvider.java index 0e328fbb0..5cd19c263 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFindUsagesProvider.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFindUsagesProvider.java @@ -2,35 +2,39 @@ package org.intellij.sdk.language; -import com.intellij.lang.cacheBuilder.*; +import com.intellij.lang.cacheBuilder.DefaultWordsScanner; +import com.intellij.lang.cacheBuilder.WordsScanner; import com.intellij.lang.findUsages.FindUsagesProvider; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; import com.intellij.psi.tree.TokenSet; import org.intellij.sdk.language.psi.SimpleProperty; import org.intellij.sdk.language.psi.SimpleTypes; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class SimpleFindUsagesProvider implements FindUsagesProvider { + @Nullable @Override public WordsScanner getWordsScanner() { return new DefaultWordsScanner(new SimpleLexerAdapter(), - TokenSet.create(SimpleTypes.KEY), - TokenSet.create(SimpleTypes.COMMENT), - TokenSet.EMPTY); + TokenSet.create(SimpleTypes.KEY), + TokenSet.create(SimpleTypes.COMMENT), + TokenSet.EMPTY); } - + @Override public boolean canFindUsagesFor(@NotNull PsiElement psiElement) { return psiElement instanceof PsiNamedElement; } - + @Nullable @Override public String getHelpId(@NotNull PsiElement psiElement) { return null; } - + @NotNull @Override public String getType(@NotNull PsiElement element) { @@ -40,7 +44,7 @@ public class SimpleFindUsagesProvider implements FindUsagesProvider { return ""; } } - + @NotNull @Override public String getDescriptiveName(@NotNull PsiElement element) { @@ -50,7 +54,7 @@ public class SimpleFindUsagesProvider implements FindUsagesProvider { return ""; } } - + @NotNull @Override public String getNodeText(@NotNull PsiElement element, boolean useFullName) { @@ -60,4 +64,5 @@ public class SimpleFindUsagesProvider implements FindUsagesProvider { return ""; } } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFoldingBuilder.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFoldingBuilder.java index bcd0f8bca..40ef96221 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFoldingBuilder.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFoldingBuilder.java @@ -3,62 +3,75 @@ package org.intellij.sdk.language; import com.intellij.lang.ASTNode; -import com.intellij.lang.folding.*; -import com.intellij.openapi.editor.*; -import com.intellij.openapi.project.*; +import com.intellij.lang.folding.FoldingBuilderEx; +import com.intellij.lang.folding.FoldingDescriptor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.FoldingGroup; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLiteralExpression; import com.intellij.psi.util.PsiTreeUtil; import org.intellij.sdk.language.psi.SimpleProperty; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware { + @NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { // Initialize the group of folding regions that will expand/collapse together. FoldingGroup group = FoldingGroup.newGroup(SimpleAnnotator.SIMPLE_PREFIX_STR); // Initialize the list of folding regions - List< FoldingDescriptor > descriptors = new ArrayList<>(); + List descriptors = new ArrayList<>(); // Get a collection of the literal expressions in the document below root - Collection< PsiLiteralExpression > literalExpressions = - PsiTreeUtil.findChildrenOfType(root, PsiLiteralExpression.class); + Collection literalExpressions = + PsiTreeUtil.findChildrenOfType(root, PsiLiteralExpression.class); // Evaluate the collection - for ( final PsiLiteralExpression literalExpression : literalExpressions ) { + for (final PsiLiteralExpression literalExpression : literalExpressions) { String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; - if ( value != null && value.startsWith(SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR) ) { + if (value != null && value.startsWith(SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR)) { Project project = literalExpression.getProject(); - String key = value.substring(SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length()); + String key = value.substring( + SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length() + ); // Get a list of all properties for a given key in the project final List properties = SimpleUtil.findProperties(project, key); - if ( properties.size() == 1 ) { + if (properties.size() == 1) { // Add a folding descriptor for the literal expression at this node. descriptors.add(new FoldingDescriptor(literalExpression.getNode(), - new TextRange(literalExpression.getTextRange().getStartOffset() + 1, - literalExpression.getTextRange().getEndOffset() - 1), - group) ); + new TextRange(literalExpression.getTextRange().getStartOffset() + 1, + literalExpression.getTextRange().getEndOffset() - 1), + group)); } } } return descriptors.toArray(new FoldingDescriptor[descriptors.size()]); } - + /** * Gets the Simple Language 'value' string corresponding to the 'key' - * @param node Node corresponding to PsiLiteralExpression containing a string in the format - * SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR + Key, where Key is - * defined by the Simple language file. + * + * @param node Node corresponding to PsiLiteralExpression containing a string in the format + * SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR + Key, where Key is + * defined by the Simple language file. */ @Nullable @Override public String getPlaceholderText(@NotNull ASTNode node) { String retTxt = "..."; - if ( node.getPsi() instanceof PsiLiteralExpression ) { + if (node.getPsi() instanceof PsiLiteralExpression) { PsiLiteralExpression nodeElement = (PsiLiteralExpression) node.getPsi(); - String key = ((String) nodeElement.getValue()).substring(SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length()); - final List< SimpleProperty > properties = SimpleUtil.findProperties(nodeElement.getProject(), key); + String key = ((String) nodeElement.getValue()).substring( + SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length() + ); + final List properties = SimpleUtil.findProperties(nodeElement.getProject(), key); String place = properties.get(0).getValue(); // IMPORTANT: keys can come with no values, so a test for null is needed // IMPORTANT: Convert embedded \n to backslash n, so that the string will look @@ -67,9 +80,10 @@ public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware } return retTxt; } - + @Override public boolean isCollapsedByDefault(@NotNull ASTNode node) { return true; } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFormattingModelBuilder.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFormattingModelBuilder.java index 563e3fb41..b65e22cd8 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFormattingModelBuilder.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFormattingModelBuilder.java @@ -5,35 +5,39 @@ package org.intellij.sdk.language; import com.intellij.formatting.*; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleSettings; import org.intellij.sdk.language.psi.SimpleTypes; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class SimpleFormattingModelBuilder implements FormattingModelBuilder { + + private static SpacingBuilder createSpaceBuilder(CodeStyleSettings settings) { + return new SpacingBuilder(settings, SimpleLanguage.INSTANCE) + .around(SimpleTypes.SEPARATOR) + .spaceIf(settings.getCommonSettings(SimpleLanguage.INSTANCE.getID()).SPACE_AROUND_ASSIGNMENT_OPERATORS) + .before(SimpleTypes.PROPERTY) + .none(); + } + @NotNull @Override public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) { return FormattingModelProvider - .createFormattingModelForPsiFile(element.getContainingFile(), - new SimpleBlock(element.getNode(), - Wrap.createWrap(WrapType.NONE, false), - Alignment.createAlignment(), - createSpaceBuilder(settings)), - settings); + .createFormattingModelForPsiFile(element.getContainingFile(), + new SimpleBlock(element.getNode(), + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + createSpaceBuilder(settings)), + settings); } - - private static SpacingBuilder createSpaceBuilder(CodeStyleSettings settings) { - return new SpacingBuilder(settings, SimpleLanguage.INSTANCE) - .around(SimpleTypes.SEPARATOR) - .spaceIf(settings.getCommonSettings(SimpleLanguage.INSTANCE.getID()).SPACE_AROUND_ASSIGNMENT_OPERATORS) - .before(SimpleTypes.PROPERTY) - .none(); - } - + @Nullable @Override public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) { return null; } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleIcons.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleIcons.java index e9325d996..b439ba485 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleIcons.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleIcons.java @@ -7,5 +7,7 @@ import com.intellij.openapi.util.IconLoader; import javax.swing.*; public class SimpleIcons { + public static final Icon FILE = IconLoader.getIcon("/icons/jar-gray.png"); -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguage.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguage.java index 41cb2c636..0c99bfb36 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguage.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguage.java @@ -5,9 +5,11 @@ package org.intellij.sdk.language; import com.intellij.lang.Language; public class SimpleLanguage extends Language { + public static final SimpleLanguage INSTANCE = new SimpleLanguage(); private SimpleLanguage() { super("Simple"); } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java index 27acc2943..9b67404bb 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java @@ -3,16 +3,18 @@ package org.intellij.sdk.language; import com.intellij.lang.Language; -import com.intellij.psi.codeStyle.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable; +import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider; import org.jetbrains.annotations.NotNull; public class SimpleLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettingsProvider { + @NotNull @Override public Language getLanguage() { return SimpleLanguage.INSTANCE; } - + @Override public void customizeSettings(@NotNull CodeStyleSettingsCustomizable consumer, @NotNull SettingsType settingsType) { if (settingsType == SettingsType.SPACING_SETTINGS) { @@ -22,21 +24,22 @@ public class SimpleLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe consumer.showStandardOptions("KEEP_BLANK_LINES_IN_CODE"); } } - + @Override public String getCodeSample(@NotNull SettingsType settingsType) { return "# You are reading the \".properties\" entry.\n" + - "! The exclamation mark can also mark text as comments.\n" + - "website = https://en.wikipedia.org/\n" + - "\n" + - "language = English\n" + - "# The backslash below tells the application to continue reading\n" + - "# the value onto the next line.\n" + - "message = Welcome to \\\n" + - " Wikipedia!\n" + - "# Add spaces to the key\n" + - "key\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n" + - "# Unicode\n" + - "tab : \\u0009"; + "! The exclamation mark can also mark text as comments.\n" + + "website = https://en.wikipedia.org/\n" + + "\n" + + "language = English\n" + + "# The backslash below tells the application to continue reading\n" + + "# the value onto the next line.\n" + + "message = Welcome to \\\n" + + " Wikipedia!\n" + + "# Add spaces to the key\n" + + "key\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n" + + "# Unicode\n" + + "tab : \\u0009"; } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLexerAdapter.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLexerAdapter.java index 52f773c65..c455fa415 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLexerAdapter.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLexerAdapter.java @@ -7,7 +7,9 @@ import com.intellij.lexer.FlexAdapter; import java.io.Reader; public class SimpleLexerAdapter extends FlexAdapter { + public SimpleLexerAdapter() { - super(new SimpleLexer((Reader) null)); + super(new SimpleLexer(null)); } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLineMarkerProvider.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLineMarkerProvider.java index 5854a4e63..7078569aa 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLineMarkerProvider.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLineMarkerProvider.java @@ -2,40 +2,51 @@ package org.intellij.sdk.language; -import com.intellij.codeInsight.daemon.*; +import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo; +import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider; import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLiteralExpression; import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl; import org.intellij.sdk.language.psi.SimpleProperty; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.Collection; +import java.util.List; public class SimpleLineMarkerProvider extends RelatedItemLineMarkerProvider { + @Override - protected void collectNavigationMarkers( @NotNull PsiElement element, - @NotNull Collection< ? super RelatedItemLineMarkerInfo > result ) { + protected void collectNavigationMarkers(@NotNull PsiElement element, + @NotNull Collection> result) { // This must be an element with a literal expression as a parent - if ( !(element instanceof PsiJavaTokenImpl) || !(element.getParent() instanceof PsiLiteralExpression) ) return; - + if (!(element instanceof PsiJavaTokenImpl) || !(element.getParent() instanceof PsiLiteralExpression)) { + return; + } + // The literal expression must start with the Simple language literal expression PsiLiteralExpression literalExpression = (PsiLiteralExpression) element.getParent(); String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; - if ( ( value == null ) || !value.startsWith( SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR ) ) return; + if ((value == null) || + !value.startsWith(SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR)) { + return; + } // Get the Simple language property usage Project project = element.getProject(); - String possibleProperties = value.substring( SimpleAnnotator.SIMPLE_PREFIX_STR.length()+ SimpleAnnotator.SIMPLE_SEPARATOR_STR.length() ); - final List properties = SimpleUtil.findProperties( project, possibleProperties ); - if ( properties.size() > 0 ) { + String possibleProperties = value.substring( + SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length() + ); + final List properties = SimpleUtil.findProperties(project, possibleProperties); + if (properties.size() > 0) { // Add the property to a collection of line marker info - NavigationGutterIconBuilder< PsiElement > builder = - NavigationGutterIconBuilder.create( SimpleIcons.FILE ) - .setTargets( properties ) - .setTooltipText( "Navigate to Simple language property" ); - result.add( builder.createLineMarkerInfo( element ) ); + NavigationGutterIconBuilder builder = + NavigationGutterIconBuilder.create(SimpleIcons.FILE) + .setTargets(properties) + .setTooltipText("Navigate to Simple language property"); + result.add(builder.createLineMarkerInfo(element)); } } -} \ No newline at end of file +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleParserDefinition.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleParserDefinition.java index 5fa6c7aeb..f4bdbdadb 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleParserDefinition.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleParserDefinition.java @@ -2,69 +2,78 @@ package org.intellij.sdk.language; -import com.intellij.lang.*; +import com.intellij.lang.ASTNode; +import com.intellij.lang.ParserDefinition; +import com.intellij.lang.PsiParser; import com.intellij.lexer.Lexer; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; -import com.intellij.psi.tree.*; +import com.intellij.psi.FileViewProvider; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IFileElementType; +import com.intellij.psi.tree.TokenSet; import org.intellij.sdk.language.parser.SimpleParser; -import org.intellij.sdk.language.psi.*; +import org.intellij.sdk.language.psi.SimpleFile; +import org.intellij.sdk.language.psi.SimpleTypes; import org.jetbrains.annotations.NotNull; public class SimpleParserDefinition implements ParserDefinition { + public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE); public static final TokenSet COMMENTS = TokenSet.create(SimpleTypes.COMMENT); - + public static final IFileElementType FILE = new IFileElementType(SimpleLanguage.INSTANCE); - + @NotNull @Override public Lexer createLexer(Project project) { return new SimpleLexerAdapter(); } - + @NotNull @Override public TokenSet getWhitespaceTokens() { return WHITE_SPACES; } - + @NotNull @Override public TokenSet getCommentTokens() { return COMMENTS; } - + @NotNull @Override public TokenSet getStringLiteralElements() { return TokenSet.EMPTY; } - + @NotNull @Override public PsiParser createParser(final Project project) { return new SimpleParser(); } - + @Override public IFileElementType getFileNodeType() { return FILE; } - + @Override public PsiFile createFile(FileViewProvider viewProvider) { return new SimpleFile(viewProvider); } - + @Override public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode right) { return SpaceRequirements.MAY; } - + @NotNull @Override public PsiElement createElement(ASTNode node) { return SimpleTypes.Factory.createElement(node); } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleRefactoringSupportProvider.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleRefactoringSupportProvider.java index a553f7d7d..eca4af9e0 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleRefactoringSupportProvider.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleRefactoringSupportProvider.java @@ -5,11 +5,14 @@ package org.intellij.sdk.language; import com.intellij.lang.refactoring.RefactoringSupportProvider; import com.intellij.psi.PsiElement; import org.intellij.sdk.language.psi.SimpleProperty; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class SimpleRefactoringSupportProvider extends RefactoringSupportProvider { + @Override public boolean isMemberInplaceRenameAvailable(@NotNull PsiElement elementToRename, @Nullable PsiElement context) { return (elementToRename instanceof SimpleProperty); } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleReference.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleReference.java index b9823e9fb..5abcf5415 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleReference.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleReference.java @@ -2,23 +2,27 @@ package org.intellij.sdk.language; -import com.intellij.codeInsight.lookup.*; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import org.intellij.sdk.language.psi.SimpleProperty; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.List; public class SimpleReference extends PsiReferenceBase implements PsiPolyVariantReference { + private final String key; - + public SimpleReference(@NotNull PsiElement element, TextRange textRange) { super(element, textRange); key = element.getText().substring(textRange.getStartOffset(), textRange.getEndOffset()); } - + @NotNull @Override public ResolveResult[] multiResolve(boolean incompleteCode) { @@ -30,14 +34,14 @@ public class SimpleReference extends PsiReferenceBase implements Psi } return results.toArray(new ResolveResult[results.size()]); } - + @Nullable @Override public PsiElement resolve() { ResolveResult[] resolveResults = multiResolve(false); return resolveResults.length == 1 ? resolveResults[0].getElement() : null; } - + @NotNull @Override public Object[] getVariants() { @@ -47,11 +51,12 @@ public class SimpleReference extends PsiReferenceBase implements Psi for (final SimpleProperty property : properties) { if (property.getKey() != null && property.getKey().length() > 0) { variants.add(LookupElementBuilder - .create(property).withIcon(SimpleIcons.FILE) - .withTypeText(property.getContainingFile().getName()) + .create(property).withIcon(SimpleIcons.FILE) + .withTypeText(property.getContainingFile().getName()) ); } } return variants.toArray(); } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleReferenceContributor.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleReferenceContributor.java index ae39d63e6..d8704b64c 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleReferenceContributor.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleReferenceContributor.java @@ -8,9 +8,11 @@ import com.intellij.psi.*; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; -import static org.intellij.sdk.language.SimpleAnnotator.*; +import static org.intellij.sdk.language.SimpleAnnotator.SIMPLE_PREFIX_STR; +import static org.intellij.sdk.language.SimpleAnnotator.SIMPLE_SEPARATOR_STR; public class SimpleReferenceContributor extends PsiReferenceContributor { + @Override public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression.class), @@ -31,4 +33,5 @@ public class SimpleReferenceContributor extends PsiReferenceContributor { } }); } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewElement.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewElement.java index 81bc131ad..73d1f2be2 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewElement.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewElement.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; public class SimpleStructureViewElement implements StructureViewTreeElement, SortableTreeElement { + private final NavigatablePsiElement myElement; public SimpleStructureViewElement(NavigatablePsiElement element) { @@ -71,4 +72,5 @@ public class SimpleStructureViewElement implements StructureViewTreeElement, Sor } return EMPTY_ARRAY; } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewFactory.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewFactory.java index 9d351df69..f8b1a3d84 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewFactory.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewFactory.java @@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class SimpleStructureViewFactory implements PsiStructureViewFactory { + @Nullable @Override public StructureViewBuilder getStructureViewBuilder(@NotNull final PsiFile psiFile) { @@ -23,4 +24,5 @@ public class SimpleStructureViewFactory implements PsiStructureViewFactory { } }; } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewModel.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewModel.java index 5b64755c7..f23cb5bec 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewModel.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleStructureViewModel.java @@ -2,31 +2,35 @@ package org.intellij.sdk.language; -import com.intellij.ide.structureView.*; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.StructureViewModelBase; +import com.intellij.ide.structureView.StructureViewTreeElement; import com.intellij.ide.util.treeView.smartTree.Sorter; import com.intellij.psi.PsiFile; import org.intellij.sdk.language.psi.SimpleFile; import org.jetbrains.annotations.NotNull; public class SimpleStructureViewModel extends StructureViewModelBase implements - StructureViewModel.ElementInfoProvider { + StructureViewModel.ElementInfoProvider { + public SimpleStructureViewModel(PsiFile psiFile) { super(psiFile, new SimpleStructureViewElement(psiFile)); } - + @NotNull public Sorter[] getSorters() { return new Sorter[]{Sorter.ALPHA_SORTER}; } - - + + @Override public boolean isAlwaysShowsPlus(StructureViewTreeElement element) { return false; } - + @Override public boolean isAlwaysLeaf(StructureViewTreeElement element) { return element instanceof SimpleFile; } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleSyntaxHighlighter.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleSyntaxHighlighter.java index 7b1b1184f..c37f7c283 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleSyntaxHighlighter.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleSyntaxHighlighter.java @@ -3,7 +3,8 @@ package org.intellij.sdk.language; import com.intellij.lexer.Lexer; -import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; +import com.intellij.openapi.editor.HighlighterColors; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; import com.intellij.psi.TokenType; @@ -14,31 +15,32 @@ import org.jetbrains.annotations.NotNull; import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey; public class SimpleSyntaxHighlighter extends SyntaxHighlighterBase { + public static final TextAttributesKey SEPARATOR = - createTextAttributesKey("SIMPLE_SEPARATOR", DefaultLanguageHighlighterColors.OPERATION_SIGN); + createTextAttributesKey("SIMPLE_SEPARATOR", DefaultLanguageHighlighterColors.OPERATION_SIGN); public static final TextAttributesKey KEY = - createTextAttributesKey("SIMPLE_KEY", DefaultLanguageHighlighterColors.KEYWORD); + createTextAttributesKey("SIMPLE_KEY", DefaultLanguageHighlighterColors.KEYWORD); public static final TextAttributesKey VALUE = - createTextAttributesKey("SIMPLE_VALUE", DefaultLanguageHighlighterColors.STRING); + createTextAttributesKey("SIMPLE_VALUE", DefaultLanguageHighlighterColors.STRING); public static final TextAttributesKey COMMENT = - createTextAttributesKey("SIMPLE_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT); + createTextAttributesKey("SIMPLE_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT); public static final TextAttributesKey BAD_CHARACTER = - createTextAttributesKey("SIMPLE_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER); - - + createTextAttributesKey("SIMPLE_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER); + + private static final TextAttributesKey[] BAD_CHAR_KEYS = new TextAttributesKey[]{BAD_CHARACTER}; private static final TextAttributesKey[] SEPARATOR_KEYS = new TextAttributesKey[]{SEPARATOR}; private static final TextAttributesKey[] KEY_KEYS = new TextAttributesKey[]{KEY}; private static final TextAttributesKey[] VALUE_KEYS = new TextAttributesKey[]{VALUE}; private static final TextAttributesKey[] COMMENT_KEYS = new TextAttributesKey[]{COMMENT}; private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0]; - + @NotNull @Override public Lexer getHighlightingLexer() { return new SimpleLexerAdapter(); } - + @NotNull @Override public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { @@ -56,4 +58,5 @@ public class SimpleSyntaxHighlighter extends SyntaxHighlighterBase { return EMPTY_KEYS; } } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java index c35b27f93..c941aab46 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java @@ -2,15 +2,18 @@ package org.intellij.sdk.language; -import com.intellij.openapi.fileTypes.*; +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; public class SimpleSyntaxHighlighterFactory extends SyntaxHighlighterFactory { + @NotNull @Override public SyntaxHighlighter getSyntaxHighlighter(Project project, VirtualFile virtualFile) { return new SimpleSyntaxHighlighter(); } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleUtil.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleUtil.java index e182e7408..764b3377c 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleUtil.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleUtil.java @@ -5,20 +5,24 @@ package org.intellij.sdk.language; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiManager; -import com.intellij.psi.search.*; +import com.intellij.psi.search.FileTypeIndex; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import org.intellij.sdk.language.psi.SimpleFile; import org.intellij.sdk.language.psi.SimpleProperty; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; public class SimpleUtil { - + // Searches the entire project for Simple language files with instances of the Simple property with the given key public static List findProperties(Project project, String key) { List result = new ArrayList<>(); Collection virtualFiles = - FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project)); + FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project)); for (VirtualFile virtualFile : virtualFiles) { SimpleFile simpleFile = (SimpleFile) PsiManager.getInstance(project).findFile(virtualFile); if (simpleFile != null) { @@ -26,7 +30,7 @@ public class SimpleUtil { if (properties != null) { for (SimpleProperty property : properties) { if (key.equals(property.getKey())) { - result.add(property); + result.add(property); } } } @@ -34,11 +38,11 @@ public class SimpleUtil { } return result; } - + public static List findProperties(Project project) { List result = new ArrayList<>(); Collection virtualFiles = - FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project)); + FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project)); for (VirtualFile virtualFile : virtualFiles) { SimpleFile simpleFile = (SimpleFile) PsiManager.getInstance(project).findFile(virtualFile); if (simpleFile != null) { @@ -50,4 +54,5 @@ public class SimpleUtil { } return result; } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleElementFactory.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleElementFactory.java index fb264ae45..6a3fc22c5 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleElementFactory.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleElementFactory.java @@ -3,10 +3,12 @@ package org.intellij.sdk.language.psi; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFileFactory; import org.intellij.sdk.language.SimpleFileType; public class SimpleElementFactory { + public static SimpleProperty createProperty(Project project, String name) { final SimpleFile file = createFile(project, name); return (SimpleProperty) file.getFirstChild(); @@ -14,7 +16,7 @@ public class SimpleElementFactory { public static SimpleFile createFile(Project project, String text) { String name = "dummy.simple"; - return (SimpleFile) PsiFileFactory.getInstance( project).createFileFromText(name, SimpleFileType.INSTANCE, text); + return (SimpleFile) PsiFileFactory.getInstance(project).createFileFromText(name, SimpleFileType.INSTANCE, text); } public static SimpleProperty createProperty(Project project, String name, String value) { @@ -27,4 +29,4 @@ public class SimpleElementFactory { return file.getFirstChild(); } -} \ No newline at end of file +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleElementType.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleElementType.java index 6a049e925..1f98b7cbf 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleElementType.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleElementType.java @@ -8,7 +8,9 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class SimpleElementType extends IElementType { - public SimpleElementType( @NotNull @NonNls String debugName) { + + public SimpleElementType(@NotNull @NonNls String debugName) { super(debugName, SimpleLanguage.INSTANCE); } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleFile.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleFile.java index 4ef00bf4e..51d6faaf2 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleFile.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleFile.java @@ -5,22 +5,25 @@ package org.intellij.sdk.language.psi; import com.intellij.extapi.psi.PsiFileBase; import com.intellij.openapi.fileTypes.FileType; import com.intellij.psi.FileViewProvider; -import org.intellij.sdk.language.*; +import org.intellij.sdk.language.SimpleFileType; +import org.intellij.sdk.language.SimpleLanguage; import org.jetbrains.annotations.NotNull; public class SimpleFile extends PsiFileBase { + public SimpleFile(@NotNull FileViewProvider viewProvider) { super(viewProvider, SimpleLanguage.INSTANCE); } - + @NotNull @Override public FileType getFileType() { return SimpleFileType.INSTANCE; } - + @Override public String toString() { return "Simple File"; } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleNamedElement.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleNamedElement.java index 42daf1966..9499b75cd 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleNamedElement.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleNamedElement.java @@ -5,4 +5,5 @@ package org.intellij.sdk.language.psi; import com.intellij.psi.PsiNameIdentifierOwner; public interface SimpleNamedElement extends PsiNameIdentifierOwner { -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleTokenType.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleTokenType.java index 30467b727..eef585869 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleTokenType.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleTokenType.java @@ -4,15 +4,18 @@ package org.intellij.sdk.language.psi; import com.intellij.psi.tree.IElementType; import org.intellij.sdk.language.SimpleLanguage; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; public class SimpleTokenType extends IElementType { + public SimpleTokenType(@NotNull @NonNls String debugName) { super(debugName, SimpleLanguage.INSTANCE); } - + @Override public String toString() { return "SimpleTokenType." + super.toString(); } + } diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/impl/SimpleNamedElementImpl.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/impl/SimpleNamedElementImpl.java index f2e55c7e9..3785f51db 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/impl/SimpleNamedElementImpl.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/impl/SimpleNamedElementImpl.java @@ -8,7 +8,9 @@ import org.intellij.sdk.language.psi.SimpleNamedElement; import org.jetbrains.annotations.NotNull; public abstract class SimpleNamedElementImpl extends ASTWrapperPsiElement implements SimpleNamedElement { + public SimpleNamedElementImpl(@NotNull ASTNode node) { super(node); } -} \ No newline at end of file + +} diff --git a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/impl/SimplePsiImplUtil.java b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/impl/SimplePsiImplUtil.java index 67b3b7312..6653a9371 100644 --- a/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/impl/SimplePsiImplUtil.java +++ b/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/impl/SimplePsiImplUtil.java @@ -15,6 +15,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; public class SimplePsiImplUtil { + public static String getKey(SimpleProperty element) { ASTNode keyNode = element.getNode().findChildByType(SimpleTypes.KEY); if (keyNode != null) { @@ -79,4 +80,4 @@ public class SimplePsiImplUtil { }; } -} \ No newline at end of file +} diff --git a/simple_language_plugin/src/main/resources/META-INF/plugin.xml b/simple_language_plugin/src/main/resources/META-INF/plugin.xml index 23747a333..129d4bfd9 100644 --- a/simple_language_plugin/src/main/resources/META-INF/plugin.xml +++ b/simple_language_plugin/src/main/resources/META-INF/plugin.xml @@ -2,21 +2,25 @@ - + org.intellij.sdk.language - - SDK: Simple Language Sample Project + + SDK: Simple Language Sample com.intellij.modules.platform com.intellij.modules.java - + Defines a new language, Simple language with support for syntax highlighting, annotations, code completion, and other features. -
    See the Custom Language Tutorial for more information. + Demonstrates how to add custom language support to an IntelliJ Platform-based IDE.
    Defines a new language, + Simple language with support for syntax highlighting, annotations, code completion, and other features. +
    + See the + Custom + Language Tutorial for more information. ]]>
    @@ -33,23 +37,30 @@ - - + - - + + - - + + - + diff --git a/theme_basics/README.md b/theme_basics/README.md new file mode 100644 index 000000000..cbc65d0bc --- /dev/null +++ b/theme_basics/README.md @@ -0,0 +1,39 @@ +# Theme Basics [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Creating Custom UI Themes in IntelliJ SDK Docs][docs:themes]* + +## Quickstart + +Custom UI Themes are available beginning in version 2019.1. + +Creating a custom UI Theme is a process of choosing a base IDE Theme (Light or Darcula) then changing aspects of the base Theme definition. +Custom UI Themes can: +- substitute icons, +- change the colors of icons and UI controls, +- alter the borders and insets of UI controls, +- provide custom editor schemes, +- add background images. + +## Structure + +Theme Basics plugin depends on the [IntelliJ Platform SDK][docs] and [DevKit][docs:devkit] as a build system. + +The main plugin definition file is stored in the [plugin.xml][file:plugin.xml] file, which is created according to the [Plugin Configuration File documentation][docs:plugin.xml]. +It describes definitions of the actions, extensions, or listeners provided by the plugin. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ---------------------------- | ------------------------------------------------------- | --------------------- | +| `com.intellij.themeProvider` | [theme_basics.theme.json][file:theme_basics.theme.json] | | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:themes]: https://jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html +[docs:devkit]: https://jetbrains.org/intellij/sdk/docs/basics/getting_started/using_dev_kit.html +[docs:plugin.xml]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_configuration_file.html + +[file:plugin.xml]: ./resources/META-INF/plugin.xml +[file:theme_basics.theme.json]: ./resources/theme_basics.theme.json diff --git a/theme_basics/resources/META-INF/plugin.xml b/theme_basics/resources/META-INF/plugin.xml index e91061f56..16959f51e 100644 --- a/theme_basics/resources/META-INF/plugin.xml +++ b/theme_basics/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ - + org.intellij.sdk.themeBasics diff --git a/tool_window/README.md b/tool_window/README.md new file mode 100644 index 000000000..148f62389 --- /dev/null +++ b/tool_window/README.md @@ -0,0 +1,27 @@ +# Tool Window Sample [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Tool Windows in IntelliJ SDK Docs][docs:tool_windows]* + +## Quickstart + +Tool Windows are child windows of the IDE used to display information. +These windows generally have their toolbars (referred to as tool window bars) along the outer edges of the main window containing one or more tool window buttons, which activate panels displayed on the left, bottom, and right sides of the main IDE window. + +The current implementation displays a `JPanel` component containing simple icons and information about the actual system date, time, and timezone. +Component is provided by the `MyToolWindow` class through the `getContent()` method invoked inside the `MyToolWindowFactory` implementation. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ------------------------- | ----------------------------------------------- | ------------------------------------------ | +| `com.intellij.toolWindow` | [MyToolWindowFactory][file:MyToolWindowFactory] | [ToolWindowFactory][sdk:ToolWindowFactory] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:tool_windows]: https://jetbrains.org/intellij/sdk/docs/user_interface_components/tool_windows.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:MyToolWindowFactory]: ./src/main/java/org/intellij/sdk/toolWindow/MyToolWindowFactory.java + +[sdk:ToolWindowFactory]: upsource:///platform/platform-api/src/com/intellij/openapi/wm/ToolWindowFactory.java diff --git a/tool_window/src/main/java/org/intellij/sdk/toolWindow/MyToolWindow.java b/tool_window/src/main/java/org/intellij/sdk/toolWindow/MyToolWindow.java index f112607fb..7d941942b 100644 --- a/tool_window/src/main/java/org/intellij/sdk/toolWindow/MyToolWindow.java +++ b/tool_window/src/main/java/org/intellij/sdk/toolWindow/MyToolWindow.java @@ -8,6 +8,7 @@ import javax.swing.*; import java.util.Calendar; public class MyToolWindow { + private JButton refreshToolWindowButton; private JButton hideToolWindowButton; private JLabel currentDate; @@ -46,4 +47,5 @@ public class MyToolWindow { public JPanel getContent() { return myToolWindowContent; } + } diff --git a/tool_window/src/main/java/org/intellij/sdk/toolWindow/MyToolWindowFactory.java b/tool_window/src/main/java/org/intellij/sdk/toolWindow/MyToolWindowFactory.java index 47815f916..529b11b47 100644 --- a/tool_window/src/main/java/org/intellij/sdk/toolWindow/MyToolWindowFactory.java +++ b/tool_window/src/main/java/org/intellij/sdk/toolWindow/MyToolWindowFactory.java @@ -10,6 +10,7 @@ import com.intellij.ui.content.ContentFactory; import org.jetbrains.annotations.NotNull; public class MyToolWindowFactory implements ToolWindowFactory { + // Create the tool window content. public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { MyToolWindow myToolWindow = new MyToolWindow(toolWindow); @@ -17,4 +18,5 @@ public class MyToolWindowFactory implements ToolWindowFactory { Content content = contentFactory.createContent(myToolWindow.getContent(), "", false); toolWindow.getContentManager().addContent(content); } + } diff --git a/tool_window/src/main/resources/META-INF/plugin.xml b/tool_window/src/main/resources/META-INF/plugin.xml index cf0594345..4fae6f488 100644 --- a/tool_window/src/main/resources/META-INF/plugin.xml +++ b/tool_window/src/main/resources/META-INF/plugin.xml @@ -2,20 +2,22 @@ - + org.intellij.sdk.toolWindow - - SDK: Tool Window Sample Project + + SDK: Tool Window Sample com.intellij.modules.platform - + See the Tool Windows for more information. + This sample plugin illustrates how to create your custom tool window.
    + See the + Tool Windows + for more information. ]]>
    diff --git a/tree_structure_provider/README.md b/tree_structure_provider/README.md new file mode 100644 index 000000000..17b3dc3f7 --- /dev/null +++ b/tree_structure_provider/README.md @@ -0,0 +1,27 @@ +# Tree Structure Provider Sample [![JetBrains IntelliJ Platform SDK Docs](https://jb.gg/badges/docs.svg)][docs] +*Reference: [Tree Structure View in IntelliJ SDK Docs][docs:tree_structure_view]* + +## Quickstart + +The Tree Structure Provider sample project implements `treeStructureProvider` Extension Point, which allows modifying the structure of the project tree in the Project View panel. +This implementation limits the presented files to the Plain Text files only. + +The current implementation checks if a Project View node represents a directory or file of the `PlainTextFileType` type. +Otherwise, an element is not included in the results list, so only directories and plain text files are rendered. + +### Extension Points + +| Name | Implementation | Extension Point Class | +| ------------------------------------ | ------------------------------------------------------------------- | -------------------------------------------------- | +| `com.intellij.treeStructureProvider` | [TextOnlyTreeStructureProvider][file:TextOnlyTreeStructureProvider] | [TreeStructureProvider][sdk:TreeStructureProvider] | + +*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* + + +[docs]: https://www.jetbrains.org/intellij/sdk/docs +[docs:tree_structure_view]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/tree_structure_view.html +[docs:ep]: https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_extensions.html + +[file:TextOnlyTreeStructureProvider]: ./src/main/java/org/intellij/sdk/treeStructureProvider/TextOnlyTreeStructureProvider.java + +[sdk:TreeStructureProvider]: upsource:///platform/editor-ui-api/src/com/intellij/ide/projectView/TreeStructureProvider.java diff --git a/tree_structure_provider/src/main/java/org/intellij/sdk/treeStructureProvider/TextOnlyTreeStructureProvider.java b/tree_structure_provider/src/main/java/org/intellij/sdk/treeStructureProvider/TextOnlyTreeStructureProvider.java index 8e5e0f24c..e60d5b7ce 100644 --- a/tree_structure_provider/src/main/java/org/intellij/sdk/treeStructureProvider/TextOnlyTreeStructureProvider.java +++ b/tree_structure_provider/src/main/java/org/intellij/sdk/treeStructureProvider/TextOnlyTreeStructureProvider.java @@ -2,21 +2,25 @@ package org.intellij.sdk.treeStructureProvider; -import com.intellij.ide.projectView.*; +import com.intellij.ide.projectView.TreeStructureProvider; +import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.nodes.PsiFileNode; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.fileTypes.PlainTextFileType; import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; public class TextOnlyTreeStructureProvider implements TreeStructureProvider { + @NotNull @Override public Collection> modify(@NotNull AbstractTreeNode parent, - @NotNull Collection> children, - ViewSettings settings) { + @NotNull Collection> children, + ViewSettings settings) { ArrayList> nodes = new ArrayList<>(); for (AbstractTreeNode child : children) { if (child instanceof PsiFileNode) { @@ -35,4 +39,5 @@ public class TextOnlyTreeStructureProvider implements TreeStructureProvider { public Object getData(@NotNull Collection> selected, @NotNull String dataId) { return null; } + } diff --git a/tree_structure_provider/src/main/resources/META-INF/plugin.xml b/tree_structure_provider/src/main/resources/META-INF/plugin.xml index 0b8aea248..46385a547 100644 --- a/tree_structure_provider/src/main/resources/META-INF/plugin.xml +++ b/tree_structure_provider/src/main/resources/META-INF/plugin.xml @@ -2,20 +2,21 @@ - + org.intellij.sdk.treeStructureProvider - - SDK: Tree Structure Provider Sample Project + + SDK: Tree Structure Provider Sample com.intellij.modules.platform - + See the Tree Structure View for more information. + Tree Structure Provider showing only plain text files. +
    See the Tree + Structure View for more information. ]]>