记录一下VSCode配置C++的内容吧。

插件列表

首先列一下目前在VSCode上使用的,涉及到C++的核心插件:

  • C/C++ (Microsoft):微软官方默认的C/C++插件,禁用了代码提示,但是调试这些还需要用它,不能完全禁用
  • clangd (LLVM):LLVM官方提供的,当前代码提示的主力插件
  • CMake (twxs):CMake的语言支持,CMakeLists的语法高亮等
  • CMake Tools (Microsoft):微软官方提供的CMake支持,提供CMake命令工具条和快捷指令
  • CodeLLDB (Vadim Chugunov):lldb调试支持,非官方支持

还有两个不太重要的插件:

  • C/C++ Themes (Microsoft)
  • Better C++ Syntax (Jeff Hykin)

C/C++ 插件和 clangd 插件配置

主要的内容是禁用默认C/C++插件的主要功能,然后用clangd以及对应插件替换掉,并对clangd进行配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//**************************************************************************//
//[[C++]]
// 关闭默认C/C++插件的格式化 C_Cpp.formatting
"C_Cpp.formatting": "disabled",
// 关闭默认C/C++插件的智能提示 C_Cpp.intelliSenseEngine
"C_Cpp.intelliSenseEngine": "disabled",
// 关闭默认C/C++插件的自动补全 C_Cpp.autocomplete
"C_Cpp.autocomplete": "disabled",
// 关闭默认C/C++插件的错误曲线 C_Cpp.errorSquiggles
"C_Cpp.errorSquiggles": "disabled",
// 关闭默认C/C++插件的自动代码分析 C_Cpp.codeAnalysis.runAutomatically
"C_Cpp.codeAnalysis.runAutomatically": false,
// C/C++的默认配置由cmaketools提供 C_Cpp.default.configurationProvider
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
// clangd的分析参数 clangd.arguments
"clangd.arguments": [
"--completion-style=detailed",
"--clang-tidy",
"--background-index",
"--enable-config",
"--header-insertion=never",
"--header-insertion-decorators",
"--fallback-style=LLVM",
// "--fallback-style=WebKit" 4缩进
],
// clangd在没有找到编译指令文件时基于如下编译指令进行静态分析 clangd.fallbackFlags
"clangd.fallbackFlags": [
"-I${workspaceFolder}",
"-I${workspaceFolder}/include",
"-fsanitize=address",
"-fsanitize=undefined",
"-Wall",
"-Wextra",
"-Wshadow",
"-Wfatal-errors",
"-Wno-unused-variable",
"-Wno-unused-parameter"
],
// clangd自动检测插件冲突 clangd.detectExtensionConflicts
"clangd.detectExtensionConflicts": true,
"clangd.checkUpdates": true,

CMaketools 插件配置

对CMake提供支持的插件配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//**************************************************************************//
//[[cmake]]
// cmake关闭自动配置 cmake.autoSelectActiveFolder
"cmake.autoSelectActiveFolder": false,
// cmake关闭在打开时自动配置 cmake.configureOnOpen
"cmake.configureOnOpen": false,
// cmake关闭在编辑时自动配置 cmake.configureOnEdit
"cmake.configureOnEdit": false,
// cmake状态条可见性 cmake.options.statusBarVisibility
"cmake.options.statusBarVisibility": "compact",
"cmake.options.advanced": {
"cpack": {
"statusBarVisibility": "hidden"
},
"workflow": {
"statusBarVisibility": "hidden"
},
"debug": {
"statusBarVisibility": "hidden"
},
"ctest": {
"statusBarVisibility": "icon"
}
},
"cmake.preferredGenerators": [
"Ninja"
],
"cmake.pinnedCommands": [
"cmake.configure",
"cmake.build",
"cmake.cleanConfigure",
"cmake.selectKit",
"cmake.setVariant",
"cmake.showConfigureCommand"
],
"cmake.showOptionsMovedNotification": false,

