学会 Vim 足以行走 Linux 江湖

Vim readme

  • 大家來學 VIM(一個歷久彌新的編輯器) http://www.study-area.org/tips/vim/
  • Vim 实用技术,第 1 部分: 实用技巧 https://www.ibm.com/developerworks/cn/linux/l-tip-vim1/index.html
  • 神奇的VIM https://www.ibm.com/developerworks/cn/linux/l-tip-prompt/tip15/
  • 普通人的编辑利器——Vim http://blog.sina.com.cn/s/blog_46dac66f010005kw.html
  • Vim 从入门到精通 - https://www.jianshu.com/p/385cb0fdc3a0
vim-basic-cheat-sheet.jpg
vim-Beautiful-Vim-Cheat-Sheet.png
vim-sheat-sheet-for-programmer.png
vim-cheat-sheet-full.png

入门可以读软件自带的 《 V I M 教 程 》

VIM 牛在哪里?

比如,我要修改php配置,关掉 Opcache 缓存,那么假设知道php.ini所在,直接用vim打开:

vim /usr/local/php56/etc/php.ini

界面看起来好丑是不是,执行命令改个blue主题色就好多了:

colorscheme blue
colors blue

然后搜索 opcache.enable 位置,

/opcache.enable [Enter]

然后可以用 n 来查找下一个,找到后用 hjkl 来移动光标到分号,按下 x 删去,也可以用 cw/cc 来修改单词/单句,改错了不要紧, 按下 [Esc] 回到命令模式,用 u 还原。改完了就用 w 命令保存,q 命令退出,可以一起执行,感叹号表示强制执行。

[Esc] w [Enter]
[Esc] wq [Enter]
[Esc] wq! [Enter]

配置 Vim 的特性

Vim 的功能特性要比 Vi 多得多,但其中大部分都没有缺省启用。为了使用更多的
特性,您得创建一个 vimrc 文件,默认地VIM会从主目录下读取配置文件 .vimrc 或Windows平台下加下划线前缀。

开始编辑 vimrc 文件,具体命令取决于您所使用的操作系统:

:edit ~/.vimrc          这是 Unix 系统所使用的命令
:edit $VIM/_vimrc       这是 MS-Windows 系统所使用的命令

接着读取 vimrc 示例文件的内容:

:r $VIMRUNTIME/vimrc_example.vim

保存文件,命令为:

:write

在退出前可以按下i打开插入编辑模式,将以下这行配色设置放在首行位置,再按下 ESC 进入命令模式保存文件:

colorscheme zellner

下次您启动 Vim 时,编辑器就会有了语法高亮的功能。您可以把您喜欢的各种设置添加到这个 vimrc 文件中。要了解更多信息请输入 :help vimrc-intro要了解 VIM 装置的配置脚本,可以使用 version 命令:

:version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Nov 24 2016 16:44:48)
Included patches: 1-1689
Extra patches: 8.0.0056
..................................................................
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
  fall-back for $VIM: "/usr/share/vim"
..................................................................
Press ENTER or type command to continue

ubuntu 16.0 系统中定位 VIM 安装目录:

root@aiirobo:~# whereis vim
vim: /usr/bin/vim /usr/bin/vim.basic /usr/bin/vim.tiny /etc/vim /usr/share/vim /usr/share/man/man1/vim.1.gz
root@aiirobo:~# ls /usr/share/vim
addons  registry  vim74  vimfiles  vimrc  _vimrc  vimrc.tiny
root@aiirobo:~# ls /usr/share/vim/vim74/
autoload       delmenu.vim   ftplugin            indent.vim  menu.vim    print        syntax
bugreport.vim  doc           ftplugin.vim        indoff.vim  mswin.vim   rgb.txt      tutor
colors         evim.vim      ftplugof.vim        keymap      optwin.vim  scripts.vim  vimrc_example.vim
compiler       filetype.vim  gvimrc_example.vim  lang        pack        spell
debian.vim     ftoff.vim     indent              macros      plugin      synmenu.vim

配色方案目录,在vimrc脚本中加入 colorscheme zellner 就可以使用:

