IntelliJ Platform Plugin Template 中文版

IntelliJ Platform Plugin Template

太长不看版本: 点击 Use this template 按钮并在 intellij IDEA 中克隆仓库

IntelliJ Platform Plugin Template 是一个提供了让创建插件项目更简单的一个纯净的模版( 点击 从模版中创建仓库 文章)的仓库 .

这个模版的主要目标是通过预先配置项目脚手架和 CI,链接到适当的文档页面,并保持组织的一切,进而帮助新人和有经验的开发者加速准备阶段。

If you’re still not quite sure what this is all about, read our introduction: What is the IntelliJ Platform?

如果你仍然不确定这是关于什么的,可以阅读我们的介绍:什么是 IntelliJ 平台?

TIP : 点击 watch 按钮上面通知发布包含新功能和修复。

目录

在这个 README 中,我们将重点介绍以下模板项目创建的元素:

Getting started

我们深入了解插件开发之前以及和与它有关的一切, 提及使用 Github 模版的好处是值得的。
通过当下的模版创建一个新的项目,你可以使用没有关于这个项目的任何历史和引用开始你的项目。
This allows you to create a new repository easily without copying and pasting previous content, clone repositories, or clearing the history manually.

这允许你无需复制粘贴之前的内容,克隆仓库以及手动清除历史即可创建非常轻松地创建一个全新的仓库

All you have to do is click the Use this template button (you must be logged in with your GitHub account).

你仅仅需要做的就是点击 Use this template 按钮(你必须登陆 Github)

image.png

After using the template to create your blank project, the Template Cleanup workflow will be triggered to override or remove any template-specific configurations, such as the plugin name, current changelog, etc.

当使用创建了你的空白的项目,这个 Template Cleanup 工作流就会被触发覆盖或者移除任何模版特定的配置,比如插件的名字,当前的版本等。
Once this is complete, the project is ready to be cloned to your local environment and opened with IntelliJ IDEA.

一旦这个过程完成,这个项目就可以被克隆到本地的环境进而可以使用 IntelliJ IDEA 打开项目。

For the last step, you have to manually review the configuration variables described in the gradle.properties file and optionally move sources from the com.github.username.repository package to the one that works best for you.
Then you can get to work implementing your ideas.

对于最后一步,你必须手动检查在gradle.properties 中的配置便利那个的信息和可以将配置从 com.github.username.repository 修改为最适合你的那一个。

TIP: To use Java in your plugin, create the /src/main/java directory.

提示:如果在你的插件中使用 Java, 创建 /src/main/java 目录。

Gradle configuration

The recommended method for plugin development involves using the Gradle setup with the gradle-intellij-plugin installed.
The gradle-intellij-plugin makes it possible to run the IDE with your plugin and publish your plugin to JetBrains Marketplace Repository.

推荐的插件开发的方法是使用 gradle-intellij-plugin 和使用 Gradle 进行配置

NOTE: Make sure to always upgrade to the latest version of gradle-intellij-plugin.

注意:确定总是升级最新的 gradle-intellij-plugin 的版本。

A project built using the IntelliJ Platform Plugin Template includes a Gradle configuration already set up.

项目使用 IntelliJ 平台构建插件模板包括一个 Gradle 配置已经建立。
Feel free to read through the Using Gradle articles to understand your build better and learn how to customize it.

随时阅读 Using Gradle 文章更好地理解您的构建和学习如何定制它。

The most significant parts of the current configuration are:

当前配置的最重要的部分是:

更多细节关于 Kotlin 集成,请参阅 IntelliJ 平台插件 SDK 文档中的 Kotlin for Plugin Developers 章节。

Gradle properties

The project-specific configuration file gradle.properties contains:

Property name Description
pluginGroup Package name – afterusingthe template, this will be set to com.github.username.repo.
pluginName Plugin name displayed in the JetBrains Marketplace and the Plugins Repository.
pluginVersion The current version of the plugin.
pluginSinceBuild The since-build attribute of the tag.
pluginUntilBuild The until-build attribute of the tag.
pluginVerifierIdeVersions Versions of the IDEs that will be used with Plugin Verifier.
platformType The type of IDE distribution.
platformVersion The version of the IntelliJ Platform IDE will be used to build the plugin.
platformDownloadSources IDE sources downloaded while initializing the Gradle build.
platformPlugins Comma-separated list of dependencies to the bundled IDE plugins and plugins from the Plugin Repositories.
javaVersion Java language level used to compile sources and generate the files for – Java 11 is required since 2020.3.
gradleVersion Version of Gradle used for plugin development.