如果CMakeLists.json插件在识别编译工具链时出现错误,可以手动修改下面的配置文件,或者直接删除,让它重新扫描配置

  • 在Windows中,配置文件位于~/AppData/Local/CMakeTools/cmake-tools-kits.json
  • 在WSL2中,配置文件位于~/.local/share/CMakeTools/cmake-tools-kits.json

C++ 调试配置

下面的部分是关于CMake项目调试的配置,早期这种配置必须存放在项目的.vscode/launch.json文件中, 现在已经支持在settings.json中添加默认配置了。

这三种配置使用的调试器分别是:

  • lldb
  • gdb
  • vsdbg

分别对应与clang,gcc和MSVC。

用它们调试对应的编译器得到的可执行程序通常是没问题的,但是混用是很可能有问题的,在Windows上

  • vsdbg可以调试target是MSVC的clang得到的可执行文件
  • vsdbg不支持调试gcc+MinGW或clang+MinGW得到的可执行文件
  • lldb可能可以替代gdb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//**************************************************************************//
//[[launch]]
// 默认的launch设置,搭配cmake和gdb/lldb使用,不需要单独的launch.json
"launch": {
"configurations": [
{
"name": "lldb(CMake)",
"type": "lldb",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"args": [],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
},
{
"name": "gdb(CMake)",
"type": "cppdbg",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "PATH",
"value": "${env:PATH}:${command:cmake.getLaunchTargetDirectory}"
}
],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"miDebuggerArgs": "-q -ex quit; wait() { fg >/dev/null; }; /usr/bin/gdb -q --interpreter=mi"
},
{
"name": "vsdbg(CMake)",
"type": "cppvsdbg",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "PATH",
"value": "${env:PATH}:${command:cmake.getLaunchTargetDirectory}"
}
],
"console": "externalTerminal"
}
],
"compounds": []
},

clangd 配置

这里的clangd指的是专门的软件(通常在下载clang时附带下载),并不是VScode插件,关于clangd主要有三种配置文件:

  • .clangd:主配置文件;
  • .clangd-tidy:关于C++静态检查的配置文件;
  • .clangd-format:关于C++格式化检查的配置文件;

.clangd

clangd有时候比较蠢,我们可以通过在项目根目录添加.clangd配置文件来协助,例如它很可能在Windows上找不到正确的标准库头文件,而是会跳转到MSVC的标准库头文件,我们可以添加--include-directory=来指定。

.clangd 示例如下

1
2
3
4
5
6
7
8
CompileFlags:
Add:
- '-Wall'
- '-Wextra'
- '-Wshadow'
- '-Wno-unused-parameter'
- '-std=c++17'
- '--include-directory=/path/to/compiler/include'

有时候需要使用C语言项目,但是默认的配置是针对C++的,对于C语言项目可以使用下面的配置,重点是-xc选项

1
2
3
4
5
6
7
CompileFlags:
Remove: [-std=*]
Add: [-xc, -Wall]
Compiler: clang
Diagnostics:
ClangTidy:
Remove: readability-identifier-naming

除此之外,clangd主要会基于compile_commands.json文件进行代码提示,CMake项目可以用特定选项在build/中自动生成compile_commands.json

.clang-tidy

clang-tidy可以提供C++的静态语法检查,包括很多具体规则的检查,需要通过.clang-tidy配置文件设置。

可以使用如下的注释去关闭特定位置的特定检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
关闭当前行的所有检查 // NOLINT
关闭当前行的特定检查 // NOLINT(xxx)

关闭下一行的所有检查 // NOLINTNEXTLINE
关闭下一行的指定检查 // NOLINTNEXTLINE(xxx)

关闭一部分区域的全部检查
// NOLINTBEGIN(check-name)
...
// NOLINTEND(check-name)

关闭一部分区域的指定检查
// NOLINTBEGIN
...
// NOLINTEND

