IntelliJ IDEA插件开发-代码补全插件入门开发

使用IntelliJ IDEA想必大家都有使用过代码自动补全功能,如输入ab,会自动触发补全,提供相应的补全建议列表。作为有追求的程序员,有没有想过这样的功能是如何实现的?本节将详细介绍如何实现一个类似的代码自动补全插件。

在IntelliJ IDEA插件开发中,CompletionContributor是一个关键的API,它允许开发者为特定语言的代码编辑器添加代码补全功能。本节将详细介绍如何使用CompletionContributor实现代码补全功能,并提供完整的示例代码和解释,理解如何使用该API来创建一个简单的代码补全插件。

一.环境准备

为了确保项目的兼容性,本章节使用以下版本:

  • IntelliJ IDEA: 2020.1.4

  • JDK: 1.8

  • Gradle: 6.1

如果不知道如何搭建IntelliJ IDEA插件开发环境,请阅读【IntelliJ IDEA插件开发-开发环境搭建】章节内容。

二.CompletionContributor介绍

CompletionContributor 是一个IntelliJ IDEA插件API的类,它允许开发者定义代码补全的行为。通过继承CompletionContributor,可以设置触发补全的条件和提供相应的补全建议。这些补全建议会在编辑器中显示,帮助开发者快速编写代码。

代码补全的两种主要类型:
  • Basic Completion:标准的代码补全,一般会在用户输入时自动显示选项。

  • Smart Completion:根据上下文提供更为智能的代码补全。

本篇将实现一个基本的代码补全功能。

三.新建项目

首先,在IntelliJ IDEA中创建一个新的插件项目,并进行基础设置。

  1. 创建插件项目:打开IntelliJ IDEA,选择Create New Project。

  2. **填写项目基本信息:**这里随意命名。

  3. **修改org.jetbrains.intellij插件版本:**如果默认生成的build.gradle文件中Gradle版本和org.jetbrains.intellij插件版本不兼容导致Build窗口输出报错,打开build.gradle文件将org.jetbrains.intellij版本改为0.7.3即解决。Gradle版本和org.jetbrains.intellij插件兼容版本,请至gradle-intellij-plugin插件的releases页面查看。

四.编写插件代码

在这个步骤中,将编写CompletionContributor子类来定义补全的逻辑。

步骤 1:创建CompletionContributor子类

在src/main/java下创建MyCompletionContributor.java文件,并让它继承CompletionContributor。

代码解读:
  1. CompletionType.BASIC:指定为基本补全类型。

  2. PlatformPatterns.psiElement():匹配所有的PsiElement(表示源代码中的元素),即允许插件在所有位置触发补全。

  3. addCompletions 方法:定义补全的内容。resultSet.addElement用于添加选项。在这里,我们简单地添加了两个字符串 "HelloWorld" 和 "HelloPlugin" 作为补全建议。

步骤 2:注册CompletionContributor

在plugin.xml中注册MyCompletionContributor类。

language="JAVA"表示我们的补全功能将应用于Java语言。

五.测试插件

  1. 运行插件:在IntelliJ IDEA中选择 Run > Run 'Plugin'。

  2. 打开测试项目:在弹出的新窗口中打开或新建一个项目。

  3. 测试补全:在Java文件中输入任意字符,例如"H"或者"Hell",你会看到"HelloWorld"和"HelloPlugin" 出现在候选项列表中,通过上下键可选择,回车自动选中并替换

六.动态补全

目前实现了一个简单的代码补全,接下来进行一些改进,实现可根据上下文进行动态补全。大家都用过IntelliJ IDEA中的属性自动提示补全功能,如下图。

接下来将实现一个类似的功能,根据定义的属性实现动态补全,代码调整如下:

如果你使用以上代码你会发现它编译报错,找不到PsiVariable和PsiTreeUtil,这是因为它需要用到IntelliJ Platform Plugin SDK进行编译,点击菜单栏的 File -> Project Structure -> Project Settings -> Project -> Project SDK ,选择IntelliJ Platform Plugin SDK版本。如果未设置过IntelliJ Platform Plugin SDK,请阅读【IntelliJ IDEA插件开发-开发环境搭建】章节内容。

