|
折腾不止,快乐不尽!! 用sublime很多年了,最近VScode崛起的趋势使我有些动摇了。但看在sublime更加折腾(啊不是),看在它启动速度快、颜值极高、高度可自定义、文本编辑功能极其强大的份上,我选择继续使用sublime,并写个教程记录一下配置的过程。
主要是我的日常需求只是编译C/C++单文件,没有使用Virtual Studio或者Clion的必要,而且这俩都是内存杀手(memory killer),启动速度还很慢。而按照我这里的步骤配置的话,不仅可以享受与Clion一模一样的代码补全、代码格式化、代码跳转服务(都是使用clangd后端)。关键是在笔记本上也能纵享丝滑,秒启动。不仅能写C/C++,还能配置Python、Java、Dart、HTML、CSS,强大到逆天。
1. 安装sublime text
进入sublime官网下载sublime的安装包(当然也可以在官网下载页面下载portable版本,不过建议下载默认的setup版本)

acff1424651b48155727ab46c78fffad.png

83fe76d7f0f18dfdfc2612e8efd042e1.png
双击安装包:

85557b4f7aa7240f77c5f86bed2e2adb.png
应该一会就下载完成了。

a5db02164c3b7b8a1e5d06af5aca7297.png
此时可以在应用列表看到sublime:

471767fe38ca3e17772de28430b097e3.png

0181c269d49d9ac4e739f9903102d7d2.png
2. 下载LLVM和Clang
参考 https://www.cnblogs.com/FrankOu/p/14215850.html 现在使用Clang编译是大趋势,所以我们这里就不使用gcc了(虽然在下载Clang的过程中也会安装gcc)
Windows下直接安装LLVM会出现C++标准库丢失的问题,所以我们需要用到MSYS2这个安装工具,原理就是直接安装别人编译好的Clang,很方便。
2.1 下载msys2并配置
2.1.1 msys2的下载
在MSYS官网下载msys2,如果是windows 64位,就选择 msys2-x86_64.exe

f5b13912f47c03e85ebfe9e0c30e9864.png
2.1.2 msys2的安装
msys2默认安装在C:\msys64,在这里我自己不做修改,安装路径读者可自行决定。

b702853675961ff7a93b0744a161c200.png
后面只要一直点next就行了。
安装完毕的界面如下

4503897c8fc9a2378ca612382a526303.png

7ba72832fe0ccf214a5aa754869c415d.png
2.1.3 msys2的配置
打开C:\msys64\etc\pacman.d可以看到mirrorlist.mingw32、mirrorlist.mingw64、mirrorlist.msys三个文件。
在文件mirrorlist.mingw32中加入: Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686
在文件mirrorlist.mingw64中加入: Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/x86_64
在文件mirrorlist.msys中加入: Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/msys/$arch
这三行是从清华镜像下载软件,速度会快很多。随后打开msys2,输入pacman -Sy同步软件包数据库。

67a3cfee058e42c2b182122f993a8b87.png
然后再输入pacman -Su更新软件包。

95861c21695f0f04c1a04729ba01c0f9.png
在此期间msys2提示你输入y之后会关闭,重新打开再输入一遍pacman -Su即可。

f814635550070eb00918cb5a0c933790.png

519b87a78a6c9ebc4ee18920e9f533fd.png
2.2 安装并配置Clang
2.2.1 安装Clang和LLVM
打开msys2,输入:
pacman -S mingw64/mingw-w64-x86_64-make mingw64/mingw-w64-x86_64-gdb mingw64/mingw-w64-x86_64-clang
按照提示,就可以完成Clang的安装了(顺便安装了gdb和make)。

3ec84878454f4c9b7493227b3186750d.png
再执行如下语句完成Clangd的安装。
pacman -S mingw64/mingw-w64-x86_64-clang-tools-extra
安装成功如下:

6b095767eac76296d27830028a02ec3d.png
注意,如果中途发生报错或者卡死,大概率是网络问题,退出重新运行命令就行了。这几个命令一个都不能漏。 2.2.2 添加环境变量
将C:\msys64\mingw64\bin添加到Path中。如果不知道什么是path的话,就按照如下步骤操作:
1、打开设置

335c77e43ae23e6558fa2e1e6bdb98fd.png
2、搜索PATH,选择edit the environment variables

105a0f5bfdbfc227b0e5443adf42aa7c.png
3、选择environment variables

97c7075cae23bc54cd1b1dc2a305a4bb.png
4、选择Path

3516a61291977c12ab62a37c74e157be.png
5、点击Edit

87f7e63954e54728eadbab5b7384b1aa.png
6、点击new

f510d82f913302f518b0ae6e80c8feca.png

54a43381852de6d2e7964edccb862dca.png
7、最后点OK即可。

5c69ad6d6179b9cf3b992f716d2bcb48.png
2.2.3 测试是否安装成功
首先进入命令提示符:

7c525a755c052146ec6236b42f7fba2b.png
(或者Win+R输入cmd回车)

0f649a7474a540e4b6897555760684cd.png
测试Clang是否安装,输入clang -v

c1f372bfd8e1819f20c2319ed526e91a.png
上面这样就是安装成功了。
测试Clangd是否安装,输入clangd即可:

0b91e467b03b4adc0520594370ebe892.png
可以看到已经启动了clangd后台,安装成功。
3. 配置sublime text4
sublime text4并非开源免费,但是你不交钱可以一直免费用下去。它只不过会时不时弹窗提醒你一下要交钱(相当于求你打赏)
这里我以我的需求为例,我想要在某个文件夹下面创建很多个xxx.cpp文件(一看就是在刷题呢)然后可以一键编译运行,产生的编译文件(xxx.exe)不会污染原目录下的cpp文件。
首先我想形成这样一个目录结构:
MyProject
|
|____code
| |___test1.cpp
| |___test2.cpp
| |___test.c
| |___test.py
|
|____bin
| |___test.exe
| |___test1.exe
| |___test2.exe
|
|____in_out
|___test.in
|___test.out
先把MyProject(名字随便取)拖到sublime里面去。

5f1ae18c00079870008fabec8c729b70.png
再在code里面随便写一个test.cpp

9f5525b6050a2d51ee553c57dab3c71d.png
第一次按Ctrl+B会弹出选择哪一种编译方式,默认只有两个——single file和single file run,前者是编译,后者是编译+运行,这里我们选择后者。

13cb45337e773363790d1d5e993c784c.png

5b16f797507b51243220b532ab98c24f.png
OK运行的结果很正常(如果报错请重新启动sublime/重启电脑试试)。但是显然,可执行文件被放在和原文件相同的文件夹下,这样会显得很乱:

b70bd1db77d44ebfda3d95175c2cf397.png
那该怎么避免呢?我们可以通过自定义编译,来把exe文件放到我想要放的位置(MyProject/bin)
3.1 自定义如何编译运行C/C++
sublime通过sublime-build文件自定义如何编译运行C/C++。
在Tools->Build System->New Build System中新建编译文件:

90ba8bd2210b500c21cab56e424151c9.png
先Ctrl+S报存为CppBuilder.sublime-build,当然Cpp Builder也是我随便取的。大家可以随意。
把cppbuilder里面本来就有的全部删光,换成这些:
{
// Windows
// build only
"shell_cmd": "clang++ -std=c++11 -g -Wall ${file} -o ${file_path}/../bin/${file_base_name}",
// check the file name using regex
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
// set the encoding to utf-8
"encoding": "utf-8",
// doesn't matter if I use full path
"working_dir": "${file_path}",
// only C and Cpp files can use this sublime-build file
"selector": "source.c, source.c++",
"variants": [
{
// build and run in CMD
// you can type something in CMD then your progam can get its inputs
// [Recommanded]
"name": "Run in CMD",
"shell_cmd": "clang++ -std=c++11 -g -Wall \"${file}\" -o \"${file_path}/../bin/${file_base_name}\" && start cmd /c \"\"${file_path}/../bin/${file_base_name}\" & pause \""
},
{
// build and run in sublime
// but you can't input anything to your progam
"name": "Run in Sublime",
"shell_cmd": "clang++ -std=c++11 -g -Wall \"${file}\" -o \"${file_path}/../bin/${file_base_name}\" && cmd /c \"${file_path}/../bin/${file_base_name}\""
}
]
}
可以看到,我使用了两种运行方式——在sublime内部直接运行以及在 windows自带的cmd中运行,为什么要选用cmd呢?因为sublime有个缺点,就是它所有文本都是可以编辑的,也就是说我们没法像正常命令行一样输入xxxx,然后回车。(你们试试就知道我说的什么意思了)
注意:sublime-build文件中涉及很多方面的知识,而且极其脆弱,一改动就可能运行失败。 保存CppBuilder.sublime-build以后,通过Ctrl+Shift+B选择编译命令,选取Run In CMD:

05f7e3112639faf14f98c1bb806a6cd9.png

a1d0373a4a80a6af0c8fdfd1d1aed14c.png
成功运行,而且把可执行文件和源文件完美隔开!
但是我不想每次都开一个黑框框。。。

7065ffb17641a9443ad2ca61932acde7.png
当然可以,欢迎进入插件的世界!
3.2 安装package control插件管理工具
Ctrl+Shift+P打开sublime的命令面板。
输入install package control回车进行安装。

135c8f21df302ff56e425e8c51bde1e5.png

64e4e35438f2841f3f2701cb8c95d563.png
上面这样就算安装成功了。
3.3 安装Terminus
Terminus是一个sublime插件,目的就是补全刚刚所说的缺点,实现sublime内置终端。 Ctrl+Shift+P打开sublime的命令面板。
输入PCI然后回车(package control install)

3300ad30b019ecba60525dcc04c1f052.png
输入terminus,回车开始安装,可以看到左下角的安装提示。

8e1a1fe1c83e892ed4a14a955c42a065.png
重启sublime(sublime一般不需要每次改动都重启,但是遇事不决重启总归没错)
进入Terminus的设置:Preferences->Package Settings->Terminus->Settings

cc9964d8b8c91c2244ffcb9bfd5efa2d.png
照旧,把里面的东西删了改成(注意到两端一定得是花括号):
{
"256color": true,
"brighten_bold_text": false,
"theme": "chalk",
}当然这主题是我的个人喜好,大家可以一个个试,看看自己喜欢哪个。
这时,我们还是Ctrl+Shift+P打开面板,输入terminus就可以查看它的主要功能。

dd8784fede0c4ff61ecee95f948e4915.png
就比如我们选择open default shell in tab

342ec6cb1a4cabfa90632f7648cc3f7b.png
会发现命令行在sublime中打开了,而且路径自动切换到了MyProject下:

8368f3b36233f7e28eb3837e2aee92fb.png