.clang-tidy 模板如下,具体含义可以参考clang官方文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
Checks: 'bugprone-*,
-bugprone-easily-swappable-parameters,
cert-*,
-cert-env33-c,
-cert-dcl50-cpp,
-cert-err33-c,
clang-analyzer-*,
cppcoreguidelines-*,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-vararg,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-avoid-const-or-ref-data-members,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-pro-type-cstyle-cast,
-cppcoreguidelines-owning-memory,
google-*,
-google-objc-*,
-google-readability-todo,
-google-readability-casting,
hicpp-*,
-hicpp-vararg,
llvm-*,
misc-*,
-misc-non-private-member-variables-in-classes,
-misc-unused-parameters,
-cppcoreguidelines-non-private-member-variables-in-classes,
modernize-*,
-modernize-loop-convert,
-modernize-use-nodiscard,
-modernize-use-trailing-return-type,
-modernize-avoid-c-arrays,
-cppcoreguidelines-avoid-c-arrays,
-hicpp-avoid-c-arrays,
mpi-*,
performance-*,
-performance-unnecessary-value-param,
readability-*,
readability-identifier-naming,
-readability-braces-around-statements,
-hicpp-braces-around-statements,
-google-readability-braces-around-statements,
-readability-identifier-length,
-readability-redundant-control-flow,
-readability-magic-numbers,
-cppcoreguidelines-avoid-magic-numbers,
-readability-const-return-type,
fuchsia-default-arguments-declarations
'

CheckOptions:
- {key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE}
- {key: readability-identifier-naming.NamespaceCase, value: lower_case}
- {key: readability-identifier-naming.ClassCase, value: CamelCase}
- {key: readability-identifier-naming.StructCase, value: CamelCase}
- {key: readability-identifier-naming.EnumCase, value: CamelCase}
- {key: readability-identifier-naming.TypedefCase, value: CamelCase}
- {key: readability-identifier-naming.TypeAliasCase, value: CamelCase}
- {key: readability-identifier-naming.TemplateParameterCase, value: CamelCase}
- {key: readability-identifier-naming.ValueTemplateParameterCase, value: CamelCase}
- {key: readability-identifier-naming.ParameterCase, value: aNy_CasE}
- {key: readability-identifier-naming.MethodCase, value: lower_case}
- {key: readability-identifier-naming.PublicMethodCase, value: aNy_CasE}
- {key: readability-identifier-naming.MemberCase, value: lower_case}
- {key: readability-identifier-naming.PublicMemberCase, value: aNy_CasE}
- {key: readability-identifier-naming.PrivateMemberPrefix, value: m_}
- {key: readability-identifier-naming.FunctionCase, value: aNy_CasE}
- {key: readability-identifier-naming.VariableCase, value: aNy_CasE}
- {key: readability-identifier-naming.ConstexprVariableCase, value: aNy_CasE}
- {key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor, value: true}
- {key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions, value: true}
- {key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctionsWhenCopyIsDeleted, value: true}
- {key: hicpp-special-member-functions.AllowSoleDefaultDtor, value: true}
- {key: hicpp-special-member-functions.AllowMissingMoveFunctions, value: true}
- {key: hicpp-special-member-functions.AllowMissingMoveFunctionsWhenCopyIsDeleted, value: true}
- {key: readability-function-cognitive-complexity.IgnoreMacros, value: true}
- {key: readability-function-cognitive-complexity.Threshold, value: 40}
- {key: cppcoreguidelines-avoid-do-while.IgnoreMacros, value: true}
- {key: hicpp-signed-bitwise.IgnorePositiveIntegerLiterals, value: true}

.clang-format

clang-format可以提供C++的代码格式化,包括很多具体规则的检查,需要通过.clang-format配置文件设置。

可以使用如下的注释去关闭特定位置的格式化

1
2
3
// clang-format off
...
// clang-format on

.clang-format 模板如下,下文中的注释行是默认设置或者目前被舍弃的选项, 更完整的内容可以参考clang官方文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
---

