vim 集锦

目录
  1. 记忆
  2. 当前行上移动光标
  3. 可视化选择:v, V, ctrl+v
  4. 分屏:split 和 vsplit
  5. 宏录制
  6. 替换
  7. 替换多个文件中的目标
  8. 部分交换
  9. 排序
  10. 反转行序
  11. 项目管理
  12. 查找一个word在何处被引用
  13. 加密
  14. 二进制文件
  15. 自动补全
  16. 缩写
  17. 文本对齐
  18. 对多个文件做同样的改动
  19. 搜索
  20. 之于程序

记忆

  • *# 对对当前光标所在的单词进行搜索
  • 选择光标所在的单词:viw (v进入visual模式,然后iw)
  • 复制光标所在的单词:yiw
  • % 匹配括号移动,包括 (, {, [)
  • K 查看man手册
  • :Man xxx 在新窗口中查看man手册
  • ga 查看ascii值
  • g CTRL-G 统计字数,使用Visual模式选取统计部分
  • q: 打开历史记录窗口
  • :marks 打开编辑标记窗口
  • `0 准确回到上一次退出vim的位置
  • gf 打开光标下的指定文件
  • CTRL-W f 在新窗口中打开
  • 格式转换: :set fileformat=unix
  • 断行: :set textwidth=70
  • 重新格式化: gq 如: gqap 格式化一段, gggqG 格式化整个文档
  • 增加/减少缩进: >>/<<
  • 块编辑: :set virtualedit=all , 退出 :set virtualedit=. 特别适用于表格编辑
  • gv 再次选定上次选择的Visual区域
  • CTRL-ACTRL-X 对数字加/减
  • ls | vim - 从标准输入读取要编辑的内容
  • \c, \C 忽略/不忽略大小写匹配
  • / 重复前一次搜索
  • zM 关闭所有折行, zR 打开所有折行, zo, zc 打开,关闭某个折行
  • 剪切版: "xy 复制到x缓冲区, "xp 粘贴x缓冲区, "+y
    复制到系统剪贴板, "+p 从系统剪切板粘贴

当前行上移动光标

  • 0 到行头
  • ^ 到本行的第一个非blank字符
  • $ 到行尾
  • g_ 到本行最后一个不是blank字符的位置
  • fa 到下一个为a的字符位置
  • ta 到a前一个字符处
  • 3fa 在当前行查找第三个出现的a
  • F和T 和f和t一样,只不过方向向反

可视化选择:v, V, ctrl+v

  • J 把所有的选择连接起来(变成一行)
  • < 或 > 左右缩进
  • = 自动缩进

分屏:split 和 vsplit

  • :split 水平分屏
  • :vsplit 垂直分屏
  • ctrl+w+dir dir就是方向,可以是 hjkl 或是 ←↓中的一个,用来切换分屏
  • ctrl+w+_/|: 最大化尺寸 (_: 水平,|: 垂直)
  • ctrl+w++/-: 增加/减小尺寸

宏录制

  • qa 把你的操作记录在寄存器a
  • @a 会replay被录制的宏
  • @@ 是一个快捷键,用来replay最新录制的宏

替换

1
:20,100s/bc/a&d/g

解释:
& 是一个特殊字符,表示被替换的内容。结果为把bc替换成abcd
如果要替换成”a&d”的话,需要用 \& 将&转义

1
:%s/(\(\d+\))/\="(".(submatch(1)+1).")"/g

作用:
将”(1), …., (2), ….,(100)”替换成”(2), …., (3), …., (101)”,即括号里的序号数字都加一。

解释:
% 全文(”%”是”1,$”范围的缩写)
s 替换
/ 搜索字符串开始
( 左括号
( 开始记录匹配
\d+ 一个或多个数字
) 结束记录匹配
) 右括号
/ 搜索字符串结束
\= 把后面的表达式计算出来作为替换字符串
“(“ 左括号
. 字符串连接运算符
(submatch(1)+1) 把第一个匹配的结果加1作为一个整体返回
.”)” 添上右括号
/g 替换字符串结束,g表示替换每一行的所有匹配结果。

1
:%s/\s\+$//

作用:
消除多余空格
解释:
\s+$ 位于行尾的一个或多个空白字符

替换多个文件中的目标

案例:将所有cpp文件中的”aaaa”替换为”bbb”

1
2
3
4
5
6
7
vim *.cpp          # 启动vim,同时指定了要编辑的文件列表
qa # 开始宏记录
:%s/\<aaa\>/bbb/ge # 在第一个文件中执行替换操作。使用'e'在没有匹配目标时也不会报错
:wnext # 保存该文件并转到下一个文件进行编辑
q # 停止宏记录
@a # 执行名为a的宏。看看整个过程有没有错
999@a # 对其余文件执行同样操作

部分交换

案例:

1
2
Doe, John       ====>        John Doe
Smith, Peter Peter Smith

在vim中只需一条命令:

1
:%s/\([^,]*\), \(.*\)/\2 \1/

解释:
可以使用的反向引用为9个,”\0”特指整个匹配到的内容

排序

通过外部程序 sort 对行排序:

1
:.,/^$/-1!sort

解释:
.,/^$/-1 选取的范围是自当前行直至下一个空行。也可以在Visual模式下选取要排序的行

反转行序

将所有行移到第0行后面:

1
:g/^/m 0

将连续行移到某一行的后面:

1
2
3
mt                  # 标记“某一行”
[n]j # 移到“连续行”的最后一行
:`t+1,.g/^/m `t

解释:
g 对范围内的所有行进行操作
^ 匹配一行的开头
m 0 或 m t 移到第0(t)行之后

项目管理

会话:session

  • 保存当前会话::wa:mks
    • 会在当前目录下生成”Session.vim”脚本文件
    • :mks filename 产生”filename”脚本文件
  • 恢复会话::so Session.vimvim -S Session.vim
  • 切换会话:
    :wall
    :mks! ~/.vim/secret.vim
    :so ~/.vim/boring.vim
    

记住编辑信息:viminfo

  • 保存信息::wviminfo ~/tmp/test.viminfo
  • 读取信息: :rviminfo ~/tmp/test.viminfo

视图:view

  • 保存视图: :mkview 1:mkview ~/.vim/main.vim
  • 恢复视图: :loadview 1:so ~/.vim/main.vim

缓冲区:buffer

  • 显示缓冲区列表: :buffer:ls , :ls!

    输出为:
        :ls
           1  h   "[未命名]"                     第 1 行
           2 %a + "Proj/Uliweb/mysite/apps/Notes/files/Ubuntu/vim.rst" 第 145 行
           3 #h   "Proj/Uliweb/mysite/apps/Notes/files/Ubuntu/imagemagick.rst" 第 23 行
           4  h   "im"                           第 0 行
    
  • 编辑一个缓冲区:

    • :buffer 2
    • :buffer im
    • :sbuffer 3 # 新窗口
  • 遍历缓冲区:
    • :bnext 下一个缓冲区
    • :bprevious 前一个缓冲区
    • :bfirst 第一个缓冲区
    • :blast 最后一个缓冲区
  • 删除缓冲区::bdelete 3

查找一个word在何处被引用

案例:希望编辑所有包含了”frame_counter”的c文件:

1
vim `grep -1 frame_counter *.c`


1
:grep frame_counter *.c

解释:

-1 使grep的输出只包含文件名而不显示匹配的行
` 反向引用符号,运行其中的命令,并将命令的结果作为当前命令的一部分
:next:first来遍历文件列表
结合:cnext, :cprev, :clist 遍历所有匹配

加密

加密:

  • 方法一: vim -x test.txt
  • 方法二: :X

解密::set key=

二进制文件

  • vim -b datafile

    :set display=uhex 以十六进制格式显示

  • 使用xxd程序 :

    vim -b datafile
    :%!xxd

自动补全

  • 补全单词:CTRL-PCTRL-N
  • 补全特殊的文档元素:

    1
    2
    3
    4
    5
    6
    7
    8
    CTRL-X CTRL-F 文件名
    CTRL-X CTRL-L 整行内容
    CTRL-X CTRL-D 宏定义(也包括那些在include文件里定义的宏)
    CTRL-X CTRL-I 当前文件和被当前文件include的文件
    CTRL-X CTRL-K 来自一个字典文件的word
    CTRL-X CTRL-T 来自一个thesaurus的word
    CTRL-X CTRL-] tags
    CTRL-X CTRL-V Vim的命令行
  • 智能补全: CTRL-X CTRL-O 常用在c源码中:w

缩写

  • 定义缩写::iabbrev lyh lyhopq@gmail.com
  • 列出以定义缩写:abbreviate
  • 删除缩写: unabbreviate lyh
  • 更正打字错误: abbreviate teh the
  • 移除所有缩写: :abclear

文本对齐

  • 居中对齐: :{range}center [width] 例: :1,5center 40
  • 左/右对齐: :left/right
  • 左右对齐:
    • 使用宏: :runtime macros/justify.vim
      | 在Visual模式下选定格式化文本,然后执行 _j
    • 使用外部程序: :%!fmt

对多个文件做同样的改动

案例1:把多个c文件中名为”x_cnt”的变量都改为”X_counter” :

1
2
:args *.c
:argdo %s/\<x_cnt\>/x_counter/ge | update

解释:
args *.c 把所有要改的文件放到参数列表上
:argdo 以另一个命令为参数,该命令将对所有待编辑的文件都执行一次
| 用来分割两个命令
update 在文件有所改变时进行保存
类似于 :argdo
:windo 对所有窗口执行同样的操作
:bufdo 对所有缓冲区进行操作, 这个要小心使用 ,最好用:ls 看一下有哪些缓冲区会被改动

案例二:将多个文件中的”-person-“都改为”Jones”其后打印出来

  1. 将要执行的vim命令(Ex模式)放入”change.vim”中 :
1
2
3
%s/-person-/Jones/g
write tempfile
quit
  1. 以批处理模式运行vim
1
2
3
4
for file in \*.txt; do
vim -e -s $file < change.vim # "-e"Ex模式, "-s"告诉vim安静地运行
lpr -r tempfile # 打印"tempfile"的内容,然后删除它("-r")
done

搜索

  • 偏移

    • /words/2 将光标停留在目标行向下的第二行
    • /words/e-1 “e”使光标在找到目标串后以它的结尾作为移动的起始处
    • /words/b+2 “b”目标串开头为起始处
    • //e 重复前一次搜索使用不同的偏移
    • ?words?e-2 反向搜索必须以”?”来分割命令的不同部分
  • 多次匹配

    • /ab* “*“匹配任意个(零个或多个)b
    • /\(ab\)* “ab”作为整体
    • /ab\+ “+”至少一次
    • /folders\= “=”一次或零次
    • /ab\{m,n} 匹配至少m次,至多n次
    • /foo\|bar “|”模式中的或操作
  • 字符范围:

    • /[a-z] ,使用”\^”指定补集
    • 预定义字符集 :
      \d 数字 [0-9]
      \D 非数字 [^0-9]
      \x 十六进制数 [0-9a-fA-F]
      \X 非十六进制数 [^0-9a-fA-F]
      \s 空白字符 [ ] ()
      \S 非空白字符 [^ ] (除 之外)
      \l 小写字母 [a-z]
      \L 非小写字母 [^a-z]
      \u 大写字母 [A-Z]
      \U 非大写字母 [^A-Z]
  • 匹配一个断行:通过前缀”_“来同时包括断行,例: /the\_s\+word匹配断行或多个空白字符

之于程序

  • tags

    • 跳转: CTRL-W ] 分割当前窗口并跳转到光标下的tag,
    • :tnext 下一个符合条件的地方
    • :tselect tagname 列出所有符合条件的地方
    • 搜索::tag /xxx ,然后按Tab
    • 预览窗口:ptag tagname
    • 关闭窗口:pclose
    • :pedit defs.h 在预览窗口中编辑一个文件
    • :psearch popen在预览窗口中显示搜索内容
  • 程序中的移动

    • [#,]# #if 内的移动
    • [[,]] {} 内的移动
    • [(,]) () 内的移动
    • [/,]/ 注释内的移动
  • 查找标识符

    • [I 查找全局标识符,光标放在要查找的标识符上
    • [Tab[I ,但它跳转到第一个匹配项
    • [D 只查找以”#define”定义的
    • gD 搜索限制在当前文件, gd 当前函数
  • 编译

    • 编译::make {arguments}
    • 错误::cnext, :cc, :clist, :clist!, :cprevious, :cfirst, :clast, :cc [n]
    • 错误列表::colder, :cnewer
  • 缩进: ===a{gg=G

评论