我们之前介绍过缩写相关的内容,缩写是可以自动帮我们将缩写的单词展开成一段完整的话。但是代码本身是结构话的,仅仅使用缩写来配置是无法完成自动生成代码这个步骤的。好在我们大量的插件来进行配置。本篇我们将要来讨论如何使用相关插件来完成代码片段自动完成的功能

vsnip 插件

我们之前在配置自动补全的时候已经下载了 vim-vsnip这个插件。

vsnip是一个非常强大的插件,它支持我们使用与 VS Code 类似的方式来扩展定义我们自己的代码片段,同时它也内置了不同语言版本的代码片段。在之前的配置中我们还加了另外一个 friendly-snippets 。它提供了丰富的已定义好的可以直接使用的代码片段,加快了我们的编码效率。在前面介绍补全的时候我们已经安装并配置了它们。它们的效果如下图所示:

自定义代码片段

虽说这些插件预定义了大量的代码片段。但是他们都是通用型的代码片段,总有那么些时候无法满足我们的需求。一个明显的例子就是不同的公司有不同的代码和注释的风格。这个时候就需要我们自定义了。本篇也准备将重点放在如何自定义代码片段上。如果小伙伴们已经有了在 vscode 上自定义代码片段的经历,那么请跳过本篇以节省各位的时间。

入门

下面我们以 C 为例来说明如何自定义代码片段来满足我们的需求。其他语言只是填入的内容不同,在定义上并没有什么大的差别。这里我采用 C 语言一个原因是静态类型的语言更方便的演示其中的各项功能,另一个原因就是我对C/C++ 比较熟悉

首先我们要找到代码片段的配置文件所在位置,这个位置保存在变量 g:vsnip_snippet_dir 中。我们可以通过 :echo g:vsnip_snippets_dir 找到它。

当然也有更简单的办法,我们可以执行 :VsnipOpen 来打开该语言对应的配置文件,如果该文件不存在,命令将创建一个以对应语言名称命名的 json 文件,例如这里它会创建一个 c.json 的文件

这里我们先来写一个最简单的代码片段——自动生成一个 Hello WorldC 程序

"example": {
"prefix": ["hello"],
"body": [
"#include <stdio.h>",
"int main(int argc, char* argv[])",
"{",
"\tprintf(\"hello world\");",
"\treturn 0;",
"}"
],
"description": "create a hello world"
}

我们来试试效果,输入 hello 将自动生成一段代码



现在我们来看看这些字段都代表什么含义

  • example:它代表该代码段的名称,也可以认为它是一个id,用于标识一个代码片段
  • prefix:用于触发该代码片段,这里也就是我们输入 hello将会触发补全,当选择对应项的时候会调用该代码片段进行补全
  • body:补全时自动生成的代码。它可以是一个字符串或者字符数组。虽然它本身也支持 \r\n来进行换行。但是我更倾向于使用字符数组的形式,每一行是数组中的一个字符串。
  • description :描述信息

使用占位符

如果我们仅仅只能生成像上述 hello world 那样给写死的代码的话,那么它也没什么太大的用处。有时候我们的代码需要生成一个模板,关键地方应该由我们自己进行填充。这个时候可以用到占位符,例如我们使用下面的来生成一个函数

"ifunc": {
"prefix": ["ifunc"],
"body": [
"int $1()",
"{",
"\treturn 0;",
"}"
],
"description": "create a function return int"
}
}

占位符内容可选

我们现在已经可以生成函数了,但是有一个问题摆在我们的面前。函数的返回类型多种多样,如果我们每一个类型都定义一个片段,例如 返回 int 的定义一个 ifunc,返回 float 的定义一个 ffunc。显得多此一举了,代码的重复度太高了。这个时候我们我们给占位符一些预选项以供我们选择。它的语法格式如下

${1|sel1, sel2, sel3,...|}

前面的1代表是第一个占位符。如果是后面的占位符需要提供选项,那么就可以依次类推

例如我们将上述生成函数的代码片段改为

"func": {
"prefix": ["func"],
"body": [
"${1|int,float,double,char,short,*|} $2()",
"{",
"\treturn $3;",
"}"
],
"description": "create a function"
}
}

