[VS Code]跟我一起在Visual Studio Code 添加自定义snippet(代码段),附详细配置
来源:互联网 发布:手机淘宝取消私人定制 编辑:程序博客网 时间:2024/05/01 02:31
Add code snippets for CLANG in VS Code
前记:今天试着用了下 Atom,发现 Atom 居然预装了 CLANG 的 snippets,而且远比 VSCode 的已有拓展「C/C++ Snippets」中的丰富!身为 VSCode 的死忠粉,我决定立马把 Atom 的 C snippets 搬到 VSCode 上来。
- Add code snippets for CLANG in VS Code
- 什么是 snippet
- 如何配置 snippet
- 操作流程
- VSCode 中 snippet 的文法 1
- 有用的建议
- 附录
既然你点开了这个页面,就说明要么你不知道 VSCode 上已有拓展「C/C++ Snippets」,要么你对这个拓展失望透顶。对于后者,本文将为你介绍如何在 VSCode 上设置 snippets,并为你提供一套可以直接用的C语言 snippets。
什么是 snippet
snippet[ˈsnɪpɪt],或者说「code snippet」,指的是能够帮助输入重复代码模式串,比如循环或条件语句,的模板。通过 snippet ,我们仅仅输入一小段代码就可以生成预定义的模板代码,甚至可以通过内部跳转快速补全模板。
当然,看图更易懂:
图中将 atc
替换成了定义 ActiveSupport::TestCase
(简称 ATC )子类的模板,并跳转到「case_name」处进行了修改。
如何配置 snippet
操作流程
- 进入 snippet 设置文件
这里提供了两种方法:- 按「Alt」键切换菜单栏,通过文件 > 首选项 > 用户代码片段,选择进入目的语言的代码段设置文件;
- 通过快捷键「Ctrl + Shift + P」打开命令窗口(all command window),输入「snippet」,通过候选栏中的选项进入目的语言的代码段设置文件。
- 填写 snippets
VSCode 中 snippet 的文法 1
设置文件头部的一个块注释给出了设置 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('');
,效果预览如下:
snippet 由三部分组成:
- prefix:前缀,定义了 snippets 从 IntelliSense 中呼出的关键字;
- body: 主体,即模板的主体内容,其中每个字符串表示一行;
- description:说明,会在 IntelliSense 候选栏中出现。未定义的情况下直接显示对象名,上例中将会显示
Print to console
。
其中 body 部分可以使用特殊结构来控制光标和要插入的文本。 支持的功能及其文法如下:
Tabstops:制表符
用「Tabstops」可以让编辑器的指针在 snippet 内跳转。使用
$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。
修改后设置文件中会多出这两行:
"editor.snippetSuggestions": "top","editor.tabCompletion": true
附录
注:我对 Atom 的 C snippet2 作了修改,使之更适合我的习惯,若有兴致你可自行修改,反正也不难。
{/* // 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" }*/ "#ifndef … #define … #endif":{ "prefix": "def", "body": "#ifndef ${1:SYMBOL}\n#define $1 ${2:value}\n#endif\t// ${1:SYMBOL}" }, "#include <>":{ "prefix": "Inc", "body": "#include <${1:.h}>" }, "#include \"\"":{ "prefix": "inc", "body": "#include \"${1:.h}\"" }, "#pragma mark":{ "prefix": "mark", "body": "#if 0\n${1:#pragma mark -\n}#pragma mark $2\n#endif\n\n$0" }, "main()":{ "prefix": "main", "body": "int main(int argc, char const *argv[]) {\n\t$1\n\treturn 0;\n}" }, "For Loop":{ "prefix": "for", "body": "for (${1:i} = 0; ${1:i} < ${2:count}; ${1:i}${3:++}) {\n\t$4\n}" }, "Define and For Loop":{ "prefix": "dfor", "body": "size_t ${1:i};\nfor (${1:i} = ${2:0}; ${1:i} < ${3:count}; ${1:i}${4:++}) {\n\t$5\n}" }, "Header Include-Guard":{ "prefix": "once", "body": "#ifndef ${1:SYMBOL}\n#define $1\n\n${2}\n\n#endif /* end of include guard: $1 */\n" }, "Typedef":{ "prefix": "td", "body": "typedef ${1:int} ${2:MyCustomType};" }, "Typedef Struct":{ "prefix": "tst", "body": "typedef struct ${1:StructName} {\n\t$2\n}${3:MyCustomType};" }, "Do While Loop":{ "prefix": "do", "body": "do {\n\t$0\n} while($1);" }, "While Loop":{ "prefix": "while", "body": "while ($1) {\n\t$2\n}" }, "fprintf":{ "prefix": "fprintf", "body": "fprintf(${1:stderr}, \"${2:%s}\\\\n\", $3);$4" }, "If Condition":{ "prefix": "if", "body": "if ($1) {\n\t$2\n}" }, "If Else":{ "prefix": "ife", "body": "if ($1) {\n\t$2\n} else {\n\t$3\n}" }, "If ElseIf":{ "prefix": "iff", "body": "if ($1) {\n\t$2\n} else if ($3) {\n\t$4\n}" }, "If ElseIf Else":{ "prefix": "iffe", "body": "if ($1) {\n\t$2\n} else if ($3) {\n\t$4\n} else {\n\t$5\n}" }, "Switch Statement":{ "prefix": "sw", "body": "switch ($1) {\n$2default:\n\t${3:break;}\n}$0" }, "case break":{ "prefix": "cs", "body": "case $1:\n\t$2\n\tbreak;\n$0" }, "printf":{ "prefix": "printf", "body": "printf(\"${1:%s }\\n\", $2);$3" }, "scanf":{ "prefix": "scanf", "body": "scanf(\"${1:%s}\\n\", $2);$3" }, "Struct":{ "prefix": "st", "body": "struct ${1:name_t} {\n\t$2\n};" }, "void":{ "prefix": "void", "body": "void ${1:name}($2) {\n\t$3\n}" }, "any function":{ "prefix": "func", "body": "${1:int} ${2:name}($3) {\n\t$5\n\treturn ${4:0};\n}" }, "write file":{ "prefix": "wf", "body": "FILE *${1:fp};\n${1:fp} = fopen (\"${2:filename.txt}\",\"w\");\nif (${1:fp}!=NULL)\n{\n\tfprintf(${1:fp},\"${3:Some String\\\\n}\");\n\tfclose (${1:fp});\n}" }, "read file":{ "prefix": "rf", "body": "FILE *${1:fp};\n${1:fp} = fopen (\"${2:filename.txt}\",\"r\");\nif (${1:fp}!=NULL)\n{\n\tfscanf(${1:fp},\"${3:Some String\\\\n}\", ${3:&var});\n\tfclose (${1:fp});\n}", "description": "read file opeartion including fopen, fscanf and fclose." }}
- https://code.visualstudio.com/Docs/customization/userdefinedsnippets ↩
- https://github.com/atom/language-c/blob/master/snippets/language-c.cson ↩
- [VS Code]跟我一起在Visual Studio Code 添加自定义snippet(代码段),附详细配置
- [VS Code]跟我一起在Visual Studio Code 添加自定义snippet(代码段),附详细配置
- Visual Studio Code 添加设置代码段(snippet)
- Visual Studio Code 添加设置代码段(snippet)
- Visual Studio Code 自定义Snippet配置
- vscode创建vue模板,添加自定义snippet(代码段),附详细配置
- VS中Code Snippet 代码段
- 使用Code Snippet在Xcode中添加代码段
- Xcode使用Code Snippet在Xcode中添加代码段
- 使用Code Snippet在Xcode中添加代码段
- 自定义Visual Studio中的code snippet
- vs code (visual studio code)配置git和markdown
- visual studio code snippet editor使用
- 自定义Xcode代码模板:Code Snippet
- 【Xcode使用技巧】xcode 使用Code Snippet 添加自己常用的代码段
- Visual Studio Code配置
- VS Code 编写代码段
- 使用C#代码段,提高工作效率(C# code snippet)
- MySQL去除查询结果重复值
- KVC 和KVO的使用
- monkey高级参数及命令格式
- C指针
- 谈谈Linux打补丁的原理以及如何判别打补丁的错误 --- 从补丁学内核
- [VS Code]跟我一起在Visual Studio Code 添加自定义snippet(代码段),附详细配置
- ubuntu
- 秒杀业务分析
- mysql 中文乱码的问题解决方法
- 软件设计——UML类图详解
- 随手记 -- xcode上使用预编译宏
- harris角点及二次型
- 【leetcode】125. Valid Palindrome【java】
- leedcode461:Hamming Distance