root@aiirobo:~# ls /usr/share/vim/vim74/colors
blue.vim      delek.vim    evening.vim   morning.vim  peachpuff.vim  shine.vim  zellner.vim
darkblue.vim  desert.vim   industry.vim  murphy.vim   README.txt     slate.vim
default.vim   elflord.vim  koehler.vim   pablo.vim    ron.vim        torte.vim

Basic Skills 基本编辑功能

注意了,在文档中,C-^C+ 通常用来表示控制键一起按。

Vim 是命令化编辑器,功能强大到没朋友,只有 Emacs 一个对头。

Vim 有命令模式 Command Mode 也叫 Normal 标准模式和编辑模式 Write/Insert Mode,进入 Vim 界面就是处于命令模式,等待用于输入命令。

此时,可以使用以下命令进入编辑模式:

  • i Insert 开启内容插入模式
  • I Beginning of line 在行前插入命令;
  • a After cursor 在光标后附加;
  • A Append 行尾附加;
  • C Change to end 修改当前字符到到行尾的内容
  • o Next line 后面插入一行;
  • O Previous line 前面插入一行;
  • s Substitutes Character 替换字符;
  • S Substitutes line 替换行;

进入编辑模式后,ESC 按键可以返回到 Normal 模式,继续进行命令交互。

此外,Vim 还有一个命令行编辑模式 Command Line Mode,在标准模式下使用 : 进入命令行模式,可以执行另一类命令,比如软件的即出 q、打开文件 o、文件写入 w,也可以执行文件内容的查找替换等等。

所以 Vim 基本就是一个不停切换状态的状态机器:

Normal --> : --> Command Line Mode --> ESC -->
Normal --> i, A, C, r --> Write/Insert Mode -->
Normal ...

基本的编辑命令功能:

  • u Undo 撤消
  • ^r Redo 重做
  • . Repeat 重做上一个命令
  • y Copy 拷贝命令
  • yy Copy line 拷贝行
  • p Paste 贴帖
  • d Delete 删除命令
  • dd Delete line 删除行
  • D Delete to End 删除到行尾
  • x Cut 剪切
  • X Cut 剪切光标前字符
  • c Change 修改命令
  • r Replce 替换字符内容
  • J Join line 拼行
  • <> 缩进与反缩进
  • [] 在匹配的括号间移动光标

这些命令使用方法,大多数可以用以下模式表示:

[operator][count][motion]

指定操作 operator,再指定重复次数 count 默认为 0 次,最后指定运动方向 motion 默认为 j 向下。

比如,光标所在行和以下的两行进行缩进 >2j,如果使用 > 直接回车就表示使用默认的重得 0 次,方向为 j 向下。

命令还可以进行组合,比如删除命令与查找命令组合,d/foo 将当前光标位置到下一个 foo 的内容删除。

又如,拷贝命令和光标前向跳转 forward 命令组合使用,y3fi 复制光标位置到后面第 3 个 i 字位置的内容。

又如,修改、删除、拷贝命令和光标跳转命令组合使用:

命令组合 c 修改 d 删除 y 拷贝
cc 修改行 删除行 拷贝行
w cw 修改单词 dw 删除单词 yw 拷贝单词
W cW 修改整个词 dW 删除整个词 yW 拷贝整个词
e ce 修改光标到词尾 de 删除光标到词尾 ye 拷贝光标到词尾
f cfx 光标到下一个 x 位置 dfx 光标到下一个 x 位置 yfx 光标到下一个 x 位置
( c( 修改 到句首 d( 删除 到句首 y( 拷贝 到句首
) c) 修改到句首 d) 删除到句首 y) 拷贝到句首
{ c{ 修改到段落开头 d{ 删除到段落开头 y{ 拷贝到段落开头
} c} 修改到段落结尾 d} 删除到段落结尾 y} 拷贝到段落结尾

在编辑模式下,还有一个块操作模式 Visual Block Mode, 或者 v 打开块操作,C+ 表示控制键一起按,Windows 平台使用 Ctrl-q。进入块操作后,可以选择要内容,即构成内容块,然后再处理。

例如,利用块操作把各行的单词拼接成一行,用逗号连接,Vim 要几步?

one
two
three
four
five
six
seven
eight
nine
ten

操作步骤:

0. Esc    进入命令模式
1. 2G     跳到第 2 行
2.   打开块操作 C+ 表示控制键一起按,Windows 平台使用 C+q
3. 8j     往下选择 8 行
4. I,Esc  往选中的 8 行的行首插入逗号
5. 1G     跳到第 1 行
6. 10J    拼接 10 行

结果

one ,two ,three ,four ,five ,six ,seven ,eight ,nine ,ten

高级的内容移动操作,如上下互换一行 ddkP

  • dd 将删除该行并将它添加到默认寄存器中。
  • k 将上移一行(j将沿直线移动)
  • P 将粘贴到当前行的上方

使用 :m 移动命令 move 移动光标所在行,或者选中的块:

  • :m+1 - 移下一行后面,即下移 1 行;
  • :m-2 - 移到前两行后面,即上移 1 行,负号表示上移;
  • :m1 - 移动第一行后面;

为了更好地使用移动命令,可以设置显示行号:

:set number

Cursor Move 光标移动控制

  • Vim中如何快速进行光标移动?

光标移动技能升级路线:

  • 掌握简单的功能,上下左右和插入 h, j, k, l, i。这时候用 Vim 的键盘像打 Dota 一样重复它们,让它们在脑中生根。
  • 学会单词移动和在文件头尾位置移动 w, b, $, ^, 0, gg, G,这时编辑起来不那么费力了。
  • 学会正则查找和替换 /search, %s/search/replace/g。
  • 学会滚屏 zz, zt, zb, ^f, ^b,标识符间来回移动、按屏幕移动光标 H, L, M、窗格间移动 ^w + hjkl。
  • 这是最近一年的水平,同时还学会了宏录制、列编辑等。

下一阶段:熟悉段落与单词间跳转,熟悉数字的使用。比如对于代码中 func(args, count),我要记住从行首到第二个参数的快捷键是 4w。

用一个方向坐标可以很形象地表示 VIM 是如何控制光标位置的:

Hello there! Vim is a modern version of Vi, the venerable Unix text
editor. Here is a cheat sheet form Vim. This line ends here.
So. This is some silly sampppp;le text to demo navigation. In Vim.
|A n|ew line.    |     ^     || | |    |       |           | |   |
|   |       |    |<- b | e ->|| | |    |       |           | |   |
|   |       |<------ } | w -->| | |    |       |           | |   |
|   |                  | E ---->| |    |       |           | |   |
|   |                  | W ------>|    |       |           | |   |
|   |                  | 2W ---------->|       |           | |   |
|   |                  | fn ------------------>|           | |   |
|   |<-------------- ( | ) ------------------------------->| |   |
|                      | tV -------------------------------->|   |
|<------------------ 0 | $ ------------------------------------->|

用到的基本方向概念除了左下上右 hjkl 外,还有 foward 前向,backward 后向:

  • f - forward 前向到某字符
  • w - forward word 向前一个单词
  • b - backward word 后向一个单词
  • e/E - Ends 单词结束位置
  • (/) - Start/End of sentence 句首行尾
  • 0/$ - Start/end of line 行首行尾
  • ^ - Line begin 行首,包括打头的空间字符也算行内容
  • {/} - Start/end of paragraph 段落开头、结尾
  • /ab - Search 查找 ab 字符串
  • ma - Mark position 标记当前位置为 a,返回标记位置使用反引号,即 ~ 键。
  • ^b - Page backward 往回翻页
  • ^f - Page forward 往前翻页

字符间移动

在 Visual 模式或者 Insert 模式,可以按 Esc 回到 Normal 模式。

在 Vim 的 Normal 模式里, 通过 h, j, k, l, i 来进行左下上右的光标移动,进入插入模式。

在 Vim 中多数操作都支持数字前缀,比如 10j 可以向下移动 10 行。

单词间移动

多数情况下单词移动比字符移动更加高效。 w 移动光标到下一个单词的词首,b 移动光标到上一个单词的词首;e 移动光标到下一个单词的结尾,ge 移动光标到上一个单词的结尾。

单词移动同样支持数字前缀,比如 4w 可以向后移动 4 个单词。连续的标点符号算一个单词。

有趣的是 W, B, E 具有同样的功能,只不过它是用空格来分隔单词的,可以跳地更远~

^ 到行首,$ 到行尾。

例如,使用 y 拷贝一行:^y$。

相对屏幕移动

注意了,在文档中,C-^C+ 通常用来表示控制键一起按。

以下翻页功能几乎在所有 Unix 软件中都是好使的,比如 man 和 less。

  • ^f 向下翻页;
  • ^b 向上翻页;
  • ^e 逐行下滚;
  • ^y 逐行上滚。
  • H 可以移动到屏幕的首行;
  • M 到屏幕中间;
  • L 到屏幕尾行;
  • zt 可以置顶当前行,通常用来查看完整的下文,比如函数、类的定义。
  • zz 将当前行置于屏幕中部;
  • zb 将当前行置于屏幕底部。

文件中移动

通过:10 可以直接移动光标到文件第 10 行。如果你看不到行号,可以:set number。

  • gg 移到文件首行;
  • G 移到尾行;

例如,使用 y 拷贝整个文件:ggyG

  • /xx 可以查找某个单词 xx,n 查找下一个,N 查找上一个。 在光标跳转之后,可以通过 ^o 返回上一个光标位置,^i 跳到下一个光标位置。
  • ?xx 可以反向查找,q/, q? 可以列出查找历史。

在编程中还可以使用 gd 来类似地移动到当前符号的定义位置,其实它移动到文件中第一出现符号的位置,结合 * 号在相同符号中跳转。

Search/Replace 查找与替换

在 normal 模式下按下 / 即可进入查找模式,输入要查找的字符串并按下回车。 Vim 会跳转到第一个匹配。按下 n 查找下一个,按下 N 查找上一个。

Vim 查找支持正则表达式,例如 /vim 匹配 "vim$"。

大小写敏感查找 \C,在查找模式中加入 \c 表示大小写不敏感查找:

  /foo\c

将会查找所有的 foo, FOO, Foo 等字符串。

Vim 默认采用大小写敏感的查找,为了方便我们常常将其配置为大小写不敏感:

set ignorecase
set smartcase 

smartcase 会在遇到有一个大写字母时,切换到大小写敏感查找。将上述设置粘贴到你的 ~/.vimrc,重新打开 Vim 即可生效。

在 normal 模式下按下 * 即可查找光标所在单词, 要求每次出现的前后为空白字符或标点符号。例如当前为 foo,可以匹配 foo bar 中的 foo,但不可匹配 foobar 中的 foo。 这在查找函数名、变量名时非常有用。

按下 g* 即可查找光标所在单词的字符序列,每次出现前后字符无要求。 即 foo bar 和 foobar 中的 foo 均可被匹配到。

查找与替换

:s(substitute)命令用来查找和替换字符串。语法如下:

:{作用范围}s/{目标}/{替换}/{替换标志}

例如,在全局范围 % 查找 foo 并替换为 bar,所有出现都会被替换 g:

%s/foo/bar/g

作用范围分为当前行、全文、选区等等。

:s/foo/bar/g
:%s/foo/bar/g

选区,在 Visual 模式下选择区域后输入 : 号即可自动补全为 :'<,'>:

:'<,'>s/foo/bar/g

指定 2-11 行:

:5,12s/foo/bar/g

当前行 . 与接下来两行 +2:

:.,+2s/foo/bar/g