设置完IntelliJ Platform Plugin SDK后,此时编译不会报错了,但如果想跑起来需要在plugin.xml中添加对 com.intellij.modules.java 的依赖,这是因为PsiVariable是Java相关的类,同时还需要在build.gradle文件中增加Java插件依赖,确保项目在构建时包含Java插件所需的依赖项, build.gradle完整代码如下:

plugin.xml代码如下:

接下来运行插件:选择Run > Run 'Plugin',代码运行效果如下:

如果你想实现右侧的文字"我是动态生成的"换成对应变量的数据类型,可以使用variable.getType().getPresentableText()替换,通过PsiVariable获取类型,具体代码如下:

LookupElementBuilder 是IntelliJ IDEA插件开发API中的一个核心类,用于构建代码补全建议的展示。以下是 LookupElementBuilder 类中一些常用且实用的方法:

  1. create(String lookupString)
  • 这是静态方法,用于生成包含补全字符串的基础 LookupElementBuilder 对象。

  • 示例:LookupElementBuilder.create("myCompletionItem")

withTypeText(String typeText)

  • 在补全建议右侧显示类型信息或描述性文本,通常用来标注该项的类型或来源。

  • 示例:withTypeText("int") 会在补全项右侧显示"int"文本。

withIcon(Icon icon)

  • 为补全项添加图标。通常用于在补全项左侧添加图标,比如类、方法或变量的图标。

  • 示例:withIcon(AllIcons.Nodes.Method)。

withTailText(String tailText, boolean grayed)

  • 在补全项后添加附加文本,例如参数或其他信息。grayed 参数表示文本是否显示为灰色。

  • 示例:withTailText("(param1, param2)", true) 在补全项后以灰色显示 (param1, param2)。

bold()

  • 让补全项的显示文本加粗。适合用于推荐性较高或特别重要的选项。

  • 示例:bold()。

withInsertHandler(InsertHandler<? super LookupElement> handler)

  • 定义插入操作的处理逻辑,例如在选择补全项后添加括号、光标移动等操作。

  • 示例:withInsertHandler((context, item) -> { /* 插入处理逻辑 */ })。

withPresentableText(String presentableText)

  • 自定义补全项的显示文本,不改变实际插入的内容。适合用在用户看到的内容和实际插入内容不同的场景。

  • 示例:withPresentableText("displayedText")。

withAutoCompletionPolicy(AutoCompletionPolicy policy)

  • 控制自动补全策略。可以设置为 AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE,使该项在自动补全时直接插入。

  • 示例:withAutoCompletionPolicy(AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE)。

withPriority(double priority)

  • 设置补全项的优先级,优先级越高的项将显示在补全列表的顶部。

  • 示例:withPriority(10.0)。

withCaseSensitivity(boolean caseSensitive)

  • 设置补全项是否区分大小写。适用于特定语言或环境要求区分大小写的情况。

  • 示例:withCaseSensitivity(false)。

这些方法可以配合使用,使补全建议更符合用户预期并提升用户体验。

本节实现了一个基础的代码补全功能,并展示了如何使用CompletionContributor来扩展和定制补全行为。完成插件开发后,你可以进一步扩展补全功能,实现更复杂的逻辑,满足实际项目需求。

相关推荐
Yan.love32 分钟前
开发场景中Java 集合的最佳选择
java·数据结构·链表
椰椰椰耶35 分钟前
【文档搜索引擎】搜索模块的完整实现
java·搜索引擎
大G哥35 分钟前
java提高正则处理效率
java·开发语言
小_太_阳1 小时前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
智慧老师1 小时前
Spring基础分析13-Spring Security框架
java·后端·spring
lxyzcm1 小时前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
V+zmm101342 小时前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
Oneforlove_twoforjob2 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
xmh-sxh-13142 小时前
常用的缓存技术都有哪些
java
AiFlutter2 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter