目录

  • Macros 宏
    • 录制宏
    • 示例
    • 运行宏
    • 查看宏
    • 保存宏
    • 宏中追加命令
    • 编辑宏
      • 在命令行上可视模式
      • 缓冲区中常规及插入模式
    • 另见
    • 参考资料
    • 注释

Macros 宏

当你不想使用 Vim 脚本或映射,或者如果你还不知道如何更优雅地完成某些任务时,录制宏是执行一次性任务的好方法,它可以帮助快速完成任务。

在 Vim 中,单词 “macros” 可能是指:

  • 向寄存器中录制一系列命令(本技巧)。
  • 一个把一系列输入的键扩展为一个更长的序列的映射(参见 教程 )。
  • 使用 Vim 脚本编写的脚本(存储在以 .vim 为扩展名的文件中,参见 :help script )。

录制宏

每个寄存器都是由一个小写字母进行标识,即 a 至 z。

想要录制一个宏,输入:

q<letter><commands>q    " 译者:q<字母><命令序列>q

想要执行该宏<number>次(默认是一次),键入:

<number>@<letter>

所以,完整的处理过程看起来这样:

qd    开始录制,并把后面的命令记录到寄存器 d 中
...   你复杂的命令序列
q     停止录制
@d    执行该宏
@@    再次执行该宏

示例

先提供以下的数据:

one    first example
two    second example
three  third example
four   fourth example

假设你想要把这些数据转换成 Python 程序的一个字典,最终的结果如下:

data = {'one': 'first example','two': 'second example','three': 'third example','four': 'forth example',
}

为了完成这个任务,可以在改变第一行的同时录制成一个宏。然后,回放该宏以实现改变其他行。当以上动作完成后,再手工输入初始的 data = { 和 最后的 } 的行。

以下演示录制一个合适宏的方法。

  • 把光标放在第一行上。

  • 键入 qdq 表示开始录制;d 就是这个寄存器名称,用于记录后面键入的键序列)。(备注:以下命令后小括号及其内容是注释)

  • 键入以下命令以改变第一个连续的空白成为 ': '

    :s/\s\+/': ' (然后点击回车)
    
  • 键入以下命令以实现在行首插入四个空格及 '

    I    ' (然后点击 Esc 键)
    
  • 键入以下命令以实现在行尾追加 ',

    A',(然后点击 Esc 键)
    
    • 键入以下命令使光标移动到行首,然后移到下一行:
    0j(或者按回车)
    
  • 键入 q 停止录制宏。

现在光标应该停在第二行上。键入 @d 会回放该宏一次。这应该会改变第二行,且光标会移动到第三行。键入 2@@ 以完成其他行。这个数字 2 表示后面动作执行两次,且 @@ 表示回放最后使用过的宏。如果不使用 2@@ ,你也可以键入 @d@@ 两次。

运行宏

使用以下映射,可以方便地执行录制在寄存器 q 中的宏:

:nnoremap <Space> @q
  • 通过键入 qq 开始录制击键。
  • q(如果处于插入insert模式,则先点击 Esc )结束录制。
  • 通过按空格键来回放该录制的一系列击键动作。

假设你有一个宏,它操作单行上的文本,那么你可以运行该宏一次,但是,对在可视模式下选择的每一行都有效:

  • 可视模式下选择一些行(例如,键入 vip 选择当前段落)。
  • 键入 :normal @q ,会在选择的每一行上运行寄存器中的 q 宏。

查看宏

你可以使用命令 :registers 来查看 Vim 中当前任意或全部寄存器中的内容。例如,使用 :reg 查看所有寄存器,或者 :reg a 只查看已经录制在寄存器 a 中的内容。键入 :reg abx 则会显示寄存器中 a, b 和 x 中的内容。

保存宏

保存宏以便今后使用,主要有两种方法:

最简单的方法是,如果你在非兼容模式下运行 Vim(如果你有 vimrc 文件,这是默认的),则默认就会出现这种情形。只需在你的 viminfo 选项中包含适当的文本,或者保留非兼容默认选项,Vim 就会自动地将所有寄存器写到一个文件中,并在下次启动时恢复它们。