标志设置:

  • 不指定替换标志表示只替换从光标位置开始,目标的第一次出现。

  • g 标志表示全局 global 替换,即替换目标的所有出现。

  • i 标志表示大小写不敏感查找,I 表示大小写敏感。等效于模式中的 \c 不敏感和 \C 敏感。

      :%s/foo\c/bar
    
  • c 标志表示需要确认,例如,全局查找 foo 替换为 bar 并且需要确认,回车后 Vim 会将光标移动到匹配位置,并提示:

      replace with bar (y/n/a/q/l/^E/^Y)?
    
    • y yes 替换
    • N no 不替换
    • A all 替换所有
    • Q quit 退出替换
    • L last 替换最后一个,并把光标移动到行首。
    • ^E ctrl+E 向下滚屏
    • ^Y ctrl+Y 向上滚屏!

Multiple Window 多窗口

  • Vim 多文件编辑:窗口

标签页 tab、窗口 window、缓冲区 buffer 是 Vim 多文件编辑的三种方式,它们可以单独使用,也可以同时使用。 它们的关系是这样的:

A buffer is the in-memory text of a file. A window is a viewport on a buffer. A tab page is a collection of windows. –vimdoc

分屏打开多个文件

使用 -O 参数可以让 Vim 以分屏的方式打开多个文件:

vim -O main.cpp my-oj-toolkit.h

使用小写的 -o 可以水平分屏。

在进入 Vim 后,可以使用这些命令来打开/关闭窗口:

:sp[lit] {file}     水平分屏
:new {file}         水平分屏
:sv[iew] {file}     水平分屏,以只读方式打开
:vs[plit] {file}    垂直分屏
:clo[se]            关闭当前窗口

上述命令中,如未指定 file 则打开当前文件。

使用快捷键操作多窗口:

Ctrl+w s        水平分割当前窗口
Ctrl+w v        垂直分割当前窗口
Ctrl+w q        关闭当前窗口
Ctrl+w n        打开一个新窗口(空文件)
Ctrl+w o        关闭出当前窗口之外的所有窗口
Ctrl+w T        当前窗口移动到新标签页

切换窗口的快捷键也使用了方向键 hjkl:

Ctrl+w h        切换到左边窗口
Ctrl+w j        切换到下边窗口
Ctrl+w k        切换到上边窗口
Ctrl+w l        切换到右边窗口
Ctrl+w w        遍历切换窗口

还有 t 切换到最上方的窗口,b 切换到最下方的窗口。

移动当前窗口,注意使用大小的方向键:

Ctrl+w H        向左移动当前窗口
Ctrl+w J        向下移动当前窗口
Ctrl+w K        向上移动当前窗口
Ctrl+w L        向右移动当前窗口

调整窗口大小的快捷键:

Ctrl+w +        增加窗口高度
Ctrl+w -        减小窗口高度
Ctrl+w =        统一窗口高度

多文件编辑与窗格间移动

  • Vim 多文件编辑:标签页

打开与关闭

标签页是最常见的多文件编辑方式吧,熟悉IDE的小伙伴一定能很快上手! 使用-p参数来用多个标签页启动Vim:

vim -p main.cpp my-oj-toolkit.h /private/etc/hosts
vim tab

在Vim中也可以打开和关闭标签:

:tabe[dit] {file}   edit specified file in a new tab
:tabf[ind] {file}   open a new tab with filename given, searching the 'path' to find it
:tabc[lose]         close current tab
:tabc[lose] {i}     close i-th tab
:tabo[nly]          close all other tabs (show only the current tab)

中括号中的部分可以省略,在Vim中:h tabedit可以查看命令帮助。
移动标签

:tabs         list all tabs including their displayed window
:tabm 0       move current tab to first
:tabm         move current tab to last
:tabm {i}     move current tab to position i+1

标签跳转

:tabn         go to next tab
:tabp         go to previous tab
:tabfirst     go to first tab
:tablast      go to last tab

在正常模式(normal)下,还可以使用快捷键:

gt            go to next tab
gT            go to previous tab
{i}gt         go to tab in position i 

可以设置更通用的切换标签页快捷键,比如我的 ~/.vimrc 是这样设置的:

noremap  :tabnext
noremap  :tabprevious

多文件编辑与缓冲区

  • Vim 多文件编辑:缓冲区