具体项目的配置文件 gradle.properties 包含:

属性名称 描述
pluginGroup 包名称——使用模板后,这将被设置为 com.github.username.repo.
pluginName 插件名称显示在 JetBrains 市场和插件仓库。
pluginVersion 当前版本的插件。
pluginSinceBuild since-build 属性标签。
pluginUntilBuild until-build 属性标签。
pluginVerifierIdeVersions 此处填写的 IDEs 版本将用于插件的插件
platformType IDE 的类型分布
platformVersion IntelliJ 平台的版本的 IDE 将用于构建插件
platformDownloadSources 初始化 Gradle 构建的时候 IDE 资源下载
platformPlugins 以逗号分隔的依赖性的 IDE 插件和插件捆绑插件存储库。
javaVersion Java 语言水平用于编译和生成文件来源—— 2020.3 以来的 Java 11 是必需的。
gradleVersion Gradle 用于插件开发的版本。

Environment variables

Some values used for the Gradle configuration shouldn’t be stored in files to avoid publishing them to the Version Control System.

一些用于 Gradle 配置的值不应存储在文件中,以避免将它们发布到版本控制系统。

来避免这种情况,介绍了环境变量,它可以提供在运行/调试配置在 IDE 中,或在 CI – 比如在 GitHub 中: ⚙️ Settings > Secrets.

Environment variables used by the current project are related to the plugin signing and publishing.

当前项目所使用的环境变量有关 plugin signing and publishing.。

Environment variable name Description
PRIVATE_KEY 证书的私钥,应该包含:-----BEGIN ENCRYPTED PRIVATE KEY-----...-----END ENCRYPTED PRIVATE KEY-----
PRIVATE_KEY_PASSWORD 密码用于加密证书文件。
CERTIFICATE_CHAIN 证书链,应该包含:-----BEGIN CERTIFICATE-----...-----END CERTIFICATE----
PUBLISH_TOKEN 发布令牌生成在 JetBrains 市场概要仪表板。

更多细节如何生成适当的值,检查上面提到的相关部分。

配置 GitHub 环境变量 ,去 ⚙️ Settings > Secrets 部分项目的存储库:

Settings ></div> Secrets” /></a></p>
<h2>插件模版结构</h2>
<p>A generated IntelliJ Platform Plugin Template repository contains the following content structure:</p>
<p>生成的 IntelliJ 平台插件模板库结构包含以下内容:</p>
<pre><code class=. ├── .github/ GitHub Actions workflows and Dependabot configuration files ├── .run/ Predefined Run/Debug Configurations ├── gradle │ └── wrapper/ Gradle Wrapper ├── build/ Output build directory ├── src Plugin sources │ └── main │ ├── kotlin/ Kotlin source files │ └── resources/ Resources - plugin.xml, icons, messages │ └── test │ ├── kotlin/ Kotlin test files │ └── testData/ Test data used by tests ├── .gitignore Git ignoring rules ├── build.gradle.kts Gradle configuration ├── CHANGELOG.md Full change history ├── gradle.properties Gradle configuration properties ├── gradlew *nix Gradle Wrapper binary ├── gradlew.bat Windows Gradle Wrapper binary ├── LICENSE License, MIT by default ├── qodana.yml Qodana configuration file ├── README.md README └── settings.gradle.kts Gradle project settings

In addition to the configuration files, the most crucial part is the src directory, which contains our implementation and the manifest for our plugin – plugin.xml.

TIP: To use Java in your plugin, create the /src/main/java directory.

插件模版结构

A generated IntelliJ Platform Plugin Template repository contains the following content structure:

生成的 IntelliJ 平台插件模板库结构包含以下内容:

