当前位置: 首页 > news >正文

在 Visual Studio Code 中添加自定义的代码片段

无论是那个编辑器,如果能够添加一些自定义代码片段,能够大大提升代码的输入效率。

本文介绍如何在 Visual Studio Code 中添加自定义代码片段。


本文内容

    • Visual Studio Code 的代码片段设置
    • 编写代码片段
    • 插入代码片段
    • 一个更复杂的例子
    • 关于代码片段编写的更多细节
      • 关于文件名称
      • 光标停留点(Tabstop)
      • 占位符
      • 下拉选项
      • 变量

Visual Studio Code 的代码片段设置

你可以在 Visual Studio Code 的菜单中找到代码片段的设置入口,在 File -> Preferences -> User Snippets 中。

打开用户代码片段设置
▲ 打开用户代码片段设置

点开后,会让你选择做什么:

  • 新建全局代码片段
  • 新建适用于当前工作区的代码片段
  • 新建特定于语言的全局代码片段

选择代码片段范围

根据你的需要选择一个范围:

  • 比如你需要在任何文件中都能够使用的代码片段,那么选择全局代码片段。
  • 比如你需要仅在当前工作区生效的代码片段(例如我写博客是才会用到的博客片段),那么选择工作区代码片段。
  • 如果是特定于语言的,那么选择自己需要的语言。

在新建全局代码片段和当前工作区的代码片段的时候,是需要自己指定名称的。

指定代码片段的名称
▲ 指定代码片段的名称

编写代码片段

无论你使用哪种方式新建代码片段,Visual Studio Code 都会帮你打开这个代码片段文件。整个文件一开始是被注释的状态,就像下面这样:

{
	// Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and 
	// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope 
	// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is 
	// used to trigger the snippet and the body will be expanded and inserted. Possible variables are: 
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. 
	// Placeholders with the same ids are connected.
	// Example:
	// "Print to console": {
	// 	"scope": "javascript,typescript",
	// 	"prefix": "log",
	// 	"body": [
	// 		"console.log('$1');",
	// 		"$2"
	// 	],
	// 	"description": "Log output to console"
	// }
}

上面的注释,翻译一下是这样的:

可以将你的全局代码片段放到这里。每一个代码片段都由一个名称来定义,其值包含此代码片段的作用域(scope)、前缀(prefix)、代码片段的内容(body)与其描述信息(description)组成。

  • scope 字段中填写以逗号分隔的作用域 Id,如果 scope 字段为空或根本没有设置,那么将适用于所有语言。
  • prefix 是用于触发代码片段的一段文字,当你输入这个文字的时候,你将可以展开这个代码片段的内容并将其插入。
  • body 你可以使用 $1 $2 来作为按下 Tab 时将切换的键盘焦点区域,$0 是插入完成后最终光标所在的位置。你也可以使用 ${1:label} 或 ${2:another} 这样的方式来增加占位符,同样 Id 的占位符将会自动关联起来。

例如,我通过以下代码片段来为我插入博客的目录:

{
	"Add toc to post": {
		"scope": "markdown",
		"prefix": "toc",
		"body": [
			"@[TOC](${1:walterlv 的目录})",
			"$0"
		],
		"description": "添加 walterlv 的博客的目录"
	}
}

插入代码片段

那么现在按下 F1 打开快捷命令输入框进入 Insert Snippet 命令,输入 toc 可以看到我们刚刚加入的代码片段:

插入代码片段

toc 片段

或者,在带有智能感知提示的文件中,可以直接通过智能感知提示插入:

通过智能感知提示插入

在插入的代码片段中,${1:walterlv 的目录} 会成为我们的第一个占位符,而且默认文字就是 walterlv 的目录

占位符效果

需要注意的是,Visual Studio Code 中 Markdown 默认是没有打开智能感知提示的。你需要在你的工作区或者全局打开它。

默认是这样的:

{
  // Configure editor settings to be overridden for [markdown] language.
  "[markdown]": {
    "editor.wordWrap": "on",
    "editor.quickSuggestions": false
  }
}

你需要把 editor.quickSuggestions 设置为 true

{
  "[markdown]": {
      "editor.quickSuggestions": true
  }
}

一个更复杂的例子

现在,我们来做一个更复杂的例子,以便了解 Visual Studio Code 中代码片段定义的更多内容。

输入 post 以便插入 blog.walterlv.com 专用的博客模板:

插入博客

在模板中,我们的的第一个焦点文字是标题,于是我们可以立刻输入博客标题:

博客标题占位符
▲ 博客标题占位符

当写完后按下 Tab 换到下一个占位符时,可以选择一些常用的选项:

选择博客分类
▲ 选择博客分类

而最后,焦点会落到博客摘要处:

最后的焦点在博客摘要
▲ 最后的焦点在博客摘要

顺便的,你可能没有注意到还有博客时间。就是那个 date 字段为空或根本没有设置,那么将适用于所有语言。

是的 代码片段中可以插入时间 和其他各种变量。

而这样的一个模板,配置文件是这样的:

{
	"Insert a post for blog.walterlv.com": {
		"scope": "markdown",
		"prefix": "post",
		"body": [
			"---",
			"title: \"${1:在此处添加标题}\"",
			"date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND} +0800",
			"categories: ${2|dotnet,csharp,uwp|}",
			"---",
			"",
			"${0:在此处编辑 blog.walterlv.com 的博客摘要}",
			"",
			"---",
			"",
			"@[TOC](本文内容)",
			"",
			"## 标题",
			"",
			"---",
			"",
			"**参考资料**"
		],
		"description": "使用 blog.walterlv.com 专用的博客模板"
	}
}