52d6f87b584ee5d8656c378205dcbd6a.png
当然,使用Terminus运行C/C++也不在话下,根据Terminus官网的配置,我们可以将CppBuilder.sublime-build添加一些选项。
{
// Windows
// build only
"shell_cmd": "clang++ -std=c++11 -g -Wall ${file} -o ${file_path}/../bin/${file_base_name}",
// check the file name using regex
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
// set the encoding to utf-8
"encoding": "utf-8",
// doesn't matter if I use full path
"working_dir": "${file_path}",
// only C and Cpp files can use this sublime-build file
"selector": "source.c, source.c++",
"variants": [
{
// build and run in Terminus (sublime plugin)
// [Recommanded]
"name": "Run In Terminus",
"target": "terminus_exec",
"cancel": "terminus_cancel_build",
"shell_cmd": "clang++ -std=c++11 -g -Wall \"${file}\" -o \"${file_path}/../bin/${file_base_name}\" && cmd /c \"${file_path}/../bin/${file_base_name}\""
},
{
// build and run in CMD
// you can type something in CMD then your progam can get its inputs
// [Recommanded]
"name": "Run in CMD",
"shell_cmd": "clang++ -std=c++11 -g -Wall \"${file}\" -o \"${file_path}/../bin/${file_base_name}\" && start cmd /c \"\"${file_path}/../bin/${file_base_name}\" & pause \""
},
{
// build and run in sublime
// but you can't input anything to your progam
"name": "Run in Sublime",
"shell_cmd": "clang++ -std=c++11 -g -Wall \"${file}\" -o \"${file_path}/../bin/${file_base_name}\" && cmd /c \"${file_path}/../bin/${file_base_name}\""
}
]
}
这里奉上评论区想要的Mac下配置(我自用的,和上面的效果一模一样)
{
// MacOS
"cmd": [
"bash",
"-c",
"clang++ '${file}' -std=c++11 -stdlib=libc++ -o '${file_path}/../bin/${file_base_name}' && ${file_path}/../bin/${file_base_name}"
],
"file_regex": "^(..{FNXX==XXFN}*):([0-9]+):?([0-9]+)?:? (.*)$",
"working_dir": "${file_path}",
"encoding": "utf-8",
"selector": "source.c, source.c++",
"variants": [
{
"name": "Run In Terminus",
"target": "terminus_exec",
"cancel": "terminus_cancel_build",
"cmd": [
"bash",
"-c",
"clang++ '${file}' -std=c++11 -stdlib=libc++ -o '${file_path}/../bin/${file_base_name}' && ${file_path}/../bin/${file_base_name}"
]
},
{
"name": "Create Input File",
"cmd": [
"bash",
"-c",
"touch ${file_path}/../in_out/${file_base_name}.in && open -a Sublime\\ Text ${file_path}/../in_out/${file_base_name}.in"
]
},
{
"name": "Run In Terminal",
"cmd": [
"bash",
"-c",
"clang++ '${file}' -std=c++11 -stdlib=libc++ -o '${file_path}/../bin/${file_base_name}' && open -a Terminal.app '${file_path}/../bin/${file_base_name}'"
]
},
]
}
Create Input File是新建输入文件的意思,不需要的可以把它删掉。还有,提醒一下,sublime-build中最开始那行是"cmd","variants"里面也必须是“cmd”;最开始是"shell_cmd","variants"里面也必须是“shell_cmd”。
然后Ctrl+Shift+B选择如何编译,选择Run In Terminus

7c09a97894261f0b6e028e7150016cf2.png

bd756dfb5ca50975750595208ad6ba45.png
OK,简直完美。

7065ffb17641a9443ad2ca61932acde7.png
嗯?居然想要享受Clion同款代码补全、提示、跳转、格式化?只能祭出LSP插件了!
(不是那个lsp)
3.4 安装Lsp插件
Ctrl+Shift+P打开sublime的命令面板。
输入PCI然后回车(package control install)
输入lsp然后回车,很快就装好了。

1f8a663a7fbd8bb67be924c90c2fe89e.png
注意,lsp只是一个语言处理的后端,需要安装相应的前端才能发挥作用。
3.4.1 lsp-clangd
这里我们使用Clangd前端——继续安装lsp-clangd插件。

6829a6a94a92c57f6e586e47a2916b63.png
装完了以后重启sublime,就能看到效果了。

我这还是在虚拟机里面运行的,可以看到真的是健步如飞,用起来不要太爽。试想一下在虚拟机里运行Clion或者VS,分分钟钟给你卡成ppt。
3.4.2 lsp-json
lsp-json的安装使我们能够更高效地设置sublime。谁用谁知道,写json最爽的就是它。
同理,在命令面板安装lsp-json。但是安装完成它会提示你下载node-js:

7793ecadac80b14087970e70c3c1b909.png
按照它说的做就完了。

b0e12ca6ff6a05a1042851f9c4df2fe3.png
3.4.3 lsp-pyright
本人除了C/C++,还需要用sublime写一点python,这时lsp-pyright就是一个很好的选择,但是与本文主题无关,这里不多加赘述。
3.4.4 配置lsp
如果你已经装好了lsp-json的话,这一步其实手打和复制黏贴差不多快()
配置一下lsp:
首先是到Preferences->Package Settings->LSP->Settings中,写入这样几行:
{
// 在主页面只显示error红色下划线
//"show_diagnostics_severity_level": 1,
// 代码提示显示灯泡图标
"show_code_actions": "bulb",
// 保存时自动格式化
"lsp_format_on_save": true,
}
再到Preferences->Package Settings->LSP->Servers->LSP-clangd中,写入这样几行:
// Settings in here override those in "LSP-clangd/LSP-clangd.sublime-settings"
{
"initializationOptions": {
// 启用clang-tidy代码检查,可能启用后warning会比较多,自己看着办吧
"clangd.clang-tidy": true,
// 美化clangd输出的JSON
"clangd.pretty": true,
}
}
但是光在这里设置clang-tidy是没有用的,还得在project/code(源文件所在目录)下新建.clang-tidy文件,写入:
---
Checks: "bugprone-*,\
google-*,\
misc-*,\
modernize-*,\
performance-*,\
readability-*,\
portability-*,\
"
HeaderFilterRegex: 'Source/cm[^/]*\.(h|hxx|cxx)$'
CheckOptions:
- key: modernize-use-default-member-init.UseAssignment
value: '1'
- key: modernize-use-equals-default.IgnoreMacros
value: '0'
- key: modernize-use-auto.MinTypeNameLength
value: '80'
...
3.4.5 配置clang-format
写代码怎么能少的了自动格式化呢。clang-format的配置很简单,只需在project/code下新建.clang-format文件,写入以下内容:
当然这只是我的配置,大部分都是抄的网上的,可以根据自己的喜好改动。 ---
# 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto
Language: Cpp
BasedOnStyle: WebKit
# 访问说明符(public、private等)的偏移
AccessModifierOffset: -4
# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
AlignAfterOpenBracket: Align
# 对齐数组列
AlignArrayOfStructures: None
# 连续赋值时,对齐所有等号
AlignConsecutiveAssignments: None
# 对齐连续位字段
AlignConsecutiveBitFields: None
# 连续声明时,对齐所有声明的变量名
AlignConsecutiveDeclarations: None
# 对齐连续宏定义
AlignConsecutiveMacros: AcrossComments
# 逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlines: Left
# 操作数对齐方式
AlignOperands: Align
# 尾随的注释对齐
AlignTrailingComments: true
# 允许函数参数在一行
AllowAllArgumentsOnNextLine: true
# 允许函数声明的所有参数在放在一行
AllowAllParametersOfDeclarationOnNextLine: true
# 允许短的块放在同一行
AllowShortBlocksOnASingleLine: true
# 允许短的case标签放在同一行
AllowShortCaseLabelsOnASingleLine: true
# 允许短的枚举放在同一行
AllowShortEnumsOnASingleLine: true
# 允许短的函数放在同一行
AllowShortFunctionsOnASingleLine: Empty
# 允许短的if语句保持在同一行
AllowShortIfStatementsOnASingleLine: false
# 允许短的匿名函数lamda表达式放在同一行
AllowShortLambdasOnASingleLine: Empty
# 允许短的循环while保持在同一行
AllowShortLoopsOnASingleLine: false
# 总是在返回类型后换行
AlwaysBreakAfterReturnType: None
# 总是在多行string字面量前换行
AlwaysBreakBeforeMultilineStrings: false
# 总是在template声明后换行
AlwaysBreakTemplateDeclarations: MultiLine
# 宏属性
AttributeMacros: ['__capability', '__output', '__ununsed']
# 表示函数实参要么都在同一行,要么都各自一行
BinPackArguments: true
# false表示所有形参要么都在同一行,要么都各自一行
BinPackParameters: true
# 位域冒号对齐方式
BitFieldColonSpacing : Both
# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效,设置其他配置则下面不生效
BraceWrapping :
# class定义后面
AfterClass: true
# 控制语句后面
AfterControlStatement: true
# enum定义后面
AfterEnum: true
# 函数定义后面
AfterFunction: true
# 命名空间定义后面
AfterNamespace: true
# ObjC定义后面
AfterObjCDeclaration: true
# struct定义后面
AfterStruct: true
# union定义后面
AfterUnion: true
# catch之前
BeforeCatch: true
# else之前
BeforeElse: false
# 缩进大括号
IndentBraces: false
# unknown:
AfterCaseLabel: true
AfterExternBlock: true
BeforeLambdaBody: true
BeforeWhile: true
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
# 在java字段的注释后换行
BreakAfterJavaFieldAnnotations: false
# 在二元运算符前换行
BreakBeforeBinaryOperators: None
# 在大括号前换行
BreakBeforeBraces: Custom
# 在concept前换行
# BreakBeforeConceptDeclarations: Never
# 在三元运算符前换行
BreakBeforeTernaryOperators: true
# 构造函数初始值设定项换行样式
BreakConstructorInitializers: BeforeColon
# 继承列表样式
BreakInheritanceList: AfterColon
# 字符串换行样式
BreakStringLiterals: false
# 每行字符的限制,0表示没有限制
ColumnLimit: 80
# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变
CommentPragmas: '^ IWYU pragma:'
# 在新行上声明每个命名空间
CompactNamespaces: false
# 构造函数的初始化列表的缩进宽度
ConstructorInitializerIndentWidth: 4
# 延续的行的缩进宽度
ContinuationIndentWidth: 4
# 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: true
# 继承最常用的换行方式
DeriveLineEnding: true
# 继承最常用的指针和引用的对齐方式
DerivePointerAlignment: false
# 关闭格式化
DisableFormat: false
# 删除访问修饰符后的所有空行
EmptyLineAfterAccessModifier: Never
# 仅当访问修饰符开始一个新的逻辑块时才添加空行
EmptyLineBeforeAccessModifier: Never
# 自动检测函数的调用和定义是否被格式为每行一个参数(Experimental)
ExperimentalAutoDetectBinPacking: false
# 自动补充namespace注释
FixNamespaceComments: false
# 需要被解读为foreach循环而不是函数调用的宏
ForEachMacros: ['RANGES_FOR', 'FOREACH']
IfMacros: ['IF']
# 多个#include块合并在一起并排序为一个
IncludeBlocks: Merge
# 可以定义负数优先级从而保证某些#include永远在最前面
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: &#39;^(<|&#34;(gtest|gmock|isl|json)/)&#39;
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: &#39;.*&#39;
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: &#39;(Test)?$&#39;
IncludeIsMainSourceRegex: &#39;&#39;
# 缩进访问修饰符
IndentAccessModifiers: false
# 缩进case标签
IndentCaseLabels: false
# case 标签后面的块使用与 case 标签相同的缩进级别
IndentCaseBlocks: false
# 向后兼容缩进外部块
IndentExternBlock: AfterExternBlock
# 缩进goto标签。
IndentGotoLabels: false
# 缩进预处理器指令
IndentPPDirectives: BeforeHash
# 缩进模板中的requires子句
IndentRequires: false
# 缩进宽度
IndentWidth: 4
# 函数返回类型换行时,缩进函数声明或函数定义的函数名
IndentWrappedFunctionNames: false
#InsertBraces: true
# 插入尾随逗号
InsertTrailingCommas: None
# 保留JavaScript字符串引号
JavaScriptQuotes: Leave
# 包装 JavaScript 导入/导出语句
JavaScriptWrapImports: true
# 保留在块开始处的空行
KeepEmptyLinesAtTheStartOfBlocks: false
# 相对于 lambda 签名对齐 lambda 主体
LambdaBodyIndentation: Signature
# 开始一个块的宏的正则表达式
MacroBlockBegin: &#39;&#39;
# 结束一个块的宏的正则表达式
MacroBlockEnd: &#39;&#39;
# 连续空行的最大数量
MaxEmptyLinesToKeep: 1
# 命名空间的缩进
NamespaceIndentation: All
ObjCBinPackProtocolList: Auto
# 使用ObjC块时缩进宽度
ObjCBlockIndentWidth: 4
ObjCBreakBeforeNestedBlockParam: true
# 在ObjC的@property后添加一个空格
ObjCSpaceAfterProperty: false
# 在ObjC的protocol列表前添加一个空格
ObjCSpaceBeforeProtocolList: true
# 缩进预处理器语句的列数
PPIndentWidth: -1
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
# 指针的对齐: Left, Right, Middle
PointerAlignment: Right
# 引用的对齐
ReferenceAlignment: Pointer
# 允许重新排版注释
ReflowComments: true
#RemoveBracesLLVM: false
# 短命名空间跨越的最大展开行数
ShortNamespaceLines: 1
# 允许排序#include
SortIncludes: CaseSensitive
# java静态导入放在非静态导入之前
SortJavaStaticImport: Before
# 对using声明排序
SortUsingDeclarations: true
# 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false
# 在!后添加空格
SpaceAfterLogicalNot: false
# 在Template关键字后添加空格
SpaceAfterTemplateKeyword: true
# 不要确保指针限定符周围有空格
SpaceAroundPointerQualifiers: Default
# 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true
# 不在case冒号之前添加空格
SpaceBeforeCaseColon: false
# 不在C++11大括号列表之前添加空格
SpaceBeforeCpp11BracedList: false
# 在构造函数初始化器冒号之前添加空格
SpaceBeforeCtorInitializerColon: true
# 在继承冒号前添加空格
SpaceBeforeInheritanceColon: true
# 开圆括号之前添加一个空格
SpaceBeforeParens: ControlStatements
# 在基于范围的for循环冒号之前添加空格
SpaceBeforeRangeBasedForLoopColon: true
# 中括号前空格
SpaceBeforeSquareBrackets: false
# {}中间空格
SpaceInEmptyBlock: false
# 在空的圆括号中添加空格
SpaceInEmptyParentheses: false
# 在尾随的评论前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 2
# 在尖括号的<后和>前添加空格
SpacesInAngles: true
# 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false
# 不在if/for/switch/while条件周围插入空格
SpacesInConditionalStatement: false
# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: true
# 行注释开头允许有多少个空格。要禁用最大值,请将其设置为-1,除此之外,最大值优先于最小值
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
# 在圆括号的(后和)前添加空格
SpacesInParentheses: false
# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响
SpacesInSquareBrackets: false
# 标准
Standard: Auto
# 在语句前面被忽略的宏定义,就好像它们是一个属性一样
StatementAttributeLikeMacros:
- Q_EMIT
# 应该被解释为完整语句的宏定义
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
# tab宽度
TabWidth: 4
# 使用\r\n换行替代\n
UseCRLF: false
# 使用tab字符:ForIndentation——仅将制表符用于缩进
UseTab: Never
# 对空格敏感的宏定义
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...
现在你一保存文件,lsp就会按照上述.clang-format文件来格式化你的代码。
4. 配置Sublime
sublime主要有两个配置文件,一个是Preferences->Settings中,一个是Preferences->Key Bindings。
进入以后左侧是默认配置,无法修改的。右侧是自定义配置,自定义配置可以覆盖默认配置选项。
4.0 设置Tab长度
我喜欢用四空格的Tab,不会有人立场不一样吧?

bfdb3e457249d2ec9eebec5effa5d8ab.png

e93149a98462c4d313d58f77e44f0a6b.png
4.1 sublime偏好设置
OK,我们先改Preferences->Settings。这是我的个人喜好:
{
&#34;font_size&#34;: 21,
&#34;ignored_packages&#34;: [
&#34;Vintage&#34;,
],
// 设置tab的大小为4
&#34;tab_size&#34;: 4,
// 使用空格代替 Tab
&#34;translate_tabs_to_spaces&#34;: true,
// 使用默认字体 Monaco
&#34;font_face&#34;: &#34;Monaco&#34;,
// 失去光标自动保存
&#34;save_on_focus_lost&#34;: true,
// 添加行宽标尺
&#34;rulers&#34;: [
100
],
// 显示空白字符
&#34;draw_white_space&#34;: &#34;all&#34;,
// 保存时自动去除行末空白
&#34;trim_trailing_white_space_on_save&#34;: &#34;all&#34;,
// 保存时自动增加文件末尾换行
&#34;ensure_newline_at_eof_on_save&#34;: true,
// 默认编码格式
&#34;default_encoding&#34;: &#34;UTF-8&#34;,
// 不检查更新
&#34;update_check&#34;: false,
// 把光标的样式从闪烁变成淡入淡出
// 其余的选项还有&#34;smooth&#34;, &#34;phase&#34;, &#34;blink&#34;, &#34;wide&#34;, &#34;solid&#34;.
&#34;caret_style&#34;: &#34;phase&#34;,
// 高亮当前行
&#34;highlight_line&#34;: true,
// 增加行间距
&#34;line_padding_bottom&#34;: 1,
&#34;line_padding_top&#34;: 1,
// 一直显示代码折叠箭头
&#34;fade_fold_buttons&#34;: false,
// 排除这些文件夹,搜索和侧边栏都不会显示
&#34;folder_exclude_patterns&#34;: [
&#34;*.dSYM&#34;,
],
// 排除这些文件,搜索和侧边栏都不会显示
&#34;file_exclude_patterns&#34;: [
&#34;.DS_Store&#34;,
&#34;.clang-format&#34;,
&#34;.clang-tidy&#34;,
],
}
4.2 sublime快捷键设置
这样配置下来,多出来了很多功能。我们可以配置一些快捷键,不得不说sublime的快捷键自定义性非常强,就是比较折腾。
sublime的快捷键逻辑是,很多插件都有key-bindings设置(如图)