占位符间跳转

生成函数的代码片段中有3个占位符,其中第一个是可以选的,第二个第三个需要我们手动填写。按照习惯,我们一般使用 <Tab> 键来进行跳转,但是这个时候我们发现它没有用。vsip 有自己的命令来跳转到占位符,因此为了保持使用习惯不变,我们需要定义快捷键

vim.cmd[[imap <expr> <Tab>   vsnip#jumpable(1)   ? '<Plug>(vsnip-jump-next)'      : '<Tab>']]
vim.cmd[[smap <expr> <Tab> vsnip#jumpable(1) ? '<Plug>(vsnip-jump-next)' : '<Tab>']]
vim.cmd[[imap <expr> <S-Tab> vsnip#jumpable(-1) ? '<Plug>(vsnip-jump-prev)' : '<S-Tab>']]
vim.cmd[[smap <expr> <S-Tab> vsnip#jumpable(-1) ? '<Plug>(vsnip-jump-prev)' : '<S-Tab>']]

由于该插件是使用 vimscript 脚本写的,它还没有提供 lua 的接口,因此这里我也就使用 vimscript 的方式来定义快捷键。

使用变量

使用语法 $name 或者 ${name: default} 可以插入一个变量。如果未设置变量,则会插入其默认值或空字符串。当变量未知(未定义其名称)时,会将插入的变量名称转换为占位符。这里的变量一般是环境变量或者是 vim 自带的一些变量。我们直接拿来用但是在不同的环境下得到的结果是不一样的。

我们可以使用变量来丰富一些信息。例如我们使用下面的代码片段来生成注释

"doc-header": {
"prefix": ["doc-header"],
"body": [
"/**",
"* @file ${TM_FILENAME}",
"* @bref ${1}",
"* @details ${2}",
"* @date ${CURRENT_YEAR}/${CURRENT_MONTH}/${CURRENT_DATE}",
"* @commit history:",
"* \t v${3}: ${4}",
"*/${0}"
],
"description": "create a doc header"
}

这样我们就生成了一个 .cpp 文件开头的注释了。其中用到了 TM_FILENAME 来表示文件名,使用 CURRENT_YEAR CURRENT_MONTH CURRENT_DATE 来分别获取到年月日。它的效果如下:



这里的 ${0} 一般用来截断 Tab键的跳转,也就说遇到 ${0} 之后 <Tab> 键就不再起到跳转到下一个占位符位置这个作用了。

具体有哪些变量可以使用,可以参考 visual studio code 官方给出的文档

本篇主要谈论了该如何定义自己的代码片段。如果想要更完整的内容可以参考 Visual Studio Code 官方的文档。我们也可以从Visual Studio Code 相关代码片段中 Copy 部分来进行使用。

从零开始配置vim(27)——代码片段的更多相关文章

  1. VS Code 折腾记 - (6) 基本配置/快捷键定义/代码片段的录入(snippet)

    前言 本来分成三篇来写的,但是想了想没必要,大家都是聪明人...简单的东西点一下就晓得了. 基本配置 快捷键自定义(Ctrl+K Ctrl + S) 那个when支持条件表达式返回一个布尔值 支持的快 ...

  2. VSCode 自定义代码片段

    Ctrl+Shift+P 输入"代码片段:配置用户代码片段": 搜索你想要设置的语言代码片段,比如,我设置 .vue 文件的代码片段,选择 vue.json: 可以配置多个代码片段 ...

  3. vim 代码片段:通过vundle插件管理器安装ultisnips |centos6.5|vim7.2

    背景:中午醒来,饭都没吃,突然想到要给vim增加个代码片段的功能,因为昨天使用了gedit的代码片段,感觉不错.为什么不直接使用gedit呢?因为我相信把时间投入到vim是不会错的,精通vim就好了. ...

  4. VSCode保存插件配置并使用 gist 管理代码片段

    setting sync 保存配置 由于公司和家里都使用 VSCode 作为主要编辑器,同步配置是最紧要的.VSCode 提供了setting sync插件,很方便我们同步插件配置.引用网上教程: 在 ...

  5. notepad++ quicktext插件安装与代码片段配置[quicktext v0.2.1]

    1 下载quicktext插件0.2.1版本 http://sourceforge.net/projects/quicktext/ 2 解压 3 把QuickText.ANSI.dll和QuickTe ...

  6. latex在vim中的代码片段

    Gilles Castel写的vim中使用的代码片段,质量很高,原文:https://github.com/gillescastel 下载后,存放到 ~/.vim/plugged/ultisnips/ ...

  7. vscode中配置代码片段

    首先我们需要把要配置的代码复制一下,如: 然后我们进入https://snippet-generator.app/网站, 进入网站之后就把你复制的代码粘贴到左边的框里面,然后就是代码的类型和命名了 写 ...

  8. 配置代码片段问题 Invalid characters in string. Control characters must be escaped.

    在使用代码片段时报错 Invalid characters in string. Control characters must be escaped. " somethings" ...

  9. 46 个非常有用的 PHP 代码片段

    在编写代码的时候有个神奇的工具总是好的!下面这里收集了 40+ PHP 代码片段,可以帮助你开发 PHP 项目. 这些 PHP 片段对于 PHP 初学者也非常有帮助,非常容易学习,让我们开始学习吧- ...

  10. 【转】46 个非常有用的 PHP 代码片段

    1. 发送 SMS 在开发 Web 或者移动应用的时候,经常会遇到需要发送 SMS 给用户,或者因为登录原因,或者是为了发送信息.下面的 PHP 代码就实现了发送 SMS 的功能. 为了使用任何的语言 ...

随机推荐

  1. 将MyBatis Mapper xml 放到 jar 包外面

    在不改程序的情况下,修改 sql 时,需要将 Mapper 中的 XML 文件 放到外面 mybatis:    mapper-locations: classpath:mapper/*.xml #J ...

  2. JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)

    JProfiler(Java性能分析神器) v11.1.4 下载 安装目录不要有空格 安装成功后,在 Intellij 里面选择对应的 jprofiler.exe 路径 点击下图JProfiler图标 ...

  3. 别再问我 2050 可以干什么,Make a Movie in a Day!

    2050 的每个年青人都是新物种.越是不可能见面的人见了面,就越会有奇迹发生,2050 努力让年青人见上另一位年青人,激发新的创造力.一起来 2050 看看? 2050 是什么? 2050 大会是由阿 ...

  4. LiveData的用法

    一.实时数据LiveData 在上一节中,我们学习了ViewModel,了解到ViewModel的主要作用是存放页面所需要的各种数据.我们在示例代码中定义了接口,当数据发生变化的时候,采用接口的方式实 ...

  5. 一个非常轻量级的 Web API Demo

    一个非常轻量级的 Web API Demo,代码量很少,实现了方法拦截器,token校验,异常拦截器,缓存 创建项目:如果选择Web API,项目中东西会比较多,这里选择Empty,把下面的Web A ...

  6. [Noip2012] 开车旅行 (倍增DP,难)

    题目链接:https://ac.nowcoder.com/acm/contest/1047/A Description 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且 ...

  7. redis命令Incr做计数器 + 切点切面

    Redis Incr 命令将 key 中储存的数字值增一. 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作. package com.example.apid ...

  8. 如何让 Llama2、通义千问开源大语言模型快速跑在函数计算上?

    本文是"在Serverless平台上构建AIGC应用"系列文章的第一篇文章. 前言 随着ChatGPT 以及 Stable Diffusion,Midjourney 这些新生代 A ...

  9. 三、java连接mongo数据库

    系列导航 一.linux单机版mongo安装(带密码验证) 二.mongo集群搭建 三.java连接mongo数据库 四.java对mongo数据库增删改查操作 五.mongo备份篇 mongoexp ...

  10. freeswitch通过limit限制cps

    概述 freeswitch在业务开发中有极大的便利性,因为fs内部实现了很多小功能,这些小功能组合在一起,通过拨号计划就可以实现很多常见的业务功能. 在voip云平台的开发中,我们经常会碰到资源的限制 ...