这里比较推荐使用 Emacs 系的快捷键而不是传统的 Command + ←/→/Delete之类的。因为后者并不通用,比如在终端中就无法使用,而 Emacs 系的快捷键则在几乎所有系统级别的输入框内都通用。
常见的几个行级别操作有:
前三个命令在终端中非常常用,能大幅度提高工作效率。后两个命令则在 Vim 系列中很常见,多用于上下切换列表中的选项。
几个比较常见的字母级别操作有:
→ + Delete
这个快捷键也很常用Delete
如果觉得按字母操作太过于细粒度,按行操作又太粗粒度,那么 Option 键绝对算得上神器,因为它可以按单词操作。
对于一些文本文件,按下空格键就可以调用系统的预览程序,快速浏览文件内容。但如果想获得更好的阅读体验,或支持更多类型文件的快速浏览,就需要通过插件来完成。
可以输入以下命令来安装拓展,下面会逐个介绍:
brew cask install qlcolorcode qlstephen qlmarkdown quicklook-json qlimagesize webpquicklook qlvideo provisionql quicklookapk
顾名思义,这是一个代码高亮的插件,效果如图所示:
详见原著
这个插件能让我们预览没有后缀的文本文件,效果如图所示:
详见原著
这个插件能让我们预览 markdown 文件的渲染效果:
详见原著
这个插件也很容易理解,提供对 JSON 文件的格式化和高亮支持:
详见原著
这个插件我没有安装,因为它需要付费,它可以预览压缩文件内部的内容,还支持自定义各种解压缩时的行为(比如解压缩后自动删除压缩包)。下图是安装前的压缩文件预览图:
安装 BetterZip 前系统默认样式
详见原著
安装 BetterZip 后的预览效果
详见原著
这个拓展可以展示图片的分辨率和大小:
qlimagesize 效果
详见原著
这个拓展可以让我们预览 WebP 格式的图片:
预览 WebP 格式图片
详见原著
预览更多格式的视频文件:
qlvideo 预览视频
详见原著
这个差距可以预览 .app 或者 .ipa 后缀的程序:
预览 ipa 或 app 文件
详见原著
预览安卓的 .apk文件:
预览 apk 文件
详见原著
以上就是和程序员相关的常用插件,还有一些设计师可能用到的插件,可以访问这个网址自行查看。
默认情况下,键盘最上面一排的 F1- F12 都有各自的作用,从图标上就能看出。比如 F1 和 F2 用来调节屏幕亮度,F5 和 F6 调节键盘灯亮度灯。此时他们可以被理解为特殊按键,更偏向与娱乐,而不是普通的 F1 - F12。
对于工作重心在编程的码农来说,这些特殊按键有些浪费,而很多 IDE 提供的快捷键都需要 F1 - F12,尤其在断点调试时格外有用,以 Xcode 为例说明下:
将 F1、F2 等设置为标准功能按键或者更高效的做法是使用命令行:
defaults write -globalDomain com.apple.keyboard.fnState -int 1
很多操作都会弹出系统的对话框,要求我们确认或者取消
如果没有开启完全键盘控制,我们只能按回车键确认,或者移动鼠标选择取消。如果开启了完全键盘控制,只要按下空格键,就相当于选中蓝色边框的按钮,也就是这里的取消键。按下 Tab 键可以在多个按钮之间切换。
完全键盘控制可以在系统的设置界面开启,也可以直接通过命令行开启:
defaults write NSGlobalDomain AppleKeyboardUIMode -int 3
无论是公司邮箱还是个人邮箱,经常会收到具备某些固定特征的邮件。比如银行信用卡的邮件,某个网站订阅后的邮件,或者公司内特定部门、发件人的邮件等等。对于这类具备固定特征的邮件,我们可以利用系统自带的邮件应用,给他们添加分类、过滤规则。
以个人邮箱为例,假设我想整理所有谷歌账号相关的通知邮件,首先在邮箱列表找到它,然后点击右侧的加号,添加某个子文件夹:
详见原著
然后输入子文件夹的名字:
详见原著
接下来在邮件列表中选中来自谷歌的账号提醒邮件,按下 Command + , 打开邮件设置,找到最后一列的规则,选择添加规则。注意:也可以不选中邮件直接添加规则,这样的缺点是不能识别邮件的特征,需要自己手动填写。
点击添加规则:
详见原著
首先填写规则描述,这个只要能让自己以后看得懂即可。可以给规则添加多个条件,并且指定同时满足或满足任一条件。
每个条件可以在邮件的发件人、主题、收件人等各种特征之间选择,如果当初选中了邮件再打开规则列表,就会自动那条邮件的特征,否则只有自行填写了。
最后的操作可以有多个,比如先标记为已读/星标再移动到刚刚创建的子文件夹下,或者对于公司里特别烦人的全员邮件,可以直接删除。
最后点击确定,然后应用到所有邮件即可。
iTerm2 是一个用来取代系统终端的命令行工具,功能比原生的终端程序强大很多,可以一行命令安装:
brew cask install iterm2
上一章 系统快捷键进阶 一节中曾经介绍过光标移动的快捷键,其中以 Ctrl 键开头的快捷键依然可用,比如移动到行首、行尾,向左/右移动或删除字符等等。
但在 iTerm2 中无法使用 Option 键进行单词跳转,因此需要自行配置快捷键,我选择用 Command + ← 来表示光标向左移动一个单词。对应的,向右移动一个单词就是 Command + →。打开设置,添加这两个快捷键:
详见原著
iTerm2 中选择文本有三种方式,分别是:
智能选择是一个比较有意思的功能,完整的介绍可以参考官方文档。对于我来说,以下几种情况下用智能选择是非常棒的:
namespace::identifier
以及 foo.bar.baz
这种语法"this is a quoted string"
另外,iTerm2 默认选中即复制,所以不用额外的 Command + C
这一步了。
Command 主要用来打开文件或者 URL。对于输出到终端的文件名或者 URL,我们可以按住 Command 键点击它,就可以直接打开了。
此外,按下 Command + Option
还可以选中矩形范围内的文本。
按下 Command + T
可以新建一个 Tab,每个标签页的后面都会标记一个序号,通过 Command + 序号
就可以在多个页面之间切换了,或者用 Command + [
和 Command + ]
来切换到左侧或者右侧的标签页。
同一个 Tab 内,还可以切分出多个 Pane,有两种切分方式:
通过 Command + Ctrl + 方向键
可以调整每个 Pane 的大小,通过 Command + Option + 方向键
可以切换 Pane。
有时候,如果上一条命令出现了某个小错误,其实不必重新打一遍,可以使用 \^old\^new
的写法进行替换:
详见原著
对于特别长的命令,可以使用 zsh 提供的快捷键 Ctrl-x + Ctrl-e
进入 vim 编辑:
详见原著
Alfred 绝对是让 Mac 更加好用的神器之一,如果 Mac 上只能安装一款三方软件,那绝对是 Alfred。我把 Alfred 拔高到如此地位绝非是为了捧杀它,而是确实实至名归,本文主要会介绍 Alfred 原生的用法。
除了 Alfred 软件自带的功能外,它还允许用户自己开发 workflow 并分享出来,正是这些 workflow,彻底奠定了 Alfred 的神器地位,下一章将会详细介绍它们的详细使用方式。
打开程序,首页中可以编辑 Alfred 的启动快捷键,这里我把它设置为 双击 Command 键,最好用的 App 当让要配备最好按的快捷键。
详见原著
Alfred 使用的是免费 App + 付费高级功能的模式,本文所介绍的所有内容都是 Alfred 免费提供的。
文件搜索是 Alfred 最基础的功能,类似于系统的 Spotlight,直接双击 Command 打开 Alfred 的窗口,然后输入文件名即可。
详见原著
这也是为什么我会设置 Dock 栏隐藏的原因,毕竟有了 Alfred,谁会去 Dock 里面找 App 呢。
关于文件的搜索,我们还可以配置搜索的范围,搜索哪些类型的文件等等,读者可以在 Features -> Default Results 中配置。
如果我们想通过 Google 搜索东西,常规步骤是:
然而有了 Alfred,搜索步骤变成了:
如图所示,先输入字母 g,大概率你会看到这个场景:
详见原著
这说明 Alfred 目前认为,你最有可能的行为是搜索 Chrome 这个应用并打开,所以把它排在第一位,第二个选项才是使用 Google 搜索。
没关系,我们 按照提示,按下 Command + 2
,效果等同于点击第二个选项。Alfred 很聪明,会智能记忆,只要多重复几次,使用 Google 搜索就变成默认选项了。
详见原著
此时按下 Tab 键或者回车键都可以快速补全命令:
详见原著
输入想要搜索的内容按下回车,Alfred 就会自动帮我们打开浏览器,并且拼接好地址,直接跳转过去。
PS:如果你觉得 Google 搜索非常高频,不想每次把 g 补全为 google,可以在 Features -> Web Search 中修改 Google 搜索的 keyword。在 Web Search 的配置中,你还会看到除了 Google 搜索外,更多的搜索方式,比如搜索 Wikipedia、YouTube 和 Gmail 等等。
有了 Alfred,我们就不需要找到系统的计算器并打开了,可以直接在 Alfred 中做基本的运算:
详见原著
考虑下面几种场景,你的做法是什么?
有了 Alfred 的剪贴板增强,以上场景都不是问题,首先要在 Features -> Clipboard 中打开剪贴板历史:
详见原著
这里我把它们都设置为存储三个月,同时把打开剪贴板的快捷键设置为 Command + Shift + C
,按下快捷键我们会看到:
详见原著
所有的复制历史,包括图片的预览都一目了然,我们还可以搜索剪贴板历史:
详见原著
同样通过 Command + 数字键
,就可以把它粘贴出来。同时被粘贴出来的内容会移动到剪贴板历史的最前方。
有一些文本是需要反复输入的,比如你的邮箱、QQ 号、地址、手机号码、某个网址等信息,亦或者聊天常用语句、表情等等,这些都可以通过 Alfred 来管理,节省输入时间。打开 Features ->; Snippets:
详见原著
首先勾选右上角的 Automatically expand,它表示只要你输入关键字,就会自动展开成文本内容。
详见原著
建议根据文本的使用场景,建立多个 Collection,比如开发相关的,个人信息相关的,聊天相关的等。
我使用了 neovim 来替代 vim,主要区别在于 neovim 更加先进,并且支持插件的异步加载。在使用上和 Vim 几乎是一致的
安装 NeoVim 需要以下几步:
brew install nvim
pip3 install --trusted-host pypi.python.org neovim jedi ipython
pip3 install --user --upgrade --trusted-host pypi.python.org PyYAML
# 下载配置
git clone https://github.com/bestswifter/vim-config.git ~/.config/nvim
ln -s ~/.config/nvim ~/.vim
用 nvim 命令打开文件后可以看到如下效果:
详见原著
Vim 分为三种模式:
普通模式是 Vim 的一大特色,能够进行很多操作,比如:
使用 nvim 打开文件后,默认进入普通模式,如果我们要编辑文本,可以按下 i
进入编辑模式,编辑完后再按下 Esc
键可以退出输入模式,进入到普通模式。
如果想退出 nvim,则需要借助命令模式。按下 :
并输入以下内容之一:
因为每次按下冒号还挺麻烦,所以我对我的 Vim 做了配置,无需进入命令模式,直接在普通模式就可以退出:
nnoremap q :pclose!:quit
nnoremap :x
// nnoremap 表示普通模式下的 map,等价于先输入冒号再输入 quit
// inoremap 表示输入模式下的 map,因此输入模式下也可以用 C-q 快捷键
nnoremap ::quit!
inoremap ::quit!
上一节中我们介绍了 Vim 的基本操作,靠着 i
、:x
等指令,配合上方向键,基本上能在 Vim 的世界里幸存下来了。勉强编辑一下服务器上的文件不是问题。
如果你的打字手势标准的话,你会发现方向键其实挺难触摸到,至少会破坏右手的姿势。因此在 Vim 中不鼓励使用方向键,可以用 hjkl
来代替:
如果要向上移动 5 行,或者向右移动 10 个字符,我们是不是要重复按下很多次呢?显然只有方向键才要这么做,Vim 中可以用数字来表示重复:
这个操作虽然简单,但是引出了两个很有意思的话题。首先,Vim 中的行号应该配置为相对行号 + 绝对行号:
详见原著
图中左侧高亮显示的 22 是当前的绝对行号,上下都是相对偏移量。这样的好处在于既方便知道当前的位置,又方便通过相对行号进行跳转。
另一个话题则是贯穿 Vim 始终的核心思想:就像英语、中文有语法一样,Vim 也有语法。
Vim 的操作可以由若干个部分组合而成,每个部分又有多个可选值(比如光标移动就分上下左右)。Vim 的入门难度高,是因为每个部分都要学习,一下子需要掌握很多新知识点。但 Vim 后期的学习成本很低,因为无非就是各种组合而已。
还是以光标移动为例,5j
由重复次数和动作组成,后面我们会介绍更多的动作,而且它们的前面都可以加上数字表示重复。
前面我们讲过利用 Option
键进行单词间移动,得益于普通模式和语法,Vim 支持更强大的单词间移动:
w
移动光标到下一个单词的词首(word)b
移动光标到上一个单词的词首(begin)e
移动光标到下一个单词的结尾(end)ge
移动光标到上一个单词的结尾(不知道怎么解释了。。。)这里的单词是有严格约定的,而且不是那么显然,所以个人感觉这几个键并不是特别好用(往往你以为的跳转地址和真实跳转地址并不一致)。
不过如果你把空格当做单词的分隔符,倒是有比较简单的跳转方式,前三个命令都有大写格式:
W
移动光标到下一个单词的词首(word)B
移动光标到上一个单词的词首(begin)E
移动光标到下一个单词的结尾(end)这里的单词特指以空格分割。
同样的,这些移动也支持重复任意多次
在后面的插件一节中,我会介绍如何用 EasyMotion 来让光标移动变得简单。
在行内,^
表示移动到行首,它会自动忽视掉行首的空格,大部分情况下这是符合预期的,尤其是在代码缩进的情况下。如果想回到行首的空格上,可以用 0
。$
表示移动到行尾。
Vim 的翻页快捷键是:
很巧的是,前两个命令和系统输入框内的,向左向右移动一个字符的快捷键是一样的。后两个命令(u 和 d)则被 Vimium 借鉴,用于浏览器的翻页。
还有几个快捷键可以用于调整页面布局:
zz
让当前行居中显示,方便浏览上下文zt
让当前行显示在最上方,方便浏览后面的内容(t 表示 top)zb
让当前行显示在最下方,方便浏览前面的内容(b 表示 bottom)代码中经常遇到括号(包括(
、[
和 {
,也就是大中小三中括号),如果当前光标停留在括号上,按下 %
即可匹配到对应的括号上。
除此以外,*
和 #
分别表示匹配当前光标下的单词,并移动到下一个单词和上一个单词
阅读完前两章,相信读者以及能够在 Vim 中自如的移动光标了,不过我们的编辑方式还比较简陋,只能进入编辑模式,像往常一样逐个字符的输入和删除,本节会介绍一些更高级的操作。
在普通模式下,按下 o
会快速进入输入模式,并且在下一行进行编辑。如果按下大写的 O
会在上一行编辑:
详见原著
如果想在当前光标位置开始编辑,可以按下 a
或 i
,前者表示在光标所在字符的右侧开始编辑,后者表示在左侧开始编辑。
我们还可以用 I
前往行头开始编辑,或者用 A
跳转到行尾编辑。
按下 dd
可以快速删除一行,此时被删除的那一行会保存在 Vim 的剪贴板中。这一点类似于系统的 Ctrl + X 剪切,我们可以通过配置 Vim 来选择是否要与系统共享剪贴板。
普通模式下,按下 p
可以把 Vim 剪贴板中的内容再拷贝出来,注意这里总是会拷贝到下一行或者光标的右侧。因此如果想交换当前行和下一行,可以输入:ddp
,这是因为当前被删除的行会复制到下一行的下面。
如果只想复制,不想删除,可以把命令 p
换成 y
(表示:yank)。如果想删除后进入编辑模式,可以把 p
换成 c
,比如 cc
表示删除当前行并且从行首开始编辑。
注意这里的 p、c、y、d
都是动作,和前面说的 j、k、l、h、w、b、e
一样,都支持用数字来重复,比如 2dd
表示删除两行。
如果想撤销上一次修改,可以用 u
,类似于系统的 Command + z
快捷键。
如果想重做,可以用 Ctrl + R
,类似于系统的 Command + Shift + z
快捷键。
Vim 的文本对象能极大幅度的提高编辑效率,也是 Vim 进阶之路上必须要掌握的概念。
对于上文介绍的 c、d、y
这些动作来说,作为单独的动作用处并不大,无非就是连续按两下对当前行做一些操作,而文本对象则扮演了语法中名词的概念,提供了更细粒度的操作。比如以下几种操作:
diw
: 删除一个单词(word)ca"
:删除双引号内的文本并编辑(包含双引号自身)yi"
:复制双引号内的文本(不包含双引号自身)dtx
:向右删除,直到遇到遇到字符 x(不包含 x)以上三个命令都属于同一大类操作,它们普遍遵循以下模式:
命令 = 动作 + 数量 + 描述词 + 文本对象
这类命令通常由三个到字母组成:
c、y、d
等,表示你这个命令的主要目的。a
表示包含边界,i
不包含,t
表示向右查找,T
向左。"、’、<、`、{、(
等等,也可以是固定单词这里详细介绍下文本对象,除了字面量外,以下单词有特定的含义:
abc
的结构,此时的 t 代表 abc对于字面量的文本对象,除了 "、’ 和 这三个引号外,另外几个括号都可以用 b 来表示(block),这样就不用区分大中小和尖括号了。
使用 /
进行搜索,我的搜索默认是忽略大小写的,使用 /pattern\C
可以强制匹配大小写。
使用 :范围s/oldpattern/newpattern/替换模式
可以进行替换。
如果我们已经进行过搜索,那么 oldpattern
可以省略不写,默认就是上一次的搜索内容。
最常用的范围是 begin,end
,其中 begin
是开始行号,end
是结束行号,表示在第 begin 行到第 end 行之间进行替换,比如::1,10s/hello/hallo/g
表示把第 1 - 10 行中所有的 hello
换成 hallo
。
范围还有一些简单的表示法:
.,10
表示当前行到第 10 行,点表示当前行.,$
表示当前行到文件末尾,美刀符号表示文件结尾%
表示 1,$
,也就是整个文件,比如全文替换通常写成 :%s/old/new/g
.,+2
表示当前行和接下来的两行上文反复提到的字母 g 其实是一种替换模式,表示替换这个范围内所有出现的 oldpattern
,如果不写则只替换第一次出现。常用的模式还有 c
,表示替换需要确认(Confirm),i
表示大小写不敏感,I
表示大小写敏感。
如果需要替换光标停留的单词,并不需要搜索,或者手动输入它。直接使用
即可。接下来只需要输入替换后的内容和替换模式。这种替换是全局替换。
以下是几个常用的,切换大小写的命令
guu
当前行全部小写,gUU
当前行全部大写~
当前光标下的字符切换大小写,3~
当前光标下后面三个字符切换大小写guiw
当前单词全部小写,gUiw
当前单词全部大写g~iw
当前单词每个字符大小写交换如果有多行文本要做相同的操作,可以借助 Vim 中列操作的概念来快速完成,举一个实际实际的例子,假设有以下这段代码:
int a;
int b;
int c;
// ...
int z;
有一天我们发现 int
不是很准确,要改成:
uint8_t a;
uint8_t b;
uint8_t c;
// ...
uint8_t z;
难道还要手动复制粘贴不成?请看列操作大法:
Ctrl + V
进入列操作模式j、k
进行跳转,表示你要操作多少行ec
,删除单词进入编辑模式uint_8
,按下 Esc
退出编辑,Vim 会自动应用到所有行上。列操作的本质是多行同时操作,如果每一行的操作类似,但都有细微差别,就需要引入 录制、回放 的概念了。此时可以用 Vim 中的宏。
一个典型的场景是,我们在写 Markdown:
1. 第一条
2. 第二条
3. 第三题
...
10. 第十条
写着写着突然发现,第一条和第二条中间还要加一条,左边的序号就不好处理了,因为我们要把原来的序号 2 到 10 分别加一。
在 Vim 中,我们“只”需要输入 qajC-aq6@a
,相信你一定很想打我,这特么一点也不简单啊。别急,拆开来看:
qa(q 表示开始录制宏,a 表示录制内容存储在寄存器 a 中)
j(向下一行)
Ctrl + a(数字加一)
q(再按一次 q 表示结束录制)
6@a(把存储在寄存器 a 中的宏执行 6 次)
是不是感觉 So Easy(录像中我用的是大写 Q,因为小写 q 被映射了):
详见原著
在本章的开头,我就提到目前的主力 IDE 是 VSCode,其实和 Atom/Sublime 这类 IDE 一样,它也是模拟了 Vim 的按键,并不支持 .vimrc
配置文件。不过 VSCode 的强大之处在于,它支持了部分 Vim 的插件。
我想,不需要我做过多解释,读者也能明白这几个被支持的插件的重要性了,必然都是 Life-Changing 系列的。下面就逐个介绍一下:
从名字就能看出,这个插件的目的是快速光标跳转。它支持按行跳转,按字符/字符串跳转和按单词跳转等。跳转时还可以选择方向为向前或者向后, 不过这就增加了一倍的复杂度,作为一个懒人,我一般选择全屏跳转。
我配置的快捷键有:
;s
:按字符串跳转(跳转到开头);w
:按单词的开头跳转;e
:按单词的结尾跳转;c
:按字符串跳转;l
:按行首跳转(忽略空格)完整的快捷键列表可以查看文档。
上一节中介绍过文本对象(Text Object)的概念,它主要用来描述括号和引号中间的文本,但考虑一下变换:
“hello” -> ‘hello’
如果想把双引号换成单引号,就远远比改变 hello 这个单词难了。而 Surround 这个插件的目的,就是为了方便对引号和括号做修改。
它支持以下几种用法:
y s motion +
:给指定范围添加 surround 字符,比如:ysaw"
表示用双引号包裹单词。d s
:删除周围的 surround,比如 ds"
表示删除两侧的双引号c s
:更换周围的 surround,比如 cs"'
表示把周围的双引号换成单引号。大多数 IDE 都支持 Command + /
给当前行添加注释,而且会根据语言自动选择注释方式。
在 Vim 中,给当前行添加/取消注释的方式是用 gcc
,虽然多了一个按键,但按起来更容易了,而且支持多行注释。这里前两个字符 gc
表示按行注释,最后一个 c
表示当前行。如果想注释当前行和下面一行,可以输入 gcj
。
美中不足的是,有些语言(如 HTML)中 VSCode 会用 /* ... */
的写法进行多行注释,这样如果想取消注释,就只能去注释开始或结束的那一行把注释全部取消,而不能只单独取消中间某一行的注释。
输入 gC
可以注释某一块代码,后面接一个文本对象,比如 gCi(
表示注释括号内的东西(不包含括号)。不过个人认为注释小括号的需求几乎不存在,但下面这个场景还是有的,考虑这段代码:
if (1 > 0) {
printf("Hello");
printf("wrold");
}
有时候我们只想注释掉那两行 printf
,写点别的逻辑,有时候会注释掉整个 if
。问题是,怎么用文本对象来表示呢?下一个插件可以让我们用文本对象的方式来表示某一块缩进
其实很简单,一般就两个文本对象:
ii
:表示某一块缩进,不包含上一层,比如上面例子中的两个 printf
aI
:表示某一块缩进,包含上一层,比如上面例子中整个的 if
语句其实还有一个不太常用的,ai
表示某一块缩进,和它的上面一行,也就是上面例子中的前三行,不包括第四行的大括号。这在 Python 中非常常用,因为它没有大括号,完全靠缩进来区分代码块。
因此,注释掉两行 printf 的语法是 gCii
,注释掉整个 if 语句的方法是 gCaI
。
详见原著
sneak 是和 EasyMotion 差不多的插件,主打快速跳转的功能。用法是 s
,即按下 s 键后输入两个字符,可以跳转到下一个,这俩字符连续出现的位置。
然而相比原生的插件,VSCode 似乎有一个很严重的问题:不支持搜索高亮,这就导致我根本无法肉眼看出在当前位置和我的目标位置之间,隔了多少个
,导致无法用重复来跳转,也不支持标签跳转。更何况这个功能以及由 EasyMotion 实现了(快捷键 ;s
),所以我就不再研究了。
Command + ,
可以编辑配置,配置分为全局配置和项目配置,项目配置的优先级高于全局配置。Command + k + Command + s
键可以管理快捷键。Command + p
可以在项目中根据名称搜索并打开文件。Command + Shift + p
可以打开命令面板,那些不记得快捷键的命令,都可以在这里找到。掌握这些就可以初步使用 VSCode 了,下面会列举一些我的配置和插件,更多关于 VSCode 的配置介绍,请参考:vscode-tips-and-tricks
Beautify
:代码格式化插件,可以将 JS、CSS 和 HTML 代码格式化Code Outline
:支持多种语言的 outline 提取Code Runner
:可以运行多种语言,我配置的快捷键为 Command + R
。注意新的文本文件因为没有后缀名,要用快捷键 Command + K + M
手动切换语言类型。Dash
:使用快捷键 Ctrl + h
快速打开 Dash 查找当前单词MarkdownLint
:Markdown 语法检查,帮助你写出标准的 MarkdownProject Manager
:帮助你管理项目,在多个项目间切换,快捷键 Option + P
(首先要添加进项目列表)TODO Highlight
:高亮显示 TODOVSCode Icons
:根据文件和文件夹名称展示恰当的图标Bracket Pair Colorizer
:给成对的括号配上颜色,方便区分File Size
:在底部 bar 中显示文件大小Path Intellisense
:自动补全文件路径Auto Close Tag
:自动补全另一侧的 TagAuto Rename Tag
:修改一个 Tag 时,另一侧的 Tag 自动修改Color Highlight
:遇到颜色字符串,自动在旁边显示颜色,方便预览CSS Peek
:ESLint
:代码格式化,支持实时监测和保存时自动修改HTML Snippets
:HTML 语法片段,方便快速输入IntelliSense for CSS class
:CSS 自动补全JavaScript code snippets
:JS 的语法片段,方便快速输入Modern JavaScript Snippets
:补充了一些更新的语法片段HTML CSS Support
:方便在 HTML 中插入 CSS 代码SASS
:sass 格式文件的代码补全和高亮Vetur
:Vue 开发必备的插件,提供代码补全、高亮等功能Vue 2 Snippets
:Vue 2 的代码片段Vue peek
:快速跳转定义一般用什么语言就装什么插件就行了。比如 Node、Bash、Python、Go、Ruby 等。
VSCode 集成了一个终端,可以直接读取 .zshrc
中的配置(也就是说使用起来和 iTerm 几乎是一模一样的)。相关快捷键有:
cmd + \
: 水平切割,生成一个新的终端界面cmd + 数字
:当光标停留在终端时,通过数字来选择要聚焦的窗口cmd + w
:当光标停留在终端时,关闭当前终端cmd + t
:当光标停留在终端时,新建一个终端cmd + l
: 在 VSCode 内嵌的终端和代码编辑器中互相切换,再也不用跳出到 iTerm 了ctrl + `
:隐藏/展示 终端PWD
记录当前所在的目录,通过 echo $PWD
查看
OLDPWD
表示上一次所在的目录,输入减号 -
可以快速跳转到上一次所在的目录
bash/zsh 中还有一些约定好的只读变量,它们的值在脚本的运行过程中动态确定,常见的有:
$0
:表示脚本名字,可能是相对路径,当我们执行 bash a/b/c/d.sh
是,$0
的值是 a/b/c/d.sh
$1、$2、……、$10
:用来表示参数,$1
表示第一个参数,以此类推$#
:表示参数个数$?
:表示上一个命令的执行结果,0 表示正常结束,非 0 表示出现错误第 2、3 条规则在函数内部同样适用。
本文前面部分内容摘录自阮一峰老师的:Bash 脚本 set 命令教程,主要是文章写得太好了。
grep
命令很容易学习,它主要有两种使用方式,一种是单独使用,比如搜索某个文件中的内容:
grep 'content' file.txt
或者从标准输入中搜索内容:
echo 'something' | grep 'some'
要想掌握好 grep
,重点在于了解它的各种参数。下面是一些常用的参数,如果不记得,后续可以用 man grep
命令来查阅。
grep
在搜索时,默认是大小写敏感的,但如果要搜索 mysql,它可能写做 mysql 也可能写做 MySQL,这就可能存在搜索不到的问题,此时可以用 -i
参数:
echo 'MySQL' | grep -i 'mysql'
如果使用 -n
参数可以打印匹配行的行号,使用 -H
参数可以打印匹配文件的文件名。
默认情况下,如果某个二进制文件中含有搜索的关键词,会显示 Binary file … matches,使用 -I
选项可以忽略二进制文件,使用 -a
选项可以把二进制文件当做文本文件来处理,从而输出匹配的部分。
默认情况下 grep
会展示匹配的那一行,如果想查看上下文,可以使用 -A
、-B
和 -C
这三个参数:
-A 3
:展示匹配行以及后面的 3 行-B 3
:展示匹配行以及前面的 3 行-C 3
:展示匹配行以及前后的 3 行,等价于 -A 3 -B 3
另外一些常用的选项包括 -v
,表示只显示那些不匹配的行,-o
表示只显示匹配的部分,-q
表示不输出内容,通常与 if
连用。
在前面的章节中我们介绍过,可以通过管道将多个命令串联起来,前提是管道后面的命令要支持从标准输入中读取数据,比如前文的 grep
命令。
然而有些命令并不支持从标准输入中读取,比如这样写是无效的:
echo 'file_name' | rm
此时我们可以借助 xargs
命令:
echo "a" | xargs rm
这条命令的原理是,xargs
会把换行符、空格、制表符、EOF等符号做为分隔符,把输入的内容切分为一个数组,并把数组中每一个元素作为参数,放到后面的命令中执行,用伪代码来写就是:
for arg in read_input; do
rm arg
done
很常见的一个坑就是,如果文件名带有空格,比如 hello world 就会被 xargs
截断为两个参数,显然不符合预期。不过一般对内容或者文件进行过滤时,我们都会使用 grep
或 find
,这两个命令都有办法配合 xargs
。
ls | grep 'a' | tr "\n" "\0" | xargs -0 rm
用 grep
的话会繁琐一些,需要用 tr
命令把换行符转换成特殊字符 \0
,再利用 xargs
的 -0
参数,根据文档所述,这个参数会把分隔符指定为 -0
,从而避免了文件名中含有空格的影响。
用 find
也是类似的原理:
find . -print0 | xargs -0 rm
只不过它自带了 -print0选项,写法更简单。
sed 诞生于 1977 年,已经 41 岁了,这么一位叔叔级别的命令至今还活跃在各种 Shell 脚本中,由此可见它是多么重要。
Mac 自带的时 BSD 版本的 sed
,因为功能较弱,我不推荐使用,建议使用 gsed
,如无特殊说明,下文的介绍都是针对 gsed
的。
brew install coreutils
which gsed
# /usr/local/bin/gsed
sed
和 grep
的用法类似,都是 sed pattern file
或者 echo 'xx' | sed pattern
,也就是说第二个参数可以是文件,也可以从标准输入流中读取。
最标准的用法是进行文本替换(也可以用 tr
命令实现):
echo "a b\nc d"
# a b
# c d
echo "a b\nc d" | gsed 's/a/aa/g'
# aa b
# c d
有时候我们可能不止使用一次 sed
,此时可以用 -e
参数把多个命令串联起来:
echo "a b\nc d" | gsed -e 's/a/aa/g' -e 's/b/bb/g'
在 gsed
中,还可以使用 Shell 里定义的变量:
old=a
new=aa
echo "a b\nc d" | gsed "s/$old/$new/g"
我推荐用 gsed 是因为它有一个 -i
选项,可以对文件进行原地修改:
gsed -i 's/a/aa/g' file
sed
最核心的部分在于这里的 s/a/aa/g
,它由若干个斜杠组成(其实也不一定要用斜杠,只要保持一致就行)。这里的 s
表示替换,a
表示待匹配的内容,支持正则,aa
表示替换后的内容,g
表示全部替换,更多的用法有:
1,3s/a/aa/g
:只替换第一到三行中的内容s/a/aa/1
:只替换每行第一个 as/a/aa/2g
:每行前两个 a 不替换,从第三个开始替换2i sss
:在第二行前面追加一行,内容为 sss1a sss
:在第一行后面追加一行,内容为 sss,等价于 2i sss/a/a sss
:遇到有字母 a 的行,就在后面追加一行 sss1c sss
:把第一行替换为 sss2d
:删除第二行gsed
在默认情况下,会把输入的每一行都输出一遍,它有一个常用的选项是 -n
,表示不输出任何一行。通常与 p
命令合用,这个命令可以打印匹配的行,类似于 grep
的效果。
awk
是和 sed
同时代的命令,并称为文本处理两大神器。个人认为 sed
的强大之处在于文本匹配后的处理,而 awk
则更适合文本的结构化处理。
这里以获取 ip 地址的命令来介绍下:
ifconfig | sed -n -e '/127.0.0.1/d' -e '/inet /p' | awk '{print $2}'
这里 awk
的用法其实很简单,就是打印第二列。awk
的核心在于内建的变量:
变量 | 说明 |
---|---|
$0 | 当前记录(这个变量中存放着整个行的内容) |
$1~$n | 当前记录的第n个字段,字段间由FS分隔 |
FS | 输入字段分隔符 默认是空格或Tab |
NF | 当前记录中的字段个数,就是有多少列 |
NR | 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。 |
FNR | 当前记录数,与NR不同的是,这个值会是各个文件自己的行号 |
RS | 输入的记录分隔符, 默认为换行符 |
awk
一个很常见的用法是 -f
参数,可以指定输入字段的分隔符:
echo "a;b;c" | awk -F';' '{print $2}'
其实理论上来说,awk
比 sed
还要强大,因为它是一个图灵完备的语言,支持 for 循环等等编程思想。建议感兴趣的读者阅读 AWK 简明教程 了解更多 awk 的使用技巧
如果不想每次都输入 cd
再输入 ls
,那么 autojump
是必装的神器:
brew install autojump
它会记住每一次 cd
的路径,并且保存在数据中,以后我们可以直接输入 j + 关键字
,从而避免频繁的 cd
。
输入快捷键 Ctrl + E
可以根据当前提示快速补全,快捷键 ;
可以补全并执行
详见原著
系统的 Finder 其实并没那么好用,最大的问题在于没法和 Shell 有效的交互,比如复制移动文件、在当前文件夹位置打开终端都很不方便。
作为程序员,我推荐使用 Ranger 来浏览文件目录,它是一个使用 Vim 键位映射的文件管理工具。
使用快捷键 r
来打开 ranger,它的完整定义是:alias r='source ranger'
,这样做的好处在于当 Ranger 中目录发生变化时,可以改变外部 Shell 的路径。
在 Ranger 中,使用 j/k
来上下移动光标,h/l
来进行目录的前进和后退。
常用的操作有:
zh
:切换是否显示系统隐藏文件,按一次打开,再按一次关闭x
:安全删除文件(放入垃圾箱中而不是 rm)yy
:复制,dd
:剪贴,pp
:粘贴,空格键多选文件gh
:进入用户目录($HOME)yn
:复制文件名,yd
复制文件夹名,yp
复制完整路径名:j
:和 autojump
一样,输入要跳转的地方Ctrl + f
:利用 fzf
搜索文件f
:当前目录内过滤文件名du
:查看当前目录内各文件夹大小oo
:在 Finder 中打开,op 或回车键
:使用系统默认的程序打开,oc
:使用 VSCode 打开(如果已经有 VSCode 进程,为了加快速度,则使用已存在的)m
:添加书签,um
:选择要删除的书签,```:展示书签fzf 是一个模糊搜索神器,^t
是特定语义下的补全快捷键,^i
是默认快捷键,很少用到:
kill
然后按下 ^t
键,就会打开 fzf 补全界面,通过输入进程名来获取到 PIDssh
、export
、unset
、unlias
等命令alt + c
可以列出当前目录下的文件夹,并快速进入^g
,会自动补全 autojump 的路径列表^r
进入命令历史模式,此时也会自动打开 fzf 补全界面,自动补全命令^x^r
来触发fzf 甚至还支持为自定义的命令添加补全,具体做法可以参考:Examples (completion)