每个寄存器的内容默认都会被保存起来,并且下一次你运行 Vim 时有效。例如,你可能录制一个宏到寄存器 a 中,然后使用 :q! 退出 Vim。当再次启动 Vim 时,你可以输入 @a 来运行寄存器中的宏 a

viminfo 选项可以禁用寄存器的自动保存特性。如果键入 :set vimifo? 显示的值包含(例如)<50s10 ,那么,在每个寄存器中将会保存最多 50 行和 10KB 内容。如果这两个项目都是零,则寄存器不会被保存。参见 :help 'viminfo'

第二种方法是,在 vimrc 中使用 let 命令来保存宏以备后用(尤其是,如果你认为可能无意中覆盖了这个宏,因此从 viminfo 文件中恢复出来错误的值)。

举一个非常简单的示例,假设你已经录制了一个宏到寄存器 a 中,而该宏的作用就是会跳转到行中第一个出现的字母 a 上,在常规模式下使用以下击键序列:

qa0faq

如果你想不管何时你启动 Vim,也不管你的viminfo 文件中包含什么,都想要恢复这个宏,则你需要编辑你的 vimrc 文件,且加入以下这行:

let @a='0fa'

假设你已经有了录制的宏,你可以容易地插入寄存器的内容,而不是再次键入它们。在输入上面这行时,在键入 let @a=' 后,简单地击键 Ctrl-R Ctrl-R a',就可以把寄存器 a 中的内容插入。两次 Ctrl-R 是想插入字面量的内容,而不是像键入时那样解释它们。