.
├── .github/                GitHub Actions 工作流和 Dependabot 配置文件
├── .run/                   预定义的运行/调试配置
├── gradle
│   └── wrapper/            Gradle wrapper
├── build/                  输出构建目录
├── src                     插件的来源
│   └── main
│       ├── kotlin/         Kotlin 源文件
│       └── resources/      资源 - plugin.xml, icons, messages
│   └── test
│       ├── kotlin/         Kotlin 测试文件
│       └── testData/       测试所使用的测试数据
├── .gitignore              Git ignore 规则
├── build.gradle.kts        Gradle配置
├── CHANGELOG.md            完整的修改历史
├── gradle.properties       Gradle配置属性
├── gradlew                 *nix Gradle Wrapper 文件
├── gradlew.bat             Windows Gradle Wrapper 文件
├── LICENSE                 许可证书, 默认为MIT授权
├── qodana.yml              Qodana 配置文件
├── README.md               README
└── settings.gradle.kts     Gradle 项目设置

In addition to the configuration files, the most crucial part is the src directory, which contains our implementation and the manifest for our plugin – plugin.xml.

除了配置文件,最重要的部分是 src 目录,其中包含我们的实现,我们的插件的清单

TIP: To use Java in your plugin, create the /src/main/java directory.

提示 在你的插件,使用 Java 创建 Java /src/main/java 的目录

插件配置文件

这个插件的配置文件是 plugin.xml 文件位于 src/main/resources/META-INF 目录。

它提供一般信息插件,其依赖关系,扩展,和监听器。


  org.jetbrains.plugins.template
  Template
  JetBrains
  com.intellij.modules.platform

  
    
    
  

  
    
  

你可以在我们的文档 Plugin Configuration File 章节阅读更多的信息。

示例代码

The prepared template provides as little code as possible because it is impossible for a general scaffold to fulfill all the specific requirements for all types of plugins (language support, build tools, VCS related tools).

预处理模版提供了尽可能少的代码因为它不可能为一个通用的脚手架提供所有类型的插件所有特定的依赖(语言支持,编译工具,版本控制相关的工具)
Therefore, the template contains only the following files:

然而,模版仅仅包含下列的文件

.
├── MyBundle.kt                         包类提供的资源信息
├── listeners
│   └── MyProjectManagerListener.kt     项目经理监听器,处理项目生命周期
└── services
    ├── MyApplicationService.kt         对于所有的应用设置的应用级别服务
    └── MyProjectService.kt             项目级别的服务

这些文件位于 src/main/kotlin.
这个位置显示所使用的语言。
所以如果你决定使用 Java (或者除了 Kotlin 语言), 这些文件应该位于 src/main/java 目录。

开始时的实际实现, 你或许应该检索我们的 IntelliJ Platform SDK DevGuide, 它包含介绍插件的基本领域一起开发专门的教程。

对于那些, 那些做的最好的示例文件, 在 IntelliJ SDK Code SamplesIntelliJ Platform Explorer – 搜索工具浏览扩展点在现有的开源实现 IntelliJ 平台插件可以查询到.

测试

Testing plugins 是一个重要的组成部分,IntelliJ-based IDE 的插件开发,以确保一切工作如预期之间的 IDE 插件版本和重构。
IntelliJ 平台插件模板项目提供集成的两种测试方法——功能和用户界面测试。

功能测试

大部分的 IntelliJ 平台代码测试模型级,在无头环境中运行使用一个实际的 IDE 实例。

测试通常测试功能作为一个整体而不是单个函数组成它的实现(就像单元测试)

src/test/kotlin, 你会发现一个 MyPluginTest 测试它利用 BasePlatformTestCase 运行检查的 XML 文件来显示一个示例操作创建动态文件或阅读他们从 src/test/resources/rename 测试文件.

TIP: Run your tests using predefined Run Tests configuration or by invoking the ./gradlew test Gradle task.

提示:使用预定义的运行你的测试运行测试配置或者调用 ./gradlew test Gradle 任务。

UI 测试

如果你的插件提供了复杂的用户界面,你应该考虑在上面覆盖了测试和他们使用的功能。