引用 Vim 官方解释,缓冲区是一个文件的内容占用的那部分 Vim 内存:

A buffer is an area of Vim’s memory used to hold text read from a file. In addition, an empty buffer with no associated file can be created to allow the entry of text. –vim.wikia

先来回顾一下 Tab,Window,Buffer 的关系吧!

基于缓冲区的多文件编辑是 Vim 最为推荐的做法,Vim 维护着你在当前打开的这些 Buffer 里的所有跳转, Ctrl+o 和 Ctrl+i 可以遍历这些光标位置。 但一个窗口内只有一个 Buffer 是处于可见状态的,所以 Buffer 的用法最不直观。

学习 Vim 就要克服那些不直观的操作!因为 Vim 本身就是基于 CLI 的,而我们相信 CLI 就是效率。

不带任何参数打开多个文件便可以把它们都放入缓冲区 Buffer:

vim a.txt b.txt

当你使用 :q 关闭文件时是否看到过 1 more file to edit 的警告?那就是缓冲区中的文件。

进入 Vim 后,通过 :e[dit] 命令即可打开某个文件到缓冲区。还记得吗?使用 :new 可以打开一个新窗口。 关闭一个文件可以用 :q,移出缓冲区用 :bd[elete],占用缓冲区的文件对你毫无影响,多数情况下不需要这样做。

如果 Buffer 未保存 :bd 会失败,如果强制删除可以 :bd!

缓冲区之间跳转最常用的方式便是 Ctrl+^,即 Ctrl-6 不需要按下 Shift,来切换当前缓冲区和上一个缓冲区。

另外,还提供了很多跳转命令:

:ls, :buffers       列出所有缓冲区
:bn[ext]            下一个缓冲区
:bp[revious]        上一个缓冲区
:b {number, expression}     跳转到指定缓冲区

:b 接受缓冲区编号,或者部分文件名。例如:

  • :b2 将会跳转到编号为 2 的缓冲区,如果你正在用 :ls 列出缓冲区,这时只需要输入编号回车即可。
  • :b exa 将会跳转到最匹配 exa 的文件名,比如 example.html,模糊匹配打开文件正是 Vim 缓冲区的强大之处。

在 Vim 多文件窗口编辑中已经介绍了 Vim 中分割屏幕的操作。 其实分屏时还可以指定一个 Buffer 在新的 Window 中打开。

:sb 3               分屏并打开编号为 3 的 Buffer
:vertical sb 3      同上,垂直分屏
:vertical rightbelow sfind file.txt

注意 sfind 可以打开在 Vim PATH 中的任何文件。这当然需要我们设置 PATH,一个通用的做法是在 ~/.vimrc 中添加:

" 将当前工作路径设为Vim PATH
set path=$PWD/**

利用通配符进行缓冲区跳转

这是缓冲区最强大的功能之一。我们可以使用通配符来指定要跳转到的缓冲区文件名。 在此之前,我们启动 wildmenu 并设置匹配后文件选择模式为 full。 wildchar 为选择下一个备选文件的快捷键, 而 wildcharm 用于宏定义中语义同 wildchar,比如后面的 noremap。

set wildmenu wildmode=full 
set wildchar= wildcharm=

比如现在按下打开这些文件:

vehicle.c vehicle.h car.c car.h jet.c jet.h jetcar.c jetcar.h

然后按下 :b 便可看到 Vim 提供的备选文件列表了, 按下 Tab 选择下一个,按下回车打开当前文件。

:b        " 显示所有Buffer中的文件
:b car    " 显示 car.c car.h
:b *car   " 显示 car.c jetcar.c car.h jetcar.h
:b .h     " 显示 vehicle.h car.h jet.h jetcar.h
:b .c     " 显示 vehicle.c car.c jet.c jetcar.c
:b ar.c   " 显示 car.c jetcar.c
:b j*c    " 显示 jet.c jetcar.c jetcar.h

我们可以为:b 设置一个快捷键,这时便用到上文中设置的wildcharm了:

noremap  :b 

你可能感兴趣的:(学会 Vim 足以行走 Linux 江湖)