Vim - 一些实用技巧

快速上手 Vim

  1. 基于 vimtutor 命令教程
  2. 参考: https://learnxinyminutes.com/docs/zh-cn/vim-cn/
  3. 鸟哥私房菜 vim 使用: http://linux.vbird.org/linux_basic/0310vi.php#vi_command

1. vim 键盘映射(MAP)

12

键盘映射,可以将键盘某个快捷键与 vim 具体操作结合起来,可以是简单的也可以是复杂的操作,这个模式很像宏,比如: :map <F5> i{<Esc>ea}<Esc>,这个快捷键通过 F5 键将单词用花括号括起来,就如同自己在 vim 中做了这一连串动作;

其中:i{将插入字符{,然后使用 Esc 退回到命令状态;接着用 e 移到单词结尾,a}增加字符},最后退至命令状态。在执行以上命令之后,光标定位在一个单词上(例如 amount),按下 F5 键,这时字符就会变成{amount}的形式。`

1.1. map/mapclear

  • :map: 制定一个映射,比如:map <F10> <Esc>:tabnew<CR>
  • :unmap: 取消映射,比如:unmap <F10>
Command 命令 Normal 常规模式 Visual 可视化模式 Operator Pending 运算符模式 Insert Only 插入模式 Command Line 命令行模式
:map (:noremap) y y y y
:nmap(:nnoremap) y
:vmap(:vnoremap) y
:omap(:onoremap) y
:map!(:noremap!) y y
:imap(:inoremap) y
:cmap(:cnoremap) y
  • :nmap/vmap/imap/omap: 不同形式的 map 命令,可以针对特定的模式设置键盘映射,依次是普通模式/视图模式/插入模式/运算符模式,更多参考: http://yyq123.blogspot.com/2010/12/vim-map.html
  • :nunmap/vnumap/iunmap/ounmap: 取消 map 映射

1.3. 映射快捷键

  • :map <F10> <Esc>:tabnew<CR>
    • <F10>: 快捷键 F10
    • <Esc>: 推出到命令行模式
    • :tabnew: 执行:tabnew命令
    • <CR>: 敲回车
  • 类似的组合键
    • <C-Esc>: 表示Ctrl+Esc
    • <S-F1>: 表示Shift+F1
    • <D-F1>: 对 Mac 用户,D 表示 Cmd
    • <A-F1>/<M-F1>: 表示Alt+F1, ALT 可以用A或者M表示
  • 更多键盘详情: :h key-notation,也可以看下: https://vim.fandom.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_2)#Key_notation
// 一些参考,复杂例子: :map <press Ctrl-V><press Ctrl-K> :ls<press Ctrl-V><press Enter>
<BS>           Backspace
<Tab>          Tab
<CR>           Enter
<Enter>        Enter
<Return>       Enter
<Esc>          Escape
<Space>        Space
<Up>           Up arrow
<Down>         Down arrow
<Left>         Left arrow
<Right>        Right arrow
<F1> - <F12>   Function keys 1 to 12
#1, #2..#9,#0  Function keys F1 to F9, F10
<Insert>       Insert
<Del>          Delete
<Home>         Home
<End>          End
<PageUp>       Page-Up
<PageDown>     Page-Down
<bar>          the '|' character, which otherwise needs to be escaped '\|'

1.4. 取消所有 map

  • :mapclear: 清理所有映射

2. 快捷键操作

Oracle 操作文档: https://docs.oracle.com/cd/E19683-01/806-7612/editorvi-43/index.html

2.1. 在文件中移动

Normal 模式

  • 字符
    • 光标移动: hljk:左右下上
    • 左右移动: 空格:右移一个字符, 删除:左移一个字符
    • 光标首尾: ^:首, $:尾
  • 单词
    • 左右移动: w:右移, b:左移, W:标点右移B:标点左移, e:单词最后
  • 半屏/一屏
    • 移动顶/中/底: H(高), M(中间), L(底部)
    • 下一屏: ctrl+f, 上一屏: ctrl+b
    • 上半屏: ctrl+d, 下半屏: ctrl+u

Insert 模式

  • 字符(可能需要结合 ide 做定制)
    • 左移: ctrl+f, 右移: ctrl+b
    • 上移: ctrl+p,下移: ctrl+n

2.2. 插入文本

  • a:当前光标后添加, A: 当前行尾添加
  • i:当前光标前添加,I: 当前行首添加
  • o:当前行上行添加,O: 当前行下行添加

2.3. 更改和替换文本

  • cw: 替换单词,英文是通过空格区分,中文一样(标点符号区分)
  • cc: 重新输入当前行
  • s: v 模式下,键入 s 后,支持替换掉选择的内容
  • r: 替换单个英文/中文字符

2.4. 撤消对文本的更改

  • u: 撤销修改,连续按 u 持续撤销

2.5. 删除文字

  • x: 向后删除一个字符, X: 向前删除一个字符
  • dw: 删除单词右侧部分,配置.持续操作,可以一直删除下去,3dw:向后删除 3 个单词
  • dd: 删除一行,5dd:从当前行,想下删除 5 行

2.6. 复制

  • yy: 复制当前行, 11yy: 复制当前行起的 11 行
  • p: 行下粘贴,P: 行上粘贴。dd 后的内容也可以被粘贴

3. vimrm 配置

3.1. 缩进配置

新版的 vimrc 示例,支持 keymap,插入模式匹配,体验与 IDE(vscode/golang)操作一致

"setting .vimr
syntax enable
"filetype plugin indent on

set nocompatible
set tabstop=4       " Size of a hard tabstop (ts)
set shiftwidth=4    " Size of an indentation (sw)
set expandtab       " Always uses spaces instead of tab characters (et)
set softtabstop=4   " Number of spaces a <Tab> counts for. When 0, featuer is off (sts).
set autoindent      " Copy indent from current line when starting a new line.
set smarttab        " Inserts blanks on a <Tab> key (as per sw, ts and sts).
set hls

" 解决删除键异常问题
set backspace=indent,eol,start

" 行首/行尾, 前/后/上/下光标移动
inoremap <C-A> <Esc>0i
inoremap <C-E> <Esc>$a
inoremap <C-F> <Right>
inoremap <C-B> <Left>
inoremap <C-N> <Down>
inoremap <C-P> <Up>

3.2. 中文说明

" 示例 ~/.vimrc
" 2015.10

" 需要 Vim iMproved 版本
set nocompatible

" 根据文件名检测文件类型,以便能进行智能自动缩进等操作。
filetype indent plugin on

" 开启语法高亮
syntax on

" 更好的命令行补全
set wildmenu

" 除了当使用大写字母时使用大小写无关查找
set ignorecase
set smartcase

" 当新开一行时,如果没有开启文件特定的缩进规则,
" 则缩进保持与你当前行一致
set autoindent

" 在左侧显示行号
set number

" 缩进选项,根据个人偏好进行修改

" 每个 TAB 的可视空格数
set tabstop=4

" 编辑时 TAB 对应的空格数
set softtabstop=4

" 当使用缩进操作 (>> 和 <<) 时缩进的空格数
set shiftwidth=4

" 将 TAB 转换成空格
set expandtab

" 为缩进和对齐开启智能化的 TAB 和空格切换功能
set smarttab

4. 查询检索操作

4.1. ‘%’ 匹配括号查找

输入%可以查找配对的括号 )、]、}

4.2. ‘%’ 搜索替换

  • 3,10s/old/new/g,3 到 10 行搜索 old 替换成 new
  • %s/old/new/gc%全文搜索替换,等价于 1,$s/old/new/gc,并提示是否替换(‘c’)

4.3. 搜索高亮设置

指令模式下输入 :set xxx 可以设置 xxx 选项。选项名可以用完整版本,也可以用缩略版本。一些有用的选项如下:

  • 'ic', 'ignorecase' 查找时忽略字母大小写
  • 'is', 'incsearch' 查找短语时显示部分匹配
  • 'hls', 'hlsearch' 高亮显示所有的匹配短语

在选项前加上 no 可以关闭选项::set noic

// 高亮
:set hls
:set hlsearch
// 取消高亮
:noh
:nohlsearch
// 快捷键
:nohlsearch<F10>

4.4. 忽略大小写搜索

  1. 要禁用忽略大小写,输入:set noic,切换回来输入set :ic
  2. 如果您想要仅在一次查找时忽略字母大小写,您可以在检索最后加上\c,比如/ignore\c <回车>

5. 变换操作

5.1. gu/gU 大小写转换

  1. crtl+V,块选中内容后,gU:切换成大写,gu:切换成小写
  2. 单个字符的处理:
    • ~:切换光标所在位置的字符的大小写形式,大写转换为小写,小写转换为大写
    • n~:将光标位置开始的 n 个字符改变其大小写(非字母的不做处理)
  3. 文本整体的处理,gu:切换为小写,gU:切换为大写,剩下的就是对这两个命令的限定(限定行字母和单词)等等。 比如: + gU0 :从光标所在位置到行首,都变为大写 + gu$:从当前指标到行位转小写 + guG: 从当前行到最尾行转小写 + ggguG:整篇文章转换为小写

5.2. 缩进

  1. 普通模式下支持>><<或者在显示模式下,可以利用<>进行内容的缩进和退回
  2. 可以利用.或者N<重复操作或者一次缩进 N 个

6. 信息显示

  1. 信息显示:CTRL+G,还可以通过指令操作设置显示信息
  2. 行号显示:set nuset nonu
  3. 光标显示:set ruler

7. 多文档编辑

7.1. 直接编辑多个文件,:n/:N 移动

  1. vim afile bfile
  2. 通过:files查下
  3. :n切换到下个文档,:N切换到上个文档
  4. afile 中选择 n 行复制,nyy,通过:n 到下个文件,通过 p 在指定位置粘贴上
  5. 全部保存退出:wqa或者:qa!

7.2. :sp 多窗口功能

  1. vim afile
  2. :sp bfile,如果想看同文件,直接键入:sp
  3. 选择窗口:
    • 按住ctrl+w,继续 w 键切换
    • 下移:先按下 ctrl 不放, 再按下w后放开所有的按键,然后再按下j(或向下箭头键),则光标可移动到下方的窗口。
    • 上移:同上,换成k或者向上箭头
    • 退出:ctrl+w,然后q 或者 :wq
  4. 垂直::vs bfile
  5. 参考:https://www.linux.com/tutorials/vim-tips-using-viewports/

8. ctrl+z 和 fg 协作

  1. vim afile
  2. 通过crtl+z换到后台
  3. 做其他事项
  4. fg,继续回来编辑 afile,如果有多个 job,需要fg %n来弹出第 n 个 vim 任务(jobs查看任务清单)

9. 另存为以及选择区域另存为

  • :w FILENAME 可将当前 VIM 中正在编辑的文件保存到名为 FILENAME 的文件中。
  • v motion :w FILENAME 可将当前编辑文件中可视模式下选中的内容保存到文件 FILENAME 中。
  • :r !dir 可以读取 dir 命令的输出并将其放置到当前文件的光标位置后面。

10. vimdiff 比对

# vimdiff 帮助
vimdiff filea filen
vim -d filea fileb
]c : 下个不同处
[c : 上个不同处

---
:diffget
:diffput
:do : diff obtian
:dp : diff put
zo: 打开折叠部分

---
更多查看
:diff tab tab (比如 diffupdate, diff)
:help