在上面示例中推荐使用单引号字符('),因为它们允许你键入的几乎都是字面内容,而在双引号(")中,你需要转义某些字母。例如,对比 '\1\2\3"abc"'"\\1\\2\\3\"abc\"" 。但是,如果寄存器必须包含单引号字母,则你得使用第二个单引号来转义它。例如,如果你想要寄存器包含 "Vim's quote handling is a little trichy" ,那么,你的键入 :let @a='"Vim''s quote handling is a little tritrichy"

然而,请注意,使用 :let 的方法对于任何以<CR><NL>(回车或换行)结尾的宏都不能正常工作。这是因为,正如在 :help :let-@ 中所记载的那样,Vim 在这些条件下把寄存器视为面向行的 (linewise) 。其原因是在处理复制或删除时,使通过 :let 设置的寄存器能以“正确的方式”进行,但是,它在处理录制的宏时,会遇到麻烦。可能的变通方法包含使用 setreg() 函数,或者添加 "no-op没有动作" 的命令到宏的结尾,例如,a<Esc> 。参见 vim_dev 中有关 unexpected behavior of the :let command 的细节的讨论。

宏中追加命令

如果你已经录制一个几乎正确的宏,但是你需要在该宏中添加很少的命令,那么,你可以容易地把这几个命令添加到已经存在的宏中,而不是再次录制所有的动作。只需使用大写字母来替代寄存器中的小写字母。

例如,如果你已经使用 qa...q 录制到寄存器 a 中,则你可以使用 qA...q 添加到这个宏中(而不是取代它)。

编辑宏

假设你已经录制一个宏在寄存器 a 中,且你想编辑这个宏。有几种方法可以实现它。

在命令行上可视模式

这个过程 上面 已经解释过了,但是,这里是这些步骤的总结:

  1. 键入 :let @a='
  2. 击键 Ctrl-R Ctrl-R a 插入当前寄存器 a 中的内容(击键 Ctrl-R 两次以精确地插入寄存器内容)。
  3. 根据需要编辑这些文本。
  4. 追加一个单引号(')完成该命令,按回车。
  5. 键入 reg a 查看寄存器中最新的值。
  6. 输入 @a 执行寄存器中 a 中的命令。

注意有关以 <CR><NL> 结尾的宏的警告。

以上步骤允许你在 Vim 的命令行上编辑宏。另一种方法是把宏保存到一个文件中,就像前面的示例中使用 let @a='0fa' 所演示那样,然后编辑该文件。

缓冲区中常规及插入模式

  1. 跳转到一个空行,或者打开一个新的缓冲区(:new)。
  2. 键入 "ap 粘贴该寄存器的内容。
  3. 进入插入模式,并根据需要进行文本编辑。
  4. Esx 返回常规模式。
  5. 键入 "ayy 复制修改过的宏到寄存器 a 中。
  6. 击键 dd ,从你正在编辑的文件中删除这些粘贴而来的寄存器内容。

另见

  • 录制递归宏
  • 反转文本块的顺序,例如录制移动块的宏
  • 使用命令行历史在没有宏的情况下重复执行 ex 命令
  • 用于快速编辑结构化文本的递归重复
  • 轻松回放录制键集
  • 为重复工作录制键
  • vim-macrobatics —— 像宏中添加一些额外功能的插件

参考资料

  • :help registers
  • :help recording
  • :help :registers
  • :help ‘viminfo’
  • :help i_CTRL-R_CTRL-R

注释

在进行复杂编辑时,我通常会使用多个宏来结束编辑,而这些宏会调用其他宏。保存这样一个宏集的一个简洁方法是打开一个新文件,并将所有相应的寄存器粘贴到其中。然后将文件的第一行作为一个宏,而该宏会把其余的行加载到适当的寄存器中以便运行这些宏集。当你想恢复时,所有你需要做的就是打开这个文件,复制第一行,执行它,很快地!你的宏集已经加载,可随时使用。


以下是一个问答:

有没有可能为不同的作业设置不同的寄存器组,例如一组用于编辑 xsl 文件,其中包含各种 xsl:xxx 标签的快捷方式,另一组用于编辑 html、 xml、 sql 等?-- 匿名用户

不,这是不可能的。Vim 中的寄存器是跨越整个 Vim 实例的全局寄存器,不像映射、缩写等可以是缓冲区本地的。-- Fritzophrenic(talk)21:49, January 15, 2013 (UTC)

我应该说“如果没有一些脚本,是不可能的”。不过有 BufEnter 和 BufLeave 事件,还有 FileType 事件,它们可以与保存和恢复所需的每个命名寄存器相结合。我知道没有现存的能这样做的插件。–Fritzophrenic (talk) 21:51, January 15, 2013 (UTC)

当我编辑各种文件时,会使用 BufEnter 把 CTRL+/ 映射为用于注释所选行的命令。不同的文件类型需要不同的注释策略,因此我是用 BufEnter 来确定应该为每个文件使用哪个序列。

au BufEnter *.js :vmap ^_ :s/^/\/\// <Enter> :nohlsearch <Enter>
au BufEnter *.py :vmap ^_ :s/^/#/ <Enter> :nohlsearch <Enter>

– Michael S. Meeks 14:11, October 9, 2013 (UTC)

看起来使用 FileType 自动命令 和 buffer-local 映射可以做得更好。参见: help:map-<buffer> 。而该问题是关于录制到寄存器中的宏,而不是关于通过 :map 类型的命令映射的问题。-- Fritzophrenic (talk) 21:39, October 9, 2013 (UTC)

Vim/Neovim中的宏相关推荐

  1. 用vim写php,Vim/Neovim中配置PHP的代码调试

    使用了一段时间的Neovim(Vim的一个变种)之后,发现再也离不开了,目前已经把Neovim作为主力开发工具了.刚也把PHP的调试功能给配置上了,这里记录一下在Neovim中配置PHP调试的整个过程 ...

  2. neovim中并行运行宏的快捷操作与lua脚本实现

    tags: Vim Lua 写在前面 最近入坑vim了, 主要是想整一个纯键盘操作的编辑器, 用sublime当然方便, 但是还是需要鼠标点点点, 不知不觉中降低了效率. (但是过渡阶段还是得先用su ...

  3. 基于qtc++设计文本编辑器的代码_文本编辑器Vim/Neovim被曝任意代码执行漏洞,Notepad:兄弟等你好久了...

    犹记前些日子,微软的记事本文本编辑器爆出了本地代码执行漏洞. Google Project Zero研究员Tavis Ormandy宣布在微软的记事本文本编辑器中发现代码执行漏洞. 可以看见,他在no ...

  4. vim保存分享录制宏

    vim中的宏是吸引我使用它的关键因素之一.确实方便,如果录制的宏可以很方便的跟朋友分享.岂不美哉! 录制宏 普通模式下: q 字母 比如:qa 此时状态栏会显示正在录制中. 一顿操作猛如虎- q 宏录 ...

  5. 文本编辑器Vim/Neovim被曝任意代码执行漏洞,Notepad:兄弟等你好久了

    犹记前些日子,微软的记事本文本编辑器爆出了本地代码执行漏洞. Google Project Zero研究员Tavis Ormandy宣布在微软的记事本文本编辑器中发现代码执行漏洞. 可以看见,他在no ...

  6. 关于Vim/Neovim/SpaceVim的一些思考

    1 前言 最近看到了Neovim以及SpaceVim,于是上手试了一下. 2 Neovim与SpaceVim Neovim是Vim的一个分支,具有更加现代的GUI.嵌入式以及脚本化的终端.异步工作控制 ...

  7. BBI综述:在微生物组研究中使用宏转录组

    在微生物组研究中使用宏转录组 Use of Metatranscriptomics in Microbiome Research https://doi.org/10.4137/BBI.S34610 ...

  8. BBI:Eran Elinav组综述在微生物组研究中使用宏转录组

    在微生物组研究中使用宏转录组 Use of Metatranscriptomics in Microbiome Research https://doi.org/10.4137/BBI.S34610 ...

  9. plsql 设置鼠标行执行_Excel中执行“宏”的方法有哪些?我列举了这5个,你会几个...

    录制完一个宏操作之后,我们可以在工作簿中反复调用创建的宏来执行重复的操作,那么执行宏操作有哪些方法呢? 上两篇文章中,其实已经跟大家讲了两种执行宏操作的方法,不知道大家有没有印象? 方法一:使用&qu ...

最新文章

  1. Linux那些事儿 之 戏说USB(11)繁华落尽
  2. jQuery计数子元素
  3. python习题:写一个备份数据库的脚本
  4. Leetcode-997 Find the Town Judge(找到小镇的法官)
  5. 关于范围for语句的使用
  6. 如何在修改 gulpfile.js 文件后自动重启 gulp?
  7. C语言标准库<string.h>
  8. MySql中左连接查询突然变得很慢
  9. 问答| 四轮驱动移动机器人(SSMR)简化模型的虚拟轮间距dLR具体是多少
  10. %%%%%%%%123564
  11. 2.晶晨A311D-编译Ubuntu/Debian固件
  12. 发现一个导致Arduino无法打开串口监视器问题
  13. MacBook Pro 上网很慢
  14. 【Win10 C盘压缩卷问题解答】:无法将卷压缩到超出任何不可移动的文件所在点
  15. Xamarin.Android之绑定库教程
  16. 更换服务器IP有哪些步骤,如何操作。
  17. html网上书店首页设计,毕业论文(设计)基于HTML5的网络书店系统 (40页)-原创力文档...
  18. 蓝海、红海指的是什么
  19. java当数值超过byte时_【Java学习重难点记录】byte数据类型在显式类型转换时超出其取值范围的转换过程...
  20. HP LaserJet M1536dnf MFP 在win11上无法安装 HP SCAN

热门文章

  1. Visual Studio 2017 安装Windows SDK10.0.17134.0 失败的解决办法
  2. Repo入门:边玩边学
  3. 前端工程师都有用哪些比较靠谱的小工具?(转)
  4. acm大一寒假集训--暴力枚举类
  5. 表格设置合并行后的斑马纹样式
  6. 网页设计后PSD时代(Post-PSD Era)
  7. 2020国内互联网大厂薪资和职级汇总表
  8. python导入数据画直方图加正态曲线_python 绘制正态曲线的示例
  9. Python读取dta数据(自己学习专用)
  10. java课设答案清华大学出版_java程序设计习题答案(清华大学出版杜)张思民版_1-12章答案全.doc...