vim简介

vim是一款免费的开源的文本编辑器,可用它来编写代码,文档等。
在Apple OS X,Linux下一般默认已经随操作系统安装好了。
vim是在Vi的基础上改进和增加了很多特性。从它诞生到现在已经有几十年的历史了。

  • vi was written by Bill Joy in 1976
  • vim (Vi IMproved) released by Bram Moolenaar in 1991
  • Neovim project was started in 2014 (更强大的vim)

为什么要学习vim呢?

  • 虽然它有一定的learning curve, 但一但掌握了它的command, operation, motion的话,那用它编码将会非常的高效,作为一个每天都要编码的程序员来说,投资时间学习vim就像是投资时间学习盲打一样,非常有价值。
  • 很多服务器都是linux系统,没有像VS Code这样的IDE,但一般都预装了vim
  • 很多现代IDE,比如VS Code等,都可以安装VIM插件,从而可以使用vim的高效motion和command等。

vim模式

vim是一个基于模式的编辑器,严格来说,vim包含6个基本模式和6个附加模式, 但常用的是以下4个基本模式。

vim的基本模式
  • Normal模式
    • vim默认模式,该模式下键盘键入的字符都相当于命令
    • 其他模式下可通过<esc>键回到normal模式, command-line模式下按Enter键执行命令后也会回到Normal模式。
  • Insert模式
    • 进入该模式后,键盘键入的字符相当于普通的文本插入文件中。
    • 在Normal模式下,可通过输入这些命令之一i, I, a, A, o, O, c, C进入Insert模式
  • Visual模式
    • 进入Visual模式后,光标下的文本是选中高亮状态。
    • 在Normal模式下,可通过以下字符命令进入Visual模式
      • v(小写) 进入visual模式,选择光标所在字符并高亮
      • v(大写) visual line模式,选中的是整行
      • <Ctrl>v 进入visual block模式,矩形选择
    • 进入Visual模式后再跟<motion>组合可增加选区
    • 选中后可以加上<operator>比如(d删除,y拷贝,c改变 >右缩进 <左移)对选中区域的文本进行相应操作。
    • 选中后也可以通过:s/<pattern>/<replace>进入command模式对选中区域进行搜索替换等
  • Command-line模式
    • 在Normal模式下,输入:/?进入命令行模式, /?为查找字符串功能。
    • 以下为常用的一些命令
      • :w 保存更改, :q 退出, :wq 保存并退出, q! 不保存退出, :w FILENAME 将对文件的改动保存到文件中.
      • 要向当前文件中插入另外的文件的内容,请输入 :r FILENAME, :r !ls 可以读取 ls 命令的输出,并把它放置在光标下面。
      • v motion :w FILENAME 可将当前编辑文件中可视模式下选中的内容保存到文件FILENAME 中。
      • :e <file> 打开文件, :new <file> 新建文件。
      • :set nu, set rnu, :set ignorecase
      • :! 然后紧接着输入一个外部命令可以执行该外部命令
      • 获取帮助信息:按F1 或 输入:help 查看帮助, 一些例子::h word, :h WORD, :h sentence, :h paragraph, 阅读 Vim 的用户手册,使用的命令是: :help user-manual
      • 使用 CTRL-D 和 可以进行命令行补全
      • :vsp 纵向拆分窗口,:sp 横向拆分窗口, 输入 CTRL-W 可以使您在窗口之间跳转。

vim的功能

vim将键盘上的所有字符,包括大小写字母,数字和标点符号每个都设计成具有功能的命令,正式由于这些命令,使得vim非常高效和强大。 所有这些字符按功能和使用特点可大致分为4类。

  • motion
  • operator
  • command
  • extra
vim graphical cheat sheet

motion

vim motion的作用是移动光标,定义前面的<operator>的操作范围,或改变Visual模式的选择区域。
所有vim motion前面均可以加上数字,表示同样的动作执行几次,比如7j向下7行;

横向motion

  • h 左移1个字符, l 右边1个字符
  • word指全是字母或标点符号的需要,可以是标点符号或空格分隔,WORD 指以空格分隔的符号序列, 可通过:h word了解详细。
  • w 右移到下1个word开头,可W 右移到下一个1个WORD开头.
  • b 左移到上一个1个word开头, B 左移到上一个1个WORD开头.
  • e 右移到下一个word尾, E 右移到下一个WORD尾.
  • ge 左移到上一个word尾,gE 左移到上一个WORD尾.
  • f 后跟1个字符,找到同一行后面的字符,tf功能相同,但光标停留在找到的字符前面,大写的F T 是反方向往左边找。;重复下一个fFtT, ,反方向重复下1个fFtT.
  • 0| 左移到行首,^_ 左移到行首的首个非空字符, $ 右移到行尾。