7fe9937af4ebbd7876ccfdce8505645c.png
打开就能显示默认快捷键(左侧)和系统快捷键(右侧),在右侧可以自己写快捷键,只要
打开Preferences->Key Bindings,我的配置是:
[
// LSP Format File (lsp&#39;s format)
// &#34;shift+alt+l&#34;一键格式化全文件或者选中区域
{
&#34;keys&#34;: [
&#34;shift+alt+l&#34;
],
&#34;command&#34;: &#34;lsp_format_document&#34;,
},
// LSP Run Source Actions
// &#34;shift+alt+enter&#34; 显示代码提示
{
&#34;keys&#34;: [
&#34;shift+alt+enter&#34;
],
&#34;command&#34;: &#34;lsp_code_actions&#34;,
&#34;context&#34;: [
{
&#34;key&#34;: &#34;lsp.session_with_capability&#34;,
&#34;operator&#34;: &#34;equal&#34;,
&#34;operand&#34;: &#34;codeActionProvider.codeActionKinds&#34;
}
]
},
// LSP Goto Definition
// &#34;F12&#34;转到定义
{
&#34;keys&#34;: [
&#34;f12&#34;
],
&#34;command&#34;: &#34;lsp_symbol_definition&#34;,
&#34;args&#34;: {
&#34;side_by_side&#34;: false,
&#34;force_group&#34;: true,
&#34;fallback&#34;: false
},
&#34;context&#34;: [
{
&#34;key&#34;: &#34;lsp.session_with_capability&#34;,
&#34;operator&#34;: &#34;equal&#34;,
&#34;operand&#34;: &#34;definitionProvider&#34;
},
{
&#34;key&#34;: &#34;auto_complete_visible&#34;,
&#34;operator&#34;: &#34;equal&#34;,
&#34;operand&#34;: false
}
]
},
// Terminus
// &#34;F2&#34;打开或关闭Terminus面板
{
&#34;keys&#34;: [
&#34;f2&#34;
],
&#34;command&#34;: &#34;toggle_terminus_panel&#34;,
&#34;args&#34;: {
&#34;cwd&#34;: &#34;${file_path:${folder}}&#34;
}
},
]

7065ffb17641a9443ad2ca61932acde7.png
怎么总感觉少了点什么?是没有调试工具!
5. 配置LLDB调试
这里得承认vscode的调试比sublime强大得多,如果极其依赖调试的话建议转VScode。
由于我是用Clang编译的C++文件,所以用 LLDB 来调试,当然如果你想用 GCC 编译,可以选择GDB调试。
注意,如果选择GDB调试的话,需要下载nodejs并且配置环境变量,较为复杂。由于这篇文章是给小白看的,所以只要LLDB够用就不多加赘述。最后奉劝各位准备装nodejs的兄弟,先装NVM(nodejs version manager),太香了。
5.1 安装LLDB
打开之前安装好的msys2,输入:
pacman -S mingw64/mingw-w64-x86_64-lldb
5.2 测试LLDB是否安装成功
在sublime里面通过F2打开终端(见4.2的快捷键配置)
然后随便调试一个可执行文件(这里选用test):