IntelliJ UI Test Robot 允许您编写和执行 UI 测试在 IntelliJ IDE 运行实例。
你可以使用 XPath query language 发现在当前可用的 IDE 视图组件。
一旦带有 robot-server IDE 开始, 你可以打开 http://localhost:8082 页面,它在 HTML 中展示了现在的 IDEA UI 组件的层次结构格式和使用一个简单的 XPath 生成器, 他可以帮助你测试用户界面.

TIP: Run IDE for UI tests using predefined Run IDE for UI Tests and then Run Tests configurations or by invoking the ./gradlew runIdeForUiTests and ./gradlew tests Gradle tasks.

提示:使用预定义的 IDE UI 测试运行

检查项目可以使用 UI 测试例子作为参考你的插件设置 UI 测试: intellij-ui-test-robot/ui-test-example.

class MyUITest {

  @Test
  fun openAboutFromWelcomeScreen() {
    val robot = RemoteRobot("http://127.0.0.1:8082")
    robot.find(byXpath("//div[@myactionlink = 'gearHover.svg']")).click()
    // ...
  }
}

UI Testing

一个专门的 Run UI Tests 工作流 is available for manual triggering to run UI tests against three different operating systems: macOS, Windows, and Linux.
Due to its optional nature, this workflow isn’t set as an automatic one, but this can be easily achieved by changing the on trigger event, like in the Build workflow file.

Qodana integration

To increase the project value, the IntelliJ Platform Plugin Template got integrated with Qodana, a code quality monitoring platform that allows you to check the condition of your implementation and find any possible problems that may require enhancing.

为了增加项目的价值,IntelliJ 平台插件模版可以和 Qodana 进行集成,一个代码质量监测平台,允许您检查您的实现的条件和找到任何可能出现的需要提高问题,

Qodana brings into your CI/CD pipelines all the smart features you love in the JetBrains IDEs and generates an HTML report with the actual inspection status.

Qodana 带给你你的 CI\/ CD 管道所有你喜爱的 JetBrains IDEs 的智能特性并生成一个 HTML 报告与实际检验状态。

Qodana inspections are accessible within the project on two levels:

Qodana 检查可在项目中在两个层面:

Qodana inspection is configured with the qodana { ... } section in the Gradle build file, and qodana.yml YAML configuration file.

Qodana 检查配置了 qodana { ... } 部分 Gradle 构建文件,qodana.yml YAML 配置文件。

NOTE: Qodana requires Docker to be installed and available in your environment.

*注意:* Qodana 需要安装和码头工人可以在您的环境中。

运行检查,您可以使用一个预定义的运行 Qodana 配置,这将提供一个完整的报告 http://localhost:8080, 或直接与调用它的任务 ./gradlew runInspections 命令行.

最终的报告在 ./build/reports/inspections/ 目录.

Qodana

预定义的运行/调试配置

在默认的项目结构, 有 .run 目录提供包含预定义的运行/调试配置,使相应 Gradle 任务:

Run/Debug configurations

Configuration name Description
Run Plugin 运行:runIdeGradle IntelliJ 插件的任务. 使用 theDebug 按钮进行.
Run Verifications 运行:runPluginVerifierGradle IntelliJ 插件任务来检查插件对于特定的 IntelliJ IDEs 检查插件的实用性。
Run Qodana 运行:runInspectionsGradle Qodana 插件任务. 在 Docker 容器中开始 Qodana 检查并在 localhost:8080 生成报告。
Run Tests 运行:testGradle 任务.
Run IDE for UI Tests 运行:runIdeForUiTestsGradle IntelliJ 插件任务来运行在 IntelliJ IDE 运行 UI 测试

TIP: You can find the logs from the running task in the idea.log tab.

提示:你可以找到从正在运行的任务的日志 idea.log 选项卡。

Run/Debug configuration logs

持续集成

持续集成依赖于 GitHub Actions, 一组工作流程,使其可能的自动化测试和发布过程。
由于这样的自动化,可以委托测试和验证阶段持续集成 (CI),而是专注于开发(和)编写更多的测试。

