微软的Vscode作为一个的开源代码编辑器,现在已经被开发者广泛使用,并且越来越强大。许多入门开发者对vscode或许早有耳闻,但是由于种种原因,一直没有深入使用过。笔者是vscode的重度使用者,早年使用Keil、IAR之流进行嵌入式开发,后来使用eclipse后顿觉keil和iar的编辑体验之差无法忍受,但eclipse放在今天,过于臃肿;不少开发者倾向使用sourceinsight,但是一方面它需要付费,另一方sourceinsight这么多年过去,止步于代码编辑,功能性稍弱;而Vscode,无论开发MCU还是Linux,它都能完美的满足需求,甚至可以基于各种插件将其当作IDE使用,集代码编辑、编译、调试、工程管理功能于一身。基于以上背景,本文将结合笔者自身经验,介绍vscode的一些使用技巧,常用插件,希望为广大新晋程序员朋友提供一些帮助。
windows安装
linux安装(ubuntu)
Vscode 的插件市场提供了大量的插件,开发者可以通过在线安装的方式来获取这些插件,非常方便。考虑到部分公司的开发环境无法访问外网,本文也提供了离线安装vscode插件的方法。
打开 Vscode 编辑器。
点击左侧的扩展图标(或使用快捷键 Ctrl+Shift+X)。
在搜索框中输入要安装的插件名称。
在搜索结果中找到您要安装的插件,并点击安装按钮。
安装完成后,可以在左侧的扩展列表中找到已安装的插件。
方法一:拷贝安装
方法二:插件市场下载手动安装
访问vscode插件官网:https://marketplace.visualstudio.com/VSCode
手动安装(三选一即可)
该插件提供了 C/C++ 开发所需的基本功能,例如代码补全、语法高亮、调试、查看反汇编等。C/C++插件的功能结合一些其他插件会更好用
CMake Tools提供了 CMake 项目的构建和调试功能,如果使用cmake进行工程管理,该插件能自动识别工程下的CMakeLists.txt文件,并方便的进行调试,安装后会在界面底部提供一系列按钮,方便用户使用。
建议CMake插件也一同安装,编写Cmake时能提供补全和高亮
保存CMakeLists.txt时自动更新Makefile
点击以上图标后,自动编译并进入调试界面,界面与上述C/C++调试界面一致
提供了在 Vscode 编辑器中运行代码的功能,适用于简单demo的一键运行和调试,支持Python、C、C++等多种语言。
GitLens 是一款用于 Vscode 的 Git 工具插件,它提供了丰富的 Git 功能和可视化界面,可以帮助开发者更加高效地使用 Git 进行版本控制。结合Vscode内置的git功能,工程管理功能非常强大
显示 Git 仓库的历史记录和分支信息。
方便的对比代码的更改
Hex Editor 是一款用于 Vscode 的十六进制编辑器插件,可以帮助开发者在编辑器中查看和编辑二进制文件、十六进制文件等。
使用方法:
Intel HEX format 是一款用于 Vscode 的插件,可以在编辑器中高亮查看和编辑 Intel HEX 格式的文件。Intel HEX 格式的文件以文本形式表示程序地址、数据及数据大小,通常用于存储固件、程序等二进制数据。因此,Hex文件大小并不代表真实的数据大小,而该插件能为用户自动计算hex数据的大小。
PlantUML 是一种基于文本的 UML 建模工具,它可以通过简单的文本描述来生成 UML 图形。PlantUML 支持多种 UML 图形类型,例如类图、时序图、用例图等,同时还支持自定义图形和扩展。语法简单,找个demo看一下就能学会,适合存储在工程中,需要时以图片形式导出。
人生苦短,我用Python,不过多作解释了,Python作为一种脚本语言,在各行各业都非常有用,该插件支持Python的自动补全和语法高亮以及调试
作为开发人员,不可避免要进行大量文档撰写工作,而Markdown是一种不错的选择,本文即作者使用Markdown编写。流行的Markdown编辑工具很多,Typora是其中久负盛名的其中一款。但如果你想沉浸式开发,一边写代码一边进行文档撰写,不希望在此过程中切换软件,可以使用Markdown Preview Enhanced,该插件提供Vscode下的Markdown的实时渲染,用于编辑和预览十分方便,需要导出文档到PDF或者World时再切换到Typora。
SFTP插件使用户可以通过ssh连接访问远程计算机的文件系统,不需要再额外安装winscp等软件,配置方法也很简单。对于调试嵌入式硬件非常友好,在板端开启ssh服务后,可以直接将编译产物传入板端,或拉取板端运行日志。
{
"name": "Profile Name",
"host": "name_of_remote_host",
"protocol": "ftp",
"port": 21,
"secure": true,
"username": "username",
"remotePath": "/public_html/project", // <--- This is the path which will be downloaded if you "Download Project"
"password": "password",
"uploadOnSave": false
}
[
{
"name": "server1",
"context": "project/build",
"host": "host",
"username": "username",
"password": "password",
"remotePath": "/remote/project/build"
},
{
"name": "server2",
"context": "project/src",
"host": "host",
"username": "username",
"password": "password",
"remotePath": "/remote/project/src"
}
]
本文的重点就是远程开发,而Remote-SSH系列插件是远程开发的必备组件,因此,下面以Q/A形式对Vscode的远程开发进行介绍。
要使用远程开发需要具备什么前提条件?
#生成rsa公私钥对
ssh-keygen
#将本地计算机的公钥拷贝到远程计算机白名单中,id_xxx.pub应改为实际生成的公钥文件名
ssh-copy-id -i ~/.ssh/id_xxx.pub username@remote_host_ip
Vscode-Server是什么?
Vscode-Server远程开发的优点是什么?
如何安装Vscode-Server?
如果远程计算机无法访问外网,如何离线安装Vscode-Server?
https://update.code.visualstudio.com/commit:${commit_id}/server-linux-x64/stable
https://update.code.visualstudio.com/commit:${commit_id}/server-linux-arm64/stable
# 手动建立安装路径,${commit_id}应换为实际的CommitID
mkdir -p ~/.vscode-server/bin/${commit_id}
# 解压下载下来的Vscode-Server压缩包
tar -zxvf vscode-server-linux-arm64.tar.gz -C ~/.vscode-server/bin/${commit_id}
# 解压后多了一级目录,需要移动到~/.vscode-server/bin根目录
cd ~/.vscode-server/bin/${commit_id}
# vscode-server-linux-arm64需要改为实际解压出的文件夹名称
mv vscode-server-linux-arm64/* .
正确安装后的Vscode-Server目录结构是怎样的?
├── bin <---------------------------------------- 各个版本的vscode-server可执行程序
│ ├── 4cb974a7aed77a74c7813bdccd99ee0d04901215
│ ├── 660393deaaa6d1996740ff4880f1bad43768c814
│ └── 74f6148eb9ea00507ec113ec51c489d6ffb4b771
├── data <--------------------------------------- 运行数据
│ ├── CachedExtensions
│ ├── CachedExtensionVSIXs
│ ├── CachedProfilesData
│ ├── languagepacks.json
│ ├── logs
│ ├── Machine
│ ├── machineid
│ └── User
└── extensions <--------------------------------- 插件安装目录
├── eamodio.gitlens-14.1.0
├── extensions.json
├── formulahendry.code-runner-0.12.0
├── github.copilot-1.96.262
├── github.copilot-chat-0.5.2023071302
├── github.copilot-labs-0.14.884
├── keroc.hex-fmt-1.0.0
├── ms-python.python-2023.12.0
├── ms-python.vscode-pylance-2023.7.20
├── ms-toolsai.jupyter-2023.6.1101941928-linux-arm64
├── ms-toolsai.jupyter-keymap-1.1.2
├── ms-toolsai.jupyter-renderers-1.0.17
├── ms-toolsai.vscode-jupyter-cell-tags-0.1.8
├── ms-toolsai.vscode-jupyter-slideshow-0.1.5
├── ms-vscode.cmake-tools-1.14.34
├── ms-vscode.cpptools-1.16.3
├── ms-vscode.cpptools-extension-pack-1.3.0
├── ms-vscode.cpptools-themes-2.0.0
├── ms-vscode.hexeditor-1.9.11
├── ms-vscode.makefile-tools-0.7.0
├── natizyskunk.sftp-1.16.3
├── shd101wyy.markdown-preview-enhanced-0.6.8
├── twxs.cmake-0.0.17
└── yzhang.markdown-all-in-one-3.5.1
为什么无缘无故就连不上vscode-server了?
可能原因一: vscode-server和vscode的版本不匹配
可能原因二: 当前登录远程计算机的用户没有.vscode-server目录的访问权限
# user根据实际情况进行更改
sudo chown user:user -R /home/user/.vscode-server
安装完成后如何使用?
连接成功后打开远程计算机路径,选择工程文件夹
仅仅连接上远程计算机,远程计算机没有插件一定是不好用的,因此还需要给远程计算机安装插件
下次连接可在历史工程中浏览历史工程,一键打开
远程开发和调试
Vscode支持用户自定义代码片段,定义关键字快速键入模板内容,该功能适合用于建立注释模板以及文件模板,比如新建源文件和头文件时,增加版权声明、以及函数的注释模板,比如笔者设置了cc为c的源文件头,当键入cc时,自动匹配模板定义的源文件头,键入ch时,自动匹配模板定义的头文件说明。
{
"C Source Format": {
"prefix": "cc",
"body": [
"/*********************************************************************************",
" *Copyright (C), 2016-2023, XXXXXX Tech. Co., Ltd.",
" *FileName: ${TM_FILENAME_BASE}.c", // 文件名
" *Author: XXX.XXXX", //作者
" *Version: V1.0", //版本
" *Date: $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE", //完成日期
" *Description: ",
" *Function List:",
" * 1. void function(void)",
" * 2. ",
" * 3. ",
" * 4. ",
" *History:",
" * 1. $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE;XXXXXXXXX;Init Function ",
" * 2. ",
" * 3. ",
" * 4. ",
"****************************************Includes***********************************/",
"",
"",
"/***************************************Variables***********************************/",
"",
"",
"",
"/***************************************Functions***********************************/",
"",
],
"description": "A c_head file template.",
},
"CPP Source Format": {
"prefix": "cxx",
"body": [
"/*********************************************************************************",
" *Copyright (C), 2016-2023, XXXXXXXXX Tech. Co., Ltd.",
" *FileName: ${TM_FILENAME_BASE}.cpp", // 文件名
" *Author: XXXXXXXXX", //作者
" *Version: V1.0", //版本
" *Date: $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE", //完成日期
" *Description: ",
" *Function List:",
" * 1. void function(void)",
" * 2. ",
" * 3. ",
" * 4. ",
" *History:",
" * 1. $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE;XXXXXXXXX;Init Function ",
" * 2. ",
" * 3. ",
" * 4. ",
"****************************************Includes************************************/",
"",
"",
"/****************************************Macros*************************************/",
"",
"",
"/***************************************Variables***********************************/",
"",
"",
"",
"/***************************************Functions***********************************/",
"",
],
"description": "A c_head file template.",
},
"C Head Format": {
"prefix": "ch",
"body": [
"/*********************************************************************************",
" *Copyright (C), 2016-2022, XXXXXXXXX Tech. Co., Ltd.",
" *FileName: ${TM_FILENAME_BASE}.h", // 文件名
" *Author: XXXXXXXXX", //作者
" *Version: V1.0", //版本
" *Date: $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE", //完成日期
" *Description: ",
" *Function List:",
" * 1. void function(void)",
" * 2. ",
" * 3. ",
" * 4. ",
" *History:",
" * 1. 2022.8.28;XXXXXXXXX;Init Function ",
" * 2. ",
" * 3. ",
" * 4. ",
"**********************************************************************************/",
"",
"#ifndef __${TM_FILENAME_BASE}_H__",
"#define __${TM_FILENAME_BASE}_H__",
"",
"/***************************************Includes***********************************/",
"",
"",
"/***************************************Macros***********************************/",
"",
"",
"/***************************************Variables***********************************/",
"",
"",
"",
"/***************************************Functions***********************************/",
"",
"",
"#endif",
"/* [] END OF ${TM_FILENAME_BASE}.h */",
],
"description": "A c_head file template.",
},
"CXX Head Format": {
"prefix": "cxh",
"body": [
"/*********************************************************************************",
" *Copyright (C), 2016-2022, XXXXXXXXX Tech. Co., Ltd.",
" *FileName: ${TM_FILENAME_BASE}.h", // 文件名
" *Author: XXXXXXXXX", //作者
" *Version: V1.0", //版本
" *Date: $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE", //完成日期
" *Description: ",
" *Function List:",
" * 1. void function(void)",
" * 2. ",
" * 3. ",
" * 4. ",
" *History:",
" * 1. 2022.8.28;XXXXXXXXX;Init Function ",
" * 2. ",
" * 3. ",
" * 4. ",
"**********************************************************************************/",
"",
"#ifndef __${TM_FILENAME_BASE}_H__",
"#define __${TM_FILENAME_BASE}_H__",
"",
"/***************************************Includes***********************************/",
"",
"",
"/***************************************Macros***********************************/",
"",
"",
"/***************************************Variables***********************************/",
"",
"",
"",
"/***************************************Functions***********************************/",
"",
"#ifdef __cplusplus",
"extern \"C\"{",
"#endif",
"",
"",
"",
"#ifdef __cplusplus",
"}",
"#endif",
"#endif",
"/* [] END OF ${TM_FILENAME_BASE}.h */",
],
"description": "A c_head file template.",
},
"C Function Decription":{
"prefix": "cf",
"body": [
"/*******************************************************************************",
" * @name ",
" * @brief ",
" * @param[in] None",
" * @param[out] None",
" * @retval None",
" * @author xxxx.yyyyy",
" *******************************************************************************/",
],
"description": "C Function Comment"
},
"C Include":{
"prefix": "ci",
"body": [
"#include "
],
"description": "C Include"
},
"C Define":{
"prefix": "cd",
"body": [
"#define "
],
"description": "C define"
},
"Typedef Struct":{
"prefix": "cs",
"body": "typedef struct{\n\t\n\n}${3:MyCustomType};"
},
"Typedef Union":{
"prefix": "cu",
"body": "typedef uinon{\n\t\n\n}${3:MyCustomType};"
},
"Python Head":{
"prefix": "ph",
"body": "# -*- coding: utf-8 -*-"
},
"Python Main":{
"prefix": "pm",
"body": "if __name__ == '__main__':"
}
}
VS Code 集成了终端,可以在编辑器中直接打开终端窗口,方便进行命令行操作。如果是远程开发,使用的是远程计算机的默认终端。因此基本可以代替securecrt以及mobaxterm等终端软件。
Git可以说是开发人员的必备技能,本来在Vscode的使用教程中单独讲它显得多余,但是由于Vscode将git的功能整合得很完备,基本上所有git命令都能找到对应的图形化操作,从而避免了繁杂的命令行操作。但是不了解git基本命令是无法理解vscode中那些按钮的作用的。因此笔者在这部分先介绍常用git命令及其使用场景,再将Vscode中的图形化操作与之对照,方便读者快速掌握Vscode中的git使用。
# 用于初始化本地仓库
git init
#从远程仓库克隆代码到本地
git clone https://xxxx.com/project_name.git
# 使用分支名拉取
git checkout -b xxx origin/xxx
# 使用commitID拉取
git checkout -b xxx commitID
git branch -m NewName
git checkout -b xxx
git push origin xxx:xxx
git diff
git status
git pull origin AAA:BBB
git branch -a
#删除本地分支
git branch -d AAA、
#删除远程分支
git push origin -d AAA
git reset HEAD^
#适用于本地代码开发到一半,但是想要从远端拉取最新代码
#此时可以先将当前代码保存到临时区防止拉取时冲突,拉取最新代码后再从临时区恢复改动
#临时区保存的改动时整个仓库都可见的,因此临时区的存储不会因为切换了分支而丢失
git stash save "comment"
git stash list
git stash show 0 -p
#应用改动且将其从临时区删除
git stash pop xx
#应用改动但不删除临时区内容
git stash apply xx
#新建本地tag
git tag -a tagname -m "tag commit"
#删除本地tag
git tag -d tagname
当然,也不是所有操作都用图形化很方便,有些操作还是命令行会更直接
#适用于基于旧分支开发,要合并到主分支前,重新移动开发分支基线,处理冲突
git rebase CommitID
git submodule update --init
#将xxx分支merge到当前分支
git merge xxx
git push origin tagname
#冒号 : 表示删除
git push origin :tagname
#适用于过去提交过一笔有效代码到其他分支,现在想要将其中的改动内容也合入其他分支的情况
git cherry-pick commit-id
最后,笔者推荐一个学习git的网站:
https://learngitbranching.js.org/?locale=zh_CN
该网站提供了一个交互式的学习环境,可以通过图形化的方式学习 Git 的基本操作和工作流程。该网站的学习内容包括分支、合并、重置、rebase、标签等,通过实际操作和练习,帮助读者深入理解 Git 的使用方法和原理。