# Add code snippets for CLANG in VS Code
> **前记**:在VS Code中自定义snippets用户代码段的方法。
* * *
* [Add code snippets for CLANG in VS Code](http://blog.csdn.net/maokelong95/article/details/54379046#add-code-snippets-for-clang-in-vs-code)
* [什么是 snippet](http://blog.csdn.net/maokelong95/article/details/54379046#什么是-snippet)
* [如何配置snippet](http://blog.csdn.net/maokelong95/article/details/54379046#如何配置snippet)
* [操作流程](http://blog.csdn.net/maokelong95/article/details/54379046#操作流程)
* [VSCode中snippet的文法1](http://blog.csdn.net/maokelong95/article/details/54379046#vscode中snippet的文法1)
* [有用的建议](http://blog.csdn.net/maokelong95/article/details/54379046#有用的建议)
## 什么是 snippet
`snippet[ˈsnɪpɪt]`,或者说`code snippet`,指的是能够帮助输入重复代码模式串,比如循环或条件语句的**模板**。通过`snippet`,仅仅输入一小段代码就可以生成预定义的模板代码,甚至可以通过内部跳转快速补全模板。
当然,看图更易懂:
![snippet示例](http://img.blog.csdn.net/20170112141959764?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFva2Vsb25nOTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
图中将`atc`替换成了定义ActiveSupport::TestCase(简称ATC)子类的模板,并跳转到`case_name`处进行了修改 .etc.
## 如何配置snippet
### 操作流程
1. 进入snippet设置文件
这里提供了两种方法:
1. 按`alt`键切换菜单栏,通过**文件**>**首选项**>**用户代码片段**,选择进入目的语言的代码段设置文件;
2. 通过快捷键`ctrl`+`shift`+`P`打开命令窗口(all command window),输入`snippet`,通过候选栏中的选项进入目的语言的代码段设置文件。
2. 填写snippets
### VSCode中snippet的文法[1](http://blog.csdn.net/maokelong95/article/details/54379046#fn:vscode "See footnote")
设置文件头部通过一个块注释讲解了snippet的文法,了解`json`就不会对此感到奇怪了。
~~~
// Place your snippets for C here. Each snippet is defined under a snippet name and has a prefix, body and
// description. 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": {
"prefix": "log",,
"body": [
"console.log('$1');",
"$2"
],
"description": "Log output to console"
}
~~~
上例snippet在输入log后效果如下,在确定后将替换为`console.log('');`。
![log](http://img.blog.csdn.net/20170112145950068?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFva2Vsb25nOTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
snippet由三部分组成:
* **prefix**:前缀,定义了snippets 从IntelliSense中呼出的关键字;
* **body**: 主体,即模板的主体内容,每个字符串表示一行;
* **description**:说明,会在IntelliSense候选栏中出现。未定义的情况下显示对象名,上例中将会显示`Print to console`。
其中**body**部分可以使用特殊结构来控制光标和要插入的文本。 支持的功能及其文法如下:
* **Tabstops**:制表符
用`Tabstops`可以让编辑器的指针在代码段内跳转。使用`$1`,`$2` .etc. 指定光标位置。这些数字指定了`Tabstops`将被访问的顺序,而`$0`表示最终光标位置。同序`Tabstops`被链接在一起,并将同步更新,比如下列用于生成头文件封装的snippet打印在编辑器上时,指针就将同时出现在`$1`位置以进行多列编辑。
~~~
"#ifndef $1"
"#define $1"
"#end // $1"
~~~
* **Placeholders**:占位符
`placeholder`是带有默认值的`Tabstops`,如`${1:foo}`。 `placeholder`文本将被插入`Tabstops`位置,并在跳转时被全选,以方便轻松更改。占位符还可以嵌套,例如`${1:another ${2:placeholder}}`。
比如结构体的snippet主体可以这样写:
~~~
struct ${1:name_t} {\n\t$2\n};
~~~
作为`Placeholder`的`name_t`一方面可以提供默认的结构名称,另一方面可以作为输入的提示。
* **Variables**:变量
使用`$name`或`${name:default}`可以插入变量的值。 当未设置变量时,将插入其缺省值或空字符串。 当`varibale`未知(即,其名称未定义)时,将插入变量的名称,并将其转换为`placeholder`。 可以使用以下`Variable`:
* `TM_SELECTED_TEXT`:当前选定的文本或空字符串
* `TM_CURRENT_LINE`:当前行的内容
* `TM_CURRENT_WORD`:光标下的单词的内容或空字符串
* `TM_LINE_INDEX`:基于零索引的行号
* `TM_LINE_NUMBER`:基于一索引的行号
* `TM_FILENAME`:当前文档的文件名
* `TM_DIRECTORY`:当前文档的目录
* `TM_FILEPATH`:当前文档的完整文件路径
注意,这些都是变量名,不是宏,在实际使用的时候还是要加上$符的。
官网也给出了snippet的EBNF范式的正则文法,注意,使用`\`(反斜杠)转义`\$`, `,`, `}`和`\`。
~~~
any ::= tabstop | placeholder | variable | text
tabstop ::= '$' int | '${' int '}'
placeholder ::= '${' int ':' any '}'
variable ::= '$' var | '${' var }' | '${' var ':' any '}'
var ::= [_a-zA-Z] [_a-zA-Z0-9]*
int ::= [0-9]+
text ::= .*
~~~
### 有用的建议
默认情况下snippet在IntelliSense中的显示优先级并不高,而且要在IntelliSense中选择相应snippet需要敲击enter,这对于手短的人来说并不是什么很好的体验。所幸,VSCode意识到了这一点,并为我们提供了改进的方式。
在VSCode的**用户设置**(ctrl+P在输入框中写`user settings`后点选)中,检索**代码段**,然后根据提示修改,设置建议优先显示,并且可以通过`TAB`补全snippet。
![修改设置](http://img.blog.csdn.net/20170112155152376?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFva2Vsb25nOTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
修改后设置文件中会多出这两行:
~~~
"editor.snippetSuggestions": "top",
"editor.tabCompletion": true
~~~