mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-28 01:07:49 +08:00
New Topic: Postfix Completion (#788)
This commit is contained in:
parent
424d882210
commit
5807d68941
4
ijs.tree
4
ijs.tree
@ -186,6 +186,10 @@
|
||||
<toc-element toc-title="Navigation"/>
|
||||
<toc-element id="editing.md">
|
||||
<toc-element toc-title="Code Completion"/>
|
||||
<toc-element id="postfix_completion.md">
|
||||
<toc-element id="postfix_templates.md"/>
|
||||
<toc-element id="advanced_postfix_templates.md"/>
|
||||
</toc-element>
|
||||
<toc-element id="templates.md">
|
||||
<toc-element id="live_templates.md">
|
||||
<toc-element id="template_support.md"/>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||
|
||||
* Code Completion
|
||||
* [](postfix_completion.md)
|
||||
* [](templates.md)
|
||||
* [](live_templates.md)
|
||||
* [](file_and_code_templates.md)
|
||||
|
@ -12,7 +12,10 @@ See [GitHub Changelog](https://github.com/JetBrains/intellij-sdk-docs/commits/ma
|
||||
|
||||
## 2022
|
||||
|
||||
### Jun-02
|
||||
### June-22
|
||||
|
||||
Postfix Completion
|
||||
: Add [](postfix_completion.md) section explaining how to implement generating or wrapping the existing code into additional constructs without navigating the caret back.
|
||||
|
||||
Gradle IntelliJ Plugin
|
||||
: Add [](tools_gradle_intellij_plugin.md) documentation to the Appendix III – Tools
|
||||
|
@ -13,6 +13,6 @@ Once the user selects a specific surrounder from the popup menu, the [`Surrounde
|
||||
**Example:**
|
||||
[`SurroundDescriptor`](upsource:///plugins/groovy/src/org/jetbrains/plugins/groovy/lang/surroundWith/GroovySurroundDescriptor.java) for Groovy plugin
|
||||
|
||||
> See the [](live_templates.md) section for information on how to support simple code surrounding with the *Live Templates* feature.
|
||||
> See the [](live_templates.md) and [](advanced_postfix_templates.md#surround-postfix-templates) sections for information on how to support code surrounding with other IDE features.
|
||||
>
|
||||
{type="note"}
|
||||
|
43
topics/tutorials/postfix_completion.md
Normal file
43
topics/tutorials/postfix_completion.md
Normal file
@ -0,0 +1,43 @@
|
||||
[//]: # (title: Postfix Completion)
|
||||
|
||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
|
||||
<excerpt>Postfix completion allows generating or wrapping existing code into additional constructs without navigating the caret back.</excerpt>
|
||||
|
||||
The
|
||||
[Postfix Completion](https://www.jetbrains.com/help/idea/auto-completing-code.html#postfix_completion)
|
||||
functionality allows developers to wrap a code fragment with a predefined template by typing a template abbreviation just after an expression meant to be wrapped, expanded, or modified.
|
||||
It relieves developers from typing repetitive or non-trivial code or helps to create the code faster, e.g., often it is convenient to write a code part and surround it with the required block without navigating the caret backward.
|
||||
|
||||
Consider a situation where a developer is not very familiar with a current Java project API and doesn't know how to name a variable that will be a result of an expression they want to type.
|
||||
The postfix completion makes it possible to write an expression at first and create a variable assignment with suggested names by adding a postfix template abbreviation at the end of the expression.
|
||||
|
||||
Assume that a user typed the following Java code:
|
||||
|
||||
```java
|
||||
void confirmOrder(Cart cart) {
|
||||
cart.getDeliveryType().getDeliveryCost()<caret>
|
||||
}
|
||||
```
|
||||
|
||||
To avoid moving the caret to the beginning of the line, the user can quickly create a variable assignment by adding the `.var` postfix abbreviation and expanding the template:
|
||||
|
||||
```java
|
||||
void confirmOrder(Cart cart) {
|
||||
cart.getDeliveryType().getDeliveryCost().var<ENTER>
|
||||
}
|
||||
```
|
||||
|
||||
When the template is applied, the above code is expanded to:
|
||||
|
||||
```java
|
||||
void confirmOrder(Cart cart) {
|
||||
Money deliveryCost = cart.getDeliveryType().getDeliveryCost();<caret>
|
||||
}
|
||||
```
|
||||
|
||||
In addition, the user can choose the best matching variable name from the name suggestions popup.
|
||||
|
||||
These sections describe how to implement Postfix Templates, and their associated building blocks, to plugins:
|
||||
- [](postfix_templates.md)
|
||||
- [](advanced_postfix_templates.md)
|
@ -0,0 +1,95 @@
|
||||
[//]: # (title: Advanced Postfix Templates)
|
||||
|
||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
|
||||
<excerpt>Advanced postfix templates provide additional features like editing possibilities, expression selector, etc.</excerpt>
|
||||
|
||||
While [simple templates](postfix_templates.md) can be handled by extending
|
||||
[`PostfixTemplate`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplate.java)
|
||||
class directly, more advanced templates require additional functionalities like selecting the expression that a template should be applied to or editing a template content.
|
||||
The IntelliJ Platform provides the base classes simplifying advanced template's features implementation.
|
||||
|
||||
## Postfix Templates With Expression Selector
|
||||
|
||||
In some contexts, it is not obvious what expression a template should be applied to.
|
||||
Consider the following Java code with the `var` postfix template at the end:
|
||||
|
||||
```java
|
||||
order.calculateWeight() > getMaxWeight(order.getDeliveryType()).var
|
||||
```
|
||||
|
||||
In the above code, a postfix template could be applied to the `getMaxWeight()` method invocation and the entire comparison expression depending on the user's intention.
|
||||
The postfix template implementation could automatically apply the template on the topmost or the closest applicable expression, but it is reasonable to leave the expression selection for the user.
|
||||
|
||||
Postfix templates with expression selector can be achieved by implementing
|
||||
[`PostfixTemplateWithExpressionSelector`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateWithExpressionSelector.java)
|
||||
and
|
||||
[`PostfixTemplateExpressionSelector`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateExpressionSelector.java)
|
||||
classes.
|
||||
|
||||
**Example:**
|
||||
[`IntroduceFieldPostfixTemplate`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java)
|
||||
introduces a Java class field, allowing to select one of the non-void expressions at the current offset.
|
||||
|
||||
## Live Template Syntax-Based Postfix Templates
|
||||
|
||||
The IntelliJ Platform-based IDEs provide the [Live Templates](https://www.jetbrains.com/help/idea/using-live-templates.html) feature.
|
||||
It allows defining a template text with dynamic expressions, replaced with actual values depending on the context.
|
||||
If the implemented postfix template's expanding behavior can be achieved with the live template syntax, it is much easier to extend the
|
||||
[`StringBasedPostfixTemplate`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StringBasedPostfixTemplate.java)
|
||||
than implementing the expansion behavior programmatically.
|
||||
|
||||
**Example:** [`StreamPostfixTemplate`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java) wraps array expression within the `Arrays.stream()` method.
|
||||
|
||||
> See the [](live_templates.md) section in SDK Docs for information on implementing the live templates feature in a plugin.
|
||||
>
|
||||
{type="note"}
|
||||
|
||||
## Editable Postfix Templates
|
||||
|
||||
All postfix templates that return `true` from the
|
||||
[`PostfixTemplate.isEditable()`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplate.java)
|
||||
method and have a key starting with `.` (dot) can be edited.
|
||||
In the simplest case, only the template's name can be edited.
|
||||
To provide more advanced editing possibilities, like creating new templates in the settings dialog, editing the template's content, variables, expression conditions, etc., a plugin must implement the related
|
||||
[`PostfixTemplateProvider's`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java)
|
||||
methods:
|
||||
|
||||
- `PostfixTemplateProvider.createEditor()` - returns an instance of the
|
||||
[`PostfixTemplateEditor`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/editable/PostfixTemplateEditor.java)
|
||||
class which is responsible for building the UI settings for a particular template and creating a template from the settings provided in this UI.
|
||||
The editor UI may contain settings controls other than the textual editor, like lists, checkboxes, etc.
|
||||
- `PostfixTemplateProvider.writeExternalTemplate()` / `readExternalTemplate()` - serializes/deserializes a given template to/from XML elements.
|
||||
Serialized template data is stored in the
|
||||
[`PostfixTemplateStorage`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplateStorage.java)
|
||||
[persistent component](persisting_state_of_components.md).
|
||||
|
||||
Implementing template, editor, and serialization methods from scratch is a tedious task, so the IntelliJ Platform provides classes that help implement editable templates:
|
||||
- [`EditablePostfixTemplateWithMultipleExpressions`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/editable/EditablePostfixTemplateWithMultipleExpressions.java)
|
||||
for editable templates with expression selector and conditions limiting the applicable contexts.
|
||||
Like [](#live-template-syntax-based-postfix-templates), it is text-based and uses the same live template syntax.
|
||||
- [`PostfixTemplateEditorBase`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplateEditorBase.java)
|
||||
for editors implementing the most common features like editing content, expression conditions, or using the topmost expression for template expanding
|
||||
- Utility class
|
||||
[`PostfixTemplatesUtils`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatesUtils.java)
|
||||
providing methods related to editable template data serialization
|
||||
|
||||
**Examples:**
|
||||
- [`JavaPostfixTemplateProvider`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java)
|
||||
providing Java editable templates
|
||||
- [`JavaPostfixTemplateEditor`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/editable/JavaPostfixTemplateEditor.java)
|
||||
implementing editor for Java editable templates
|
||||
- [`ObjectsRequireNonNullPostfixTemplate`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ObjectsRequireNonNullPostfixTemplate.java)
|
||||
implementing template wrapping the selected expression in `Objects.requireNonNull()` method
|
||||
|
||||
## Surround Postfix Templates
|
||||
|
||||
Existing
|
||||
[`Surrounder`](upsource:///platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java)
|
||||
implementations of the [](surround_with.md) feature required to invoke the <menupath>Code | Surround With...</menupath> action can be reused for postfix completion by extending the
|
||||
[`SurroundPostfixTemplateBase`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java)
|
||||
class and returning the surrounder object from the `getSurrounder()` method.
|
||||
|
||||
**Example:**
|
||||
[`NotNullCheckPostfixTemplate`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java)
|
||||
surrounding the selected expression with an `if` statement checking if the expression is `null`.
|
79
topics/tutorials/postfix_completion/postfix_templates.md
Normal file
79
topics/tutorials/postfix_completion/postfix_templates.md
Normal file
@ -0,0 +1,79 @@
|
||||
[//]: # (title: Postfix Templates)
|
||||
|
||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
|
||||
<excerpt>Postfix templates implement possibility to modify or wrap the existing code in additional constructs without navigating the caret back.</excerpt>
|
||||
|
||||
The IntelliJ Platform allows plugins to provide custom postfix templates specific to the supported languages, frameworks, or libraries.
|
||||
|
||||
To provide custom postfix templates for an existing or custom language, register an implementation of
|
||||
[`PostfixTemplateProvider`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java)
|
||||
in the `com.intellij.codeInsight.template.postfixTemplateProvider` extension point (EP).
|
||||
|
||||
The `PostfixTemplateProvider` extension contains the list of templates that extend the
|
||||
[`PostfixTemplate`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplate.java)
|
||||
class.
|
||||
During the code completion mechanism, all postfix template providers registered for the current language are queried for their templates.
|
||||
All templates enabled and applicable in the current context will be added to the completion popup items set.
|
||||
|
||||
**Examples:**
|
||||
- [`JavaPostfixTemplateProvider`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java) providing Java postfix templates
|
||||
- [`PyPostfixTemplateProvider`](upsource:///python/src/com/jetbrains/python/codeInsight/postfix/PyPostfixTemplateProvider.java) providing Python postfix templates
|
||||
|
||||
## Postfix Templates Implementation
|
||||
|
||||
The simplest way to create a postfix template is by extending the
|
||||
[`PostfixTemplate`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplate.java)
|
||||
class and implementing the key methods:
|
||||
- `boolean isApplicable()` determining whether the template can be used in the context described by parameters
|
||||
- `void expand()` inserting the template content in the editor
|
||||
|
||||
**Examples:**
|
||||
- [`InstanceofExpressionPostfixTemplate`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java) surrounding an expression with the _instanceof_ check
|
||||
- [`TryWithResourcesPostfixTemplate`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java) wrapping a selected expression in _try-with-resources_ block
|
||||
|
||||
> See the [](advanced_postfix_templates.md) section for information on how to implement postfix templates with more advanced features and editing possibilities.
|
||||
>
|
||||
{type="note"}
|
||||
|
||||
## Postfix Template Description
|
||||
|
||||
All postfix templates must provide descriptions and examples showing the code before and after a template is expanded.
|
||||
The files describing the template must be placed in the plugin's <path>resources</path> in the <path>postfixTemplates/_$TEMPLATE_NAME$_</path> where the _$TEMPLATE_NAME$_ directory must match the simple name of the template class,
|
||||
e.g., for a template implemented in `com.example.IntroduceVariablePostfixTemplate` class, the directory name should be named as <path>IntroduceVariablePostfixTemplate</path>.
|
||||
|
||||
Providing the description explaining the template purpose and context details is achieved by creating the <path>description.html</path> file.
|
||||
|
||||
Providing the code snippets showing the template in "before" and "after" expanding states is achieved via the <path>before._$EXTENSION$_.template</path> and <path>after._$EXTENSION$_.template</path> files accordingly.
|
||||
The _$EXTENSION$_ placeholder should be replaced with the extension of the template language, e.g., <path>before.kt.template</path> for a Kotlin template.
|
||||
|
||||
The code snippets included in the example files can use the `<spot>` marker, which should surround the most important code parts, e.g., expression to expand and position of the caret after expanding.
|
||||
Marked parts will be highlighted in the <menupath>Settings/Preferences | Editor | General | Postfix Completion</menupath> settings page, making it easier for users to understand how a template is expanded, e.g.:
|
||||
- <path>before.java.template</path>:
|
||||
```java
|
||||
<spot>cart.getProducts()</spot>.var
|
||||
```
|
||||
|
||||
- <path>after.java.template</path>:
|
||||
```java
|
||||
List<Product> products = cart.getProducts();<spot></spot>
|
||||
```
|
||||
|
||||
Template example files can also use the `$key` placeholder which is replaced with the actual template key in the preview UI, e.g., consider a template with the `var` key:
|
||||
|
||||
<compare title-before="Content" title-after="Rendition">
|
||||
<code style="block" lang="Text">
|
||||
cart.getProducts()$key
|
||||
</code>
|
||||
<code style="block" lang="Text">
|
||||
cart.getProducts().var
|
||||
</code>
|
||||
</compare>
|
||||
|
||||
The gutter icons for a postfix template class allow navigating to the corresponding description and before/after files in plugin resources.
|
||||
|
||||
**Example:**
|
||||
[`TryWithResourcesPostfixTemplate`](upsource:///java/java-impl/src/postfixTemplates/TryWithResourcesPostfixTemplate)
|
||||
directory containing description files for
|
||||
[`TryWithResourcesPostfixTemplate`](upsource:///java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java)
|
||||
template.
|
Loading…
x
Reference in New Issue
Block a user