vim 进阶
1. 软件设计的宏观理念
任何一款优秀的软件,都是 “通用性” 和 “特定性” 的结合。
任何一款软件,一定有其所面向某个领域、某个问题的通用的、常规的、核心的需求,满足了这些需求,达到了软件的基本要求,实现了软件的“通用性”。软件面向各类有使用需求用户,这些用户除了通用性、共性的需求,通常还有某些特定性的需求,优秀的软件往往还为这些“特定性”需求预留解决方案的可能性。因此,要想成为一款优秀的软件,除针对通用共性的需求给出独有高效的解决方案外,还要依托软件实现既有功能对外提供足够的开放性(如参数定制、命令系统、API 调用等),软件的用户可利用这种开放性,进一步对软件资源进行拓展(如二次开发、插件开发等),利用这种机制,满足软件各类用户的“特定化”需求(如核心功能的扩展,与外部软件功能的高效对接等),进而形成了基于核心软件的一个庞大的“生态系统”。Vim,无疑是这类优秀软件的典型代表。
针对文本编辑需求,Vim 提供了自己一套独有的解决方案,与此同时,Vim 还提供了一套强大的命令系统,用户可基于这套命令系统,进行 vim 的参数定制,开发适合自身需求的插件。经过多年的发展,Vim 已经培养出了一个庞大高效的“生态系统”,针对各类编辑问题均具有出色的 solution。
2. map 命令 — 快捷键的灵活定制
1)map 基本指令
map 是一个映射命令,它可以将常用的一个很长的命令映射到一个简洁的功能键上。其基本形式如下:
***: map {lhs} {rhs}***
{复杂指令} > {简单指令}
其含义是,map 命令将左边的键系列 {lhs},映射为(>)右边的键系列 {rhs}。
map 命令可进行递归映射,即如果 {rhs} 还有其它映射,可一直递归映射下去。
2)map 扩展指令体系
作为编辑器领域泰山北斗,Vim 为文本编辑提供了一套独特的世界观,将软件的使用状态划分为多个模式,不同模式有不同的特点和核心任务,通过多个模式共同配合完成文本编辑工作。
各模式简要说明如下:
- 普通模式:输入命令时。默认进入 vim 之后,处于这种模式。
- 插入模式:处在编辑输入的状态。普通模式下,可以按 i 进入。
- 可视模式:这种模式下选定一些字符、行、多列。普通模式下,可以按 v 进入。
- 操作符等待模式(待决模式):操作符等待中 (“d”,”y”,”c” 等等之后)。
- 命令行模式:可以输入各种命令,使用vim的各种强大功能。输入 “:” 或 “/” 命令,进入该模式。
因为 Vim 有多种模式,因此,map 命令的映射也涉及不同模式下的不同映射指令问题,map 命令采用在基本指令 map 的基础上,增加不同的前缀来解决这个问题,为不同模式下的快捷操作提供便利。
Command | Normal | Visual | Operator Pending | Insert Only | Command Line |
---|---|---|---|---|---|
:map | Y | Y | Y | ||
:nmap | Y | ||||
:vmap | Y | ||||
:imap | Y | ||||
:cmap | Y | ||||
![]() |
Y | ||||
:map! | Y | Y |
图中不难看出,map 命令结合不同的“模式前缀”指明了快捷键映射生效的场景。
- n — 表示在普通模式下生效;
- v — 表示在可视模式下生效;
- i — 表示在插入模式下生效;
- c — 表示在命令行模式下生效;
map 命令的其它重要形式(功能前缀):
- noremap — 可理解为 no+re[cursive]+map,使用 nore 前缀,map 命令不再进行递归映射;
- unmap — 顾名思义,unmap 命令对应取消 map 命令所设置的快捷键,具体命令格式如下:
> :unmap {lhs} - mapclear — 清场指令,取消所有 map 绑定的映射
“模式前缀” + “功能前缀”组合使用,即可实现特定模式下的特定映射。
3)替换指令串的构造
为 {lhs} 和 {rhs} 的构造提供充分的灵活性,map 命令还引入特殊符号(也可视为符号常量),在 {lhs} 和 {rhs} 表达式中表示特定的含义。
- <k0> – <k9> — 小键盘 0 到 9
- <S-…> — Shift+键
- <C-…> — Ctrl+键
- <A-…> — Alt+键 或 meta+键
- <Esc> — Esc 键
- <Up> — 光标上移键
- <Space> — 插入空格
- <Tab> — 插入Tab
- <CR> — 等于<Enter>
- <silent> — 执行键绑定时不在 vim 底端命令行上回显
动态替换指令串构建 — \<Leader> 和 mapleader 变量
map 使用 <leader> 和 mapleader 变量提供了构建动态可变替换指令串的能力。
<leader>是一个占位符,目的是为 mapleader 的变量值提供位置信息。mapleader 变量是 Vim 的一个内置变量,作用是将特殊符号 <leader> 替换成 mapleader 变量的值(类似于宏替换),比如:
:map < Leader>A oanother line< Esc>
如果 mapleader 变量没有设置,则默认用 \ (反斜杠)
代替,因此,这个映射等效于:
:map \A oanother line< Esc>
意思时输入 \A 键时,在下一行输入 another line 并返回到普通模式。
如果设置了mapleader变量,比如:
let mapleader = ","
则等效于:
:map ,A oanother line< Esc>
<leader> + mapleader 方法对所有 map 映射命令起效。
此外,除了 <leader>占位符外,Vim 还提供另一占位符 — <localleader>。localleader 与 leader 作用一样,只是适用范围有所缩小,只适用于特定类型的文件。
map、mapleader、maplocalleader 指令的相关信息,可通过 : help map
,: help mapleader
, : help maplocalleader
进一步了解。