纵向motion

  • j 下移1行,k 上移1行, + 下一行行首,- 上一行行首。
  • G 移动到文件末尾,{number}G 移动到第number行,M 移动到屏幕中央, H 移动到屏幕顶部, L 移动到屏幕底部.
  • { 跳转到上一段空行处 } 跳转到下一段空行处,以空行隔开的为不同的段。:h paragraph查看详情。
  • ( 左括号为跳到上一句,) 右括号跳转到下一句,句子以.?!等隔开。空行也认为是1句。:h sentence查看帮助。
  • <Ctrl> e 向上滚动1行,<Ctrl> y 向下滚动1行。
  • <Ctrl> d 向下翻半页,<ctrl> u 向上翻半页, <Ctrl> f 向下翻一页, <Ctrl> b 向上翻一页.
  • % 跳到匹配的()[]{}
  • [, ] misc
    • [(Go to previous unmatched (
    • [{ Go to previous unmatched {
    • ]) Go to next unmatched )
    • ]} Go to next unmatched }
    • ]m Go to next start of method (Java like languages)
    • ]MGo to next end of method
    • [mGo to previous start of method
    • [MGo to previous end of method

查找

  • / 向后查找, ? 向前查找,n 同方向查找下一个, N 反方向查找下一个。
  • * 向后查找光标所在处单词, # 向前查找光标所在处单词。

jump list

:h jump-motions 可以查看哪些命令会加入jump list, 查看当前jump list: :jump

  • Ctrl-o 跳转到jump list的上个位置
  • Ctrl-i 跳转到jump list的下个位置

替换类命令

  • :s/thee/the 只改变光标所在行的第一个匹配。
  • :s/thee/the/g 则是替换全行的匹配串
  • :#,#s/old/new/g 要替换两行之间出现的每个匹配串, 其中 #,# 代表的是替换操作的若干行中首尾两行的行号。
  • :%s/old/new/g 则是替换整个文件中的每个匹配串。
  • :%s/old/new/gc 会找到整个文件中的每个匹配串,并且对每个匹配串提示是否进行替换。

command

这些字符在Normal模式下可以单独执行。

  • Esc 回到Normal模式
  • u undo, U undo line, <Ctrl> + r redo重做

  • 在Normal模式下,输入以下命令将进入Insert模式
    • i 当前光标的前面开始插入, a 当前光标的后面开始插入
    • I 当前行首开始插入, A 当前行尾开始插入
    • o(小写) 当前行下面开一个新空行开始插入, O(大写) 当前行上面开一个新空行开始插入
    • s 删除光标所在字符并开始插入, S 删除整行并开始插入
    • C(大写) 删除当前光标到行尾,并进入插入模式,相当于c$, 小写c是1个operator,后要接进入insert模式
  • R 进入Replace mode r 替换光标所在字符
  • X 删除光标前的字符,相当于backspace, x删除光标所在的字符
  • D 删除到行尾,相当于d$
  • Y 注意,这个命令在vim和neovim功能不同,在vim中是拷贝整行,相当于yy, 而在neovim中是拷贝当前光标到行尾,相当于y$
  • p 粘贴在光标后,P(大写)粘贴在光标前
  • ~ 切换大小写
  • J join lines,合并为1行,默认合并当前+下1行, visual模式下合并选中的所有行。
  • K help
  • Q ex mode

  • . 重复前一个命令, & repeat :s重复前一个查找替换操作
  • Marks功能,m + a~z 将当前位置做标记,后续可使用 重音符号 + a~z的返回, 单引号 + a~z返回标记所在行的第1个非空字符, 重音符号+.返回最后1次修改点。A~Z是全局标记,a~z是每个buffer级别的标记。
  • 录制macro功能,q + a~z开始录制,录制完再按1个q结束。后面通过@ + a~z重放macro, @@ 重放上一个执行的macro

operator

<operator>后面要跟上相应的<motion>表示的操作范围;
格式为<operator> + 数字 + <motion> ,比如d7j表示删除向下7行。 或者先在visual模式下选择好范围,再按操作该范围。

  • c(小写) + <motion> :清空并进入Insert模式
  • d 删除
  • y 拷贝
  • < 左移indent > 右移indent = auto format,
  • ! external filter

以上这些operator的双字符都代表操作范围为光标所在行。比如dd删除整行,yy拷贝整行,cc清空整行进入Insert模式,>> 右移整行,<< 左移整行.

  • operator + (inside, around)
    • di" 删除双引号内文本 di( 删除括号内文本
    • da" 删除包含双引号的文本, da( 删除包含括号的文本
    • diw 删除光标所在word, daw 删除光标所在word和两边空格。

extra

特殊功能,需要和其他进行组合。

  • g extra cmds,
    • gg 移动到文件开头,
    • ge 移动到前一个word尾, gE 移动到前一个WORD尾。
    • gu{motion} 改为小写
    • guu 当前行改为小写
    • gU{motion} 改为大写
    • gUU 当前行改为大写
  • 小写z extra cmds, zt 移动光标所在位置到顶部,zz到中部,zb到底部
  • 大写Z quit , ZZ 保存退出, ZQ不保存退出
  • " register, 寄存器

  • 1~9数字 放到其他操作前面表示次数
  • \ not used

vim中的核心概念

register

  • :reg 可查看vim的register, :help reg 可查看vim寄存器帮助。
  • " + a~z + operator : 以双引号开头可定义1个register, 后接 a~z的命名,后续operator操作将文本存储在该register, 或从该register取出内容
  • "adddd删除的行存储在"a, "ap 将register里的内容粘贴。
  • "" 是默认的register, 最近1次操作的内容存储在里面。
  • q @ record macro和play macro底层原理也是将这些命令存储在了register中。
  • 每次在vim中删除的文本都会推入 "1 ~ "9 的register中, "0 保存着拷贝的文本。vim会自动保存最近的9次删除。不足1行的文本会保存到小删除register "-
  • 3个只读寄存器,". 上次insert模式下的文本, “% 当前文件名,": 上次命令行模式下的命令。
  • "# 交替文件寄存器,指buffer中的上一个文件。可通过<Ctrl> ^切换到交替文件。
  • "*"+ 指系统剪贴板, 比如"*yy可以将当前行存入系统剪贴板,可以在其他程序粘贴。反过来也可以。
  • "/ 存储上一次搜索的关键词。

buffer

  • :ls:buffers 列出所有的buffer.
  • :b <number> 显示号buffer.
  • :b <partial> 通过文件名显示buffer.
  • :bd 删除当前buffer
  • :bd! 删除当前buffer(丢弃更新)

Autocommands

  • Added in Vim 4.0
  • Hooks to allow the user to execute commands depending on the file name.
  • Often used for filetype specific settings:
    :au BufRead *.c set tw=78 cindent sw=4
    :au BufRead *.java source ~/.vim/java.vim
    
vim Autocommands

Vim script

  • Added in Vim 5.0
  • defines the syntax
    :if
    :while
    expressions
    variables (only numbers and strings)
    User functions (added in Vim 5.2)
    
  • Automatic memory management:
    • Reference counting for most things
    • Garbage collection for cycles (later)
  • Used for syntax highlighting, later ftplugin and indenting.

plugin

  • Added in Vim 6.0
  • Drop a script file in the right place and it gets loaded.
  • plugin management
    • Added package support in Vim 8.0. :packadd
    • With a plugin manager plugin:
      • Vimball (unpacking only)
      • Pathogen
      • Vundle
      • VAM
      • vim-plug

Seven habits of effective text editing

Habit 1: Moving around quickly

  • :set hlsearch and use * command to search

Habit 2: Don’t type it twice

  • insert mode completion:CTRL-N
  • Vim 7.0: omni-completion

Habit 3: Fix it when it’s wrong

  • spell correction macros. :iabbrev teh the :syntax keyword WordError teh

Habit 4: A file seldom comes alone

  • use gf - Goto file

Habit 5: Let’s work together

Habit 6: Text is structured

Habit 7: Sharpen the saw

  • You have to keep on tuning the set of commands you use for your needs.

Three basic steps

Step 1: Detect inefficiency

  • Find out what you waste time on

Step 2: Find a quicker way

  • read the on-line help
  • read the quick reference, books, etc.
  • ask friends and colleagues
  • search the internet
  • do it yourself

Step 3: Make it a habit

  • do it
  • keep on improving