ca2bc0728def647b9bf8c28acd55a7d7.png
lldb ../bin/test.exe
C:\Users\hzy\Downloads\MyProject\code>lldb ../bin/test.exe
(lldb) target create &#34;../bin/test.exe&#34;
Current executable set to &#39;C:\Users\hzy\Downloads\MyProject\bin\test.exe&#39; (x86_64).
(lldb) b 10
Breakpoint 1: where = test.exe`main + 112 at test.cpp:10:12, address = 0x00000001400015f0
(lldb) r
(lldb) Process 4168 laun\Users\hzy\Downloads\MyProject\bin\test.exe&#39; (x86_64)
Process 4168 stopped
* thread #1, stop reason = breakpoint 1.1
frame #0: 0x00007ff6642115f0 test.exe`main(argc=1, argv=0x0000025bcc901970) at test.cpp:10:12
7 std::queue<int> q;
8 q.push(100);
9 q.push(2);
-> 10 q.push(20);
11 a = 30;
12 q.push(a);
13 return 0;
(lldb) p q
(std::queue<int, std::deque<int, std::allocator<int> > >) $0 = {
c = size=2 {
[0] = 100
[1] = 2
}
当然,想要更愉快的调试程序,少不了插件的协助。
5.2 安装debugger插件
同理,打开命令面板,进入package control install安装界面,输入debugger回车,等待安装完成。
安装完成后,我们可以在Tools->debugger中打开它。

1e487004ceb6759b6c1d2179f4ff4a3b.png
由于我们还没有建立项目,它提示我们建立sublime project,点击即可创建MyProject.sublime-project和MyProject.sublime-workspace。

aa25b20d09b5ccea71b9370668c421fa.png
前者是对该项目的配置(项目地址等等),后者是对文件操作的记录、记录打开了哪些文件、记住代码补全的选择(一般不进行修改)。
建立项目文件后,debugger就能跑起来了。这时选择Add Config

259017b65e72ba30ca2eb81b0b81298e.png
选择install adapters,我们要安装lldb对应的适配器。(⚠️需要魔法上网)

7b52d94c6940127afe794800a78e2af0.png
选择lldb,进去后选择第一个。(⚠️需要魔法上网)
x

ef8e626942513c993f155d7f13e1b577.png
安装完成。(⚠️需要魔法上网)

fc521c5c768c9aca5205f8a42cb324fb.png
别急,还有,继续点击Add Config

259017b65e72ba30ca2eb81b0b81298e.png
选择Add Configuration

9c14435f8123ee421418eb772473852d.png
选择lldb,然后选择第一个。

da8a7c86ba4116e98efea138f13377f3.png
这一步实际上只是到.sublime-project文件里面插入了一段代码而已。如果显示插入失败的话(Mac就是这样)不用管它,反正这段代码迟早也要被爆改一通。
5.3 配置debugger
此时,基本的LLDB配置都完成了,如果想用GDB的话(或者LLDB因为莫名的错误用不了的话),可以以相同的原理安装GDB适配器。我的sublime-project里面是这样的:
{
&#34;folders&#34;: [
{
&#34;path&#34;: &#34;.&#34;,
}
],
&#34;debugger_configurations&#34;: [
{
&#34;type&#34;: &#34;lldb&#34;,
&#34;request&#34;: &#34;launch&#34;,
&#34;name&#34;: &#34;Launch&#34;,
&#34;program&#34;: &#34;${folder}/bin/${file_base_name}&#34;,
&#34;args&#34;: [],
&#34;cwd&#34;: &#34;${folder}&#34;
},
],
}
勉强可以用,但是更优的配置如下:
{
&#34;folders&#34;: [
{
&#34;path&#34;: &#34;.&#34;
},
],
&#34;debugger_tasks&#34;: [
{
// 用Clang编译
&#34;name&#34;: &#34;CompileWithClang&#34;,
&#34;working_dir&#34;: &#34;${file_path}&#34;,
&#34;shell_cmd&#34;: &#34;clang++ -std=c++11 -g &#39;${file}&#39; -o &#39;${file_path}/../bin/${file_base_name}&#39;&#34;,
&#34;file_regex&#34;: &#34;(..[^:]*):([0-9]+):([0-9]+)?:? error: (.*)&#34;,
},
{
// 用GCC编译
&#34;name&#34;: &#34;CompileWithGCC&#34;,
&#34;working_dir&#34;: &#34;${file_path}&#34;,
&#34;shell_cmd&#34;: &#34;g++ -std=c++11 -g &#39;${file}&#39; -o &#39;${file_path}/../bin/${file_base_name}&#39;&#34;,
&#34;file_regex&#34;: &#34;(..[^:]*):([0-9]+):([0-9]+)?:? error: (.*)&#34;,
},
],
&#34;debugger_configurations&#34;: [
{
// 在Terminus窗口运行程序,使用GDB调试
&#34;name&#34;: &#34;C++ GDB (Terminus)&#34;,
&#34;type&#34;: &#34;gdb&#34;,
&#34;request&#34;: &#34;launch&#34;,
// Debug之前先用GCC编译一波
&#34;pre_debug_task&#34;: &#34;CompileWithGCC&#34;,
// bin目录下的可执行文件
&#34;target&#34;: &#34;${file_path}/../bin/${file_base_name}&#34;,
&#34;cwd&#34;: &#34;${project_path}&#34;,
&#34;terminal&#34;: &#34;external&#34;,
&#34;valuesFormatting&#34;: &#34;parseText&#34;
},
{
&#34;name&#34;: &#34;C++ GDB (Attach)&#34;,
&#34;type&#34;: &#34;gdb&#34;,
&#34;request&#34;: &#34;attach&#34;,
&#34;target&#34;: &#34;${command_pick_process}&#34;, // sublime text 4 only
&#34;cwd&#34;: &#34;${folder}&#34;,
&#34;valuesFormatting&#34;: &#34;parseText&#34;
},
{
// 在Terminus窗口运行程序,使用LLDB调试
&#34;name&#34;: &#34;C++ LLDB (Terminus)&#34;,
&#34;type&#34;: &#34;lldb&#34;,
&#34;request&#34;: &#34;launch&#34;,
// Debug之前先用Clang编译一波
&#34;pre_debug_task&#34;: &#34;CompileWithClang&#34;,
// bin目录下的可执行文件
&#34;program&#34;: &#34;${file_path}/../bin/${file_base_name}&#34;,
&#34;cwd&#34;: &#34;${project_path}&#34;,
// 使用外部终端运行程序(默认是Terminus)
&#34;terminal&#34;: &#34;external&#34;,
},
{
&#34;name&#34;: &#34;C++ LLDB (Attach)&#34;,
&#34;type&#34;: &#34;lldb&#34;,
&#34;request&#34;: &#34;attach&#34;,
&#34;pid&#34;: &#34;${command_pick_process}&#34; // sublime text 4 only
},
],
}
OK,现在再次Tools->debugger->Open(或者在命令面板输入debugger open也可以),点击运行