# 语言
Language: Cpp
# 基于LLVM风格进行微调
BasedOnStyle: LLVM
# 访问说明符(public、private等)的偏移
AccessModifierOffset: -4
# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
# 例如
# someLongFunction(argument1,
# argument2);
# AlignAfterOpenBracket: Align
# 连续赋值时,对齐所有等号
# AlignConsecutiveAssignments: Consecutive
# 连续声明时,对齐所有声明的变量名
# AlignConsecutiveDeclarations: Consecutive
# 对齐逃脱换行(使用反斜杠换行)的反斜杠
# AlignEscapedNewlines: Right
# 水平对齐二元和三元表达式的操作数
# AlignOperands: Align
# 对齐连续的尾随的注释
# AlignTrailingComments: true
# 允许函数声明的所有参数在放在下一行
# AllowAllParametersOfDeclarationOnNextLine: true
# 允许短的块放在同一行
AllowShortBlocksOnASingleLine: Always
# 允许短的case标签放在同一行
AllowShortCaseLabelsOnASingleLine: true
# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
# AllowShortFunctionsOnASingleLine: All
# 允许短的if语句保持在同一行,除非没有else分支
AllowShortIfStatementsOnASingleLine: WithoutElse
# 允许lambda表达式在同一行
# AllowShortLambdasOnASingleLine: All
# 允许短的循环保持在同一行
AllowShortLoopsOnASingleLine: true
# 函数是否在定义返回类型后换行
# AlwaysBreakAfterReturnType: None
# 总是在多行string字面量前换行
# AlwaysBreakBeforeMultilineStrings: false
# 是否在template声明后换行
AlwaysBreakTemplateDeclarations: true
# false表示函数实参要么都在同一行,要么都各自一行
# BinPackArguments: true
# false表示所有形参要么都在同一行,要么都各自一行
# BinPackParameters: true


# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: NonAssignment
# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似),
# Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似),
# Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom(自定义)
# 注:这里认为语句块也属于函数
BreakBeforeBraces: Custom
# 大括号换行自定义规则,只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:
# class定义后面
AfterClass: false
# 控制语句后面
AfterControlStatement: Never
# enum定义后面
AfterEnum: false
# 函数定义后面
AfterFunction: false
# 命名空间定义后面
AfterNamespace: false
# struct定义后面
AfterStruct: false
# union定义后面
AfterUnion: false
AfterExternBlock: false
# catch之前
BeforeCatch: true
# else之前
BeforeElse: true
# 大括号
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: true


# 在构造函数的初始化列表的逗号前换行
# BreakConstructorInitializersBeforeComma: false
# BreakConstructorInitializers: BeforeColon
# 每行字符的限制,0表示没有限制
# ColumnLimit: 80
# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变
# CommentPragmas:'^ IWYU pragma:'
# 嵌套的命名空间的namespace语句是否合并到一行
# CompactNamespaces: false
# 构造函数的初始化列表的缩进宽度
# ConstructorInitializerIndentWidth: 4
# 延续的行的缩进宽度
# ContinuationIndentWidth: 4
# 去除C++11的列表初始化的大括号{后和}前的空格
# Cpp11BracedListStyle: true
# 基于当前文件中最常用的指针和引用的对齐方式进行处理
# DerivePointerAlignment: false
# 对于public/private之类的非空部分,自动加入空行进行分隔
# EmptyLineBeforeAccessModifier: LogicalBlock
# 在命名空间的}后面自动添加注释 // namespace XXX
# FixNamespaceComments: true
# 缩进宽度
IndentWidth: 4
# 函数返回类型之后立刻换行时,是否缩进函数声明或函数定义的函数名
# IndentWrappedFunctionNames: false
# 保留在块开始处的空行,这里不允许块开头有空行
KeepEmptyLinesAtTheStartOfBlocks: false
# 开始一个块的宏的正则表达式
# MacroBlockBegin: ''
# 结束一个块的宏的正则表达式
# MacroBlockEnd: ''
# 连续空行的最大数量
# MaxEmptyLinesToKeep: 1
# 命名空间的缩进: None, Inner(只缩进嵌套的命名空间中的内容), All
# NamespaceIndentation: None
# 视作命名空间的宏列表,类似的还有视作if的,视作foreach的宏
# 例如
# NamespaceIndentation:
# - MACRO1
# - MACRO2
# NamespaceMacros
# 在call(后对函数调用换行的penalty
# PenaltyBreakBeforeFirstCallParameter: 19
# 在一个注释中引入换行的penalty
# PenaltyBreakComment: 300
# 第一次在<<前换行的penalty
# PenaltyBreakFirstLessLess: 120
# 在一个字符串字面量中引入换行的penalty
# PenaltyBreakString: 1000
# 对于每个在行字符数限制之外的字符的penalty
# PenaltyExcessCharacter: 1000000
# 将函数的返回类型放到它自己的行的penalty
# PenaltyReturnTypeOnItsOwnLine: 60
# 指针和引用的对齐: Left, Right, Middle
# PointerAlignment: Right
# 引用的对齐(参照指针)
# ReferenceAlignment: Pointer
# 允许重新排版注释,保证行的长度
# ReflowComments: true
# 在函数之间,类和结构体之间自动使用空行分隔
SeparateDefinitionBlocks: Always
# 大小写敏感地排序include
# SortIncludes: CaseSensitive
# 在C风格类型转换后添加空格
# SpaceAfterCStyleCast: false
# 在template关键词之后紧接着加空格
# template <int> void foo();
# SpaceAfterTemplateKeyword: true
# 在赋值运算符例如+=和=之前添加空格
# a += 5;
# SpaceBeforeAssignmentOperators:true
# 开圆括号之前添加一个空格: Never, ControlStatements, Always
# SpaceBeforeParens: ControlStatements
# 在空的Block中添加空格
# SpaceInEmptyBlock: false
# 在空的圆括号中添加空格
# SpaceInEmptyParentheses: false
# 在尾随的注释前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 2
# 在尖括号的<后和>前添加空格
# SpacesInAngles: Never
# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
# SpacesInContainerLiterals: true
# 在C风格类型转换的括号中添加空格
# SpacesInCStyleCastParentheses: false
# 在圆括号的(后和)前添加空格
# SpacesInParentheses: false
# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响
# SpacesInSquareBrackets: false
# tab宽度
TabWidth: 4
# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Never
---

