撸一撸VIM -- 5 命令行模式

2016年04月30日

一、叨叨逼

  • 最近两周阅读完了解读基金,五一假期,继续更新博客。

二、说明

  • 前面几章已经介绍过vim的三大类模式,分别是普通模式,插入模式,可视模式,剩下命令模式还没有介绍。介绍命令模式之前我们先简单地回顾一下几个模式以及它们的切换关系
  • 八种模式
    • 普通模式是Vim的自然放松状态,也是Vim的默认模式
      • 普通模式之所以强大,主要由于它可以把操作符和动作命令结合在一起
      • 操作 = 操作符 + 动作命令
    • 插入模式
      • 与Sublime Text默认模式类似
    • 插入-普通模式
      • 这是普通模式的一个特例,让我们从插入模式执行一次普通模式命令,然后回归插入模式,按键为
    • 替换模式
      • 与插入模式的区别:在替换模式中输入会替换文档中的已有文本
    • 虚拟替换模式(推荐)
      • 把制表符当成一组空格进行处理,假设制表符列宽为8,输入的前7个字符时,每个字符会被插入到制表符之前,当输入第8个字符时,该字符会替换制表符
    • 可视模式允许我们选中一块文本区域并在其上进行操作
      • 面向字符:v
      • 面向行:SHIFT+v
      • 面向列:
    • 选择模式
      • 与Word和Sublime Text的操作模式类似,当选中一段文本后,再输入任何可见字符,选择的文本会被删除
    • 命令模式
      • 行编辑器ex是vi的先祖,vim支持Ex命令
  • 切换关系图
  • 再说命令模式
    • 操作缓冲区文本的常用Ex命令(完整列表:h ex-cmd-index)
      • [range]:连续的行
        • 行号:{start},{end}{command}
          • :1p:打印第一行
          • :2,5p:打印第2-5行
          • :$p:打印最后一行
          • :1,$p:打印全部
          • :.,$p:打印当前行到最后一行
          • :%p:打印全部
        • 位置标记
          • ‘m:包含位置标记m的行
          • ’<:高亮选区首行
          • ’>:高亮选区最后一行
          • :’<,’>:高亮选区的范围
        • 查找模式
          • :/<html>/,/<\/html>/p:打印第一个<html>标签和第一个</html>标签之间的内容
        • 位置偏移
          • {address}+n:{address}可以为行号,位置标记,查找模式
      • global:可以是[range]范围内非连续的行
    • Ex命令 vs 普通模式
      • 普通模式一般操作当前字符或当前行
        • 适合”本地“操作
      • EX命令
        • 可以在任意位置执行
        • 在多行上同时执行的能力
        • 可以远距离操作
Ex命令 用途
:[range]delete [x] 删除指定范围内的行[到寄存器 x 中]
:[range]yank [x] 复制指定范围的行[到寄存器 x 中]
:[line]put [x] 在指定行后粘贴寄存器 x 中的内容
:[range]copy {address} 把指定范围内的行拷贝到 {address} 所指定的行之下
:[range]move {address} 把指定范围内的行移动到 {address} 所指定的行之下
:[range]join 连接指定范围内的行
:[range]normal {commands} 对指定范围内的每一行执行普通模式命令 {commands}
:[range]substitute/{pattern}/ {string}/[flags] 把指定范围内出现{pattern}的地方替换为{string}
:[range]global/{pattern}/[cmd] 对指定范围内匹配{pattern}的所有行,在其上执行 Ex 命令{cmd}

三、演示

1. 复制(:co[py]==:t)和移动(:m[ove])行

2. :normal - 代码行尾添加分号 和 注释代码

  • 在普通模式时介绍过,可以使用命令.重复修改,但不适用于有很多行的代码
  • :nomal:将强大表现力的Vim普通模式命令和具有大范围影响力的Ex命令结合在一起
  • Ex命令结合命令.能节省很多按键操作
  • 注释代码
    • 在执行指定的普通模式命令之前,Vim 会先吧光标移动到该行的行首
    • :%normal i//

3. 遍历缓冲区列表

  • 同时打开多个文件,会形成缓冲区列表,bn[ext]打开下一个缓冲文件,bp[revious]打开上一个缓冲文件。
  • :@::重复执行上次Ex命令;
  • @@:重复执行:@:
  • :回退到上一个缓冲文件

4. Ex命令自动补全

  • 针对zsh的vim配置
    • set wildmenu
    • set wildmode=full
  • 正向查找
  • 反向查找

5. 替换单词

  • :复制光标下的单词并把它插入到命令行中

6. 命令行窗口

  • 命令模式适用于从头开始构建命令,但在命令模式中编辑命令的能力有限,而且不能利用历史命令(Ex命令或查找命令),命令行窗口能弥补这两个短处
  • 命令行窗口就像一个常规的Vim缓冲区,只不过内容是命令历史,允许我们使用Vim完整的区分模式的编辑能力来修改历史命令,并可以在活动窗口的上下文中执行命令
    • q::打开Ex命令历史的命令行窗口
    • q/:打开查找命令历史的命令行窗口
    • :从命令模式切换到命令行窗口,保存原先输入
    • :q:退出命令行窗口
    • :在活动窗口上下文执行命令并退出命令行窗口
  • 演示例子中,将:w,:%p,:!python3 %在命令行窗口中合成一个命令并执行

7. 运行Shell命令

  • %:代表当前文件
  • 调用外部命令
    • :shell:启动一个shell(输入exit返回Vim)
    • !{cmd}:在shell中执行{cmd}
    • read !{cmd}:在shell中执行{cmd},并把其标准输出插入到光标下方
    • [range]write !{cmd}:在shell中执行{cmd},以[range]作为其标准输入
    • [range]!{filter}:使用外部程序{filter}过滤执行的[range]
      • [range]所指定的内容会传递给{cmd}作为标准输入,然后又会用{cmd}的输出覆盖[range]内原本的内容
  • 把缓冲区内容作为标准输入和标准输出

  • 过滤缓冲区内容(依据第三行)
    • !{motion}:切换到命令模式,命令行上预设为.,{motion}!,即当前行移动{motion}的区域