vimbook-OPL(11-13)
Contents
vimbook-OPL(11-13)
CH11 Dealing with Text Files(处理文本)
这一章主要讲将 Vim 用作类似字处理器时所提供的功能,包括自动文本回绕,文本格式化命令,自动文本格式化选项(formatoptions)以及处理不同操作系统下的换行符还有就是字处理器 Troff 相关的命令,最后介绍了 Vim 自带的 rot13 算法混淆功能。
11.1 自动文本回绕
自动文本回绕在处理注释或者写文档时十分有用,一般我们要求文档一行的长度不要超过 80 字符,如果每次都需要手动插入换行符是相当累的一件事。Vim 提供了自动换行的功能,通过选项 :set textwidth=80
当输入的文本长度超过 80 字符时将自动插入一个换行符。还有一种可以设置右边边距的选项 :set wrapmargin=10
当插入的字符距离屏幕右边 10 列时将自动插入一个换行符。这个选项只有在 textwidth 为 0 的情况下才会生效。书中原文是 The ’textwidth’ option overrules ‘wrapmargin’.
用 gq{motion}
命令能够对选中的文本块进行自动排版,gq 在未配置的情况下使用内部排版机制,内部排版机制依据 textwidth 和 formatoptions 来进行排版。{motion} 可以是 4j
这样的表示下行 4 行,更为常见的是 }
表示从当前位置到段落尾部,或者 ip
表示当前段落。ip 这种 {motion} 是文本对对象在帮助文档 :h object-select
中可以找到完整的解释。
用 gqq
可以格式化当前行。
11.2 文本排版
:[range]center [width]
将范围 range 中的文本按照 width 长度进行中间对齐,width 缺省为 textwidth;:[range]right [width]
将范围 range 中的文本按照 width 长度进行向右对齐,width 缺省为 textwidth;:[range]left [indent]
将范围 range 中的文本按照 indent 长度从左边缩进,不指定则为 0,表示向左对齐;
以上 range 请参考 vimbook-OPL(5-10) 篇中的 print 命令,里边详细讲解了各种 range 的选择方式。我想到一个有用的场景就是在写文档的时候,我们需要对某些代码的句子或者一些配置进行居中对齐,用 center 命令就不用收到缩进了。
11.3 格式化微调
‘joinspaces’ 选项可以调整当用 J
命令粘合两行文本时,如果第一行以 ‘.’ 、’?’ 和 ‘!’ 之后插入两个空格,如果设置的是 ’nojoinspaces’ 则只插入一个空格。‘formatoptions’ 在第 9 章已经详细讲解过了,详细查看帮助文档 fo-table 标签。
Vim 自动排版时默认用的内部的排版机制,通过 ‘formatprg’ 选项可以设置外部程序作为 gq 的排版机制,如在 Linux 下 :set formatprg=fmt
将 fmt 程序作为排版程序。或者调用 !ip fmt
直接格式化本段内容。
11.4 文件格式
文件在不同的系统下有以不同的符号作为换行符,典型的 Linux/macOS 以 <NL>
作为换行符,Windows 以 <CR><NL>
作为换行符。Vim 编辑器能够自动识别文件格式,并用正确的换行符。Vi 没有功能,所以对待 Windows 下的换行符会显示一个 ^M 字符。通过设置 :set fileformats=unix,dos
可以告知 Vim 先以 unix 方式识别文件,如果不成功再以 dos 形式识别文件。如果只指定一种格式那么当文件格式不一致时会发生转换。
当打开选项 ’endofline’ 时,会自动在文件的末尾加上一个换行符。这个标记在通常在文本文件都是设置的,因而不需要怎么关注。而在二进制文件中可以设置 ’noendofline’ 来关闭自动添加换行符功能。
11.5 Troff 相关的移动
这里介绍 句子(sentence) 段落(paragraph) 和 小节(section) 的概念。在代码中我们一般并不会用到这些概念,在书写文档时或者一般性文章时还是蛮有用的。
-
句子:指的是以标点符号 ‘.’ ‘!’ 或者 ‘?’ 结尾并紧随一个换行符、空格或者制表符的一串文本,小节和段落的边界也是句子的边界。motion 命令
[count](
反向 count 个句子,[count])
正向 count 个句子; -
段落:指的是以空行或者段落宏分隔的一大段文本,小节的边界也是段落的边界。空行必须是只有一个换行符,不能有空白字符。motion 命令
[count]{
反向 count 个段落,[count]}
正向 count 个段落。段落宏指的就是 Troff 的段落宏,通常以点号和两个字符定义,如: .IP .LP 等,点号必须出现在第一列。Vim 中识别的段落宏在选项 ‘paragraphs’ 中定义,段落宏以成对出现的所定义,默认的段落宏如下::set paragraphs=IPLPPPQPP<Space>TPHPLIPpLpItpplpipbp
-
小节:指的是以首列
<C-L>
或者小节宏命令分隔的文本。小节宏以 ‘sections’ 选项中成对出现的字符定义。缺省的小节宏如下::set sections=SHNHH<Space>HUnhsh
通过
]]
][
移动到下一个小节,在 C 语言中]]
前进到下一个首列 { ,][
出现在下一个首页 } 处。通过[[
[]
移动到上一个小节,在 C 语言中[[
移动到上一个首列 { 处,[]
移动到上一个首列 } 处。
11.6 用 Rot13 混淆文本
Rot13 是一个很弱的混淆算法,因为英文字母有 26 个,将任意一个字母加上 13 得到的新的字母,对于相加大于 26 的字母进行回绕。这样对任意字母加两次之后又还原回的字母。g?motion
将 motion 表示的文本块进行 Rot13 加密,当需要阅读原文时用 g?motion
就有可以了。g??
对当前行进行加密。
CH12 Automatic Completion
12.1 自动补全
按住 CTRL-P
可以回溯搜索匹配当前光标的单词,CTRL-N
进行前向搜索,如果光标下什么也没有输入就会回溯遍历所有单词。Vim 的搜索策略如下:
- 当前文件;
- 其它窗口的文件;
- 其它缓冲列表中的文件;
- 被卸载的缓冲文件(
:bd
命令进行卸载); - 当前tags文件中的标识符;
- #include 头文件;
自定义补全
:set ignorecase
选项告知 vim 搜索时进行大小写不敏感匹配,设置 :set infercase
可以让 vim 推断光标所在单词的大小写,从而可以转为合适的大小写;用 :set complete=key,key,key
设置补全的搜索顺序,缺省为 “.,w,b,u,t,i” key的含义如下:
. 当前缓冲
b 加载的缓冲但是不在窗口中
d 在当前文件和 #include 中的定义
i 由 #include 包含的文件
k 'dictionary' 选项定义的文件
k{file} 文件{file}中的单词
t tags文件中的标识符
u 卸载的缓冲
w 其它窗口中的文件
vim 使用 ‘path’ 选项来指示从哪些目录查询 #include 文件,默认值是 .,/usr/include,,
,设置补全的查找字典文件,通过设置 ‘dictionary’ 来指定,每个文件用逗号分隔。
控制搜索项目
CTRL-X CTRL-D 搜索宏定义
CTRL-X CTRL-F 搜索文件名
CTRL-X CTRL-K 搜索字典
CTRL-X CTRL-I 搜索当前文件和 #include 文件
CTRL-X CTRL-L 搜索整行
CTRL-X CTRL-] 搜索 Tags,默认情况下只显示标签名字,当设置 'showfulltag' 选项时将显示完整的函数原型
CH13 Autocommands
13.1 介绍
自动命令是在特定的事件发生时自动执行的命令。事件是 Vim 预设的,比如文件打开、文件写入、文件关闭等。命令:
|
|
将在用户写入文件前一刻执行插入时间的自动命令,自动命令的一般形式如下:
|
|
其中 group 是可选的,用来管理和调用命令。events 是一系列逗号分隔的预定义的事件,file_pattern 是文件名的规则表达式,nested 标识允许自动命令嵌套,允许一个自动命令再触发另一个自动命令,例如:
|
|
以上命令中的 e!
将会触发 FileReadPre 事件。
command 就是最终执行的命令。
13.2 Groups
:augroup
用来开启自动命令组的定义,后面跟随组名。例如:
|
|
以上两个命令就包含在组 cprograms 中,如果你想再添加一个新的命令到组中你可以执行如下命令:
|
|
自动命令也可以手动执行,例如现在正在编辑 sam.cx 文件,如果需要对其执行 cprograms 组命令,得用一下方式调用:
|
|
假装当前文件是 foo.c 并以 cprograms 组命令执行 FileReadPost 事件。通用命令格式如下:
|
|
指的是如果省略 group 将会查找所有的组,如果省略 file_name 将以当前文件的文件名去执行 event ,其中 event 是不可以省略的。
13.3 Events
预定义的事件如下表:
PreEvent | PostEvent | 触发时机 |
---|---|---|
BufNewFile | 当编辑不存在的文件时触发 | |
BufReadPre | BufReadPost | 在读取缓冲前/后触发 |
BufFilePre | BufFilePost | 当用:file 命令改变一个缓冲的文件名前/后 |
FileReadPre | FileReadPost | 当用:read 命令读取一个文件的前/后 |
FilterReadPre | FilterReadPost | 在使用过滤(filter)命令读取前/后 |
FileType | 当filetype 选项被设置时 | |
Syntax | 当 syntax 选项被设置时 | |
StdinReadPre | StdinReadPost | 当冲标准输入输出读取前/后 |
BufWritePre | BufWritePost | 将缓冲写入到文件的前/后 |
BufWrite | 与 BufWritePre 一样 | |
FileWritePre | FileWritePost | 写入缓冲的一部分到文件中 |
FileAppendPre | FileAppendPost | 添加到文件的前/后 |
FilterWritePre | FilterWritePost | filter 命令写入文件的前后 |
FileChangedShell | 当vim执行shell时发现文件的的修改时间发生改变 | |
FocusGained | FocusLost | 当 GUI 版本的 vim 获得、丢失输入焦点时 |
CursorHold | 当用户停止输入updatetime选项指定的时间时会执行 | |
BufEnter | BufLeave | 当buffer进入或离开时触发 |
BufUnload | 当缓冲卸载时触发 | |
WinEnter | WinLeave | 当进入或离开窗口时触发 |
BufCreate | BufDelete | 当缓冲被创建或者删除时触发 |
VimEnter | 当 vim 被打开并且初始文件被执行之后触发 | |
VimLeavePre | 当 Vim 被关闭并且 .viminfo 还没有写入 | |
VimLeave | 当 Vim 被关闭并且 .viminfo 已经写入内容 | |
FileEncoding | 当 fileencoding 选项被设置时触发 | |
TermChanged | 当 term 选项被改变时触发 | |
User | 当 :doautocmd 时可以指定此事件,vim 不会触发 |
13.4 File Patterns
自动命令的文件正则表达式运用了 UNIX 的标准,以下是一些正则的用法:
符号 | 含义 |
---|---|
* | 匹配任意长度的所有字符 |
? | 匹配任意单个字符 |
, | 分割多个表达式 |
\? | 精确匹配 ? 字符 |
\, | 精确匹配 , 字符 |
\character | 将 character 作为搜索模式字符,如 + 等 |
实用命令
:autocmd
列举所有自动命令,更一般的 :autocmd group [event] [pattern]
会列举在 group 下的 event 事件下的文件类型的自动命令。event 可以是 *
号表示匹配所有事件。用 :autocmd!
将删除所有自动命令,:autocmd! group [event] [pattern]
将将删除匹配的自动命令。以下命令可以忽略特定事件的自动命令,如:
|
|
将忽略窗口进入和离开事件,调用 :set eventignore=all
将忽略所有事件。
Author zoro.wang
LastMod 2017-11-25