ca4ef3fa8d5142c4fd8a292b717bacac.png
选择C++ LLDB (Terminus)

519b943bc706bdde7630bebbad55eb78.png
就能愉快地进行调试啦。

81bf3f62376cf728c572bec4f7641ec8.png
3. sublime美化
3.1 美化debugger
我觉得debugger的默认字体太丑了,而且界面元素太大了,不符合sublime的UI风格。
所以我试着把它改为sublime的默认字体(需要安装Monaco字体),UI大小改小。
Monaco字体的下载链接
解压以后双击Monaco

47580e28bd6af294402a8682582c5768.png
点击install就行了

9c65df82dfd5a35f2afbe8f60ba72cd9.png
然后在命令面板输入debugger settings,进入debugger设置界面。黏贴如下设置:
{
// 开sublime不自动启动debugger
&#34;open_at_startup&#34;: false,
// 设置为sublime的默认字体
&#34;font_face&#34;: &#34;Monaco&#34;,
// 字体改小一些
&#34;ui_scale&#34;: 14,
// 自动决定是否显示汇编代码
&#34;lldb_show_disassembly&#34;: &#34;auto&#34;,
&#34;integrated_output_panels&#34;: {
&#34;integrated_output_panels&#34;: {
&#34;diagnostics&#34;: {
&#34;name&#34;: &#34;Diagnostics&#34;,
},// 代码诊断并入debugger界面
&#34;Terminus&#34;: {
&#34;name&#34;: &#34;Terminal&#34;,
&#34;position&#34;: &#34;bottom&#34;
}// Terminus终端并入debugger界面
}
}
}
最终效果图:

ebc603deecab56b60fa4215f0d557a23.png
2023/4/10 更新:
注意,debugger0.10.1版本有重大bug。写这篇文章的时候是没有的。症状如下:

解决方法很简单。
在你的
- Mac: /Users/你的用户名/Library/Application Support/Sublime Text/Packages/Debugger/modules/dap/configuration.py
- Windows: C:\Users\你的用户名\AppData\Roaming\Sublime Text\Packages\Debugger\modules\dap\configuration.py
文件中,修改第207行的正则表达式——把(\${(.*)})改成(\${(\w+)})

如图所示,然后重启sublime就行了。
3.2 美化UI
(觉得sublime的UI已经够好看的可以跳过)
最近 Material UI 比较火。还好sublime也有个material UI插件。
同上,package control install输入material theme

1821e6132d6558f29c8041609ad41ce7.png
安装完成后,它会提示安装图标插件,用来在侧边栏显示各种文件类型。安装就完事了。

cb0197bbd55f79ddd7b42d755e145c4f.png
最后,在命令面板输入material theme activate

b43b3d20434893001fa0ac46bfa67ffb.png
我选的是Material-Theme Darker

0feaa89766ff60fe11cab648649c6cf2.png
再在命令面板输入UI-Select Color Theme

9aa3e8e9f270a6e7528900ec49291f9c.png
我选的是Material Theme

1b4eb1ace30bfa51f123c0e71c07d52f.png
这时,我们可以发现sublime的设置中多了两行:

9da81a4cd7bb4d75247e444d479da8fc.png
4. sublime怎么用?
通过上面的介绍,你可以发现,几乎所有sublime的选项和插件设置都可以在命令面板中找到,打开命令面板的快捷键是Ctrl+Shift+P。
此外,sublime的插件配置都是代码化的,你可以在左侧看到所有的选项和注释(当然需要英文好),在右侧对默认设置进行修改。
下面介绍一些非常实用的快捷键:
可以通过Ctrl+~打开sublime的控制台,一些报错都可以在上面找到并解决。

93362f6f11f41ad59685e6cd2806eed7.png
- 先按Ctrl K再按Ctrl B可以打开/关闭侧边栏
- Ctrl+P 搜索框
- Ctrl+G 跳转到第几行
- Ctrl+W 关闭当前打开文件
- Ctrl+Shift+W 关闭所有打开文件
- Ctrl+Shift+V 粘贴并格式化
- Ctrl+D 选择单词,重复可增加选择下一个相同的单词
- Ctrl+Shift+D 复制光标所在整行,插入到下一行
- Ctrl+L 选择行,重复可依次增加选择下一行
- Ctrl+Shift+L 选择多行
- Ctrl+Shift+Enter 在当前行前插入新行
- Ctrl+X 删除当前行
- Ctrl+M 跳转到对应括号
- Alt+鼠标拖动 多光标选择
- Ctrl+J 选择标签内容
- Ctrl+F 查找内容
- Ctrl+N 新建窗口
- Ctrl+/ 注释
- Ctrl+Shift+K 删除整行
- Tab 向右缩进
- Shift+Tab 向左缩进
- Ctrl+Z 撤销
- Ctrl+Y 恢复撤销
- F6 单词检测拼写
- Ctrl+P 打开搜索框
- Ctrl+Tab 按文件浏览过的顺序,切换当前窗口的标签页。
- 输入当前项目中的文件名,快速搜索文件
- 输入@和关键字,查找文件中函数名
- 输入:和数字,跳转到文件中该行代码
- 输入#和关键字,查找变量名
本文使用 Zhihu On VSCode 创作并发布 |
|