vscode用法

工欲善其事,必先利其器。vscode是一个值得花费时间去掌握精通的编辑器。

好文档不必远求

打开vscode,把菜单看上三遍,仔细思考每个菜单项的作用,思考为啥要这样归类每个菜单项。

配置是系统的核心

"文件/首选项"这个菜单至关重要,它包括如下四大块配置功能:

  • 设置
  • 快捷键
    快捷键设置分为两类:1)系统提供的菜单项的快捷键;2)使用现有的keymap映射,如vim、idea、sublime等流行编辑器
    vscode的快捷键必然是从快捷键到command的映射,而command并不是可执行文件,而是可以在ctrl+shift+p中看到的命令。
  • 代码片段snippets
    snippets是一些代码片段,这些代码片段可以通过前缀来触发。可以给不同的语言设置不同的代码片段,下面的文件就是给java设置的代码片段。
{
	"sout": {
		"prefix": "sout",
		"body": [
			"System.out.println($1);",
			"$2"
		],
		"description": "打印"
	},
	"cla": {
		"prefix": "class",
		"body": [
			"public class $1 {
	$2
}"
		],
		"description": "定义类"
	},
	"main": {
		"prefix": "main",
		"body": [
			"public static void main(String[]args){
	$1
}"
		],
		"description": "定义main函数"
	}
}

prefix就是触发条件,body就是插入的代码片段,description是一些提示性内容。在body中可以使用$数字的形式表示光标位置,使用tab键可以逐个到达$数字所在的位置。

  • 主题:包括整体样式主题和文件图标主题两部分。样式主题有浅色、深色、高对比度三大类,每个大类又包含若干小类。

牢记常用快捷键