移除注释之后,更简洁的版本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
---

Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -4
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakTemplateDeclarations: true

BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: true

KeepEmptyLinesAtTheStartOfBlocks: false
SeparateDefinitionBlocks: Always
SpacesBeforeTrailingComments: 2
IndentWidth: 4
TabWidth: 4
UseTab: Never
---

补充

必要软件

为了正常使用所有功能,除了针对VSCode的配置,至少还需要单独安装下列软件,并把路径添加到PATH

  • Git
  • CMake
  • ninja

vscode 快捷键

和 vim 类似,为了提高效率,有必要整理一下 vscode 常用的快捷键。(虽然 vscode 也支持 vim 模式,但是毕竟没有原始的快捷键体系方便)

两个最主要的:

  • ctrl+p 快速打开
    • :n 转到第 n 行
    • @symbol 查找并跳转到符号(对于 md 文件是各级目录)
    • filename 打开当前文件夹的其他文件
  • ctrl+shift+p 快速打开命令面板(相当于快速打开后加上>继续输入命令)
  • ctrl+shift+o 快速打开符号查找(相当于快速打开后加上@继续输入命令)

主要操作

  • ctrl+, 进入设置的 GUI 界面
  • ctrl+shift+n 打开新的 vscode 窗口实例
  • ctrl+shift+m 显示问题界面
  • `ctrl+`` 显示或关闭集成终端界面
  • ctrl+shift+~ 显示集成终端界面并新建一个终端实例
  • ctrl+<enter>在下方插入一行,光标也随之移动
  • ctrl+shift+<enter>在上方插入一行,光标也随之移动(这个有很多快捷键冲突,可能没有用)

当前光标未选择内容时,复制剪切粘贴都是以当前行为单位进行的:

  • ctrl+c 复制当前行
  • ctrl+x 剪切当前行
  • ctrl+v 粘贴到当前行的前面

其他

  • ctrl+shift+k删除当前行
  • alt+up 把当前行上移
  • alt+down 把当前行下移
  • shift+alt+up 把当前行复制并插入到上方
  • shift+alt+down 把当前行复制并插入到下方