Skip to content

第八章:文本对象

到目前为止,你删除、修改、复制时,操作的目标要么是字符(x)、要么是整行 (dd)、要么是靠移动命令一点点圈出来的范围(d$dw)。但工作中我们更常想 的其实是"改掉这个引号里的字符串"、"删掉这对括号里的内容",而不是去数有几个字符。

这时候就轮到 Vim 最迷人的特性之一 —— 文本对象(Text Objects)登场了。

什么是文本对象

文本对象不是一个命令,而是一类"目标",它需要跟在操作符(d 删除、c 修改、y 复制、v 选择)后面使用,用来描述"要操作的是哪一块结构化的文本"。

文本对象都是两个字母,第一个字母是范围修饰:

  • i 表示 inner(内部),只包含对象里面的内容
  • a 表示 around(周围),连同包裹的符号/空白一起

第二个字母表示对象类型(单词、引号、括号等,见下)。

注意:文本对象不依赖光标停在对象的哪个位置,只要光标在对象范围之内就行。比如 光标在引号中间任意位置,ci" 都能修改整个引号内的内容。

常用文本对象

单词

  • iw 一个单词(不含两侧空白)
  • aw 一个单词(含一侧空白)

引号

  • i" i' i` 引号内的内容
  • a" a' a` 连同引号本身

括号

  • i(ib 小括号内的内容
  • i[ 中括号内的内容
  • i{iB 大括号内的内容
  • a( a[ a{ 连同括号本身

标签(HTML/XML)

  • it 标签对内部的内容,如 <a></a> 之间
  • at 连同标签本身

段落与句子

  • ip / ap 一个段落
  • is / as 一个句子

配合操作符

文本对象真正的威力在于和操作符组合,读起来就像一句话:

  • ciw change inner word —— 改掉当前单词
  • di" delete inner quotes —— 删掉引号内的内容
  • ya( yank around parens —— 复制包含括号的整块
  • vi{ visually select inner braces —— 选中大括号内的内容
  • dap delete a paragraph —— 删掉整个段落
  • cit change inner tag —— 改掉标签内的文本

Tips:记忆方式很简单,"动词 + i/a + 对象",例如"我要改(c)里面(i)的单词 (w)" 就是 ciw

在下面这段代码中练习一下。把光标移到不同位置,试试 ci" 改字符串、ci( 改参数、 di{ 清空函数体、cit(需要在标签内)等等。改错了随时 u 撤销。

javascript
const greeting = "hello world";
const user = { name: "seven", age: 18, tags: ["vim", "editor"] };

function render(title, content) {
  return `<div class="card"><h1>${title}</h1><p>${content}</p></div>`;
}

试试这些组合并感受区别:

  • 光标放在 hello world 上,ci"ca" 有什么不同?
  • 光标放在 { name... } 内,di{da{ 呢?
  • 光标放在 ["vim", "editor"] 内,vi[ 选中了什么?

掌握了文本对象,你会发现自己按键变少了,但改得更准了。这是从"会用 Vim"到"用得爽" 的分水岭。

下一章将介绍 Vim 的寄存器与剪贴板。