.github/workflows 目录, 你可以找到以下 GitHub 操作工作流的定义:

  • Build
    • pushpull_request 事件中触发.
    • 运行 Gradle Wrapper Validation Action 来验证 wrapper’s 校验和.
    • 运行 verifyPlugintest Gradle 任务.
    • 使用 buildPlugin 编译插件,Gradle 任务并在工作流中为下一个任务提供一个新的制品。
    • 使用 *IntelliJ Plugin 验证工作验证工作.
    • 准备发布的草稿 GitHub 手动验证版本页面.
  • Release
    • 通过 released 事件触发.
    • 提供发行日志中的内容更新 CHANGELOG.md 文件.
    • 在发布之前使用提供的证书进行签名
    • 将插件 JetBrains 发布市场使用提供的 PUBLISH_TOKEN.
    • 设置发布渠道根据插件版本, i.e. 1.0.0-beta -> beta 频道
    • 补丁的更新日志和提交。
  • Run UI Tests
    • 手动触发。
    • 在 macOS、Windows 和 Linux 运行。
    • 运行 runIdeForUiTests and test Gradle tasks.
  • Template Cleanup
    • 当创建了一个新的基于模板库采用 push 事件触发 。
    • 覆盖文件从脚手架 .github/template-cleanup 目录.
    • 覆盖 JetBrains-specific 句子或包名称的特定目标库中。
    • 删除冗余文件。

所有工作流文件有精确的文档, 因此查看相关的资源是一个好的方法。

依赖关系管理

这个模板项目取决于 Gradle 插件和外部库,在开发,您将添加更多的人。

保持良好的项目和所有依赖项更新需要时间和努力,但是可以使用 Dependabot 自动化这个过程。

Dependabot GitHub 检查所提供的是一个机器人构建配置文件和审查任何过时的或不安全的依赖你的——如果任何更新可用,它创建一个新的请求提供 the proper change.

笔记:Dependabot 不支持检测 Gradle Wrapper。
检查 Gradle Releases 页面来升级 gradle.properties 文件

更新日志的维护

当发布一个更新,必须让用户知道新版本提供。
这样做的最好办法是提供发行说明。

更新日志是一个策划列表包含任何新特性信息,修复和用法。

当他们提供,这些列表可以在几个不同的地方:

There are many methods for handling the project’s changelog.

有很多的方法来处理项目的变更日志
The one used in the current template project is the Keep a Changelog approach.

其中一个是在当前的项目模版中的 Keep a Changelog 方法

The Gradle Changelog Plugin takes care of propagating information provided within the CHANGELOG.md to the Gradle IntelliJ Plugin.

Gradle Changelog Plugin 负责 在 CHANGELOG.mdGradle IntelliJ Plugin 提供的信息进行信息传播
You only have to take care of writing down the actual changes in proper sections of the [Unreleased] section.

你仅仅需要关心的是在 [Unreleased] 章节的合适的模块写下真实的变更信息。

你从一个几乎空的更新日志:

# YourPlugin Changelog

## [Unreleased]
### Added
- Initial scaffold created from [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template)

Now proceed with providing more entries to the Added group, or any other one that suits your change the most (see How do I make a good changelog? for more details).

现在处理更多的信息添加到 Added 组中,或者任何其他的合适的变化(观看 How do I make a good changelog? 查询更多的信息).

When releasing a plugin update, you don’t have to care about bumping the [Unreleased] header to the upcoming version – it will be handled automatically on the Continuous Integration (CI) after you publish your plugin.

当发布一个插件更新,你不需要关心修改 [Unreleased] 请求头到新的版本 – 它将在你发布你的插件后被自动在持续集成环境中处理。
GitHub Actions will swap it and provide you an empty section for the next release so that you can proceed with your development:

GitHub Actions 会互换它,为下一个版本提供你一个空的部分,这样您就可以开始你的开发:

# YourPlugin Changelog

## [Unreleased]

## [0.0.1]
### Added
- An awesome feature
- Initial scaffold created from [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template)

### Fixed
- One annoying bug

To configure how the Changelog plugin behaves, i.e., to create headers with the release date, see Gradle Changelog Plugin README file.

Release flow

The release process depends on the workflows already described above.

发布过程取决于上述已经被描绘的工作流。
When your main branch receives a new pull request or a direct push, the Build workflow runs multiple tests on your plugin and prepares a draft release.