ctrl+P:打开文件
ctrl+shift+P:打开命令面板,这个快捷键堪称最有用的快捷键。快捷键的缺点在于1)键少容易冲突;2)难于记忆。使用命令面板,我们只需要记忆简短的命令,既快又准。
ctrl+shift+E:打开文件资源管理器(Exploerer)
ctrl+shift+D:打开调试窗口(Debug)
ctrl+shift+G:代开Git窗口
ctrl+shift+X:打开包管理工具
ctrl+B:隐藏侧边栏
ctrl+`:打开控制台

把界面布局中无关的视图全部关闭,当需要某些视图时使用快捷键调出。

vscode相关的目录

/Program Files/Microsoft VS Code

vscode默认的安装位置。

  • bin:一些命令
  • locale:一些语言包
  • resources:包括vscode自带的插件,界面所需要的一些资源,vscode所需要的其它node模块(vscode是用nodejs运行的)
  • 其它文件是一些动态链接库和exe

.vscode

每个打开的文件夹都可以有单独的配置,存放在.vscode中,主要包括launch.json、tasks.json、settings.json,分别是调试器设置、任务设置、项目本身的设置(会覆盖全局的settings.json)。

~/.vscode

在~/.vscode目录下,extensions存放了已安装的扩展,想要学习如何编写扩展,直接看这个文件夹就可以了。

~/AppData/Roaming/Code

在~/AppData/Roaming/Code下,文件夹包括备份、缓存、日志、cookie、用户配置等信息,其中用户配置文件件User是最重要的,它包括:

  • snippets:为各种语言设定的snnippets,每种语言都对应一个json文件
  • keybindings.json:用户自定义的命令和快捷键
  • locale.json:语言设置
  • settings.json:用户修改之后的配置

portable模式

vscode意识到了有太多文件夹不够简洁清晰,于是vscode提供了portable(便携)模式,这种模式把所有数据文件都集中放在一个文件夹中。好处是便于移动,换环境之后免于重新配置(即便不是便携模式,也能够通过复制相关文件夹的方式实现复制vscode配置);坏处是注册表、路径需要自己手动更新,需要手动设置许多文件关联。

关于portable的模式的安装方法详见:https://code.visualstudio.com/docs/editor/portable

大概步骤如下:

  • 下载zip安装包
  • 把当前的~/.vscode和%APP_DATA%/Code复制到解压后的安装包的data目录

修改主题

vscode内置了许多主题,这些主题都是通过json文件指定的。vscode在界面上并没有提供修改主题文件的功能,但我们可以通过修改文本文件的方式来修改细节,例如:把注释颜色调为较亮的绿色。只需要修改vscode安装目录下的主题文件即可:C:Program FilesMicrosoft VS Code esourcesappextensions heme-monokai hemes

修改内置界面

vscode的设置并没有提供菜单栏、侧边栏的字体设置。但是我们可以通过修改
C:Program FilesMicrosoft VS Code esourcesappoutvsworkbenchworkbench.main.css文件来实现界面定制。
其中文件导航侧边栏的css选择器为:

.monaco-workbench>.part>.content{
  font-size:16px;
  font-family:"微软雅黑";
  line-height: 18px;
}

自定义task

好的系统都是开放的,vscode通过task和extension两种方式向用户开放。

一个例子

打开命令面板,configure task命令设置task,会在当前目录的.vscode目录下生成一个tasks.json。再次打开命令面板,task run build命令会执行build过程,这个命令的快捷键为ctrl+shift+B。这是会自动打开控制台执行设定的命令。

task自动探测

如果为每个项目都设置很多task,那将会非常费事。而现有的一些构建工具如make、npm、maven等已经包含了很多命令,vscode正在和这些工具集成起来。例如使用npm时,在package.json中定义了run命令,就可以直接通过命令面板执行run命令,不需要更改tasks.json。

目前vscode只把前端的npm、gulp、grunt等工具的可执行任务集成进来了。

使用自定义的命令

假设在scripts文件夹下有一个test命令,我们需要运行这个命令。

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Run tests",
            "type": "shell",
            "command": "./scripts/test.sh"
        }
    ]
}

task中的部分字段的含义如下:

  • label:命令的名称,用于在界面中展示
  • type:命令的类型,可取值为shell和process。shell会打开控制台并打印信息,process则只启动一个进程执行并不打印信息。
  • command:实际上需要执行的命令,可以是各种可执行文件。
  • windows、osx、linux:这三个都是是字典类型的字段,在不同的操作系统下task的配置可能有差异,解析时会使用操作系统定义的字段中的内容覆盖掉task其它字段。
  • group:任务也是有组的,把任务分成若干个组更加清晰。最常见的组是生命周期,maven中的构建过程分为compile、build、test、deploy等生命周期,每个生命周期包含若干个命令。
  • problemMatcher:将此字段设为[]可以避免每次选择是否查看输出

关于task.json的配置细节,参考:https://code.visualstudio.com/docs/editor/tasks-appendix

把若干个小命令组合起来

有向无环图DAG在工程界很受欢迎,似乎任何项目中都无法避开有向无环图。原因是因为:好项目必定复杂,复杂必定很大,大则需要拆分,拆分之后会得到一堆小组件,小组件之间必有依赖,有依赖的项目必然构成一个有向无环图,如果有环就变成死循环了。

vscode中的若干个task也可以组合起来。这通过task的dependOn字段来实现。利用这个字段就能够把一系列task串联起来实现逐步构建。

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Client Build",
            "command": "gulp",
            "args": ["build"],
            "options": {
                "cwd": "${workspaceRoot}/client"
            }
        },
        {
            "label": "Server Build",
            "command": "gulp",
            "args": ["build"],
            "options": {
                "cwd": "${workspaceRoot}/server"
            }
        },
        {
            "label": "Build",
            "dependsOn": ["Client Build", "Server Build"]
        }
    ]
}

然而,我认为这个功能很鸡肋,这已经超出了vscode的职责范围了,没有dependOn我们照样写出逐步构建的代码,完全可以把depend的一些命令写在一个shell脚本中。

problem matcher

vscode task的一个重要作用就是语法检测,在编辑代码时,这些问题检测程序一直在执行,vscode需要读取这些语法检测程序的输出并可视化的展示给用户。

problem matcher相关的内容较多,设计也很复杂,详见参考资料。

给任务绑定快捷键

{
    "key": "ctrl+h",
    "command": "workbench.action.tasks.runTask",
    "args": "Run tests"
}

给任务绑定的快捷键command都是相同的,只有args不同,args参数对应task的label字段。
在vscode中,最好不要给task绑定快捷键,因为keybinding.json是一个全局文件,.vscode文件夹中tasks.json是项目特有的文件。

变量替换

在配置task时,我们需要给命令行传递一些参数,如当前文件、当前文件夹。
例如:

  • ${file}表示当前文件名
  • ${workspaceFolder}表示当前工作空间的名字
  • ${lineNumber}当前文件的行号

掌握这三个变量替换足够用了,vscode还定义了许多并无卵用的变量,此处是一份详细的变量列表。https://code.visualstudio.com/docs/editor/variables-reference

编写一个有用的task

使用vscode经常编写一些单文件程序,使用的语言有多种:

  • java:先使用javac命令编译,然后执行
  • cpp:先使用g++命令编译,然后执行
  • python:使用python命令运行
  • js:使用node运行
  • html:打开浏览器查看

tasks.json

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build",
      "type": "shell",
      "command": "lang",
      "args": [
        // Ask msbuild to generate full paths for file names.
        "${file}"
      ],
      "group": "build",
      // Use the standard MS compiler pattern to detect errors, warnings and infos
      "problemMatcher": [],
      "promptOnClose": true
    }
  ]
}

将lang.cmd这个命令放在全局变量PATH下

python %~dp0lang.py %*

主体程序使用python实现

import sys
import os
import tempfile
"""
使用单文件运行
"""
if len(sys.argv) <= 1:
    print("usage : lang filename")
    exit(0)
filename = sys.argv[1]
print("正在运行", filename, "
")
if filename.endswith('.js'):
    os.system('node ' + filename)
elif filename.endswith('.py'):
    os.system("python " + filename)
elif filename.endswith('.java'):
    os.system("javac {} -d {}".format(filename, tempfile.gettempdir()))
    os.system("java  -cp {} {}".format(tempfile.gettempdir(),
                                       os.path.basename(filename[:-5])))
elif filename.endswith('.cpp'):
    os.system("g++ {} -o {}/a.exe".format(filename, tempfile.gettempdir()))
    os.system(os.path.join(tempfile.gettempdir(), "a.exe"))
elif filename.endswith(".html"):
    os.startfile(filename)
else:
    print(filename, "是什么文件?")

经过以上配置,就可以快速实现对单文件的测试了。

在使用java语言编写单文件程序时,每次运行总是弹出提示“Classpath is incomplete”,这个提示官方已经说明了,这个问题不是事,可以直接设置java.errors.incompleteClasspath.severity忽略掉这个问题。

编写扩展

扩展提供的功能

vscode将哪些接口暴露给了扩展?扩展能够实现哪些功能?

  • vscode负责激活扩展。每个扩展运行的时候都以独立进程运行,vscode负责监视进程执行情况。扩展激活有如下几种情况:文件类型被检测到;目录下包含某种文件;命令面板触发;某种按键组合触发。
  • 读取、写入编辑器内容。
  • 工作空间。获取工作空间目录,状态栏信息,界面布局情况等。
  • 事件。例如打开、关闭、更改某个文件。
  • 编辑交互。包括代码提示、悬浮提示、错误提示等。

vscode的扩展的两种特殊类型

  • Language Server,语言服务器,用于代码提示、定义跳转、错误检测等。
  • Debugger,调试器,用于代码调试。调试器都是语言必备的组件,扩展的作用就是遵循vscode调试器适配协议在vscode和调试器之间搭建一座桥梁。

这两种类型的扩展遵循同一套vscode扩展基础架构。这些类型的扩展都和外界工具松耦合,通过某种协议进行交流,vscode提供了调试器适配器协议用来和不同语言的调试器进行交流,提供了语言服务器协议和语言服务器进行交互。

参考资料

vscode技巧,内容全面丰富,涉及vscode功能各个方面
https://code.visualstudio.com/docs/getstarted/tips-and-tricks

为vscode编写task
https://code.visualstudio.com/docs/editor/tasks

vscode插件体系概览
https://code.visualstudio.com/docs/extensions/overview

LSP(language server protocol)协议是微软提出的一种协议,功能包括代码提示、查找引用等功能。
https://microsoft.github.io/language-server-protocol/

原文地址:https://www.cnblogs.com/weiyinfu/p/10156453.html