接下来我们就来说说这是怎么做出来的。

关于代码片段编写的更多细节

关于文件名称

在阅读前面的博客内容时,你可能注意到了:添加全局代码片段的时候,文件扩展名为 .code-snippets,例如 blog.code-snippets;添加语言特定的代码片段的时候,扩展名为 .json,如 markdown.json。这个规则无论在全局还是在工作区,都是一样适用的。

光标停留点(Tabstop)

使用 $1 $2 这些可以作为按下 Tab 键时的光标停留位置,而 $0 无论出现在代码片段的哪个地方,都会是最后一个光标位置。

占位符

${1:占位符 Id} 可以表示一个占位符。当你插入此代码片段的时候,会出现 占位符 Id 字样,然后光标会选中这几个字以便你进行修改。

占位符可以嵌套,例如 ${1:walterlv 的 ${2:嵌套占位符}}。这时,光标会首先选中所有的文字,随后按下 Tab 之后选中后面那一部分。

在前面那个比较复杂的博客代码片段中,${1:在此处添加标题} 就是一个占位符,而 ${0:在此处编辑 blog.walterlv.com 的博客摘要} 就是光标的最终停留点。

下拉选项

使用 ${1|选项 1,选项 2,选项 3|} 可以创建三个选项的下拉框。

在前面的博客代码片段中,${2|dotnet,csharp,uwp|} 就是一个下拉选框,帮助我选择常用的一些博客类别。

变量

使用 $变量名 或者 ${变量名:变量的默认值} 可以创建变量。

在 Visual Studio Code 中,你有这些变量可以使用:

-TM_SELECTED_TEXT
- 在插入代码片段的时刻选中的文本
-TM_CURRENT_LINE
- 在插入代码片段的时刻光标所在的行
-TM_CURRENT_WORD
- 在插入代码片段的时刻光标所在的词
-TM_LINE_INDEX
- 在插入代码片段的时刻的行号(0 为首行)
-TM_LINE_NUMBER
- 当前文档的总行数
-TM_FILENAME
- 当前文档的文件名称
-TM_FILENAME_BASE
- 当前文档不含扩展名的名称
-TM_DIRECTORY
- 当前文档所在的文件夹
-TM_FILEPATH
- 当前文档的完全路径
-CLIPBOARD
- 剪贴板中的内容
-CURRENT_YEAR
- 年
-CURRENT_YEAR_SHORT
- 两位数字显示的年
-CURRENT_MONTH
- 月,如 02
-CURRENT_MONTH_NAME
- 月的英文名称,如 July
-CURRENT_MONTH_NAME_SHORT
- 月的英文缩写,如 Jul
-CURRENT_DATE
- 日
-CURRENT_DAY_NAME
- 星期的英文名称,如 Monday
-CURRENT_DAY_NAME_SHORT
- 星期的英文缩写,如 Mon
-CURRENT_HOUR
- 24 小时制的时
-CURRENT_MINUTE
- 分
-CURRENT_SECOND
- 秒

所以在上面比较复杂的博客模板中,我们可以直接插入当前的时间 ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND} +0800

这个时间我之前也在输入法中调过:常用输入法快速输入自定义格式的时间和日期(搜狗/QQ/微软拼音)。


参考资料

  • Creating your own snippets in Visual Studio Code

我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • 用 dotTrace 进行性能分析时,Timeline 打不开?无法启动进程?也许你需要先开启系统性能计数器的访问权限
  • 了解 .NET/C# 程序集的加载时机,以便优化程序启动性能
  • git 如何更可靠地解决冲突?
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • 文件被占用?系统自带的“资源监视器(resmon)”也能帮你找到占用它的真凶
  • Windows 系统文件资源管理器的命令行参数(如何降权打开程序,如何选择文件)
  • 为 .NET 各种开发工具设置网络代理,提升在大陆的网络性能
  • 如何在旧版本的 .NET Core / Framework 中使用 C# 8 的异步流(IAsyncDisposable / IAsyncEnumerable / IAsyncEnumerator)
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • 为什么实现 .NET 的 ICollection 集合时需要实现 SyncRoot 属性?如何正确实现这个属性?
  • 为什么不应该公开用来同步的加锁对象?为什么不应该 lock(this)/lock(string) 或者 lock 任何非私有对象?
  • WPF 中如何创建忽略 DPI 属性的图片
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • Win32 方法 CreateFile 中选择合适的文件打开模式(CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING, OPEN_ALWAYS, TRUNCATE_EXI
  • 使用 Kestrel 为你的 ASP.NET Core 服务添加 https 支持
  • #Java异常处理
  • CAP 一致性协议及应用解析
  • CentOS6 编译安装 redis-3.2.3
  • co.js - 让异步代码同步化
  • CSS实用技巧
  • ECMAScript6(0):ES6简明参考手册
  • EOS是什么
  • iOS编译提示和导航提示
  • JavaScript 奇技淫巧
  • Java超时控制的实现
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • underscore源码剖析之整体架构
  • win10下安装mysql5.7
  • 订阅Forge Viewer所有的事件
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 优秀架构师必须掌握的架构思维
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • #13 yum、编译安装与sed命令的使用
  • #pragma multi_compile #pragma shader_feature
  • $(function(){})与(function($){....})(jQuery)的区别
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (2.2w字)前端单元测试之Jest详解篇
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (二)c52学习之旅-简单了解单片机
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • ***测试-HTTP方法
  • .bat批处理(一):@echo off
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .NET Core中Emit的使用
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET 常见的偏门问题
  • .net 程序发生了一个不可捕获的异常
  • .NET6实现破解Modbus poll点表配置文件