当你的主要分支收到一个新的拉请求或直接推送,Build 工作流运行你的插件的多个测试,并准备一份发布草稿。

Release draft

The draft release is a working copy of a release, which you can review before publishing.

草稿发布是一个发布的工作副本,你可以回顾之前出版。

It includes a predefined title and git tag, the current plugin version, for example, v0.0.1.

它包括一个预定义的标题和 git 标签,当前插件版本,例如,v0.0.1.

使用 gradle-changelog-plugin 自动提供更新日志

在插件的附件中就几十年后附属一个编译后的文件

每一个新的构建覆盖之前的草稿来保持版本页面干净。

When you edit the draft and use the Publish release button, GitHub will tag your repository with the given version and add a new entry to the Releases tab.
Next, it will notify users who are watching the repository, triggering the final Release workflow.

当你编辑草稿并使用发布版本按钮,GitHub 将标签与给定的存储库版本并将一个新条目添加到版本标签。

接下来,它将通知关注存储库发行新版本的用户。

插件签名

Plugin Signing is a mechanism introduced in the 2021.2 release cycle to increase security in JetBrains Marketplace and all of our IntelliJ-based IDEs.

插件签名是一种在 2021.2 的发布周期增加的安全机制中用来增加 JetBrains Marketplace 的安全和我们所有的 IntelliJ-based IDEs 的安全。

JetBrains Marketplace signing is designed to ensure that plugins are not modified over the course of the publishing and delivery pipeline.

JetBrains 市场签名旨在确保插件不修改的出版和输送管道。

The current project provides a predefined plugin signing configuration that lets you sign and publish your plugin from the Continuous Integration (CI) and local environments.

当前项目提供了一个预定义的插件配置让你可以在持续集成和发布你的插件(CI)和本地环境签名。

To find out how to generate signing certificates, check the Plugin Signing section in the IntelliJ Platform Plugin SDK documentation.

为了找出如何生成签名证书, 检查在 IntelliJ Platform Plugin SDK 文档的 Plugin Signing 章节。

发布插件

Releasing a plugin to JetBrains Marketplace is a straightforward operation that uses the publishPlugin Gradle task provided by the gradle-intellij-plugin.

JetBrains 市场发行一个插件是一个简单的操作,使用在 gradle-intellij-plugin 中提供的 publishPlugin Gradle 任务。
In addition, the Release workflow automates this process by running the task when a new release appears in the GitHub Releases section.

另外,当一个新的 release 出现在 Github 发行章节时,Release 工作流自动地处理这个发布插件的工作。

TIP : Set a suffix to the plugin version to publish it in the custom repository channel, i.e. v1.0.0-beta will push your plugin to the beta release channel.

提示:设置一个后缀的插件版本发布它在自定义库通道,比如 v1.0.0-beta 将会将插件推送到 beta release channel.

The authorization process relies on the PUBLISH_TOKEN secret environment variable, specified in the Secrets section of the repository Settings .

这个认证过程依赖于在环境变量中的 PUBLISH_TOKEN 信息,在 Secrets section of the repository 设置中配置

You can get that token in your JetBrains Marketplace profile dashboard in theMy Tokens tab.

你可以在你 JetBrains 市场内容仪表板在 My Tokens 选项卡中得到你的令牌。

重要:

在使用自动化部署过程之前,需要手动创建一个新的插件在 JetBrains 市场像许可证指定选项,存储库 URL 等等。

请按 Publishing a Plugin 说明进行操作。

FAQ

如何使用 Java 在我的项目吗?

Java language is supported by default along with Kotlin.

Java 语言和 Kotlin 语言是默认支持的
最初, 这个 /src/main/kotlin 目录在自己的示例项目是默认存在的.
你仍然可以取代它或者添加 /src/main/java 目录开始使用 Java 语言。

如何使用 [skip ci] 提交信息来测试构建工作?

2021 年 2 月以来,GitHub Actionssupport the skip CI feature

如果信息中包含 [skip ci], [ci skip], [no ci], [skip actions], or [actions skip] 中的一个,工作流将不会被触发。

用户链接

评论

  1. 7月前
    2022-3-09 13:59:01

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
%d 博主赞过: